views:

1474

answers:

10

How can I copy a line 10 times easily in Emacs? I can't find a copy-line shortcut or function. I can use C-aC-spcC-eM-w to laboriously copy the line but how can I then paste it more than once?

Any ideas before I go and write my own functions.

A: 

You will want to kill the line: C-a C-k, and then C-y or ?

mmattax
er.. the question is how to do it ten times, not once.
Baxissimo
+3  A: 

you can use a keyboard macro for that:-

C-a C-k C-x ( C-y C-j C-x ) C-u 9 C-x e

Explanation:-

  • C-a : Go to start of line
  • C-k : Kill line
  • C-x ( : Start recording keyboard macro
  • C-y : Yank killed line
  • C-j : Move to next line
  • C-x ) : Stop recording keyboard macro
  • C-u 9 : Repeat 9 times
  • C-x e : Execute keyboard macro
kronoz
A: 

I don't know of a direct equivalent (C-y 10 times is the best I know), but you may be interested in Viper, which is a vi emulation package for emacs. It's part of the standard emacs distribution.

Mike Monette
+5  A: 

Copying:

If you frequently work with lines, you might want to make copy (kill-ring-save) and cut (kill-region) work on lines when no region is selected:

(defadvice kill-ring-save (before slickcopy activate compile)
  "When called interactively with no active region, copy a single line instead."
  (interactive
   (if mark-active (list (region-beginning) (region-end))
     (list (line-beginning-position)
           (line-beginning-position 2)))))
(defadvice kill-region (before slickcut activate compile)
  "When called interactively with no active region, kill a single line instead."
  (interactive
   (if mark-active (list (region-beginning) (region-end))
     (list (line-beginning-position)
           (line-beginning-position 2)))))

Then you can copy the line with just M-w.

Pasting:

Often a prefix argument just performs an action multiple times, so you'd expect C-u 10 C-y to work, but in this case C-y uses its argument to mean which element of the kill-ring to "yank" (paste). The only solution I can think of is what kronoz says: record a macro with C-x ( C-y C-x ) and then let the argument of C-u go to kmacro-end-and-call-macro instead (that's C-u 9 C-x e or even just C-9 C-x e or M-9 C-x e).

Another way: You can also just stay in M-x viper-mode and use yy10p :)

ShreevatsaR
+2  A: 

The only way I know to repeat arbitrary commands is to use the "repeat by argument" feature of keyboard macros.

C-a C-space down M-w C-x ( C-y C-x ) C-9 C-x e

  • C-a : Go to start of line
  • C-space : Set mark
  • down : Go to start of following line
  • M-w : Copy region
  • C-x ( : Start keyboard macro
  • C-y : Yank copied line
  • C-x ) : End keyboard macro
  • C-9 C-x e : Execute keyboard macro nine times.

That's kind of weak compared to vim. But only because vim is amazingly efficient at this sort of thing.

If you are really pining for modal vi-like interaction, you could use one of the vi emulation modes, such as viper-mode. Check in the section "Emulation" of online emacs manual.

ddaa
Heh heh, that's 8 keystrokes compared to 10 to just C-y the darn thing ten times. I guarantee I can type C-y ten times faster than I can type all that.
Baxissimo
+4  A: 

You may know this, but for many commands a "C-u 10" prefix will do the trick. Unfortunately for the C-y yank command, "C-u" is redefined to mean "go back that many items in the kill ring, and yank that item".

I thought you might be able to use the copy-to-register and insert-register commands with the C-u prefix command, but apparently that doesn't work either.

Also C-x z, "repeat last command" seems to be immune to C-u.

Another thought would be to use M-: to get an Eval prompt and type in a bit of elisp. I thought something like (dotimes '10 'yank) might do it, but it doesn't seem to.

So it looks like using C-u on a macro may indeed be the best you can do short of writing your own little function.

Had I a vote, I'd vote for kronoz answer.

Baxissimo
(dotimes '10 (yank)) seems to work for me
quodlibetor
+3  A: 

Here's a function I took from an OS/2 port of Emacs. (Yes, I've been using Emacs for a while.)

;; Author: Eberhard Mattes <[email protected]>
(defun emx-dup-line (arg)
  "Duplicate current line.
Set mark to the beginning of the new line.
With argument, do this that many times."
  (interactive "*p")
  (setq last-command 'identity) ; Don't append to kill ring
  (let ((s (point)))
    (beginning-of-line)
    (let ((b (point)))
      (forward-line)
      (if (not (eq (preceding-char) ?\n)) (insert ?\n))
      (copy-region-as-kill b (point))
    (while (> arg 0)
      (yank)
      (setq arg (1- arg)))
    (goto-char s))))

I have that bound to F9 d:

(global-set-key [f9 ?d]    'emx-dup-line)

Then I'd use C-u 10 F9 d to duplicate a line 10 times.

cjm
A: 

You get the line with C-k, you make the next command happen ten times with C-u 10, then you paste the line with C-y. Pretty simple.

If you always want C-k to do the whole line, you can set kill-whole-line to t. No more fiddling with C-a or C-e.

There's a lot you can do with fancy kill rings, registers, and macros, and I encourage you to learn them, but yanking a line ten times doesn't have to be tough or strange.

jfm3
Nice guess, but did you actually try it out? The C-u prefix command selects which element from the kill ring to yank when used in combo with C-y. It does not repeat the command 10 times.
Baxissimo
A: 

You don't need both C-x ) and C-x e in this example.

You can just give the repeat argument straight to C-x ). This stops recording and repeats the macro, in one step. Or you can skip C-x ) and go straight to C-x e, since C-x e will end the recording before doing the repeats.

Which way to choose depends on how you like your repeat count to work. For C-x ) you say how many repeats you wanted in total (so 10 in this case). For C-x e you need to say how many more repeats are left (i.e. 9).


C-a C-k C-k will also kill the trailing newline, so you don't have to put it back yourself later. It's quicker than using the mark, and doesn't need you to change any variables.

Even better (unless you're in a terminal), you can use C-S-Backspace* to kill the entire line, regardless of where you are in it.

[* If you're using X windows, make sure to type shift (not alt) or you may terminate your session!]

Speaking of terminals, M-9 is a nice alternative if you find you can't type C-9.


In Emacs 22 and higher, by default F3 starts a macro and F4 end/repeats a macro. You just hit F3 to start recording, hit F4 when you're done, and hit F4 again to repeat the macro. (F4 also takes an argument.)


Putting this all together, to get 10 copies of the current line:

  • C-S-Backspace : kill this line
  • F3 : start macro
  • C-y : yank the line
  • C-1 C-0 F4 : make that 10 yanks

Not quite as short as y y 10 p, but pretty close. :)

Paul
A: 

Based on Baxissimo's answer I defuned this:

(defun yank-n-times (arg)
  "yank prefix-arg number of times. Not safe in any way."
  (interactive "*p")
  (dotimes 'arg (yank)))

Set that to some key, call it with a prefix argument, and off you go.

edit (also modified the interactive call above to be less lousy)

Or, here's a version that can sort of replace yank-pop:

(defun yank-n-times (&optional arg)
  "yank prefix-arg number of times. Call yank-pop if last command was yank."
  (interactive "*p")
  (if (or (string= last-command "yank")
      (string= last-command "yank-pop"))
      (yank-pop arg)
    (if (> arg 1)
    (dotimes 'arg (yank))
      (message "Previous arg was not a yank, and called without a prefix."))))

the message is kind of a lie, but you shouldn't call it without a prefix of greater than 1 anyway, so.

Not sure if it's a good idea, but I replaced M-y with this, I'll see how that goes.

quodlibetor