How do I duplicate a whole line in Emacs?

前端 未结 30 971
时光取名叫无心
时光取名叫无心 2020-12-04 05:20

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 num

相关标签:
30条回答
  • 2020-12-04 05:26

    Here's yet another function for doing this. My version doesn't touch the kill ring, and the cursor ends up on the new line where it was on the original. It will duplicate the region if it's active (transient mark mode), or default to duplicating the line otherwise. It will also make multiple copies if given a prefix arg, and comment out the original line if given a negative prefix arg (this is useful for testing a different version of a command/statement while keeping the old one).

    (defun duplicate-line-or-region (&optional n)
      "Duplicate current line, or region if active.
    With argument N, make N copies.
    With negative N, comment out original line and use the absolute value."
      (interactive "*p")
      (let ((use-region (use-region-p)))
        (save-excursion
          (let ((text (if use-region        ;Get region if active, otherwise line
                          (buffer-substring (region-beginning) (region-end))
                        (prog1 (thing-at-point 'line)
                          (end-of-line)
                          (if (< 0 (forward-line 1)) ;Go to beginning of next line, or make a new one
                              (newline))))))
            (dotimes (i (abs (or n 1)))     ;Insert N times, or once if not specified
              (insert text))))
        (if use-region nil                  ;Only if we're working with a line (not a region)
          (let ((pos (- (point) (line-beginning-position)))) ;Save column
            (if (> 0 n)                             ;Comment out original with negative arg
                (comment-region (line-beginning-position) (line-end-position)))
            (forward-line 1)
            (forward-char pos)))))
    

    I have it bound to C-c d:

    (global-set-key [?\C-c ?d] 'duplicate-line-or-region)
    

    This should never be re-assigned by a mode or anything because C-c followed by a single (unmodified) letter is reserved for user bindings.

    0 讨论(0)
  • 2020-12-04 05:27

    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.

    0 讨论(0)
  • 2020-12-04 05:28

    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.

    0 讨论(0)
  • 2020-12-04 05:28

    There is package called Avy It has command avy-copy-line. When you use that command, every line in your window gets letter combination. Then you just have to type combination and you get that line. This also works for region. Then you just have to type two combination.

    Here you can see interface:

    0 讨论(0)
  • 2020-12-04 05:28

    If you're using Spacemacs, you can simply use duplicate-line-or-region, bound to:

    SPC x l d 
    
    0 讨论(0)
  • 2020-12-04 05:30

    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)

    0 讨论(0)
提交回复
热议问题