使用 Vim 进行的编辑的核心使用逻辑为执行,重复,回退。即先执行一次编辑动作,再在别的地方重复同一操作,如果不小心出错了就回退操作。可以理解为每次的编辑动作都被 Vim 自动保存为了一小段宏,再移动到另一个地方执行同一段宏,如果发现宏录错了,就快速回退,再重复这一过程,直到编辑完成。
所以,掌握 Vim 的第一步就是理解哪些是可以重复的操作以及如何回退。
可重复操作和对应的回退操作
Vim 中有很多操作是同一操作的两个方向,这类操作一般使用大小写来区分方向,比如 f{char}
向前到指定字符,F{char}
向后前进到指定字符。
一些编辑操作也有特别的撤销的操作,如下表所示:
目的 | 操作 | 重复 | 回退 |
---|---|---|---|
做出一个修改 | {edit} | . | u |
在行内查找下一个制定字符 | f{char} /t{char} | ; | , |
在行内查找上一个制定字符 | F{char} /T{char} | ; | , |
在文档中查找下一处匹配项 | /pattern<CR> | n | N |
在文档中查找上一处匹配项 | ?pattern<CR> | n | N |
执行替换 | :s/target/replacement | & | u |
执行一系列修改 | qx{changes}q | @x | u |
Undo 命令
Normal 模式下使用 u
可以撤销一次编辑动作。
注意
命令撤销的不是上一次的输入,而是一次编辑动作。
一次编辑动作可以被以下三种情况规定:
- 在 Normal Mode 中使用编辑动作, 比如
.
,<C-a>
,s/target/replace
; - 进入 Insert Mode 到退出 Insert Mode 中间的所有操作,除了包含 3 中所述的情况;
- 在 Insert Mode 中使用光标移动的操作,会立即将已有的输入保存为一次编辑动作块,包括
<UP>
,<Down>
,<Left>
,<Right>
等,可以理解为我们回到了 Normal Mode 进行了光标的移动。
Tips
使用 Redo 命令来撤销 Undo,快捷键为
<Ctrl + r>
。
快速增减数字
<c-a>
会正向跳到第一个数字上,并将数字 +1, <c-x>
会将数字 -1, 也可手动制定增减的值,如 180<c-a>
。但有两点需要注意:
- 进制问题,类似
007
这种数字,会默认识别为 8 进制数 - 日期增减问题,如果日期格式为
2020-10-07
,当试图对月日进行增减时,会被识别为负数,其增减方向和期望的方向恰好相反
以 root 权限保存文件
:w !sudo tee % > /dev/null
%
符号会自动展开为当前文件路径,所以这条命令工作的原理就是通过 Vim :write
命令将文件内容通过标准输出写入到有 root 权限的 sudo tee <filepath>
命令,这样就能成功保存了。
注意
这个技巧只能用于 Vim,而不适用于 Neovim,Neovim 中不支持
!
命令中交互输入密码,所以只能使用插件或者将tee
命令设置为不使用密码也能使用sudo
,再使用命令:w sudo -n tee %
调用。 See Also: Neovim FAQ, Neovim Issue, Another Issue
输入特殊字符
Vim/Neovim中支持使用ASCII或Unicode编码输入键盘上无法找到的字符,在输入模式下使用 Ctrl + v
快捷键就能进入编码输入的模式,这模式下有三种不同输入。
- 直接输入 3 位数字,如
<Ctrl + v>065
会以十进制编码输入字符,这里会输入大写字母 “A” - 输入
u
之后可以输入 4 位数字的 Unicode 字符,如<Ctrl + v>u00bf
会输入字符 ”¿” - 输入非数字键则会直接输入键入的字符,比如
<Ctrl + v><TAB>
会输入一个 tab 符,并且不会因为在配置中设置了 tab 转空格而自动的被转化为空格
如果已经在文本中存在的字符,如果想知道其字符编码,可以在 Normal Mode 将光标移动到对应字符使用快捷键 ga
,屏幕下方就会显示出其对应的编码。
另外也可以通过二合字母来插入特殊字符,使用方式是在插入模式下使用 <Ctrl + k>{char1}{char2}
的快捷键,比如 <Ctrl + k><<
可以输入左书名号 ”«“,<Ctrl + k>12
可以输入 “½”,二合字母比起使用数字更容易记忆使用,使用 :h digraphs
了解更多信息,或者使用 :h digraph-table
查询所有可以输入的字符表。
按键 | 用途 |
---|---|
<Ctrl+v>{123} | 以十进制字符编码输入字符 |
<Ctrl+v>u{1234} | 以十六进制编码输入字符 |
<Ctrl+v>{nondigital} | 按原义插入非数字字符 |
<Ctrl+k>{char1}{char2} | 插入二合字母表示的字符 |