A few weeks ago I wrote about how I remapped yank to my command which allows to transform the yanked text. The whole setup – where I press C-y twice to trigger the transformation transient – has one drawback: I sometimes legitimately want to call yank twice in a row. This happens when I need to copy the current line and modify the copy so that I have two similar lines in a row. (I often need this when editing Ledger transactions, for example.) What I sometimes do in such a situation is basically a dance of C-a C-1 C-k C-y C-y.
It turns out I don’t need to. There is a duplicate-line command which does exactly what is says on the tin. The only issue is that it is not bound to any key by default. There is, however, one key which is ideally suited for it - C-x C-d. It is normally bound to list-directory, which I find completely useless given that Dired (C-x d) exists.
Before binding duplicate-line to C-x C-d, let’s poke around a bit. This command is almost completely superseded by its cousin duplicate-dwim, which duplicates the current line if the region is inactive and the current region otherwise. Also, there are two options which allow to tweak both commands’ behavior. If you set duplicate-line-final-position to 0 (the default), duplicating the line leaves the point where it was. Setting it to +1 or -1 moves it to the first and last duplicated line, respectively (of course duplicate-line and duplicate-dwim accept a prefix argument!). The duplicate-region-final-position option works in a similar way.
(setq duplicate-line-final-position 1) (setq duplicate-region-final-position 1) (bind-key "C-x C-d" #'duplicate-dwim)
That’s not the end of the story, though. While looking around in the file where these commands are defined (lisp/misc.el), I found a few more interesting ones. One of them is copy-from-above-command. I’m not sure how useful it is (and what to bind it to in case I find a use for it), but it’s there if you need it. As its docstring says, it copies characters from the line above, starting above point and until the end of that line. (A prefix argument limits the maximum number of characters copied.) There is zap-up-to-char which works like zap-to-char but does not delete the character it zaps to. There are forward-to-word and backward-to-word, which work very similarly to forward-word and backward-word, but leave the point at the opposite end of the words they move to (so for example forward-to-word moves the point forward until it gets at the beginning of a word). There are a few more, but these I find the most interesting. Maybe I’ll bind them some day – but even if not, they might come in handy with M-x or in Elisp code one day.
That’s it for this time, see you next week!