views:

3861

answers:

18

I saw this same question for VIM and it has been something that I myself wanted to know how to do for Emacs. In ReSharper I use CTRL-D for this action. What is the least number of commands to perform this in Emacs?

A: 

well ive usually used:

Ctl-Space (set the mark)
move to end of line
Ctl-K kill line
Ctl-Y * 2 (yank the line back)

there may be a much better way though :P

Arthur Thomas
Do you mean: `C-a C-SPC C-e M-w RET C-y`?
J.F. Sebastian
yeah :) that's the precise way hehe.
Arthur Thomas
@Aurthor Thomas: Why kill? Why not simply copy?
Török Gábor
Arthur Thomas, it is spelled right there! haha. Ctl-W is fine too. He was just asking about a single line. wow.
Arthur Thomas
A: 

because i don't know, i'll start this round of golf with a slowball:

ctrl-k, y, y

Kevin Conner
A: 

ctrl-k, ctrl-k, (position to new location) ctrl-y

Add a ctrl-a if you're not starting at the beginning of the line. And the 2nd ctrl-k is to grab the newline character. It can be removed if you just want the text.

CJP
+11  A: 

Place cursor on line, if not at beginning do a CTRL-A, then:

CTRL-K

CTRL-K

CTRL-Y

CTRL-Y

epatel
I don't think the second C-Y is needed.
Bastien Léonard
it won't be a duplicate without
epatel
Use C-S-Backspace (kill-whole-line) instead of C-k. You don't have to screw with cursor position or killing the newline.
Cirno de Bergerac
+2  A: 

@[Kevin Conner]: Pretty close, so far as I know. The only other thing to consider is turning on kill-whole-line to include the newline in the C-k.

Allen
@Allen: remove `[` and `]` in `@[Kevin Conner]`
J.F. Sebastian
+3  A: 
C-a C-k C-k C-y C-y
sverrejoh
+12  A: 

I use

C-a C-SPACE C-n M-w C-y

which breaks down to

  • C-a: move cursor to start of line
  • C-SPACE: begin a selection ("set mark")
  • C-n: move cursor to next line
  • M-w: copy region
  • C-y: paste ("yank")

The aforementioned

C-a C-k C-k C-y C-y

