vi/vim 总结 | emacs evil 使用教程

使用 evil 之前,得了解 vi/vim 的一些基本常识。
命令模式下的游标是一个方块,它的当前位置是指块的最左边。下图中当前游标所在位置是两个 e 的中间。
在这里插入图片描述

文章目录

    • 模式
      • 命令模式(执行管理任务)
        • 末行模式
      • 插入模式(向文件中输入文本)
      • 可视模式
      • 模式间的切换
    • 移动[^1]
    • 复制、粘贴和删除
      • 复制
      • 剪切
      • 粘贴
      • 删除
    • 其他命令
    • 搜索和替换
      • 搜索
        • 显示搜索历史
      • 替换
      • 标签
    • 撤销
    • 重复命令
    • 退出
    • 总结
    • 参考
    • 补充
    • TODO

模式

命令模式(执行管理任务)

  • 所输入的内容被解释成命令,功能包括
    1. 保存文件、执行命令
    2. 移动游标、剪切、粘贴多行或多个单词、查找、替换
  • 所输入的任何字符被解释成命令
  • 命令模式包含末行模式(last line mode/指令列命令模式)

末行模式

末行模式在命令模式下输入 : 进入。由于此时光标移动到最后一行,因此得名。

插入模式(向文件中输入文本)

键入所有内容被认为是文本输入。

在命令模式下输入以下命令将进入插入模式。没有进入插入模式的会注明。

命令 结果
i 在当前游标位置之前插入文本
I 在当前行的开始处插入文本(非空字符的行首)
a 在当前游标位置之后插入文本
A 在当前行的结尾处插入文本
o 在当前行下面新建一行
O 在当前行的上面新建一行
s 删除游标后的一个字符
S 删除游标所在的行(删除当前行)
r 替换(覆盖)当前游标位置之后的一个字符,然后进入命令模式
R 替换(覆盖)当前游标位置及后面的若干文本(进入替换模式
cc 删除当前行内容
cw 删除游标所在位置到单词末尾
ch 删除游标位置之前的一个字符
cl 删除游标位置之后的一个字符
cj 删除当前行和下一行
ck 删除当前行和上一行

提醒,想在下图行末加个空格时,命令模式下移到最后一个字符,再键入 a (原来没做这个总结时,不知道有向后插入的命令,我都是先键入 i,再 C-e 到最后的,边摁边想这也太麻烦了。现在再想真的太羞耻了

当然也可以直接 A
在这里插入图片描述

可视模式

这个一开始不必掌握,而且能在命令模式下解决的就尽量不进入可视模式解决(使用 C-v 真的很方便)
在命令模式下输入以下命令进入可视模式

命令 结果
v 逐个字符选择文本
V 逐行选择文本
C-v 按照块的方式选择文本(忽视行,可以理解为面向列)
gv 重选上次的高亮区域

高亮选区由两个端点确定:一个固定的端点,一个活动的端点。
字符 o 可以在不同的的端点之间来回的切换。

其中块选中的理解可以参考 cmd 下选中文本块。
vi/vim 总结 | emacs evil 使用教程_第1张图片

当我们选中了一片高亮区域后,可以使用如下命令对高亮区域进行操作:

命令 效果
d 剪切选中文本
c 修改选中文本
r 替换选中文本
I 在选中文本前插入
A 在选中文本后插入
gu 选中区域转为小写
gU 选中区域转为大写
g~ 大小写互调
> 向右缩进一个单位
< 向左缩进一个单位

比如我有如下这个文本,我想把它快速转化成列表,就可以用到 C-v 命令
在这里插入图片描述
在第四行 C-v 进入可视模式后,使用 k 向上移动到第一行。我们再键入 c 删除选中列,再输入 .,最后键入 Esc 退出。就可以看到结果了。
在这里插入图片描述 在这里插入图片描述

模式间的切换

任何模式下使用 ESC 将退回到命令模式,实在不行摁两下。

移动1

因而,在使用命令进行操作的时候,首先要搞清楚的就是要采用哪种操作单位,也就是说,是要操作一个字符,一个句子,一个段落,还是要操作一行,一屏、一页。单位不同,命令也就不同。只要单位选用得当,命令自然就恰当,操作也自然迅速高效;否则,只能是费时费力。这也可以说是最能体现 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
:$
移动到文件末尾
移动到文件开头
移动到文件第一行
移动到文件最后一行

说明:

  1. W、B、E 命令操作的单词是以空白字符(空格、Tab)分隔的字串
    比如字符串 “str1-str2 str3-str4”
    对 W、B、E 命令来说是两个单词
    而对 w、b、e 命令来说则是四个单词。
  2. 0 为数字零(zero)
  3. 句子指以 ”.”、”?” 和 ”!” 结尾,后面至少有一个空格或换行符的字符串

复制、粘贴和删除

以下命令都是在命令模式下进行,并且执行之后还在命令模式

复制

操作单位 命令 效果
字符 yl/vy(visual yank) 复制当前字符
单词 yiw 复制当前单词
yy 复制当前行

这一系列的 yank2 操作可以大致总结如下3

  • yl 复制单个字符(好像只支持 ASCII,具体讨论可以看给出的链接)
  • yiw 复制整个单词
  • yaw 复制整个单词(带空格)
  • yw 复制游标所在单词的后半部分
  • yy 复制整行
  • 3yy 复制含当前行在内的下三行
  • yap 复制整个自然段(包括换行符)

剪切

操作单位 命令 效果
字符 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 到达该行。

当然这个只能是在同一个文件内,并且关闭文件再打开后得重新创建。

  • 如果标记的太多了,记不住标记了哪些的话,可以尝试使用 package evil-visual-mark-mode
  • 如果想保存设置的标签,可以尝试使用 desktop.el 保存,参考 How to Persist Evil Markers?

撤销

命令模式下

  1. u 撤销上一次编辑
  2. U 当前行恢复到原始状态(撤销对本行的所有操作)
  3. C-r 反反撤销

重复命令

在命令模式输入命令之前,可以先输入一个数字,表示想要执行接下来输入的命令的次数。

  1. 10j 下移10行
  2. 10l 右移10个字符
  3. 6h 左移6个字符
  4. 3dd 删除三行

退出

命令 说明
: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! 打开文件的上一次成功保存的版本。

总结

下图来自 vi/vim 基本使用方法,侵删。
vi/vim 总结 | emacs evil 使用教程_第2张图片

参考

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 吧。

TODO

  • spacemacs: evil mode 窗口管理
  • linux vi 常用命令
  • vi cgn

  1. 技巧:快速提高 Vi/Vim 使用效率的原则与途径
    Vi/Vim 中很多命令是针对不同的操作单位而设的,不同的命令对应不同的操作单位。 ↩︎

  2. 为什么在 vi 的世界, 拷贝都使用 yank 这个词, 而不是 copy? ↩︎

  3. https://vi.stackexchange.com/questions/5806/how-can-i-yank-copy-the-single-character-on-which-the-cursor-rests ↩︎

你可能感兴趣的:(emacs)