VIM | Vim与Vscode内置快捷键的完美结合

1,177 阅读8分钟

image.png

使用Vscode的Vim插件的过程中,同样也可以使用Vscode内置的命令来提升编码体验,现在就来介绍下几个常用的开发场景,帮助你提高全键盘编辑的使用效率吧!

显示代码操作

下面来介绍下怎么主动呼出显示代码操作(show code actions),如果当前输入的代码中存在一些问题或者有可以优化的空间,比如未引入的模块、语法错误、智能重写等,此时光标所在的行首周围就会显示一个灯泡的图标,点击该图标就会出现对应的选项单,通过这个选项单就可以进行代码操作了。 案例: 若当前的场景下系统检测到代码可以进行重写(参考下图),此时就可以选择 重写 这个选项来将代码改写成更简易的写法。

  • 重写前:

image.png

  • 重写后:

image.png

键盘党的处理的方案

实际上Vscode针对该功能有提供对应的按键呼出的方案,也就是 ctrl/cmd + . 。通过这个快捷键,就可以快速的呼出代码操作选项菜单,通过up/down上下方向键来切换对应的选项,enter执行对应的处理方案。

20240820_103833.gif

主动触发参数提示

想象下下面一个场景,比如我定义了一个函数:

/**
 * 判断值是否改变
 */
export const hasChanged = (value: any, oldValue: any): boolean => {
  return !Object.is(value, oldValue)
}

现在我在Vscode中需要调用这个函数,书写完成函数名,到需要填写实际参数的时候,Vscode会贴心的显示参数提示(如下图)。

image.png

此时如果输入错误的内容或者移动了光标到其他地方,后面在回到该处进行编辑的时候,会发现此时输入内容不会有上图所示的参数提示,那么此时就可以通过 shift + ctrl/cmd + space 来主动通过快捷键触发参数提示(trigger parameter hints)。

20240820_104620.gif

主动触发代码建议

Vscode中的代码建议(trigger suggestion)是个非常好用的功能,比如输入exp就会出现提示export,但是如果出现了此时如果输入错误的内容或者移动了光标到其他地方,后面回到原本想要编辑的地方,会发现需要输入一个字符,代码建议提示框才会重新显示,那么针对该场景的解决方案就是使用快捷键ctrl/cmd + i来主动呼出代码建议提示框。

Win场景下的使用问题与对应的配置思路

首先因为mac的设计上有command键与control键两个按键, command + icontrol + i 是有不同的对应功能的,所以不会有按键冲突的问题。 但是在windows系统下所有的工作就都需要集中在ctrl一个按键上面了,所以会出现没办法使用 ctrl + i 触发代码建议功能的问题。 为什么会有使用不了 ctrl+i这样的问题呢,为了方便理解,首先来看下 ctrl + i 在Vim中的作用:

  • ctrl + i:跳转到 jump list 的后一个记录
  • ctrl + o:跳转到 jump list 的前一个记录

是的 ctrl + i 在Win系统下会和该快捷键冲突,那么有什么对应的解决方案呢? 思路分析: 首先主动呼出代码建议(trigger suggestion)的使用场景的通常情况下指的是在进入Vim的insert模式后,通过编辑代码才会选择性的主动呼出代码建议选项,而vim中通过 ctrl+i 跳转到 jump list 的后一个记录更多的功能对应的使用场景是在normal模式下,对应的功能是快速切换光标位置。

那么我想就可以配置成,当处于insert模式下,可以通过触发 ctrl+i 触发主动呼出代码建议(trigger suggestion)的功能,而如果是处于normal模式下的时候,此时使用ctrl+i 则为调用原先Vim中内置的功能。

image.png

解决方案: 在 keybindings.json 配置文件中添加如下配置项:

[
  ...,
    // 主动呼出代码建议(insert模式才能触发)
  {
    "key": "ctrl+i",
    "command": "editor.action.triggerSuggest",
    "when": "vim.mode == 'Insert' && editorTextFocus && vim.active && vim.use<C-i> && !inDebugRepl"
  },
  // 防止和 Vim 原先的ctrl+i(返回上一个跳转点)冲突
  {
    "key": "ctrl+i",
    "command": "extension.vim_ctrl+i",
    "when": "vim.mode !== 'Insert' && editorTextFocus && vim.active && vim.use<C-i> && !inDebugRepl"
  },
  // 记得禁用原先 Vscode 中的ctrl+i
  {
    "key": "ctrl+i",
    "command": "-editor.action.triggerSuggest",
    "when": "editorHasCompletionItemProvider && textInputFocus && !editorReadonly && !suggestWidgetVisible"
  },
  {
    "key": "ctrl+i",
    "command": "-extension.vim_ctrl+i",
    "when": "editorTextFocus && vim.active && vim.use<C-i> && !inDebugRepl"
  },
]

这样就可以使用ctrl+i来触发代码建议了,下面是具体的效果演示:

20240820_112009.gif

行操作相关指令

移动行

之前如果使用原先Vim中内置的功能对** 行 **进行操作,比较常见的就是如果我想移动某行的内容,此时对应的做法就是,通过dd删除该内容,光标移动到想要的位置后,通过p来粘贴。这样做实际上有些繁琐,事实上使用Vscode中内置的快捷键就可以做到一样的事情了并且触发该行操作的方式更加简单,对应的快捷键如下:

  • option/alt+up/down:上/下移动行或是选中区域的内容。

20240820_135750.gif

新建行

原先Vim中新建行对应的命令是o/Oo指的是行后插入,O值得是行前插入,触发该命令的时候还需要加入一个esc或者 ctrl+[ 退出 Insert 模式才能完成新建行的整个操作,不太方便。实际上,Vscode就有内置的命令,并且不会进入 Insert 模式,相应的快捷键为:

  • ctrl/cmd+enter:在当前行下方新建空白行(和o一样,但是不会进 insert 模式)
  • ctrl/cmd+shift+enter:在当前行上方新建空白行(和O一样,但是不会进入 insert 模式)

20240820_135947.gif

删除光标前面的单词

Vim中删除单词的方式有很多,比如dediwciw等等,而Vscode也提供了对应的方案可以实现删除光标前的单词,并且分为了按照一个单词为文本块与按照驼峰命令的单词为文本块进行删除。

该快捷键在windows系统下和mac系统下有着显著的差异,触发的前置快捷键不同,甚至在windows系统下没有对应的文本处理方案,这使得需要进行配置。

首先在mac系统下对应的快捷键如下图所示:

image.png

  • option+backspace(deleteWordLeft):删除光标前的单词(以一个单词为一个文本块,比如isString就是一个单词)
  • option+contrl+backspace(deleteWordPartLeft):删除光标前的单词(按照驼峰规则划分单词的方式,比如isString会被分为isString两个单词)

下面来看下win系统下的处理方案:

image.png

  • ctrl+backspace(deleteWordLeft):删除光标前的单词(以一个单词为一个文本块,比如isString就是一个单词)
    • 该功能的使用需要将vim插件内置的 ctrl + backspace 对应的按键绑定删除(否则触发不了删除单词的操作,会优先执行vim插件的操作)
  • ctrl+alt+backspace(deleteWordPartLeft)
    • 作用:删除光标前的单词(按照驼峰规则划分单词的方式进行删除,比如isString会被分为isString两个单词)
    • 注意❕:该配置选项需要手动配置,win系统下默认ctrl+alt+backspace对应的按键绑定的功能为删除括号,因为Vscode中的Vim插件使用了Vim-surround插件实现了快速删除括号的功能(比如通过dab或者da)删除括号),这里这个快捷键组合对应的功能就可以修改成deleteWordPartLeft了。
  • 配置:编辑keybinds.json文件,添加如下内容
[
  ...,
  // 删除光标左侧单词(按照驼峰规则划分文本块)
  {
    "key": "ctrl+alt+backspace",
    "command": "-editor.action.removeBrackets",
    "when": "editorTextFocus"
  },
  {
    "key": "ctrl+alt+backspace",
    "command": "deleteWordPartLeft"
  },
  // 删除vim插件中的ctrl+backspace快捷键设置
  {
    "key": "ctrl+backspace",
    "command": "-extension.vim_ctrl+backspace",
    "when": "editorTextFocus && vim.active && vim.use<C-BS> && !inDebugRepl && vim.mode != 'Insert'"
  },
]
  • 演示:
    • ctrl+backspace(deleteWordLeft):

20240820_142648.gif

  • ctrl+alt+backspace(deleteWordPartLeft):

0fa0474e-f2ac-4cf2-a78e-fb0bf556bafd.gif

跳转到代码错误处

如果当前代码存在语义问题,比较常见的就是用了不存在的变量,这个时候想要快速跳转到该位置就可以使用快捷键:

  • f8:跳转到下一处错误
  • shift+f8:跳转到上一处错误

备注:

  • 该快捷键作用的范围不仅仅是当前文件,而针对的是当前打开的整个工作区具体的效果参考下面的演示gif

20240820_144145.gif

选中所有相同单词

Vscode中的Vim插件内置了gb命令,可以实现Vscode中内置的快捷键ctrl+d相同的快速选中相同文本块(单词)的功能,而如果当前文本比较多的情况下,通过反复按gb来选中相同的文本内容未免有些繁琐了,此时就可以通过快捷键ctrl/cmd+f2来触发快速选中相同单词的功能了,但是这个功能个人觉得不好按,所以我将这个快捷键配置到了Vim的easymotion中方便随时调用,对应的命令为:

  • <leader>+g+b
    • 备注:g+b的组合对应了gb命令,方便记忆。

下面是我这块的配置,编辑settings.json

// normal 模式下的按键绑定(防止按键循环调用)
"Vim.normalModeKeyBindingsNonRecursive": [
  ...,
  // 修改所有的配置项
  {
    "before": ["<leader>", "g", "b"],
    "commands": ["editor.action.changeAll"]
  },
]

演示:

20240820_143245.gif

参考资料