专属运动的相关背景,适合需要以下服务的人士:
我一直对Vim中操作符后面的动作感到恼火。最近我听说这是因为它们通常是“排他的”:它们忽略了最右边的字符,而“包含”操作则会拾取光标下起点和终点之间的所有内容。出于某种原因,几乎所有操作员挂起模式下的运动都是这样工作的,例如,按“dl”只会删除光标下的字符(保留最右边的第二个字符),行尾的d 0会保留行尾的最后一个字符不受影响。有些动作,例如“d$”或“de”,会再次打破这个模式,并包含最右边的字符。更多信息,请参阅Motion.txt。
我觉得排他性的概念是不必要的,也是令人困惑的。我可以理解,当你在“搜索”一个单词、一个标记或一个搜索结果的下一个出现时,你通常会希望在操作时不选择运动的实际目标。排他性运动实现了这一点。但排他性概念的不一致性是很奇怪的。主要问题是当你向后移动某个地方时:该操作将保持最右边的字符(起始字符)不变,并且无论您执行什么操作,仍将对移动的目标进行操作,这与向前搜索不同。例如,您可能希望“edb”完全删除一个单词,而“bde”会删除。“dl”只删除光标下的字符(而不包括右边的字符),“dh”只删除左边的一个字符。This inconsistency is annoying, and seemingly makes it look like Vim secretly is keeping the cursor actually between letters on the left side of the cursor block.
幸运的是,在操作符后使用“v”可以切换字符操作的排他性,所以我已经能够用onoremap vb修复一些运动,比如b和h。许多“搜索”移动命令可以向后或向前移动,因此当向后移动时不可能使它们包括最右边的字符议案
- 我的问题简而言之 *:当相对于光标位置向后移动时,有没有一种简单的方法可以使所有操作都包含在一起(如包含光标起始点下的字符),而不影响向前移动?
(Even更好的做法是完全忘记整个排他性的事情,并让“v”切换是否包括运动的目标(因此,“dn”将从光标删除到搜索结果的开始,“dvn”将从光标删除到结果的结束),但这可能意味着编辑源。
很抱歉,我的帖子很长,很难解释,我很恼火。
2条答案
按热度按时间dbf7pr2w1#
在你描述的大多数场景中,Vim text-objects 肯定比motion更适合使用。
3mpgtkmj2#
我在in/exclusivity上也遇到了类似的问题。对我来说,事情似乎还不直观。我不太使用搜索动作(例如d/或d?),但在
:h search-offset
中发现了一些非常有用的东西。类似于
v/hello/e
的运动将通过搜索项的末尾,而不是在开始处停止。类似地,v?hello?e
将在搜索项的末尾停止,而不是转到开始处。如果我没理解错的话,这些动作可能会达到你想要的效果:
d/likes<cr>
--删除最多但不包括搜索结果dv?likes<cr>
--删除回上一个搜索结果d/likes/e<cr>
--删除搜索结果(包括搜索结果)d?likes?e1<cr>
--删除回上一个搜索结果,但不包括上一个搜索结果所以,为了回答你的问题(更好的部分),你可以使用
d/hello/e
通过'hello'删除,然后使用dn
通过下一个删除。它只在一个方向上工作得很好。你必须重新设置搜索到另一个方向,在这个例子中是dv?hello
,然后是dn
。下面是我如何开始理解这些命令的。它伤害了我的大脑。另外,对于其他阅读这个答案的人,我包括了对in/exclusive行为和
v
操作符(:h exclusive
和:h o_v
)的解释。(Take
^---^
为可视范围,|
s之间的字符为/
和?
将操作的字符)一个
当我们从行的开头搜索
likes
时,我们得到可视区域字符串
我们希望我们所做的任何操作都是对
|
s之间的字母进行操作型
这样,
d<motion>
就不会删除喜欢的第一个l
。这是Vim默认的行为。
两个
当我们从行的末尾搜索
likes
时,我们得到可视区域型
我们希望我们所做的任何操作都是对
|
s之间的字母进行操作型
这样,
d<motion>
会删除行尾和搜索开始之间的整个区域。由于Vim默认为在One中向前移动的方便行为,因此将被操作的字母实际上是
型
请注意,这与第一个行为是一致的--不包括高亮区域的最后一个字符。(注意:这就是Vim文档所说的
/
和?
运动是 exclusive 运动的意思)。我们可以通过使用
dv<motion
来改变这一点。通过使用dv<motion>
,操作的字母将是型
太好了,问题解决了。
到目前为止
d/likes<cr>
--删除最多但不包括搜索结果dv?likes<cr>
--删除回上一个搜索结果好了,现在我们怎么才能找到其他人?
???
--删除搜索结果(包括搜索结果)???
--删除回上一个搜索结果,但不包括上一个搜索结果一个搜索偏移量
e
就可以做到这一点(:h search-offset
)。这很棒,但它令人困惑的原因,至少对我来说。我们将在下面看到为什么。三个
当我们从行的开头(
v/likes/e
)搜索likes/e
时,我们得到可视区域型
我们希望我们所做的任何操作都是对
|
s之间的字母进行操作型
这样,
d<motion>
将删除likes
中的最后一个s
这是vim默认的行为。但请注意!现在它是 * 包括 * 可视区域中的最后一个字母。当使用
e
搜索偏移量时,Vim会自动将/
运动的行为更改为 * 包括 *四个
当我们从行的末尾(
v?likes?e
)搜索likes?e
时,我们得到可视区域型
我们希望我们所做的任何操作都是对
|
s之间的字母进行操作型
这样,
d<motion>
会删除行尾和排除搜索结果之间的整个区域。由于Vim默认为在Three中向前移动的方便行为,因此将被操作的字母实际上是
型
更奇怪的是,因为Vim的默认行为现在是包含
e
的搜索偏移量,所以walking中的最后一个g
被默认包含。不需要包含dv
。我们可以使用
d?likes?e1
来修改它。1
的意思是“在搜索结果的末尾向右移动一个字符”。这将给给予型
好的,这就是我们要找的。