Add $OUTPUT and $LAST eshell variables
These contain the output from the last eshell command. Cool how easily I implemented this.
This commit is contained in:
parent
bcb014a9ef
commit
2a6302c43d
1 changed files with 72 additions and 0 deletions
|
@ -210,6 +210,78 @@ This allows us to replace some of our aliases with functions:
|
|||
(eshell-fn-on-files 'find-file-other-window 'find-file-other-window args))
|
||||
#+end_src
|
||||
We’ll leave the =e= alias to replace the =eshell= buffer window.
|
||||
** Last Results
|
||||
The [[https://github.com/mathiasdahl/shell-underscore][shell-underscore]] project looks pretty cool, where the =_= character represents a /filename/ with the contents of the previous command (you know, like if you were planning on it, you’d =tee= at the end of every command). An interesting idea that I could duplicate.
|
||||
|
||||
While diving into the =eshell= source code, I noticed that the special variable, =$$= can be used /sometimes/ as the output of the last command. For instance:
|
||||
#+begin_example
|
||||
$ echo "hello world"
|
||||
hello world
|
||||
$ echo $$
|
||||
hello world
|
||||
#+end_example
|
||||
However, what I would like is something like this to work:
|
||||
#+begin_example
|
||||
$ ls *.org(U)
|
||||
a.org b.org f.org
|
||||
$ rg "foobar" $$
|
||||
#+end_example
|
||||
|
||||
The problem /may/ be between calling Emacs functions versus external commands, as the =echo= works, but the call to =ls= doesn’t:
|
||||
#+begin_example
|
||||
$ ls *.org(U) b.txt
|
||||
a.org b.org f.org b.txt
|
||||
|
||||
$ echo Nam $$
|
||||
("Nam" nil)
|
||||
#+end_example
|
||||
|
||||
However, we could add a hook that runs /after/ every command to copy the output to a variables of our choosing:
|
||||
#+begin_src emacs-lisp
|
||||
(defvar OUTPUT ""
|
||||
"Contains the output from the last eshell command executed.")
|
||||
|
||||
(defvar LAST nil
|
||||
"Contains a list of elements from the last eshell command executed.")
|
||||
#+end_src
|
||||
|
||||
Why two variables? Well unlike the behavior of the original shell (and most of its descendents, like =bash=), =eshell= doesn’t automatically split on whitespace. For instance, =echo= called this way:
|
||||
#+begin_example
|
||||
$ echo a b *.txt
|
||||
("a" "b"
|
||||
("b.txt" "date today.txt"))
|
||||
#+end_example
|
||||
Is given a list of /three elements/: =a=, =b=, and a list of all files in the current directory with an =.org= extension. An interesting side-effect is that spaces in filenames are /often okay/. So we want =$OUTPUT= to contain the command’s output /as a string/, and we have, =$LAST= contains the same stuff, but separated by spaces, into a list. So, if we are passing the output from =ls= to =grep=, we would use =$LAST= to represent files.
|
||||
|
||||
The following function does the work of saving the output of the last command. We can get this because after every command, eshell updates two variables, [[elisp:(describe-variable 'eshell-last-input-end)][eshell-last-input-end]] (the start of the output), and [[elisp:(describe-variable 'eshell-last-output-start)][eshell-last-output-start]] (the end of the output):
|
||||
#+begin_src emacs-lisp
|
||||
(defun ha-eshell-store-last-output ()
|
||||
"Store the output from the last eshell command.
|
||||
Called after every command by connecting to the `eshell-post-command-hook'."
|
||||
(setq OUTPUT
|
||||
(s-trim
|
||||
(buffer-substring-no-properties eshell-last-input-end eshell-last-output-start)))
|
||||
(setq LAST
|
||||
(split-string (rx (one-or-more space)) OUTPUT)))
|
||||
#+end_src
|
||||
|
||||
Now we save this output after every command by adding it to the [[elisp:(describe-variable 'eshell-post-command-hook)][eshell-post-command-hook]]:
|
||||
#+begin_src emacs-lisp
|
||||
(add-hook 'eshell-post-command-hook 'ha-eshell-store-last-output)
|
||||
#+end_src
|
||||
|
||||
Success:
|
||||
#+begin_example
|
||||
$ ls *.org(U) b.txt
|
||||
a.org b.txt
|
||||
|
||||
$ rg Nam $LAST
|
||||
a.org
|
||||
8:Nam vestibulum accumsan nisl.
|
||||
|
||||
b.txt
|
||||
1:Nam euismod tellus id erat.
|
||||
#+end_example
|
||||
* Special Prompt
|
||||
Following [[http://blog.liangzan.net/blog/2012/12/12/customizing-your-emacs-eshell-prompt/][these instructions]], we build a better prompt with the Git branch in it (Of course, it matches my Bash prompt). First, we need a function that returns a string with the Git branch in it, e.g. ":master"
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
|
|
Loading…
Reference in a new issue