背景介绍
Vim 是从 vi 发展出来的一个文本编辑器。和 Emacs 并列成为类 Unix 系统用户最喜欢的编辑器。
Vim
提供了一系列很强大的编辑文本的操作方式,可以使用纯键盘完成编辑文本操作。再搭配许多插件可以配置成一个 IDE。但是 Vim
有着一个比较陡峭的学习曲线,并且不是开箱即用的。
如果没有特定的开发环境限制,可以使用
更漂亮易上手的编辑器 (Visual Studio Code)
+ 更流畅的编辑体验 (Vim)
来提高编码效率,各取所长。
如今市面上几乎所有的 IDE 和编辑器都提供有 Vim 的相关插件。例如我所体验过的
- Sublime Text - Vintageous、Six
- Visual Studio - VsVim
- Visual Studio Code - Vim
本文的所有操作都基于 Visual Studio Code
+ Vim 插件
演示。(虽然我更喜欢 Sublime Text…)
先来点甜头 例子
举例几个实际例子,可以想像之前是怎么操作的
字母顺序写反了
ab
写成了ba
删除 HTML 元素中的内容 / 删除双引号之间的内容
…
安装
- 打开 VS Code 的扩展商店
- 搜索 Vim
- 点击安装
Vim 模式
模式意味着你的键盘会根据你所使用的模式获得不同的功能。也就是说,根据你所使用的模式,在键盘上键入一个按键会产生不同结果。
就像主键盘区上方的数字健可以直接按数字键 1
输入 1 也可以通过 shift + 1
输入 !
,这样一个健位上就具有了不同的功能。
常用模式
normal
模式—— 默认模式,可以通过键盘移动光标、删除字符、复制、粘贴等。insert
模式—— 正常的输入模式visual
模式—— 选中文本,类似通过鼠标选择文本
Vim
插件安装完成后,默认是 normal
模式,normal
模式下不能输入文本。按 i
键切换到 insert
模式。
如何判断编辑器当前所处模式
- 通过光标样式判断
- VS Code 底部 status 栏会显示当前模式
安装 Vim 后的副作用
Ctrl + c
不再是复制,而是切换到normal
模式Ctrl + v
不再是粘贴,而是进入visual
模式Ctrl + f
不再是搜索,而是向前滚动一页
如果不希望 vim 改变这些健
1 | // 禁用 vim 使用 Ctrl |
模式切换
insert 切换 normal
Esc
Ctrl + c
Ctrl + [
normal 切换 insert
i(insert)
在当前字符前进入insert
模式a(append)
在当前字符后进入insert
模式o(open)
在当前行下开启新的一行进入insert
模式I
在行首进入insert
模式A
在行尾进入insert
模式O
在当前行上开启新的一行进入insert
模式gi
在最后一次insert
的地方进入insert
模式
normal 模式
normal
模式下 hjkl
可以像键盘上的方向键一样上下左右移动光标而不是输入。hjkl
适用于短距离移动。
1 | ↑ |
数字搭配命令使用,快乐加倍。{count}{command}
快速移动
单词之间移动
Vim 中的一个单词是
- 字母和数字组成 (w、e、b、ge)
- 其他非空白字符序列 (W、E、B、GE)
1 | hello vim world |
w
移动至下个单词开头e(end)
移动至下个单词结尾 endb(back)
移动至上个单词开头 backge
移动至上个单词末尾gE
以上命令还可大写,大小写的区别在于单词的范围不同。
- 小写只由字母组成的单词
- 大写是以非空白符分割的单词
{n}w/e/b/ge/gE
跳转第几个单词
行间搜索移动
f{character}
移至行中下一个出现的字符F{character}
移至行中上一个出现的字符t{character}
移至行中下一个出现的字符前T{character}
移至行中上一个出现的字符后
重复查找上次的搜索命令,避免再次输入。
;
下一个,
上一个{n};
第 n 个
水平移动
0
移至行首^
移至行首的非空白字符$
移至行尾g_
移至行尾的非空白字符
垂直移动
(
上个句子)
下个句子{
上个段落}
下个段落%
移动光标到括号的另一半包括 () [] {}
段落和句子都是以空行来分割。
页面移动
gg
第一行G
最后一行{n}gg/{n}G
移动到第 n 行H(head)
移动到屏幕顶部M(middle)
移动到屏幕中间L(lower)
移动到屏幕低部zz
当前行放到屏幕中间
语义移动
gd
跳转到定义gf
跳转到导入的源文件gh
相当于将鼠标悬停在光标所在的位置。
文本对象
文本对象可以理解为范围,hjkl 移动是以一个字符为单位移动。
使用文本对象可以更大范围的移动操作
w
单词s
句子p
段落(
被 { 包围的块{
被 ( 包围的块'
被 ‘ 包围的块"
被 “ 包围的块t
被 html 标签包围的块
快速删除
d (delete)
dd
删除当前行{n}dd
删除 n 行df{character}
从当前字符向后删除到目标字符dF{character}
从当前字符向前删除到目标字符dt{character}
从当前字符向后删除到目标字符前dT{character}
从当前字符向前删除到目标字符后x = dl
删除一个字符X = dh
删除前一个字符{n}x
删除 n 个字符
配合水平移动删除
d^
从当前字符删除到行首d0
从当前字符删除到行首d$ = D
从当前字符删除到行尾dg_
从当前字符删除到行尾
配合文本对象删除
dw
从光标向后删除单词d{n}w
从光标向后删除 n 个单词d{n}aw
从当前单词向后删除 n 个单词db
从光标向前删除单词diw
删除单词daw
删除单词 + 单词后的空格dit
删除 html 标签包裹的内容dat
删除 html 标签 + 包裹的内容di(
删除 () 包裹的内容da(
删除 () + 包裹的内容di{
删除 {} 包裹的内容da{
删除 {} + 包裹的内容di"
删除 “” 包裹的内容da"
删除 “” + 包裹的内容di'
删除 ‘’ 包裹的内容da'
删除 ‘’ + 包裹的内容
i - inner
a - around
快速修改
r (replace)
r
替一个字符
c (change)
- c 的命令基本可以把上面快速删除中的 d 都替换成 c。唯一区别是 c 最后会进入到 insert 模式。
s
s = ch
删除光标下的字符并进入 insert 模式{n}s
删除 n 个字符并进入 insert 模式S
删除当前行并进入 insert 模式~
切换单个字符大小写g~
当前行所有字符字符切换大小写
Command 模式
VS Code 只支持部分 Vim 的 command 命令。
运行命令以 : 开头
:edit {relative-path-to-file} = :e {path}
打开或创建文件 建议创建文件使用,打开文件使用 Ctrl + p
相对路径是相对的当前打开文件。
保存和关闭文件
:write = :w
保存文件:quit = :q
关闭文件:wq
保存并关闭
如果文件未更改或为只读则将失败。同样,:quit将关闭文件,但如果文件未保存的更改将失败。
后面加 ! 强制执行
:wall = :wa
保存所有文件:qall = :qa
关闭所有文件:wqall = :wqa
保存和关闭所有文件:qall! = :qa!
关闭所有文件不保存
删除/修改/复制 d c y:[range]command[options]
:[range]delete [register]
删除多行到寄存器·@:
重复上一个ex命令·@@
重复一次后,您可以继续重复此操作
command 模式范围
:{start},{end} 起始行到结束行 1,2d
:{start},{offset} 起始行和偏移范围 1,+2d
.
当前行 .,+2d%
整个文件 %d0
文件开头 0,10d$
文件结尾 10,$d:'<,'>
command 替换
:[range]s/{pattern}/{substitute}/{flags}
range
范围s/
当前行%s
整个文件pattern
搜索模式 支持正则substitute
要替换的文本flags
选项-g
全局-i
不区分大小写-c
确认每一次替换
:s/led/gold
当前行第一个 led => gold:s/led/gold/g
全局
command 模式搜索
搜索以 / 或 ? 开头
/{pattern}
向后搜索 pattern 是个正则表达式?{pattern}
向前搜索/ = n
下一个匹配项 重复搜索?= N
上一个匹配项gn
选中下一个匹配项gN
选中上一个匹配项dgn
删除下一个匹配项dgN
删除上一个匹配项
Visual 模式
Visual 模式相当于用鼠标选择文本,但是在 Vim 中你可以用键盘来完成。
v
逐字符选择文本V
逐行选择文本Ctrl + v
使用矩形块选择文本o
切换选择方向d
删除
insert 模式
ctrl h
删除上一个字符ctrl w
删除上一个单词ctrl u
删除当前行ctrl a
移动到行首ctrl e
移动到行尾ctrl b
向前移动ctrl f
向后移动
终端中也可以使用
复制粘贴
在 Vim 中
y
复制Y
复制当前行p
在当前字符后粘贴p
在当前字符前粘贴yyp
重复当前行ddp
交换上下行xp
交换字符yl
复制当前字符
配合文本对象使用
yaw
复制一个单词yas
复制一个单词yi(
yip
yap
寄存器
寄存器是一个特殊的剪贴板,你可以选择在其中一次保存多个内容。就像有很多盒子,你可以自由的选择将复制、删除的内容放在哪个盒子中,需要的时候可以自由拿出来(粘贴)。Vim 的删除、复制与粘贴命令均需要使用 Vim 寄存器。
通过在命令前加 "寄存器名
前缀的方式可指定寄存器,否则 Vim 将缺省使用无名寄存器。
若想在 Vim 和操作系统外部程序间共享复制内容,则必须使用 Vim 系统剪贴板。
""
无名寄存器 默认使用「无名寄存器」""p === p
"[a-z]
有名寄存器,以 26 个英文字母命名,使用小写字母引用有名寄存器会覆盖该寄存器的原有内容,而用大写字母引用则会将新内容 追加 到该寄存器的原有内容之后。
特殊寄存器
"0
复制寄存器"+
系统剪贴板"%
当前文件名".
上次插入的文本"[1-9]
存储最后 9 次删除或更改命令的内容:reg {name}
查看寄存器内容
Vim 宏 (marcro)
可以看作是一些系列命令的集合,可以录制一系列操作然后用于「回放」
在 normal 模式下,按下 q{register}
后开始进入宏录制状态,VS Code
编辑器左下角会显示 Recording
q{register}
开始录制 再按q
结束录制 录制保存在寄存器中@a
回放保存在a
寄存器中的操作@@
重复上次回放{n}@{register}
Example
1 | rusty sword,obsidian dagger,silver poniard,broadsword 转换成 |
插件
VS Code 中内置了许多有用的 Vim 插件。
vim-suround
默认启用
ds
删除cs
更改ys
添加
Example
ds'
删除周围的'
ds(
ds[
ds{
cs"'
把"
改成'
vim-sneak
默认禁用,setting.json 中 vim.sneak: true
开启。
s{char}{char}
类似 f 命令,不过现在 s 可以搜索两个字符更容易定位。S{char}{char}
向上搜索
Input Method
在插入模式输入中文再进入到 normal 模式后,需要切换回英文输入法。Input Method
避免了这种问题。
使用方法参考 如何解决VSCode Vim中文输入法切换问题?
vim-easymotion
默认禁用,setting.json 中 vim.easymotion: true
开启。
easymotion 试图通过消除记数来简化 Vim 中运动的使用。当使用 easymotion 时,它会使用叠加层(在相关文字上方)标识。输入该标识跳转过去。easymotion 适用于四处移动。
“vim.leader”: “space” 可以自行映射 leader 键盘。
<leader><leader>w
标记后面所有单词的开头<leader><leader>b
<leader><leader>bdw
<leader><leader>e
<leader><leader>ge
<leader><leader>j
<leader><leader>k
<leader><leader>f{char}
<leader><leader>F{char}
<leader><leader>t{char}
<leader><leader>T{char}
<leader><leader>s{char}
Setting
1 | // VS Code setting.json 中设置 |
Tips
Ctrl + Shift + p
打开命令面板输入Toggle Vim Mode
快速切换 Vim 开关.
重复最后一次修改>>
向右缩进<<
向左缩进u
撤销*
跳转到下一个相同单词#
跳转到上一个相同单词
Chrome 插件 Vimium
Vimium 提供了在浏览器上使用 Vim 功能
j
向下移动网页k
向上移动网页gg
移动到网页顶部G
移动到网页底部J
上一个标签页K
下一个标签页
…
让键盘适应工具
可以选择 ESC 和 Ctrl 比较容易触碰的键盘,或者把 CapsLock 映射成 Ctrl。
⌨️
- HHKB
- Poker2
我使用 Vim 几个阶段
从第一次接触到现在也有 3-4 年左右了吧。
- 最开始在学校的时候看网上的一个视频课程,里面用的
Sublime + Vim
插件。算是我的Vim
启蒙。导致我到现在一直对Sublime Text
情有独钟。当时基本只会hjkl dd gg p
一些简单的操作。 - 学了文本对象,
f{char} t{char} d/c{文本对象}
等 稍微熟练了些。 - 开始了解
VS Code
与Vim
的搭配。不得不说VS Cod
中的Vim
比Sublime
中的Vim
功能强大了不少。
有时可能同时会有同事在我电脑上操作,会很不习惯。这种时候 toggle vim mode
就很好使了。
End
先挑选对自己有用的用到日常开发中,不要一口一个大胖子。Vim
实在是太强大了,写这篇文章时,也有很多是现学(抄)的,熟能生巧。VS Code
和 Vim
的结合会有一些功能重合或冲突的地方根据自己习惯取舍,最适合自己的就是最好的。
参考链接 🔗
https://vimjc.com/
https://github.com/VSCodeVim
https://coding.imooc.com/learn/list/50.html
https://www.zhihu.com/question/303850876
https://www.barbarianmeetscoding.com/blog/2019/02/08/boost-your-coding-fu-with-vscode-and-vim