Do you find yourself often running a yank or undo immediately after killing lines? Would you like to copy a line instead of killing it? Do you wish that there was a prefix argument to C-k (kill-line) that made it copy instead of cut (to use the non-Emacs terminology). Here is your solution—a command that acts just like kill-line except that it is a copy.
(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, so I suggest setting kill-read-only-ok to t." (interactive "P") (toggle-read-only 1) (kill-line arg) (toggle-read-only 0)) (setq-default kill-read-only-ok t) (global-set-key "\C-c\C-k" 'copy-line)
24 responses so far ↓
You mean Emacs doesn’t have the simple vim commands for kill-copy line (D) and yank line (Y)? =P
Okay, okay. I’m a sucker for Lisp so I’ll let emacs’s quirks slide.
What’s wrong with M-w?
yeah as WZ said kill-ring-save normally bound to M-w
Yes, M-w is an option, but it requires the region to be marked first instead of working on lines.
i use (kill-ring-save (line-beginning-position) (line-end-position)) to copy current line
Is C-c C-k really easier than C-k C-y? I’m not being snarky, I’m legitimately curious.
To each, his own. For me, I’ll probably never rewire my brain away from
C-k C-y, but Greg’s hack of playing off of the read-only features ofkill-lineis an interesting approach. There are probably a half a dozen good ways of doing this.For a key binding, I probably would chose
M-kforcopy-lineto coincide withM-w(kill-ring-save).M-kis normallykill-sentence, but I never use it.Stylistic comment, might be cleaner to use a let (in case something ever goes wrong with the command)
(let ((buffer-read-only t))
(kill-line arg))
Very clever solutions.
Caveat lector nostalgia: Back in the late nineties when I was moving to emacs from Q-Edit, I craved the same functionality, so I wrote the following after going through the elisp tutorial and still use it today. I don’t mark anything, I just use my bound key and it assumes I want the whole line copied. I’d revisit my hack more if it didn’t work reasonably and reliably for the last 10+ years.
(defun tjc-duplicate-line (arg)
“Copy current line beneath itself. Move point to new copy of line in
exact same position as previous line.”
(interactive “p”)
(let ((orig (point)))
(beginning-of-line)
(let ((beg (point)))
(end-of-line)
(let ((end (point)))
(copy-region-as-kill beg end)
(newline)
(yank)
;; Place point on copied line at column where point was on
;; previous line.
(goto-char (+ orig (- end orig) (- orig beg) 1))))))
(defun tjc-kill-line (arg)
“Kill the current line and move to next line. Place point in same column
as deleted line or place point at end of line if line is shorter than deleted
line.”
(interactive “p”)
(let ((orig (point)))
(beginning-of-line)
(let ((beg (point)))
(forward-line 1)
(delete-region beg (point)))
;;If line is shorter than previous line, then just go to end of line.
(end-of-line)
(let ((new (point)))
(if (< orig new)
(goto-char orig)))))
In response to ilsaj:
> Is C-c C-k really easier than C-k C-y?
> I’m not being snarky, I’m legitimately curious.
Command copy-line could be bound to a single key (for instance M-k as Ryan suggested) then it would be less typing, but the significant advantage is not in the number of keystrokes. C-k C-y makes Emacs think the buffer has been modified when it hasn’t (see mode line), and adds to the undo-history when it shouldn’t—a copy doesn’t need to be undone.
In response to WZ:
> What’s wrong with M-w?
Upon further consideration, this idea is really growing on me, and I might like it better than my custom function copy-line. I can copy lines by doing or some variation. Like the custom copy-line function that I wrote, it does not affect mode line (was buffer modified status) or undo history. It is a little less convenient, but it has the benefit of being standard, which I consider a significant advantage.
Even if I ultimately wind up using M-w rather than the custom copy-line function, this has been a great discussion and I’ve learned a lot. Thanks everyone for your comments.
Correction of my previous comment:
“I can copy lines by doing C-SPC C-n M-w or some variation”
I prefer the SlickEdit/TextMate way of copying and cutting lines: if no text is selected, the current line is acted on instead. No extra functions, just clever behavior.
To implement this in Emacs, see http://www.emacswiki.org/emacs/SlickCopy
Call me a weenie if you like, but I like simply enabling (pc-selection-mode 1). Then all the hard work is done for you. Copying lines is done the same way you would in any editor or IDE from any platform: Make your selection and hit . To paste, C-y or work just as well.
You can also cut a selection with . (C-k only kills up to the end of the line and is independent of the selection, so it’s not quite the same.)
Sorry, I didn’t realize that angle brackets were interpreted as HTML here. The universal copy command is <C-insert>. The universal paste command is <S-insert>, and the universal cut command is <S-delete>.
15 A quick-tips Emacs post « Tech Rants // May 22, 2009 at 2:22 pm
[...] 6) Another awesomely helpful tip: ;Copy-only from M-x all things emacs. (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, so I suggest setting kill-read-only-ok to t.” (interactive “P”) (toggle-read-only 1) (kill-line arg) (toggle-read-only 0)) (setq-default kill-read-only-ok t) (global-set-key “C-cC-k” ‘copy-line) From M-x all-things-emacs [...]
Thanks for this, I’ve been annoyed ‘C-k M-y’ing too often. From the tips in the comments I’ve culled it down to:
(defun copy-line (&optional arg)
(interactive “P”)
(let ((kill-read-only-ok t)
(buffer-read-only t))
(kill-line arg)))
I tweaked it because (toggle-read-only) would complain with files under version-control. But is there anyway to get it to not move the cursor after the ‘kill’? I guess I could push a mark and pop back, or just see if the moving cursor is as annoying as i think! One side effect is you can copy several lines of text by repeated M-k as it appends the new text to the kill-ring.
Here’s an arguably better solution to both copying and killing lines.
http://www.emacswiki.org/emacs/SlickCopy
Wow, I found many things up here, but not what I dream of yet !
I’d like to have a command which allows to copy a line wherever my cursor is on this line -so I don’t like much the “kill-line”-like functions.
SlickCopy (link above) is pretty pretty, and does what I just described, but it requires transient-mark-mode enabled, and I don’t like it because I like to use marks with C-space and C-x-x.
What do you think ?? any solution ?
thanks
Vincent
You say, code in response 5 ? Allright, I hardly understand emacslisp for the moment so I didn’t understand; I’ll try to bind it to M-w or sthg.
Thank you, bye !
(global-set-key (kbd “C-S-k”)
(lambda ()
(interactive)
(set ‘this-command ‘copy-to-kill)
(set-mark (point))
(if (= (point) (line-end-position))
(forward-line)
(goto-char (line-end-position)))
(if (eq last-command ‘copy-to-kill)
(append-next-kill))
(kill-ring-save (mark) (point))))
Here’s some code that works for me:
(defun kill-ring-save-wrapper ()
“If no region exists, call kill-ring-save with point and
line-end-position as the beginning and end arguments.”
(interactive)
(if (ignore-errors (mark))
(kill-ring-save (region-beginning) (region-end))
(kill-ring-save (point) (line-end-position))))
(global-set-key “\M-w” ‘kill-ring-save-wrapper)
Based on Greg’s decision to go with M-w, and vinz wish, here’s my attempt:
(defun whatever()
“copy the line that point is on “
(interactive “P”)
(save-excursion
(move-beginning-of-line)
(next-line-mark)
(copy-region-as-kill-nomark)))
Basically this is C-o C-n M-w, wraped in a save-excursion so that your cursor / mark are unaffected. I too would bind this to M-k
oh duh! check this out: http://www.emacswiki.org/emacs/CopyingWholeLines
I found it in my .emacs when I went to add above. <blush/>
(defun mjl-copy-line (arg)
“Copy lines (as many as prefix argument) in the kill ring
http://www.emacswiki.org/emacs/CopyingWholeLines”;
(interactive “p”)
(kill-ring-save (line-beginning-position)
(line-beginning-position (+ 1 arg)))
(message “%d line%s copied” arg (if (= 1 arg) “” “s”)))
I copyied this to my X clipboard thus: C-u 7 M-k — three key presses (5 if you count the modifier keys)
It is extremely interesting for me to read this blog. Thanks for it. I like such topics and everything connected to this matter. I would like to read a bit more soon.
Alex Stepman
Leave a Comment