Tips and tricks for the fledgling Emacs user

Notes from my journey through the manual
The iconic Superman emblem, but instead of an 'S' in the center, it's the Emacs 'E'.

Yup. I did it. I finally read the f*cking manual.

Whenever I have gone looking for the Emacs equivalent of Drew Neil’s amazing Practical Vim1, I have always found people recommending reading the Emacs manual, saying how good it is. For the longest time I put it off, and I was on the verge of ordering Mickey Petersen’s Mastering Emacs, which I also often see mentioned, when I decided that I should just bite the bullet and at least start with the manual. It can’t be that much of an undertaking, right? … right?

Wrong.

Coming into 2020, I decided that I’d get through the manual by the end of January. I had no idea how much content was in there. Throughout the first 30 days of 2020 I sunk hour upon hour upon hour into this collection of text documents, assembled through many decades, until I finally found my way out, clothes tattered and torn, beard long and graying2, but my mind opened and enlightened.

What I want to share today is not the entire voyage, but rather just the high points that come to mind when I think back on my journey. Undoubtedly there will be things I’ve forgotten that should be here and things that are here that I should have forgotten, but such is the nature of human experiences. The best we can do is to just sit back and enjoy what we have.

I will be using the same notation for key bindings as Emacs does in the manual. Most characters are just represented as themselves, but some are special. Chords (or modified keys) are represented as modifiers connected to letters by a hyphen. A list of the modifiers and special keys used in this document is presented below. More information on characters and notation can be found in chapter 2 of the Emacs manual.

C and M
These upper case letters represent Control (your trusty control key) and Meta (usually alt), respectively. When used with other characters, they’re connected by a hyphen: C-a and C-M-a, for instance.
<RET>
The return (or enter) key
<ESC>
The escape key

In addition, note that M-x opens the execute-extended-command menu, wherein you can type in the name of a command. Thus, when you see something such as M-x other-window, that means that the text after M-x is the name of the command. To execute the command, press return.

The Emacs key bindings

Among the reasons to go through the manual, learning the ‘proper’ Emacs key bindings was actually pretty high up. It might seem trivial, but there’s been a number of times where I’ve ended up in a state that I just can’t navigate and don’t know how to get out of.

As someone who fell in love with the Vim way of editing, I came to Emacs through Spacemacs, which uses Evil mode to provide a very comfortable editing experience for Vim users. As such, I’ve already spent a considerable amount of time learning one very specific set of key bindings (and I love it every day). Why would I bother learning another?

For some time, I’ve been using ‘hybrid-mode’, giving me Vim key bindings in every mode except insert mode, where I switch to using Emacs key bindings. What I have discovered is that they both have their uses, and they shine in different ways. When navigating text, I feel much safer and much more agile in Vim’s normal mode, able to take leaps and bounds through the buffer, working on text as objects, confident that I won’t accidentally insert some text by a stray key press. However, when typing out text, having to exit insert mode and then type a command before entering insert mode again can be pretty tedious, and being able to make certain movements from that state just makes a lot of sense. A good example would be needing to go back to an earlier part of a line, delete some text, and then keep inserting at the end. In Vim, assuming we’re already in insert-mode:

And in Emacs

If my counting is correct, the Vim version has three more key presses than the Emacs version. Unless you’re into golfing, this probably doesn’t mean much to you (especially if d a w feels like a single movement to you), but to me, it feels (subjective, I know) like more work.

A surprising key binding that I’ve never really considered, but which Emacs has bound to C-M-v by default: scroll-other-window. If you have multiple windows open in a single frame, it’ll scroll one of the other windows, but lets you keep your focus (and your cursor) in your current window. There may be a way to target a specific window, but I found it most useful when having only two windows open. If you have more than two windows open, it’ll scroll the next window as defined by Emacs buffer ordering. From what I can tell, this is left to right, top to bottom. It’s the same order as when going through the windows by C-x o (other-window).

Naturally, coming from Vim, I think that the Vim way is the way for navigating text on a screen. Or at least I did. In fact, I was surprised to learn that Emacs has all the same facilities for navigating a buffer as Vim does, and it turns out that all the same movement patterns that I rely on in Vim are available in Emacs; they’re just bound to different keys.

There are a couple of editing patterns that I haven’t found the equivalent of yet, though (send me tips if you’ve got them!):

