vim 使向后的动作总是包容的?

igsr9ssn  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(146)

专属运动的相关背景,适合需要以下服务的人士:
我一直对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”将从光标删除到结果的结束),但这可能意味着编辑源。
很抱歉,我的帖子很长,很难解释,我很恼火。

dbf7pr2w

dbf7pr2w1#

在你描述的大多数场景中,Vim text-objects 肯定比motion更适合使用。

3mpgtkmj

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时,我们得到可视区域

John likes walking
^----^

字符串
我们希望我们所做的任何操作都是对| s之间的字母进行操作

|John |likes walking
 ^-----^


这样,d<motion>就不会删除喜欢的第一个l
这是Vim默认的行为。
两个
当我们从行的末尾搜索likes时,我们得到可视区域

John likes walking
     ^-----------^


我们希望我们所做的任何操作都是对| s之间的字母进行操作

John |likes walking|
      ^-----------^


这样,d<motion>会删除行尾和搜索开始之间的整个区域。
由于Vim默认为在One中向前移动的方便行为,因此将被操作的字母实际上是

John |likes walkin|g
      ^------------^


请注意,这与第一个行为是一致的--不包括高亮区域的最后一个字符。(注意:这就是Vim文档所说的/?运动是 exclusive 运动的意思)。
我们可以通过使用dv<motion来改变这一点。通过使用dv<motion>,操作的字母将是

John |likes walking|
      ^-----------^


太好了,问题解决了。

到目前为止

  • d/likes<cr>--删除最多但不包括搜索结果
  • dv?likes<cr>--删除回上一个搜索结果

好了,现在我们怎么才能找到其他人?

  • ???--删除搜索结果(包括搜索结果)
  • ???--删除回上一个搜索结果,但不包括上一个搜索结果

一个搜索偏移量e就可以做到这一点(:h search-offset)。这很棒,但它令人困惑的原因,至少对我来说。我们将在下面看到为什么。
三个
当我们从行的开头(v/likes/e)搜索likes/e时,我们得到可视区域

John likes walking
^--------^


我们希望我们所做的任何操作都是对| s之间的字母进行操作

|John likes| walking
 ^--------^


这样,d<motion>将删除likes中的最后一个s
这是vim默认的行为。但请注意!现在它是 * 包括 * 可视区域中的最后一个字母。当使用e搜索偏移量时,Vim会自动将/运动的行为更改为 * 包括 *
四个
当我们从行的末尾(v?likes?e)搜索likes?e时,我们得到可视区域

John likes walking
         ^-------^


我们希望我们所做的任何操作都是对| s之间的字母进行操作

John likes| walking|
         ^--------^


这样,d<motion>会删除行尾和排除搜索结果之间的整个区域。
由于Vim默认为在Three中向前移动的方便行为,因此将被操作的字母实际上是

John like|s walking|
          ^-------^


更奇怪的是,因为Vim的默认行为现在是包含e的搜索偏移量,所以walking中的最后一个g被默认包含。不需要包含dv
我们可以使用d?likes?e1来修改它。1的意思是“在搜索结果的末尾向右移动一个字符”。这将给给予

John likes| walking|
         ^--------^


好的,这就是我们要找的。

相关问题