LV01-VIM-02-VIM基础知识.md

本文主要是VIM编辑器的一些基础知识和操作的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。

点击查看使用工具及版本
Windows windows11
Ubuntu Ubuntu16.04的64位版本
VMware® Workstation 16 Pro 16.2.3 build-19376536
点击查看本文参考资料
点击查看相关文件下载
--- ---

一、 vim 基础

1. vim 的几种模式

一般来说是有三种模式,可是似乎有些也会说是四种模式,自己用了这么久,感觉四种模式的话可能更合适些。即普通模式,插入模式,命令模式。

模式 说明
普通模式 normal 当我们打开一个文件时,最初进入的就是普通模式,即 normal 模式。在此模式下,可使用方向键(上、下、左、右键)或 k、j、h、i 移动光标的位置,还可以对文件内容进行复制、粘贴、替换、删除等操作。其他的模式都需要经过该模式才能进行切换。
插入模式 insert 插入模式,也就是 insert 模式。在该模式下,我么可以对文件进行编辑,使用键盘输入字符,就像在 Windows 下使用记事本编辑文件差不多。
可视模式 visual 可视模式,即 visual 模式。该模式只要是用于选中目标文本,需要注意的是,当选中文本并做完相应操作(例如选中文件并按 p 键将其复制到剪贴板中)后, vim 会自动从可视化模式转换为普通模式。
命令模式 有的也会叫底行模式,因为该模式出现在 vim 编辑器最下边的一行,进入该模式时就可以开始执行命令。可以进行文件的保存、退出、查找、替换、列出行号等操作。

2. vim 几种模式切换命令

模式切换命令如下图所示。

image-20220304101056470
点击查看详细操作说明
操作(进入) 命令 功能
插入模式 A、a (Append)进入(insert)插入模式
A: 光标移动到行尾,并开始插入键盘输入的字符
a:从当前光标之后并跳过一个字符的位置开始插入键盘输入的字符
I、i (Insert)进入(insert)插入模式
I:光标移动到行首,并开始插入键盘键入字符
i:从当前光标所在的位置开始插入键盘输入的字符
O、o (Open)进入(insert)插入模式,并插入一新行
O:向当前光标的上一行插入新行
o:向当前光标的下一行插入新行
普通模式 ESC 进入或者从其他模式返回(normal)普通模式
命令模式 :Command 进入命令模式,在vim中执行外部命令Command,按回车键可以返回vim继续工作
可视模式 v 又称字符可视化模式,此模式下目标文本的选择是以字符为单位的,也就是说,该模式下要一个字符一个字符的选中要操作的文本
V 又称行可视化模式,此模式化目标文本的选择是以行为单位的,也就是说,该模式化可以一行一行的选中要操作的文本
CTRL+v 又称块可视化模式,该模式下可以选中文本中的一个矩形区域作为目标文本,以按下 Ctrl+v 位置作为矩形的一角,光标移动的终点位置作为它的对角。

【注意】以上模式切换,都需要在 normal 模式下进行切换。

3. vim 常用命令

3.1 保存与退出

命令 功能
:q (Quit)退出没有修改的文件(若文件被修改了而没有保存,则此命令无效)
:q! (Insert)强制退出,且不保存修改过的部分
:w (Write)保存文件,但不退出
:x (Exit)保存文件并退出
:w File 另存为File给出的文件名,不退出
:r File (Read)读入File指定的文件内容插入到光标位置

3.2 拷贝与粘贴

命令 功能
[n]x (Expurgate)删除从光标位置开始的连续n个字符(并复制到编辑缓冲区)
[n]dd (Delete)删除从光标位置开始的连续n行(并复制到编辑缓冲区)
[n]yy (Yank)复制从光标位置开始的连续n行到编辑缓冲区
p或P (Put)从编辑缓冲区复制文本到当前光标位置(即粘贴)
u (Undo)取消上一次操作(即恢复功能)