The equivalent of vim-surround
Yup, Evil has a function for it, and I’m sure you can write a function that will contain text, change surrounding delimiters to something else, or delete surrounding delimiters, but it’s not immediately available. That said, even in Vim, it’s a plugin, so maybe this shouldn’t count.
Delete to next search hit
In Vim (normal mode), a common way for me to operate on some text is to d / <search string> <RET> to delete up until the first occurrence of the search string. I haven’t found a way to do that in barebones Emacs. Emacs comes with the default binding of M-z as zap-to-char, which is almost what I want. However, rather than being able to input just a single character, I want to be able to input a search string and kill up to that point. It’d be similar to C-<SPC> C-s <search string> <RET> <DEL>, but without killing the actual search string (kill up to, not including), and it should be a single key chord. If I were to override the M-z binding, it’d be M-z <search string> <RET>.

Overall, though, I am surprisingly happy with Emacs’ movement keys, and while I don’t think I’ll be switching over completely just yet (or ever?), being able to navigate comfortably in either mode can only make things better.

The kill ring (chapter 12.2.1)

Of all the things I’ve learned, this is probably the one that’s given me the most bang for my buck. Whatever your preferred way of getting text into your kill ring (also known as the clipboard), once you’ve got it there, Emacs doesn’t just store the last entry, but rather your last 60 (by default) entries. The reason it’s called a ring is that you can cycle through your entries, and once you reach the end, you loop back around.

So when you paste (or yank) something into a buffer with C-y, you can then follow that up by using M-y to cycle through the kill ring. You can view the entire contents of the kill ring with C-h v kill-ring, though be warned: the kill ring is displayed as lisp code, so it may not read as plainly as you’d expect.

Side note: I wish Vim and Emacs could at least agree on the meaning of the word ‘yank’. Whether it means to copy something from the buffer (Vim) or to paste something into the buffer (Emacs), I don’t care. Just pick one.

The undo-stack (chapter 16.1)

Spacemacs uses the undo-tree-mode (see the Emacs wiki entry) to store buffer states in a change tree. This is really intuitive and lets you visualize your changes in a graphical model that maps pretty well onto my view of a set of changes. What I wasn’t aware of was that plain, ol’, vanilla Emacs comes with a pretty uncommon, but super-powerful undo history out of the box: instead of taking the view that history branchces after undoing a change, the default undo is more like a strictly linear timeline. When you undo a change, Emacs simply pushes this onto the history ‘stack’ as a new change. Thus, Emacs doesn’t have a traditional redo as such: it’s just another undo.

It’s a bit tricky to wrap your head around, but is really worth checking out. For context, here is an excerpt from the relevant chapter in the manual (link to web version):

To begin to undo, type ‘C-/’ (or its aliases, ‘C-_’ or ‘C-x u’). This undoes the most recent change in the buffer, and moves point back to where it was before that change. Consecutive repetitions of ‘C-/’ (or its aliases) undo earlier and earlier changes in the current buffer. If all the recorded changes have already been undone, the undo command signals an error.

Any command other than an undo command breaks the sequence of undo commands. Starting from that moment, the entire sequence of undo commands that you have just performed are themselves placed into the undo record. Therefore, to re-apply changes you have undone, type ‘C-f’ or any other command that harmlessly breaks the sequence of undoing; then type ‘C-/’ one or more times to undo some of the undo commands.

Alternatively, if you want to resume undoing, without redoing previous undo commands, use ‘M-x undo-only’. This is like ‘undo’, but will not redo changes you have just undone.

Bookmarks (chapter 13.8)

When reading through a document in several sittings, it’s useful to be able to jot down how far you’d gotten so that you can easily resume your reading. To this end, Emacs has a bookmarks system which was very useful when reading through the documentation. Similarly to how one might use bookmarks in a web browser, I’ve also bookmarked a number of documents to read later, so that I don’t forget. In addition to being useful for reading, I can also imagine it being useful if you often need to refer back to a specific file when programming, though registers (chapter 13), specifically File Registers (chapter 13.6), may be better suited to this.

Amusements (chapter 47)

The Amusements chapter covers a couple of really neat, mostly useless, tricks that you can do with Emacs. It lists a couple of built-in games, including classics such as Snake, Pong, and Tetris (turns out I’m horrible at that, by the way); text-based adventure games (dunnet) and Conway’s Game of Life simulation (life); ways to convert a region into morse code or NATO phonetic alphabet (morse-region and nato-region to encode, unmorse-region and denato-region to decode); ways to play with the display when idling (zone); and references to XKCD.

Glasses mode (chapter 26.9) and flipping tables

In addition to being able to encode a region as morse or the NATO phonetic alphabet, Emacs also comes with something known as glasses mode. This isn’t actually an amusement and is originally supposed to help make camelCased words easier to read by turning them into snake_cased words instead (or using any other separator that you want). This is all just presentational, so even though Emacs might display the identifier as my_Favorite_Identifier, it’ll get saved as myFavoriteIdentifier, and when you edit the text, the underlines aren’t actually there for you to edit.

