第三章 Vim 常用命令 #
在第二章已经介绍了 VimL 语言的基本语法,理论上来说,就可以据此写出让 vim 解释 执行的合法脚本了。然而,能写什么的脚本呢?除了打印“Hello World!”,以及高级点的 用循环计算诸如“1+2+…+100”这样人家好像也能心算的题目外,还能干嘛呢?
所以,如果要让 vim 脚本真正有实用价值,还得掌握 vim 提供的内置命令,用以控制 Vim 或定制 Vim。本章就来介绍一些主要的、常用用的命令。
Vim 是个极高自由度的文本编辑软件,它在以下几个层级上给用户提供了自由度:
option选项。预设了一个很庞大的选项集,用户可以按自己的喜好设置每个选项的 值(当然很多选项也可以接受默认址而假装当它们不存在),这可能改变 Vim 的很多 基础表现与行为。map(快捷键)映射。一个非常简单但非常强大的机制。用户可以根据自己的习惯 来重新映射各种模式下不同按键(及按键序列)的解释意义。初入门的 Vimer 很容易 沉迷于折腾各种快捷键。command自定义命令。Vim 是基于 ex 命令的,然后允许又你自定义 Ex 命令。可 见这是比简单映射更灵活强大的利器,当然它的使用要求也比映射要高一些。VimL脚本。进一步将命令升级为脚本语言,据此开发插件,使得 Vim 的扩展性具 有无限可能。在 Vim 社区已经涌现了很多优秀插件,大多可以直接拿来用。当自己掌 握了 VimL 语言后,也就可以自己写些插件来满足自己的特殊需求或癖好。
本教程虽是旨在 VimL 脚本语言,但还是有必要从简单的选项说起吧。
3.1 选项设置 #
选项分类与设置命令 #
设置选项的命令是 set。根据选项值的不同情况,可以将选项分为以下三类:
- 不需要值的选项,或者说是 bool 型的开关切换状态的选项。这种选项有两个相对立
的选项名,分别用命令
:set option表示开启选项,:set nooption表示关闭选 项。例如:set number是设置显示行号,:set nonumber是设置不显示行号。 - 选项有一个值。用命令
:set option=value设定该类选项的值。选项值可以是数字 或字符串,但字符串的值也不能加引号,就按字面字符串理解。也就是说,:set后 面的参数,不是 VimL 的表达式,与:let命令有根本的不同。这个命令更像是shell设置变量的语法,=前后也最好不要用空格。 - 选项允许有多个值,值之间用逗号分隔。设置命令形如
:set option=val1,val2。 此外还支持+=增量与-=减量语法,如:set option+=val3或:set option-=val2,表示在原来的“值集合”的基础上增加某个值或移除某个值。
选项值变量 #
在选项名前面加个 & 符号,就将一个选项变成了相应的选项值变量。例如,以下两条
命令是等效的:
: set option=value
: let &option = value
与普通变量赋一样,= 前后的空格是可选的,这里的空格只是一种编程习惯,为增加
可读性。另外有以下几点要注意:
- 第一类选项,在用
:set命令时不需要等号,但是用:let &命令时也要用等号将 其值赋为 1 或 0,分别表示开启选项与关闭选项。同时&只允许作用在没有no前缀的选项之前。比如:let &nonumber = 1是非法的,只能用:let &number = 0表示相同意图。 - 第二类选项,如果值是字符串,用
:let &命令时要将值用引号括起来,也就像普 通变量赋值一样,要求等号后面是合法的表达式。 - 第三类选项,它的值也是一个由逗号分隔的(长)字符串,比如
:echo &rtp。并不 能由于这类选项支持多个值就将 VimL 的列表赋给它,不过很容易通过split()函 数从这类选项值中分隔出一个列表。
备注:选项设置 :set 应是历史渊源最早的命令之一吧。而 :let 是后来 VimL 语言
发展丰富起来提供的命令。两者有不一样的语法,所以又提供了这种等价转换方法。
vimrc 配置全局选项 #
严格地说,:set 是设置全局选项的命令。既是影响全局的选项,一般是要第一时间在
vimrc 中配置的。最重要的是以下两条配置:
: set nocompatible
: filetype plugin indent on
第一条配置是说不要兼容 vi,否则可能有很多 vim 的高级功能用不了。第二条配置
(虽然不是 set 选项)是用 Vim 编写程序源代码必要的,意思是自动检测文件类型,
加载插件,自动缩进的意思。除非在很老旧的机器上,或为了研究需要,一般都没理由不
加上这两条至关重要的配置。
下面再介绍一些比较重要的几类配置选项,当然这远远不够全面。查看选项的帮助命令是
:help options,查看某一个选项的帮助是在用单引号括起选项名作为帮助参数,例如
:help 'option'。查看某个选项的当前值是命令 :set option? 或 :echo &option
。
编码相关:encoding fileencodings fileencoding
- encoding 是 Vim 内部使用的编码。建议
:set encoding=utf-8。 - fileencodings 是打开文件时,Vim 用于猜测检测文件编码的一个编码列表。对中文
用户,建议
:set fileencodings=ucs-bom,utf-8,gb18030,cp936,latin1。 - fileencoding (局部选项),当前文件的编码,如果与 encoding 不同,在写入时 自动转码。用户一般不必手动设这个选项,除非你想用另外一种编码保存文件。
- encoding 是 Vim 内部使用的编码。建议
外观相关:number/relativenumber wrap statusline/tabline
- number 是在窗口左侧加一列区域显示行号,relativenumber 显示相对行号,即相对 光标所在的行的行号,当前行是 0,上面的行是负数,下面的行是正数。
- wrap 是指很长的文本行折行显示。一般良好风格的程序源文件不应出现长行,但 Vim 作为通用文件编辑器,不一定只用于编辑程序。
- statusline 是定制状态栏,格式比较复杂,建议查看文档,也有些插件提供了很炫 酷的状态栏。tabline 的定制格式与状态栏一样,在开多个标签页时才生效。
- laststatus 什么时候显示状态栏,建议用值
2表示始终显示状态栏。 - cmdheight 命令行的高度,默认只有 1 行太少,当命令行有输出时可能经常要多按 一个回车才回到普通模式。建议 2 行,更多就浪费空间了。
- wildmenu 这是在编辑命令行时,按补全键后,会临时在状态栏位置显示补全提示。
GUI外观:只在 gVim 或有 GUI 版本的 Vim 有效
- guioptions 设置 GUI 各部件(菜单工具栏滚动条等)是否显示。
- clipboard 设置剪切板与 Vim 的哪个寄存器关联。
颜色主题:
- colorscheme 这是个单独的命令,不是
set选项。选择一个颜色主题。颜色主题 是放在运行时各路径的colors/子目录的*.vim文件。 - background 背景是深色
dark或浅色light。有的 colorscheme 只适于深色或 浅色背景,有的则分别为不同背景色定义不同的颜色主题。 - term 与 t_Co 有的颜色主题可能还与终端与终端色数量有关。
- cursorline 与 cursorcolumn 用不格式高亮当前行与当前列,具体高亮格式由颜色 主题定义。个人建议只高亮 cursorline 。
- hlsearch 高亮搜索结果。
- colorscheme 这是个单独的命令,不是
格式控制:
- formatoptions 控制自动格式化文本的许多选项,建议看文档。
- textwidth 文本行宽度,超过该宽度(默认78)时自动加回车换回。在编辑程序源文 件时可用上个 formatoptions 选项控制只在注释中自动换行但代码行不自动换行。
- autoindent smartindent 插入模式下回车自动缩进。
- shiftwidth 缩进宽度。
- tabstop softtabstop 制表符宽度,软制表符是行首按制符缩进的宽度。一般建议 硬制表符宽度 tabstop 保持 8 不变,用 shiftwidth softtabstop 表示缩进。
- expandtab 插入制表符自动转为合适数量的空格。
- paste 将 Vim 的插入模式置于“粘贴”模式,从外部复制文本进 Vim 开启该选项可避 免一些副作用。但只建议临时开启该选项。
路径相关:
- runtimepath 运行时路径,简称(rtp)。vim 在运行时搜索脚本的一组路径。一般
不手动设置该值,如果有插件管理器管理插件的话。插件必须放在某个
&rtp路径 下,现在流行的是将插件工程主目录添加至 Vim 的&rtp中。 - packpath (Vim8开始才支持)动态加载插件的搜索路径,默认是
~/.vim/pack。 插件主目录可置于{packpath}/{packname}/opt/{plugin}。然后用:packadd启用插件。 - path 这是 vim 在寻找编辑文件,如
gf:find等命令时所要搜索的一组目录。 - tags 这是 vim 按标签跳转
Ctrl-]或:tag等命令所依据的标签文件,默认是./tags,tags(相对路径)。一般不建议修改默认值,但可以默认值基础上添加更 多的标签文件,比如编辑一个工程时,将工程主目录下的 tags 文件也加进来。 - autochdir 将当前路径自动切换到当前编辑的文件所在的目录。当你依赖一些管理工
程类的插件时,可能要求当前路径锁定在工程主目录,不宜开启该选项。但是个人喜
欢开启这插件,这样在用
:e命令打开同目录下的其他文件时很方便。
- runtimepath 运行时路径,简称(rtp)。vim 在运行时搜索脚本的一组路径。一般
不手动设置该值,如果有插件管理器管理插件的话。插件必须放在某个
Vim 所支持的选项实在是太多了。初学者建议参考前人经验成熟的配置,用 :help 查
看每个选项的具体含义,然后决定这种选项是否适合自己。另外注意有些选项可能要配合
起来才能发挥更好的效果。
VimL 控制局部选项 #
局部选项是只影响当前缓冲文件或窗口(buffer/window)的选项。严格来说是局部选项 值,而不是有另外一类选项。默认情况下每个新文件或窗口都继承选项的全局值,但对于 一些选项,可以为该文件或窗口设定一个不同与全局的局部值。然而并不是所有选项都有 局部值意义,在每个选项的帮助文档中,会指明该选项是全局(global)或局部的( local to buffer 或 local to window)。
设置局部选项(值)用 :setlocal 命令。如果目标选项没有局部值,则等效 :set
命令设置全局值。但是最好不要混用,避免误解。局部选项值变量用 &l:option 表示
。比如 number 行号就是个局部选项:
: set nonumber
: setlocal number
: echo &number
: echo &l:number
: echo &g:number
你可以将 vim 分裂出两个窗口(:split 或 :vsplit),在其中一个窗口上执行以上
语句,试试看结果。需要注意的是,虽然局部选项值借用了变量的局部作用域前缀 l:
,但它的默认规则又有点不同。看这里的 &number 是默认的 &l:number 而不是
&g:number。事实上,普通的局部变量 l:var 根本不能在函数外的命令行使用。
当用 VimL 写脚本时,如果要改变选项设置,且该选项支持局部值,最好用 :setlocal
只改变局部值。这也是编程的一大原则,尽量将影响局部化。下面介绍一些比较重要的局
部选项设置:
- 文件类型:filetype
- 大部分情况下,这个选项不用手写设,也不用脚本显式地设,打开自动检测就可以自 动根据后缀名设置相应的文件类型。不过在创建新的文件类型时,可能需要自己设置 这个选项。
- 文件类型插件,如
~/.vim/ftplugin/*.vim脚本内若涉及选项更改,也尽量用:setlocal只设局部选项。
- 缓冲类型:buftype
- “buffer type” 与 “file type” 是两个不同的概念。缓冲类型更加抽象,是 vim 内 部用于管理缓冲一些控制属性,而文件类型是着眼于文件内容性质的。
buftype的两个重要的选项值是nofile与nowrite,表示特殊的不用写文件 的 buffer,而这两者又还有细微差别,具体请读文档。
- 其他 buffer 属性:
- buflisted 是否将当前缓冲记录在缓冲列表中。
- bufhidden 当缓冲不再任一窗口展示,如何处理该缓冲,有几种不同的选项值。
- modifiable 当前缓冲是否可修改,包括更改编码与换行符格式也算种修改。
由于在 Vim 中,最主要的可见(可编辑)对象就只是 buffer,所以在一些复杂而细致的
插件中,经常会开辟一个辅助窗口,仅为展示辅助内容,这就往往要设置一个特殊的
buftype 及其他一些 buffer 属性。
此外,在脚本中,可能有需求只临时改变某个选项值,处理完毕后再恢复原选项设置,这 就要借且选项值变量了。处理流程大致如下:
: let l:save_option = &l:option
: let &l:option = ? |" 或者 setlocal option = ?
: " do something
: let &l:option = l:save_option