这篇文章编辑自 2016 年的一篇文章.
当年研究过一段时间 VIM, 因为操作不熟练没有用作主力 IDE, 而是单纯在 CLI 里面用于轻度编辑
多年过去了, VSC 成为了主力 IDE, VSC 的 VIM 插件也变得更好用了
我使用 VSC 的快捷键已经可以达到很高的操作速度, 不过多学几个快捷键没什么坏处
首先需要安装 VSC 的 VIM 插件
gd
: VSC 类似 Ctrl+点击
, 查看所选内容的引用gh
: 类似于鼠标 hoveraf
- visua mode command which selects increasingly large blocks of text. For example, if you had "blah (foo [bar 'ba|z'])" then it would select 'baz' first. If you pressed af again, it'd then select [bar 'baz'], and if you did it a third time it would select "(foo [bar 'baz'])".gt/gT
: 正向反向跳转文件标签页, VSC 自身也有快捷键这个可以选择性使用 2gt
: 这个其实是激活第二个标签页, 注意不是跳两次这个插件的目的是为了方便使用 motion 命令快速跳转
Based on vim-easymotion and configured through the following settings:
需要进行一些配置:
"vim.leader": "<space>", // 关键快捷键
"vim.easymotion": true, // 开启功能
如上配置之后可以通过 <space><space>w{char}
快速跳转到包含特定字母的字符的开头
Motion Command | Description |
---|---|
<leader><leader> s <char> | Search character 搜索单个字母 |
<leader><leader> f <char> | Find character forwards 向后搜索单个字母, 建议使用 <leader><leader> s <char> 代替 |
<leader><leader> F <char> | Find character backwards 向前搜索单个字母, 建议使用 <leader><leader> s <char> 代 |
<leader><leader> t <char> | Til character forwards |
<leader><leader> T <char> | Til character backwards |
<leader><leader> w | Start of word forwards 向后搜索单词头 |
<leader><leader> b | Start of word backwards 向前搜索词头 |
<leader><leader> l | Matches beginning & ending of word, camelCase, after _, and after # forwards 向后搜索单词词首或者词尾, 单词数量少的情况下 <leader><leader> w 效率更高 |
<leader><leader> h | Matches beginning & ending of word, camelCase, after _, and after # backwards 向前搜索单词词首或者词尾, 单词数量少的情况下 <leader><leader> w 效率更高 |
<leader><leader> e | End of word forwards |
<leader><leader> ge | End of word backwards |
<leader><leader> j | Start of line forwards |
<leader><leader> k | Start of line backwards |
<leader><leader> / <char>…… <CR> | Search n-character |
<leader><leader><leader> bdt | Til character |
<leader><leader><leader> bdw | Start of word |
<leader><leader><leader> bde | End of word |
<leader><leader><leader> bdjk | Start of line |
<leader><leader><leader> j | JumpToAnywhere motion; default behavior matches beginning & ending of word, camelCase, after _ and after # |
<leader><leader> (2s|2f|2F|2t|2T) <char><char>
and <leader><leader><leader> bd2t <char>char>
are also available. The difference is character count required for search. For example, <leader><leader> 2s <char><char>
requires two characters, and search by two characters. This mapping is not a standard mapping, so it is recommended to use your custom mapping.
{
"before": ["J"], // 将 Shift+J 设置成 Easymotion 的
"after": ["<leader>", "leader", "/"]
},
Based on surround.vim, the plugin is used to work with surrounding characters like parentheses, brackets, quotes, and XML tags.
Setting | Description | Type | Default Value |
---|---|---|---|
vim.surround | Enable/disable vim-surround | Boolean | true |
t
or <
as <desired>
or <existing>
will enter tag entry mode. Using <CR>
instead of >
to finish changing a tag will preserve any existing attributes.
Surround Command | Description |
---|---|
S <desired> | Surround when in visual modes (surrounds full selection) 需要预先选中内容 |
y s <motion> <desired> | Add desired surround around text defined by <motion> 经常误操作, 建议选中后使用 S <desired> 代替此操作 |
d s <existing> | Delete existing surround 删除包裹的符号, 不需要选中, 直接查找最近的符号 |
c s <existing> <desired> | Change existing surround to desired 替换包裹的符号, 不需要选中, 直接查找最近的符号 |
Some examples:
"test"
with cursor inside quotes type cs"'
to end up with 'test'
"test"
with cursor inside quotes type ds"
to end up with test
"test"
with cursor inside quotes type cs"t
and enter 123>
to end up with <123>test</123>
Based on vim-sneak, it allows for jumping to any location specified by two characters.
另一种跳转工具, 实现搜索两个首字母方便跳转
Setting | Description | Type | Default Value |
---|---|---|---|
vim.sneak | Enable/disable vim-sneak | Boolean | false |
vim.sneakUseIgnorecaseAndSmartcase | Respect vim.ignorecase and vim.smartcase while sneaking | Boolean | false |
Once sneak is active, initiate motions using the following commands. For operators sneak uses z
instead of s
because s
is already taken by the surround plugin.
Motion Command | Description |
---|---|
s<char><char> | Move forward to the first occurrence of <char><char> 核心在于搜索两个首字母 |
S<char><char> | Move backward to the first occurrence of <char><char> |
<operator>z<char><char> | Perform <operator> forward to the first occurrence of <char><char> |
{
"vim.leader": "<space>",
"vim.easymotion": true,
"vim.surround": true,
"vim.useSystemClipboard": true,
"vim.sneak": true,
"vim.sneakUseIgnorecaseAndSmartcase": true,
"vim.normalModeKeyBindingsNonRecursive": [
{
"before": ["x"] /* delete a char and do not copy */,
"after": ["\"", "_", "x"]
},
{
"before": ["X"],
"after": ["\"", "_", "X"]
},
{
"before": ["d", "d"] /* delete a line and do not copy */,
"after": ["\"", "_", "d", "d"]
}
],
"vim.normalModeKeyBindings": [
{
"before": ["J"],
"after": ["<leader>", "leader", "/"]
},
{
"before": ["H"] /* (Uppercase) H = ^ */,
"after": ["^"] /* jump to the first (non-blank) character of the line */
},
{
"before": ["L"] /* (Uppercase) L = ^ */,
"after": [
"g",
"_"
] /* jump to the last (non-blank) character of the line */
}
],
"vim.handleKeys": {
"<C-d>": false /* set to false then VSCode will handle hotkeys instead of vim */,
"<C-a>": false,
"<C-s>": false,
"<C-c>": false,
"<C-v>": false,
"<C-z>": false
}
}
控制面板\所有控制面板项\轻松使用设置中心\设置筛选键
里面将 启用重复键和慢速键
打开
i
进入插入模式 i
将光标定位到选择内容前方a
将光标定位到选择内容后方Esc 或者 Ctrl+[
回到普通模式Esc
回到普通模式w
: 跳到下一个单词的开头b
: 跳到当前单词或者上一个单词的开头e
: 跳到当前单词或者下一个单词的结尾ge
: 调到上一个单词的结果0
: 数字 0, 跳到行首的任何字符$
: 跳到行尾的任何字符^
: 跳到行首的非空字符g_
: 跳到行尾的非空字符gg
: 跳到文件第一行的行首非空字符G
: 跳到文件最后一行的行首非空字符f{char}
: 跳转到行内下一个 {char} 位置F{char}
: 跳转到行内上一个 {char} 位置t{char}
: 跳转到行内下一个 {char} 前, 比 f{char}
少取一个字符T{char}
: 跳转到行内上一个 {char} 后, 同样少取一个字符vim.handleKeys
可以防止冲突 ) Ctrl+f/b
: 向前/向后移动一页Ctrl+d/u
: 向前/向后移动半页;
/,
: 正向/反向重复行内查找.
/u
: 正向/反向重复文本改变n
/N
: 正向/反向重复全文查找&
/u
: 正向/反向重复替换@{marco}
/u
: 正向/反向执行宏i
: 选中范围内(Inner), vi(
会选括号内的内容a
: 选中范围(Around), va(
会连括号一起选中d
: 删除(同时会复制)c
: 修改(同时进入插入模式)y
: 复制v
: 进入 VISUAL 模式dd
: 删除一行cc
: 删除一行并从非空位置开始输入yy
: 复制一行2yy
: 复制三行di(
/dib
: 删除小括号内的内容da(
/dab
: 删除小括号以及里面的内容di{
/diB
: 删除大括号内的内容ci<
: 快速修改尖括号里面的内容dfa
: 从当前开始删除到下一个字母 aya`
: 快速复制 backtick 符号以及里面的内容d$
: 从当前一直删除到结尾d^
: 从当前一直删除到开头die
: 删除整个文件dit
: 删除一个 Tag 里面的内容, 适合 XML 文件dat
: 删除一个 Tag 全部q{char}
: 录制一个宏命令并保存到 {char}
- q
: 输入完毕后停止录制, 可能不会有什么反应但是会停止录制 - @{char}
: 执行录制的名称为 {char}
的宏 - :register {char}
: 查看已经录制的宏的细节 - qaq
: 清楚所有宏{char}
指任何可输入字符<CR>
指 Enter
按键<C-{char}>
指按住 Ctrl
然后按下 {char}
对应的按钮命令码 | 含义 | Comment |
---|---|---|
h j k l | 光标左,下,上,右 | |
x | 删除一个字符 | |
y | 复制 | |
. | 重复上次编辑行为,重复命令码之前执行的所有编辑行为 | 圆点符号 |
u | 撤销 | |
> | 增加缩进 | |
w | 正向移动到下一单词的开头 | 改为大写按钮后则不按照单词移动,按照字串移动 |
b | 反向移动到上一单词的开头 | 改为大写按钮后则不按照单词移动,按照字串移动 |
e | 正向移动到下一单词的结尾 | 改为大写按钮后则不按照单词移动,按照字串移动 |
c | 修改 | 从当前字符修改至单词末尾: cw修改整个单词: caw |
d | 删除光标所在整个单词 | 删除整个单词: daw删除整个段落: dap |
<C-a> | 对选中的数字进行加 1 对选中的数字进行减一 | 对负数也有效 |
f{char} | 在行内查找下一指定字符 | 继续查找下一个: ;继续查找上一个: , |
/pattern<CR> | 在文档中查找下一处匹配项 | 继续查找下一个: n继续查找上一个: N |
?pattern<CR> | 在文档中查找上一处匹配项 | 同上 |
:s/target/replacement | 替换 | 继续替换下一个: &回退: u替换特定行范围内的文字: {num},{num}s/old/new/ |
$ | 行尾 | 单独使用可以跳到行尾,也可配合其他命令使用 |
r | 替换 | 可以替换单个字符,如果选中多个字符则会换为相同长度的重复单个字符 |
% | 跳转括号 | 跳转到对应括号的字符处 |
a | 在光标之后插入文本 | 在行末插入文本: A |
:wq | 保存并退出 | 前方加上! 可以强制执行 |
:q | 不保存并退出 | 前方加上! 可以强制执行 |
:{number} | 直接跳转特定行号 | |
0 | 无脑移动到行首 | |
^ | 移动到本行第一个非 blank 的位置 | |
$ | 无脑移动到行尾 | 注意这里和 ^ 并不是完全相反的功能 |
g_ | 移动到本行最后一个非 blank 的位置 | 注意是 g 后面带上一个下划线 |
o O | 在当前行的前或后重新创建一行开始输入并进入编辑模式 | 这里是大小写的字母 O |
I A | 在当前行的行首或行尾开始输入并进入编辑模式 |
附一张 VIM 键位图1:
例如下面这样的文字:
| aaa| vaaaa<br>aaaa<br>bbbb |
如果我们要修改出左边的aaa
,则可以直接双击然后修改
而若要修改右边的一团 vaaaa<br>aaaa<br>bbbb
,只需要几个按键:vt|
v
代表开始选择t
代表直到某个特定字符|
就代表竖线字符如此可以快速的选中右边的一团,最重要的是不需要操作鼠标
如果有多个这样格式的一团需要进行批量选中修改,那么VIM
可以节省很多时间
[^2]: [http://www.vimer.cny](http://www.vimer.cn)
例如需要选取大括号内的数据,只需要输入vi[
即可快速选中括号内所有数据,而不用移动鼠标来进行选取
如果选取是为了修改则可以直接输ci[
之前就听说 Marco Recording 是个很 6 的功能,这次正好来体验一下2
比如有 100 个这样的 item,要从中筛选出 30 个,如果用普通方法我们需要选中每个 item,然后删除,如果使用普通vim
,我们可以使用5dd
来删除每个 item,但是需要定位到 item 开头的cards
标签才能执行,这时候macro
是个很不错的 Solution
cards
cardNamecardName
cardDesc-cardDesc
cardType7cardType
cards
cards
cardNamecardName
cardDesc-cardDesc
cardType7cardType
cards
cards
cardNamecardName
cardDesc-cardDesc
cardType7cardType
cards
命令码 | 含义 | Comment |
---|---|---|
q{char} | 录制宏并保存到{char}这个变量中 | |
q | 停止录制 | |
「{char}p | 显示{char}变量里录制好的命令细节,会输出到光标所在位置 | |
{num}@{char} | 执行{char}里面录制的宏命令 |
这时候只需要以下几步
qa
: 开始录制宏并保存到变量a
中?cards{Enter}
: 跳转到前一个 cards 的位置并取消选择5ddq
: 删除 5 行并停止录制然后如果想要删除特定 item 就只需要输入@a
来调用变量a
里面保存的宏命令