【注意】这里使用 yy 命令复制的整行是带有自动换行符的,要想不换行可以这样复制 0y$ 这样复制的行不带有换行符。

3.3 光标移动

详细可查看 vim 在线中文文档:VIM: motion

3.3.1 基本移动

命令 功能
h 方向键,向左移动光标一个字符的位置,相当于键“←”
j (Delete)方向键,向下移动光标到下一行的位置,相当于键“↓”
k 方向键,向上移动光标到上一行的位置,相当于键“↑”
l 方向键,向右移动光标一个字符的位置,相当于键“→”
:N 移动光标到第N行(N待定)
1G 移动光标到文件的第1行
gg 移动光标到文件的第1行
G 移动光标到文件的最后1行

3.3.2 位置标记

详细的也可以查看 vim 在线中文文档:VIM: motion - mark-motions

  • 标记位置
m{a-zA-Z}把位置标记 {a-zA-Z} 设在当前光标位置 (不移动光标,这不是动作命令)。
m' 或 m 设置前次上下文标记。以后可以用 "''" 或者 " " 跳转到这个位置 (不移动光标,这不是动作命令)。

【说明】

a - z 小写位置标记,在每个文件内有效。 A - Z 大写位置标记,也叫做文件标记,在文件间都有效。

  • 跳到标记位置
