实践中学习vim之vim配置文件、插件文件加载路径

0 引言

理解vim的启动过程对于增强使用vim的信心非常重要,本文所有的信息均来自vim自身提供的参考手册和作者实际操作实践。VIM REFERENCE MANUAL的Starting Vim这节详细描述了vim的启动过程。vim完整的启动过程非常复杂,因为要兼容不同的平台,不同的运行模式。本文只考虑Windows, Mac OS X, Linux平台上最常见的启动流程。

1 vim启动初始化流程

(1)设置内部变量shell和term

vim根据环境变量$SHELL和$TERM设置这两个内部变量(option).

(2)处理命令行参数

命令行参数包括选项和要打开的文件名,vim为每一个文件开辟内存空间。

(3)加载系统级别和用户级别的配置文件

    (a) 根据编译时指定的路径,加载系统级别vimrc配置文件

    (b) 根据编译时指定的路径或默认路径,加载用户级别的vimrc配置文件

(4)加载插件文件

    根据runtimepath内部变量的值加载。所有runtimepath中的所有目录下名为plugin的子目录们下面所有以.vim结尾的文件都会被加载执行。

(5)设置shellpipe和shellredir内部变量

(6)如果命令行参数有-n,则设置updatecount内部变量

(7)如果命令行参数有-b,则设置二进制相关的多个内部变量

(8)执行GUI部分的初始化

(9)如果viminfo不为空,则读取指定的viminfo文件,恢复上次的编辑环境

(10)如果命令行参数有-q,则读取quickfix文件

(11)打开显示所有的窗口

(12)执行用户指定的启动时命令

可以看出,vim的启动初始化流程非常复杂。本文我们只关心配置文件的加载部分,这也是与大多数vim使用者直接相关的部分。从上面的流程看出:

  • vim加载系统级配置文件是根据编译时指定的路径加载的;
  • 用户级配置文件则可以在编译时指定,也可以不指定,如果不指定,则使用默认值。默认值对于不同的平台是不同的。
    • 对于unix平台:$HOME/.vimrc
    • 对于Windows平台:$HOME/_vimrc,如果不存在,则使用$VIM/_vimrc
  • 插件文件是根据runtimepath来确定路径的。
仔细分析就会发现,其实这里面还有很多不确定的东西:
  1. 编译时指定的系统级配置文件路径可以是绝对路径,也可能含有$VIM环境变量。
  2. 用户级别配置文件路径中含有环境变量$HOME。
  3. runtimepath的默认值如下:对于Unix平台: $HOME/.vim, $VIM/vimfiles, $VIMRUNTIME, $VIM/vimfiles/after,$HOME/.vim/after;对于Window平台:$HOME/vimfiles,$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after, $HOME/vimfiles/after.
可见除了编译时通过绝对路径指定的系统级配置文件vimrc之外的所有其他情况下的配置文件路径都严重依赖于环境变量的设置。问题是用户如果在运行vim之前没有设置这些环境变量,vim该如何是好呢?

2 配置文件路径的确定

2.1 编译时指定的路径

在编译vim源码的时候,需要指定各种配置文件的路径。如果最终用户不是当初执行编译的人如何知道这些信息呢?编译后的二进制vim可执行文件,自身包含了当初编译的时候指定的配置信息。我们可以通过执行vim --version来查看,如下是三个实例,一个是CentOS6.4下自带vim的编译时信息,另一个是Mac OS X 10.1系统自带vim的编译时信息,第三个是Windows8.1平台安装的vim官方7.4二进制版本。

【CentOS自带vim的编译时配置信息】

[root@localhost test]# vim --version
VIM - Vi IMproved 7.2 (2008 Aug 9, compiled Apr  5 2012 10:12:47)
Included patches: 1-411
Modified by <[email protected]>
Compiled by <[email protected]>
Huge version without GUI.  Features included (+) or not (-):
+arabic +autocmd -balloon_eval -browse ++builtin_terms +byte_offset +cindent
-clientserver -clipboard +cmdline_compl +cmdline_hist +cmdline_info +comments
+cryptv +cscope +cursorshape +dialog_con +diff +digraphs -dnd -ebcdic
+emacs_tags +eval +ex_extra +extra_search +farsi +file_in_path +find_in_path
+float +folding -footer +fork() +gettext -hangul_input +iconv +insert_expand
+jumplist +keymap +langmap +libcall +linebreak +lispindent +listcmds +localmap
+menu +mksession +modify_fname +mouse -mouseshape +mouse_dec +mouse_gpm
-mouse_jsbterm +mouse_netterm -mouse_sysmouse +mouse_xterm +multi_byte
+multi_lang -mzscheme -netbeans_intg -osfiletype +path_extra +perl +postscript
+printer +profile +python +quickfix +reltime +rightleft -ruby +scrollbind
+signs +smartindent -sniff +startuptime +statusline -sun_workshop +syntax
+tag_binary +tag_old_static -tag_any_white -tcl +terminfo +termresponse
+textobjects +title -toolbar +user_commands +vertsplit +virtualedit +visual
+visualextra +viminfo +vreplace +wildignore +wildmenu +windows +writebackup
-X11 -xfontset -xim -xsmp -xterm_clipboard -xterm_save
   system vimrc file: "/etc/vimrc"
     user vimrc file: "$HOME/.vimrc"
      user exrc file: "$HOME/.exrc"
  fall-back for $VIM: "/usr/share/vim"
Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H     -O2 -g -pipe -Wall  -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i686 -mtune=atom -fasynchronous-unwind-tables -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64  -D_FORTIFY_SOURCE=1    -D_REENTRANT -D_GNU_SOURCE  -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64  -I/usr/lib/perl5/CORE  -I/usr/include/python2.6 -pthread
Linking: gcc   -Wl,-E -Wl,-rpath,/usr/lib/perl5/CORE   -L/usr/local/lib -o vim       -lselinux  -lncurses -lacl -lgpm   -Wl,-E -Wl,-rpath,/usr/lib/perl5/CORE  -fstack-protector -L/usr/local/lib  -L/usr/lib/perl5/CORE -lperl -lresolv -lutil -lc -L/usr/lib/python2.6/config -lpython2.6 -lutil -lm -Xlinker -export-dynamic
[root@localhost test]#

