Skip to content

Commit

Permalink
Part 3 of why eshell
Browse files Browse the repository at this point in the history
  • Loading branch information
oneness committed Jul 10, 2021
1 parent 3408862 commit 6332a95
Show file tree
Hide file tree
Showing 9 changed files with 477 additions and 36 deletions.
105 changes: 105 additions & 0 deletions 2021-07-10-why-eshell-part-3.html
@@ -0,0 +1,105 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="alternate"
type="application/rss+xml"
href="https://www.birkey.co/rss.xml"
title="RSS feed for https://www.birkey.co/">
<title>Why Eshell - Part 3</title>
<meta name="author" content="Kasim Tuman">
<meta name="referrer" content="no-referrer">
<link href= "static/style.css" rel="stylesheet" type="text/css" />
<link rel="icon" href="static/favicon.ico">
<link rel="apple-touch-icon-precomposed" href="static/birkey_logo.png">
<link rel="msapplication-TitleImage" href="static/birkey_logo.png">
<link rel="msapplication-TitleColor" href="#0141ff">
<link rel="alternate" type="application/rss+xml" title="RSS Feed for birkey.co" href="/rss.xml"
<meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8">
<meta name="viewport" content="initial-scale=1,width=device-width,minimum-scale=1"></head>
<body>
<div id="preamble" class="status"><br><center>
<div style="display: inline-block; vertical-align:middle;">
<a href="https://www.birkey.co/index.html" style="text-decoration: none;"><b>BIRKEY CONSULTING</b><br>
</a><hr/><div style="text-align: justify;display: inline-block; width: 100%;">
<a class="title" href="https://www.birkey.co/resume.html">ABOUT</a> &nbsp;<a class="title" href="https://github.com/oneness">GITHUB</a> &nbsp;<a class="title" href="https://www.birkey.co/rss.xml">RSS</a> &nbsp;<a class="title" href="https://www.birkey.co/archive.html">ARCHIVE</a> &nbsp;<a class="title" href="https://paypal.me/ktuman">DONATE</a></div></div>
</center><br><br>
<div style="margin-bottom: 3ch;text-transform: none;"></div></div>
<div id="content">
<div class="post-date">10 Jul 2021</div><h1 class="post-title"><a href="https://www.birkey.co/2021-07-10-why-eshell-part-3.html">Why Eshell - Part 3</a></h1>
<p>
If you have been following my `Why Eshell` series, you might be
wondering about interactive ido completion for eshell. Since Eshell
buffer is just a regular emacs buffer, we can compose few emacs
builtin functionalities to bend it to our command line work flow.
Following is all the code you need. Note that it is heavily commented
so you can understand what is happening.
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">(defun kshell-with-name (&amp;optional name)
;; creates an eshell buffer with `kshell' as the default name. Take
;; optional name to override
(let ((m (-&gt;&gt; (or name "kshell")
(format "*%s*"))))
(if (get-buffer m)
(pop-to-buffer m)
(progn
(eshell)
(rename-buffer m)))))

(defun kshell (&amp;optional cmd buff-name send-input)
;; interactive fn that you can call via M-x or hotkey. It detects
;; current project root to start eshell buffer if no `buff-name' is
;; given. You can control how the `cmd` gets insert only or insert
;; and executed using `send-input` flag. Ex. Useful for further
;; editing.
(interactive)
(let ((dir (projectile-project-root))) ;; you need projectile
(if buff-name
(kshell-with-name buff-name)
(kshell-with-name))
(eshell/clear-scrollback)
(insert (format "cd %s" (or dir "~/")))
(eshell-send-input)
(insert (format "%s" cmd))
(when send-input (eshell-send-input))))

(defun krun (cmd)
;; eshell command history with ido completion. Assign it to a hot
;; key say, F12 and you will get a search-able command history that
;; you can execute just by doing ido interactive search.
(interactive
(list
(ido-completing-read
"Enter cmd to run (append ##name for buffer name): "
(let ((history nil))
;; We have to build up a list ourselves from the ring vector.
(dotimes (index (ring-length keshell-history-global-ring))
(push (ring-ref keshell-history-global-ring index) history))
;; Show them most-recent-first.
(setq history (nreverse history))))))
(let* ((cmds (split-string cmd "##")) ;; you need s.el lib
(tag (or (-&gt; cmds second)
"kshell"))
(buff-name (-&gt; tag s-chomp s-trim)))
(kshell cmd buff-name)))
</pre>
</div>
<p>
Here is the screen recording in action:
<img src="https://www.birkey.co/images/eshell-ido-interactive.gif" alt="eshell-ido-interactive.gif">
</p>