Because you can change the separator, you can also use glasses mode to separate your identifiers with an arbitrary text string. My coworker suggested the ‘table flip’, and sure enough, Emacs is happy to comply:

becomes

and for fun, here it is in morse

Debugging (chapter 27.6)

This is something I want to get into at a later stage, and the manual makes it seem rather impressive. I’ve not used a debugger at all since switching to Emacs, and while I usually manage just fine, I find myself longing for one every so often.

Compilation buffers and jumping to the next error (chapter 27.2)

Somewhat related to debugging is compiling your programs in your editor. While a lot of text editors have built-in terminals that you can run things in, I haven’t often seen them also have the ability to jump to any errors that occurred during compilation, though I haven’t actually gone looking. I am told, however, that this is fairly commonplace in applications known traditionally as IDEs. Emacs, eager not to disappoint, comes with support for this built in.

When using Emacs for compiling a program, it will usually open a compilation buffer. If you have compilation errors, you can then use one of a number of keyboard shortcuts (my favorite is `M-g n`) to jump to the next compilation error. The best part is: this works from any buffer, even one not in compilation mode. In other words, if you have errors, you can jump through them sequentially without ever going back to the compilation buffer.

Indentation and programming indentation (chapter 24 and chapter 26.3)

There’s a number of cool indentation tricks listed in the indentation and the program indentation chapters, but I think the one I found that the most useful was for indenting languages derived from C. For a detailed explanation, check out this page on customizing indentation in C, C++, and Java, but the short version of it is that you can analyze the various syntactic parts of your program directly in your buffer, and then tell Emacs how it should indent a specific construct.

Org mode

What about org mode? You’d think that that was one of the best parts of Emacs, and that I’d have a ton of tips to share, right? Well, you’re probably right, but org mode comes with its own manual (another pretty massive text document), and I haven’t made my way through that one yet. Trust me, though: it’s on my list of must-reads this year. I’ll get to it later.


So that’s the first item on my SMART goal list completed. I’m not quite ready to start configuring Emacs from scratch, but it doesn’t feel that daunting anymore. Now: do I go to work on Kubernetes, or do I spend some extra time with org mode to get really comfy with Emacs?

Footnotes


  1. Seriously, if you’re into Vim and haven’t read it: I highly recommend you take the time to go through it. For a beginner it’s an absolute gem, and even for experienced vimmers, I’m sure there’s a good few tricks in there that you didn’t know about.

  2. I have actually found a grey hair in my beard this month (sshhh!) and I attribute that wholly to Emacs.


Use git to restore parts of a file

The restoration movement
The git logo with the 'git restore --patch' superimposed next to it.

One of my favorite, little-known git tricks is using the --patch option (-p for short) to affect only parts of a file when you’re adding, committing, or—as I recently found out—restoring.

Now some of you may be thinking ‘hold up! Restoring a file? What’s that?’ If you haven’t been following git development for a while (while a solid project, it’s not exactly the JS framework du jour), you’d be excused for not knowing about the two new git commands switch and restore. Introduced in git 2.23.0 (released in August 2019), these two commands were introduced to offload the checkout command for switching branches and restoring files. As you may expect, switch allows you to switch branches (and create new ones in the same way as checkout -b by using switch -c), and restore takes over for restoring files from a previous commit.

git restore -p

While there is lots to be said about the new commands and all the options they accept, I advise you to go check out the official docs for switch and restore for that. This post is about using restore with the -p option, specifically.

Sometimes (read: quite often) when making changes to a file, you have some changes that you want to keep and some that you want to discard. In situations like this, there’s a number of ways to go about it. If the changes are ready to be staged or committed, you can use the -p option to pick the parts you want and then just restore the file afterwards. However, in the event that the changes you want aren’t quite ready just yet, and you don’t want to stage, restore, and unstage, you might want to consider using restore -p.

By default, restore -p brings up an interactive prompt that lists the differences between your working tree and the last commit, asking you in turn whether you want to discard each hunk. This way, if you have some changes in one part of the file that you don’t want to keep, you can discard those, but keep the rest. As per usual with the --patch option, you can also split hunks or edit them manually if you need to.

When not given any paths to act on, git restore -p will ask you about all your unstaged changes in all your files. To limit it to a specific file, supply a pathspec: git restore -p myfile.txt. The documentation says that ‘--patch can accept no pathspec and will prompt to restore all modified paths.’1, but when testing it out using git version 2.23.1, using pathspecs was no problem at all.

