【发布时间】:2008-09-16 13:06:39
【问题描述】:
如何在 Emacs 中轻松复制一行 10 次?我找不到复制行快捷方式或功能。我可以使用 C-aC-spcC-eM-w 费力地复制该行,但我怎样才能将其粘贴多次?
在我编写自己的函数之前的任何想法。
【问题讨论】:
如何在 Emacs 中轻松复制一行 10 次?我找不到复制行快捷方式或功能。我可以使用 C-aC-spcC-eM-w 费力地复制该行,但我怎样才能将其粘贴多次?
在我编写自己的函数之前的任何想法。
【问题讨论】:
您可以为此使用键盘宏:-
C-a C-k C-x ( C-y C-j C-x ) C-u 9 C-x e
说明:-
【讨论】:
<C-S-backspace>,它运行 kill-whole-line,相当于 vi 中的 dd。因此,每当您发现自己在做C-a C-k C-k 时,您只需<C-S-backspace>。
C-x ( 和 C-x ) 您可以分别键入 F3 和 F4 键。 See emacs manual for more info
复制:
如果您经常使用线条,您可能希望在未选择区域时对线条进行复制 (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 使用它的参数来表示要“拉”(粘贴)的 kill-ring 的哪个元素。我能想到的唯一解决方案是 kronoz 所说的:用 C-x ( C-y C-x ) 记录一个宏,然后让 C-u 的参数转到 kmacro-end-and-call-macro ( 那是 C-u 9 C-x e 甚至只是 C-9 C-x e 或 M -9 C-x e)。
另一种方式:
您也可以留在M-x viper-mode 并使用 yy10p :)
【讨论】:
viper-mode; it has many Vim features that viper doesn't.
您可能知道这一点,但是对于 许多 命令,“C-u 10”前缀就可以解决问题。不幸的是,对于 C-y yank 命令,“C-u”被重新定义为“返回杀伤环中的那么多物品,然后猛拉该物品”。
我认为您可以将复制注册和插入注册命令与 C-u 前缀命令一起使用,但显然这也不起作用。
还有 C-x z,“重复上一个命令”似乎对 C-u 免疫。
另一个想法是使用 M-: 来获得 Eval 提示并输入一些 elisp。我认为像 (dotimes '10 'yank) 这样的东西可能会这样做,但似乎没有。
所以看起来在宏上使用 C-u 可能确实是你能做的最好的事情,而不是编写自己的小函数。
如果我投票,我会投票给 kronoz 答案。
【讨论】:
在此示例中,您不需要同时使用 C-x ) 和 C-x e。
您可以直接将重复参数直接提供给 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 windows,请确保输入 shift(not alt),否则您可能会终止会话!]
说到终端,如果您发现无法键入 C-9,M-9 是一个不错的选择。
在 Emacs 22 及更高版本中,默认情况下 F3 启动一个宏,F4 结束/重复一个宏。您只需按 F3 开始录制,完成后按 F4,然后再次按 F4 重复宏。 (F4 也接受一个参数。)
将这些放在一起,得到当前行的 10 个副本:
不像y y 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)
然后我会使用 C-u 10 F9 d 将一行复制 10 次。
【讨论】:
我知道重复任意命令的唯一方法是使用键盘宏的“按参数重复”功能。
C-a C-空格向下 M-w C-x ( C-y C-x ) C-9 C-x e
与 vim 相比,这有点弱。但这只是因为 vim 在这类事情上的效率惊人。
如果您真的很喜欢模态 vi 类交互,您可以使用 vi 仿真模式之一,例如 viper 模式。查看在线 emacs 手册的“仿真”部分。
【讨论】:
你会想要终止这条线:C-a C-k,然后是 C-y 或 ?
【讨论】:
我不知道直接等效(C-y 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)))
将其设置为某个键,使用前缀参数调用它,然后就可以使用了。
edit(还修改了上面的交互调用,使其不那么糟糕)
或者,这是一个可以替代 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,我会看看结果如何。
【讨论】:
你用 C-k 得到该行,用 C-u 10 使下一个命令发生十次,然后用 C-y 粘贴该行。很简单。
如果你总是希望 C-k 做整行,你可以将 kill-whole-line 设置为 t。不用再摆弄 C-a 或 C-e。
你可以用花哨的杀戮环、寄存器和宏做很多事情,我鼓励你学习它们,但拉线十次并不一定很难或奇怪。
【讨论】: