vscode + vim 全键盘操作高效搭配方案

基础知识

vscode-vim

vscode-vim是一款vim模拟器,它将vim的大部分功能都集成在了vscode中,你可以将它理解为一个嵌套在vscode中的vim。

由于该vim是被模拟的的非真实vim,所以原生vim中有些功能它并不支持,如宏录制功能,但这依然不妨碍vscode-vim插件的优秀。

其实在vscode的扩展商店中,还有一个vscode neovim的插件也十分不错,但是相较于vscode-vim来说依然存在一些让我难以接受的缺点,比如visual模式下的选择并非真正的vscode选择等,基于种种原因我还是考虑使用vscode-vim,尽管它可能占用了更大的内存。

安装使用

我们需要在插件商店中搜索vim插件,然后安装:

image-20211106152007384

安装完成之后,需要做一些基础配置。

1)仅MAC用户,关闭MAC的重复键:

$ defaults write com.microsoft.VSCode ApplePressAndHoldEnabled -bool false  

2)设置相对行号,在settings.json中添加上以下配置项:

"editor.lineNumbers": "relative",

3)关闭自动传参建议,使用按键手动触发:

"editor.parameterHints.enabled": false,

4)控制资源管理器中的键盘导航无法自动触发:

"workbench.list.automaticKeyboardNavigation": false,

配置文件

基础配置项

vscode-vim插件由于是一款模拟器,所以它的配置文件是放在settings.json文件中,而不是vimrc文件中,个人也并不推荐将配置放在vimrc文件中,因为这会导致多端同步变的复杂,尽管这款插件可以支持从vimrc文件中读取配置。

下面是一些我会在使用vscode-vim插件时配置的vim选项,直接放入到settings.json文件中即可:

{
  // 绑定vim前导键
  "vim.leader": "<space>",
  // 启用easymotion插件
  "vim.easymotion": true,
  // 启用系统粘贴板作为vim寄存器
  "vim.useSystemClipboard": true,
  // 由vim接管ctrl+any的按键,而不是vscode
  "vim.useCtrlKeys": true,
  // 突出显示与当前搜索匹配的所有文本
  "vim.hlsearch": true,
   // 普通模式下的非递归按键绑定
  "vim.normalModeKeyBindingsNonRecursive": [],
   // 插入模式下的非递归按键绑定
  "vim.insertModeKeyBindings": [],
  // 命令模式下的非递归按键绑定
  "vim.commandLineModeKeyBindingsNonRecursive": [],
  // 可视模式下的非递归按键绑定
  "vim.operatorPendingModeKeyBindings": [],
  // 下面定义的按键将交由vscode进行处理,而不是vscode-vim插件
  "vim.handleKeys": {
    "<C-a>": false,
    "<C-f>": false
  }
}

热键配置项

基本上vim的所有模式你都可以配置在下面的4个选项中:

// 普通模式下的非递归按键绑定
"vim.normalModeKeyBindingsNonRecursive": [],
// 插入模式下的非递归按键绑定
"vim.insertModeKeyBindings": [],
// 命令模式下的非递归按键绑定
"vim.commandLineModeKeyBindingsNonRecursive": [],
// 可视模式下的非递归按键绑定
"vim.operatorPendingModeKeyBindings": [],
// 下面定义的按键将交由vscode进行处理,而不是vscode-vim插件
"vim.handleKeys": {
    "<C-a>": false,
    "<C-f>": false
}

一个简单的例子,在INSERT模式下使用jj退回到NORMAL模式:

  "vim.insertModeKeyBindings": [
    {
      "before": [
        "j",
        "j"
      ],
      "after": [
        "<Esc>"
      ]
    },
  ],

下面的示例将演示如何在NORMAL模式下按下快捷键执行COMMAND的命令,如按下<C-n>后,取消高亮搜索:

  "vim.normalModeKeyBindingsNonRecursive": [
    {
      "before": [
        "<C-n>"
      ],
      "commands": [
        ":nohl"
      ]
    },
  ],

