From:http://blog.youkuaiyun.com/smstong/article/details/20567235
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来确定路径的。
- 编译时指定的系统级配置文件路径可以是绝对路径,也可能含有$VIM环境变量。
- 用户级别配置文件路径中含有环境变量$HOME。
- 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.
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 <bugzilla@redhat.com>
Compiled by <bugzilla@redhat.com>
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 root@apple.com
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 在实践中使用配置文件
3.1 添加或修改配置文件
set nu
set tabstop=4
set autoindent
这样我们以当前账户运行vim的时候,就会总是显示行号,tab键相当于4个空格的宽度,自动缩进。
3.2 添加插件文件
nmap <F10> ggODate:<Esc>:read !date<CR>kJ$
这样,启动vim后,就可以通过F10快捷键直接在首行输入当前的日期信息。