<p>
I am using F12 to invoke `krun` and my cross session eshell history
shows up in the minibuffer where I can use ido completion to select a
command that I can run. As an added benefit, above code allows one to
bring a eshell buffer with specific name by adding ##name at the end
of the command if one wants to have the command run in a dedicated
buffer.
</p>
<div class="taglist"><a href="https://www.birkey.co/tags.html">Tags</a>: <a href="https://www.birkey.co/tag-eshell.html">eshell</a> <a href="https://www.birkey.co/tag-emacs.html">emacs</a> </div></div>
<div id="postamble" class="status"><br><center>
<div style="display: inline-block; vertical-align:middle;"></div></div>
</body>
</html>
1 change: 1 addition & 0 deletions archive.html
Expand Up @@ -27,6 +27,7 @@
<div style="margin-bottom: 3ch;text-transform: none;"></div></div>
<div id="content">
<h1 class="title">Archive</h1>
<div class="post-date">10 Jul 2021</div><h2 class="post-title"><a href="https://www.birkey.co/2021-07-10-why-eshell-part-3.html">Why Eshell - Part 3</a></h2>
<div class="post-date">27 Jun 2021</div><h2 class="post-title"><a href="https://www.birkey.co/2021-06-27-why-eshell-part-2.html">Why Eshell? - Part 2</a></h2>
<div class="post-date">20 Jun 2021</div><h2 class="post-title"><a href="https://www.birkey.co/2021-06-20-why-eshell-part-1.html">Why Eshell? - Part 1</a></h2>
<div class="post-date">13 Jun 2021</div><h2 class="post-title"><a href="https://www.birkey.co/2021-06-13-let-and-binding-macros-in-clojure.html">Let and Binding macros in Clojure</a></h2>
Expand Down
Binary file added images/eshell-ido-interactive.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
109 changes: 74 additions & 35 deletions index.html
Expand Up @@ -27,6 +27,79 @@
<div style="margin-bottom: 3ch;text-transform: none;"></div></div>
<div id="content">

<div class="post-date">10 Jul 2021</div><h1 class="post-title"><a href="https://www.birkey.co/2021-07-10-why-eshell-part-3.html">Why Eshell - Part 3</a></h1>
<p>
If you have been following my `Why Eshell` series, you might be
wondering about interactive ido completion for eshell. Since Eshell
buffer is just a regular emacs buffer, we can compose few emacs
builtin functionalities to bend it to our command line work flow.
Following is all the code you need. Note that it is heavily commented
so you can understand what is happening.
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">(defun kshell-with-name (&amp;optional name)
;; creates an eshell buffer with `kshell' as the default name. Take
;; optional name to override
(let ((m (-&gt;&gt; (or name "kshell")
(format "*%s*"))))
(if (get-buffer m)
(pop-to-buffer m)
(progn
(eshell)
(rename-buffer m)))))

(defun kshell (&amp;optional cmd buff-name send-input)
;; interactive fn that you can call via M-x or hotkey. It detects
;; current project root to start eshell buffer if no `buff-name' is
;; given. You can control how the `cmd` gets insert only or insert
;; and executed using `send-input` flag. Ex. Useful for further
;; editing.
(interactive)
(let ((dir (projectile-project-root))) ;; you need projectile
(if buff-name
(kshell-with-name buff-name)
(kshell-with-name))
(eshell/clear-scrollback)
(insert (format "cd %s" (or dir "~/")))
(eshell-send-input)
(insert (format "%s" cmd))
(when send-input (eshell-send-input))))

(defun krun (cmd)
;; eshell command history with ido completion. Assign it to a hot
;; key say, F12 and you will get a search-able command history that
;; you can execute just by doing ido interactive search.
(interactive
(list
(ido-completing-read
"Enter cmd to run (append ##name for buffer name): "
(let ((history nil))
;; We have to build up a list ourselves from the ring vector.
(dotimes (index (ring-length keshell-history-global-ring))
(push (ring-ref keshell-history-global-ring index) history))
;; Show them most-recent-first.
(setq history (nreverse history))))))
(let* ((cmds (split-string cmd "##")) ;; you need s.el lib
(tag (or (-&gt; cmds second)
"kshell"))
(buff-name (-&gt; tag s-chomp s-trim)))
(kshell cmd buff-name)))
</pre>
</div>
<p>
Here is the screen recording in action:
<img src="https://www.birkey.co/images/eshell-ido-interactive.gif" alt="eshell-ido-interactive.gif">
</p>

