(Emacs)~eshell gets some love

I really like Eshell.  Fanboy a bit about it in my configuration, and
describe its true abilities.  Further split up the config so it's a
bit easier to read.
This commit is contained in:
2022-09-16 17:07:47 +01:00
parent 6c99a8a1d2
commit 3b5ea1834d

View File

@@ -1654,36 +1654,55 @@ xwidget."
(xwidget-webkit-browse-url (concat "https://" engine "/?q=" query)))))
#+end_src
** Eshell
Eshell is the integrated shell environment for Emacs. Though it isn't
necessarily *the best* shell, it really suits the 'integrated
computing environment' moniker that Emacs gets.
*** Why Eshell?
Eshell is the integrated shell environment for Emacs. I argue that it
is the best shell/command interpreter to use in Emacs.
It may be argued that Emacs integrates within itself many of the
functionalities that one would use within a shell or terminal. Stuff
like compilation, file management, large scale text manipulation could
be done through Emacs' own tools (~compile~, ~dired~ and ~occur~ come
to mind). However, I'd argue that eshell's greatest ability comes from
it's separation (or perhaps better phrased, *integration*) of two
'parsers': the Lisp parser and the Shell parser. With these parsers
you can mix and match at will for use in the shell, which grants
greater power than many shells I know of.
Eshell is unlike the alternatives in Emacs as it's a /shell/ first,
not a terminal emulator. It has the ability to spoof some aspects of a
terminal emulator (through the shell parser), but it is NOT a terminal
emulator.
Setup a function that /toggles/ the eshell window rather than just
opening it via ~+dx/toggle-buffer~. Along with that setup the prompt
so it looks a bit nicer and add pretty symbols to eshell.
I'd say the killer benefits of eshell (which would appeal to Emacs
users) are due to eshell being written in Emacs lisp:
- incredible integration with Emacs utilities (such as ~dired~,
~find-file~, any read functions, to name a few)
- very extensible, easy to write new commands which leverage Emacs
commands as well as external utilities
- agnostic of platform: "eshell/cd" will call the underlying change
directory function for you, so commands will (usually) mean the same
thing regardless of platform
- this means as long as Emacs runs, you can run eshell
However, my favourite feature of eshell is the set of evaluators that
run on command input. Some of the benefits listed above come as a
result of this powerful feature. These evaluators are describe below.
Lisp evaluator: works on braced expressions, evaluating them as Lisp
expressions. Any returned objects are printed. This makes eshell an
Emacs Lisp REPL!
External evaluator: works within curly braces, evaluating them via
some external shell process (like sh). This makes eshell a (dumb)
terminal emulator!
The alias evaluator is the top level evaluator. It is the main
evaluator for each expression given to eshell. When given an
expression it tries to evaluate it by testing against these conditions
(going to the next if it doesn't find it):
- it's an alias defined by the user or in the ~eshell/~ namespace of
functions (simplest evaluator)
- it's some form of lisp expression (lisp evaluator)
- it's an external command (bash evaluator)
Essentially, you get the best of both Emacs and external shell
programs *ALL WITHIN* Emacs for free.
*** Eshell bindings
Bind some evil-like movements for easy shell usage, and a toggle
function to pull up the eshell quickly.
#+begin_src emacs-lisp
(use-package eshell
:commands +shell/toggle-shell
:display
("\\*e?shell\\*" ; for general shells as well
(display-buffer-at-bottom)
(window-height . 0.25))
:pretty
(eshell-mode-hook
("lambda" . "λ")
("numberp" . "")
("t" . "")
("nil" . "Ø"))
:commands +shell/toggle-eshell
:general
(leader
"tt" #'+shell/toggle-eshell)
@@ -1704,6 +1723,40 @@ so it looks a bit nicer and add pretty symbols to eshell.
(recenter))
"k" #'eshell-kill-process))))
:config
(+oreo/create-toggle-function
+shell/toggle-eshell
"*eshell*"
eshell))
#+end_src
*** Eshell pretty symbols and display
Pretty symbols and a display record.
#+begin_src emacs-lisp
(use-package eshell
:pretty
(eshell-mode-hook
("lambda" . "λ")
("numberp" . "")
("t" . "")
("nil" . "Ø"))
:display
("\\*e?shell\\*" ; for general shells as well
(display-buffer-at-bottom)
(window-height . 0.25)))
#+end_src
*** Eshell variables and aliases
Set some sane defaults, a banner and a prompt. The prompt checks for
a git repo in the current directory and provides some extra
information in that case (in particular, branch name and if there any
changes that haven't been committed).
Also ~eshell/goto~, which is actually a command accessible from within
eshell (this is because ~eshell/*~ creates an accessible function
within eshell with name ~*~). ~eshell/goto~ makes it easier to change
directories by using Emacs to provide an interface (which is a faster
loop than ~cd ..; ls -l~).
#+begin_src emacs-lisp
(use-package eshell
:config
(defun +eshell/get-git-properties ()
(let* ((git-branch (shell-command-to-string "git branch"))
(is-repo (string= (substring git-branch 0 1) "*")))
@@ -1716,7 +1769,6 @@ so it looks a bit nicer and add pretty symbols to eshell.
"×"
"")
">"))))
(setq eshell-cmpl-ignore-case t
eshell-cd-on-directory t
eshell-banner-message (concat (shell-command-to-string "figlet eshell") "\n")
@@ -1731,10 +1783,9 @@ so it looks a bit nicer and add pretty symbols to eshell.
"λ ")))
eshell-prompt-regexp "")
(+dx/create-toggle-function
+shell/toggle-eshell
"*eshell*"
eshell))
(defun eshell/goto (&rest args)
"Use `read-directory-name' to change directories."
(eshell/cd (list (read-directory-name "Enter directory to go to:")))))
#+end_src
** Elfeed
Elfeed is the perfect RSS feed reader, integrated into Emacs