Vim 快捷键
Vim 相关快捷键
背景 & 目标
个人使用 vim 已经很久了,但由于快捷键种类繁多,一直没有下决心好好学习整理一下,本篇文章会把这次学习的过程详细记录下来
目前在 IDE 和一些文档编辑器如 Obsidian 上都有对应的 vim 支持,因此完整学习后,对于文章的书写或者开发日常,泛用性比较好
本篇文章以 vscode 中 Learn Vim 插件作为参考资料,并整理核心内容为中文
基础移动
这四个键是 vim 中基础移动动作
- h 左
- j 下
- k 上
- l 右
使用 vim 动作快速移动
- f(字符) 移动到本行下一个字符出现的地方
- F(字符) 移动到本行上一个字符出现的地方
t 的移动和 f 基本一致,但是光标落的地方稍有不同
type t( ==> v v
const fireball = function(target){
type f( ==> ^ ^
当需要反复执行 f( 可以使用 ; 来重复上一个动作
type fdfdfd ==> v v v v
let damage = weapon.damage * d20();
let damage = weapon.damage * d20();
type fd;; ==> v v v v
水平移动
- 0 移动到行首
- ^ 移动到行首非空字符
- $ 移动到行尾
- g_ 移动到尾的非空字符
垂直移动
- } 移动到下一段
- { 同上,但向上移动
- CTRL-D 向下翻半页
- CTRL-U 向上翻半页
搜索
- /{内容} 向下搜索
- ?{内容} 向上搜索
在输入 / 或 ? 后, 接自己想要搜索的内容, 如 /cucumber 接着按下 ENTER 键,进入搜索模式
- n 跳转下一个匹配项
- N 跳转上一个匹配项
这里的内容不一定是一段准确的字符串,同样支持正则表达式
数字+动作
在 vim 中,数字可以理解为重复次数,比如 2w 就相当于按了两次 w 键,可以和其他动作一起组合, 这里我们以 w 和 f 为例
type wwww ==> v v v v v
word. are two words
word. are two words
type 3w2w ==> ^ ^
type f[;; ==> vv v
[[1], [1, 2], [3]]
[[1], [1, 2], [3]]
type 3f[ ==> ^
其他核心动作
- gg 跳转至文件第一个字符
- {行}gg 跳转至指定行
- G 跳转至文件最后一个字符
- % 在 ({[]}) 直接来回跳转
使用 Vim 操作符进行神奇的编辑
使用 运算符/operators 与 数量/counts 和 动作/motions 结合使用,来定义应用于文本范围的操作:
做什么 (删除, 修改...)
/
/ 做多少次(缺省时相当于count 为 1)
/ /
v v
{operator}{count}{motion}
^
/
/
在哪里执行这个动作
以删除为例,d2w 相当于执行 删除 2 次 w 的范围
start here
/
/
v
DO NOT ENTER!
# 执行后
ENTER!
撤销/重做
在尝试删除之前,需要先知道如何 撤销/重做
- u 撤销
- CTRL-R 重做
d
- d 删除字符
- dd 删除一行
- D 从光标删除到行尾
- dt; 从光标删除到 ; 字符
- d/hello 从光标删除直到 hello
c
- c 替换并插入,相当于 d + i
- cc 替换整行,相当于 dd + i
- C 从光标替换到行尾 d + $ + a
在如下例子中,我们希望将 const courteousSalute 修改为 const politeSalute,整体相当于少敲了一个键
start here
/
/
v
const courteousSalute
// d + i 时: wdtSipolite
// c 时: wctSpolite
. 操作
- . 重复上一次改动
这里要理解什么是 改动
- 使用 d{motion} 算改动
- 使用 i{xxx} 算改动
- 使用 c{xxx} 算改动
在如下例子中,我们希望将两个 courteous 替换为 polite
start here
/
/
v
const courteousSalute = "I courteously salute you good person.";
// d + i 时: wdtSipolite<ESC>fcdwipolitely<ESPACE><ESC>
// c 时: wctSpolite<ESC>fccwpolitely<ESPACE><ESC>
// c + . 时: wcfspolite<ESC>fc
又或者使用搜索配合 c + .
/co<ENTER>cfspolite<ESC>n.
找到下一个 co 开头的位置, 然后修改至s字符,接着输入 polite,使用 n 进入查找的下一个,最后使用 . 重复执行一次
文本对象
在 Vim 中,我们可以使用如下组合
{操作}{a|i}{文本对象}
其中 a|i 和 文本对象 的解释为
|- `a` 是 around
|- `i` 是 inner
/
/
/
{a|i}{文本对象}
/
/
| w - 单词
| s - 句子
| p - 段落
| " - 引号
以下面这个为例,执行后会删除双引号中所有内容,fR 指找到下一个 R 开头的位置,ci" 指替换双引号内部的所有内容
单单在这个粒子中,fR 可以省略,直接输入 ci" 效果也是一样的
you are here!
/
/
v
const poem = "Roses are red";
// fRci"
其他操作
- y yank,复制
- p put,粘贴
- g~ 字母大小写切换
- gu 字母小写
- 给U 字母大写
- > 增加缩进
- < 移除缩进
- = 格式化代码
- x 等于 dl 删除当前光标的字符
- X 等于 dh 删除光标前的字符
- s 等于 ch 或 dli,删除当前光标的字符并进入插入模式
- r 替换当前字符
- ~ 切换当前字符大小写
插入文字
目前为止,我们所有的介绍都在 Normal Mode 中,接下来会介绍 Insert Mode
- i 在光标前插入
- a 在光标后插入
- I 在行首插入
- A 在行尾插入
you are here
/
/
v
const status = "I'm in awe"
^ ^ ^ ^
| | | |
I i a A
- o 在当前行的下方增加一行,并进入 Insert Mode
- O 在当前行的上方增加一行,并进入 Insert Mode
you are here
/
/
O -> v
const status = "I'm in awe"
o ->
选择文字
这个部分是 Visual Mode
- v 逐字模式
- V 逐行模式
- CTRL-V 逐块模式
在 Visual Mode 下,我们提交操作符时,与 Normal Mode 的顺序是反过来的
进入 Visual Mode
/
/ 做那个操作
/ /
--------- /
{v|V|C-V}{count}{motion}{operator}
---------------
/
/
执行哪个动作
以下发内容为例,我们希望在 Visual Mode 中删除 It is,此时可以执行 vtbd
,这段操作可以理解为,进入视觉模式,选择直到 b 字符的前方(此时 It is 已经被选中),最后执行删除
start here
/
/
v
It is better to go forward without a goal
同样的如果我们希望删除多行,仅保留最后的 123,此时可以执行 Vjjd
,可以理解为,进入逐行模式,选择三行后,执行删除操作
start here
/
/
v
It is better to go forward without a goal
It is better to go forward without a goal
It is better to go forward without a goal
123
如果希望对多行进行追加,比如下方的例子,在行首追加 aaa 在行尾追加 bbb,此时可以执行 CTRL-V2jIaaa<Esc>
接着执行 CTRL-V2j$Abbb
这里指令变多了,稍微复杂些,第一段是进入逐块模式,向下选择两行,然后在行首插入 aaa, 接着 Esc 退出
第二段是,再次进入逐块模式,向下选择两行,跳转到行尾,接着在行尾插入 bbb
start here
/
/
v
123
456666
789
结果
aaa123bbb
aaa456666bbb
aaa789bbb
- 感谢你赐予我前进的力量