Leap.nvim 是一个在 Vim 和 Neovim 社区非常流行的移动插件,可以让你在 Vim 中快速定位到代码中的任何位置。但是,由于 VSCodeVim 不支持该插件,看到别人使用 leap.nvim 的效果,我也感到十分眼红。
更令人郁闷的是,VSCodeVim 的维护者似乎也没有打算更新该插件。在对应的 issue 中,大家的反馈已经很久没有得到回应了。
于是,我决定自己动手实现该插件。经过一番努力,现在已经可用了,并且在 VSCodeVim 中使用效果非常棒。
不得不说,由于 VSCodeVim 不支持插件系统,所以插件的开发确实比较麻烦,需要深入了解它的运行机制。VSCodeVim 果然是个阉割版啊。
使用
下面介绍下目前已经支持的功能:
- 上下搜索
- 双向搜索
- 可视化模式
- 自定义 Leap 标签
- 自定义标记点显示位置
- 大小写敏感
接下来将逐一介绍。
上下搜索
这是 Leap 最基本的功能,通过按下 s char1 char2
向下搜索,按下 S char1 char2
向上搜索。
例如,按下 "s o n" 就可以向下搜索文本:
按下 "S o n" 就可以向上搜索文本:
有个小细节:如果匹配点只有一个,则会自动跳转过去:
如果你想要搜索的字符后面是空白符,则可以使用 s char space
。例如:
这里想跳转到 "h" 后面,但是 "h" 后面是一个空白符,这时候只需要按下 s h space
就搞定啦。
如果你想执行上一次的搜索,只需要按下 s enter
就可以执行上次的搜索了。搜索的顺序也是按照上一次的顺序来的:
这里第一次搜索的是 s o n
,然后想重复执行的时候按下 s enter
搞定。
预览模式
这里要特别说明一下,Leap 有一个预览模式。按下 "s char" 的第一个字符的时候,会提前显示标记点位置,让你先有个心理预期,知道等会可能会跳转的点在哪里。然后当按下第二个搜索字符的时候,就会只剩下符合要求的标记点,然后就可以通过按键的字符来跳转了。
注意:很多同学在使用的时候会错把第一个提示点当成跳转点,发现按下的时候不生效。
支持双向搜索
当然,有些用户可能不想区分搜索方向,也不想按下 S
(需要按下 shift
,对于像我这样的懒人来说有些麻烦)。因此,为了满足这些用户的需求,还增加了双向搜索功能,只需按下一个 s
就可以搞定啦!
只需要在 settings.json
中设置这个配置 "vim.leapBidirectionalSearch": true
。
跳转点的设计也非常巧妙,为了让标记点均匀分布在上下两个方向,我特意设计了下面的算法,默认的 label
是 sklyuiopnm,qwertzxcvbahdgjf;
,双向搜索的跳转点会变成:下一个用 s
,上一个用 k
,下一个用 l
,上一个用 y
。这样设计可以保证距离较近的跳转点都是单字符,并且还能保证使用 s
必定跳转到最近的下一个,使用 k
必定跳转到最近的上一个。
支持可视化模式
搜索功能也可以在可视化模式下使用,比如:
先按下 v
进入可视化模式,然后按下 s e r
来搜索 e r
跳转选中,非常方便。
这里有个小小的遗憾,向上搜索的时候不可以使用 S
,因为 S
被 Surround
插件占用了。但是如果开启双向搜索的模式的话就不会有这个烦恼了,因为 s
可以同时上下搜索。
在可视化模式下,不光可以使用 s
,还可以使用 x
和 X
:
那么 s x
的区别你看出来了吗?区别就是 s
是包含搜索的两个字符的,而 x
是不包含的。
例如,按下 s i n
可以看到是包含 In
的:
而按下 x i n
可以看到是不包含 In
的:
支持自定义 Leap 标签
如果您对默认的 labels
不满意,可以通过配置进行修改。
vim.leapLabels = 'sklyuiopnm,qwertzxcvbahdgjf;';
这里是和 easymotion
的 labels
对齐的,因此如果之前使用过 easymotion
的话,你应该会非常熟悉, 其目的就是为了保持操作一致,因为这 2 个插件可以结合起来使用。
支持自定义标记位置
您还可以自定义 Leap 的标记位置。通过配置 "vim.leapShowMarkerPosition": "target"
,标记将显示在搜索字符的位置,如下动画所示:
默认情况下,标记将显示在要跳转到的字符后面,但在我的使用体验中,跳转到实际标记更为直观。
支持大小写敏感
您还可以通过配置 "vim.leapCaseSensitive": false
来自定义大小写敏感度。默认情况下,大小写敏感度关闭,这意味着大写和小写字母被视为相同。
聊聊和 leap.nvim 的差异在哪里
由于 VSCodeVim 的底层实现问题,有一些 leap.nvim 的功能无法实现,另外还有一些功能进行了微小的修改以适应与原有功能的配合使用。
不支持在 OperatorPendingMode 使用
也就是说不可以配合 d
y
p
之类的 operator
这是由于 VSCodeVim 的底层实现问题导致的。但是支持在可视化模式下使用,只需要多按一个 v
即可。
多跳转点的实现方式与原生 leap.nvim 不同
在 leap.nvim 中,如果匹配点过多,则需要使用 space
和 tag
切换相应的组。这种方法的问题在于,如果匹配了三个组,则需要按两次 space
进行选择,这种情况非常极端,可能不会经常出现。
在我的实现中,参考了 easymotion 的跳转实现方式,从标记点从一个字母开始,如果超过一个字母,则使用两个字母。这样的好处是,无论匹配了多少次,两个字母都可以直接定位标记点。另外一个原因是,这种实现方式与 easymotion 统一,因为有些移动场景使用 easymotion,所以有两套选择方式会很难受。
安装
如果你看到这里,肯定是想尝试一下了。
很遗憾,由于官方还没有合并我的 PR,所以你需要下载我的 vim 版本来安装。
不过也不算麻烦,我已经打包好了,只需要下载下来就可以了:
- 下载 vim 插件安装包 github.com/cuixiaorui/…
- 执行
code --install-extension vim-1.25.2.vsix --force
需要注意的是,路径必须正确:
视频教程
当然,如果通过本文你仍然无法弄清如何安装和使用,还有视频教程可以观看:
结尾
好了,如果你对插件的功能有任何意见或建议,请留言给我反馈。
最后,有些同学可能会问:为什么不用 neovim 呢?用 VSCodeVim 不是很低端吗?这其实完全是个人偏好的问题,有人喜欢吃甜的,有人喜欢吃苦的,没有必要在这些没有意义的问题上纠结。这篇文章是送给使用 VSCodeVim 的同学的。
对了 想看代码实现的同学这是 pr 链接:github.com/VSCodeVim/V…