Death to the Shell
I hate the Shell
— Howard Abrams
@howardabrams
Well, I kinda hate the Shell
As Emacsians, we have a love/hate relationship with shells.
- shell, term, ansi-term, eshell, vterm, oh my…
- Like
dired
, we have better options
Agenda
I have two shell-related itches to scratch related to both shell uses:
- Interactive Data transformations through pipes are good and bad.
- Automative Personally, I want to replace 20+ years of shell scripts with Emacs Lisp.
Work in Progress
This project is for tinkers only (at least, at this point).
Let’s Start with a Story
- Hey Howard, can you restart the Openstack service for me?
Uh, you mean, services?
for S in $(systemctl --all | grep openstack | sed 's/\.service.*//' | cut -c3-) do systemctl restart $S done
That was easy to bang out, right?
Converting data by chaining small executables is incredibly flexible.
Bad Parts of Pipes
The flow of data through pipes is inscrutable.
Similar to function calls:
a | b | c
→ (c (b (a)))
Good thing we can use an editor to do the real dirty work, eh?
$ systemctl --all > /tmp/all-services
$ emacsclient /tmp/all-services
$ systemctl restart $(cat /tmp/all-services)
Wait a minute…
Merging Shell Pipes and Emacs
In the shell, we use commands, editors, and scripts based on personal preference.
This flexibility gives a shell its power.
But Emacs has this same flexibility.
First Idea:
Transform data flows through pipes from command to command to Transform a buffer of data from function to function
Sending Data to Commands
Transforming data in an Emacs buffer is easy.
How do we use that data in the shell?
- As standard in to a command
- As a series of command line arguments (aka
xargs
) - Repeatedly run command with line as argument (aka
for
loop) - Copy data to clipboard
- Just to visually inspect it (aka
less
)
Demonstration: Piper
- Primarily a user interface
- Thin wrapper around existing Emacs functions
Steps:
- Cat
/proc/acpi/wakeup
- Pair it down to just the enabled device names
- Write each device back to
/proc/acpi/wakeup
Steps:
- Get a list of all services:
service --status-all
- Filter to just the service names.
- Get a description of each service.
Note: We can talk about a better name later. ☻
Summary
- Transforming data from standard in to standard out is better in an Emacs buffer
- Sending data to an executable can be improved:
for
loopsxargs
, etc.
- Any Lisp is better than Shell’s language:
- Emacs Lisp is pretty hacky, and that’s a good thing
- Calling Emacs functions is trivial and pretty flexible
- Making Emacs Lisp as your go to scripting language is pretty fun
Discussion
Some potential sources for inspiration:
- Should we come up with a memorable acronym?
- SEAS
- Stitching Emacs and Shell
- HORSE
- Howard’s Obvious Replacement of the Shell with Emacs
- https://en.wikipedia.org/wiki/List_of_bagpipers
- https://en.wikipedia.org/wiki/List_of_flautists
- something related to the https://en.wikipedia.org/wiki/Hermit_crab , which leaves its shell
- something related to the https://en.wikipedia.org/wiki/Pied_Piper_of_Hamelin
- something related to plumbing or pipefitting
- see if https://en.wikipedia.org/wiki/Piper triggers anything
- https://en.wikipedia.org/wiki/Gheorghe_Zamfir , pan flautist with a place in the popular consciousness
- translate “piper” to other languages:
- Scots gaelic: pìobaire
- Irish: píopaí
- Galician: gaiteiro
- Arabic: zamar, mizmari
(defun emacs-piper-presentation-title () (interactive) (demo-it-frame-fullscreen) (delete-other-windows) (find-file "/tmp/emacs-presentation-title-a.org") (demo-it-load-file "/tmp/emacs-presentation-title-b.org")) (defun emacs-piper-presentation-reset () (interactive) (setq piper--command-history '()) (setq history-delete-duplicates t) (add-to-history 'piper--command-history "cut -f1") (add-to-history 'piper--command-history "service --status-all")) (use-package demo-it :load-path "~/Other/demo-it" :config (demo-it-create :advanced-mode :single-window (demo-it-show-image "~/Downloads/emacs-piper-presentation-title.png" :none) (demo-it-presentation (buffer-file-name) 3 :both)))