Emacs 相当于 Vim 的 yy10p?

发布于 2024-07-04 16:26:52 字数 120 浏览 6 评论 0原文

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

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

土豪 2024-07-11 16:26:52

您将想要删除该行:Ca Ck,然后 Cy 或 ?

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

只是一片海 2024-07-11 16:26:52

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

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.

梦里泪两行 2024-07-11 16:26:52

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

然后我会使用 Cu 10 F9 d 来复制一行 10 次。

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.

跨年 2024-07-11 16:26:52

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

Ca C-空格向下 Mw Cx ( Cy Cx ) C-9 Cx e

  • C-a : 转到行首
  • C-space : 设置标记
  • 向下 : 转到下一行开头
  • M-w : 复制区域
  • C-x ( : 启动键盘宏
  • C-y : 复制复制行
  • C-x ) : 结束键盘宏
  • C-9 Cx e : 执行键盘宏九次。

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

如果您确实渴望类似 vi 的模态交互,则可以使用其中一种 vi 模拟模式,例如 viper 模式。 查看在线 emacs 手册的“仿真”部分。

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.

故事和酒 2024-07-11 16:26:52

您可以使用键盘宏:-

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

说明:-

  • Ca : 转到行首
  • C-k : 终止行
  • C-x ( : 开始录制键盘宏
  • C-y : 猛拉杀死行
  • C-j : 移动到下一行
  • C-x ) : 停止录制键盘宏
  • C-u 9 : 重复 9 次
  • C-x e : 执行键盘宏

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
烟花易冷人易散 2024-07-11 16:26:52

复制

如果您经常使用线条,您可能需要复制 (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)。

另一种方式
您也可以只停留在 Mx viper-mode 并使用 yy10p :)

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 :)

滥情哥ㄟ 2024-07-11 16:26:52

您可能知道这一点,但对于许多命令来说,“Cu 10”前缀就可以解决问题。 不幸的是,对于 Cy yank 命令,“Cu”被重新定义为“返回杀戮环中的许多项目,并拉出该项目”。

我认为您也许可以将复制到寄存器和插入寄存器命令与 Cu 前缀命令一起使用,但显然这也不起作用。

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

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

因此,看起来在宏上使用 Cu 确实可能是您除了编写自己的小函数之外所能做的最好的事情。

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

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.

断桥再见 2024-07-11 16:26:52

在此示例中,您不需要同时使用 Cx ) 和 Cx e。

您可以直接将重复参数提供给 Cx )。 这将停止录制并重复宏,一步完成。 或者您可以跳过 Cx ) 并直接转到 Cx e,因为 Cx e 将在重复之前结束录制。

选择哪种方式取决于您希望重复计数的工作方式。 对于 Cx ),您可以说出总共需要多少次重复(在本例中为 10 次)。 对于 Cx e,您需要说明还剩下多少次重复(即 9)。


Ca Ck Ck 也会杀死尾随的换行符,因此您不必稍后自己将其放回去。 它比使用标记更快,并且不需要您更改任何变量。

更好的是(除非您在终端中),您可以使用 CS-Backspace* 来终止整行,无论您位于其中的哪个位置。

[* 如果您使用的是 X windows,请确保输入 Shift(而不是 alt),否则您可能会终止会话!]

说到终端,如果您发现可以,M-9 是一个不错的选择不要输入 C-9。


在 Emacs 22 及更高版本中,默认情况下 F3 启动宏,F4 结束/重复宏。 您只需按 F3 开始录制,完成后按 F4,然后再次按 F4 重复宏。 (F4 也带有一个参数。)


将所有这些放在一起,以获得当前行的 10 个副本:

  • CS-Backspace :终止此行
  • F3 :启动宏
  • C-y :拉动
  • C-1 C-0 行 F4 :拉动 10 次

虽然不像 yy 10 p 那么短,但也很接近了。 :)

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. :)

拥有 2024-07-11 16:26:52

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

如果您总是希望 Ck 执行整行,可以将kill-whole-line 设置为t。 不再需要摆弄 Ca 或 Ce。

您可以使用花哨的kill环、寄存器和宏做很多事情,我鼓励您学习它们,但是将一条线拉动十次并不一定是困难或奇​​怪的。

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.

北方的巷 2024-07-11 16:26:52

首先,您需要在 .emacs 中绑定此键:

;; yank n times
(global-set-key "\C-y" (lambda (n) (interactive "*p") (dotimes (i n) (clipboard-yank))))

然后您可以执行以下操作:

C-a C-SPC C-n M-w C-u 10 C-y

Ca C-SPC Cn Mw - 选择整行
Cu 10 Cy - 重复“剪贴板猛拉”10 次

First you need this key binding in your .emacs:

;; yank n times
(global-set-key "\C-y" (lambda (n) (interactive "*p") (dotimes (i n) (clipboard-yank))))

Then you can do:

C-a C-SPC C-n M-w C-u 10 C-y

C-a C-SPC C-n M-w - select whole line
C-u 10 C-y - repeat "clipboard-yank" 10 times

暮凉 2024-07-11 16:26:52

根据 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,所以。

不确定这是否是一个好主意,但我用这个替换了 My,我会看看效果如何。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文