[toc]
Vim基础
{
/* vim */
"vim.incsearch": true,
"vim.useSystemClipboard": true,
// "vim.hlsearch": true, 对/字符串的搜索方式来说,搜索到的结果一直高亮显示,不设置这一项美观些
"vim.easymotion": true, // 启用vim-easymotion
"vim.leader": "<space>", // easymotion中,leader键映射为空格键
"vim.sneak": true, // 启用vim-sneak
"vim.insertModeKeyBindings": [
{
"before": ["j", "j"],
"after": ["<Esc>"]
}
],
"vim.normalModeKeyBindingsNonRecursive": [
// 到行首^映射为H,到行尾$映射为L
{
"before": ["H"],
"after": ["^"]
},
{
"before": ["L"],
"after": ["$"]
},
// easymotion快速跳转映射,s + <char>
{
"before": ["<leader>", "s"],
"after": ["<leader>", "<leader>", "s"]
},
// leader+u/d 代替 Ctrl+u/d 使页面向上/下滚动半屏
{
"before": ["leader", "u"],
"after": ["<C-u>"]
},
{
"before": ["leader", "d"],
"after": ["<C-d>"]
},
// 删到行首/行尾 暂时只能用leader + H/L,若dH/L会删除此处到代码开头/结尾
{
"before": ["leader", "H"],
"after": ["d", "^"]
},
{
"before": ["leader", "L"],
"after": ["d", "$"]
}
],
// 可视模式
"vim.visualModeKeyBindingsNonRecursive": [
{
"before": ["H"],
"after": ["^"]
},
{
"before": ["L"],
"after": ["$"]
}
],
"vim.useCtrlKeys": true, //结合下面的"vim.handleKeys"配置
"vim.handleKeys": {
"<C-a>": false,
"<C-f>": false,
// 带有vim插件的vscode,它的Ctrl+w是由vscode控制,非vim插件扩展快捷键控制。若改为true,则就是了。
"<C-w>": false
}
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
普通模式 Normal 插入模式 Insert 可视模式 Visual 命令模式 : 替换模式Replace
注
:若配置了"vim.sneak": true
则s与S就不起作用
字符 | 单词 | 行 | 跳转 | 句和段 |
---|---|---|---|---|
h 左 | w下一个单词开头 | 0 行首 | f char 跳到char位置 | ( 到句首 |
j 下 | b本单词或上一个单词开头 | ^ 行首非空字符 | F char 反向 | ) 到句尾 |
k 上 | e本单词或下一个单词结尾 | $ 行尾 | t char char前一位置 | { 到段首 |
l 右 | ge上一个单词结尾 | gg 首行 | T char char后一位置 | } 到段尾 |
W长单词 E长单词 B长单词 | G 尾行 | ; 重复上次的跳转 | ||
ngg 第n行 | , 反向查找上次的查找 |
%
移动到与光标所在括号相对应的另一半括号上(对小括号,中括号和大括号有用,尖括号无用)
注
:比较的全面,但是看每个人的习惯不同,惯用的就会不同。上述是普通模式和可视模式的光标移动,它们完全一致,由于插入模式下的光标移动快捷键和很多VSCode内置快捷键冲突,这里就不介绍了,在文章末尾有写
方便编辑和阅读代码的操作如下(不仅仅限于光标移动,包含tricks等):
类型1
zt
屏幕滚动使得当前行成为屏幕的最上面一行
zz
中间一行
zb
最下面一行
zc
关闭代码块
zo
打开代码块
za
打开或关闭代码块
类型2
Ctrl + 0
:跳转到侧边栏,并可以用jk上下移动,空格打开文件或者文件夹
Ctrl + 2
:增加一个工作区栏,以此类推,Ctrl + 1
:跳到第一个工作区栏
Ctrl + N
:新建文件 Ctrl + Shift + N
:新建文件夹(这两个在Settings -> Keyboard Shortcuts -> 搜索explorer.new -> 自定义
l
:从侧边栏回到未跳转前的文件工作区,或者新打开的文件工作区
gt
(go to tab):跳到下一个标签页
gT
(go to tab):跳到上一个标签页
ngt
(go to tab):跳到第n个标签页
类型3
gh
(go to hover):悬浮查看一些文档,签名
gd
(go to destination):跳转到定义声明或具体描述的地方
Ctrl + o
:回到跳转之前的地方 Ctrl + i
:与之相反
gb
:光标置于单词的任意位置,输入一个gb,就选中一相同的单词(想选中4个相同的单词就连续输入gb4次
==
:格式化代码
gcc
:注释本行代码
gcnj
/ngcj
:注释从本行和下方n行的代码
gcnk
/ngck
:注释从本行和上方n行的代码
操作符opertator 4个 |
---|
d 剪切(delete) |
x 剪切光标所停留的那个字符 X 剪切光标所停留的前一个字符 |
c 删除并进入插入模式(change) |
y 复制(yink) |
介词 2个 |
---|
i 表示里面 |
a 表示外面 |
名词 9个 |
---|
光标移动之字符 h j k l |
光标移动之单词 w b e… |
光标移动之行 ^ $ ngg… |
光标移动之跳转 f F … |
光标移动之句段 ( { |
( { [’`" 各种括号引号 |
t 标签 |
a 全部 |
e 全文 |
公式1:操作符
dd`:剪切一行 `3dd`/`d3d`:剪切包括本行在内的三行 `以此类推
公式2:操作符 + 名词(前五个)
3dh
/d3h
:剪切光标所停留字符的左三个字符 3dj
/d3j
:剪切光标所在行及下面三行
db
:剪切光标所停留单词到开头
dngg
:剪切本行到第n行
dfn
:剪切到当前行到下一个n字符
d{
:剪切到段落开头
公式3:操作符 + 介词 + 名词(重点后四个)
diw
剪切当前光标所停留单词,或输入gbw
di(
:删除( )
中的所有内容
da(
:删除( )
中同时包括( )
的所有内容
dit
:剪切标签对中的内容,不包含标签对
dat
:剪切标签对中的内容,包含标签对
yia
:这个我试了以下,在for…in和for…of里面可以复制,其它的暂且不知
yie
:复制全文
其它操作符及编辑技巧 6个 |
---|
rx 用字符x替换光标位置的字符 nrx 用x字符替换光标位置前的n个字符 R 进入替换模式 |
p 粘贴到当前光标的右边/下一行 P 粘贴到当前光标的左边/上一行 np(nP) 重复粘贴内容n次 |
<< 向前缩进 |
>> 向后缩进 |
u 撤销操作 |
. 再次执行刚执行过的命令 |
注
:上述展示的都是很常用的Vim普通模式下的编辑技巧
相信尝试过上述的Vim基础后,用一段时间的你,一定能够掌握好适合的常用命令
小技巧
:
- Ctrl 键有时候可以用小拇指指根摁
- VSCode内置的
Alt + ↑/↓
将当前行或者块(visualmode选择即可)上/下移
- 大写字母可以使用 Shift + 字母
vim-easymotion:Vim插件介绍里vim-easymotion有详细说明,常用的有以下(键映射中有)
vim-surround:同上,可以自己尝试,以下例子
Old text Command New text Hello world vS" "Hello world" "Hello world" ds" Hello world Hello world ysiw[ [ Hello ] world Hello world ysiw] [Hello] world [Hello] world cs]" "Hello" world "Look ma, I'm *HTML!" cs"<q> <q>Look ma, I'm HTML!</q> <div>Yo!*</div> dst Yo! <div>Yo!*</div> cst<p> <p>Yo!</p> 12345678910
vim-sneak:同上,和easymotion有些像,但是有自己的方便之处
切换大小写
~
将光标下的字母改变大小写
3~
将光标位置开始的3个字母改变其大小写
g~
改变当前行字母的大小写,
gUU
将当前行的字母改成大写
guu
将当前行的字母改成小写
gUaw或gUiw
将光标下的单词改成大写
guaw或gUaw
将光标下的单词改成小写
其它跳转方式
/string,n下翻查询结果,N上翻查询结果,enter跳转(string代表你想查找的内容)
插入模式下的光标移动
个人习惯是,在插入模式下且移动的范围很小的时候,选择性的使用插入模式下的光标移动,它的原生vim中的快捷键如下(不过很多与VSCode内置快捷键是冲突的,我是直接使用↑/↓/←/→新手使用Vim先适应模式切换,暂且不用插入模式下的光标移动可能更锻炼一些)
快捷键 | 作用 |
---|---|
Ctrl + p | up |
Ctrl + n | down |
Ctrl + b | left |
Ctrl + f | right |
Ctrl + a | 到行首 |
Ctrl + e | 到行尾 |
Ctrl + h | delete 1 |
Ctrl + w | delete back 1 word |
Ctrl + u | delete back to start of line |
原生vim的快捷键如下
快捷键 | 功能 |
---|---|
Ctrl + v | 向上滚屏 |
Ctrl + e | 向下滚屏 |
Ctrl + u | 向上滚半屏 |
Ctrl + d | 向下滚半屏 |
Ctrl + b | 向上滚整屏 |
Ctrl + f | 向下滚整屏 |
vscode-vim是一款vim模拟器,它将vim的大部分功能都集成在了vscode中,你可以将它理解为一个嵌套在vscode中的vim。
其实在vscode的扩展商店中,还有一个vscode neovim的插件也十分不错,但是相较于vscode-vim来说依然存在一些让我难以接受的缺点,比如visual模式下的选择并非真正的vscode选择等,基于种种原因我还是考虑使用vscode-vim,尽管它可能占用了更大的内存。
安装完成之后,需要做一些基础配置。
1)仅MAC用户,关闭MAC的重复键:
$ defaults write com.microsoft.VSCode ApplePressAndHoldEnabled -bool false
2)设置相对行号,在settings.json中添加上以下配置项:
"editor.lineNumbers": "relative",
3)关闭自动传参建议和代码补全建议,使用按键手动触发(可选):
"editor.parameterHints.enabled": false,
"editor.quickSuggestions": 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": [
//在NORMAL模式下按下快捷键执行COMMAND的命令,如按下<C-n>后,取消高亮搜索
{
"before": [
"<C-n>"
],
"commands": [
":nohl"
]
},
{
"before": [
"<leader>",
"g",
"c"
],
"commands": [
"workbench.action.showCommands"
]
},
],
// 插入模式下的非递归按键绑定
"vim.insertModeKeyBindings": [
// 在INSERT模式下使用jj退回到NORMAL模式
{
"before": [
"j",
"j"
],
"after": [
"<Esc>"
]
},
],
// 命令模式下的非递归按键绑定
"vim.commandLineModeKeyBindingsNonRecursive": [],
// 可视模式下的非递归按键绑定
"vim.operatorPendingModeKeyBindings": [],
// 下面定义的按键将交由vscode进行处理,而不是vscode-vim插件
"vim.handleKeys": {
"<C-a>": false,
"<C-f>": false
}
}
注意!leader键只在代码编辑区域生效,它无法做到全vscode生效。
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文件,基本的键位设置就如同上面看到的一样,但是做了一些额外的限制条件,比如和以及等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://github.com/raw/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窗口的滚动:
该问题在vscode的github上多次被提到,这对全键盘操作用户来说是非常不友好的,可以参见#69836。
对此有一个折中的解决方案,安装一个Doc View插件,将翻译结果放在侧边栏中,这样我们就有足够的空间来显示翻译结果了:
另外一个问题就是关于Error的提示信息,你可以自定义一些热键来快速查看Error,或者跟我一样安装一个Error Lens插件。
如下图所示,有了该插件我们就能快速的查看到一些问题的提示信息了:
配合上面定义的g[或者g]热键,就可以快速的定位到某个错误并进行修改。
为什么不选择使用vim来搭建一个IDE呢?
- 太麻烦、懒得折腾,vscode足够强大…
为什么不选择使用vscode neovim插件呢?
- visual模式不是vscode的真正选择,多端同步比vscode-vim麻烦是我没选择它的主要原因
vim真的很好用吗?
- 使用vim能治好你的vim崇拜症,但是vim并不是必须的
此外,网上搜了很多资料无一例外都是比较浅显的介绍了一下vsocode-vim插件就完了,但是真正让你能够搭配出一套全键盘使用方案的文章少之又少,所以这里就将我的折腾历程发了出来,很显然它比单纯的折腾vim要快很多。
参考文档:
我在windows上进行了尝试,它令我感到惊叹。
vim插件不知为何在mac和linux上都有些许卡顿,但是windows上异常顺滑,下面是我的配置方案:
[
// --- 全局命令
// 显示命令面板
{
"key": "ctrl+g c",
"command": "workbench.action.showCommands"
},
// 打开设置页面
{
"key": "ctrl+g s",
"command": "workbench.action.openSettings"
},
// 打开热键映射
{
"key": "ctrl+g k",
"command": "workbench.action.openGlobalKeybindings"
},
// 打开一个目录
{
"key": "ctrl+g d",
"command": "workbench.action.files.openFolder"
},
// 打开一个文件
{
"key": "ctrl+g f",
"command": "workbench.action.files.openFile"
},
// 打开最近记录
{
"key": "ctrl+g h",
"command": "workbench.action.openRecent"
},
// 新建vscode实例
{
"key": "ctrl+g n",
"command": "workbench.action.newWindow"
},
// 关闭vscode实例
{
"key": "ctrl+g q",
"command": "workbench.action.closeWindow"
},
// --- 文件命令
// 新建文件
{
"key": "ctrl+f n",
"command": "welcome.showNewFileEntries",
},
// 打开文件
{
"key": "ctrl+f o",
"command": "workbench.action.files.openFileFolder"
},
// 另存为文件
{
"key": "ctrl+f e",
"command": "workbench.action.files.saveAs"
},
// 保存文件
{
"key": "ctrl+f s",
"command": "workbench.action.files.save"
},
// 保存所有文件
{
"key": "ctrl+f w",
"command": "workbench.action.files.saveAll"
},
// 关闭文件
{
"key": "ctrl+f q",
"command": "workbench.action.closeActiveEditor"
},
// 关闭所有文件
{
"key": "ctrl+f a",
"command": "workbench.action.closeAllEditors"
},
// -- 侧边栏命令
// 切换侧边栏显示状态
{
"key": "ctrl+n [",
"command": "workbench.action.toggleSidebarVisibility"
},
// 显示文件资源管理器
{
"key": "ctrl+n 1",
"command": "workbench.files.action.focusFilesExplorer"
},
// 显示TODO Tree
{
"key": "ctrl+n 2",
"command": "todo-tree-view.focus"
},
// 显示全局搜索
{
"key": "ctrl+n 3",
"command": "workbench.action.replaceInFiles",
},
// 显示debug
{
"key": "ctrl+n 4",
"command": "workbench.view.debug",
"when": "viewContainer.workbench.view.debug.enabled"
},
// 显示版本控制
{
"key": "ctrl+n 5",
"command": "workbench.view.scm",
"when": "workbench.scm.active"
},
// 显示SQL Tools
{
"key": "ctrl+n 6",
"command": "workbench.view.extension.sqltoolsActivityBarContainer"
},
// 显示Docker
{
"key": "ctrl+n 7",
"command": "workbench.view.extension.dockerView"
},
// 显示测试
{
"key": "ctrl+n 8",
"command": "workbench.view.testing.focus"
},
// 显示插件商店
{
"key": "ctrl+n 9",
"command": "workbench.view.extensions",
"when": "viewContainer.workbench.view.extensions.enabled"
},
// --- 面板命令
// 切换面板显示状态
{
"key": "ctrl+p [",
"command": "workbench.action.togglePanel"
},
// 显示问题
{
"key": "ctrl+p 1",
"command": "workbench.panel.markers.view.focus"
},
// 显示输出
{
"key": "ctrl+p 2",
"command": "workbench.action.output.toggleOutput",
"when": "workbench.panel.output.active"
},
// 显示终端
{
"key": "ctrl+p 3",
"command": "workbench.action.terminal.toggleTerminal",
"when": "terminal.active"
},
// 显示调试控制台
{
"key": "ctrl+p 4",
"command": "workbench.debug.action.toggleRepl",
"when": "workbench.panel.repl.view.active"
},
// 显示SQL CONSOLE
{
"key": "ctrl+p 5",
"command": "workbench.view.extension.sqltoolsPanelContainer"
},
// --- 编辑区命令
// 关闭当前选项卡或分屏
{
"key": "ctrl+q",
"command": "workbench.action.closeActiveEditor"
},
// 聚集在第一个选项卡中
{
"key": "ctrl+e",
"command": "workbench.action.focusFirstEditorGroup"
},
// 切换到上一个选项卡
{
"key": "ctrl+,",
"command": "workbench.action.previousEditor"
},
// 切换到下一个选项卡
{
"key": "ctrl+.",
"command": "workbench.action.nextEditor",
},
{
"key": "ctrl+w s",
"command": "workbench.action.splitEditorDown"
},
// 拆分一个左右分屏
{
"key": "ctrl+w v",
"command": "workbench.action.splitEditor"
},
// 将光标向上动1屏
{
"key": "ctrl+w k",
"command": "workbench.action.focusAboveGroup"
},
// 将光标向下动1屏
{
"key": "ctrl+w j",
"command": "workbench.action.focusBelowGroup"
},
// 将光标向左移动1屏
{
"key": "ctrl+w h",
"command": "workbench.action.focusLeftGroup"
},
// 将光标向右移动1屏
{
"key": "ctrl+w l",
"command": "workbench.action.focusRightGroup"
},
// --- 代码编辑命令
// 触发帮助提示
{
"key": "ctrl+h",
"command": "editor.action.showHover",
"when": "editorTextFocus"
},
// 触发参数提示
{
"key": "ctrl+j",
"command": "editor.action.triggerParameterHints",
"when": "editorHasSignatureHelpProvider && editorTextFocus"
},
{
"key": "ctrl+j",
"command": "closeParameterHints",
"when": "editorFocus && parameterHintsVisible"
},
// 触发建议提示
{
"key": "ctrl+k",
"command": "editor.action.triggerSuggest",
"when": "editorHasCompletionItemProvider && textInputFocus && !editorReadonly"
},
{
"key": "ctrl+k",
"command": "hideSuggestWidget",
"when": "suggestWidgetVisible && textInputFocus"
},
// 移动到下一个建议
{
"key": "ctrl+n",
"command": "selectNextSuggestion",
"when": "suggestWidgetMultipleSuggestions && suggestWidgetVisible && textInputFocus"
},
// 移动到上一个建议
{
"key": "ctrl+p",
"command": "selectPrevSuggestion",
"when": "suggestWidgetMultipleSuggestions && suggestWidgetVisible && textInputFocus"
},
// 打开快速修复
{
"key": "ctrl+m",
"command": "editor.action.quickFix",
"when": "editorHasCodeActionsProvider && editorTextFocus && !editorReadonly"
},
// 格式化代码
{
"key": "ctrl+alt+l",
"command": "editor.action.formatDocument",
"when": "editorHasDocumentFormattingProvider && editorTextFocus && !editorReadonly && !inCompositeEditor"
},
// 放大字体
{
"key": "ctrl+=",
"command": "editor.action.fontZoomIn"
},
// 缩小字体
{
"key": "ctrl+-",
"command": "editor.action.fontZoomOut"
},
// --- 资源管理器中对文件或目录的操作
// 新建文件
{
"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"
},
]