启动vi

语法: vi [-rR] [file…]

如果用vi启动了一个不存在的文件,那么他将新建这个文件。如果只输入vi,那么他将在当前文件夹下创建一个空文件

-R 以只读模式启动

vim是vi的进阶版本

语法: vi -C [-rR] [file…]

-C是兼容模式,它将尽可能的和vi保持一样

命令模式和编辑模式

当使用vi时,存放数据的区域叫做编辑缓冲区(editing buffer),如果想编辑文件,那么vi就将文件的内容复制到缓冲区中,然后再缓冲区中编辑。因此处理的其实是文件的副本。

在命令模式中,输入的一切字符都是命令。例如,在命令模式中,单个字母x就是删除一个字符。dd就是删除整行的命令。

第二种模式就是输入模式。这种模式下,任何内容都会输入到缓冲区中。

在启动过程中,vi完成三件事情。将文件中的内容复制到编辑缓冲区,将光标定位到缓冲区第一行的开头。最后vi进入命令模式。

数据的恢复和关闭vi

当使用vi时,数据会保存在编辑缓冲区内,因此当程序非正常终止时,临时文件依然存在。使用-r(recovery)就可以重新打开缓冲区

如果需要先保存再退出,使用的命令时ZZ,即先按下shift键,然后按z两次。这个命令不需要按enter键

如果不保存直接退出,可以 :q!,然后按return键

vi屏幕的格式即vi和ex命令

屏幕底部的一行叫做命令行。这一行有两种功能:显示消息和显示键入时的命令。

大多数时候vi编辑的数据都是纯文本(字母,数字,标点符号等)。如果想输入控制字符,需要使用^v。 例如,如果想输入^c,那么需要输入^v^c.

vi和ex命令其实都是vi编辑器中的命令。大多数vi命令都是单字母或双字母形式。大多数vi命令无需按下return键。例如,一但输入dd,那么立刻会删除一行。

ex命令一般都比较长,并且在键入过程中会显示在屏幕下方。如果键入有错误,可以backspace删除单个字符或者^x/^u删除所有字符。

移动光标

h 向左移动一个字符

j 向下移动一个字符

k 向上移动一个字符

l 向右移动一个字符

另外一种方式是上下左右键。

此外,backspace 向左移动一个位置,space向右移动一个位置。-号移动到上一行,+号移动到下一行。

0移动到当前行的开头,$移动到当前行的结尾。^移动到第一个非制表符/空格字符上

w移动到下一个单词的开头,e移动到下一个单词的结尾。b移动到上一个单词的开头

W,E,B的作用和w,e,b的作用相同,但是忽略标点符号

( 移动到上一个句子

) 移动到下一个句子

{ 移动到上一个段落

} 移动到下一个段落

句子的定义时一个字符串,以句号,逗号,问号和感叹号结尾,并且后面要接一个新行字符或者两个空格

H 移动到屏幕的顶部(是当前屏幕,不是整个文章)

M 移动到屏幕的中间

L 移动到屏幕的底部

为了增强命令的功能,可以在命令之前输入数字确定重复次数。例如:10w代表跳过十个单词。不需要输enter。

整屏移动

^f(ctrl+f,forward) 移动到下一屏

^B(backward) 移动到上一屏

^d 下移半屏,^u 上移半屏

这里^d和^u前面加数字与前面略有不同。前面只对该次有效,而这里是一直有效

跳转到前一位置

可以使用两个反引号跳转到前一位置。这个前一位置并不简单指的是上一条指令的位置。如果你一直使用行跳转的话那么这条指令将会带你去没进行行跳转时的位置。其实相当于保存了两个地址,你可以在两个地址之间跳转进行修改,第一个地址就是每跳转之前的地址。第二个地址就是跳转之后的地址。如果你现在位于第二个地址上,那么进行跳转只会改变第二个地址。用了反引号后直接回到第一个地址,然后如果再在第一个地址上跳转,那么只会修改第一个地址。

第二个跳转地址是在你第一次使用移动命令后产生的,也可以看为开始第一个地址和第二个地址再同一位置。之后一直都是在对第二地址进行修改。

如果使用两个单引号,那么将会回到对应地址的开头。

