camdez.com

Rule #1: There are no rules.

Emacs: Transpose-lines

| Comments

The command transpose-lines, bound to C-x C-t by default, is a standard Emacs workhorse. It exchanges the line point is on with the previous line. Because it also moves point down a line we can invoke it repeatedly to “drag” a line down:

1
2
3
4
5
6
one           two           two           two           two
two<          one           three         three         three
three   -->   three<  -->   one     -->   four    -->   four
four          four          four<         one           five
five          five          five          five<         one
                                                        <

This is particularly handy for reordering lists. We can also give it a numeric argument or a negative argument and these do what you’d expect (C-h f transpose-lines RET for details), transposing over distances or in reverse direction.

But what I did not know is that if invoked with a M-0 prefix, it will exchange the line point is in with the line mark is in, essentially allowing us to insert a line at an arbitrary location we had previously marked.

I have to say, this definitely beats my typical C-a C-k C-k (movement) C-y workflow, assuming I know the destination ahead of time.

Update: turns out I got a little excited and didn’t think through the details of what I was saying. The semantics of those two scenarios are different—M-0 C-x C-t swaps the two lines whereas the other simply inserts the killed line, but doesn’t move the line at point to where mark was. Mea culpa.

Here’s a quick-and-dirty function for your .emacs to get the behavior I claimed:

1
2
3
4
5
6
7
8
9
10
(defun move-line-to-point ()
  "Insert the line mark is in before the current line."
  (interactive "*")
  (save-excursion
    (exchange-point-and-mark)
    (beginning-of-line)
    (kill-whole-line)
    (exchange-point-and-mark)
    (beginning-of-line)
    (yank)))

Comments