除此之外,你也可以定义在按下一些按键后,调用vscode下的命令API,比如在NORMAL模式下按下<leader>gc后,调用vscode的全局命令:

  "vim.normalModeKeyBindingsNonRecursive": [
    {
      "before": [
        "<leader>",
        "g",
        "c"
      ],
      "commands": [
        "workbench.action.showCommands"
      ]
    }
  ],

注意!leader键只在代码编辑区域生效,它无法做到全vscode生效。

针对一些刚接触vscode不久的朋友,可能不知道怎么拿到vscode的热键映射命令,其实你可以从vsocde的键盘快捷键中复制命令ID获得。

image-20211102153604048

自用热键方案

下面是个人自用的vim+vscode全键盘热键方案,对于非代码编辑区的热键将其定义在keybindings.json中,对于代码编辑区且属于vim的热键将其定义在settings.json文件中。

我目前使用的是mac平台,所以cmd按键会比ctrl按键更加常用,如果是windows或者linux平台,则将cmd替换为ctrl按键即可:

cmd + g c : 显示命令面板
cmd + g s : 打开设置页面
cmd + g k : 打开热键映射
cmd + g m : 打开一个目录
cmd + g f : 打开一个文件
cmd + g h : 打开最近记录
cmd + g n : 新建vscode实例
cmd + g q : 关闭vscode示例

cmd + f n : 新建文件
cmd + f o : 打开文件
cmd + f e : 另存为文件
cmd + f s : 保存文件
cmd + f w : 保存所有文件
cmd + f q : 关闭文件
cmd + f a : 关闭所有文件

cmd + n [ : 切换侧边栏显示状态
cmd + n 1 : 显示文件资源管理器
cmd + n 2 : 显示TODO Tree
cmd + n 3 : 显示全局搜索
cmd + n 4 : 显示debug
cmd + n 5 : 显示版本控制
cmd + n 6 : 显示SQL Tools
cmd + n 7 : 显示Docker
cmd + n 8 : 显示测试
cmd + n 9 : 显示插件商店

cmd + p ] : 切换面板显示状态
cmd + p 1 : 显示问题
cmd + p 2 : 显示输出
cmd + p 3 : 显示终端
cmd + p 4 : 显示调试控制台
cmd + p 5 : 显示SQL CONSOLE

以下是编辑区域操作控制方案:

cmd + q :关闭当前选项卡或分屏
cmd + e :聚焦在第一个选项卡中
cmd + , :切换到上一个选项卡
cmd + . :切换到下一个选项卡

cmd + w s :拆分一个上下分屏
cmd + w v :拆分一个左右分屏

cmd + w k :将光标向上移动1屏
cmd + w j :将光标向下移动1屏

cmd + w h :将光标向左移动1屏
cmd + w l :将光标向右移动1屏

代码控制区域:

cmd + h : 触发帮助提示
cmd + j : 触发参数提示
cmd + k : 触发建议提示
cmd + n : 移动到下一个建议
cmd + p : 移动到上一个建议
tab : 选择下一个建议
enter : 选择当前建议

cmd + alt + l : 格式化代码(个人习惯)

cmd + = : 放大字体
cmd + - : 缩小字体

在settings.json中配置的代码控制区域热键方案:

jj : 退出INSERT模式
zz : 切换代码折叠(原生vim的zz不是切换折叠)

H :跳转行首、取代^
L :跳转行尾、取代$

g[ : 跳转到上一个问题
g] : 跳转到下一个问题

我的配置文件

以下是settings.json文件中关于代码编辑区的一些操作配置项:

  "vim.normalModeKeyBindingsNonRecursive": [
    {
      "before": [
        "H"
      ],
      "after": [
        "^"
      ]
    },
    {
      "before": [
        "L"
      ],
      "after": [
        "$"
      ]
    },
    {
      "before": [
        "z",
        "z",
      ],
      "commands": [
        "editor.toggleFold"
      ]
    },
    {
      "before": [
        "g",
        "[",
      ],
      "commands": [
        "editor.action.marker.prevInFiles"
      ]
    },
    {
      "before": [
        "g",
        "]",
      ],
      "commands": [
        "editor.action.marker.nextInFiles"
      ]
    },
  ],
  // 插入模式下的非递归按键绑定
  "vim.insertModeKeyBindings": [
    {
      "before": [
        "j",
        "j"
      ],
      "after": [
        "<Esc>"
      ]
    },
  ],
  // 命令模式下的非递归按键绑定
  "vim.commandLineModeKeyBindingsNonRecursive": [],
  // 可视模式下的非递归按键绑定
  "vim.operatorPendingModeKeyBindings": [],

