This article is not about
Emacs wrapper around a your OS's shell REPL, nor is it
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
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, then
Ctrl-Dto be rid of the window.
I do this as an Emacs user, but in a slightly different way.
Long-term, per-project terminals
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
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.
While in the
dired buffer, several single-key
commands are available to you:
g— will run
ls -l, refreshes the current view so you can see what files are available.
i— when the cursor is over a directory, calls
ls -lon that directory and appends the output of it to the
diredtext buffer. The
gcommand will refresh these sub-directories as well.
C-M-p— navigate the cursor to the next/previous subdirectory entry appended by the
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.
<Enter>— when the cursor is over a file, edits that file. This is like running
vimon a file in the current directory.
o— is similar to
fbut will also split the screen into two windows and edits the file in the new split window, sort of like running
tmux 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 like
tar xzf. If it is a script, you can also run
pythonon the file, output is captured in a buffer called
*Async shell command*.
rmon the file under the cursor
chmodon the file under the cursor
Emacs provides a nice wrapper around the
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
less but with hyperlinks
to jump to the search results.
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
cmake. It is similar to
& 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
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
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 like
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 do
C-x C-sin the temporary buffer to save the output to a file, or
C-x C-kto discard it. Note that this command launches the child process with the current working directory set to the currently focused
direddirectory, or the parent directory of the currently focused file.
M-x term— best for use with a command like
mpv, because the
M-x termcommand does terminal emulation, and can handle the ANSI terminal codes for text coloring, and responds to interactive key presses, like for pausing/resuming playback in
mpv. I use this with
htopoften 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 man— is a wrapper around the CLI
M-x manprompts 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 of
manjust as the
lesscommand would do.
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.