Duplicate current line or region in Emacs

What don’t you do to avoid studying for an exam? I found myself bored and wrote an Emacs Lisp function that duplicates the current line or region. The are probably lots of those out there, but here’s my version of it.

(defun duplicate-current-line-or-region (arg)
  "Duplicates the current line or region ARG times.
If there's no region, the current line will be duplicated. However, if
there's a region, all lines that region covers will be duplicated."
  (interactive "p")
  (let (beg end (origin (point)))
    (if (and mark-active (> (point) (mark)))
        (exchange-point-and-mark))
    (setq beg (line-beginning-position))
    (if mark-active
        (exchange-point-and-mark))
    (setq end (line-end-position))
    (let ((region (buffer-substring-no-properties beg end)))
      (dotimes (i arg)
        (goto-char end)
        (newline)
        (insert region)
        (setq end (point)))
      (goto-char (+ origin (* (length region) arg) arg)))))

Then bind a key to it. I use C-c d.

(global-set-key (kbd "C-c d") 'duplicate-current-line-or-region)

There are a few ways to use the function.

Duplicate line

Lets say you have this contents and you want to duplicate the second line.

1 class Foo
2   attr_accessor :bar
3 end

Put your cursor at line 2 and press C-c d. You should now have this:

1 class Foo
2   attr_accessor :bar
3   attr_accessor :bar
4 end

Duplicate region

Not lets try to duplicate a region.

1 class Foo
2   def to_s
3     ":#{bar}:"
4   end
5 end

Select the lines 2 to 4. Note that you don’t have to select the complete lines. It’s enough that some part of the first and last lines are selected.

Now press C-c d and the whole to_s method should be duplicated like this:

1 class Foo
2   def to_s
3     ":#{bar}:"
4   end
5   def to_s
6     ":#{bar}:"
7   end
8 end

Duplicate several times

Imagine you want to duplicate some line more than once. You could hit C-c d multiple times, but there’s a better way to do it.

1 <ul id="stuff-to-do">
2   <li>Clean the house</li>
3 </ul>

Put the cursor on line 2 and press (depending on how many duplicates you want) for example: M-5 C-c d or C-u 10 C-c d.

1 <ul id="stuff-to-do">
2   <li>Clean the house</li>
3   <li>Clean the house</li>
4   <li>Clean the house</li>
5   <li>Clean the house</li>
6 </ul>

blog comments powered by Disqus Back to Top

Fork me on GitHub