以下是keybindings.json文件,基本的键位设置就如同上面看到的一样,但是做了一些额外的限制条件,比如<C-a>和<C-c>以及<C-v>等vscode原生命令在代码编辑区域中非NORMAL模式下是不生效的:

[
    // --- 全局命令
    // 显示命令面板
    {
        "key": "cmd+g c",
        "command": "workbench.action.showCommands"
    },
    // 打开设置页面
    {
        "key": "cmd+g s",
        "command": "workbench.action.openSettings"
    },
    // 打开热键映射
    {
        "key": "cmd+g k",
        "command": "workbench.action.openGlobalKeybindings"
    },
    // 打开一个目录
    {
        "key": "cmd+g m",
        "command": "workbench.action.files.openFolder"
    },
    // 打开一个文件
    {
        "key": "cmd+g f",
        "command": "workbench.action.files.openFile"
    },
    // 打开最近记录
    {
        "key": "cmd+g h",
        "command": "workbench.action.openRecent"
    },
    // 新建vscode实例
    {
        "key": "cmd+g n",
        "command": "workbench.action.newWindow"
    },
    // 关闭vscode实例
    {
        "key": "cmd+g q",
        "command": "workbench.action.closeWindow"
    },
    // --- 文件命令
    // 新建文件
    {
        "key": "cmd+f n",
        "command": "welcome.showNewFileEntries",
    },
    // 打开文件
    {
        "key": "cmd+f o",
        "command": "workbench.action.files.openFileFolder"
    },
    // 另存为文件
    {
        "key": "cmd+f e",
        "command": "workbench.action.files.saveAs"
    },
    // 保存文件
    {
        "key": "cmd+f s",
        "command": "workbench.action.files.save"
    },
    // 保存所有文件
    {
        "key": "cmd+f w",
        "command": "workbench.action.files.saveAll"
    },
    // 关闭文件
    {
        "key": "cmd+f q",
        "command": "workbench.action.closeActiveEditor"
    },
    // 关闭所有文件
    {
        "key": "cmd+f a",
        "command": "workbench.action.closeAllEditors"
    },
    // -- 侧边栏命令
    // 切换侧边栏显示状态
    {
        "key": "cmd+n [",
        "command": "workbench.action.toggleSidebarVisibility"
    },
    // 显示文件资源管理器
    {
        "key": "cmd+n 1",
        "command": "workbench.files.action.focusFilesExplorer"
    },
    // 显示TODO Tree
    {
        "key": "cmd+n 2",
        "command": "todo-tree-view.focus"
    },
    // 显示全局搜索
    {
        "key": "cmd+n 3",
        "command": "workbench.action.replaceInFiles",
    },
    // 显示debug
    {
        "key": "cmd+n 4",
        "command": "workbench.view.debug",
        "when": "viewContainer.workbench.view.debug.enabled"
    },
    // 显示版本控制
    {
        "key": "cmd+n 5",
        "command": "workbench.view.scm",
        "when": "workbench.scm.active"
    },
    // 显示SQL Tools
    {
        "key": "cmd+n 6",
        "command": "workbench.view.extension.sqltoolsActivityBarContainer"
    },
    // 显示Docker
    {
        "key": "cmd+n 7",
        "command": "workbench.view.extension.dockerView"
    },
    // 显示测试
    {
        "key": "cmd+n 8",
        "command": "workbench.view.testing.focus"
    },
    // 显示插件商店
    {
        "key": "cmd+n 9",
        "command": "workbench.view.extensions",
        "when": "viewContainer.workbench.view.extensions.enabled"
    },
    // --- 面板命令
    // 切换面板显示状态
    {
        "key": "cmd+p [",
        "command": "workbench.action.togglePanel"
    },
    // 显示问题
    {
        "key": "cmd+p 1",
        "command": "workbench.panel.markers.view.focus"
    },
    // 显示输出
    {
        "key": "cmd+p 2",
        "command": "workbench.action.output.toggleOutput",
        "when": "workbench.panel.output.active"
    },
    // 显示终端
    {
        "key": "cmd+p 3",
        "command": "workbench.action.terminal.toggleTerminal",
        "when": "terminal.active"
    },
    // 显示调试控制台
    {
        "key": "cmd+p 4",
        "command": "workbench.debug.action.toggleRepl",
        "when": "workbench.panel.repl.view.active"
    },
    // 显示SQL CONSOLE
    {
        "key": "cmd+p 5",
        "command": "workbench.view.extension.sqltoolsPanelContainer"
    },
    // --- 编辑区命令
    // 关闭当前选项卡或分屏
    {
        "key": "cmd+q",
        "command": "workbench.action.closeActiveEditor"
    },
    // 聚集在第一个选项卡中
    {
        "key": "cmd+e",
        "command": "workbench.action.focusFirstEditorGroup"
    },
    // 切换到上一个选项卡
    {
        "key": "cmd+,",
        "command": "workbench.action.previousEditor"
    },
    // 切换到下一个选项卡
    {
        "key": "cmd+.",
        "command": "workbench.action.nextEditor"
    },
    // 拆分一个上下分屏
    {
        "key": "cmd+w s",
        "command": "workbench.action.splitEditorDown"
    },
    // 拆分一个左右分屏
    {
        "key": "cmd+w v",
        "command": "workbench.action.splitEditor"
    },
    // 将光标向上动1屏
    {
        "key": "cmd+w k",
        "command": "workbench.action.focusAboveGroup"
    },
    // 将光标向下动1屏
    {
        "key": "cmd+w j",
        "command": "workbench.action.focusBelowGroup"
    },
    // 将光标向左移动1屏
    {
        "key": "cmd+w h",
        "command": "workbench.action.focusLeftGroup"
    },
    // 将光标向右移动1屏
    {
        "key": "cmd+w l",
        "command": "workbench.action.focusRightGroup"
    },
    // --- 代码编辑命令
    // 触发帮助提示
    {
        "key": "cmd+h",
        "command": "editor.action.showHover",
        "when": "editorTextFocus"
    },
    // 触发参数提示
    {
        "key": "cmd+j",
        "command": "editor.action.triggerParameterHints",
        "when": "editorHasSignatureHelpProvider && editorTextFocus"
    },
    {
        "key": "cmd+j",
        "command": "closeParameterHints",
        "when": "editorFocus && parameterHintsVisible"
    },
    // 触发建议提示
    {
        "key": "cmd+k",
        "command": "editor.action.triggerSuggest",
        "when": "editorHasCompletionItemProvider && textInputFocus && !editorReadonly"
    },
    {
        "key": "cmd+k",
        "command": "hideSuggestWidget",
        "when": "suggestWidgetVisible && textInputFocus"
    },
    // 移动到下一个建议
    {
        "key": "cmd+n",
        "command": "selectNextSuggestion",
        "when": "suggestWidgetMultipleSuggestions && suggestWidgetVisible && textInputFocus"
    },
    // 移动到上一个建议
    {
        "key": "cmd+p",
        "command": "selectPrevSuggestion",
        "when": "suggestWidgetMultipleSuggestions && suggestWidgetVisible && textInputFocus"
    },
    // 格式化代码
    {
        "key": "cmd+alt+l",
        "command": "editor.action.formatDocument",
        "when": "editorHasDocumentFormattingProvider && editorTextFocus && !editorReadonly && !inCompositeEditor"
    },
    // 放大字体
    {
        "key": "cmd+=",
        "command": "editor.action.fontZoomIn"
    },
    // 缩小字体
    {
        "key": "cmd+-",
        "command": "editor.action.fontZoomOut"
    },
    // --- window 用户删除以下重映射,这里是为MAC用户准备的
    {
        "key": "cmd+r",
        "command": "extension.vim_ctrl+r",
        "when": "editorTextFocus && vim.active && vim.use<C-r> && !inDebugRepl"
    },
    {
        "key": "ctrl+r",
        "command": "-extension.vim_ctrl+r",
        "when": "editorTextFocus && vim.active && vim.use<C-r> && !inDebugRepl"
    },
    {
        "key": "cmd+a",
        "command": "extension.vim_ctrl+a",
    },
    {
        "key": "ctrl+a",
        "command": "-extension.vim_ctrl+a",
        "when": "editorTextFocus && vim.active && vim.use<C-a> && !inDebugRepl"
    },
    {
        "key": "cmd+x",
        "command": "extension.vim_ctrl+x",
    },
    {
        "key": "ctrl+x",
        "command": "-extension.vim_ctrl+x",
        "when": "editorTextFocus && vim.active && vim.use<C-x> && !inDebugRepl"
    },
    {
        "key": "cmd+u",
        "command": "extension.vim_ctrl+u",
        "when": "editorTextFocus && vim.active && vim.use<C-u> && !inDebugRepl"
    },
    {
        "key": "ctrl+u",
        "command": "-extension.vim_ctrl+u",
        "when": "editorTextFocus && vim.active && vim.use<C-u> && !inDebugRepl"
    },
    {
        "key": "cmd+d",
        "command": "extension.vim_ctrl+d",
        "when": "editorTextFocus && vim.active && vim.use<C-d> && !inDebugRepl"
    },
    {
        "key": "ctrl+d",
        "command": "-extension.vim_ctrl+d",
        "when": "editorTextFocus && vim.active && vim.use<C-d> && !inDebugRepl"
    },
    {
        "key": "cmd+i",
        "command": "extension.vim_ctrl+i",
        "when": "editorTextFocus && vim.active && vim.use<C-i> && !inDebugRepl"
    },
    {
        "key": "ctrl+i",
        "command": "-extension.vim_ctrl+i",
        "when": "editorTextFocus && vim.active && vim.use<C-i> && !inDebugRepl"
    },
    {
        "key": "cmd+o",
        "command": "extension.vim_ctrl+o",
        "when": "editorTextFocus && vim.active && vim.use<C-o> && !inDebugRepl"
    },
    {
        "key": "ctrl+o",
        "command": "-extension.vim_ctrl+o",
        "when": "editorTextFocus && vim.active && vim.use<C-o> && !inDebugRepl"
    },
    // --- 取消一些vim插件的额外功能
    {
        "key": "cmd+a",
        "command": "-extension.vim_cmd+a",
        "when": "editorTextFocus && vim.active && vim.use<D-a> && !inDebugRepl && vim.mode != 'Insert'"
    },
    {
        "key": "alt+cmd+down",
        "command": "-extension.vim_cmd+alt+down",
        "when": "editorTextFocus && vim.active && !inDebugRepl"
    },
    {
        "key": "alt+cmd+up",
        "command": "-extension.vim_cmd+alt+up",
        "when": "editorTextFocus && vim.active && !inDebugRepl"
    },
    {
        "key": "cmd+c",
        "command": "-extension.vim_cmd+c",
        "when": "editorTextFocus && vim.active && vim.overrideCopy && vim.use<D-c> && !inDebugRepl"
    },
    {
        "key": "cmd+v",
        "command": "-extension.vim_cmd+v",
        "when": "editorTextFocus && vim.active && vim.use<D-v> && vim.mode == ''CommandlineInProgress' !inDebugRepl' || editorTextFocus && vim.active && vim.use<D-v> && !inDebugRepl && vim.mode == 'SearchInProgressMode'"
    },
    {
        "key": "cmd+d",
        "command": "-extension.vim_cmd+d",
        "when": "editorTextFocus && vim.active && vim.use<D-d> && !inDebugRepl"
    },
    {
        "key": "cmd+left",
        "command": "-extension.vim_cmd+left",
        "when": "editorTextFocus && vim.active && vim.use<D-left> && !inDebugRepl && vim.mode != 'Insert'"
    },
    {
        "key": "cmd+right",
        "command": "-extension.vim_cmd+right",
        "when": "editorTextFocus && vim.active && vim.use<D-right> && !inDebugRepl && vim.mode != 'Insert'"
    },
    // --- 取消或更改一些vscode键位
    // cmd+a全选功能在非INSERT模式下不生效
    {
        "key": "cmd+a",
        "command": "editor.action.selectAll",
        "when": "vim.mode != 'Normal' && vim.mode != 'Visual' && vim.mode != 'VisualLine' && vim.mode != 'VisualBlock' && vim.mode != 'CommandlineInProgress'"
    },
    {
        "key": "cmd+a",
        "command": "-editor.action.selectAll"
    },
    // cmd+c或者cmd+v功能在非INSERT模式下不生效
    {
        "key": "cmd+c",
        "command": "-editor.action.clipboardCopyAction"
    },
    {
        "key": "cmd+v",
        "command": "-editor.action.clipboardPasteAction"
    },
    {
        "key": "cmd+c",
        "command": "-execCopy"
    },
    {
        "key": "cmd+c",
        "command": "execCopy",
        "when": "vim.mode != 'Normal' && vim.mode != 'Visual' && vim.mode != 'VisualLine' && vim.mode != 'VisualBlock' && vim.mode != 'CommandlineInProgress'"
    },
    {
        "key": "cmd+v",
        "command": "-execPaste",
    },
    {
        "key": "cmd+v",
        "command": "execPaste",
        "when": "vim.mode != 'Normal' && vim.mode != 'Visual' && vim.mode != 'VisualLine' && vim.mode != 'VisualBlock' && vim.mode != 'CommandlineInProgress'"
    },
]

