`vi{`可以扩大当前的视觉选区,但是我能以类似的方式缩小视觉选区吗?`

6

那么如果我有这样的文本:

if answer == 42 {                        #1
    if bugs == 'bunny' {                 #2
        if injury == 'but a scratch' {   #3
            // do the thing              #4
        }                                #5
    }                                    #6
}                                        #7

我现在将光标放在// do the thing上,然后执行va{命令,接着我会选择从第3行到第5行的{},再次执行a{命令,然后我会选择从第2行到第6行的{}

但是糟糕的是,我现在意识到我实际上只想选择从第3行到第5行的{}。恐怖的是,vim通常的大写 => 相反的方法不起作用,A{只会在行尾添加一个{

我能否在不取消选择、移动光标并重新选择的情况下从大的选择中缩小到更小的选择?在这个例子中,使用一些hjklwbeo手动更改选择也很简单,但在实践中,代码块通常又长又复杂。

我知道如果在一个父块内有多个兄弟块将会产生歧义,但我会很满意地选择第一个,因为这种情况很少发生。

谢谢!

编辑:有一个能够做到这一点的插件也是一个很好的选择。如果没有这样的插件,我会快速做一个MVP,并在此处发布链接以供评论。


2
相关:https://dev59.com/poTba4cB1Zd3GeqP75K9 - T.J. Crowder
2
我怀疑不多有人需要在可视模式下使用 A/I 来完成他们的工作。也许制作一个插件来实现你所建议的行为会受到欢迎。 - Enlico
3
根据您的帖子,我决定制作vim-visual-history插件,该插件可以保留以[v]v[V]V开始的之前的视觉选择,并可遍历记录。因此,在您的情况下,您只需按一下[v即可返回先前的一个选择。该插件已经可用,但仍在建设中。 - mattb
2
@Enlico,我刚刚制作了vim-visual-history插件来实现它。 - mattb
2个回答

5

文本对象总是向外扩展,因此即使您尝试像 i{ 这样的操作,它覆盖的区域比 a{ 小,选择仍然会被扩展。

正如您所提到的,您可以使用 o 和各种运动来更改选择的几何形状,但这很麻烦。离开可视模式,移动光标,然后重新选择的替代方法同样麻烦。

构建自定义的“缩小”伪文本对象可能是可能的,并且社区可能会乐意欢迎它。

---编辑---

下面的快速而简单的代码似乎适用于 a{a(a[a<

function! InvertObject()
    call getline('.')[getcurpos()[2] - 1]->search('b')
endfunction
xnoremap A{ <Esc><Cmd>call InvertObject()<CR>va{
xnoremap A{ <Esc><Cmd>call InvertObject()<CR>va(
xnoremap A[ <Esc><Cmd>call InvertObject()<CR>va[
xnoremap A< <Esc><Cmd>call InvertObject()<CR>va<

请参见 :help getcurpos():help getline():help search()
添加“内部”变体可能更加复杂,因为根据各种参数,光标可能不总是停留在相同的位置。
由于下列文本对象有几个原因,上面的代码片段不能直接使用:
  • awaWasap,因为它们并没有被特定的标记所包围。虽然添加as可能是最容易的。
  • at,因为分隔符标记比单个字符更复杂。
  • a'a"a`,因为它们不像其“括号”近亲一样扩展,所以需要完全不同的逻辑。

1
好的,我猜你不知道已经存在解决这个问题的插件了吧?否则我可能会自己去做,并在我有MVP时在这里发布。 - beyarkay
@beyarkay,请看我的修改。 - romainl
2
根据OP和您的帖子,我决定制作vim-visual-history插件,该插件可以保留以前的可遍历记录,包括[v]v[V]V的视觉选择。该插件已经可以使用,但仍在建设中。 - mattb

2
根据您的帖子,我决定制作一个vim-visual-history插件,它可以记录以前使用[v]v[V]V进行的可遍历的视觉选择。这些命令的小写版本也可以接受计数。因此,在您的情况下,您只需要执行[v即可返回一个选择。
[count][v : Reselect previous visual selection
[count]]v : Reselect next visual selection
[V : Reselect first visual selection
]V : Reselect last visual selection

enter image description here

命令计数的演示:

enter image description here


1
这看起来很不错!我现在不在电脑旁,但今晚稍后会好好查看它。 - beyarkay
很酷!我希望你和其他人都喜欢它。 - mattb

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