How do I duplicate a whole line in Emacs?

134

Solution 1

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.

Solution 2

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)

Solution 3

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

CTRL-K

CTRL-K

CTRL-Y

CTRL-Y

Solution 4

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)

Solution 5

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).

Share:
134

Related videos on Youtube

deadfish
Author by

deadfish

Updated on May 27, 2021

Comments

  • deadfish
    deadfish almost 3 years

    How can I fix my code under this text?

    //puncts = puncts ?? new List<Vector2>() { new Vector2(position.X, position.Y) };
    
    if (Vector2.Distance(position, puncts[indexpunkt] = puncts[indexpunkt]  ??  new Vector2(position.X, position.Y)   ) < 1)
                    indexpunkt++;
    

    Error:

    Error   1   Operator '??' cannot be applied to operands of type 'Microsoft.Xna.Framework.Vector2' and 'Microsoft.Xna.Framework.Vector2'
    

    I wish create new puncts if it is null and add first element to its list. Can I use operator ?? and how can I use it in if statement?

  • jfs
    jfs over 15 years
    @Allen: remove [ and ] in @[Kevin Conner]
  • jfs
    jfs over 15 years
    Do you mean: C-a C-SPC C-e M-w RET C-y?
  • Arthur Thomas
    Arthur Thomas over 15 years
    yeah :) that's the precise way hehe.
  • danielpoe
    danielpoe over 15 years
    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
  • Bastien Léonard
    Bastien Léonard almost 15 years
    I don't think the second C-Y is needed.
  • Jitendra Vyas
    Jitendra Vyas almost 15 years
    it won't be a duplicate without
  • Rahul Das
    Rahul Das almost 15 years
    Use C-S-Backspace (kill-whole-line) instead of C-k. You don't have to screw with cursor position or killing the newline.
  • viam0Zah
    viam0Zah almost 14 years
    @Aurthor Thomas: Why kill? Why not simply copy?
  • viam0Zah
    viam0Zah almost 14 years
    As for version 23, it is the part of the standard GNU Emacs distribution as well.
  • Arthur Thomas
    Arthur Thomas almost 14 years
    Arthur Thomas, it is spelled right there! haha. Ctl-W is fine too. He was just asking about a single line. wow.
  • qmega
    qmega over 13 years
    It doesn't seem to be in my version. Does something have to be loaded? My version is GNU Emacs 23.2.1 (amd64-portbld-freebsd8.1) of 2010-11-14 on [host clipped].
  • ptrn
    ptrn almost 13 years
    Excellent! The undo and cursor position feature makes this one the best. Thanks!
  • Dmitry
    Dmitry over 12 years
    @qmega You need to do (require 'misc).
  • deadfish
    deadfish over 12 years
    so, I cannot do anything in if statement with my vector2?
  • Ethan Cabiac
    Ethan Cabiac over 12 years
    you can do lots of things in an if statement with a vector2, you just can't check if it is null. That would be like saying int i; if(i == null){...}
  • annonymously
    annonymously over 12 years
    Actually it would probably be more like saying int i; if(i == "hello") {...}
  • Rohaq
    Rohaq about 12 years
    I'm getting the following error with this: Symbol's function definition is void: move-beginning-of-line
  • David Gomes
    David Gomes about 12 years
    The problem with this is that "Del" key is also binded to duplicating the line...
  • tofutim
    tofutim almost 12 years
    This really is embarassing.
  • JS.
    JS. almost 12 years
    Kudos @RayVega! I tried this solution and it works like a champ (in my GNU Emacs 23.3.1, anyway). Is this solution not working for some people? This is the best answer to your (own) question.
  • ericzma
    ericzma over 11 years
    What about C-S-backspace C-y C-y?
  • Ollie Saunders
    Ollie Saunders almost 11 years
    Would be nice to have a version that did this without modifying the kill ring or the cursor position
  • Chris Conway
    Chris Conway almost 11 years
    You think Emacs can't do that? stackoverflow.com/questions/637351/…
  • katox
    katox over 10 years
    Somewhat easier is to hit C-S-Backspace followed by C-y C-y. Which means kill current complete line and then put it back twice.
  • phils
    phils over 10 years
    All things considered, Emacs mandates very little -- the huge win that it gives you is the ease of customising it to your own needs. Of course in practice there are lots of standard ways of doing things which it's beneficial to stick to, but if you're using "default" Emacs and doing something a harder way than necessary just because you think "it's better to use the standard", you're pretty much doing it wrong.
  • Peter Wood
    Peter Wood over 10 years
    @tofutim Indeed. In Netbeans I do C-S-down.
  • Chris Conway
    Chris Conway over 10 years
    @PeterWood Seriously? You think this operation is so important that it must be mapped to a single keystroke? I do this in Emacs literally every day and the key sequence above never enters my conscious mind.
  • Bala
    Bala over 10 years
    what is M-w ? which key to use for that ?
  • Chris Conway
    Chris Conway over 10 years
    @Bala "M" is "Meta" (usually Esc or Alt, it depends on your keyboard layout). "M-w" is "Meta" and "w" simultaneously (on my keyboard, "Alt-w").
  • pcarvalho
    pcarvalho about 10 years
    also, on the link there's some code for regions too!
  • Plankalkül
    Plankalkül almost 10 years
    Very nice solution. Thx
  • Alexander Shcheblikin
    Alexander Shcheblikin over 9 years
    So, any ideas of how to un-bind Del from this function?
  • Alexander Shcheblikin
    Alexander Shcheblikin over 9 years
    OK, found a solution to reverting Del back to normal while keeping the new C-d: (global-set-key (kbd "<delete>") 'delete-char) needs to be added after the C-d definition.
  • Zelphir Kaltstahl
    Zelphir Kaltstahl over 8 years
    Trying that on an empty line results in inserting two lines, instead of only one. I don't know why. Is there an easy fix?
  • Davor Cubranic
    Davor Cubranic about 8 years
    Really? Which "recent" Emacs would that be? Not the case with 24.4: you get "The mark is not set now, so there is no region."
  • Davor Cubranic
    Davor Cubranic about 8 years
    You should accept this answer as the correct one. It does exactly what you asked for, and in "the least number of commands".
  • Louis Kottmann
    Louis Kottmann about 8 years
    current Emacs is 24.5, and M-w is bound to easy-kill. Check that's what you get when you do C-h c M-w
  • Ha-Duong Nguyen
    Ha-Duong Nguyen over 7 years
    This is a bad answer, definitely should not be considered as the accepted answer. Relying on keybindings leads to unexpected consequences, especially when people re-bind default ones.
  • McBear Holden
    McBear Holden over 7 years
    You should try the great evil mode
  • junius
    junius about 7 years
    I put this in my .emacs file, but when I try to use C-c d I get the error command-execute: Wrong type argument: commandp, duplicate-line-or-region. Any idea what's up? I'm using Emacs 25.1.1 on Windows
  • Alex Trueman
    Alex Trueman about 7 years
    Really nice solution, I appreciate the region feature and the commenting-with-negative-argument feature. Also like the suggested key binding.
  • tejasbubane
    tejasbubane about 7 years
    This is nice. Thanks!
  • Stryker
    Stryker almost 7 years
    This works nicely but isn't there a short way to do this?
  • Stryker
    Stryker almost 7 years
    Works great. Thanks for the solution.
  • Derek Mahar
    Derek Mahar over 6 years
    Didn't work in Emacs 24.5.1. Copied only from start of line to point at the beginning of the same line after inserting a preceding blank line.
  • Dodgie
    Dodgie over 6 years
    Note that this will mess with kill ring.
  • bartlomiej.n
    bartlomiej.n almost 6 years
    This has to be the most straightforward method here. Thanks!
  • rofrol
    rofrol almost 6 years
    @pesche crux-duplicate-current-line-or-region works better for me, because with your function it undos line duplication and last operation also.
  • Mark
    Mark almost 6 years
    This appends the line onto itself when it is the last line and the file does not end in a new line
  • MarkSkayff
    MarkSkayff almost 4 years
    Looks like not there by this dates.
  • knobo
    knobo over 3 years
    (progn (beginning-of-line)(insert (thing-at-point 'line)))
  • Steve Eynon
    Steve Eynon almost 3 years
    I love the addition of move-line-up/down - for that was going to be my next question!
  • Kirk Walla
    Kirk Walla almost 3 years
    This is probably my favourite approach since it requires the least amounts of keystrokes.
  • Kirk Walla
    Kirk Walla almost 3 years
    @junius C-c d is reserved kbd for kill-whole-line, use another kbd.
  • Michael Terry
    Michael Terry over 2 years
    Unfortunately, as was the case for me: "Note that many text terminals will prevent you from typing the key sequence C-S-backspace." gnu.org/software/emacs/manual/html_node/emacs/…