22

如何在 Emacs 中轻松复制一行 10 次?我找不到复制行快捷方式或功能。我可以使用 C-aC-spcC-eM-w 费力地复制该行,但是我怎样才能将其粘贴多次?

在我去编写自己的函数之前的任何想法。

4

10 回答 10

21

您可以为此使用键盘宏:-

Ca Ck Cx ( Cy Cj Cx ) Cu 9 Cx e

解释:-

  • Ca : 转到行首
  • Ck : 杀戮线
  • Cx ( : 开始录制键盘宏
  • Cy : Yank 杀线
  • Cj : 移动到下一行
  • Cx ) : 停止录制键盘宏
  • Cu 9 : 重复 9 次
  • Cx e : 执行键盘宏
于 2008-09-16T13:13:53.327 回答
11

复制

如果您经常使用线条,您可能希望在未选择任何区域时使复制 ( 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 :)

于 2008-09-16T13:30:57.700 回答
11

您可能知道这一点,但对于许多命令,“Cu 10”前缀就可以解决问题。不幸的是,对于 Cy yank 命令,“Cu”被重新定义为“返回杀伤环中的那么多物品,然后猛拉该物品”。

我认为您可能可以将复制注册和插入注册命令与 Cu 前缀命令一起使用,但显然这也不起作用。

Cx z,“重复上一个命令”似乎对 Cu 免疫。

另一个想法是使用 M-: 来获得 Eval 提示并输入一些省略号。我认为像 (dotimes '10 'yank) 这样的东西可能会这样做,但似乎没有。

所以看起来在宏上使用 Cu 可能确实是你能做的最好的事情,而不是编写自己的小函数。

如果我投票,我会投票给 kronoz 答案。

于 2008-09-16T14:02:53.957 回答
7

在此示例中,您不需要同时使用 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 个副本:

  • CS-Backspace : 杀死这一行
  • F3 : 启动宏
  • Cy:拉线
  • C-1 C-0 F4 : 做 10 次猛拉

不如 yy 10 p 短,但非常接近。:)

于 2009-10-14T17:57:43.727 回答
3

这是我从 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次。

于 2008-09-16T15:37:06.493 回答
2

我知道重复任意命令的唯一方法是使用键盘宏的“按参数重复”功能。

Ca C-space down Mw Cx ( Cy Cx ) C-9 Cx e

  • Ca : 转到行首
  • C-space : 设置标记
  • down : 转到下一行的开头
  • Mw : 复制区域
  • Cx ( : 启动键盘宏
  • Cy : Yank 复制的行
  • Cx ) : 结束键盘宏
  • C-9 Cx e :执行键盘宏九次。

与vim相比,这有点弱。但这仅仅是因为 vim 在这类事情上的效率惊人。

如果您真的很喜欢模态 vi 类交互,您可以使用 vi 仿真模式之一,例如 viper 模式。检查在线 emacs 手册的“仿真”部分。

于 2008-09-16T13:32:40.787 回答
0

你会想要杀死这条线:Ca Ck,然后是 Cy 或?

于 2008-09-16T13:08:53.213 回答
0

我不知道直接等效(Cy 10 次是我所知道的最好的),但您可能对 Viper 感兴趣,它是 emacs 的 vi 仿真包。它是标准 emacs 发行版的一部分。

于 2008-09-16T13:26:45.620 回答
0

根据 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 的前缀的情况下调用它,所以。

不确定这是否是一个好主意,但我用这个替换了我的,我会看看情况如何。

于 2009-10-29T02:40:15.203 回答
-1

你得到 Ck 行,你用 Cu 10 使下一个命令发生十次,然后你用 Cy 粘贴该行。很简单。

如果你总是想让 Ck 做整行,你可以设置 kill-whole-line 为 t。不再摆弄 Ca 或 Ce。

你可以用花哨的杀戮环、寄存器和宏做很多事情,我鼓励你学习它们,但拉线十次并不一定很难或很奇怪。

于 2008-09-16T18:26:10.173 回答