amounts to the same thing (TMTOWTDI)

  • C-a: move cursor to start of line
  • C-k: cut ("kill") the line
  • C-k: cut the newline
  • C-y: paste ("yank") (we're back at square one)
  • C-y: paste again (now we've got two copies of the line)

These are both embarrassingly verbose compared to C-d in your editor, but in Emacs there's always a customization. C-d is bound to delete-char by default, so how about C-c C-d? Just add the following to your .emacs:

(global-set-key "\C-c\C-d" "\C-a\C- \C-n\M-w\C-y")

(@Nathan's elisp version is probably preferable, because it won't break if any of the key bindings are changed.)

Beware: some Emacs modes may reclaim C-c C-d to do something else.

Chris Conway
Hi! Be aware that if you have '(setq kill-whole-line t)' you will only need one 'C-k' (solution 2) as it already kills the newline together with the contents of the line. My prefered use of 'C-k'.Cheers,Daniel
danielpoe
+12  A: 

In addition to the previous answers you can also define your own function to duplicate a line. For example, putting the following in your .emacs file will make C-d duplicate the current line.

(defun duplicate-line()
  (interactive)
  (move-beginning-of-line 1)
  (kill-line)
  (yank)
  (open-line 1)
  (next-line 1)
  (yank)
)
(global-set-key (kbd "C-d") 'duplicate-line)
Nathan
+2  A: 

I have copy-from-above-command bound to a key and use that. It's provided with XEmacs, but I don't know about GNU Emacs.

`copy-from-above-command' is an interactive compiled Lisp function
-- loaded from "/usr/share/xemacs/21.4.15/lisp/misc.elc" (copy-from-above-command &optional ARG)

Documentation: 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.

Darron
As for version 23, it is the part of the standard GNU Emacs distribution as well.
Török Gábor
+4  A: 

Nathan's addition to your .emacs file is the way to go but it could be simplified slightly by replacing

  (open-line 1)
  (next-line 1)

with

  (newline)

yielding

(defun duplicate-line()
  (interactive)
  (move-beginning-of-line 1)
  (kill-line)
  (yank)
  (newline)
  (yank)
)
(global-set-key (kbd "C-d") 'duplicate-line)
pw
+1  A: 

something you might want to have in your .emacs is

(setq kill-whole-line t)

Which basically kills the entire line plus the newline whenever you invoke kill-line (i.e. via C-k). Then without extra code, you can just do C-a C-k C-y C-y to duplicate the line. It breaks down to

C-a go to beginning of line
C-k kill-line (i.e. cut the line into clipboard)
C-y yank (i.e. paste); the first time you get the killed line back; 
    second time gives the duplicated line.

But if you use this often then maybe a dedicated key binding might be a better idea, but the advantage of just using C-a C-k C-y C-y is you can duplicate the line elsewhere, instead of just below the current line.

polyglot
+1  A: 

The defaults are horrible for this. However, you can extend Emacs to work like SlickEdit and TextMate, that is, copy/cut the current line when no text is selected:

(transient-mark-mode t)
(defadvice kill-ring-save (before slick-copy activate compile)
  "When called interactively with no active region, copy a single line instead."
  (interactive
   (if mark-active (list (region-beginning) (region-end))
     (message "Copied line")
     (list (line-beginning-position)
           (line-beginning-position 2)))))
(defadvice kill-region (before slick-cut activate compile)
  "When called interactively with no active region, kill a single line instead."
  (interactive
   (if mark-active (list (region-beginning) (region-end))
     (list (line-beginning-position)
           (line-beginning-position 2)))))

Place the above in .emacs. Then, to copy a line, M-w. To delete a line, C-w. To duplicate a line, C-a M-w C-y C-y C-y ....

Marius Andersen
+2  A: 

I don't quite remember how line duplication works anywhere else, but as a former SciTE user I liked one thing about SciTE-way: it doesn't touch the cursor position! So all the recipies above weren't good enough for me, here's my hippie-version:

(defun duplicate-line ()
    "Clone line at cursor, leaving the latter intact."
    (interactive)
    (save-excursion
     (let ((kill-read-only-ok t) deactivate-mark)
      (toggle-read-only 1)
      (kill-whole-line)
      (toggle-read-only 0)
      (yank))))

Note that nothing gets actually killed in process, leaving marks and current selection intact.

BTW, why you guys so fond of jerking cursor around when there's this nice'n'clean kill-whole-line thingy (C-S-backspace)?

FraGGod
+5  A: 

My version of a function to duplicate a line that works nice with undo and doesn't mess with the cursor position. It was the result of a discussion in gnu.emacs.sources from November 1997.

(defun duplicate-line (arg)
  "Duplicate current line, leaving point in lower line."
  (interactive "*p")

  ;; save the point for undo
  (setq buffer-undo-list (cons (point) buffer-undo-list))

  ;; local variables for start and end of line
  (let ((bol (save-excursion (beginning-of-line) (point)))
        eol)
    (save-excursion

      ;; don't use forward-line for this, because you would have
      ;; to check whether you are at the end of the buffer
      (end-of-line)
      (setq eol (point))

      ;; store the line and disable the recording of undo information
      (let ((line (buffer-substring bol eol))
            (buffer-undo-list t)
            (count arg))
        ;; insert the line arg times
        (while (> count 0)
          (newline)         ;; because there is no newline in 'line'
          (insert line)
          (setq count (1- count)))
        )

      ;; create the undo information
      (setq buffer-undo-list (cons (cons eol (point)) buffer-undo-list)))
    ) ; end-of-let

  ;; put the point in the lowest line and return
  (next-line arg))

Then you can define CTRL-D to call this function:

(global-set-key (kbd "C-d") 'duplicate-line)
pesche
A: 

' I wrote my own version of duplicate-line, cause I don't want to screw up the killing ring.

  (defun jr-duplicate-line ()
    "EASY"
    (interactive)
    (save-excursion
      (let ((line-text (buffer-substring-no-properties
                        (line-beginning-position)
                        (line-end-position))))
        (move-end-of-line 1)
        (newline)
        (insert line-text))))
  (global-set-key "\C-cd" 'jr-duplicate-line)
Joyer
+1  A: 

Instead of kill-line (C-k) as in C-a C-k C-k C-y C-y use the kill-whole-line command:

C-S-Backspace
C-y
C-y

The advantages over C-k include that it does not matter where point is on the line (unlike C-k which requires being at start of the line) and it also kills the newline (again something C-k does not do).

Ray Vega
+1  A: 

I liked FraGGod's version, except for two things: (1) It doesn't check whether the buffer is already read-only with (interactive "*"), and (2) it fails on the last line of the buffer if that last line is empty (as you cannot kill the line in that case), leaving your buffer read-only.

I made the following changes to resolve that:

(defun duplicate-line ()
  "Clone line at cursor, leaving the latter intact."
  (interactive "*")
  (save-excursion
    ;; The last line of the buffer cannot be killed
    ;; if it is empty. Instead, simply add a new line.
    (if (and (eobp) (bolp))
        (newline)
      ;; Otherwise kill the whole line, and yank it back.
      (let ((kill-read-only-ok t)
            deactivate-mark)
        (toggle-read-only 1)
        (kill-whole-line)
        (toggle-read-only 0)
        (yank)))))
phils
A: 

With prefix arguments, and what is (I hope) intuitive behaviour:

(defun duplicate-line (&optional arg)
  "Duplicate it. With prefix ARG, duplicate ARG times."
  (interactive "p")
  (next-line 
   (save-excursion 
     (let ((beg (line-beginning-position))
           (end (line-end-position)))
       (copy-region-as-kill beg end)
       (dotimes (num arg arg)
         (end-of-line) (newline)
         (yank))))))

The cursor will remain on the last line. Alternatively, you might want to specify a prefix to duplicate the next few lines at once:

(defun duplicate-line (&optional arg)
  "Duplicate it. With prefix ARG, duplicate ARG times."
  (interactive "p")
  (save-excursion 
    (let ((beg (line-beginning-position))
          (end 
           (progn (forward-line (1- arg)) (line-end-position))))
      (copy-region-as-kill beg end)
      (end-of-line) (newline)
      (yank)))
  (next-line arg))

I find myself using both often, using a wrapper function to switch the behavior of the prefix argument.

And a keybinding: (global-set-key (kbd "C-S-d") 'duplicate-line)

Karthik