资源管理配置

默认的资源管理配置只包含了上下左右移动等基础命令,所以我们需要手动添加新增、删除、剪切、刷新等操作命令,它们仅在资源管理器中生效:

j : 向下移动
k : 向上移动
space : 打开文件或目录

// 手动新增:

i : 新增文件
o : 新增目录
r : 刷新目录
a : 重命名文件或目录
d : 删除文件或目录
x : 剪切文件或目录
y : 复制文件或目录
p : 粘贴文件或目录

在keybindings.json文件中加入以下配置项:

    // --- 资源管理器中对文件或目录的操作
    // 新建文件
    {
        "key": "i",
        "command": "explorer.newFile",
        "when": " explorerViewletVisible && filesExplorerFocus && !explorerResourceIsRoot && !explorerResourceReadonly && !inputFocus "
    },
    // 新建目录
    {
        "key": "o",
        "command": "explorer.newFolder",
        "when": " explorerViewletVisible && filesExplorerFocus && !explorerResourceIsRoot && !explorerResourceReadonly && !inputFocus "
    },
    // 刷新资源管理器
    {
        "key": "r",
        "command": "workbench.files.action.refreshFilesExplorer",
        "when": " explorerViewletVisible && filesExplorerFocus && !explorerResourceIsRoot && !explorerResourceReadonly && !inputFocus "
    },
    // 重命名文件或目录
    {
        "key": "a",
        "command": "renameFile",
        "when": " explorerViewletVisible && filesExplorerFocus && !explorerResourceIsRoot && !explorerResourceReadonly && !inputFocus "
    },
    // 删除文件或目录
    {
        "key": "d",
        "command": "deleteFile",
        "when": " explorerViewletVisible && filesExplorerFocus && !explorerResourceIsRoot && !explorerResourceReadonly && !inputFocus "
    },
    // 剪切文件或目录
    {
        "key": "x",
        "command": "filesExplorer.cut",
        "when": "explorerViewletVisible && filesExplorerFocus && !explorerResourceIsRoot && !explorerResourceReadonly && !inputFocus"
    },
    // 复制文件或目录
    {
        "key": "y",
        "command": "filesExplorer.copy",
        "when": "explorerViewletVisible && filesExplorerFocus && !explorerResourceIsRoot && !inputFocus"
    },
    // 粘贴文件或目录
    {
        "key": "p",
        "command": "filesExplorer.paste",
        "when": "explorerViewletVisible && filesExplorerFocus && !explorerResourceReadonly && !inputFocus"
    },

