Emacs as a shell
This article is not about shell-mode
, an
Emacs wrapper around a your OS's shell REPL, nor is it
about term-mode
, the Emacs terminal emulator. It is
about how Emacs is a shell in and of itself, and how it can replace
a CLI shell.
Why a CLI shell is so useful
CLI terminals are nice because you can access any one of hundreds, if not thousands, of functions on your computer system with just a few keystrokes. If you are a regular CLI user, you probably have a favorite terminal emulator, and use it in the following ways:
Long-term, per-project terminals — You probably keep at least one terminal window open for every project you work on, where you can quickly create or edit a file, or inspect the state of your project. You might have your editor open in this window most of the time.
Short-lived, one-time use terminals — You probably also have a key binding set in your window manager configuration to quickly open a fresh new terminal window so you can quickly run a command once, like
htop
,df -h
,ip addr
, some command to check the status of something on your computer system. You quickly open a terminal window, run the command, check want you need, thenCtrl-D
to be rid of the window.
I do this as an Emacs user, but in a slightly different way.
Long-term, per-project terminals
Start with dired
C-x d
— prompts for a directory path to
browse, then launches a dired
(I pronounce it
"Dir--ed"), the Emacs directory editor. I have
one dired
buffer open for every project I work on in
Emacs, and I switch to this buffer as the starting point for
anything I might do in the project I am working on.
dired
commands
While in the dired
buffer, several single-key
commands are available to you:
g
— will runls -l
, refreshes the current view so you can see what files are available.i
— when the cursor is over a directory, callsls -l
on that directory and appends the output of it to thedired
text buffer. Theg
command will refresh these sub-directories as well.C-M-n
andC-M-p
— navigate the cursor to the next/previous subdirectory entry appended by thei
command.C-u k
— delete the text display of a subdirectory (does not delete anything in the filesystem), the cursor must be on the green subdirectory header text for this to work.f
or<Enter>
— when the cursor is over a file, edits that file. This is like runningvim
on a file in the current directory.o
— is similar tof
but will also split the screen into two windows and edits the file in the new split window, sort of like runningtmux split-window 'exec vim ./filename'
, if your shell is always inside of a Tmux session.&
— prompt for a shell command to run on the file under the cursor. This is perfect for running commands likegzip
, ortar xzf
. If it is a script, you can also runbash
orpython
on the file, output is captured in a buffer called*Async shell command*
.D
— runsrm
on the file under the cursorM
— runschmod
on the file under the cursor
M-x find-grep
Emacs provides a nice wrapper around the find
and grep
shell programs. It calls these programs, but
captures and formats the output in a separate buffer that you can
more easily navigate with the cursor. It is like always piping the
output of grep
to less
but with hyperlinks
to jump to the search results.
M-x compile
This is a make-shift IDE tool to run a compiler on code in the
current directory. This will prompt you for a command to run, such
as make
or cmake
. It is similar to
pressing &
in the dired
buffer, but will
use regular expressions to find and highlight file and line numbers,
so if your compilation process discovers an error, you can navigate
to location of the error in the source code using the cursor or
mouse.
Browsing through source code
I wrote a more detailed walk-through comparing the specific
actions I would take when starting work on a new long-term project,
please refer to
the Browsing source
ccode
article.
Short-term, one-time-use terminals
You might be in the middle of your work, then realize you need to
run a command, such as htop
to what program is using
your CPU the most, or df -h
to check how much disk
space you have available. You could just launch a terminal emulator
to do this, but it is good to get into the habit of using Emacs
instead of a terminal emulator for this, since you never know when
the text output by this command might be something you want to copy
and paste elsewhere.
M-&
— best for a command likedf
,ip addr
, or some command that produces a non-interactive textual report. It prompts for a shell command to run, runs the command and captures it's output in a temporary buffer called*Async shell command*
. When the command finishes, you can doC-x C-s
in the temporary buffer to save the output to a file, orC-x C-k
to discard it. Note that this command launches the child process with the current working directory set to the currently focuseddired
directory, or the parent directory of the currently focused file.M-x term
— best for use with a command likehtop
ormpv
, because theM-x term
command does terminal emulation, and can handle the ANSI terminal codes for text coloring, and responds to interactive key presses, like for pausing/resuming playback inmpv
. I use this withhtop
often enough that I bind my own Emacs command to it:(global-set-key (kbd "C-c h t") (lambda () (term "htop")))
Note that Emacs also has a TOP-like tool built-in:
M-x proced
.M-x man
— is a wrapper around the CLIman
command. RunningM-x man
prompts you for a search term with tab completion so you don't have to know the name of the exact manual page you are looking for, it then captures the output ofman
just as theless
command would do.
Further Reading
EINVAL blog: "Emacs as a Shell" — Wojciech Siewierski had published an article of the very same name as this one only two years before me, you may find their explanation with screen captures easier to understand than my article.
Emacs for Professionals
This article is part of my Emacs for Professionals series, in which I explain in a few paragraphs how I perform a specific common task using Emacs in ways that people already familiar with command line tools and Linux shell scripting can quickly understand.