In addition to the default patch restoration functionality, some of the other notable options are:

-s <tree> / --source=<tree>
Use this option if you want to restore a file to a different commit than HEAD. What you pick as your source can be another branch, a commit hash, or something like HEAD~2. Without the --patch flag, this will change the entire file to reflect the state at that source.
-S / --staged
Not to be confused with the lowercase -s above, the -S option allows you to restore changes from the index (your staging area or ‘added files’). By default, restore only works on files in your work tree. Using this option will make it work only on files in your staging area. To act on both at once, supply both the -S and the -W (--worktree) options: git restore -SW.

Footnotes


  1. https://git-scm.com/docs/git-restore#Documentation/git-restore.txt---patch


feature(slice_patterns)

A welcome stabilization
A snippet of source code using the new subslice matching feature. Ferris is peeking in from the top right corner and there is a Rust logo in the bottom right corner.

Weeee!

About a week ago, there was an item in This Week in Rust (issue 320) that caught my eye under the Tracking Issues & PRs heading:

[disposition: merge] Stabilize #![feature(slice_patterns)] in 1.42.0.

Aww, yeah! I’ve been waiting for this for literal years, so you better believe that was a good day! I mentioned this in my Rust 2020 post as one of the things I’m the most excited to see this year, so now that it’s getting stabilized soon (2020-03-12), let’s make sure we’re prepared!

About slice patterns

Most of the information contained in this section can also be found in the RFC on GitHub. The RFC is very thorough and gives lots of examples, so go give it a read if you want to know more about the feature!

We’ve had some form of slice matching on stable Rust for a while now, but without this feature, the form of matching you can do is rather limited. With an array of a known length, you can destructure and match as you please, but for slices of an unknown length, you must provide a fallback because there is no way to cover all the potential cases in a match expression. Also, quite importantly: there is no way to bind variables to subslices. This feature finally opens the gates to subslice and subarray matching, mitigating both the above issues, and making slice patterns immensely more powerful.

Two flavors

There are two syntactic flavors for the new subslice patterns: one for when you want to bind a subslice to a variable, and one for when you just want to denote that there are elided elements. Both flavors use the .. pattern (referred to as a rest pattern) to match a variable number of elements. The number of elements matched depend on the length of the array or slice and the number of matching elements before and after in the match.

Matching without binding

Looking at the first flavor, matching without binding, we get introduced to the .. pattern straight away:

Remember that .. can match any number of elements, including 0. This means that the first pattern matches anything that has at least two items. You can also use the pattern without ‘delimiting’ it on both ends, such as if you wanted to implement these two functions for getting the first and last element of a slice:

Notice how both of these functions pick out a single element of the slice (first and last respectively) and ignore the rest. Because .. matches 0 or more elements, the first pattern in both functions matches slices with one or more elements.

Matching and binding a subslice

The other flavor lets you bind a subslice to a value, which takes slice patterns and cranks the power level up another notch or two. The binding is done using the @ operator.

Imagine for instance that we want to write a sum function. That could be done as such:

In the example above, if the slice is not empty, we take the first element, x, and add it to the result of summing the rest of the list, xs. With Rust already having a sum method on iterators, this function is pretty redundant, but it makes a good example of how to bind and use subslices.

Another example would be to get the middle element of a slice if the slice has an odd number of elements. If the slice is empty or has an even number of elements, return None:

Here we iterate through the slice from both sides, continuously picking off one element at the start and one element at the end. Whatever is left in the middle (if there are at least two elements) gets assigned to xs and used as input to another step through the function. Once we have either one or zero elements left, we have our answer.

Why this is a big deal

It might come across as somewhat strange that I’m so enthused about a feature that may seem rather small, but it’s one of those quality of life things that I find myself running into all the time. Being used to Haskell and their pattern matching behavior, I always forget how cumbersome it is to match on an arbitrary slice in Rust. Up until now, we’ve had the split_first method (and split_at) on slices, which I can never remember the name of, which returns an Option, and which doesn’t let you do arbitrary match-stuff (such as using match guards, for instance). The new slice_patterns feature is a major step up in that regard.

The other thing that I’m super jazzed about? Being able to match on the end of a slice. Not only can you pick off items from either end of the slice, but you can also make sure that the slice ends in a certain value or series of values.


In short, I think this is an amazing addition to stable Rust. Hats off to all the people that have made it possible. Now go read the RFC and look out for all the other cool stuff they’re talking about (arbitrarily nested OR patterns? Oh, my!).

First Prev Page 2 Next Last