Killing, yanking and copying lines

Kind reader William Annis noticed how clumsily i copied a line in the kill ring in my last screencast. I went to the beginning of the line (C-a), killed it (C-k) so i got it in my kill-ring, and yanked it back (C-y). Admittedly, a bit cumbersome, my only excuse being that i have this keystroke sequence hardwired in my nervous system from the dawn of my emacs times; approximately the same epoch when i put in my .emacs this setting to make kill-line eat also the final carry return:

(setq kill-whole-line t)

But, as William notices, there’re better ways of copying the current line. A quick one would be:

(defun jao-copy-line ()
  "Copy current line in the kill ring"
  (kill-ring-save (line-beginning-position) 
                  (line-beginning-position 2))
  (message "Line copied"))

which can be easily extended to take as a prefix argument the number of lines to copy (with 1 as the default)

(defun jao-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")))

Assign the new function to a handy shortcut, and you’re done. These functions have the additional benefit of leaving the point untouched.

Next thing you’ll do after using your new shiny shortcut will most probably be yanking those lines somewhere. And it may well happen that they’ll be mis-indented in their new location. A relatively quick way of realigning them is to take advantage of the fact that after a yank the region is set to the yanked text and use indent-region, which is bound to C-M-\. But i prefer to let Emacs do that for me, using this piece of advice in my .emacs:

(defadvice yank (after indent-region activate)
  (if (member major-mode '(emacs-lisp-mode scheme-mode lisp-mode
                           c-mode c++-mode objc-mode
                           LaTeX-mode TeX-mode))
      (indent-region (region-beginning) (region-end) nil)))

where, as you can see, i’m limiting the advice to some modes: just delete the major-mode check if you want it to work everywhere.


10 Responses to “Killing, yanking and copying lines”

  1. Ian Eure Says:

    I took a different approach; I only copy from the start of the indentation to the end of the line; RET is bound to newline-and-indent, so I can copy a line with these functions and it’s already lined up when I yank, with no need to reindent.

    I’m sure this is not the most graceful way to do it, but I’m a Lisp newbie, and it works well for me:

    (defun mark-line (&optional arg)
    “Marks a line from start of indentation to end”
    (interactive “p”)
    (end-of-line-mark arg))

    (defun copy-line (&optional arg)
    “Kills a line, not including leading indentation”
    (interactive “p”)
    (mark-line arg)
    (kill-ring-save (point) (mark)))

    I have mark-line bound to C-c l and copy-line bound to C-x l, and as you can see, it takes arguments.

    I prefer the default behavior of C-k, but sometimes I want to kill a whole line. I found that there is a kill-whole-line function, but it’s not bound by default. I bound it to C-c C-k, and find that it works quite well. It takes an arg, too.

  2. randomhack Says:

    So what’s wrong with C-a C- C-e M-w?

  3. Wm Annis Says:

    > So what’s wrong with C-a C- C-e M-w?

    Nothing, really, but it does seem like an awful lot of extra keying when it’s something you do often. When I find myself repeating the same sequence, I write a little elisp, since I object on principle to doing anything a computer can do.

  4. Helmar Says:

    After i yank something in emacs 22 it is *not* the region. Why could this be?

  5. Ryan Davis Says:

    I use C-u C-k, where is the number of lines to kill. Oddly it is the real number of lines to kill, not 2N (the number of C-k’s you’d have to type to kill N lines).

  6. Ryan Davis Says:

    damnit. I stupidly wrapped N in angle brackets. Here:

    C-u N C-k

  7. Bill Lovett Says:

    I found that the yank advice as posted didn’t work until I set mark-even-if-inactive to true, like so:

    (defadvice yank (after indent-region activate)
    (let ((mark-even-if-inactive t))
    (indent-region (region-beginning) (region-end) nil)))


  8. Marius Andersen Says:

    You might want to look at, which does line-wise editing when no text is selected. SlickEdit has it, TextMate has it, and now Emacs has it, too. 🙂

  9. Ryan Krauss Says:

    This is sort of a trivial modification, but I changed (line-beginning-position) to (point) and am very happy with it. I only want to copy from point to the end of the line.

    This is so much better than C-k C-y, which leaves the file as modified if you are copying from one file to another. Thanks!

Leave a Reply to Bill Lovett Cancel reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: