VSCodeVim 配置指南

个人定制 VSCodeVim 的配置, 配置文件可见 setting.json 以及 keybindings.json。 鉴于目前 VSCodeVim 尚且不支持在 .vimrc 中进行设置 (仅支持 keymapping), 还是需要使用 keybindings.json 配置键位映射。 而且有些 VSCode 特有的界面也是需要通过这种方式实现的。

vscode 热键映射命令可以在 Preference: Open Keyboard Shortcuts 中复制命令的 ID 即可获得。

VSCodeVim Usage Demo, HangX-Ma
VSCodeVim Usage Demo, HangX-Ma

1. vim 基础指令说明

有几个 vim 基础指令之前一直不是很明白或者忘了, 需要特别记录一下使用功能。

1.1 Operators

  • ~: 转换大小写
  • gu: 转为小写
  • gU: 转为大写

1.2 Motions

  • gee 跳转到单词的最后一个字符, ge 的作用是跳转到上一个单词的最后一个字符
  • aw: “a word” 的缩写, 这个指令需要和操作符联合使用, 选择一整个单词, 包括它边上的空格
  • aW: “a word” 的缩写, 这个指令需要和操作符联合使用, 选择一整个单词 (包含标点), 包括它边上的空格
  • iw: “in word” 的缩写, 这个指令需要和操作符联合使用, 选择一整个单词, 但不包括它边上的空格
  • iW: “in word” 的缩写, 这个指令需要和操作符联合使用, 选择一整个单词 (包含标点), 但不包括它边上的空格

1.3 Quick Editor

通过下面两个指令可以实现编辑界面的快速切换, 有时候我们使用了 Goto Definition 会跳转到另外一个文件中, 这时候这个指令就非常有用了。

  • <C-i>: 回到上一个编辑点。
  • <C-o>: 前进到下一个编辑点。

2. 基础配置项 (settings.json)

对于非代码编辑区的热键将其定义在 keybindings.json 中, 对于代码编辑区且属于 vim 的热键将其定义在 settings.json 文件中。

2.1 代码控制区域热键方案

  • Normal, Non-recursive
    • <leader> nh: 取消搜索高亮
    • g [: 跳转到上一个问题
    • g ]: 跳转到下一个问题
  • Visual, Recursive
    • >: 向右缩进
    • <: 向左缩进

2.2 热键配置区域说明

基本上 vim 的所有模式都可以配置在下面的 4 个选项中。 用过 Makefile 应该知道 Recursive Parse 和 NonRecursive Parse, 一般来说用非递归模式可以避免很多奇怪的错误, 推荐用非递归模式。

// 普通模式下的非递归按键绑定
"vim.normalModeKeyBindingsNonRecursive": [],
// 插入模式下的递归按键绑定
"vim.insertModeKeyBindings": [],
// 命令模式下的非递归按键绑定
"vim.commandLineModeKeyBindingsNonRecursive": [],
// 可视模式下的递归按键绑定
"vim.visualModeKeyBindings": [],

配置项的内容与解释如下:

  • Vim 相关

      "vim.useSystemClipboard": true, // use system clipboard as vim registers
      "vim.useCtrlKeys": true,        // vim will take over <C-any> rather than vscode
      "vim.hlsearch": true,           // highlight all matched text
      "vim.smartcase": true,          // This group will cause case sensitive when only one capital character exists
      "vim.ignorecase": true,
      "vim.leader": "<space>",        // bind the 'leader' key
    
  • Vim 无关

    • "editor.lineNumbers": "relative": 设置相对行号, 这在我们进行多行删除/注释等操作的时候非常有用, 否则自己去计算行数会很麻烦。
    • "workbench.editor.enablePreviewFromQuickOpen": false: 用 <C-p>(映射后为 <C-g> p) 打开的文件默认是处于预览状态的, 重新预览其他文件时就没了,要双击标签才会固定住, 这个设置就是解决这个问题的。

3. 自定义热键方案 (keybindings.json)

3.1 侧边栏命令定义

<C-k> [ : 切换侧边栏显示状态
<C-k> ] : 切换第二侧边栏显示状态
<C-k> 1 : 显示文件资源管理器
<C-k> 2 : 显示全局搜索
<C-k> 3 : 显示版本控制
<C-k> 4 : 显示 debug
<C-k> 5 : 显示插件商店
<C-k> 6 : 显示 TODO Tree
<C-k> 7 : 显示 Bookmark
<C-k> 8 : 显示 test 资源管理器
<C-k> 9 : 显示 Project Manager

3.2 文件管理器配置

# default
j       : 向下移动
k       : 向上移动
<C-d>   : 向下翻页
<C-u>   : 向上翻页
gg      : 回到顶部
G       : 回到底部
space   : 打开文件或目录
<S-A-r> : 打开操作系统下当前目录的资源管理器

# user defined​
z       : 折叠文件夹
a       : 新增文件
o       : 新增目录
f       : 刷新目录
r       : 重命名文件或目录
d       : 删除文件或目录
x       : 剪切文件或目录
y       : 复制文件或目录
p       : 粘贴文件或目录
/       : 在当前光标所指的文件夹内进行文件搜索

# panels
<C-k> e : 打开 Open Editors 面板
<C-k> t : 打开 Timeline 面板
<C-k> o : 打开 Outline 面板

3.3 代码编辑区命令定义

<C-h> h : 触发帮助提示
# Insert mode
<C-h> a : 触发参数提示
<C-h> s : 触发建议提示
<C-n>   : 移动到下一个建议
<C-p>   : 移动到上一个建议

<C-\>   : 快速修复问题
<C-=>   : 放大字体
<C-->   : 缩小字体

3.4 编辑区命令定义

<C-q>   :关闭当前选项卡或分屏
<C-w> e :聚焦在第一个选项卡中
<C-,>   :切换到上一个选项卡
<C-/>   :切换到下一个选项卡
​
<C-w> s :拆分一个上下分屏
<C-w> v :拆分一个左右分屏
​
<C-w> k :将光标向上移动1屏
<C-w> j :将光标向下移动1屏
​
<C-w> h :将光标向左移动1屏
<C-w> l :将光标向右移动1屏

3.5 文件命令定义

<C-f> n : 新建文件
<C-f> o : 打开文件
<C-f> f : 打开文件夹
<C-f> e : 另存为文件
<C-f> s : 保存文件
<C-f> w : 保存所有文件
<C-f> q : 关闭文件
<C-f> a : 关闭所有文件

3.6 全局命令定义

<C-g> c : 显示命令面板
<C-g> s : 打开设置页面
<C-g> p : 快速打开文件
<C-g> r : 打开最近记录
<C-g> n : 新建 vscode 窗口
<C-g> q : 关闭 vscode 窗口

3.7 面板命令定义

