按键映射
VSCode 允许直接从键盘执行大多数任务。
键盘快捷方式编辑器
键盘快捷键方式: 文件|首选项|设置|键盘快捷方式
他提供了交互式的方式来帮助用户修改快捷键,最终设置的快捷键会被保存到 keybindings.json
中。
keybindings.json
尽管方便但是要想设置比较复杂的还是直接编辑 keybindings.json 文件方便。
一个完整的键位映射由以下几部分组成:
key
: 用于描述哪些键被按下command
: 要自信的命令when
: 包含布尔表达式来定义执行的条件
// Keybindings that are active when the focus is in the editor
{ "key": "home", "command": "cursorHome", "when": "editorTextFocus" },
{ "key": "shift+home", "command": "cursorHomeSelect", "when": "editorTextFocus" },
// Keybindings that are complementary
{ "key": "f5", "command": "workbench.action.debug.continue", "when": "inDebugMode" },
{ "key": "f5", "command": "workbench.action.debug.start", "when": "!inDebugMode" },
// Global keybindings
{ "key": "ctrl+f", "command": "actions.find" },
{ "key": "alt+left", "command": "workbench.action.navigateBack" },
{ "key": "alt+right", "command": "workbench.action.navigateForward" },
// Global keybindings using chords (two separate keypress actions)
{ "key": "ctrl+k enter", "command": "workbench.action.keepEditor" },
{ "key": "ctrl+k ctrl+w", "command": "workbench.action.closeAllEditors" },
key
key 定义被按下的按键,他通常由前缀(modifier)和键(key)组成,允许出现 Ctrl+K Ctrl+C
这样的类 Emacs 的组合键。其中可用的修饰键包括:
平台 | 修饰键 |
---|---|
MacOS | Ctrl+ Shift+ Alt+ Cmd+ |
Windows | Ctrl+ Shift+ Alt+ Win+ |
Linux | Ctrl+ Shift+ Alt+ Meta+ |
接受的按键包括:
f1 ~ f19
、a-z0-9
- `,-=[]\;,'./``
left up right down pageup pagedown end home
tab enter escape space backspace delete
pausebreak capslock insert
command
命令中包含要执行的命令字符串,可以在通过右键复制命令 ID 来获取命令字符串:
对于需要参数的命令,可以使用 args
来指定:
// type 将接受 {"text": "Hello World"} 作为参数
{
"key": "enter",
"command": "type",
"args": { "text": "Hello World" },
"when": "editorTextFocus"
}
VSCode 提供了一个比较特殊的 runCommands
来运行多条命令,其他命令以参数形式提供:
{
"key": "ctrl+alt+c",
"command": "runCommands",
"args": {
"commands": [
"editor.action.copyLinesDownAction",
"cursorUp",
"editor.action.addCommentLine",
"cursorDown"
]
}
}
when
when 子句来定义应用快捷键的上下文。他会根据后面的布尔表达式的结果来确定是否应用快捷键对应的命令。
布尔表达式可以由运算符参与运算:
运算符 | 说明 | 示例 |
---|---|---|
== | 相等 | "editorLangId == typescript" |
≠ | 不等 | "resourceExtname != .js" |
> ≥ < ≤ | 比较 | "gitOpenRepositoryCount >= 1" |
\|\| |
或 | "isLinux \|\| isWindows" |
&& | 与 | "textInputFocus && !editorReadonly" |
! | 非 | "!editorReadonly" |
=~ | 正则匹配 | "resourceScheme =~ /^untitled$ \| ^file$/" |
in/not in | 成员检测 | "resourceFilename in supportedFolders" |
键盘映射扩展 Vim
扩展中提供了对其他键盘映射的支持,其中比较重要的就是 vim 模拟。VSCode 中可以通过安装vim 插件来引入 vim-mode,不过他与真正的 vim 还有些区别而且配置与 vim 也大相径庭,要想好用需要进行一些比较复杂的配置。
按键映射
在 VSCode 中模拟 vim 最重要也是最麻烦的就是按键映射。由于存在 vim 插件和 vscode 内置按键映射体系所以配置起来会比较麻烦。
模拟 vim 按键映射
vim 插件提同样提供了四种类型的按键映射方法:
vim.insertModeKeyBindings
: Insert 模式下映射vim.normalModeKeyBindings
: Normal 模式下映射vim.visualModeKeyBindings
: Visual 模式下映射vim.operatorPendingModeKeyBindings
: 操作映射
他们还有一个非递归版本:
vim.insertModeKeyBindingsNonRecursive
: Insert 模式下映射(非递归)vim.normalModeKeyBindingsNonRecursive
: Normal 模式下映射(非递归)vim.visualModeKeyBindingsNonRecursive
: Visual 模式下映射(非递归)vim.operatorPendingModeKeyBindingsNonRecursive
: 操作映射(非递归)
注意他们被定义在 settings.json 中,每一个按键绑定可以包含:
before
: 数组,其中包含触发按键after
: 数组,其中包含映射按键commands
: 数组,可以包含的 vim 命令、vscode 中的命令silent
: 布尔值,表示是否静默
{
"vim.insertModeKeyBindings": [
{
"before": ["j", "j"],
"after": ["<Esc>"]
}
],
"vim.normalModeKeyBindingsNonRecursive": [
{
"before": ["<leader>", "d"],
"after": ["d", "d"]
},
{
"before": ["<C-n>"],
"commands": [":nohl"]
},
{
"before": ["K"],
"commands": ["lineBreakInsert"],
"silent": true
}
],
"vim.leader": "<space>",
"vim.handleKeys": {
"<C-a>": false,
"<C-f>": false
}
}
使用 vscode 内置的映射
插件建议首先应当考虑使用模拟 vim 按键映射的方式来创建映射,不过有时候直接使用 vscode 内置的 keybindings.json
来编辑映射是非常方便的,并且 vim 映射并不支持 Alt + key
或 Ctrl+Shift+key
这样的组合键。它通常用于将 VSCode 中的快捷键映射到 vim 模式下:
{
"key": "ctrl+shift+y",
"command": "vim.remap",
"when": "inputFocus && vim.mode == 'Normal'",
"args": {
"after": ["y", "y"]
}
}
上面就是一个典型的映射方式,其中比较特殊的就是使用 when 指定映射规则,inputFocus 表示光标激活,vim.mode == 'Normal'
即处于 Normal 模式,目前支持的模式包括:
- Normal
- Insert
- Visual
- VisualBlock
- VisualLine
- SearchInProgressMode
- CommandlineInProgress
- Replace
- EasyMotionMode
- EasyMotionInputMode
- SurroundInputMode
- OperatorPendingMode
- Disabled
vim 设置
vim 插件提供了几个 vim 设置来规定一些行为:
setting | desc | default |
---|---|---|
vim.autoindent | 创建新行时继承缩进 | true |
vim.hlsearch | 突出显示搜索匹配的的文本 | false |
vim.ignorecase | 搜索忽略大小写 | true |
vim.incsearch | 输入搜索时显示下一个匹配项 | true |
vim.leader | 定义 leader 的按键 | '\\' |
vim.showmodename | 在状态栏显示 mode | true |
vim.smartcase | 如果搜索字符串时包含大写,则覆盖忽略大小写设置 | true |
vim.textwidth | 使用 gq 自动换行的宽度 | 80 |
vim.timeout | 重新映射命令的超时时间 | 1000 |
vim.whichwrap | 当光标位于行中第一个/最后一个字符上时允许移动光标的上一行/下一行 | 'b,s' |
插件
vim插件重写了一些著名的 vim 插件。
vim-easymotion
用于快速光标移动。
用户配置
{
"vim.leader": " ", // Leader 设置为空格
"vim.easymotion": true, // 开启 easymotion 插件 <leader>jw{char} <leader>jl
"vim.sneak": true, // 开启 sneak 插件 s{char}{char}
"vim.sneakUseIgnorecaseAndSmartcase": true,
"vim.useCtrlKeys": false, // 禁用 vim 的 ctrl 按键,允许 Ctrl+s 之类键位可用
"vim.foldfix": true, // 允许 jk 跳过折叠
"vim.useSystemClipboard": true, // 使用系统剪切板
// Normal 下按键绑定
"vim.normalModeKeyBindingsNonRecursive": [
{
"before": [":"],
"commands": ["workbench.action.showCommands"],
"silent": true
},
// ============== 窗口管理 ============================
// 聚焦到 1-5 编辑器组
{
"before": ["<leader>", "1"],
"commands": ["workbench.action.focusFirstEditorGroup"],
"silent": true
},
{
"before": ["<leader>", "2"],
"commands": ["workbench.action.focusSecondEditorGroup"],
"silent": true
},
{
"before": ["<leader>", "3"],
"commands": ["workbench.action.focusThirdEditorGroup"],
"silent": true
},
{
"before": ["<leader>", "4"],
"commands": ["workbench.action.focusFourthEditorGroup"],
"silent": true
},
{
"before": ["<leader>", "5"],
"commands": ["workbench.action.focusFifthEditorGroup"],
"silent": true
},
// 关闭编辑器组以及其中的编辑组
{
"before": ["<leader>", "w", "d"],
"commands": ["workbench.action.closeEditorsAndGroup"],
"silent": true
},
// 最大化组
{
"before": ["<leader>", "w", "c"],
"commands": ["workbench.action.maximizeEditor"],
"silent": true
},
// 关闭其他编辑器
{
"before": ["<leader>", "w", "o"],
"commands": ["workbench.action.closeEditorsInOtherGroups"],
"silent": true
},
// 聚焦下上右左编辑器组
{
"before": ["<leader>", "w", "j"],
"commands": ["workbench.action.focusBelowGroup"],
"silent": true
},
{
"before": ["<leader>", "w", "k"],
"commands": ["workbench.action.focusAboveGroup"],
"silent": true
},
{
"before": ["<leader>", "w", "h"],
"commands": ["workbench.action.focusLeftGroup"],
"silent": true
},
{
"before": ["<leader>", "w", "l"],
"commands": ["workbench.action.focusRightGroup"],
"silent": true
},
// 垂直水平分隔编辑器
{
"before": ["<leader>", "w", "v"],
"commands": ["workbench.action.splitEditorRight"],
"silent": true
},
{
"before": ["<leader>", "w", "s"],
"commands": ["workbench.action.splitEditorDown"],
"silent": true
},
//================== Buffer ===========================
// vscode 以编辑器呈现 Buffer
// 所有组中关闭编辑器,默认关闭 buffer
{
"before": ["<leader>", "b", "d"],
"commands": ["workbench.action.closeEditorInAllGroups"],
"silent": true
},
// 打开组中下一个编辑器
{
"before": ["<leader>", "b", "l"],
"commands": ["workbench.action.openNextRecentlyUsedEditorInGroup"],
"silent": true
},
// 打开组中上一个编辑器
{
"before": ["<leader>", "b", "h"],
"commands": ["workbench.action.openPreviousRecentlyUsedEditorInGroup"],
"silent": true
},
// 切换只读,选项卡处加锁
{
"before": ["<leader>", "b", "r"],
"commands": [
"workbench.action.files.toggleActiveEditorReadonlyInSession"
],
"silent": true
},
// ============== File ===========================
// 保存文件
{
"before": ["<leader>", "b", "w"],
"commands": ["workbench.action.files.save"],
"silent": true
},
{
"before": ["<leader>", "e"],
"commands": ["workbench.files.action.focusFilesExplorer"],
"silent": true
},
// ============== easymotion =======================
{
"before": ["<leader>", "j", "w"],
"after": ["<leader>", "<leader>", "s"]
},
{
"before": ["<leader>", "j", "l"],
"after": ["<leader>", "<leader>", "<leader>", "b", "d", "j", "k"]
}
]
}