SiteMap Search ElispArea HowTo Glossary RecentChanges News Problems Suggestions
Eritrea, Independence Day

CopyingWholeLines

Standard Emacs

There are various way to copy the copy the current line to the kill ring in vanilla GnuEmacs:

Using the mouse

You can also use either of these mouse selection methods to select whole lines as the SecondarySelection – just hold down the Meta key while you click.

Using the keyboard

In the key sequences above, ‘C-a’ goes to beginning of line, ‘C-e’ goes to the end of line, ‘C-n’ goes to the next line, ‘C-SPC’ sets the mark, ‘M-w’ saves the region, ‘C-k’ kills from point to the end of line, and ‘C-y’ yanks the last kill back.

You can also copy whole lines using Viper: yy (current line), yj (current + next etc.).

Enhancements

This section presents some additional ways to copy a line, besides those available out of the box.

  1. Define a new command for copying the current line. It can then be bound to a shorter key sequence, e.g., ‘C-c C-k’.
  2. Modify the vanilla commands, for some context-dependent behavior.

New commands

A copy-line with variable arguments

    (defun copy-line (arg)
      "Copy lines (as many as prefix argument) in the kill ring"
      (interactive "p")
      (kill-ring-save (line-beginning-position)
                      (line-beginning-position (+ 1 arg)))
      (message "%d line%s copied" arg (if (= 1 arg) "" "s")))
   ;; optional key binding
   (global-set-key "\C-c\C-k" 'copy-line)

A copy-line that uses kill-line in a read-only context

Originally by GregReagle?; improvements by [[Bodhi?]].

    (defun copy-line (&optional arg)
      "Do a kill-line but copy rather than kill.  This function directly calls
    kill-line, so see documentation of kill-line for how to use it including prefix
    argument and relevant variables.  This function works by temporarily making the
    buffer read-only."
      (interactive "P")
      (let ((buffer-read-only t)
            (kill-read-only-ok t))
        (kill-line arg)))
    ;; optional key binding
    (global-set-key "\C-c\C-k" 'copy-line)

quick-copy-line

Anonymous’s first EmacsLisp function.

    (defun quick-copy-line ()
      "Copy the whole line that point is on and move to the beginning of the next line.
    Consecutive calls to this command append each line to the
    kill-ring."
      (interactive)
      (let ((beg (line-beginning-position 1))
            (end (line-beginning-position 2)))
        (if (eq last-command 'quick-copy-line)
            (kill-append (buffer-substring beg end) (< end beg))
          (kill-new (buffer-substring beg end))))
      (beginning-of-line 2))

I bind this command to <f11>. Hitting <f11> multiple times appends each line to the kill ring (which is why the command moves to the beginning of the next line). This makes it really quick and easy to copy multiple lines.

quick-cut-line

(defun quick-cut-line ()
  "Cut the whole line that point is on.  Consecutive calls to this command append each line to the kill-ring."
  (interactive)
  (let ((beg (line-beginning-position 1))
	(end (line-beginning-position 2)))
    (if (eq last-command 'quick-cut-line)
	(kill-append (buffer-substring beg end) (< end beg))
      (kill-new (buffer-substring beg end)))
    (delete-region beg end))
  (beginning-of-line 1)
  (setq this-command 'quick-cut-line))

Similar to the quick-copy-line, I define the function quick-cut-line to quickly cut multiple lines and append them to the kill-ring. I bind it to \M-f11.

This is the same behavior as hitting ‘C-S-DEL’, the binding for ‘kill-whole-line’.

avi-kill-line-save

I too always wondered why stock Emacs didn’t have a convenient line copying keybinding, or even a function. There are C-w (kill-region) and M-w (kill-ring-save), but C-k (kill-line) doesn’t seem to have a counterpart that just saves the lines into the kill ring.

This one behaves the same way as ‘kill-line’, except that it doesn’t move point at all, because I felt that it suits me the best this way. What I’d like to expand it with is the possibillity to be able to call it consecutively and copy multiple lines one for one, as quick-copy-line does, and let this behaviour depend on a variable or a prefix. When I find time for that. As of now I use both functions with different keys, depending on the situation i need them. – avi

    (defun avi-kill-line-save (&optional arg)
      "Copy to the kill ring from point to the end of the current line.
    With a prefix argument, copy that many lines from point. Negative
    arguments copy lines backward. With zero argument, copies the
    text before point to the beginning of the current line."
      (interactive "p")
      (save-excursion
        (copy-region-as-kill
         (point)
         (progn (if arg (forward-visible-line arg)
                  (end-of-visible-line))
                (point)))))

duplicate-current-line

I (dim) am doing that instead:

    ;; duplicate current line
    (defun duplicate-current-line (&optional n)
      "duplicate current line, make more than 1 copy given a numeric argument"
      (interactive "p")
      (save-excursion
        (let ((nb (or n 1))
    	  (current-line (thing-at-point 'line)))
          ;; when on last line, insert a newline first
          (when (or (= 1 (forward-line 1)) (eq (point) (point-max)))
    	(insert "\n"))
    
          ;; now insert as many time as requested
          (while (> n 0)
    	(insert current-line)
    	(decf n)))))
    
    (global-set-key (kbd "C-S-d") 'duplicate-current-line)

smart copy region

To copy the rest of the line without marking it, I use

    (defun my-kill-ring-save ()
        (interactive)
        (if (equal mark-active nil) (kill-ring-save (point) (line-end-position)) (kill-ring-save (point) (mark))))
    (global-set-key "\M-w" 'my-kill-ring-save)

If you mark a region this behaves as expected and saves the region to the kill ring, otherwise, saves the region between (point) and the end of line to the kill ring.

Modifying the default commands

SlickEdit, TextMate and VisualStudio have clever line-wise behavior: if no text is selected, the copy and cut commands act on the current line instead. To do this in Emacs (with M-w and C-w), see WholeLineOrRegion.

A more versatile solution is provided by Leo: if the region is active, M-w behaves like normal, otherwise it copies an URL, e-mail address or the current line, in that order. M-w followed by the key f, l, s or w copies file name, list, S-expression and word, respectively. See his page for more details.


CategoryRegion CategoryMouse