` (反引号)光标放在指定的位置, exclusive 开动作。
' (单引号)光标放在指定位置所在行的首个非空字符上, linewise 行动作。

例如,在正常模式中,按下 ma ,然后移动光标到其他位置,再按下 ‘a ,光标将跳回刚才的标记点。

3.4 查找

在普通模式下,输入 /string <Enter> ,即可查找字符串 string ,输入完毕后按 n 则继续向后查找,按 N 则向上继续查找。要注意的是 string 可以是正则表达式:

参数 含义
^ 表示开始的行
$ 表示结束的行
. (点)匹配一个非换行符的字符

3.5 替换

3.5.1 使用格式

1
2
" 替换命令格式
:[range]s/source_string/target_string/[option]
  • 格式说明
[range] 表示要替换的范围
source_string 表示源字符串(要被替换的字符串)
target_string 表示目标字符串(要替换成的字符串)
[option] 无:只替换第一个
g:全局替换
c:是否确认替换
p:替换结果逐行显示

3.5.2 使用实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
:s/L/l/        " 替换当前行第一个 L 为 l
:s/L/l/g " 替换当前行所有 L 为 l

:n,$s/L/l/ " 替换第 n 行开始到最后一行中每一行的第一个 L 为 l
:n,$s/L/l/g " 替换第 n 行开始到最后一行中每一行所有 L 为 l

:.,$s/L/l/ " 替换当前行开始到最后一行中每一行的第一个 L 为 l
:.,$s/L/l/g " 替换当前行开始到最后一行中每一行所有 L 为 l

:%s/L/l/ " 替换每一行的第一个 L 为 l
:%s/L/l/g " 替换每一行中所有 L 为 l

:2,5s/L/l/ " 替换第2行~第5行的第一个 L 为 l
:2,5s/L/l/g " 替换第2行~第5行中所有 L 为 l

3.6 数字增减

1
2
3
4
CTRL + a       " 数字自动增加 1
n + ctrl + a " 数字自动增加 n
CTRL + x " 数字自动减少 1
n + ctrl + x " 数字自动减少 n

4. vim 标签页 tab

什么是标签页?这个问题是我看到这个标题后最先想到的,我想去百度一下,但是似乎好像没什么意义,直接来张图就理解了。

image-20220304123643297

我们经常浏览网页查阅资料,每次都会打开很多的页面,它们在浏览器中就如上图所示,这就叫标签页 tab 。vim 中也有标签页,用于多文件编辑,每一个标签页也可以包含多个缓冲区或窗口(什么是缓冲区和窗口?我们后边再说)

4.1 打开与关闭 tab

  • 打开文件时启动标签页
1
vim -p 1.txt 2.md 3.c

我们可以使用 -p 选项来打开多个文件,每个文件都将占用一个标签页。打开后,效果如下图所示:

image-20220304124319480
  • 在 vim 中打开标签页
1
2
:tabe[dit] {file}   " 在当前标签页后新建一个名为 file 的标签页(新建文件)
:tabf[ind] {file} " 在当前标签页后,打开一个名字为 file 的标签页(并非新建文件)

【说明】 [ ] 中的内容可以省略。

  • 关闭标签页
1
2
3
4
5
:tabc[lose]         " 关闭当前标签页,但只剩一个标签页时,它将无法工作
:tabc[lose] {n} " 关闭指定标签页,n 为标签
:tabo[nly] " 关闭所有标签页,仅保留当前标签页
:wq " 保存并关闭当前标签页
:q " 关闭当前标签页

【说明】 [ ] 中的内容可以省略。

4.2 标签页跳转

1
2
3
4
:tabn        " 跳转到下一个标签页
:tabp " 跳转到上一个标签页
:tabfirst " 跳转到第一个标签页
:tablast " 跳转到最后一个标签页

在 normal 模式下,还可以使用命令进行跳转。

1
2
3
gt            " 跳转到下一个标签页
gT " 跳转到上一个标签页
{n}gt " 跳转到指定标签页, n 表示标签页编号(n从1开始)

4.3 移动标签页

1
2
3
4
:tabs         " 列出所有标签页,当前标签页会有 > 标识
:tabm 0 " 移动当前标签页到第一个位置
:tabm " 移动当前标签页到最后
:tabm {n} " 移动当前标签页到第 n + 1 的位置(n从1开始)

5. vim 窗口 window

上边我们说了标签页的相关操作,接下来看看窗口 window 。 vim 支持多窗口编辑的功能,但是并不是一下子启动好几个 vim ,而是在一个 vim 中进行分屏,就像 VScode 向左向右拆分窗口那种操作(当然,用过 VScode 的话)。

5.1 打开与关闭 window

  • 打开文件时直接启动多窗口
1
2
3
vim -O 1.txt 2.md     " 大写 O ,表示实现纵向(垂直)分屏
vim -o 1.txt 2.md " 小写 o ,表示实现横向(水平)分屏
vim -o3 1.txt 2.md " 将分配3个相同的窗口,有1个是闲置的

这样打开后有虽然多个窗口,但光标是位于第一个文件的。

  • 在 VIm 中打开新窗口
1
2
3
4
:sp[lit] {file}     " 水平分屏 file 为新窗口想要显示的文件的名称
:new {file} " 水平分屏 file 为新窗口想要显示的文件的名称
:sv[iew] {file} " 水平分屏,以只读方式打开,file 为新窗口想要显示的文件的名称
:vs[plit] {file} " 垂直分屏,file 为新窗口想要显示的文件的名称

【说明】 [ ] 中的内容可以省略,另外要注意光标的位置不会发生改变,还会处于原来的窗口中。

另外在 normal 模式下,也有默认的快捷键进行分屏,但是貌似有点反人类,反正我是这样认为的,不过问题不大,后边我们可以进行按键重映射,来任意修改,以符合我们自己的操作习惯:

1
2
3
4
Ctrl+w s        " 水平分割当前窗口
Ctrl+w v " 垂直分割当前窗口
Ctrl+w n " 打开一个新窗口(空文件)
Ctrl+w T " 当前窗口移动到新标签页
  • 关闭窗口
1
:clo[se]        " 关闭当前窗口

normal 模式下,也可以用以下快捷键关闭窗口:

1
2
Ctrl+w n        " 打开一个新窗口(空文件)
Ctrl+w o " 关闭出当前窗口之外的所有窗口

5.2 切换窗口

上边我们会发现,虽然可以分出很多窗口来查看文件,但是却并不会移动光标,怎么办呢?可以用以下命令:

1
2
3
4
5
6
7
Ctrl+w h        " 切换到左边窗口 h 也可以是 ←
Ctrl+w j " 切换到下边窗口 j 也可以是 ↓
Ctrl+w k " 切换到上边窗口 k 也可以是 ↑
Ctrl+w l " 切换到右边窗口 l 也可以是 →
Ctrl+w w " 遍历切换窗口
Ctrl+w t " 换到最上方的窗口
Ctrl+w b " 切换到最下方的窗口

5.3 移动窗口

分屏后还可以把当前窗口向任何方向移动,只需要将上述快捷键中的 hjkl 大写即可:

1
2
3
4
Ctrl+w H        " 向左移动当前窗口
Ctrl+w J " 向下移动当前窗口
Ctrl+w K " 向上移动当前窗口
Ctrl+w L " 向右移动当前窗口

5.4 调整窗口大小

1
2
3
4
5
Ctrl+w =        " 使得所有窗口 (几乎) 等宽、等高
:res+n " 当前窗口增加 n 行的高度
:res-n " 当前窗口减小 n 行的高度
:vertical res+n " 当前窗口增加 n 列的宽度
:vertical res-n " 当前窗口减小 n 列的宽度

6. vim 缓冲区 Buffer

vim 打开一个文件时,从磁盘中读取文件到内存中, vim 的一些操作其实是在操作缓冲区,编辑的也是存在于缓冲区的文件,当使用 vim 对缓冲区进行操作时,磁盘文件内容与内存映像不再一致,也就是说这个时候,原来的文件没有改变,改变的是缓冲区的文件。当使用 vim 的保存命令时,才将缓冲区写回给文件,这个时候文件内容才会发生改变。

这个缓冲区( Buffer )其实是一块内存区域,用于存储着正在编辑的文件。一个窗口内只有一个 Buffer 是处于可见状态,所以比较难以观察。

再进行以下学习之前,需要先知道一个命令,就是列出当前 vim 窗口中所有的缓冲区( Buffer ):

1
2
:ls
:buffers

上边两个命令就是列出所有缓冲区,当前窗口可见的缓冲区前边会有一个 %a 的标识,上一次编辑的的缓冲区前边会有一个 # 的标识, buffer 已修改未保存也未写入文件,但是强制跳转到其他 buffer 时,前边会有一个 h 标识。

6.1 打开缓冲区

  • 打开文件时打开缓冲区

vim 支持同时打开多个文件,不带任何参数时,打开多个文件便可以把它们都放入缓冲区( Buffer )。

1
vim 1.txt 2.md 3.c 

这样可以一次打开三个文件,并将每个文件放入单独的缓冲区(共 3 个缓冲区)。但是窗口中却始终只有一个缓冲区可见,处于激活状态,其他的都存在,只不过是隐藏了。

  • 在 vim 中打开缓冲区
1
:e[dit] {file}   " 打开文件到缓冲区, file 为文件名称

此时,窗口显示的是新打开的文件缓冲区。

6.2 保存和关闭缓冲区

  • 保存缓冲区

当缓冲区的文件被修改时,应该先将缓冲区的内容写入文件,否则在一般情况下,都会报错。

1
2
:wa!          " 保存所有 buffer
:w " 将当前 buffer 写入文件
  • 关闭缓冲区
1
2
:qa!          " 关闭所有buffer,且不保存
:bd[elete]{n} " 移除第 n 个缓冲区

如果 buffer 未保存 :bd 命令会报错,如果强制删除可以 :bd! 。

6.3 缓冲区跳转

在命令行模式下,我们可以使用以下命令进行跳转:

1
2
3
4
5
:bn[ext]            " 跳转到下一个缓冲区
:bp[revious] " 跳转到上一个缓冲区
:bfirst " 跳转到第一个缓冲区
:blast " 跳转到最后一个缓冲区
:b{n, expression} " 跳转到指定缓冲区,n 表示缓冲区编号,expression表示缓冲区名称的模糊匹配。

在 normal 模式下也可以这样进行跳转:

1
Ctrl+^   " 不需要按 Shift,实现切换当前缓冲区和上一个缓冲区

若是 buffer 修改了,但是未保存,也未写入时,可以用 ! 强制执行。

例如:

1
2
3
:b2                 " 跳转到第二个缓冲区
:b!2 " 强制跳转到第二个缓冲区
:bn[ext]! " 强制跳转到下一个缓冲区

6.4 分屏显示缓冲区

1
2
:sb {n}             " 水平分屏并打开编号为 n 的Buffer
:vertical sb {n} " 垂直分屏并打开编号为 n 的Buffer

例如:

1
2
:sb 3               " 水平分屏并打开编号为 3 的Buffer
:vertical sb 3 " 垂直分屏并打开编号为 3 的Buffer

7. vim 配置文件

在 vim 启动过程中,首先将查找配置文件并执行其中的命令。初始化文件一般有 vimrc 、 gvimrc 和 exrc 三种,包括了系统配置文件和用户配置文件。那么我怎么知道配置文件在哪里呢?可以这样来进行查询

1
vim --version

然后我们就会看到这样一部分内容了。

image-20220304152405725

通图中中的显示的数据,我们可以知道, $VIM 为 /usr/share/vim ,而 $HOME 我们应该都清楚,就是自己的家目录 ~ ,所以系统配置文件为 /usr/share/vim/vimrc ,用户配置文件在 ~/.vimrc 。修改这两个文件都可以对 vim 进行配置,但是安全起见,我们一般还是只配置用户配置文件。当然,一般情况下,我们很可能会找不到用户配置文件,可能它根本就不存在这个时候,就在 ~/ 下手动创建一个 .vimrc 文件即可。

还有一种方式可以查看自己的用户配置文件位置。按下边操作即可:

1
2
3
4
5
# 1.启动vim
vim
# 2.进入命令模式,打印MYVIMRC
:echo $MYVIMRC
# 3.观察窗口底部,应该会打印出用户配置文件的位置

注意, vim 用户配置文件比系统配置文件的优先级高, vim 启动时,会优先读取 vim 用户配置文件(位于家目录中的),所以我们只需要修改用户配置文件即可(并不建议直接修改系统配置文件)。

二、 vim 寄存器

1. vim 寄存器分类

常见文本编辑器都会提供剪切板来支持复制粘贴, vim 也不例外。 不同的是 vim 提供了 10 类共 48 个寄存器,提供极为强大的寄存功能。可以在 vim 中通过 :help registers 来查看寄存器的帮助内容。

1
2
3
4
5
6
7
8
9
10
11
There are ten types of registers: *registers* *{register}* *E354*
1. The unnamed register ""
2. 10 numbered registers "0 to "9
3. The small delete register "-
4. 26 named registers "a to "z or "A to "Z
5. Three read-only registers ":, "., "%
6. Alternate buffer register "#
7. The expression register "=
8. The selection and drop registers "*, "+ and "~
9. The black hole register "_
10. Last search pattern register "/
  • 匿名寄存器 "
  • 数字寄存器 0 to 9
  • 行内删除寄存器 -
  • 26 个命名寄存器 a to z 或者 A to Z
  • 3个只读寄存器 :, .%
  • Buffer 交替文件寄存器 #
  • 表达式寄存器 =
  • 选择和拖放寄存器 *, +~
  • 黑洞寄存器 _
  • 搜索模式寄存器 /

2. vim 寄存器使用

  • 访问寄存器的值

vim 中每一个 register 都可以通过添加双引号的方式来访问,”a 来访问 a 寄存器。

1
2
3
4
5
6
7
8
# normal模式下
"{register_name} # 该模式的访问要配合一定的命令才能显示结果

# command模式下
<C-r>+"寄存器名称 # 输入<C-r>后VIM会自动打出寄存器引用符号 "

# insert模式下
<C-r>+寄存器名称 #无需输入寄存器引用符号 "

例如:

1
"%p      " normal模式下,粘贴当前文件名及相对路径
  • 查看寄存器的值

在命令模式中,可以通过以下命令来查看每个寄存器当前的值。

1
2
:reg[ister]                " 查看所有寄存器的值
:reg[ister] register_name " 查看特定寄存器的值

【说明】[]中的内容可以省略,查看指定寄存器值得时候,似乎有没有"都可以。

3. vim 寄存器详解

3.1 匿名寄存器 “

当我们使用 d , c , s , x 等会删除字符的命令时,被删除字符会进入匿名寄存器 “ 暂存。虽然通过命令删除了字符,但是我们依然可以通过 “” 来访问刚才删掉的字符。另外, y 命令复制的字符也会出现在该寄存器中。

任意打开一个文件,进入 normal 模式,使用 yy 命令复制一行,然后执行以下命令:

1
:reg "

会有以下结果出现,这是因为我使用 yy 命令复制了某一行内容: file1 ,查看 “ 寄存器的值就会出现下图结果。

image-20220304162451660

3.2 数字寄存器

这是一组寄存器,从 0-9 共包含了 10 个寄存器,其中:

(1)0 中保存着拷贝的最新的字符串,也就是我们最近一次拷贝的字符串。

(2)1 到 9 保存着删除掉的字符串,最近一次删除的字符串会被放到 1 中,上一次删除的字符串会被保存在 2 中,依次类推,总共会保存 9 条删除历史记录,第 9 条记录是时间最早的,第 1 条是最新的。比如使用了三次 dd 命令,那么这三行文本被分别存放在寄存器 1 , 2 , 3 中,我们可以通过命令 “1P , “2P , “3P 将这些文本再粘贴回来。

但是我们在实际操作的时候会发现,删除的单个字符并不会出现在 1-9 这几个寄存器中,只有整行或者多于一行被删除时,这些寄存器才会更新。

总结一下,寄存器 0 不断被复制的文本所覆盖,总是保存着最新复制的内容,但是若是指定了其他的寄存器,那么该寄存器也不会被写入;在删除文本时,如果指定了寄存器或者文本小于一行,那么包含了最近删除内容的寄存器 1 将不会被覆盖,其他 8 个寄存器也不会发生变化。

3.3 行内删除寄存器 -

上边我们发现,数字寄存器会存储一整行或者多于一整行的删除内容,那么 vim 对于少于一整行的删除内容总不能置之不理把,那岂不是厚此薄彼。

这个时候, - 寄存器就派上了用场,当删除文本少于一行时,内容将被放入 - 寄存器,除非指定了其它寄存器。起作用的删除操作符包括 s , c , d , x 等。例如

1
2
3
dw    " 删除一个词
d3l " 删除3个字符
cb " 向前更改一个词

3.4命名寄存器

这也是一组寄存器,由 a 到 z 这 26 个小写英文字母或者大写英文字母组成的 26 个寄存器。这些寄存器只有当我们指定时才会被使用。当我们在录制宏时,所有键盘操作会以字符串的形式存到寄存器中。 例如录制一个宏存到 “a 寄存器中,内容为更改当前行 qidaink ,改为 fanhua 字符串,在 normal 模式中按以下按键:

1
qaccfanhua <esc>q

命令解释: qa 表示开始录制宏到 a 寄存器, cc 表示修改当前行,会清空当前行并进入插入模式, fanhua 表示在插入模式下在当前行键入这个字符串, <esc> 表示退出插入模式,回到普通模式, q 表示结束录制。然后我们再来查看 a 寄存器的值:

1
:reg a
image-20220304170816974

【注意】当文本被放入以小写字母命名的寄存器(例如 a )时,该寄存器原有的内容将被覆盖;而使用以大写字母命名的寄存器(例如 A )时,将会把文本追加到原有内容之后。

3.5 只读寄存器

只读寄存器共有三个,分别是 . 、 % 和 : 三个,它们的内容是由 vim 决定的,我们只能读取,不能修改。

.最近一次在插入模式插入的文本
%当前文件名,不是全路径,也不是纯文件名,而是从当前 Vim 的工作目录到该文件的路径。
:最近一次命令模式下键入的命令。

我们可以通过以下命令查看这三个寄存器的值:

1
:reg % : .

3.6 Buffer 交替文件寄存器 #

交替文件( alternate file )是指 Buffer 中的上一个文件,可通过 Ctrl+^ 来切换交替文件与当前文件(上一个缓冲区和当前缓冲区)。交替文件寄存器 # 存储着当前 vim 窗口( window )的交替文件。不知道为什么,使用 :reg # 并未能显示寄存器内容,但是这样做就可以显示:

1
:reg % #       " 查看当前文件和交替文件名
image-20220304180922423

3.7 表达式寄存器 =

表达式寄存器 = 主要用于计算 vim 脚本的返回值,并插入到文本中。

(1)在普通模式下,当我们键入 “= (包含 “ )后光标会移动到命令行, vim 底部会显示以 = 开始的提示行,然后我们就可以在其中输入表达式并按回车键确认。随后使用命令 p ,可以将表达式的结果粘贴到按下 “= 时光标所在位置。

(2)在插入模式下,按下 CTRL + r + = 三个按键,也可以进入 = 提示行,此时键入表达式,然后按下回车,就可以直接将计算结果插入到当前光标处。也就是说,不用离开插入模式,也无需额外执行粘贴命令,也可以完成表达式计算。

这在调试 vim 脚本时非常有用,比如调用一个函数看它是否有正确的返回值,它也可以用来执行外部命令,比如 进入 = 提示行之后输入 system(‘ls’) <enter> 来显示 ls 的结果。

3.8 选择和拖放寄存器

选择和拖放寄存器包括 * , + , 和 ~ ,这三个寄存器的行为是和 GUI 相关的。

(1)在 Mac 和 Windows 下, “* 和 “+ ,都用于访问系统剪切板。例如 “*yy 即可复制当前行到剪切板。 其他程序中复制的内容也会被存储到这两个寄存器中。

(2)在 Linux 下, “+ 用于访问系统剪切板,而 “* 包含选中的文本。例如:使用 “+y 命令,可以将当前选中的文文本复制到系统剪切板中。而 “+p 命令,则可以粘贴系统剪切板中的内容。通过剪切板寄存器,能够在不同的 vim 编辑器或者是其他应用程序之间,进行文本交换。

在 X11 系统中(绝大多数带有桌面环境的 Linux 发行版)中

  • “* 指 X11 中的 PRIMARY 选区,即鼠标选中区域。在桌面系统中可按鼠标中键粘贴到光标所在位置。
  • “+ 指 X11 中的 CLIPBOARD 选区,即系统剪切板。在桌面系统中可按 Ctrl+V 粘贴。

有文本拖拽到 vim 时,被拖拽的文本被存储在 ~ 中。 vim 默认的行为是将 “~ 中内容插入到光标所在位置。

3.9 黑洞寄存器 _

黑洞寄存器 “_ ,所有删除或拷贝到黑洞寄存器的文本将会不复存在。 可以用于想要永久删除某些文本,又不想将其放入任何寄存器,或者说不想影响任何寄存器值的情况, “_ 通常 在 vim 脚本中应用较多。

3.10 搜索寄存器 /

搜索寄存器 / 用于存储上一次搜索的关键词。 在 normal 模式下按下 / 即进入 search 模式,输入关键字并按下回车即可开始搜索关键字。搜索完毕后,可以看一看该寄存器里边是什么。

1
:reg /
image-20220304190504921

搜索寄存器是可写的,例如 :let @/ = “test” 将会把 “test” 写入该寄存器。 下次搜索时不输入搜索词直接回车便会搜索 “test” 。

4. vim 录制宏

前边已经了解过了所有的寄存器,接下来接触一下宏的相关操作,也许这可以帮我们节省大量重复工作的时间。什么是宏录制功能呢,现在大部分的软件都会有这种功能,像 Excel , PhotoShop 等软件都有。我的理解就是, vim 把我们要做的某些操作(按的按键,以及按键的顺序等)记录下来,随后 vim 就按照这个记录的操作步骤进行自动运行,以便于帮助我们完成大量重复的工作。 vim 宏有录制和播放两个过程,录制就是我们教给 vim 该怎么操作,播放就是 vim 照着我们教的进行自动操作。

其实前边介绍命名寄存器的时候已经接触了宏录制的过程了,接下来就来进行一下实操。所用文本为:

1
2
3
4
5
6
7
8
9
<a href="./IMG_0301.jpg">1. IMG_0301.jpg</a><br>
IMG_0302.jpg
IMG_0303.jpg
IMG_0304.jpg
IMG_0305.jpg
IMG_0306.jpg
IMG_0307.jpg
IMG_03010.jpg
IMG_03011.jpg

现在要把这些图片名字做成一个链接,点击图片名字就可以访问到图片,并且图片名称前边要加上序号,类似于这样:

1
2
<a href="./IMG_0301.jpg">1. IMG_0301.jpg</a><br>
<a href="./IMG_0302.jpg">2. IMG_0302.jpg</a><br>

图片少的时候可以手动添加,若是有 100 张或者 1000 张呢,那么怎么做呢?接下来就是见证奇迹的时刻了。

  • 做好一个模板

首先将第一行做成想要的格式备用。

1
<a href="./IMG_0301.jpg">1. IMG_0301.jpg</a><br>
  • 准备工作
1
2
3
4
<esc> " 回到 normal 模式下
gg " normal模式下,使光标回到首行
1j " 使光标移动到要开始处理的行
qa " normal模式下,开启录制

【说明】 qa 表示开启录制,并将录制结果保存在命名寄存器 a 中,也可以 qa, qb,或者qc… 等,由于是小写字母,之前录制的会被覆盖掉,这样也能保证录制的宏仅仅只有本次的操作。正常情况下, vim 的命令行会显示 记录中 @a 的字样,

  • 操作步骤
1
2
3
4
5
6
7
8
9
10
11
12
0    " 回到行首
y$ " 复制整行内容
I " 进入插入模式,并使光标位于行首
<a href="./<esc>""pa"> " 写出前半部分标签
<esc>A</a><br> " 从行尾插入,关闭a标签并换行
<esc>k0 " 回到上一行行首
/><enter>l " 光标移动到数字的位置
v/ <enter>y " 复制数字到空格的数据
1j0/><enter>""p " 粘贴数字数据
0/><enter>lv/ <enter>CTRL a " 数字加1
1j0 " 光标移动到下一行首
q " 结束录制

【说明】 “”p 表示使用匿名寄存器中拷贝的内容进行粘贴,直接用 p 粘贴的话会多一个换行, / 表示查找内容, CTRL a 表示数字自加一, q 表示结束宏录制,录制过程中 记录中 @a 一直存在,录制结束消失。

这样进行操作过后,第二行就变成了这样,此时光标位于第三行行首。

1
<a href="./IMG_0302.jpg">2. IMG_0302.jpg</a><br>

那么怎么自动化处理接下来的行呢?

1
n@a   " 播放宏, n 表示执行 n 次

这就是宏录制使用的一个栗子了,有点复杂,感觉,貌似有这点时间早就一个一个添加完了,但是若是图片少的话手动添加倒是无所谓,要是有上 100 行或者更多,那么这点时间的花费就很值得了,毕竟量大的时候还是很节省时间的。

后边就是 vim 的进一步学习,以及 vimscript 的相关内容了,本篇文章暂时结束,后续有补充,会再进行更新,毕竟都是一些基础的知识。