文章目录
写在前面
本篇为课程第五章内容,包含两节课:L17 和 L18,前者介绍Vim
复制粘贴的基本概念与用法,后者则重点介绍了Vim
的寄存器机制 —— 这也是Vim
让人爱不释手的又一神级设计。所有知识点都逐一罗列,方便后期快速查找。同步练习拟放到下一篇几种进行。
第 5 章 删除、复制与粘贴(Section 5:Deleting, Yanking and Putting)
S05L17 第一部分:剪切、复制与粘贴(Cut, Copy and Paste - Part I)
本节介绍 Vim
的文本剪切、复制与粘贴操作。
演示文件:vimclass/cutcopypaste.txt
0 为什么会用到剪切、复制、粘贴
- 移动文件文本的需要;
- 重复(Duplicate)文本内容的需要;
- 创建一个文件内部的简要备份(如配置文件中 1)
- 复用(Reuse)同一段文本的需要;
其实剪切相关的命令已经学过一些了:
d
命令与x
命令其实是 剪切 命令,不仅仅是删除;- 剪切 = 删除 + 存入 寄存器(
register
) - 寄存器是一个类似剪切板(clipboard)的存储区域
1 默认寄存器(未命名寄存器)default register / unnamed register
按 DD 剪切第 1 行,该行内容将存入 默认寄存器(default register)(也叫未命名寄存器(unnamed register))。
P:在当前光标的下一行,粘贴刚才剪切的内容。
在 Vim
中,p
命令又叫 put
命令。也可以理解为 paste(粘贴)
2 交换两行文本
使用 DDP:先剪切第一行(第二行上移)再粘贴到原第二行的下一行。
3 粘贴到当前光标的上一行
使用 Shift + P
注意:剪切(cut)后的内容可以被多次粘贴(put
),只要寄存器中的内容未被其他命令(如删除命令 d
)清除。
4 粘贴某个字符
先用 X 剪切,再用 P 粘贴该字符。
XP:交换当前光标与光标 右边 的一个字符(还原:ShiftXShiftP + XP,或者 UU)
ShiftX + P:交换当前光标与光标 左边 的一个字符(还原:ShiftXShiftP + XP,或者 UU)
5 剪切光标右边的剩余文字,粘贴到该行开头
D$ + 0 + ShiftP
或者:
ShiftD + 0 + ShiftP
6 复制内容
使用 Y:即 Yank
命令,表示复制(相当于 Copy)
标准叫法 | Vim 叫法 |
---|---|
cut | delete |
copy | yank |
paste | put |
7 复制 + operator[motion]
YW:复制一个单词
2YW:复制两个单词(或 Y2W)
粘贴则用 P 或 Shift + P
8 复制一整行
使用 YY
9 快速复制当前行并粘贴到下一行
使用 YYP
⭐️ 粘到上一行:YYShiftP
两者的区别:
yyp
:光标在原来位置的下一行,感觉被复制的文本在往上 ⬆️ 走;yyP
:光标还在原来的行上,感觉被复制的文本在往下 ⬇️ 走。
实测命令 yyp
:
实测命令 yyP
:
10 复制多行文本
格式:[count]yy
4YY:从光标当前行开始(含当前行),下数 4 行内容进行复制。
11 撤回操作命令
使用 U(表示 Undo)
注意:撤回的是上一次 命令,而不是某一行(有人误以为误删多行后,按 U 只恢复一行内容,这是错误的)
12 重新执行(重做)命令
使用 Ctrl + R(表示 Redo)
S05L18 第二部分:Vim 寄存器机制(Cut, Copy and Paste - Part 2 - Registers)
- 演示文件:
vimclass/cutcopypaste.txt
1 register 的分类
register
(寄存器)的类型:
unnamed
:未命名寄存器,表示为""
numbered
:数字寄存器,表示为"0
、"1
、"2
、……"9
named
:命名寄存器,表示为"a
、"b
、"c
、……"z
2 register 存放的内容
""
:holds text fromd
,c
,s
,x
andy
operations(存储由d
/c
/s
/x
/y
命令截取下来的文本内容)"0
:holds last text yanked (y
)(存储上一次复制的文本)"1
:holds last text deleted (d
) or changed (c
)(存储上一次d
/c
操作删除的文本)- Numbered registers shift with each
d
orc
(数字寄存器在每次d
/c
操作时 移位)
3 register 的位移机制(Shift Mechanism)
每次执行 d
或 c
命令时,现有的寄存器内容会向后移动一位(即 1
的内容会移到 2
、2
的内容会移到 3
,依此类推)。
0
号和 1
号寄存器总是会分别存储 最近复制 与 最近删除 的内容,而 2
到 9
号寄存器则存储 之前的 删除(deleted)或 改变过(changed)的内容。
【注意】
复制下来的内容 并不参与 位移!
复制下来的内容 并不参与 位移!
复制下来的内容 并不参与 位移!
复制下来的内容 并不参与 位移!
复制下来的内容 并不参与 位移!复制内容只会在
0
号寄存器 不停被新的复制内容替换!
4 查看 register 列表
使用 :REG(即 :reg
)+ Enter
5 复制于删除内容分开存放的好处
先复制,再删除,此时又想粘贴先前复制的内容,而非删除的内容时,很有效。
6 黑洞寄存器(black hole register)
写法:"_
作用:不进入寄存器,同时也不影响其他寄存器的正常使用
场景:在需要频繁复制粘贴、且偶尔需要删除一些内容时,对删除内容应用黑洞寄存器。
实测:黑洞寄存器和普通寄存器的区别
打开
cutcopypaste.txt
文件,定位到第 39 行:
复制第 39 行(
TODO
),然后删除第 41 行(Fix this line too!
),再查看寄存器:
此时文件变为:
使用 黑洞寄存器 删除第 41 行:
然后重新打开寄存器列表:
作为对比,再用 U 撤回删除,改用普通方式删除第 41 行,再次查看寄存器列表:
均符合预期。
7 粘贴指定寄存器的内容
"2p
:在当前行下方,粘贴 2 号寄存器中的内容
8 复制 3 行后查看寄存器
运行 3yy
+ :reg
+ Enter
此时默认寄存器、0 号寄存器均为复制的三行内容(^J
代表换行)
9 命名寄存器
共 26 个,从 a
到 z
:"a
、"b
、"c
、…… "z
复制当前行并存入 a
寄存器:"ayy
10 命名寄存器内容的追加
再复制一行,追加到寄存器 a
:"Ayy
11 通过 d 命令存入命名寄存器
"adw
:将删除的那个单词存入寄存器 a
12 查看一个或多个具体的寄存器
- 查看
"z
::reg z
+ Enter - 查看
"a
和"z
::reg az
+ Enter
13 寄存器的重复执行
格式:[count][register]operator
或者:[register][count]operator
例如:"hyy
+ 2"hp
或者 "hyy
+ "h2p
(复制到寄存器 h
,并将内容粘贴两次,粘到当前行的下方)
本章小结
cut
-copy
-paste
=delete
-yank
-put
- Registers are storage locations(因此又译【缓冲区】,用于存储和读取)
""
包含了上一次操作截取下来的内容(contains last operated on text)- 没有指定寄存器运行的命令,用的都是默认寄存器里的内容,例如粘贴命令
p
- 数字寄存器有 10 个:从
"0
到"9
。其中:"0
存放上一次复制的(yanked)文本"1
存放上一次删除的(deleted)文本
- 每成功执行一次删除(delete)或变更(change),寄存器的内容就依次上移一位,直到覆盖 9 号寄存器上次存入的内容。
- 具名寄存器有 26 个:从
"a
到"z
- 具名寄存器可使用大写形式对存入的内容进行追加:
"R[yanked][deleted]
表示将复制或删除的内容追加到寄存器"r
中。 - 查看具体的寄存器:
:reg [register(s)]
- 操作命令的撤销:U;重新执行:Ctrl + R。撤销与重做都是针对命令而言,而非针对具体内容的行数或字数。
- DIY 补充:
:reg
列表中的Type
栏表示存放内容的类型。其中:c
表示characterwise
;l
表示linewise
;b
表示blockwise-visual
。
类似场景非常多:修改某配置文件的某行前,先复制一份并注释掉,以此作为备份。 ↩︎