输入法切换

如果你在INSERT模式下使用中文输入法进行编辑,当ESC到NORMAL模式下后,它将依然保持中文输入法,这会使我们需要频繁的使用ctrl+shift或者cmd+space进行输入法切换,非常麻烦。

为了解决这个问题,你必须先在你的计算机上安装一个im-select脚本(根据官方文档来看,貌似只有mac和windows平台下存在这个问题):

$ curl -Ls https://raw.githubusercontent.com/daipeihust/im-select/master/install_mac.sh | sh

这个脚本有2个作用,当你输入im-select后它将获取当前输入法,当你输入im-select xxx后它将切换至xxx输入法。

首先你需要先切换到英文输入法中到终端执行im-select命令,并把结果保存下来:

$ im-select
com.apple.keylayout.ABC

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

  // 自动切换输入法
  "vim.autoSwitchInputMethod.enable": true,
  "vim.autoSwitchInputMethod.defaultIM": "com.apple.keylayout.ABC",  // 这里输入你刚刚获得的英文输入法名称
  "vim.autoSwitchInputMethod.obtainIMCmd": "/usr/local/bin/im-select",
  "vim.autoSwitchInputMethod.switchIMCmd": "/usr/local/bin/im-select {im}"

内置插件

vsocde-vim中内置了很多插件,使用它们可以快速的进行某一些操作。

