vim命令:基本语法
站内链接:
- vim 笔记(1)-命令-基本命令
- vim 笔记(2)-命令-ex 命令
- vim 笔记(3)-命令-map 映射
- vim 笔记(4)-命令-输入模式
- vim 笔记(5)-配置-通用配置和术语
- vim 笔记(6)-配置-neovim
操作对象
命令格式
一个基本的 vim 命令格式:<operator> [count] <动作>|<文本对象>
- operator: 操作符,表示要进行的操作
- count: 数量,可选值,指定操作应该应用的次数
- motion:动作,指定光标移动的方向和范围
- text object: 文本对象,与动作互斥,指定在特定文本块上执行操作,文本对象通常用于比光标移动更精确的文本选择
根据上面的命令介绍给出一些基本的命令实例
dd
: 删除当前行(operator + motion)2dd
: 删除当前行和下一行(operator + count + motion)viw
:在可视模式下选择当前单词,不包括周围的空格
motion
在讲解所有的 vim 命令之前必须先简单的了解下操作对象选择,毕竟没有待操作对象
,再多的处理动作都是空中楼阁。例如下面的一些命令:
- b: 反向移动一个单词,默认的操作对象是当前光标所在位置前后的单词
- 3b: 反向移动 3 个单词
结合上一节的命令格式,操作对象一般分为两类:动作、文本对象,其中 motion 是一种用于在文本中移动光标的命令
。它允许你在文本中跳转到特定的位置或者选择一定范围的文本, 下面是 motion 的常见分类:
- 上下左右动作, 见
h, j, k, l
- 单词动作, 如
w,e,b
等,见 help word-motions - 行级别动作,如
0-行首,^-行内第一个非空白字符,$-行尾
等 - 查找字符动作,若
f,F,t,T
- 跳转, 如
gg, G, ctrl+b, ctrl+f,H-移动到屏幕底部的行,M-移动到屏幕中间的行,L-移动到屏幕底部的行
,见 help jump-motions
motion 命令允许您快速准确地在文件中移动,无需使用鼠标或箭头键,从而提高编辑效率,其一般和操作符相结合,而且同其他命令结合能够产生更加高效复杂的文本命令。
text object
文本对象指一块特定的文本区域,其不仅可以是单词或句子,还可以是代码或括号内的内容,文本对象允许用户快速选中并对这些区域进行编辑操作,如删除、复制、更改等。下面是文本对象常见分类:
- 单词: aw, iw
- 句子:as, is
- 段落:ap, ip
- 括号内容: a(, i(
通过对比 motion 和 text object 可以得出
- motion 命令主要用于光标的移动,其关注从当前位置到另一个位置的移动,其一般和操作命令配合完成文本编辑任务
- text object 主要用于指定编辑命令的作用范围(结构化块),其关注围绕或包含光标当前位置的文本块,其指定了一个明确的文本区域作为操作的目标
虽然 text object 在使用频率相比 motion 更加小,但是 text objects 从定义上看更加贴近操作对象
这个概念,而且作用的选择范围也更加宽泛(段落、句子等)。另外,通过结合 motion 和 text object,在 vim 社区提出了object-motions
和object-select
两个概念:
- 文本对象动作,
help object-motions
:利用 “motion” 命令和 “text objects” 结合的方式来移动光标或选择文本,例如daw
就是opeartor + 文本块
- 文本对象选择,
help object-select
:使用 “text objects” 来选择文本区域的操作,特别是在可视模式(Visual Mode)下,例如可视模式下使用iw
选择一个单词内的文本
注意,object-select
一般在”可视模式”以及”operator”后面生效, 用于选择某一个限定的对象.其中操作符之后的文本作用范围见文档-[非]块对象的说明。下面是一些常见的选择命令:
1 | aW: 选择一个字串, 光标所在的字串 |
其命令格式一般为operator + a/i + 分隔符文本对象
,其中a/i
表示:
- i(inside)–选择分隔符内的文本
- a(all)–选择包括分隔符在内的文本
操作符
操作符(Operator)是用于对文本进行操作的命令。它们通常用于在文本中执行删除、复制、替换等操作,下面是一些常见的操作符:
- d:删除选中的文本,类似于剪切操作。
- c:修改(替换)选中的文本,类似于剪切并进入插入模式。
- y:复制选中的文本,类似于拷贝操作。
>
:向右缩进选中的文本。<
:向左缩进选中的文本。- =:对选中的文本进行自动缩进。
- g~:反转选中文本的大小写。
- gu:将选中的文本转换为小写。
- gU:将选中的文本转换为大写。
关于操作符的详细信息见: help operator
。Motion/文本对象 和操作符(Operator)是密切相关的概念。操作符是用于对文本进行操作的命令,例如删除、复制、替换等。而 Motion 是用于在文本中移动光标的命令,用于指定操作符的作用范围。
在 Vim 的操作中,通常先输入一个操作符,然后再输入一个 Motion/text objects
来指定操作符的作用范围。例如,假设你想要删除一行文本,你可以使用 d
操作符(表示删除)后跟一个 Motion 来指定删除的范围:
dd
:删除当前行。d2j
:删除当前行及其下面的两行(总共删除三行)。dG
:删除当前行及其后面的所有行(删除到文件末尾)。
基本命令
插入命令
- 移动插入命令
1 | i " 光标首插入 |
- 插入选择,进入普通模式,执行一次 action,之后再次回到插入模式, 例如:
1 | " 删除一行并重新输入(蛮常用的) |
移动命令
- 屏幕移动
- 半屏幕:下移:Ctrl + D, 上移:Ctrl+U
- 整个屏幕:ctrl + B、ctrl + F
- 字符移动:操作对象为行, 当前行到行尾的查找
1 | f " 向前移动光标到字符所在位置 |
- 单词或字符串移动
*, 微型的宏命令,选择光标所在的字符串作为匹配对象
1 | W " 说明:WROD--所有非空白字符组成的任意长度的串,只要不是空白串 |
- 更改光标位置
1 | H " 屏幕开头 |
- 括号间跳转:在开、闭括号之间跳转
使用命令:%
,其作用对象:()、{}、[]
,例如:ft{ --> % --> r] -->--> r[
将{}更改为[],使用到%以及标记命令
更新命令
- 普通模式: 一次修改可以是字符、整行、整个文件. 其中一次修改: 最后一次命令 + motion
1 | x " 作用于字符 |
插入模式, 每一次修改动作:
进入插入模式+...+ESC 结束(包含进入 insert 模式的最后一个命令)
,注意:如果发生光标移动,则会重置修改状态Virtual 模式,每一次修改: 进入可视模式+选择对象+…+ESC(如果进入插入模式)
替换模式,注意使用 r 产生了一个非常棒的方法,利用 r+Enter 键,进行换行操作,只不过会删除当前 cursor 下的字符
1 | r " 当前cursor下的字符 |
删除命令
- ‘’之间字符
使用 vim 中的文本对象选区功能,涉及到的命令有:i 和 a,其中 i 选定文本对象之间的内容,注意,这里的 i 和 a 并不是动作命令删除’’之间的字符之后进行插入操作:ci'
- 行尾空格
1 | " \s在正则中表示所有的空格,即\s\+$匹配所有末尾的空格 |
- 删除并进入输入模式
1 | cc " 删除一行(特殊的语法规则) |
- 删除 motion
1 | cw " 删除一个单词,进入insert模式 |
- 删除单词(重要),在插入模式下使用,无需进行插入-选择模式操作就可以达到目的
1 | <C-h> " 删除前一个字符 |
Undo/Redo
把握撤销的力度
- 命令
1 | u " 一直往后撤销 |
另外,undo/redo 命令前面可以加上 count,例如2 Ctrl + r
将重做最近被撤销的两次操作
- Granularity
将撤销单元尽可能的切成规整的小块单元,保证撤销的粒度在合理且高效的处理范围内。例如: 输入一长串的字符串(超过一百行),此时发现最后的 50 个字符出错,如果使用 u 命令,会撤销所有输入:
- 如果停顿(画家开始构思了),构建断点,ESC,之后可以使用 A 重新开始输入
- 在连续性的多行操作时,将换成 ESC+o
- 重置粒度: 类似于’.’范式中一次修改动作的重置,在插入模式下如果使用光标键(上下作用),则断点会发生重置
Case-sensitive
- 用于将当前光标或者选中的字符变为大写或小写的命令
1 | ~ "反转光标下的字符 |
注意:这里的操作对象类似于缩进中的说明, 具体见vim model.
- 数学运算
1 | <C-a> " 增加 |
重复和宏
help single-repeat, help multi-repeat
vim 本身对重复性操作进行了优化,记录最近的操作,之后使用极为精短的按键就可以重复之前的工作。注意:对于每一个重复性工作,必须实现认真规划按键动作,从而完成任务。
single-repeat
单次重复,允许用户重复上一次的命令或操作,常见的single repeat
命令如下:
.
:微型的宏结构,用于重复一次完整的修改, 注意不能重复”Ex-命令行”命令,’.’范式表示一次按键移动,一次按键 motion; and ,
:微型的宏结构,用于重复最近一次使用f
,F
,t
,T
命令的搜索动作,其中;
用于重复上一次命令的搜索方向,,
则是相反,重复上一次命令的相反搜索方向@:
:微型的宏结构,在普通模式下通过@+:组合键重复执行上一次的 EX 命令,测试过程如下:
1 | 首先执行:%normal A kuang 在每一行末尾添加字符串 |
&
:微型的宏结构,重复上一次的替换操作,相当于执行了上一次使用的:s
(substitute)命令,但不包含任何参数n/N
:查找模式下的重复按键(n/N)
Ex 命令是一类在命令行模式(Command-line Mode)下执行的命令,它们源自 Vim 的前身——Ex 编辑器,例如:w, :s/old/new/g, :set option
等命令,更详细的说明见vim 模式中的介绍。
Multiple Repeat
多次重复命令和单次重复命令的区别就是次数,他们操作的对象主体都是命令或者宏,例如上面的宏命令:
1 | 录制宏:按下q,按下任意字母,比如c,此时就进入@c记录器了 |
对于single-repeat
则仅仅需要输入@c
即可,对于multiple-repeat
则输入3@c
就表示执行 3 遍。单次重复适用于快速重做一个操作,而多次重复适合于批量执行相同操作
宏命令
宏,将任意数量的按键操作录制到寄存器,之后进行回放,类此流量回放,自动化测试回放等等。宏的使用实例在上面章节已经介绍,下面是使用宏的基本命令:
1 | q{register} 开始录制宏 |
- 执行方式
- 串行执行:一次执行一个宏,然后再执行下一个宏。这种方式通常用于需要按照特定顺序处理文本的情况,每次宏执行完毕后,下一次执行可能依赖于前一次执行的结果,一旦中间发生警告,则会直接中断宏的执行。例如对于需求:
在每行的开头添加特定的标记,然后在每行的结尾添加另一个标记
,则需要录制宏:行首的添加操作、行尾的添加操作
,并且这两个宏是顺序执行的。 - 并行执行:指一次性执行多个操作的宏,这些操作对每个目标都是相同的,而不依赖于它们执行的顺序,例如对于需求:
多个行的开头都添加相同的标记
,则需要录制宏:在一行开头添加标记,然后使用 :normal 命令或重复执行宏的方式多次执行
黄金规则:确保录制一个宏时,保证每一条命令都可以被重复执行,从而高效准确的重复利用宏
常见错误
- 在编写代码时,常常会错误的开启宏录制功能,此时状态栏会显示“记录中”,此时尽快退出
缓冲和窗口
vim 中有很多与文件操作和管理有关的术语或功能,比如缓冲区、缓冲区之上的窗口、filetype 和文件编码等,下面就简单的介绍下这些术语或功能。
缓冲区
- 缓冲区
缓冲区是 Vim 中的一个核心概念,Vim 为打开的文件内容在内存中的临时存储区,每次打开或新建一个文件都会对应的创建一个文件缓冲区,注意,这个缓冲区是直接加载到内存区域中的(这也是 vim 不能编辑大文件的根源吧?)。缓冲区允许用户对其中的内容进行增删改查操作,但不会立即影响磁盘中真正的文件内容(异常推出时会保存为.swp 临时文件),只有:w
成功保存之后才会将数据输入磁盘中。
通过缓冲区是编辑过程中的工作区,让用户可以自由地进行文本编辑和其他操作,而不必担心对原始文件造成即时的或不可逆的更改,而且由于是缓冲区的缘故,vim 才会产生各种各样华丽的操作。正因为是内存中的文件, 所以 vim 对于大文件的操作性非常不好。下面是一些常用的缓冲区命令
1 | " 1. 保存或者重新载入缓冲区 |
- swap 文件
前面提到,vim 在编辑文件之后发生异常的时候会文件所在目录下,创建文件名以 .swp
、.swo
、.swn
等扩展名结尾的临时的交换文件,这些文件统一被称为 swap 文件,它实际上就是文件缓冲区的磁盘存储部分,在每次编辑或新建文件的时候都相应的在磁盘上创建一个相关临时 swap 文件,用于存储未保存的更改,从而在系统异常的时候进行数据恢复。
缓冲区数据是完全存储在内存中的,它是用户文件编辑操作的直接对象,但是在 vim 后台有进程(猜测,可能是假的,但是应该类似吧)将这些数据定时刷新到 swap 磁盘文件中。所以,从存储位置、存储目的、生命周期三个角度看 buffer 和 swap 是不同的,但是他们两又是前后紧密合作的。
窗口
缓冲区是内存中的文本文件,窗口是缓冲区的视窗,在 vim 中的所有操作都是在 buffer 进行的,自然而然,每一个操作窗口标签页是窗口的集合,他们两的区别如下:
- “窗口” 被用来查看缓冲区里的内容。你可以用多个窗口观察同一个缓冲区,也可以用多个窗口观察不同的缓冲区。
- “缓冲区” 是一块内存区域,里面存储着正在编辑的文件(亦或帮助文件、目录列表等)。如果没有把缓冲区里的文件存盘,那么原始文件不会被更改。
另外,vim 支持多窗口,这确保了 vim 可以同一时间内编辑多个文件或者多窗口查看同一个文件,其中每个窗口都有自己的光标信息、折叠状态信息等,这是窗口非常重要的功能。
- 切割命令
1 | sp " 水平切割,并在新窗口中载入file |
- 移动命令 s
1 | <C-w>w " 窗口循环切换 |
寄存器
分类和命令
寄存器(Registers)是用来存储文本、命令、搜索模式等信息的临时存储空间,通过寄存器可以将命令(宏则是一组)或文本放入其中,后续可以通过类似重放的方式重复的复制或执行这些内容或命令,在 Vim 正常使用过程中这是非常高频的用法:复制黏贴(通过 xterm_clipboard 还可以同系统交互)、命令、搜索和替换、宏录制。Vim 提供 10 类寄存器,大约 48 个寄存器,用以实现复制黏贴功能。
- 寄存器分类
""
:无名寄存器,比如执行删除操作 d、x 命令时,被删除的文本默认会存储到未命名寄存器中,此时使用 p 会立即黏贴该文本"0, ... ,"9
:数字个编号寄存器"-
:小删除寄存器,用于存储较小的删除操作的内容,通常是少于一行的删除,例如"_
:黑洞寄存器寄存器"a 到 "z,"A 到 "Z
:26 个命名的寄存器":、". 和 "%
:三个只读寄存器"#
:轮换缓冲区寄存器"=
:表达式寄存器"*、"+ 和 "~
:选择和拖放寄存器"/
:最近搜索模式寄存器
- 命令,当使用寄存器的时候,可以通过按键
" + 寄存器名
来使用寄存器进行数据的录入和输出,下面一些常用的寄存器相关命令
1 | " 1 查看寄存器中的内容 |
- 插入模式下的寄存器使用
普通模式下使用寄存器的方法非常简单,通过" + 寄存器名
即可实现,那么在插入模式下应该怎么使用寄存器呢?通过<C_r>{register}
可以将指定寄存器中的值复制到当前输入位置。另外,还可以通过该方式进行数学运算。
系统剪贴板
寄存器的使用仅能在 vim 的多个 buffer 之间实现数据的复制黏贴,但是脱离某个 vim 独立进程就无法在多个打开的标签之间、vim 和外部程序之间进行数据的复制黏贴。
这里就需要引入 xterm_clipboard 编译项支持,另外 mac 需安装 macvim, 确保能进行 vim 和 GUI 的交互,这样就能基础系统剪贴板进行数据的复制黏贴了
*/+
功能类似,在 x11 系统中,前者存放选中或者高亮的内容,后者存放复制和剪贴的内容"*p
命令可以避免使用 F7 命令的缩进行为(非常棒的方法)- 格式:
{virtual}"+y, "+y{motion}
其整体流程如下
1 | # 1 vim-->clipboard |