好的,假设我们有一行文字:
[s]tackoverflow rocks
其中括号显示光标在正常模式下的位置。按下tr
后,您会收到:
stackov[e]rflow rocks
现在为有趣的部分。如果你按;
重复命令会怎么样?没有! Vim找到下一个'r'(紧靠光标右侧)并将其自身定位在其左侧(已经存在的位置)。
我希望;
将光标前进到此位置:
stackoverflow[ ]rocks
这可以通过在按l
之前使用;
向右移动一个字符来实现,但额外的步骤令人恼火。 T
存在类似问题,但f
和F
没有。有没有办法让;
以t
和T
的方式行事?
答案 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 强>
好吧,这些事情总是比我原先想象的要困难。当前映射存在以下问题:tr
之类的搜索。那么d;
或c;
应该做什么?就我而言,他们应该删除或更改直到第一个r
而不是第二个v;;;;
。这可以通过仅对正常模式和可视模式进行映射来解决,而不是操作员暂挂模式。;
之后键入:call
,则编辑器不再处于可视模式(因为@=
)。这可以通过使用:call
而不是,
来调用函数来解决。所以现在我在.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
或其他内容。