1)vim-esaymotion插件,使用它之前你必须在settings.json中加入下面这一行:

"vim.easymotion": true,

它的作用是通过以下的按键组合,你可以快速的定位到任何你想修改的行中:

<leader><leader>s<char>

2)vim-surround插件,如果你想修改、或者删除单引号和双引号,它带给你的体验将是无与伦比的,以下是它的语法:

ds<existing>
cs<existing><desired>

示例如下:

# 删除以下的[]
[1, 2, 3] -> ds[

# 将以下的[]修改为()
[1, 2, 3] -> cs[(

3)vim-commentary插件,该插件能够快速的利用键盘进行行或者块的注释,它内部其实是调用了vscode的注释API:

gcc :行注释
gCC :块注释

便捷操作

除此之外,vscode-vim插件也额外提供了一些非常多的快捷键用于编辑操作:

gd : 跳转到函数定义或引用处,搭配cmd+i/cmd+o查看源码很方便
gh : 触发帮助提示
gb : 开启多光标模式,选中和当前单词相同的单词

推荐插件

有一些朋友可能和我一样安装了google-translate插件或者comment-translate插件来查看源代码注释的翻译结果,这个时候你将会遇到一些问题。

如一次性选择翻译的文本太长,vscode的hover无法支持scroll的快捷键滚动操作,你只能通过鼠标滚轮进行hover窗口的滚动:

comment-demo

该问题在vscode的github上多次被提到,这对全键盘操作用户来说是非常不友好的,可以参见#69836

对此有一个折中的解决方案,安装一个Doc View插件,将翻译结果放在侧边栏中,这样我们就有足够的空间来显示翻译结果了:

image-20211108021727731

另外一个问题就是关于Error的提示信息,你可以自定义一些热键来快速查看Error,或者跟我一样安装一个Error Lens插件。

如下图所示,有了该插件我们就能快速的查看到一些问题的提示信息了:

image-20211108022237711

配合上面定义的g[或者g]热键,就可以快速的定位到某个错误并进行修改。

写在后面

为什么不选择使用vim来搭建一个IDE呢?

  • 太麻烦、懒得折腾,vscode足够强大…

为什么不选择使用vscode neovim插件呢?

  • visual模式不是vscode的真正选择,多端同步比vscode-vim麻烦是我没选择它的主要原因

vim真的很好用吗?

  • 使用vim能治好你的vim崇拜症,但是vim并不是必须的

此外,网上搜了很多资料无一例外都是比较浅显的介绍了一下vsocode-vim插件就完了,但是真正让你能够搭配出一套全键盘使用方案的文章少之又少,所以这里就将我的折腾历程发了出来,很显然它比单纯的折腾vim要快很多。

参考文档

参考文档:

原文地址:https://www.cnblogs.com/YunyaSir/p/15522565.html