cosine.blue

Blog by Gregory Chamberlain.

Emacs Keeps Surprising Me

Some incredibly useful features built into Emacs that were right under my nose from day one.

History

Cover image: GNU Emacs logo featuring a red Gnu and blue text in a
cursive pen style

Emacs keeps surprising me. Though I've been using it regularly for about two years now, I am still discovering features and nuances that have been right under my nose since day one.

I'm not talking about writing your own Elisp. I'm not even talking about third-party packages. I'm talking about stock, built-in, everyday functionality that is right there when you open GNU Emacs for the first time, wondering what all the fuss is about.

There is so much there. It's overwhelming. Really, it's insane. Stuff you didn't think existed, stuff you didn't know was possible, stuff you don't expect to find, stuff you didn't think you needed, stuff you really really needed that one time but didn't know about or even think to look for, and stuff you always suspected might exist but hadn't looked into yet.

Sometimes it's a default key binding, however obscure, that has been waiting patiently under your fingers, hidden beneath the keyboard all this time, never before invoked (except perhaps by mistake). Sometimes it's a minor mode, or a unique tool for editing, or just a subtlety in the behaviour of a command you've already been using for months.

Most of these things are documented thoroughly in the manual, so it's not like they're deliberately hidden from us. It's just that there is such an abundance of features built into Emacs that they effectively must compete for our attention.

Inserting special characters

Recently I finally got around to looking in more detail at a feature I only vaguely knew of: input methods. I do not know why I waited until now to look into it but, as someone who is interested in languages, it was curiosity that eventually led me there.

Now, there are a couple of sections in the manual about input methods (22.3 and 22.4), and I'm sure they're great, but that was not how I went about learning this particular feature. No, I just dove straight in. What little I did know of input methods was only because I inadvertently hit C-\ from time to time, invoking toggle-input-method. I knew it had something to do with internationalisation but I had always hit C-g to get out of it and continue with whatever highly important task I was doing (such as M-x tetris). This time I hit TAB instead, revealing a screenful or two of completion candidates.

Among them were czech, arabic, japanese and many other languages and their related input methods. No surprises there. What caught my eye, though, were TeX and sgml. These are not spoken languages. These are methods for inserting all kinds of special characters—obscure diacritical marks, quote marks, superscript and subscript mathematical symbols, playing card suits, smileys, various shapes and arrows, and so on.

Input methods allow you to insert characters that you can’t type by typing a sequence of characters that you can type. For example, using the spanish-postfix input method, typing n~ produces ñ. C-h C-\ (describe-input-method) shows you all the sequences for a given input method.

Until now I had been using C-x 8 RET (insert-char) to insert special characters by name, if I could guess the name (was it SMALL LATIN LETTER ETH or LATIN SMALL LETTER ETH?). Suddenly I had a much smoother, less cumbersome way of doing the same thing.

This is a feature you can just use. There’s no Lisp to write or variables to tweak to make it usable. There’s no external package you have to install from MELPA. You hit C-\, choose your input method, and start writing.

My last article was about IPA (the International Phonetic Alphabet) and I had to write a lot of phonetic symbols like ə and ʧ. There I was going through Wiktionary, painstakingly copy-pasting symbols into Emacs while its ipa input method was right under my nose the whole time.

A few days later I discovered it. That’s what prompted me to write this article.

View and edit lines that match a pattern

grep is an old-school UNIX program for printing only the lines of a file that match a regular expression.

Emacs has a command called occur (M-s o), which does a similar thing for Emacs buffers. The matching lines are shown in the *Occur* buffer, which can be used to jump to the location in the source buffer where that match occurs.

What’s really cool is that you can edit the *Occur* buffer and any changes made there are reflected in the source buffer. You just hit e to begin editing and C-c C-c to apply the changes when you’re done. In that sense, it’s a bit like C-x n n (narrow-to-region) but for “multiple regions,” if you like.

As an example, let’s say I wanted to reword some of the headings in this article. I’m writing it in Markdown, so each heading is on its own line beginning with #. So I begin with M-s o ^# RET to have all the headings reproduced in the *Occur* buffer—not unlike a table of contents. In that buffer, I can use o or C-o to jump to that section in my article. I can also hit e to begin editing them. When I’m happy with my reworded headings, I can hit C-c C-c to apply the changes.

Occur is a built-in package. M-s o is a default global key binding. It’s right there from day one. No external packages or Elisp to copy and paste into your init file. Just vanilla Emacs.

Visualisation of whitespace

The annoying thing about editing whitespace is that you can’t see it. I mean, that’s kind of the point, but sometimes you need to know exactly where it is and how much of it is there. This is especially true for some programming languages where whitespace and indentation are significant to the compiler or interpretter.

The Emacs developers know this pain all too well, and that’s why we have whitespace-mode. It makes it abundantly clear where there are spaces, tabs and newline characters by highlighting them and denoting them with certain symbols—a middle dot (·) for spaces, a double chevron for tabs (»), a dollar sign ($) for newlines. The symbols shown can be changed or removed, of course—see whitespace-style and whitespace-display-mappings.

Trailing whitespace is made particularly obvious because it is highlighted in red. Lines longer than whitespace-line-column characters (80 by default) are highlighted in yellow. These colours may vary by theme.

I wouldn’t recommend keeping whitespace mode on at all times because it makes the rest of the text quite hard to read. I only enable it for a moment while I check for stray whitespace, or sometimes when editing tab-separated data.

Display buffer continuously over several windows

When I’m learning (or writing) a new piece of music, I like to have the notes (chords, tabs, lyrics, etc.) for the entire song shown at one time, if possible. This way I can play through it from start to finish without having to pause for scrolling.

Usually I set it up in a column layout to make the most of the horizontal screen space. Emacs is perfect for this because of its windowing capabilities combined with a minor mode called follow-mode. Follow mode shows adjacent screenfuls of the same buffer across multiple windows, like pages in a book.

It’s hard to explain, so maybe it’s best to try it for yourself—for example, by visiting this very page with M-x eww. Create a side-by-side split using C-x 3 (split-window-right), then do M-x follow-mode and try scrolling around. The window on the right shows the part of the buffer that immediately follows the part in the window on the left.

Undo only within a region

This feature is phenomenal and it’s actually enabled already because it’s just a nuance of the undo command. I don’t know of any other text editor that can do this. I believe Vim has “time travel” history which is cool in its own right, but not quite the same.

Emacs allows you to undo changes that happened in a particular region of the buffer, without undoing changes elsewhere across it. Typically that region will be a range of lines but it doesn’t have to be.

All you do is select the region of text in which the changes occured, then invoke undo as normal (e.g. C-/).

Again, this is something that was right under my nose and for months I had no idea Emacs could do this—I had never even wondered if it was possible; it simply didn’t occur to me.


To leave a comment, please send a plaintext email to ~chambln/public-inbox@lists.sr.ht and it will show up in my public inbox.