Emacs相当于Vim的yy10p?
如何在Emacs中轻松地复制一条线10次?我找不到复制行快捷方式或者功能。我可以使用C-aC-spcC-eM-w费力地复制该行,但是如何才能多次粘贴呢?
在编写自己的函数之前,请先提出任何想法。
解决方案
回答
我们将要杀死这条线:C-a C-k,然后C-y或者?
回答
我们可以为此使用键盘宏:-
C-a C-k C-x(C-y C-j C-x)C-u 9 C-x e
解释:-
- C-a:转到行首
- C-k:杀线
- C-x(:开始录制键盘宏
- C-y:扬克杀线
- C-j:移至下一行
- C-x):停止录制键盘宏
- C-u 9:重复9次
- C-x e:执行键盘宏
回答
我不知道直接等效(C-y是我所知道的最好的10倍),但是我们可能对Viper感兴趣,Viper是emacs的vi仿真包。它是标准emacs发行版的一部分。
回答
复制中:
如果我们经常使用线条,则可能需要在未选择任何区域的情况下对线条进行复制(kill-ring-save
)和剪切(kill-region
):
(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)))))
然后,我们可以仅使用M-w复制该行。
贴上:
通常,前缀参数会执行多次操作,因此我们希望C-u 10 C-y可以工作,但是在这种情况下,C-y使用其参数来表示杀死环中的哪个元素要"粘贴"。我能想到的唯一解决方案是kronoz所说的:用Cx(Cy Cx)记录一个宏,然后将Cu的参数改为kmacro-end-and-call-macro
(Cu 9 Cx e甚至是只需C-9 Cx e或者M-9 Cx e)。
其他方式:
我们也可以只停留在M-x viper-mode
并使用yy10p :)
回答
我知道重复任意命令的唯一方法是使用键盘宏的"按参数重复"功能。
C-a C-空间向下M-w C-x(C-y C-x)C-9 C-x e
- C-a:转到行首
- C空间:设置标记
- 下:转到下一行的开始
- 宽:复制区域
- C-x(:启动键盘宏
- C-y:Yank复制行
- C-x):结束键盘宏
- C-9 C-x e:执行键盘宏九次。
与vim相比,这是一种弱点。但这仅仅是因为vim在这种情况下非常有效。
如果我们确实希望进行类似于模式的vi交互,则可以使用其中一种vi仿真模式,例如viper模式。签入在线emacs手册的"仿真"部分。
回答
我们可能知道这一点,但是对于许多命令,使用" C-u 10"前缀即可解决问题。不幸的是,对于C-y猛拉命令," C-u"被重新定义为"返回杀死环中的许多物品,然后猛拉该物品"。
我以为我们也许可以将C-u前缀命令与copy-to-register和insert-register命令一起使用,但是显然这也不起作用。
同样,C-x z的"重复最后命令"似乎不受C-u的影响。
另一个想法是使用M-:来获取一个Eval提示符并输入一些elisp。我认为类似(dotimes '10'yank)的方法可以做到,但似乎没有。
因此,看起来像在宏上使用C-u确实是我们可以写的最好的方法,只是没有编写自己的小函数。
如果我投票,我会投票给克朗兹答案。
回答
这是我从Emacs的OS / 2端口获得的功能。 (是的,我使用Emacs已有一段时间了。)
;; 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))))
我已经绑定到F9 d:
(global-set-key [f9 ?d] 'emx-dup-line)
然后,我将使用C-u 10 F9 d将一行重复10次。
回答
我们使用C-k获得该行,使用C-u 10使下一个命令发生十次,然后使用C-y粘贴该行。很简单
如果我们始终希望C-k完成整行,则可以将kill-whole-line设置为t。不再摆弄C-a或者C-e。
花式杀手环,寄存器和宏可以做很多事情,我鼓励我们学习它们,但是拉线十次并不一定很困难或者陌生。
回答
在此示例中,我们不需要C-x和C-x e。
我们可以直接将repeat参数直接赋予C-x)。这将停止记录,并一步一步重复宏。或者,我们可以跳过C-x)并直接转到C-x e,因为C-x e在执行重复操作之前将结束录制。
选择哪种方式取决于我们希望重复计数的工作方式。对于C-x),我们说总共要重复多少次(本例中为10次)。对于C-x e,我们需要说还剩下多少重复(即9)。
C-a C-k C-k也会杀死结尾的换行符,因此我们不必稍后再放回去。它比使用标记更快,并且不需要我们更改任何变量。
更好的是(除非我们在终端中),无论我们位于行中何处,都可以使用C-S-Backspace *杀死整个行。
[*如果我们使用的是X窗口,请确保键入shift(而不是alt),否则我们可能会终止会话!]
说到终端,如果我们发现无法键入C-9,则M-9是一个不错的选择。
在Emacs 22及更高版本中,默认情况下F3启动一个宏,F4结束/重复一个宏。我们只需按F3键开始录制,完成后按F4键,然后再次按F4键重复宏。 (F4也有一个参数。)
将所有这些放在一起,以获得当前行的10个副本:
- C-S-Backspace:杀死这行
- F3:开始宏
- C-y:拉线
- C-1 C-0 F4:拉10杆
不及y y p 10短,但很接近。 :)
回答
根据Baxissimo的回答,我对此表示怀疑:
(defun yank-n-times (arg) "yank prefix-arg number of times. Not safe in any way." (interactive "*p") (dotimes 'arg (yank)))
将其设置为某个键,使用前缀参数调用它,然后就可以使用了。
编辑(还修改了上面的交互式调用,以减少麻烦)
或者,这是一个可以代替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."))))
该消息有点是谎言,但是无论如何我们都应该在没有大于1的前缀的情况下调用该消息。
不确定这是否是个好主意,但我将其替换为M-y,我将看看情况如何。