<p>
I am using F12 to invoke `krun` and my cross session eshell history
shows up in the minibuffer where I can use ido completion to select a
command that I can run. As an added benefit, above code allows one to
bring a eshell buffer with specific name by adding ##name at the end
of the command if one wants to have the command run in a dedicated
buffer.
</p>
<div class="taglist"><a href="https://www.birkey.co/tags.html">Tags</a>: <a href="https://www.birkey.co/tag-eshell.html">eshell</a> <a href="https://www.birkey.co/tag-emacs.html">emacs</a> </div>
<div class="post-date">27 Jun 2021</div><h1 class="post-title"><a href="https://www.birkey.co/2021-06-27-why-eshell-part-2.html">Why Eshell? - Part 2</a></h1>
<p>
Among many reasons of why I use eshell as my main terminal, I listed
Expand Down Expand Up @@ -281,41 +354,7 @@
is a classic. If you are planning to attend Strange Loop, remember to
say hello and thank her for it.
</p>
<div class="taglist"><a href="https://www.birkey.co/tags.html">Tags</a>: <a href="https://www.birkey.co/tag-books.html">books</a> </div>
<div class="post-date">27 Mar 2021</div><h1 class="post-title"><a href="https://www.birkey.co/2021-03-27-less-is-more-literally.html">less is literally more</a></h1>
<p>
As an Emacs user, your muscle memories constantly remind you of
certain behavior of it when you had to use other Unix tools. I was
recently viewing a large file using <b>less</b> and searched for
<b>ErrorCode</b> by just typing <b>errorcode</b> and surprised to find that it
did not find any match. Then, I searched by typing <b>ErrorCode</b> and it
did find a match containing the word, which reminded me of the fact
that <b>less</b> by default is case sensitive. I then set out to find if I
can tell <b>less</b> to ignore case by reading man pages. I am pleasantly
surprised to read following:
</p>
<div class="org-src-container">
<pre class="src src-bash">-i or --ignore-case
Causes searches to ignore case; that is, uppercase and lowercase
are considered identical. This option is ignored if any upper-
case letters appear in the search pattern; in other words, if a
pattern contains uppercase letters, then that search does not
ignore case.
</pre>
</div>
<p>
That is exactly how Emacs isearch behaves by default. I added
following alias to my bash config to make above the default for less.
</p>
<div class="org-src-container">
<pre class="src src-bash">alias less='less -i'
</pre>
</div>

<p>
Once again, less is <b>literally</b> more and you could do more using less.
</p>
<div class="taglist"><a href="https://www.birkey.co/tags.html">Tags</a>: <a href="https://www.birkey.co/tag-shell.html">shell</a> </div><div id="archive">
<div class="taglist"><a href="https://www.birkey.co/tags.html">Tags</a>: <a href="https://www.birkey.co/tag-books.html">books</a> </div><div id="archive">
<a href="https://www.birkey.co/archive.html">Other posts</a>
</div>
</div>
Expand Down
68 changes: 68 additions & 0 deletions posts/2021-07-10-why-eshell-part-3.org
@@ -0,0 +1,68 @@
#+title: Why Eshell - Part 3
#+date: <2021-07-10 10:18>
#+filetags: eshell emacs

If you have been following my `Why Eshell` series, you might be
wondering about interactive ido completion for eshell. Since Eshell
buffer is just a regular emacs buffer, we can compose few emacs
builtin functionalities to bend it to our command line work flow.
Following is all the code you need. Note that it is heavily commented
so you can understand what is happening.
#+begin_src emacs-lisp
(defun kshell-with-name (&optional name)
;; creates an eshell buffer with `kshell' as the default name. Take
;; optional name to override
(let ((m (->> (or name "kshell")
(format "*%s*"))))
(if (get-buffer m)
(pop-to-buffer m)
(progn
(eshell)
(rename-buffer m)))))

(defun kshell (&optional cmd buff-name send-input)
;; interactive fn that you can call via M-x or hotkey. It detects
;; current project root to start eshell buffer if no `buff-name' is
;; given. You can control how the `cmd` gets insert only or insert
;; and executed using `send-input` flag. Ex. Useful for further
;; editing.
(interactive)
(let ((dir (projectile-project-root))) ;; you need projectile
(if buff-name
(kshell-with-name buff-name)
(kshell-with-name))
(eshell/clear-scrollback)
(insert (format "cd %s" (or dir "~/")))
(eshell-send-input)
(insert (format "%s" cmd))
(when send-input (eshell-send-input))))

