Vim:重复上一个动作?

77
假设我正在视觉模式下,然后我键入“aw”以扩展视觉区域以包括下一个单词。 我想随后包括接下来的几个单词。是否有一个按键可以按来重复前一个动作(包括文本对象动作)?
我知道“.”重复前一个更改,“n”重复前一个搜索,以及其他“重复”命令,但我不知道任何命令可以重复前一个动作(无论是什么动作)。

19
内置的重复运动命令“,”和“;”只适用于fFtT类型的动作。对于一般的命令,你需要使用一个插件。 - Hotschke
1
有一些事情你仍然可以在没有插件的情况下完成。例如,请参考https://superuser.com/questions/429917/repeat-last-normal-mode-command-including-moves-in-vim。我已经整理了我在[我的回答](https://dev59.com/0l8d5IYBdhLWcg3wsDxW#76778797/)中找到的内容。 - joeljpa
6个回答

81

有一个命令可以重复使用f、t、F或T的每个动作。请记住:
fx 跳转到下一个字符x的位置
Fx 跳转到上一个字符x的位置
tx 跳转到下一个字符x之前的位置
Tx 跳转到上一个字符x之后的位置
要重复这些动作,请按

;

要将它们倒序重复(相反的方向),请按

,

5
这绝对是最好的答案。 - Caveman
8
值得注意的是,当重复键入tT时,使用分号;与仅再次输入命令是不同的。例如,如果您键入t(t(,您将无法跳过第一个(字符。但如果您键入t(;,则会跳转到第二个(。请参见:help cpo-; - Andrew Keeton
1
似乎没有内置的方法可以重复像 gE10j 这样的动作。 - Nikhil CSB
1
@NikhilCSB 你还可以做一些事情。查看我的回答 - joeljpa

30

有一些插件可以提供此功能:


4
我想要重复 [{ 样式的动作。repeatable-motions.vim 可以直接使用(repmo 似乎不行)。 - dsummersl
3
它存在于Emacs中。Vim开发者们,赶快跟上啊!https://dev59.com/r3VC5IYBdhLWcg3wfxM8 - Nathan majicvr.com

4

2

不使用插件,使用;

下面是详细示例:

int function1(){
   some code here;
   ...
   ...
   return 0;
}

int function2(){
   some code here;
   ...
   ...
   return 0;
}

现在假设您想要重写函数1和函数2中 {} 内部的部分。

  • 将光标放在 {} 内的任意位置
  • 从普通模式(ESCctrl+c),按下 di}(表示删除内部的“{”)
  • 现在您已经删除了函数中的所有内容
  • 将光标移动到函数2的 {}
  • 按下 ;.

对于可视化模式,我认为宏是您唯一的选择(对于 aw 可能过于繁琐)

  • 要开始录制宏,请按下 q + q(最后一个 q 可以是任何字母。它是宏将保存的位置)
  • ...执行您想要重复的操作...
  • 再次按下 q 停止录制

要重放这些操作(甚至在可视化模式下):

  • @q(或任何您保存到的字母)

要重放这些操作 99 次:

  • 99@q(或任何您保存到的字母)

3
有点震惊,我现在才了解到 di} 这个运动... - Eidolon108
2
如果你只按 . 而不是 ;,它会起作用吗? - Jake
虽然这很有趣,我确实学到了一些东西,但我不明白这如何回答问题。楼主问的是如何重复之前的动作。这会删除函数下的文本然后再次执行吗?如果我理解错了,请纠正我。 - joeljpa

1

如果你的目标是不使用插件,仍然有一些希望。

案例1

对于简单的跳转动作,nelstrom的答案(1)效果很好。对于分别执行100j100k

  • :+100:-100
  • @:(重复上一个命令)。

案例2

使用norm命令。从手册中可以得知:

执行普通模式命令{commands}。这使得能够在命令行上输入普通模式命令。

  • norm 100j然后跟上我们可靠的@:

这里的优势在于我们可以将其应用到其他动作上,比如说norm 10l表示向右移动10步。

案例3

宏命令是你的朋友。JK ABC确实说过 "需要更多的精神力量" (2) ,一旦你学会了使用它们的基础知识,你就可以在编辑器中对所有重复性任务造成严重破坏。

当涉及到重复动作时,它们非常出色。如果你对宏命令还不熟悉,请查阅一下基础知识。

  • q1(开始录制一个存储在寄存器 1 的宏命令)
  • 100j(你的移动动作)
  • q(停止录制)
  • @1(重新播放寄存器 1 中的宏命令。如果只执行一次,之后你可以使用更轻松的 @@ 来重新运行上次使用的宏命令)

这种方法甚至更加灵活,因为你可以将任何自定义动作存储在不同的寄存器(a-Z, 0-9等)中,并且在手腕一转之间执行任何一个。

参考资料

1. 从[这里](nelstrom's answer)可以找到关于[如何一次又一次地跳过X行](How to jump down X amount of lines, over and over)的答案。 2. 在[这里](JK ABC's answer)可以找到关于在Vim中重复上一个正常模式命令(包括移动)的答案(来自Super User)。

1
我创建了一个小插件vim-remotions,它允许使用;,键重复上次的动作(就像ft动作一样)。
默认情况下,它重复以下动作:]m]M]]][}g;]b]l]q]t]g
它使用缓冲区中由filetype定义的动作。
可以配置要重复的动作列表。
它可以重复动作及其计数,也可以只重复动作。
它可以按照初始动作的方向重复动作(就像;,对于ft一样),也可以按照文档的方向重复动作,以便更加直观。
感谢@romainl的提示。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接