的行为;重复最后一个命令困扰我。你能帮助我做得更好吗?

时间:2009-10-06 04:33:22

标签: vim

好的,假设我们有一行文字:

[s]tackoverflow rocks

其中括号显示光标在正常模式下的位置。按下tr后,您会收到:

stackov[e]rflow rocks

现在为有趣的部分。如果你按;重复命令会怎么样?没有! Vim找到下一个'r'(紧靠光标右侧)并将其自身定位在其左侧(已经存在的位置)。

我希望;将光标前进到此位置:

stackoverflow[ ]rocks

这可以通过在按l之前使用;向右移动一个字符来实现,但额外的步骤令人恼火。 T存在类似问题,但fF没有。有没有办法让;tT的方式行事?

4 个答案:

答案 0 :(得分:31)

从Vim版7.3.235开始,这种烦恼已被修改。现在,默认值是您首先想到的行为:;使光标在第二个“r”之前跳转到右边。

这是补丁公告:

  

补丁7.3.235
  问题:“;”卡在“t”命令上,没用   解决方案:添加';' 'cpo'中的旗帜。 (Christian Brabandt)

旧行为已被降级为兼容性选项。您可以使用:set cpo+=;将其恢复。请参阅:h cpo-;

答案 1 :(得分:9)

也许这不是您正在寻找的答案,但我无法抗拒为此编写VIM脚本。我把它放在我的.vimrc中,它对我有用:

map ; :call Semicolon()<CR>
function Semicolon()
   let s:pos1 = getpos(".")
   normal! ;
   let s:pos2 = getpos(".")
   if s:pos1 == s:pos2
      normal! 2;
   endif
endfunction 

基本想法是;不会移动到下一个匹配,但2;会(如果匹配)。该脚本在;之后支持tTfF。实现,命令的最简单方法是为此编写类似的函数。

修改 在Luc的出色建议之后改变了剧本

<强> EDIT2

好吧,这些事情总是比我原先想象的要困难。当前映射存在以下问题:

  1. 假设您执行了上述tr之类的搜索。那么d;c;应该做什么?就我而言,他们应该删除或更改直到第一个r而不是第二个v;;;;。这可以通过仅对正常模式和可视模式进行映射来解决,而不是操作员暂挂模式。
  2. 当前映射在可视模式下不起作用。即,如果您在第一个;之后键入:call,则编辑器不再处于可视模式(因为@=)。这可以通过使用:call而不是,来调用函数来解决。
  3. 所以现在我在.vimrc中结束了以下内容(我还为;" Remap ; and , commands so they also work after t and T " Only do the remapping for normal and visual mode, not operator pending " Use @= instead of :call to prevent leaving visual mode nmap ; @=FixCommaAndSemicolon(";")<CR> nmap , @=FixCommaAndSemicolon(",")<CR> vmap ; @=FixCommaAndSemicolon(";")<CR> vmap , @=FixCommaAndSemicolon(",")<CR> function FixCommaAndSemicolon(command) let s:pos1 = getpos(".") execute "normal! " . a:command let s:pos2 = getpos(".") if s:pos1 == s:pos2 execute "normal! 2" . a:command endif return "" endfunction 创建了一个函数):

    {{1}}

答案 2 :(得分:2)

2评论一:你能映射;到你要找的lt_命令?第二:为什么不使用2tr或/ r后跟n呢?

答案 3 :(得分:1)

听起来问题更多的是t而不是;的行为。

在你的例子中,我们假设你从'e'开始:

stackov[e]rflow rocks

我猜你(合理地)希望tr跳到[ ]rocks而不是留在原地。

如果是这样,您应该保留;,并将t重新映射到lt或其他内容。