Thoughts on Perl and Emacs, technology and writing

A Simple Emacs Shortcut – Duplicate Line

If there is something you find yourself doing over and over again in emacs, you can create a shortcut. For example, something I find myself doing repeatedly is duplicating a line and making a modification on the second line.

intv1 = 1;
intv2 = 2;

The way I used to do this is:

I moved to the beginning of the line

I set the marker

I moved to the end of the line

I copied the marked region

I pressed enter

and finally I yanked the copied line

There may be a quicker way, even in vanilla emacs. However, this doesn’t take long, but it is still better to have it available with a single keypress.

“Copy characters from previous nonblank line, starting just above point.
Copy ARG characters, but not past the end of that line.
If no argument given, copy the entire rest of the line.
The characters copied are inserted in the buffer before point.”

@maziran – I know about keyboard macros and use them quite extensively if you’re talking about the ones using C-x ( … C-x ). I think this solves a different problem though: making multiple similar edits within one session rather than a few similar edits across multiple different sessions. That is unless there is a way to store keyboard macros between invocations of emacs. Even then, I don’t see the benefit over a short interactive defun such as I described in the post.

@thomas11 & Dan Lewis – I don’t like setting kill-whole-line, but that is a neat trick with yanking twice, thanks. However, I think I still like having the shortcut as C-c d as it is even quicker and I use this so frequently the 0.2s saving adds up. I’ve also added back-to-indentation to duplicate-current-line which ties in well with my normal usage.

@Dima – thanks for the fix. I’ll have to take a look at it later to see how it works. I had previously imagined a fix using (newline).

@Peter BARABAS – thanks for the pointer to copy-from-above-command. It looks more robust than my version and should probably be added in place of copy-region-as-kill. There are a lot of useful functions in the .el files that aren’t loaded in at start-up so I should probably take a look at these at some point.

I have a similar command I bound to M-o which I use a lot. It is special because it also increments numbers, which is perfect for your example. When there are no numbers, it acts like other copy lines. It’s pretty old, so there is probably a better way to do it. It is:

I’ve used the code below for many years to do something similar. You kill whatever text you want to copy and call cbb-copy-kill-ring-regexp which prompts you for a regexp.
Then, you do cbb-yank-with-regexp, which yanks the copied text and prompts for replacement text.

;;;; copy-regexp.el
;;;; emacs lisp for kill/yank with regexp

(defvar cbb-copy-regexp-text nil
“Holds the text which will be used in the next yank-regexp operation”)

(defvar cbb-copy-regexp-regexp nil
“Holds the regexp which will be used in the next yank-regexp operation”)

You may modify the default copy and cut commands so that they act on the current line when no text is selected. That’s how SlickEdit and TextMate do it. To implement it in Emacs, see http://www.emacswiki.org/emacs/SlickCopy