【Mac OS X自带vim的编译时配置信息】

smstongtekiMac-mini:~ smstong$ vim --version
VIM - Vi IMproved 7.3 (2010 Aug 15, compiled Aug 24 2013 18:58:47)
Compiled by [email protected]
Normal version without GUI.  Features included (+) or not (-):
-arabic +autocmd -balloon_eval -browse +builtin_terms +byte_offset +cindent
-clientserver -clipboard +cmdline_compl +cmdline_hist +cmdline_info +comments
-conceal +cryptv +cscope +cursorbind +cursorshape +dialog_con +diff +digraphs
-dnd -ebcdic -emacs_tags +eval +ex_extra +extra_search -farsi +file_in_path
+find_in_path +float +folding -footer +fork() -gettext -hangul_input +iconv
+insert_expand +jumplist -keymap -langmap +libcall +linebreak +lispindent
+listcmds +localmap -lua +menu +mksession +modify_fname +mouse -mouseshape
-mouse_dec -mouse_gpm -mouse_jsbterm -mouse_netterm -mouse_sysmouse
+mouse_xterm +multi_byte +multi_lang -mzscheme +netbeans_intg -osfiletype
+path_extra -perl +persistent_undo +postscript +printer -profile +python/dyn
-python3 +quickfix +reltime -rightleft +ruby/dyn +scrollbind +signs
+smartindent -sniff +startuptime +statusline -sun_workshop +syntax +tag_binary
+tag_old_static -tag_any_white -tcl +terminfo +termresponse +textobjects +title
 -toolbar +user_commands +vertsplit +virtualedit +visual +visualextra +viminfo
+vreplace +wildignore +wildmenu +windows +writebackup -X11 -xfontset -xim -xsmp
 -xterm_clipboard -xterm_save
   system vimrc file: "$VIM/vimrc"
     user vimrc file: "$HOME/.vimrc"
      user exrc file: "$HOME/.exrc"
  fall-back for $VIM: "/usr/share/vim"
Compilation: gcc -c -I. -D_FORTIFY_SOURCE=0 -Iproto -DHAVE_CONFIG_H -arch i386 -arch x86_64 -g -Os -pipe
Linking: gcc -arch i386 -arch x86_64 -o vim -lncurses
smstongtekiMac-mini:~ smstong$

【Windows8.1 安装的vim官方二进制vim7.4编译配置信息】

VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Aug 10 2013 14:33:40)
MS-Windows 32 位控制台版本
编译者 mool@tororo
大型版本 无图形界面。  可使用(+)与不可使用(-)的功能:
+arabic          +ex_extra        -mouseshape      +tag_binary
+autocmd         +extra_search    +multi_byte      +tag_old_static
-balloon_eval    +farsi           +multi_lang      -tag_any_white
-browse          +file_in_path    -mzscheme        -tcl
++builtin_terms  +find_in_path    -netbeans_intg   -tgetent
+byte_offset     +float           +path_extra      -termresponse
+cindent         +folding         -perl            +textobjects
+clientserver    -footer          +persistent_undo +title
+clipboard       +gettext/dyn     -postscript      -toolbar
+cmdline_compl   -hangul_input    +printer         +user_commands
+cmdline_hist    +iconv/dyn       -profile         +vertsplit
+cmdline_info    +insert_expand   -python          +virtualedit
+comments        +jumplist        -python3         +visual
+conceal         +keymap          +quickfix        +visualextra
+cryptv          +langmap         +reltime         +viminfo
+cscope          +libcall         +rightleft       +vreplace
+cursorbind      +linebreak       -ruby            +wildignore
+cursorshape     +lispindent      +scrollbind      +wildmenu
+dialog_con      +listcmds        +signs           +windows
+diff            +localmap        +smartindent     +writebackup
+digraphs        -lua             -sniff           -xfontset
-dnd             +menu            +startuptime     -xim
-ebcdic          +mksession       +statusline      -xterm_save
+emacs_tags      +modify_fname    -sun_workshop    -xpm_w32
+eval            +mouse           +syntax          
     系统 vimrc 文件: "$VIM\vimrc"
     用户 vimrc 文件: "$HOME\_vimrc"
 第二用户 vimrc 文件: "$HOME\vimfiles\vimrc"
 第三用户 vimrc 文件: "$VIM\_vimrc"
      用户 exrc 文件: "$HOME\_exrc"
  第二用户 exrc 文件: "$VIM\_exrc"