(defun krun (cmd)
;; eshell command history with ido completion. Assign it to a hot
;; key say, F12 and you will get a search-able command history that
;; you can execute just by doing ido interactive search.
(interactive
(list
(ido-completing-read
"Enter cmd to run (append ##name for buffer name): "
(let ((history nil))
;; We have to build up a list ourselves from the ring vector.
(dotimes (index (ring-length keshell-history-global-ring))
(push (ring-ref keshell-history-global-ring index) history))
;; Show them most-recent-first.
(setq history (nreverse history))))))
(let* ((cmds (split-string cmd "##")) ;; you need s.el lib
(tag (or (-> cmds second)
"kshell"))
(buff-name (-> tag s-chomp s-trim)))
(kshell cmd buff-name)))
#+end_src
Here is the screen recording in action:
https://www.birkey.co/images/eshell-ido-interactive.gif

I am using F12 to invoke `krun` and my cross session eshell history
shows up in the minibuffer where I can use ido completion to select a
command that I can run. As an added benefit, above code allows one to
bring a eshell buffer with specific name by adding ##name at the end
of the command if one wants to have the command run in a dedicated
buffer.
82 changes: 81 additions & 1 deletion rss.xml
Expand Up @@ -4,7 +4,87 @@
<title><![CDATA[BirkeyCo]]></title>
<description><![CDATA[BirkeyCo]]></description>
<link>https://www.birkey.co/</link>
<lastBuildDate>Sun, 27 Jun 2021 08:59:35 -0700</lastBuildDate>
<lastBuildDate>Sat, 10 Jul 2021 11:16:30 -0700</lastBuildDate>
<item>
<title><![CDATA[Why Eshell - Part 3]]></title>
<description><![CDATA[
<p>
If you have been following my `Why Eshell` series, you might be
wondering about interactive ido completion for eshell. Since Eshell
buffer is just a regular emacs buffer, we can compose few emacs
builtin functionalities to bend it to our command line work flow.
Following is all the code you need. Note that it is heavily commented
so you can understand what is happening.
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">(defun kshell-with-name (&amp;optional name)
;; creates an eshell buffer with `kshell' as the default name. Take
;; optional name to override
(let ((m (-&gt;&gt; (or name "kshell")
(format "*%s*"))))
(if (get-buffer m)
(pop-to-buffer m)
(progn
(eshell)
(rename-buffer m)))))
(defun kshell (&amp;optional cmd buff-name send-input)
;; interactive fn that you can call via M-x or hotkey. It detects
;; current project root to start eshell buffer if no `buff-name' is
;; given. You can control how the `cmd` gets insert only or insert
;; and executed using `send-input` flag. Ex. Useful for further
;; editing.
(interactive)
(let ((dir (projectile-project-root))) ;; you need projectile
(if buff-name
(kshell-with-name buff-name)
(kshell-with-name))
(eshell/clear-scrollback)
(insert (format "cd %s" (or dir "~/")))
(eshell-send-input)
(insert (format "%s" cmd))
(when send-input (eshell-send-input))))
(defun krun (cmd)
;; eshell command history with ido completion. Assign it to a hot
;; key say, F12 and you will get a search-able command history that
;; you can execute just by doing ido interactive search.
(interactive
(list
(ido-completing-read
"Enter cmd to run (append ##name for buffer name): "
(let ((history nil))
;; We have to build up a list ourselves from the ring vector.
(dotimes (index (ring-length keshell-history-global-ring))
(push (ring-ref keshell-history-global-ring index) history))
;; Show them most-recent-first.
(setq history (nreverse history))))))
(let* ((cmds (split-string cmd "##")) ;; you need s.el lib
(tag (or (-&gt; cmds second)
"kshell"))
(buff-name (-&gt; tag s-chomp s-trim)))
(kshell cmd buff-name)))
</pre>
</div>
<p>
Here is the screen recording in action:
<img src="https://www.birkey.co/images/eshell-ido-interactive.gif" alt="eshell-ido-interactive.gif">
</p>
<p>
I am using F12 to invoke `krun` and my cross session eshell history
shows up in the minibuffer where I can use ido completion to select a
command that I can run. As an added benefit, above code allows one to
bring a eshell buffer with specific name by adding ##name at the end
of the command if one wants to have the command run in a dedicated
buffer.
</p>
<div class="taglist"><a href="https://www.birkey.co/tags.html">Tags</a>: <a href="https://www.birkey.co/tag-eshell.html">eshell</a> <a href="https://www.birkey.co/tag-emacs.html">emacs</a> </div>]]></description>
<category><![CDATA[eshell]]></category>
<category><![CDATA[emacs]]></category>
<link>https://www.birkey.co/2021-07-10-why-eshell-part-3.html</link>
<pubDate>Sat, 10 Jul 2021 10:18:00 -0700</pubDate>
</item>
<item>
<title><![CDATA[Why Eshell? - Part 2]]></title>
<description><![CDATA[
Expand Down

0 comments on commit 6332a95

Please sign in to comment.