此外,我们还可以通过设置标识来新增跳转地址。先键入m,再输入标识符,之后就可以直接跳转到有标识符的位置。标识符是不可见字符,所以最好自己先记好。

例如: ma设置a标识符。 `a回到a的位置

搜索模式

符号: / ?

/ 向下面搜索,/+字符表示要搜索哪个字符。如果还想继续搜索该字符只需要输入/然后回车就会搜索下一个

? 用法相同,向上搜索

或者按n继续向下搜索,N继续向上搜索

此外,还可以使用正则表达式中的锚

使用行号和切换模式

可以通过 :set number 设置显示行号

如果行号关闭,可以通过 ^G键查看现在在文本中的哪个位置

可以通过 数字+G(大写)跳转到任意一行

此外,还可以通过 :+数字跳转到任意一行,其中 :$ 跳转到文本末尾

前文已经说了vi有两种模式,一种是编辑模式,一种是命令模式,从编辑模式切换成命令模式只有一种方法,按esc键。但是从命令模式转换到编辑模式有十二种之多

i 在当前光标之前插入字符
a 在光标之后插入字符
I 在当前行的开头插入字符
A 在当前行的末尾插入字符
o 在当前行下面插入一行
O 在当前行上面插入一行

修改文本

如果只需要修改一个字符的话,那么可以在命令模式下输入r+字符就可以修改光标后面的字符(注意不是增加而是直接把光标后面的字符变成输入的字符)

如果想要修改很多字符,可以输入R,这时会切换到输入模式。随后键入的每个字符都会替换当前字符。

如果想要修改的字符数与原来并不相同,那么可以使用s(substitute)命令把一个字符变成许多个字符。如果输入了s,那么将回到输入模式,且此时光标后面的后面的字符将会变成$,然后再输入字符,$就会变成对应的字符

例如 m|a,输入s后变成 m|$,然后输入other,就会变成 mother

此外C命令是将光标后面的字符都替换,如果输入了这个命令,那么在该行的最后将会出现$

cc命令可以替换一整行,无论光标在哪里

c+移动光标命令,这将替换从光标处到移动后的光标处所有的字符,可以有重复次数

替换文本

这里我们主要谈论的是ex命令。这些命令都以 : 为开始。

替换语法: :s/pattern/replace/

这条命令的含义是替换第一个pattern,如果后面加上g(global),那么将替换所有pattern。

如果希望改变之前先请求同意,可以在后面加上 c(confirm)。也可以同时使用gc

如果想要删除某些pattern,只需要 :s/pattern//g即可

在s前面加上数字表示替换某些行。例如: :57s/unix/linux 表示把第57行第一次出现的unix变成linux。

如果想从当前行到末尾,那么可以使用 : . , $s/pattern/replace/

其中 .(点)表示当前行,$表示最后一行,中间用逗号分割开来。

删除字符

x 删除右边的字符
X 删除左边的字符
D 删除当前光标到本行末尾的字符
d+移动指令 删除从当前光标到移动指令后的字符
dd 删除当前行
ex 命令
:lined 删除指定行
:line,lined 删除多个行

如果要删除所有行,一种是 :1,$d,另一种是:%d,%指的是所有行

撤销或重复改变

撤销就是如果命令输入错误,可以使用命令撤销

u 撤销上一命令对缓冲区进行的修改

U 恢复当前行

. 重复上一命令对编辑缓冲区进行的修改

其中 U 指的是将撤销至移动到当前行的那一刻起,对当前行所进行的所有改变

.命令可以用来重复,但是如果使用了撤销,那么它将会使用撤销所恢复的命令

恢复删除

每当删除一行或者多行文本时,vi都将文本储存在一个缓冲区中,这个缓冲区称为编号缓冲区。vi有9个缓冲区。在任何时候,都可以将一个编号缓冲区中的内容插入到编辑缓冲区中。这样做时,需要键入一个双引号(“),后面跟着缓冲区的编号,再后面跟着一个p(put)命令,p是在当前行下面插入,P是在当前行上面插入。

如果你忘记是哪个编号缓冲区的话,可以先撤销一次,然后使用.号重复插入,这时vi将自动把缓冲区编号加1

移动文本

vi总是在一个称为无名缓冲区的地方为上一次删除保存一个副本。与编号缓冲区不同,编号缓冲区只会保存删除的多行,删除少数字符是不会被保存的。

p 命令用来把无名缓冲区的内容插入到当前位置之后

考虑组合命令xp,x是删除当前光标处的字符。p是把字符插入光标的右边。这样相当于把两个自住房换了一下顺序。

另一个重要的组合命令是deep,这个命令是将两个单词换序

ddp 调换两行,因为dd是删除一行,删除这行后光标在原本该行的下一行,然后p是插入到这一行的后一行,相当于两行换了位置。

复制文本

复制文本分为三步:

  1. 使用y,yy或Y命令将文本有编辑缓冲区复制到无名缓冲区中,但不删除原始文本。
  2. 将光标移动到希望插入文本的位置。
  3. 使用p或P命令命令执行插入

在不删除文本的情况下将文本复制到无名缓冲区,叫做接出(yank),因此将命令命名为y,yy,Y。y,yy命令和d命令执行情况相同,

改变字母大小写

符号: ~

该命令会改变vi当前字母的大小写,然后将光标向前移动一个字符。改变大小写的意思是把大写变成小写,小写变成大写。

有些版本的vi使用这个命令不会超过一行,just like me。

设置选项

:set showmode 输入模式提醒
:set number 显示行号
:set nonumber 不显示行号
:set tabstop = number 设置制表符间距
:set autoindent 缩进以匹配上一行/下一行
:set autowrite 如果文本已修改,则在切换文件前保存
:set errorbells 显示错误信息时发出声音
:set list 将制表符显示成^I,将行的结束显示成$
:set showmatch 显示匹配的 () {} []
:set wrapscan 环绕文本进行搜索
:set lines 设置文本行数
:set wrapmargin = n 在键入过程中自动换行,n是离右边缘的位置,例如n=6意味着在例右边缘6个字符的地方换行,为0关闭自动换行

如果想查看当前选项是在什么状态,可以使用:set 选项?

如果显示所有选项的值,可以使用 :set all

复制移动行

如果想指定行号进行移动,可以使用ex命令中的 :co(copy) :m(move)

:5co10,复制第5行,并将其放在第10行的下面

:4,8co20 复制4到8行,并将其放在20行的下面

输入shell命令

可以通过 :!+命令的方式,在不退出vi的情况下进行shell命令

:!! 重复上一条shell命令

如果现在缓冲区中直接插入shell命令的输出,可以使用 :r !

例如 :1r !date,就是将date输出插入第一行的后面

如果直接用感叹号,那么就会将文件中的数据交给shell命令进行操作,然后再将操作后的文件复制到原位置

例如: 5!!sort ,这个命令将会从当前开始把接下来5行排序。

!}sort 这个命令是将接下来一段排序。

将文件中的数据插入编辑缓冲区中

语法: :[line]r file

line 是行号 file是文件名

:r命令读取文件中的内容,然后将其插入指定行的后面

不退出vi的情况下进行保存

:w 将数据写入原有文件
:w file 将数据写入一个新文件中
:w! file 覆盖原有文件
:w>> file 将数据追加到一个新文件中
:10w! save 将特定行保存到文件中
:wq 保存退出vi 和 ZZ有同样的效果

切换到一个新文件

:e + 文件名

当编辑一个新文件时,原有缓冲区内容会消失,所以首先要使用 :w保存.当使用:e时,系统会自动检查是否保存,如果没有保存,不允许切换到新文件。如果希望忽略这种保护,可以使用:e!命令

使用缩写

:ab [short long]

short是缩写,long是缩写的原文。如果确定了缩写,那么在编辑模式下,如果拼写了缩写,系统会自动变成全称。当然,只有在这个缩写是一个单词(两边有空格)的情况下才会变全称。

:map命令可以创建命令模式下的缩写,实际上,这就可以自己创建命令。这些命令叫做宏

语法: :map [x commands]

x是一个字符,commands是vi或ex命令序列

例如 :map K deep就是将两个单词换位的命令设置成一个宏

初始化文件

对于vim来说,初始化文件是.vimrc,

如果想删除一个缩写,可以使用 :una short