<C-l> [ : 切换面板显示状态
<C-l> 1 : 显示问题
<C-l> 2 : 显示输出
<C-l> 3 : 显示终端
<C-l> 4 : 显示调试控制台
<C-l> 5 : 显示 GitLens

3.8 取消 vim 与 vscode 的一些指令

<C-a>   : 全选, 非 INSERT 模式不生效
<C-c>   : 复制, 非 INSERT 模式不生效
<C-v>   : 复制, 非 INSERT 模式不生效

3.9 Extensions

3.9.1 Bookmark

<C-m> t     : 创建或消除书签
<C-m> n     : 跳转到下一个书签
<C-m> p     : 跳转到上一个书签
<C-m> l     : 列出当前文件的所有书签
<C-m> <A-l> : 列出所有文件的所有书签
<C-m> c     : 列出当前文件的所有书签
<C-m> <A-c> : 清除所有文件的所有书签

3.9.2 Project Manager

<C-k> <A-o> : 在当前窗口打开一个 project
<C-k> <A-n> : 在新的窗口打开一个 project
<leader> sf : 在文件中查找
<leader> sr : 在文件中替换
<C-n>       : 聚焦下一个搜索结果
<C-p>       : 聚焦上一个搜索结果

3.9.5 Markdown Preview

<C-k> v     : 在侧边打开/关闭 Markdown Preview
<C-k> <A-v> : 打开/关闭 Markdown Preview

4. 插件与定制化

4.1 输入法切换

设置 NORMAL 模式下的输入法为英文, 方便进行 vim 指令操作。

  1. 使用 Windows scoop 安装

     scoop bucket add im-select https://github.com/daipeihust/im-select
     scoop install im-select
    
  2. 切换至英文输入法获取输入法别名。

     im-select.exe
     1033
    
  3. 然后再到 settings.json 中加入以下配置项即可完成输入法在 INSERT 模式以及 NORMAL 模式下的自动切换。

     // 自动切换输入法
     "vim.autoSwitchInputMethod.enable": true,
     "vim.autoSwitchInputMethod.defaultIM": "1033",  // 这里输入你刚刚获得的英文输入法名称
     "vim.autoSwitchInputMethod.obtainIMCmd": "C:/Users/User/scoop/apps/im-select/current/im-select.exe",
     "vim.autoSwitchInputMethod.switchIMCmd": "C:/Users/User/scoop/apps/im-select/current/im-select.exe {im}"
    

4.2 Emulated Plugins

这里记录几个比较常用的 VSCodeVim 内置插件, 有些插件的功能感觉累赘就没用它了。

vim-esaymotion
基于 vim-easymotion 它的作用是通过以下的按键组合, 你可以快速的定位到任何你想修改的行中, 这里就只列出几个常用的。
  • <leader><leader>s<char>: 在当前文件查找 <char> 字符。
  • <leader><leader>f<char>: 在当前文件向前查找 <char> 字符。
  • <leader><leader>F<char>: 在当前文件向后查找 <char> 字符。
  • <leader><leader>t<char>: 在当前文件向前查找, 直到 <char> 字符,例如找了 g, 光标会落在 g 字符的前面。
  • <leader><leader>T<char>: 在当前文件向后查找, 直到 <char> 字符, 例如找了 g, 光标会落在 g 字符的后面。
  • <leader><leader> j: 向前定位行头部。
  • <leader><leader> k: 向前定位行尾部。
  • <leader><leader> w: 向前定位到单词的头部。
  • <leader><leader> b: 向前定位到单词的尾部。
  • <leader><leader> e: 向后定位到单词的头部。
  • <leader><leader> ge: 向后定位到单词的尾部。

类似 <leader><leader>2s<char><char> 这样加上数字也是可以的, 不同的是现在需要匹配两个字符。

vim-surround
基于 surround.vim 实现, 该插件用于处理括号、括号、引号和 XML 标记等周围的字符。
Surround Command Description
ds<existing> 删除 existing 符号, ds" 能删除 “test” 中的 "
cs<existing><desired> existing 符号替换为 desired 符号, cs"' 能将 “test” 变更为 ‘test’
ys<motion><desired> 通过 motion 给特定的文本添加 desired 符号, ysiw) 会给光标所在单词添加符号 )yss) 则给当前行添加符号 )

注: “ys” 的意思就是 “your surround”, 相关使用说明参考 surround.txt

vim-commentary
vim-commentary 类似, 该插件能够快速的利用键盘进行行或者块的注释。
  • gc: 行注释, 使用 gcc 可切换当前行的注释, gc2j 能对当前行以及下两行切换注释。
  • gC: 块注释, 使用 gCi) 能够对圆括号内的所有代码进行注释。
CamelCaseMotion
基于 CamelCaseMotion 的实现, 可以在 camelCase 以及 snake_case 的单词之间移动。
  • <leader>w: 向前移动到下一个 camelCase 或者 snake_case 单词段的开头。
  • <leader>e: 向前移动到下一个 camelCase 或者 snake_case 单词段的末尾。
  • <leader>b: 向后移动到最开始的 camelCase 或者 snake_case 单词段。
  • <operator>i<leader>w: 选择/更改/删除/…当前的 camelCase 或者 snake_case 单词段, 例如 di<leader>w 这个操作会删除 camelCase 前半部分的 Camel

具体的实现效果推荐自己尝试观察, 会发现这个工具真的是完美解决单词选择痛点。

4.3 快捷指令

  • gd: 跳转到函数定义或引用处。
  • gh: 触发帮助提示, 和鼠标悬浮查看类型以及错误信息的实现完全一致!
  • gq: 在 Visual 模式下可以合并选中的注释并保留其样式, 在格式化注释时非常有用。
  • gb: 在 Visual 模式下开启多光标模式, 匹配与当前光标所在位置相同的下一词并将其添加入光标选中。
  • af: 在 Visual 模式下不断扩大选中的文本框, 但扩大的范围受到括号的限制。

5. 参考