Emacs has a reputation for being borderline unusable out of the box, of being bloated but somehow surprisingly bare.
This is largely a discoverability problem1. The solution the Internet has settled on seems to be “Emacs distributions” like Doom, Spacemacs or Prelude that glue together dozens (sometimes hundreds) of addons to deliver a batteries included, finely tuned and user-friendly experience from first launch. While it’s not for me, this does work great 2, and many of these packages will probably make their way into the default Emacs experience in due time.
But while modern features like built-in LSP support, faster syntax highlighting (through tree-sitter) and ligature support are still being debated in the development mailing list, the long running, slow moving train of Emacs has picked up many interesting passengers.
Emacs as shipped does a lot more than meets the eye, and external package functionality often partially replicates built in behavior.
Here is a list of useful features in emacs I use regularly that I don’t see mentioned or recommended often online. Guidelines I used to populate this list:
- No packages, stock Emacs only.
- No steep learning curves. Learn each feature in under two minutes or bust.
- No gimmicks. No doctor, tetris, snake, dunnet, zone or butterfly.
- Just the deltas. No commonly mentioned packages like flymake, doc-view, outline-minor-mode or eww/w3m. Nothing that Emacs brings up automatically or a nonspecific Google search gets you.
- Assume a modern Emacs, 26.3+.
The list is written in the language of Emacs’ conventions. If you’re new to Emacs, here’s some extra cognitive load for you:
|Emacs jargon||Modern parlance|
||Alt + x|
||Ctrl + x|
|Buffer||Contiguous chunk of text/data|
|Point||Cursor position in a buffer|
|Active Region||Text selection|
|Region||Text selection (not highlighted)|
|Face||Font, color and display properties|
OK? Let’s go.
Artist mode (
Turn Emacs into an Ascii art based paint program. Draw (poly-)lines, rectangles and ellipses. Fill or spray.
I’m not much of an (ascii) artist, but I do use
artist-mode to draw boxes when
writing documentation or READMEs.
The included pulse library provides functions to flash a region of text. The most useful general application is to flash the line the cursor is on as a navigational aid or accessibility feature.
As is the annoying case with many things Emacs though, it provides all the ingredients and lights the flame but leaves the cooking to you. Here’s a simple recipe:
(defun pulse-line (&rest _) "Pulse the current line." (pulse-momentary-highlight-one-line (point))) (dolist (command '(scroll-up-command scroll-down-command recenter-top-bottom other-window)) (advice-add command :after #'pulse-line))
Modify as needed. There’s more than one external package
(beacon) that does this and more, but
pulse is just fine.
Undo in region (
Limit your undoing to the active region:
There’s nothing to set up or run here. This is the default behavior of undo in Emacs.
Follow mode (
Most monitors are much wider than they are tall. Most text files are much longer than they are wide. That’s a problem.
follow-mode shows a contiguous buffer paginated across multiple windows. The
cursor flows from one window to the next.
Selective display (
If you code with rigid indentation, you can get a quick overview of your
set-selective-display. No mucking around with folding,
Call the command with the prefix argument set to the column to hide. Call without a prefix argument to disable.
Pretty symbols (
This one’s mainly for LaTeX users. Display unicode versions of math operators,
greek symbols and more.
M-x prettify-symbols-mode in a TeX buffer.
The equivalent in
M-x org-toggle-pretty-entities. Other major
modes will have to define the replacements explicitly to get this behavior.
Example with Python:
(add-hook 'python-mode-hook (lambda () (mapc (lambda (pair) (push pair prettify-symbols-alist)) '(;; Syntax ("def" . #x2131) ("not" . #x2757) ("in" . #x2208) ("not in" . #x2209) ("return" . #x27fc) ("yield" . #x27fb) ("for" . #x2200) ;; Base Types ("int" . #x2124) ("float" . #x211d) ("str" . #x1d54a) ("True" . #x1d54b) ("False" . #x1d53d) ;; Mypy ("Dict" . #x1d507) ("List" . #x2112) ("Tuple" . #x2a02) ("Set" . #x2126) ("Iterable" . #x1d50a) ("Any" . #x2754) ("Union" . #x22c3)))))
View mode (
Provide pager-like keybindings. Makes navigating read-only buffers a breeze.
Move down and up with
delete (backspace) or
S-SPC, half a page
down and up with
u, and isearch with
This is my preferred way to read code or documents as I can avoid chorded
commands. Note that
evil-mode doesn’t help here either, since paging is bound
To that end I just hook this into Prolific emacser Omar
Antolin Camarena points out a built-in way to use
view-mode in all read-only
buffers, including ones you set read-only with
(setq view-read-only t)
This is my favorite feature of the bunch, considering how much time I spend in Emacs reading things.
cycle-spacing command is more versatile than it appears. By default, it
cycles between deleting all whitespace around cursor but one, deleting all
whitespace and restoring whitespace. But with a negative argument, it deletes
all blank lines around the cursor. (Calling it with a negative argument is fast:
Hold down Meta and hit minus and space in sequence.)
Put together, it’s doing the job of (almost) three older commands:
delete-blank-lines!3 This opens up the
C-x C-o and
M-\ for more useful functions.
Indirect buffers (
One buffer. Two windows. Two states.
This one’s for outline/org users. Do you want to see an overview of your
document and the section you’re working on?
M-x make-indirect-buffer or
Here I clone an org buffer and narrow the original to get a makeshift TOC:
At this point we’re a few lines of elisp away from writing a
for org files!
But the possibilities are much larger, because as the manual puts it:
The text of the indirect buffer is always identical to the text of its base buffer; changes made by editing either one are visible immediately in the other. But in all other respects, the indirect buffer and its base buffer are completely separate. They can have different names, different values of point, different narrowing, different markers, different major modes, and different local variables.
Reproduce the look of your emacs buffer as a html file with CSS. This is either extremely useful or useless to you!
Here is the html-fontified version of the source file of this write-up.
DWIM commands (upcase, downcase and more4)
Modern versions of Emacs provide Do-What-I-Mean versions of various editing
commands: They act on the region when the region is active, and on an
appropriate semantic unit otherwise. Replace
downcase-dwim respectively, and you can safely eject
the bindings for
(global-set-key (kbd "M-u") 'upcase-dwim) (global-set-key (kbd "M-l") 'downcase-dwim) (global-set-key (kbd "M-c") 'capitalize-dwim)
DWIM is standard behavior for emacs commands even when it doesn’t say that in
query-replace, the list goes on. Check to see if your
frequently used commands DWYM.
Unit conversion in calc (
u c. And
' (quote) for algebraic entry:
calc does a lot more with units. You can simplify, define new unit conversions
and more. Hit
u ? to see your options.
Symbolic computation in calc (
We’re skirting the “learn each feature in under two minutes or bust” rule with this one, as it deserves its own write-up, or a perusal of the manual. The general interaction paradigm is simple, though.
Let’s find a Taylor expansion of the integral of the error function:
Access algebraic routines (root finding, symbolic manipulation) in calc under
a prefix. Indefinite integration is
a i, differentiation is
solving algebraic equations is
a S and so on. (Hit
Scroll lock mode (
What it says on the tin. Move the buffer instead of the cursor when navigating.
Just press the scroll lock key or
These are mentioned often, but rarely recommended. Most Emacs users find the idea of tabs in Emacs to be redundant, but will happily recommend window configuration registers, which provide similar functionality.
Tabs work great to separate projects, or work and email buffers. In principle this is equivalent to popping up a new frame and letting the window manager handle the separation, but on stacking window managers I find tabs to be much preferable.
Since there’s never one way to do something in Emacs, a secondary
tab-line-mode is available that adds tabs to each window instead of frame.
fido: Incremental completion systems
completion-styles: Supercharge completion in the minibuffer
rx: Visual regular expressions
orgtbl-mode: Easy table formatting everywhere
strokes-mode: Control emacs with mouse gestures
… and more.
Coupled with some antiquated defaults. I’m not holding my breath here. ↩︎
And no wonder, a staggering amount of work has gone into Doom/Spacemacs etc. Tens of thousands of man hours. ↩︎
Not quite, since
delete-blank-lineswill leave one newline untouched. ↩︎
There is of course also
capitalize-dwim. Many thanks to Zachary Kanfer, the author of all three DWIM commands, for reminding me of its existence! ↩︎
Unless you like working with inactive regions. In which case you’re probably an Emacs greybeard and you don’t need this write-up! ↩︎