Moving Text in Emacs

Charles Choi has another great Emacs post. It’s about Moving Text Elegantly in Emacs. The TL;DR is that Choi considers some elegant ways of moving various text objects forward and backwards. It’s really a generalization of the transpose-* functions. We all know about transpose-chars and transpose-words and some of us even remember that you can do the same with sentences. On my system, at least, transpose-sentences isn’t bound to any keys but I use it rarely enough that I don’t mind typing in the command. It’s easy to remember the name so I consider it part of my toolkit.

There’s also a transpose-sexps but it’s action is a bit more mysterious. When you’re in a Lisp buffer, it does just what you’d think it would but for other languages or text based buffers the situation is more complicated. In those cases the idea of an s-expression is replaced by the more general “balanced expression”. A balanced expression is something between matching delimiters like “”, [], <> and so on. Part of what makes things so complicated is that what those delimiters are depends on the buffer mode.

Choi’s idea is to use a combination of moving forward or backward over a text object and the transpose functions to create a series of functions to move those objects forward or backward over objects of the same type. He motivates this with the example

["a", "b", "c", "d"]

Suppose, he says, you want to move the "a" forward into the third position so that the list becomes

["b", "c", "a", "d"]

It’s easy to brute force that, of course, but if you have to do it repeatedly, it quickly becomes tedious. Choi creates a simple function using just forward-sexp and transpose-sexps that does this easily. He has several functions for moving various objects forward and backward.1

He also observes that these are seldom used routines and not worth remembering let alone binding a key sequence to. His solution is to add them to the Edit menu. That’s perfect because all you have to do is remember that they exist and can otherwise forget about them until you need them.

It’s a good post so take a look when you have a few minutes.

Footnotes:

1

If you want to experiment with the above example, be sure to do it in some sort of text buffer. In particular, it won’t work in the *scratch* buffer because that’s a Lisp buffer and its definition of “balanced expression” isn’t right for this example.

This entry was posted in General and tagged . Bookmark the permalink.