如何在 Emacs 中轻松复制一行 10 次?我找不到复制行快捷方式或功能。我可以使用 C-aC-spcC-eM-w 费力地复制该行,但是我怎样才能将其粘贴多次?
在我去编写自己的函数之前的任何想法。
您可以为此使用键盘宏:-
Ca Ck Cx ( Cy Cj Cx ) Cu 9 Cx e
解释:-
复制:
如果您经常使用线条,您可能希望在未选择任何区域时使复制 ( 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)))))
然后,您可以仅使用 Mw 复制该行。
粘贴:
通常一个前缀参数只是多次执行一个动作,所以你希望 Cu 10 Cy 可以工作,但在这种情况下,Cy 使用它的参数来表示要“拉”(粘贴)的 kill-ring 的哪个元素。我能想到的唯一解决方案是 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 :)
您可能知道这一点,但对于许多命令,“Cu 10”前缀就可以解决问题。不幸的是,对于 Cy yank 命令,“Cu”被重新定义为“返回杀伤环中的那么多物品,然后猛拉该物品”。
我认为您可能可以将复制注册和插入注册命令与 Cu 前缀命令一起使用,但显然这也不起作用。
Cx z,“重复上一个命令”似乎对 Cu 免疫。
另一个想法是使用 M-: 来获得 Eval 提示并输入一些省略号。我认为像 (dotimes '10 'yank) 这样的东西可能会这样做,但似乎没有。
所以看起来在宏上使用 Cu 可能确实是你能做的最好的事情,而不是编写自己的小函数。
如果我投票,我会投票给 kronoz 答案。
在此示例中,您不需要同时使用 Cx ) 和 Cx e 。
您可以直接将重复参数提供给 Cx )。这将停止录制并在一个步骤中重复宏。或者您可以跳过 Cx ) 并直接转到 Cx e,因为 Cx e 将在重复之前结束录制。
选择哪种方式取决于您喜欢重复计数的工作方式。对于 Cx )你说你总共想要多少次重复(在这种情况下是 10 次)。对于 Cx e,您需要说明还剩下多少重复(即 9)。
Ca Ck Ck 也会杀死尾随的换行符,所以你以后不必自己放回去。它比使用标记更快,并且不需要您更改任何变量。
更好的是(除非您在终端中),您可以使用 CS-Backspace* 来杀死整条线路,无论您在其中的哪个位置。
[* 如果您使用的是 X windows,请确保键入 shift(而不是alt),否则您可能会终止会话!]
说到终端,如果您发现无法键入 C-9,M-9 是一个不错的选择。
在 Emacs 22 及更高版本中,默认情况下 F3 启动一个宏, F4 结束/重复一个宏。您只需按 F3 开始录制,完成后按 F4,然后再次按 F4 重复宏。(F4 也接受一个参数。)
把这些放在一起,得到当前行的 10 个副本:
不如 yy 10 p 短,但非常接近。:)
这是我从 Emacs 的 OS/2 端口获取的功能。(是的,我使用 Emacs 已经有一段时间了。)
;; Author: Eberhard Mattes <mattes@azu.informatik.uni-stuttgart.de>
(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)
然后我会用 Cu 10 F9 d 复制一条线10次。
我知道重复任意命令的唯一方法是使用键盘宏的“按参数重复”功能。
Ca C-space down Mw Cx ( Cy Cx ) C-9 Cx e
与vim相比,这有点弱。但这仅仅是因为 vim 在这类事情上的效率惊人。
如果您真的很喜欢模态 vi 类交互,您可以使用 vi 仿真模式之一,例如 viper 模式。检查在线 emacs 手册的“仿真”部分。
你会想要杀死这条线:Ca Ck,然后是 Cy 或?
我不知道直接等效(Cy 10 次是我所知道的最好的),但您可能对 Viper 感兴趣,它是 emacs 的 vi 仿真包。它是标准 emacs 发行版的一部分。
根据 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 的前缀的情况下调用它,所以。
不确定这是否是一个好主意,但我用这个替换了我的,我会看看情况如何。
你得到 Ck 行,你用 Cu 10 使下一个命令发生十次,然后你用 Cy 粘贴该行。很简单。
如果你总是想让 Ck 做整行,你可以设置 kill-whole-line 为 t。不再摆弄 Ca 或 Ce。
你可以用花哨的杀戮环、寄存器和宏做很多事情,我鼓励你学习它们,但拉线十次并不一定很难或很奇怪。