Vim 使用
Vim,模态 (式) 编辑器。
由于目前主要在 VS Code,Android Studio 等图形化界面的编辑器中使用 Vim,所以这里主要记录在编辑器使用的 Vim 操作,诸如 Vim 的排版,多窗口编辑,环境设置,配色等操作,就不再涉及。
References
日常使用
模式:
- 基本模式:命令模式,插入模式,末行模式 (ex,或者理解成扩展命令模式)
- 其它模式:替换模式,可视模式 ...
只有编辑文档时才处于插入模式,其余时候主要都处于命令模式。
默认是命令模式,其它模式都是从命令模式进入的。
- 进入插入模式:i I a A o O s S (s / S 替换插入)
- 进入末行模式::
- 进入替换模式:R
- 进入可视模式:ctrl + v, v, V
- 回到命令模式:ESC
命令模式:
- 进入其它模式
- 光标移动:hjkl, 0, ^, $, gg, G, w, e, b
- 查找:/ # g g#
- 编辑少量文本:x, r, dd, dw, yy, yw, p, u, ctrl + r
- dgg:从光标所在行删除到第一行
- dG:从光标所在行删除到最后一行
- D:等于
d$
,从光标所在处删除到该行最后
末行模式:
- 保存退出:w, q, wq, q!, wq!
查找替换:
:[rang]s/pattern/string/[cegi] # s 表示 search
读入或写文件
:r test.txt :1,8 w /root/test2.txt
设置 vim 工作环境 (~/.vimrc)
:set nu :set nonu :set ic :set noic # 忽略大小写
定位到行
:15
保存、退出:
:w
: 保存:q
: 未修改的情况下直接退出:q!
: 在修改了文件的情况下强制不保存退出:wq
: 保存并退出
跳转:
gg
: 跳转至文首[n]gg
: 跳转至某一行,[n]
表示某一行,比如13gg
表示跳转至第 13 行G
: 跳转到文末^
: 跳转至行首$
: 跳转至行末%
: 跳转至与当前{} [] ()
匹配的另一半ctrl + [f/b/d/u/e/y]
: 翻一页,翻半页,翻一行H/M/L
: 移动当前屏幕的 header, middle, last
编辑:编辑指令大部分都可以在前面加上数字,以及在末尾加上 ^ / $ / G / w
来表示范围。
选择。命令是
v
。v
: 进入可视模式,移动光标选定内容V
: 选中当前行所有内容ctrl + v
: 进行块/列选择
复制。命令是
y
(yank)。y
: 在使用了v
进入可视模式选中某一块后复制选中的内容到缓冲区。(无法快速地复制单个字符,必须用复制单个字符:v
+y
配合使用才行,vy
或者yl
)yy / [n]yy
: 复制一行或 n 行,如5yy
表示复制从光标开始的 5 行yw / [n]yw
: 复制一个或多个 wordy^ / y$ / yG
: 复制至行首,行末,或文末
剪切。命令是
d
(delete)。与复制使用方法相同,可搭配数字及^ / $ / G
使用。d
: 剪切选定块内容到缓冲区dd / [n]dd
dw / [n]dw
d^ / d$ / dG
x / [n]x / X / [n]X
: 剪切当前光标处或光标前面的单个或 n 字符
删除并进入插入模式。命令是
c
(change)。相当于执行d
加上i
。cw
: 删除光标到单词结尾部分的文本后,进入插入模式ciw
: 删除光标所在的单词后,进入插入模式cc
: 删除整行后,进入插入模式
粘贴。命令是
p
(put)。p
: 粘贴于光标后P
: 粘贴于光标前
替换。命令是
r
。r
: 单个字符替换R
: 连续替换
高效编辑。
[d/y/v]i["/(/[/{]
:i
表示 inner,这个指令表示 删除/复制/选择 在""
()
[]
{}
等中间的内容,i
前后的指令自由组合,比如di"
表示删除""
之间的内容,yi(
表示复制()
之间的内容,vi[
选择[]
之间的内容[d/y/v]t[x]
:t
表示 till,这个指令表示 删除/复制/选择 从当前光标开始往后,直到遇到的第一个[x]
字符之间的所有字符[y/v/d]iw
: 复制/选择/删除光标所在的单词[y/v/d]aw
: 复制/选择/删除光标所在的单词,同时包括单词尾部的空格[y/v/d]ap
: 复制/选择/删除光标所在的整个段落,包括尾部的空行
查找:
/string
: 查找目标内容*
,#
: 查找与当前光标所在字符串完全匹配的内容g*
,g#
: 查找与当前光标所在字符串部分匹配的内容n
,N
: 定位查找到的内容,在查找到的多个目标间跳转
查找替换:
:[range]s/pattern/string/[c,e,g,i]
: 通过正则查找并替换- range : 查找范围,可以是某一行,或某些行,或全部,如,
1
,1,7
,1,$
,%
- c : confirm
- e : ignore error
- g : global line, 替换所有结果
- i : incasesentive
- range : 查找范围,可以是某一行,或某些行,或全部,如,
撤消与重做:
u
: 撤消操作ctrl + r
: 重做
其它操作:
.
: 重复上次操作:! [comand]
: 执行 shell 命令,如:! pwd
查看当前文档所在路径:r [filename]
: 读取某个文件内容到当前文档:r! [command]
: 执行 shell 命令,并把输出结果写入当前文档
寄存器
先温习一篇以前写的文章:开启 Redhat 上的 Vim 的系统剪切板功能
vim 有多个所谓的寄存器,其实就是小块的单独的内存 buffer,来存放一些临时的文本。
用 :reg
命令可以查看这些寄存器及其中存放的内容。主要的寄存器有 「0-9,-,/,"」,「"」称为无名寄存器,是默认使用的寄存器。在没有指定寄存器的情况下,最近一次的操作影响的文本会放到「"」寄存器中。
使用方法:
- 用
"
再加上这些寄存器的名字来选中这个寄存器,然后配合y / p
使用。比如选中一段文本,按下"1y
表示将选中的文本保存到了 1 号寄存器中,"1p
表示从 1 号寄存器选择文本进行替换。 - 用 Ctrl+R 加寄存器名来选中这个寄存器的内容并粘贴,比如
ciw<C-r>0
,表示选中一段文字,然后用 0 号寄存器中的内容粘贴。
长久以来,我都有一个烦恼,很常见的一种场景,我用 y
复制了一些内容,想用这些内容去替换多处地方,但只要用 p
替换一次以后,替换的内容就会覆盖原来复制的内容,使我不得不需要再次 y
复制一遍。
解决办法:
使用黑洞寄存器:
_
。具体的解释:Vim's black hole register它有点像 shell 中的 null 输出,输出到 null,意味着什么都不输出。这里,写到
_
和从_
读取,实际什么都不会发生,因此,它也阻止了影响"
的默认操作。因此,我们选中一段文本后,可以用
"_dp
或"_dP
来粘贴 (你试过就会发现,后者效果更好),"_dP
等价于"_d""P
,它表示,先删掉选中的内容,并将删掉的内容放到_
寄存器,因此实际删掉的内容哪都没放,消失了,然后再从"
寄存器读取内容,粘贴到此处。然后,你可以为
"_dP
映射一些快捷操作。Replace a word with yanked text
提供了多种方法,都是通过操作寄存器来实现。
最简单的方法:用
"0p
来替代 p。解释:y
d
p
x
等这些操作影响的文本会放到未命名的"
寄存器,但y
影响的文本同时也会放到命名的0
寄存器,所以之后的p
操作会影响"
,但却不会影响0
寄存器。
Vim 正则查找替换
一些技巧
多行相同位置快速插入相同内容。
按下
ctrl + v
进行列选择模式,选中多行,按shift + i
在第一行插入所需内容,然后按两次ESC
退出此模式,就会同时插入。