vim使用指南
下面主要是针对vscode-vim的使用指南,1-9节的内容是通用的,但是后面的内容是vscode-vim特有的功能。
01.最基本操作
vim有三种模式:
- 按
ESC
进入正常模式(normal) - 在正常模式下按i,进入插入模式(insert)
- 在正常模式下按
:
键进入命令模式
三个模式里面只有插入模式是用于输入文本的,正常模式是用于编辑文本的,包括移动光标,复制粘贴删除等
命令模式可以用来执行搜索,批量替换等
在正常模式下,移动光标可以用以下几个字幕或者方向键
↑
← h j k l →
↓
在插入模式下,按 <ESC>
, <CTRL-[>
or <CTRL-C>
返回正常模式
02.更快地移动光标 motion
w
,b
,W
,B
,e
,g
,e
以单词为间隔移动光标
- w是后移
- b是向前
- W是后移包含符号的单词
- B是前移包含符号的单词
- e 移动到单词的尾部
- ge 移动到上一个单词的尾部
f
移动到本行下一个特定的字母活符号
F
移动到本行前一个特定的字母
f
和F
光标在搜索的字母前,你也可以使用t
和T
,他的光标在搜索的字母之后
当你使用了f{character}
之后,你可以用;
向后重复查找,或者使用,
向前重复查找
0
^
$
g_
移动到行末或行尾
-
0
移动到这行的最开头字母 -
^
移动到本行最开头的非空字母 -
$
移动到本行最尾部 -
g_
移动到本行最尾部的非空字母
{
}
以段落为间隔移动
翻页 CTRL+D CTRL+U
搜索
可以用正则表达式
-
/{pattern}
向下搜索 -
?{pattern}
向上搜索
输入上面的按回车就进入搜索模式,可以用n(向下)和N在搜索到的词之间移动
按照数字移动
数字在通常模式里,可以重复执行一个命令多次。
{count}{command}
比如2w
就是向下移动两个单词
5j
,就是向下移动5行
2/count
就是跳转到第二个搜索到的count位置
gd
跳转到定义,gf
跳转到导入的文件
{line}gg
跳转到指定行
-
gg
跳转到文件开头 -
G
跳转到文件结尾 -
{line}gg
跳转到文件指定行 -
%
,跳转到 匹配括号的开始和结尾({[]})
03.编辑相关操作
关于编辑操作的语法是这样的
{operator}{count}{motion}
- operator是具体的操作,比如delete,change,
- count 是操作执行的次数
- motion是操作执行的位置
举个例子,d2w
是向下删除两个单词
这些操作可以用一些英语首字母帮助记忆
- d for delete
- f for find
- c for change
- t for unTil
d
剪切(删除)操作
d
其实是剪切的功能,只不过剪切之后不粘贴回去相当于删除。
- 删除当前行
dd
-
dw
删除下一个单词 -
ggdG
删除整个文件,拆解一下就好理解,gg跳到文件开头,然后执行删除,删到文件末尾。 -
D
删除当前行光标之后的内容,等价于d$
u
撤销前一步操作 CTRL+R
重做前一步
c
删除并进入插入模式
-
cc
删除一整行并进入插入模式 -
C
删除本行光标后的内容并进入插入模式 -
cw
删除下一个单词并进入插入模式
.
重复上次产生改变的操作
以下几种类型会被视为一个可以重复的改变
-
d{motion}
-
i{typeSomething}<ESC>
-
c{typeSomething}<ESC>
使用c带来的可重复性比d会高很多
举个例子,当我们想修改下面这句话的courteously
为polite
,我们移动到单词开头执行cwpoliteESC
,就可以完成替换的工作,然后我们就可以用.
操作符重复这个替换操作
const courteousSalute = "I courteously salute you good person."
效率更高的是我们搜索和操作符,这样省去了我们移动光标找单词的时间
文本对象
文本对象就是结构化的文本,它描述一个文档中的单词,句子,段落,被引号的文本,html的tags等,你可以用这个和操作符结合来改变一个单词,句子,段落等等
|- `a` means around
|- `i` means inner
/
/
/
{a|i}{text-object}
/
/
| w - word
| s - sentence
| p - paragraph
| " - quotes
| t - html tags
和操作符结合就是这样:
{operator}{a|i}{text-object}
举个例子,假设你要修改下面的字符串,只要fR
移动到R字母,然后执行ci"
,就可以输入你想输入的内容了。也就是修改引号内的内容。
const poem = "Roses are red";
实际上上述操作还可以优化,因为文本对象,是自动应用的和你光标的位置无关,所以第一步的移动操作不需要。所以这个操作的可重复性,会比单纯的c要高。
"
,''
,和反引号操作符比较特殊,一般的wsp只有光标在文本对象上才会自动查找,而引号在同一行的前面和后面都没问题。
关于around的作用是,用a代替i会影响到分隔符和空格比如引号,大括号,小括号作为文本对象的时候会把分隔符和空格一起删除,而用i不会删除分割符和空格
其他操作
-
y
(yank)复制- yy 复制一行,和d,c这些键的逻辑是一样的
- Y 复制光标到行尾的内容
-
p
(put)粘贴
-
g~
(switch case): 把字母从小写变成大写
-
>
(shift right): 添加缩进 -
<
(shift left): 移除缩进 -
=
(format code): 格式化代码
更多简写
-
x
相当于dl
删除光标下的字母 -
X
相当于 todh
删除光标前的字母 -
s
相当于ch
, deletes 删除光标前的字母并且进入插入模式 -
r
将一个字母替换为另一个 -
~
切换一个字母的大小写
A nice way use case for x
is to swap a couple of characters when you make a typo. You remove (and cut) a character with x
and immediately paste it after the cursor with p
. Try it!
04.插入操作(insert)
i
,a
,I
,A
四种插入:
-
i
插入到光标所在字母 -
a
插入到光标后 -
I
插入到行首 -
A
插入到行尾
o
,O
开启新一行
-
o
在当前行下方开新行 -
O
在当前行上方开新行
gi
回到上次离开插入模式的地方
我们发现g这个字母,通常用作其他操作的修饰符,比如e和ge,e是到单词的结尾,ge是到上一个单词结尾。
插入模式的删除快捷键
这个快捷键小写也是生效的
-
CTRL-H
删除上次输入的字符并向左移动光标 -
CTRL-W
清楚上一个word -
CTRL-U
删除上次输入的行
退出插入模式
<ESC>
CTRL-C
CTRL-[
05.视觉模式选中文本(visual mode)
-
v
字母长度的选择 -
V
选择行 -
Ctrl-V
块选择模式
选择的语法如下
get into Visual Mode
/
/ action to apply
/ /
--------- /
{v|V|C-V}{count}{motion}{operator}
---------------
/
/
bit of text over which
to apply an action
ctrl+v
块选择模式
块选择模式比较特殊,适合批量在前方或尾部插入的场景。
总体来说在视觉模式下的操作会更加直观,相比于normal模式能清晰地看到自己想要编辑的区域。
06.更迅速地执行搜索操作
之前我们已经学到了用/
进入搜索,按下回车后,可以用n
在搜索的关键词之间移动。此时我们可以执行一个修改操作,然后n到下一个用.
操作复现。下面有一种更便捷的方式
gn
选中下一个搜索块
有了gn以后,我们就不需要按一下n在复现删除
我们直接搜索,然后gn选中第一个搜索关键词,在删除,之后用.
就可以复现选择关键词然后删除的操作。
可以dgn也可以gnd,效果是一样的,然后 4.
可以重复这个操作4词
07.复制和粘贴
-
y
复制 -
p
和P
分别是向下拷贝和向上拷贝
gp
和 gP
粘贴的时候光标位置不同,光标会在粘贴的内容往后一个字符的位置,也就是会包含换行符
d
,c
和p
实现剪切和粘贴
vim寄存器 Vim Registers
-
unnamed register
"
是拷贝或者剪切的内容不指定寄存器时默认存放的位置 -
named registers
a-z
,命名寄存器,你可以为接下来剪切或者复制的内容指定特定的a-z的字符的寄存器 -
yank register
0
存储了你上次复制的东西 -
cut registers
1-9
存储了你之前9次剪切操作的内容,包括d和c操作
举个例子 "ayas
会复制一个句子,然后存储在寄存器a
,也就是说语法是"{register}
后面跟你的复制剪切操作就会把东西存到指定的寄存器里,当你想粘贴的时候,"ap
,也是同样的
使用寄存器的大写字母,表示继续往那个寄存器添加复制或剪切的内容。
查看寄存器的内容
:reg
命令可以查看寄存器的呢日荣,你也可以查看指定寄存器的内容:reg {register}
08.命令行模式
命令行模式支持使用扩展命令(ex commands)的特性(:
开启)
举例一些常用的扩展命令
-
:colorscheme
查看vim当前使用的主题 -
edit
编辑文件,后面跟上文件路径就可以打开一个新的buffer来编辑文件
编辑文件扩展命令
:edit {relative-path-to-file}
执行这个命令后如果不存在文件那么就会新建一个再打开,这个命令的简写是:e
保存文件和关闭文件命令
-
:write
简写是:w
,用于保存文件 -
:quit
简写是:q
,用于关闭文件 -
:wall
简写是:wa
,用于保存所有文件 -
:qall
简写是:qa
,用于关闭所有文件 -
:wqall
:wqa
,用于保存并关闭所有文件 -
:qall!
:qa!
,强制退出所有文件不保存
如果你想强制执行忽略错误,那么就在前面或后面加上!
,比如!q
就是强制退出
你也可以组合两个命令,比如 wq
就是保存后关闭
同时删除多行
文本扩展命令的形式如下:
:[range]command[options]
其中,我们要执行删除操作的时候,命令的形式会变成如下:
:[range]d [register]
其中寄存器是存放我们剪切的内容的
举个例子,执行:10,12d a
,那么10-12行的内容就会被删除,剪切的内容存放在a寄存器,可以使用"ap
粘贴就还原了。
具体还有如下的使用方式
- 使用数字(e.g.
:10,12d
会删除行 10, 11 , 12) - 使用偏移值 (e.g.
:10,+2d
会删除行 10, 11 , 12) - 使用
.
表示当前行 (e.g.:.,+2d
会删除当前行和接下来的两行) - 使用
%
表示整个文件 (e.g.:%d
会删除整个文件) - 使用
0
表示整个文件的开始 (e.g.:0,+10d
会删除前十行) - 使用
$
表示文件的结尾 (e.g.:.,$d
会删除从当前行到文件结尾的内容) - 当使用visual mode选中文本后再输入
:
:'<,'>
表示你选中的范围, 执行:'<,'>d
就可以删除当前选中的内容
其他也有一些有用的命令包括 :yank
, :put
, :copy
and :move
等
重复执行命令
使用 @:
可以重复执行你上一个命令,之后你可以用@@
再次重复执行
替换文本
语法如下
:[range]s/{pattern}/{substitute}/{flags}
- range定义了执行替换的范围
- pattern 匹配替换内容的正则表达式
- substitute 是我们想要替换的文本
- flags 是用于配置替换文本的选项
举个例子
:s/led/gold
会替换当前行第一个匹配到的led为gold
如果你想要替换当前行所有的匹配,那么加一个g flag执行 :s/led/gold/g
如果你想替换整个文件的所有匹配,用%
表示整个文件的范围,执行:%s/led/gold/g
出了g以外,还有其他flag:
-
i
,忽略大小写 -
c
,每次替换需要确认
09.切换分屏(splits)和标签(tabs)
分屏(splits)
执行下面的命令可以实现分屏显示
-
:sp {relative-path-to-file}
水平分屏打开一个文件 -
:vsp {relative-path-to-file}
垂直分屏打开一个文件
除了命令的方式,你也可以使用快捷键
-
<CTRL-W> S
打开一个水平分屏的窗口 -
<CTRL-W> V
打开一个垂直分屏的窗口
在vscde的vim插件里面可以用 *CTRL-P
在分屏里打开新文件
使用 CTRL-W
+ hjkl
在分屏见移动
标签(tabs)
在分屏里面也可以打开标签
使用命令打开标签的方式是
-
:tabnew {file}
在新标签中打开文件 -
:tabn
(:tabnext
) 切换到下一个标签 -
:tabp
(:tabprevious
) 切换到前一个标签 -
:tabo
(:tabonly
) 关闭所有其他标签
10.vim-surround插件的使用
VSCodeVim自带了这个插件,这个插件带来了一个新操作符s,surroundings值得是包裹单词句子的符号,比如引号,花括号还有html标签(quotes, parenthesis, braces, tags, etc…)等
-
ds
删除surroundings -
cs
修改 surroundings -
ys
添加 surroundings
具体的语法如下
ds{count}{motion}
cs{count}{motion}
ys{count}{motion}
举个例子
-
ds'
删除包围的'
(ds{char}
) -
cs'"
替换包围的'
为"
(cs{old}{new}
) -
ysaptli>
包围一段话用<li>
标签 (ys{motion}{char}
)
也可以在v视觉模式下选中然后 S{desired character}
,就可以用你喜欢的符号包围了。
11.自定义按键映射
自定义映射可以把按键调整到你更舒服的位置
在vscode里面的编辑步骤如下
首先找到设置
- 打开命令面板
CMD-SHIFT-P
或者CTRL-SHIFT-P
- 输入preferences(或者在菜单栏也可以打开)
- 选择 Open User Settings Options
- 输入
vim
可以 编辑三种模式的自定义映射:
- Normal Mode Key Bindings Non Recursive for normal mode
- Visual Mode Key Bindings Non Recursive for visual mode
- Insert Mode Key Bindings Non Recursive for insert mode
举个例子,自定义normal模式的映射
{
"vim.insertModeKeyBindingsNonRecursive": [
{
"before": ["j", "k"],
"after": ["<ESC>"]
}
],
}
- before 就是你输入的命令
- after 就是你映射的值,当你输入before里的值后就会执行after中映射的键
在这个例子里,你可以在插入模式里把j和k当作ESC使用,不过这个设置就不是很实用,因为在插入模式里面j和k的输入需求也不少
关于创建自定义映射的指导方针
自定义映射比较灵活自由,但是不好的设置可能会给自己带来麻烦。
一般来说,遵循以下3个原则会比较好:
- 自定义映射用leader key打头来触发,一般是反斜杠
\
,这样就不会和已有的键位发生冲突了 - 如果你的工作流程中有经常使用的按键,那么映射替换vim默认的按键也是可以的。
- 尽量使用更容易记忆的映射,比如vim的 c表示change,d表示delete
自定义前导键(leader key)
你也可以把leader key改成比反斜杠更容易输入的键。
比如说你想把leader key改成空格键
{
"vim.leader": "<Space>",
}
下面比较好的映射的例子
让正常模式的上下移动更快
这个改动遵循了一个vim的一个理念,就是大写字母命令会比小写版本的更强。
所以大写的J会比小写的移动更快。
但是我们在这里覆盖了一个比较有用的vim默认按键J,这个按键的作用是合并当前行和下一行。但是这个键的使用频率其实不高
K键是用作关键词搜索,不过在VSCodeVim中还没有实现这个功能
{
"vim.normalModeKeyBindingsNonRecursive": [
{
"before": ["J"],
"after": ["5", "j"]
},
{
"before": ["K"],
"after": ["5", "k"]
},
]
}
为了保持合并行功能,我们把它加到leader key里
{
"vim.normalModeKeyBindingsNonRecursive": [
{
"before": ["<Leader>", "j"],
"after": ["J"]
},
]
}
在分屏间快速切换
{
"vim.normalModeKeyBindingsNonRecursive": [
{
"before": ["<C-h>"],
"after": ["<C-w>", "h"]
},
{
"before": ["<C-j>"],
"after": ["<C-w>", "j"]
},
{
"before": ["<C-k>"],
"after": ["<C-w>", "k"]
},
{
"before": ["<C-l>"],
"after": ["<C-w>", "l"]
}]
}
处理标签更方便
因为VSCodeVim中处理标签唯一的方式是命令模式输入命令,所以你可以用按键映射来代替这一点
commands键就是用来替换命令模式的扩展命令的
{
"vim.normalModeKeyBindingsNonRecursive": [
{
"before": ["<Leader>", "t", "t"],
"commands": [":tabnew"]
},
{
"before": ["<Leader>", "t", "n"],
"commands": [":tabnext"]
},
{
"before": ["<Leader>", "t", "p"],
"commands": [":tabprev"]
},
{
"before": ["<Leader>", "t", "o"],
"commands": [":tabo"]
}]
}
清除文本高亮
当你使用搜索命令的时候(/
和?
),匹配项会被高亮,为了清除高亮你需要扩展命令:noh
(no higlighting)
这个任务很常见,我们可以创建下面的按键映射
{
"vim.normalModeKeyBindingsNonRecursive": [
{
"before": ["<Leader>", "/"],
"commands": [":noh"]
}]
}
这里的助记法是,斜杠是被用来搜索的,所以前导键加斜杠就是和搜索最相关的撤销高亮
使用自定义映射影响vscode的action
下面的例子就是用 leader+w来触发保存文件
{
"vim.normalModeKeyBindingsNonRecursive": [
{
"before": ["leader", "w"],
"commands": [
"workbench.action.files.save",
]
}
}
找到设置Preferences: Open Keyboard Shortcuts,你就可以看到vscode里面命令的全名,然后你就可以替换你想替换的命令了。
下面是例子
CTRL-SHIFT-P
是打开命令面板,我们替换成前导键+p
CTRL-T
是Go To Symbol in Workspace,我们替换成前导键+t
{
"vim.normalModeKeyBindingsNonRecursive": [
{
"before": ["<Leader>", "p"],
"commands": [
"workbench.action.showCommands",
]
},
{
"before": ["<Leader>", "t"],
"commands": [
"workbench.action.gotoSymbol",
]
}
]
}
12.使用vim插件更快的移动
Vim-sneak 和vim-EasyMotion 是能够帮助你在vim里快速移动的插件
VSCodeVim 内置了这两个插件,不过需要你在设置里开启才能使用。
13.增强vscode的文件浏览器
<CTRL-W> h
切换到vscode的文件浏览器
-
k
和j
在文件浏览器的条目中上下移动 - Expand directories with
-
l
(right) 用于展开文件夹 -
h
(left) 用于折叠文件夹 - 使用
l
(right)打开光标下的文件
记住vscode的其他快捷键会很有用
-
Go To File with
CMD-P
in Mac (orCTRL-P
in Windows/Linux) -
Go To Symbol in File with
CMD-SHIFT-O
in Mac (orCTRL-SHIFT-O
in Windows/Linux) -
Go To Symbol in Workspace with with
CMD-T
in Mac (orCTRL-T
in Windows/Linux)
你在弹出的面板里面也可以用k和j或者tab选择,enter进入