Hongchao Liu thinks that emacs is the “2D command-line interface”. Sure enough, I could do many things with the 2D command-line interface. However, there are still many things I prefer to use the 1D command-line interface, i.e. the Linux shell. Hate to admit, but I prefer to manage files with the Linux command line than the sometimes-cumbersome dired. “But that can well be my prejudice.”™
For a long time, I needed to find a good terminal emulator and settled with Kitty. But I use the boring gnome-terminal now.
One can also run shell inside emacs. Just talking about built-in ones, there are
eshell. Advanced emacs users tend to use eshell, probably because it can execute both shell and emacs lisp.
But I am not very excited by mixing shell and emacs lisp 1. Instead, I use vterm by Lukas Fürmetz et al. Because it is fast, no-BS, highly compatible, and exactly as advertised: “Using vterm is like using Gnome Terminal inside Emacs”. Unlike eshell, vterm respects my .zshrc configuration file. Some tricky interactive shell programs such as
less work, even hipster favorites such as
Installation was not straightforward. But with the currtent emacs 28, it is now super easy.
I have two bullet points on how to use vterm more joyfully.
Running vterm inside emacs, instead of a standalone terminal emulator, is usually for copying and pasteing (or using the emacs terminology: killing and yanking) text from and to other buffers. For
pasting yanking text to vterm, I recommand making
C-y (the usual
yank key combination) map to
(use-package vterm :bind (:map vterm-mode-map ("C-y" . vterm-yank)) )
copying killing text from vterm, it is a bit complicated. First, it is really 1D. And the cursor can really walk in one direction. The up and down arrow keys are used to look at command history in a shell. The orthodox emacs combinations,
next-line) also functions as arrow keys.
In order to kill text from vterm, one needs to switch on copy mode by pressing
M-x vterm-copy-mode (or
C-c C-t) to enable “vterm-copy-mode”. Then the cursor can be moved in two dimensions and the usual way of killing text works. After that, just
M-x vterm-copy-mode once again to go back to the default mode, i.e. “vterm-copy-mode” disabled.
Another issue is that some shell programs use the same key combinations of emacs. For whatever reasons, you might need to run
nano under vterm sometimes 2. You might find that you can’t quit
nano by pressing
C-x. It is because emacs intercepts your
C-x and thinks: “um… maybe you still want to press something, e.g.
There are actually two solutions. First solution is to use the crazy array of
vterm-send-* commands. In this example, you can press
M-x vterm-send-C-x. However, my preferred solution is to use the command
M-x vterm-send-next-key and then
But it can get tedious very quickly. I map
C-q to the command
vterm-send-next-key (I will talk about
C-q later, I promise), i.e.
(use-package vterm :bind (:map vterm-mode-map ("C-y" . vterm-yank) ("C-q" . vterm-send-next-key)) )
Therefore, I can just press
C-q C-x in this situation to quit. But, it can be more informative. I don’t like that
vterm-send-next-key doesn’t give me any visual clue that it is activated. I write myself a little command in emacs lisp.
(use-package vterm :init (defun vterm-send-next-key-verbose () (interactive) (progn (message "vterm-send-next-key enabled.") (vterm-send-next-key) )) :bind (:map vterm-mode-map ("C-y" . vterm-yank) ("C-q" . vterm-send-next-key-verbose)) )
C-q, I know the next key will not be captured by emacs but capturd by the program running inside vterm.
After talking about the terminal, I will talk about how / why I use the GUI version of emacs but not the terminal version. Also, how I fix some quirks.
Deep-learnest’s remark on Mastodon: “I recommend
M-x shell for sessions where you need to capture large outputs, or for long-lived interactive sessions in the shell. The ability to have an infinite log of easily accessible text that you can navigate in the regular emacs ways is very powerful and eventually grows on you. I only use vterm for applications that need a proper terminal (htop, btop, nvtop, …), but for everything else I much prefer the feeling of
shell is better in this case because the cursor is not walking in 1D (as vterm) but in 2D. Yanking and killing work the same way as a regular buffer.
Thank you, Deep-learnest!