编译方式: cl -c /W3 /nologo  -I. -Iproto -DHAVE_PATHDEF -DWIN32   -DFEAT_CSCOPE       -DWINVER=0x0400 -D_WIN32_WINNT=0x0400  /Fo.\ObjCi386/ /Ox /GL -DNDEBUG  /Zl /MT -DDYNAMIC_ICONV -DDYNAMIC_GETTEXT -DFEAT_BIG /Fd.\ObjCi386/ /Zi
链接方式: link /RELEASE /nologo /subsystem:console /LTCG:STATUS oldnames.lib kernel32.lib advapi32.lib shell32.lib gdi32.lib  comdlg32.lib ole32.lib uuid.lib /machine:i386 /nodefaultlib  libcmt.lib   user32.lib             /PDB:vim.pdb -debug

可以看出,不同版本的vim,其编译时指定的配置文件路径并不相同。除了CentOS平台的vim使用绝对路径指定/etc/vimrc为其系统配置文件以外,其他的平台及配置文件均依赖于环境变量$VIM和$HOME。

2.2 环境变量的确定步骤

先来看$VIM,大部分用户在使用vim前并没有手动去设置这个环境变量,而vim仍然正确的找到了配置文件,这是如何做到的呢?vim内部按照如下顺序查找或者定义$VIM,一旦有一个步骤成功,那么后面的步骤就会忽略掉。

(1)如果操作系统平台定义了$VIM环境变量,则直接使用;

(2)如果helpfile变量的值不包含其他的环境变量,则使用这个变量值来确定。实际上helpfile的默认值是$VIMRUNTIME/doc/help.txt,也就是说包含一个环境变量,所以默认情况下不能通过helpfile来确定。

(3)对于Windows平台,vim使用自身的可执行文件所在的位置来确定。我们前面Windows平台的例子中,vim就是在这一步确定的$VIM,其值为:VIM=C:\Program Files (x86)\Vim。

对于*inx平台,使用编译时指定的安装路径来确定(也就是前面vim --version结果中显示的"fall-back for $VIM" 。前面Mac OS X和CentOS平台的vim都是在这一步确定的$VIM,其值均为VIM=/usr/share/vim。


再来看$VIMRUNTIME。这个环境变量一般不需要用户去设置,而是让vim自身去猜测。下面是猜测步骤:

(1)如果用户定义了$VIMRUNTIME环境变量,直接使用;

(2)如果$VIM/vim{版本号}这个路径存在,那么使用它作为$VIMRUNTIME的值;

(3)如果$VIM/runtime存在,使用它作为$VIMRUNTIME的值;

(4)使用$VIM的值作为$VIMRUNTIME的值,这是vi时期的兼容模式;

(5)如果helpfile内部变量不包含环境变量,则使用helpfile来推导$VIMRUNTIME。

对于我们前面的三个平台,都是在第(2)步骤确定了$VIMRUNTIME的值。


最后来看$HOME,这个对于unix类环境来说,一般都会设置的,无需多说。

3 在实践中使用配置文件

通过前面的分析,我们弄清楚了vim配置文件及插件文件的加载时机与加载路径。接下来就可以根据这些知识来定制属于我们自己的配置了。

3.1 添加或修改配置文件

配置文件的主要作用是修改vim的默认行为以满足个性化需求,也就是修改vim内部变量的默认值。vim分为系统级配置文件和用户级配置文件。vim的手册推荐用户自定义的配置放入用户自定义文件中。我们以CentOS平台下的vim为例。用户级配置文件路径为:$HOME/.vimrc。在这个文件里增加如下代码:
  set nu
  set tabstop=4
  set autoindent

这样我们以当前账户运行vim的时候,就会总是显示行号,tab键相当于4个空格的宽度,自动缩进。

3.2 添加插件文件

插件文件的主要作用是增强vim的功能,也就是创造新的功能而不是修改已有的功能。从前面的分析,我们知道插件文件可以存在很多路径下。我们以/usr/share/vim/vim72/plugin目录下为例。在这个目录下随便新建一个文本文件test.vim。内容如下:
nmap <F10> ggODate:<Esc>:read !date<CR>kJ$
这样,启动vim后,就可以通过F10快捷键直接在首行输入当前的日期信息。

其实vim配置文件和插件文件所支持的语法完全一样,只是人为的按照功能作用分开存储了,两者都支持vim的专用脚本语言VimScript,关于vimscript的使用超出了本文的范畴,作者本人也尚未掌握,以后学习的时候再做记录。

你可能感兴趣的:(实践中学习vim之vim配置文件、插件文件加载路径)