3.1 选项设置

    选项分类与设置命令

    设置选项的命令是 set。根据选项值的不同情况,可以将选项分为以下三类:

    1. 不需要值的选项,或者说是 bool 型的开关切换状态的选项。这种选项有两个相对立 的选项名,分别用命令 :set option 表示开启选项,:set nooption 表示关闭选 项。例如 :set number 是设置显示行号,:set nonumber 是设置不显示行号。
    2. 选项有一个值。用命令 :set option=value 设定该类选项的值。选项值可以是数字 或字符串,但字符串的值也不能加引号,就按字面字符串理解。也就是说,:set 后 面的参数,不是 VimL 的表达式,与 :let 命令有根本的不同。这个命令更像是 shell 设置变量的语法,= 前后也最好不要用空格。
    3. 选项允许有多个值,值之间用逗号分隔。设置命令形如 :set option=val1,val2。 此外还支持 += 增量与 -= 减量语法,如 :set option+=val3:set option-=val2,表示在原来的“值集合”的基础上增加某个值或移除某个值。

    选项值变量

    在选项名前面加个 & 符号,就将一个选项变成了相应的选项值变量。例如,以下两条 命令是等效的:

    : set option=value
    : let &option = value
    

    与普通变量赋值一样,= 前后的空格是可选的,这里的空格只是一种编程习惯,为增加 可读性。另外有以下几点要注意:

    1. 第一类选项,在用 :set 命令时不需要等号,但是用 :let & 命令时也要用等号将 其值赋为 1 或 0,分别表示开启选项与关闭选项。同时 & 只允许作用在没有 no 前缀的选项之前。比如 :let &nonumber = 1 是非法的,只能用 :let &number = 0 表示相同意图。
    2. 第二类选项,如果值是字符串,用 :let & 命令时要将值用引号括起来,也就像普 通变量赋值一样,要求等号后面是合法的表达式。
    3. 第三类选项,它的值也是一个由逗号分隔的(长)字符串,比如 :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 不同,在写入时 自动转码。用户一般不必手动设这个选项,除非你想用另外一种编码保存文件。
    • 外观相关: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 高亮搜索结果。
    • 格式控制:

      • 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 命令打开同目录下的其他文件时很方便。

    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 的两个重要的选项值是 nofilenowrite,表示特殊的不用写文件 的 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