这一篇文章将开始进入 Vim 的世界,首先概要介绍一些 vi 的同类品,包括这些同类品对 vi 做的各种改进。之后将重点介绍 Vim,它也是 vi 同类品之一,只不过是最经典、使用最广泛的 vi 同类品。从这篇文章开始,我们将正式学习 vim。
vi 的同类品
有许多可以自由取得的 vi 编辑器同类品,其中最经典就是 Vim 编辑器了。除了 Vim 之外,还有三种常用的同类品:nvi,elvis,vile。这些同类品都提供了 vi 之外的许多扩展功能,尽管方式可能各不相同,但这些同类品通常会提供一些共通的扩展功能:
- 多窗口编辑:可以将屏幕分隔成多个
窗口
,从而在每个窗口编辑不同的文件,或者观察同一文件的不同部分。这使得同时在多个文件中工作更加容易,在文件间剪贴文本也更加方便 - 图形用户界面:除了 nvi 之外,所有同类品都可以编译成支持 X Window 界面
- 扩展的正则表达式:之前已经学习过了 vi 编辑器中可用于搜索和替换模式的正则表达式元字符。每种同类品都提供了某种形式的扩展正则表达式。但每一种扩展方式的“风味”都与众不同
除此之外,还有一些扩展功能需要重点介绍。
增强的标签
Exuberant ctags
程序是 ctags 的同类品。比 UNIX 上的 ctags 功能更强大,可以产生扩展的tags文件格式,让标签的搜索与匹配处理更加灵活,更加强大。以下是 Exuberant ctags
的特色功能:
- 支持 C 与 C++ 代码,另外还支持 29 种程序设计语言,包括 C# 和 java
- 能够产生所有类型的 C 与 C++ 语言标签
- 在解析代码时非常可靠
- 列出供人阅读用的源文件中的被选择对象的列表
- 支持产生GNU Emacs样式的标签文件
传统的 tags 文件有三个以制表符分隔的字段:
- 标签名称(一般是标识符)
- 包含标签的源文件
- 以及何处可找到标识符的指示符。指示符可以是简单的行号,或者是以斜线或问号括起的 nomagic 搜索模式。
新的格式向下兼容传统格式。前面三个字段仍然相同:标签,文件名称与搜索模式。扩展的属性会放在用于分隔的 ;
分隔符后面。属性间以tab字符分隔,每个属性均由以冒号分隔的两个子字段组成,第一个子字段是描述属性的关键字,第二个则是实际的值。
标签栈
每一种 vi 同类品都扩充了所维护的标签栈。每次通过 :tag
命令或者 vi 中的 ^]
命令搜索某个标签时,编辑器会先保存当前的位置。这样以后就可以使用vi编辑器的 CTRL + T
命令或者 ex 命令回到保存起来的位置。Vim的标签栈功能将在后续文章进一步学习。
改进的编辑工具
所有的同类品都提供了编辑 ex 命令行、不限次数的撤销、任意长度的行、增量搜索,将屏幕从左往右滚动以代替绕排过长的行、可视模式、以及模式指示器等其他特性。
编程辅助
vi 是为编程者开发的编辑器,它提供了一些功能,使得传统的 UNIX 编程者(编写 C 程序和 troff 文档的人)工作起来更容易。vi 的同类品在此基础上,提供了更多功能:
- 编辑-编译的加速:在编译期间,完全不需要离开编辑器,而且可以取得编译器的输出,并自动跳到包含错误的行上
- 语法高亮:将代码中的不同语法元素用不同的颜色与字体来显示
Vim 概述
Vim 指的是 vi improved
,即改进版的 vi。目前 Vim 可能是使用最为广泛的 vi 同类品。Vim 由 Bram Moolenaar 编写,也得到其他人的协助开发。所以 Vim 能够随着计算机工业以及文本编辑需求而相应地成长与改变,并维持着自身的价值。今天的 Vim 是功能最为全面的类 vi 编辑器之一,在线帮助也很丰富。
与vi的比较
Vim 的接受度比 vi 更为广泛,因为某些版本的 Vim 几乎可供所有操作系统使用,而 vi 只适用于 UNIX 或类似于 UNIX 的系统。
vi 是原始版本,但是 Vim 实现了所有的 vi 功能,同时提供了许多好用而强大的扩展功能,这些扩展功能包括:语法扩展、程序员辅助、图形用户界面功能、脚本编写与插件程序、初始化、会话上下文、后处理、状态转换、透明的编辑、元信息、黑洞寄存器、关键字补全等。Vim 也能通过设置 compatible 选项回到与 vi 兼容的模式。
取得 Vim
如果操作系统是 Unix-Like 操作系统,Vim 可能已经安装好了。现在许多的 Unix 环境中已经附有某一版本的Vim了,大多数GNU/Linux发行包均把默认的 vi 位置 /bin/vi
链接到 Vim 可执行文件。如果你的操作系统没有安装 Vim,就需要自己手动安装 Vim 了。
Vim是个自由软件,也是个慈善软件(charityware),如果你正在使用 Vim,不妨输入 :help uganda
以了解更多信息。
Vim 的改进
Vim 对 vi 做了大量改进,这些改进包括:内置帮助功能、启动与初始化选项、新的移动命令、扩展的正则表达式、扩展的撤销,自定义可执行文件等。
内置帮助功能
Vim 的说明文档超过 10 万行,几乎所有的说明都可以通过 Vim 内置的帮助工具取得,使用它最简单的形式就是调用 :help
命令。使用内置的帮助功能需要了解 vi 的导航技巧,知道如何在标签间前进与后退。当光标处于某个标签上时,按下 ctrl + ]
前往该标签,按下ctrl + t
或者 ctrl + o
从该标签返回。
:help
命令后面可以包含帮助主题,我们输入的主题字符串可能会与现在 Vim 帮助主题里的某个字符串符合,例如输入 help split
再按下 tab
键后,help 命令会在与 split
相关的帮助主题字符串间循环,想看某个帮助主题,直接按下 enter
键即可。
启动与初始化选项
Vim 可以使用不同的机制在启动时设置环境,Vim 也可以使用一系列初始化文件来定义并调整难以计数的行为组合。想要了解 Vim 的启动细节,可以使用 :help startup
命令。
Vim 的命令行选项也提供了极大的灵活性。有些选项可以调用额外功能,有的选项可以抑制默认行为。在命令行选项后面,可以列出一个或多个待编辑的文件,文件名甚至可以为 -
,让 Vim 知道输入来自标准输入。接下来列出部分 Vim 有但 vi 没有的命令行选项(Vim 已包含了所有 vi 选项):
- -b:在二进制模式中编辑
- -c:command: command将被视为 ex 命令执行
- -C:以兼容 vi模式运行 Vim
- -cmd command:command 在 vimrc 文件前执行,这也是 -c 选项的长形式。
- -d:以 diff 模式启动。Vim执行 2-4 个文件的 diff 功能以及可以设置选项来简化文件差异的查看。在 UNIX 中 Vim 使用系统的 diff 命令来执行 diff 任务,在 Windows 上则可下载另行提供的可执行文件
- -E:以改进的 ex 模式启动
- -g:启动 gvim(GUI)
- -m:关闭写入选项,此时不能修改缓冲区
- -o:所有文件均各自打开窗口。可以指定要打开的窗口数量(以整数指定,紧跟在 -o 选项后面),命令行中列出的文件分别于指定数量的窗口中打开。若窗口数超过文件数,Vim打开空白窗口,以满足数量需求。如果窗口数小于文件数,则将剩下的文件放入Vim的缓冲区中
- -O:与 -o 一样,但打开垂直分隔的窗口
- -y:以 easy 模式运行 Vim,对初学者而言这个选项会使 Vim 有较为直观的行为,但经验丰富的用户反而会对此觉得困惑
- -Z:以 restricted 模式运行,基本上关闭所有外部接口并防止对系统功能访问
系统与用户的配置文件
Vim 依照特定的顺序寻找初始化文件,它执行找到的第一组指令(可能以环境变量或文件的形式出现),然后开始编辑。所以 Vim 在下列清单中遇到的第一个项目,就是清单中被执行的唯一项目。顺序如下:
- VIMINIT:环境变量,如果变量不为空,Vim 将它的内容作为 ex 命令执行
- 用户的 vimrc 文件:vimrc 初始化文件是个跨平台的文件,在UNIX系统中,Vim 寻找的该文件的位置为:
$HOME/.vimrc
(注意,在 UNIX 中,如果.vimrc
文件不存在,也会尝试寻找_vimrc
文件) - 环境变量 EXINIT,EXINIT 变量的内容也将作为ex命令执行
- 用户的 exrc 文件,类似于 vimrc 文件。在 UNIX 系统中,Vim 寻找该文件的位置为
$HOME/.exrc
- exrc 选项:如果设置了 Vim 的 exrc 选项,Vim 会在当前目录下寻找三个额外的配置文件:在 UNIX 中分别为
.vimrc
,_vimrc
,.exrc
关于Vim初始化搜寻的顺序可以通过”:help startup”。vimrc 文件是配置 Vim 编辑特性较好的地方,几乎任何选项都可以在该文件中设置。以下是vimrc的一些注意事项:
- 注释都以双引号
"
开始,可位于一行的任意位置。所有位于双引号后的文本,包括双引号都会被忽略 - 可用(也可不用)冒号表示ex命令。
- 如果一大组选型定义能分开为不同行,这个文件将较容易管理。
环境变量
有许多环境变量影响到 Vim 的启动及编辑时的行为,这里列出最为明显的且在未配置时会以默认值处理的环境变量:
- SHELL:指定 Vim 用于执行 shell 命令的 shell 或外部命令解释器
- TERM:设置 Vim 内部的 internal term 选项。但这个选项其实不太需要,编辑器会以自己觉得适当的方式设置其终端
- MYVIMRC:覆盖 Vim 对初始化文件的搜索。如果启动时找到 MYVIMRC 的值,Vim 假设这个值是初始化文件的名称,如果文件存在,则从中取得初始化设置,并不再搜寻其他文件。
- VIMINIT:指定 Vim 启动时欲执行的命令。命令间以竖线分隔即可定义多个命令
- EXINIT:与 VIMINIT 相同
- Vim:包含标准 Vim 安装系统信息的系统目录路径
- VIMRUNTIME:指向Vim支持的文件,例如在线说明文档,插件目录等。通常 Vim 能自己找出这些文件
新的移动命令
Vim 提供所有 vi 移动命令,同时增加了一些命令:
- Ctrl+end:转至文件最后一行的最后一个字符,如果加上数字,则跳到该行的最后一个字符
- Ctrl+home:转至文件第一行的第一个非空字符。或者可以使用 gg 命令
- count%:转至依据文件百分比计算出的行。光标置于该行附近第一个非空白的行。而且需要注意,Vim 以文件的行数作为计算依据,而不是以总字符数为依据
- :go n: 转至缓冲区的第n个字节,所有字符包括行末字符都计算在内
可视模式的移动
Vim 能够让用户以可视化的方式定义所选项,且在此可视化所选项上执行编辑命令。这个功能和在图形化编辑器中点击并拖动鼠标造成的高亮效果很像。Vim在定义可视选择项时,也能让我们使用其它的命令以及一些特殊的可视模式命令。
在正常模式中输入 v
已进入可视模式(再次输入 v
即可关闭可视模式)。进入可视模式后,任何移动光标的命令除了将光标移动到新位置,沿途还会以高亮显示文本。而且,在可视模式中,Vim使用一些特有命令,方便我们借由选择光标附近的文本对象而选择文本:
countaw
,countaW
:选择count指定的单词数量。分隔单词的空格不视为一个词。小写的 w 将标点符号也视为一个词,而大写 W 只以空格作为单词的分隔符。countiw
,countiW
:和上条命令类似,只不过将分隔单词的空格也视为一个词(i 表示 inner object,不包含空格)as
, `is·:选择一个句子,或增加选择内部句子(inner sentence,不含句子边界)ap
,ip
:选择一个段落,或增加选择内部段落(inner paragraph,不含段落边界)a(
,a)
,ab
,i(
,i)
,ib
:选择()
中的内容(以 i 开头不含边界)a{
,a}
,aB
,i{
,i}
,iB
:选择()
中的内容(以 i 开头不含边界)a"
,a'
,i"
,i'
:选择相应引号中的内容(以 i 开头不含边界)
类似的还有选择 []
<>
中的内容。想要了解文本对象更多细节内容,可以使用帮助命令 :help text-objects
。