vim-easymotion和vim-sneak都是vscode中vim内集成的插件,我们可以更改vim的默认配置很快的开启并使用
vim-easymotion
vim-easymotion是为了解决什么问题?
在使用vim
的过程中经常会遇到组合按键的情况,比如18j
、10k
这样的组合指令,遇到这种指令手就需要经常向上移动去按数字按键,导致打起来并不舒服,而vim-easymotion
的设计就可以减少手去按数字按键的频率,也可以实现在屏幕可视范围内让光标进行快速跳转的操作。
如何开启easymotion插件
打开VScode的settings.json
配置文件,加入如下配置:
{
...,
"vim.easymotion": true,
"vim.leader": "<space>",
}
vim.easymotion
设置为true
表示启用vim内置的vim-easymotion
插件。vim.leader
设置vim
中对应的leader
键
什么是
<Leader>
?
- vim 中有本身内置了不少快捷键以及各种插件,为了防止按键冲突以及进一步丰富按键的组合,vim推出了
<Leader>
的概念,实际上可以将这个概念理解为vim中的老板键,通过老板键配合其他按键的组合可以完成各种各样的效果。
vim-easymotion的内置指令
<Leader>
<Leader>
w
:高亮光标后的所有单词的开头<Leader>
<Leader>
b
:高亮光标前的所有单词的开头<Leader>
<Leader>
e
:高亮光标后的所有单词的结尾<Leader>
<Leader>
ge
:高亮光标前的所有单词的结尾<Leader>
<Leader>
h
:高亮光标前的所有单词的开头和结尾、驼峰、_
或者#
之后的内容<Leader>
<Leader>
l
:高亮光标后的所有单词的开头和结尾、驼峰、_
或者#
之后的内容<Leader>
<Leader>
j
:高亮光标下方的所有行的开头<Leader>
<Leader>
k
:高亮光标上方的所有行的开头<Leader>
<Leader>
<Leader>
j
:高亮所有单词的开头和结尾、驼峰、_
或者#
之后的内容
输入对应命令后,会有高亮的文本,此时输入对应的字符就可以快速将光标跳转到对应的位置了
vim-sneak
vim-sneak解决了什么问题?
我们知道在vim
中使用f
、F
在只能在行内进行快速跳转,并且在使用的时候只能快速搜索单个字符,很难满足大部分的使用场景,而vim-sneak
插件可以解决这个问题。vim-sneak
相比vim
自带的f
以及F
解决了上述的两个问题,即在按下s
后可以跟上两个字符进行全局快速搜索,并未可以使用;
不断的向下搜索,将光标移动到相同匹配结果的内容上。为了使用更方便,则这里会对vscode
进行配置,将F
与f
分别映射到S
与s
上,用于替换(增强)原先的F
与f
的功能。
开启vim-sneak并对vscode进行配置
打开vscode
的setting.json
这个加入如下的配置选项开启vim-sneak
的基本功能:
{
...,
"vim.sneak": true,
}
启用了sneak
后,现在需要对f
、F
做重新映射,将其映射到s
与S
上:
首先,如果将f/F
映射到s/S
上,就会产生不能使用s
和S
两个按键原先对应的功能:
s
:删除光标所在字符并进入 insert 模式;S
:删除光标所在行从开头非 blank 字符到行尾的内容
所以我们需要重新设置s
与S
对应的按键功能,这里我们将s
设置为cl
(c
删除并进入编辑模式,l
代表影响的范围,删除光标右侧的字符),而S
设置为^C
(^
移动到本行第一个【非空字段】的位置,C
删除从光标当前位置到行尾的内容)。
看到这里有没有发现到这里的按键配置很奇怪?是的,这样配置会产生递归映射按键的情况如f
->s
->cl
,而vscode
的vim
插件为了防止出现递归映射的情况,给了对应的解决方案——配置项:"vim.normalModeKeyBindingsNonRecursive"
扩展阅读:
"vim.normalModeKeyBindingsNonRecursive"和"vim.normalModeKeyBindings"有什么区别?
官方文档中截取的相关内容:
这里的解释是如果我们在
"vim.normalModeKeyBindings"
的模式下,进行j
、k
两个按键的交换,此时按下j
相当于按下了k
,而按下k
又会触发按下j
,这样就会不换递归循环调用下去,如果将其配置到"vim.normalModeKeyBindingsNonRecursive"
,则就不会有这种递归调用的问题,非递归键绑定意味着键绑定不会递归地再次触发其他键绑定。换句话说,如果一个键绑定包含在另一个键绑定中,设定为非递归将会阻止第一个键绑定再次触发第二个键绑定。总结:
vim.normalModeKeyBindingsNonRecursive
确保设置的键绑定不会触发其他键绑定,避免递归问题。vim.normalModeKeyBindings
允许设置键绑定,但可能会触发递归的链式调用问题。
在setting.json
中加入vim.normalModeKeyBindingsNonRecursive
的基本配置:
{
...
"vim.normalModeKeyBindingsNonRecursive": [
// 通过将F映射为S,F映射为s,启用更好用的sneak插件
// 通过将s重新映射为cl,S映射为^C,从而不影响s/S原本的功能
{
"before": ["f"],
"after": ["s"]
},
{
"before": ["F"],
"after": ["S"]
},
{
"before": ["s"],
"after": ["c", "l"]
},
{
"before": ["S"],
"after": ["^", "C"]
}]
}
如果现在只是在normal
模式下配置完成了对应的配置,但是要知道vim
还有可视化模式(visual mode
)和处于操作等待(opratorPending
)的状态(输入d
或者c
之后就会处于这个状态),对应这两个状态下也需要进行一定的配置:
- 在处于操作等待(
opratorPending
)下sneak
是使用z
来进行操作的,但是现在我们需要的效果是df
+两个字符
组合(该效果为删除匹配到的范围)的这种操作,所以需要配置在该状态下按下f
和F
分别对应的按键为z
和Z
。 - 在可视化模式下,
F
无法使用,所以之需要配置f
映射为s
即可。 - 这两个配置因为也要防止绑定按键后递归调用的问题,所以需要分别在
"vim.visualModeKeyBindingsNonRecursive"
与"vim.operatorPendingModeKeyBindingsNonRecursive"
进行配置,下面是上述选项的具体配置:
{
...,
"vim.visualModeKeyBindingsNonRecursive": [
{
"before": ["f"],
"after": ["s"]
}
],
"vim.operatorPendingModeKeyBindingsNonRecursive": [
{
"before": ["f"],
"after": ["z"]
},
{
"before": ["F"],
"after": ["Z"]
}
],
}