Vim编辑器简明教程
Vim是从vi发展出来的一个文本编辑器,其代码补完、编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用
最初的简称是Vi IMitation
,随着功能的不断增加,正式名称改成了Vi IMproved
RHEL9
中vim
打开后界面如下,首行清晰写着VIM - Vi IMproved
1 | VIM - Vi IMproved |
对于初学者而言,学习曲线陡峭原因之一在于其独特的多模式编辑方式
Vim的设计哲学之一就是多模式
,可以确保一个按键可以在多种模式下实现不同的功能
Vim的设计哲学另外一点就是操作符+动作
功能,可以极大提高编辑效率
1 多模式
初学者刚用vim
打开文件,会发现一个奇怪的现象:输入的内容并没有实时反应在编辑器上,随机地键盘输入一些内容,忽然发现键盘的打字内容又出现在屏幕上了
实际上这背后的原因就是因为输入了诸如a
、i
等功能键触发进入了插入模式
本文开篇将围绕多模式功能将进一步展开描述
Vim的多模式系统包括普通模式
、插入模式
、命令行模式
以及可视模式
四种模式
通过一些按键可以快速地在普通模式
和其余三个模式下进行切换
1.1 普通模式
普通模式是默认的模式,当你打开一个文件时,你会处于这个模式
有些教程会提示当打开一个文件时会处于命令模式,个人更倾向于认为命令模式是基于在输入
:
前提下,编辑器对于在命令框内输入的指令进行响应回复
在普通模式下,你可以进行以下操作
1、导航:使用箭头键hjkl
来移动光标。你也可以使用b
或者w
按照单词进行跳转
这里注意两点
1、对于光标位于单词的开头时,输入
b
会返回到上一个单词的开头,而光标位于单词的非开头处时,b
会返回到本单词的开头2、对于输入
w
,普通模式下都会将光标跳转到下一个单词的开头3、对于
0
和^
的区别:前者是跳到本行的开头,如果本行开头有空格,后者会跳到本行的第一个非空字符
2、文本操作:例如x
(删除/剪切字符)、dd
(删除/剪切整行)、yy
(复制整行)、p
粘贴等
注意几点:
1、文本的剪切操作和删除操作可以看成是一个动作,删除或者剪切单个字符或者整行内容,后续可以通过
p
粘贴进行操作2、其中
x
针对单个字符类进行操作,dd
和yy
都是基于整行的3、如果针对当前行后续多行,可以使用
d{n}d
,例如d5d
就是包括当前行在内后续行一共5整行内容一起进行删除/剪切4、而
{n}p
中是一次性执行粘贴{n}
次,例如d5d
执行后,再执行5p
,其实最终效果是剪切的行数一共是5行,但是粘贴多了25行
3、进入其他模式。例如按i
键进入插入模式;按:
进入命令行模式
帮助记忆
1、a代表append,在后面追加
2、i代表insert,在前面插入
3、大写代表行首或者行尾
同时也可以使用o
或者大写O
在当前光标行后新增或者行前新增一行
帮助记忆
1、gg可以理解为游戏结束,所以回到最上方行
2、G代表最后一行
3、普通模式下输入
:
切换到命令模式,在命令提示行直接输入行号,可以直接跳转到指定行4、使用
{n}gg
,或者{n}G
同样也可以快速跳转到指定行
1.1.1 当前行快速查找
在vim中,有一个快速定位的技巧必须学习,那就是在当前行查找字符并快速定位
使用小写f
然后跟着一个字符,就能往后快速定位到第一个匹配到的字符
使用大写F
然后跟着一个字符,就能往前快速定位到第一个匹配到的字符
使用;
分号重复找,,
逗号反方向重复查找,找到下一个都会将光标快速定位
1.1.2 查找
在普通模式下,查找和替换功能是平时经常使用的
处于普通模式下,按下 /
键,那么就进入查找界面,输入你要查找的字符串,然后按下回车,光标就会跳转到文件中下一个查找到的匹配处
如果字符串不存在,那么会显示 "pattern not found"
n
跳转到下一个匹配项
N
跳转到上一个匹配项
注意
1、在命令提示符下,输入完想要查找的字符内容后,需要输入
Enter
键,后续可以通过n
或者大写的N
键去跳转到下一个或者上一个匹配项2、查找到的匹配项默认情况下会高亮显示
3、但是在后续插入模式下继续编辑,高亮显示有时候会影响操作,可以通过
:noh
进行临时关闭,这个命令是:nohlsearch
的缩写,它会清除当前的高亮显示,但不会影响之后的搜索。4、永久关闭:在Vim配置文件设置
set nohlsearch
,意为设置不高亮搜索,如何配置Vim的配置文件,详见《第四章节 配置文件》
1.1.3 查找并替换
1 | # 把全部foo替换为bar,全局替换 |
注意:当前行和全局的查找和替换,区别就在于全局使用了
%s
关键字,而当前行作用域下使用s
关键字
1.2 插入模式
在普通模式下,可以通过诸如a
进入插入模式,此时编辑器左下角会显示-- INSERT --
插入模式是用于输入或编辑文本的模式,在插入模式下,按键直接向文本缓冲区插入文本,而不是执行命令
从某种意义上说,插入模式下才是我们传统理解下的所见即所得编辑器工作模式
此时 vim 就跟一般的编辑器一样使用了,按下什么键就是什么键,所见即所得【当然输入ESC除外,如果输入ESC会继续退回到普通模式】
从插入模式返回正常模式,通常使用ESC
键
1.3 命令模式
命令模式的作用进行退出、保存以及相关查找并替换等操作
命令模式的进入比较简单,就是输入shift+;
即:
实现
当我们输入:
后,后续键盘内容均显示在该行命令提示框内,当输入Enter
键后,Vim编辑器执行命令
当我们输入:
键后,我们继续输入set number
可以显示各行行号
命令模式下其他操作指令包括
1、w
:保存当前文件
2、wq
:存盘并退出vim,注意两个字符的先后顺序
3、q!
:输入q!,不存盘强制退出vim
在实际操作中,我一般使用
q!
和wq!
执行退出不保存和保存和退出两种场景
1.4 可视模式
可视模式相当于普通编辑器的多选功能,可以选择一段文本进行相应操作
分为字符可视模式
、行可视模式
、块可视模式
1、在普通模式下,键入小写v
键进入字符可视模式,左下角显示-- VISUAL --
字符根据方向键进行选择,左右方向键则按照逐字符
进行,上下方向键则可以直接选择到上/下一行当前字符下的当中所有内容
2、在普通模式下,键入大写V
键进入行可视模式,左下角显示-- VISUAL LINE --
在行可视模式下,不能在选择单个字符或单词,只能选择完整的行
3、在普通模式下,键入ctrl+V
键进入块可视模式,左下角显示-- VISUAL BLOCK --
选择形成一种矩形形状,这种模式特别适用于对多行进行列操作,如同时修改多行的特定列
1.4.1 可视模式的几个特点
1、普通模式快速移动光标的命令,在可视模式下可以继续使用,例如$
、^
、f{char}
,以及hjkl
等方向键
2、可视模式可以在三种选择模式之间进行随意的切换,例如在块模式下再次输入大写V
键进入行可视模式
1.4.1 三种可视模式的最佳实践
三种可视模型可以参考下图
我们在很多场景下实际是需要在多行的同一列下添加字符,或者删除字符。或者直接在多行的行尾后者行尾添加增加注释等
因此实际上字符可视模式并不合适上述场景
行可视模式的缺点在于只能整行整行选择,但是胜在选择效率高
块可视模式的选择缺点在于当前光标位置只能作为最终矩形选择范围的其中一个顶点
读者可以多试验体会其中情况
1.4.1 栗子1:给多行同时同一列位置增加内容
通过可视操作,利用多行选择的优势,可以极大的实现多行缩进、多行添加内容和删除内容,提高编辑效率
特别注意点
1、当选择多行后,由于光标对应的是多行,因此后续想进入多行编辑模式,只能通过
I
和A
键实现2、普通模式下的
i
和a
是无法完成编辑的3、在多行模式下如果可以实现所见即所得的编辑,左下角必须出现
-- INSERT --
1.4.2 栗子2:在多行的行首添加注释
其实对于这种场景下,如果选择的是行可视模式,其实只要确保当前光标在需要修改的多行的第一行或者最后即可,因为当中都会通过
^
跳转到行首
1.4.3 栗子3:同时修改多行内容
2 大杀器二:操作符+动作
如前所述,Vim的设计哲学另外就是操作符+动作
,可以极大提高编辑效率
2.1 操作符operator
首先先说下操作符,操作符是告诉Vim编辑器干什么?,主要的操作符有以下四个
操作符按键 | 功能 |
---|---|
d | 删除 |
c | 修改(删除并进入插入模式) |
y | 复制 |
v | 选中并进入可视模式 |
2.2 动作motion
动作是告诉Vim编辑器,怎么去做?具体点是指操作哪些范围
动作包括两个字符
动作的前一个字符可以选择i
或者a
,其中i
表示inner
不包括边界,a
表示around
,表示包括边界在内
动作的第二个字符,表示动作范围的边界,例如如果我们要修改单括号{}
或者单引号''
或者双引号""
内的内容,第二个字符就可以输入对应的单括号、单引号或者双引号
解释的有点拗口,操作符+动作需要结合一起说明,这里我们直接通过两个简单例子说明清楚
2.3 栗子1:修改特定字符中内容
正常情况下我们要删除某个单词,可以直接dw
进行删除
但是如果遇到类似string: 'i am iron man'
中,要快速删除或者替换单引号内容这种情况呢?总不能定位后再逐个删除吧
我们只需要将光标通留在需要修改的内容中间任意位置,然后依次输入c
、i
、'
,这三个键即可,其中c
就是操作符,后面的i'
就是动作
第一个键c
:告诉vim编辑器接下来是修改(删除并进入插入模式)
第二个键i
:告诉vim编辑器我们的动作范围是inner
即不包括后续字符边界本身
注:如果这里我们选择输入的是
a
的话,那我们就是把单引号一起进行修改
第三个键'
,:告诉vim编辑器我们的动作边界的点是单引号'
注:我们这里的边界都是成对出现的,否则vim是不知道边界的左右两侧
上述操作符+动作
完成后,我们就可以继续正常输入响应内容,用于替换既定要修改的内容
2.4 栗子2:修改某个数组里的所有元素
例如删除const a = [1,2,3,4,5]
中数组里的所有元素
我们只要只要将鼠标定位到数组中括号里的任一位置,然后键入ci[
或者di[
即可
第一个键c
:告诉vim编辑器接下来是修改(删除并进入插入模式)
第二个键i
:告诉vim编辑器我们的动作范围是inner
即不包括后续字符边界[
本身
第三个键[
,:告诉vim编辑器我们的动作边界的点是单引号[
注:因为边界是成对出现,因此我们也可以输入
]
3 其它操作
撤回对应键是u
,而撤回后想继续上一步操作那就是 ctrl + r
重复操作就是.
4 配置文件
如果希望所在的配置是永久性的,那么需要在家目录( cd ~
)创建一个 Vim
的配置文件 .vimrc
1 | # 显示行号 |
5 运维
5.1 问题1 提示出现了一个临时文件
当我们vim编辑器遇到没有正常退出,例如ssh的会话终端退出前未保存编辑器
当我们再次打开原先文件时,系统会提示以下信息:
1 | Found a swap file by the name ".aa.swp" |
5.1.1 原因
事实上vim编辑器在打开一个文件例如文件a
时,本质是去创建并编辑一个在原文件名后添加.swp
后缀的隐藏的临时文件,即.a.swp
我们通过lsof
查看当前并没有进程去开打原文件a
,而vim编辑打开的就是这个隐藏的临时文件
1 | [root@ethan ~]# lsof .a.swp |
我们在过程中编辑的变化都会写入到这个临时文件
如果命令行选择q!
即退出不保存,则会删除这个临时文件.a.swp
,原文件不会发生变化
如果命令行选择w!
即退出保存,则会回写至一个新的的文件,同时删除原文件a
和临时文件.a.swp
,将这个新的文件命名为a
我们可以通过文件的inode进行验证
5.1.2 解决方法
如果我们需要恢复原来未保存的临时文件,此时我们可以选择输入R
进行恢复,即继续编辑
编辑器会进一步提示已经恢复,并且缓冲区已经和恢复的文件内容一致然后可以删除.swp
文件了
1 | Swap file ".a.swp" already exists! |
总结,想恢复之前未保存的内容的步骤
1、选择R
恢复,根据提示选择Enter
2、此时vim编辑器会恢复到上次一次未保存状态
3、选择wq!
保存退出
4、务必删除.swp
文件,否则下次打开vim编辑器时候还会继续提示