使用 evil 之前,得了解 vi/vim 的一些基本常识。
命令模式下的游标是一个方块,它的当前位置是指块的最左边。下图中当前游标所在位置是两个 e 的中间。
末行模式
(last line mode/指令列命令模式)末行模式在命令模式下输入 :
进入。由于此时光标移动到最后一行,因此得名。
键入所有内容被认为是文本输入。
在命令模式下输入以下命令将进入插入模式。没有进入插入模式的会注明。
命令 | 结果 |
---|---|
i | 在当前游标位置之前 插入文本 |
I | 在当前行的开始处 插入文本(非空字符的行首) |
a | 在当前游标位置之后 插入文本 |
A | 在当前行的结尾处 插入文本 |
o | 在当前行下面新建一行 |
O | 在当前行的上面新建一行 |
s | 删除游标后 的一个字符 |
S | 删除游标所在的行(删除当前行) |
r | 替换(覆盖)当前游标位置之后的一个字符,然后进入命令模式 |
R | 替换(覆盖)当前游标位置及后面的若干文本(进入替换模式 ) |
cc | 删除当前行内容 |
cw | 删除游标所在位置到单词末尾 |
ch | 删除游标位置之前的一个字符 |
cl | 删除游标位置之后的一个字符 |
cj | 删除当前行和下一行 |
ck | 删除当前行和上一行 |
提醒,想在下图行末加个空格时,命令模式下移到最后一个字符,再键入 a
(原来没做这个总结时,不知道有向后插入的命令,我都是先键入 i,再 C-e 到最后的,边摁边想这也太麻烦了。现在再想真的太羞耻了
这个一开始不必掌握,而且能在命令模式下解决的就尽量不进入可视模式解决(使用 C-v 真的很方便)
在命令模式下输入以下命令进入可视模式
命令 | 结果 |
---|---|
v | 逐个字符选择文本 |
V | 逐行选择文本 |
C-v | 按照块的方式选择文本(忽视行,可以理解为面向列) |
gv | 重选上次的高亮区域 |
高亮选区由两个端点确定:一个固定的端点,一个活动的端点。
字符 o
可以在不同的的端点之间来回的切换。
当我们选中了一片高亮区域后,可以使用如下命令对高亮区域进行操作:
命令 | 效果 |
---|---|
d | 剪切选中文本 |
c | 修改选中文本 |
r | 替换选中文本 |
I | 在选中文本前插入 |
A | 在选中文本后插入 |
gu | 选中区域转为小写 |
gU | 选中区域转为大写 |
g~ | 大小写互调 |
> | 向右缩进一个单位 |
< | 向左缩进一个单位 |
比如我有如下这个文本,我想把它快速转化成列表,就可以用到 C-v 命令
在第四行 C-v 进入可视模式后,使用 k 向上移动到第一行。我们再键入 c
删除选中列,再输入 .
,最后键入 Esc 退出。就可以看到结果了。
任何模式下使用 ESC
将退回到命令模式,实在不行摁两下。
因而,在使用命令进行操作的时候,首先要搞清楚的就是要采用哪种操作单位,也就是说,是要操作一个字符,一个句子,一个段落,还是要操作一行,一屏、一页。单位不同,命令也就不同。只要单位选用得当,命令自然就恰当,操作也自然迅速高效;否则,只能是费时费力。这也可以说是最能体现 Vi/Vim 优越于其它编辑器的地方之一,也是 Vi/Vim 有人爱有人恨的地方之一。
在操作单位确定之后,才是操作次数,即确定命令重复执行的次数。要正确高效的运用 Vi/Vim 的各种操作,一定要把握这一原则:先定单位再定量
。操作对象的范围计算公式为:操作范围 = 操作次数 * 操作单位。比如:5h 命令左移 5 个字符,8w 命令右移 8 个单词。
操作单位 | 命令 | 效果 |
---|---|---|
字符 | h l |
左移一个字符 右移一个字符 |
单词 | w/W b/B e/E |
移到下一单词的开头 移到上一单词的开头 移到光标所在单词末尾 |
行 | j k 0 ^ g_ $ :n nG n+ n- |
下移一行 上移一行 移到当前行开头 移到当前行的首个非空字符 移到当前行末尾 移到当前行末尾 移动到第 n 行 移动到第 n 行 从光标当前行下移 n 行 从光标当前行上移 n 行 |
句子 | ) ( |
移动到当前句子 的末尾 移动到当前句子的开头 |
段落 | } { |
移动当前段落的末尾(下一个有空行的地方) 移到当前段落的开头(上一个有空行的地方) |
屏 | H M L |
游标移动到屏幕的第一行 游标移动到屏幕的中间一行 游标移动到屏幕的最后一行 |
页 | C-f C-b C-u C-d zz |
向前滚动一页 向后滚动一页 向前滚动半页 向后滚动半页 当前行居中 |
文件 | G gg :0 :$ |
移动到文件末尾 移动到文件开头 移动到文件第一行 移动到文件最后一行 |
说明:
以下命令都是在命令模式下进行,并且执行之后还在命令模式
操作单位 | 命令 | 效果 |
---|---|---|
字符 | yl/vy(visual yank) | 复制当前字符 |
单词 | yiw | 复制当前单词 |
行 | yy | 复制当前行 |
这一系列的 yank2 操作可以大致总结如下3
操作单位 | 命令 | 效果 |
---|---|---|
字符 | x X |
剪切游标位置后一字符(相当于 DELETE) 剪切游标位置前一字符(相当于 BACKESPACE) |
单词 | dw (更多参考上面的 yank) | 剪切当前游标位置至下一个单词前的字符 |
行 | dd D d0 d$ |
剪切游标所在的行 从游标位置开始剪切到行尾 从游标位置剪切至行首 从游标位置剪切至行尾 |
用 v 进入可视模式后,选中文本之后可以按 y 进行复制,如果按 d 就表示剪切。
命令 | 说明 |
---|---|
p | 将复制的单词粘到游标后面 复制后的行粘到游标所在行下面 |
P | 将复制的单词粘贴到游标前面 复制后的行粘到游标所在行上面 |
删除后改变当前模式的命令可以参考 插入模式
小节
操作单位 | 命令 | 效果 |
---|---|---|
字符 | x X |
剪切游标位置后一字符(相当于 DELETE) 剪切游标位置前一字符(相当于 BACKESPACE) |
单词 | dw | 剪切当前游标位置至下一个单词前的字符 |
行 | dd D d0 d$ J |
剪切游标所在的行 从游标位置开始剪切到行尾 从游标位置剪切至行首 从游标位置剪切至行尾 合并游标所在行及下一行为一行 |
功能 | 命令 | 效果 |
---|---|---|
重复操作 | . |
重复上次操作 |
交换相邻字符或行 | xp ddp |
交换光标位置的字符和它右边的字符 交换光标位置的行和它的下一行 |
大小写转换 | ~ guw gUw guu gUU g~~ |
将光标下的字母大小写反向转换 将光标所在的单词变为小写 将光标所在的单词变为大写 光标所在的行所有字符变为小写 光标所在的行所有字符变为大写 光标所在的行所有字符大小写反向转换 |
下面的 前 是指 h 的方向
命令 | 说明 |
---|---|
/ | 从当前位置向后搜索 |
? | 从当前位置向前搜索 |
n | 搜索下一个 |
N | 反向搜索下一个 |
* | 在文件中向后搜索当前光标所在的单词 |
# | 在文件中向前搜索当前光标所在的单词 |
q/
或 q?
命令 | 说明 |
---|---|
:s/被换单词/新单词/ | 替换光标所在行的第一个被换单词 |
:s/被换单词/新单词/g | 替换光标所在行的全部被换单词 |
:x,ys/被换单词/新单词/ | 在x和y行之间替换每一行的第一个被换单词 |
:x,ys/被换单词/新单词/g | 在x和y行之间替换全部被换单词 |
:%s/被换单词/新单词/ 替换每一行的第一个被换单词
:%s/被换单词/新单词/g 替换每一行中所有被换单词
如果我们想要替换的字符串中包含 / 怎么办呢?
此时我们可以使用分隔符 # 来代替 分隔符 /
:s#vivian/#sky/#
替换当前行第一个 vivian/ 为 sky/
:%s+/oradata/apras/+/user01/apras1+
(使用 + 来 替换 / )
将 /oradata/apras/ 替换成 /user01/apras1/
为了防止替换错了,我们可以在替换前加个提醒
:1,$s/misspelled/spelled correctly/gc
:1,$s/misspelled/spelled correctly/c
c 确认后再替换
使用 m
创建,`(ESC 下面的那个键)访问。
比如 m a
创建一个叫做 a 的标签,然后使用 ` a 到达该行。
当然这个只能是在同一个文件内,并且关闭文件再打开后得重新创建。
命令模式下
u
撤销上一次编辑U
当前行
恢复到原始状态(撤销对本行的所有操作)C-r
反反撤销在命令模式输入命令之前,可以先输入一个数字,表示想要执行接下来输入的命令的次数。
命令 | 说明 |
---|---|
:q | 如果修改文件,vi询问用户是否保存文件,不保存则退出vi,否则不能退出。 |
:w | 保存当前文件。如果用户对当前文件没有写权限,不能保存文件并收到一条错误消息。 |
:wq | 保存并退出,与:wq相同 |
:q! :w! :wq! |
!表示直接执行命令,不提供保护措施,不考虑命令是否执行成功。 |
ZZ | 保存并退出,与:wq相同 |
ZQ | 无条件退出,与:q!相同 |
:x | 保存并退出 |
:w filename | 将编辑内容另存到文件 filename 中。启动vi时未指定文件名,须用此命令保存编辑内容到文件中 |
:m,nw filename | 将 m 行到 n 行部分的内容保存到文件 filename 中 |
:m,nw >> filename | 将 m 行到 n 行的内容添加到文件 filename 的末尾 |
:e! | 打开文件的上一次成功保存的版本。 |
Vim 技巧之四大模式_可视模式
linux:vi 替换命令
Linux—vi/vim 复制剪切粘贴以及常用命令小结
这篇文章我感觉有些因小失大了,我自己常用的命令翻来覆去也就 j k dd c-v ~ 那么几个。反而这段时间无意中尝试到了几个更加有用的,原来压根不知道的快捷键:
C-c p
(evilnc-comment-or-uncomment-paragraphs):快速注释某一段代码
原来我都是 C-@
然后 j k 选中要注释掉的区域,运行 M-x comment/uncomment region
的,无意间发现这个命令心情真是久久难以平复。
C-c l
(evilnc-quick-comment-or-uncomment-to-the-line):Comment/uncomment to line number by last digit(s) whose value is UNIT (这个不太理解)
如果写 lisp 程序的话,如下几个处理括号的命令你一定不能错过,来自
ci(
删除这对括号里的所有内容(不包括这对括号)va(
选中这对括号在内的所有内容(包括这对括号)%
在这对括号之间移动如果你对在 evil 的 insert mode 移动感到不满的话,或许 Traversing text in Insert mode 这篇帖子和 Evil Mode best practice 会对你有所启发。
至于如果找到更多有用键位,我还不太清楚。大概是 evil-collection 吧。
技巧:快速提高 Vi/Vim 使用效率的原则与途径
Vi/Vim 中很多命令是针对不同的操作单位而设的,不同的命令对应不同的操作单位。 ↩︎
为什么在 vi 的世界, 拷贝都使用 yank 这个词, 而不是 copy? ↩︎
https://vi.stackexchange.com/questions/5806/how-can-i-yank-copy-the-single-character-on-which-the-cursor-rests ↩︎