Chinaunix首页 | 论坛 | 博客
  • 博客访问: 659385
  • 博文数量: 175
  • 博客积分: 2457
  • 博客等级: 大尉
  • 技术积分: 1488
  • 用 户 组: 普通用户
  • 注册时间: 2011-07-13 20:31
文章分类

全部博文(175)

文章存档

2012年(22)

2011年(153)

分类:

2011-12-23 15:18:38

本节所用命令的帮助入口:

:help filetype
:help setfiletype
:help modeline
:help 'modelines'
:help 'shiftwidth'
:help 'expandtab'
:help autocmd

打开文件类型检测功能很简单,在你的vimrc中加入下面一句话就可以了:

filetype plugin indent on

如果你用的是VIM自带的示例vimrc,那么你已经打开了文件类型检测功能。或者,你也可以输入“:filetype”命令查看你的文件类型检测功能有没有打开。

这条命令究竟做了什么呢?我们在下面详细介绍。

其实,上面这一条命令,可以分为三条命令:

filetype on
filetype plugin on
filetype indent on

我们逐条介绍这三条命令。

filetype on”命令打开文件类型检测功能,它相当于文件类型检测功能的开关。在执行“filetype on”命令时,VIM实际上执行的是$VIMRUNTIME/filetype.vim脚本。这个脚本使用了自动命令(autocmd)来根据文件名来判断文件的类型,如果无法根据文件名来判断出文件类型,它又会调用$VIMRUNTIME/scripts.vim来根据文件的内容设置文件类型。有兴趣可以读一下这两个脚本,以获得更深的认识。

在上述步骤完成后,绝大多数已知类型的文件,都能被正确检测出文件类型。如果文件的类型未能被正确的检测出来,就需要手工设置文件类型,这可以通过“set filetype”完成,例如,如果你把main.c改名为main.c.bak1,那么它就无法被正确检测出文件类型。通过下面的Ex命令,就可以把它的文件类型设为c

:set filetype=c
或者,你可以在文件中加入一个模式行,来指明这个文件的类型。VIM在打开文件时,会在文件首、尾的若干行(行数由'modelines'选项决定,缺省为5行)检测具有VIM特殊标记的行,称为模式行。如果检测到,就使用模式行中定义的选项值,来修改该缓冲区的选项。你可以留意一下VIM的帮助页,每个文件的最后一行都是这样的模式行。

针对上例,我们可以在main.c.bak1的第一行或最后一行加上下面的内容,要指定这个文件的类型:

/* vim: ft=c */
这句话使用“/* */”注释起来了,因此不会影响编译。“ft”是“filetype”的缩写,VIM中很多命令、选项都有缩写形式,以方便使用。注意“/*”与“vim:”间的空格。在“*/”与“ft=c”间,也需要有至少一个空格,这是模式行格式的要求,更多信息参阅“:help modeline”。

检测出文件的类型有什么作用呢?我们知道,不同类型的文件具有不同的格式,VIM通过对文件类型的识别,可以为不同类型的文件,设置不同的选项值、定义不同键绑定等。例如,对于c类型的文件,它就和bash脚本有不同的注释格式、不同的缩进格式、不同的关键字等。VIM在设置文件类型后,会触发FileType事件,执行FileType相关的自动命令,对不同类型的文件区别对待。

上面提到的“filetype plugin on”,允许VIM加载文件类型插件。当这个选项打开时,VIM会根据检测到的文件类型,在runtimepath中搜索该类型的所有插件,并执行它们。

filetype plugin on”命令,实际上是执行$VIMRUNTIME/ftplugin.vim脚本,有兴趣可以读一下这个脚本。这个脚本中会设置自动命令,在runtimepath中搜索文件类型插件。

runtimepath的定义在不同的系统上不一样,对UNIX系统来说,这些路径包括:$HOME/.vim$VIM/vimfiles$VIMRUNTIME$VIM/vimfiles/after$HOME/.vim/after

举一个例子,当我们对一个c类型的文件打开“filetype plugin on”时,它会在上述这几个目录的ftplugin子目录中搜索所有名为c.vimc_*.vim,和c/*.vim的脚本,并执行它们。在搜索时,它按目录在runtimepath中出现的顺序进行搜索。缺省的,它会执行$VIMRUNTIME/ftplugin/c.vim,在这个脚本里,会设置c语言的注释格式、智能补全函数等等。

filetype indent on”允许VIM为不同类型的文件定义不同的缩进格式。这条命令也是通过一个脚本来完成加载:$VIMRUNTIME/indent.vim。和“filetype plugin on”类似,它也通过设置自动命令,在runtimepathindent子目录中搜索缩进设置。对c类型的文件来说,它只是打开了cindent选项。

我们了解了文件类型检测的用途及它是如何工作的之后,就可以根据自己的需要,来对特定的文件类型进行特殊设置。

例如,我们在上篇文章中介绍过lookupfile插件,在它打开一个缓冲区时,会把缓冲区的filetype设置为lookupfile,我们可以利用这一点,在这个缓冲区里进行一些特殊的配置。例如,我们创建一个名为lookupfile.vim的文件,其内容为:

" close lookupfile window by two
nnoremap q
inoremap q
它定义了两个局部于缓冲区的键绑定,无论在normal模式还是插入模式,只要连按两次ESC,就关闭当前缓冲区。

把这个文件保存到你的runtimepath所指向任一目录的ftplugin子目录中(一般是放在~/.vim/ftplugin目录中)。你在下次打开lookupfile窗口时,试试连按两次ESC,是不是lookupfile窗口就关闭了?这样设置,非常适合VIM中按ESC取消命令的习惯,效率也高。

如果你对VIM缺省文件类型插件的设置不太满意,那么可以把这个全局插件拷贝到$HOME/.vim/plugin目录中,然后更改其中的设置。你可以留意一下VIM缺省的文件类型插件,它们的头部都有这样的代码:

" Only do this when not done yet for this buffer
if exists("b:did_ftplugin")
  finish
endif
这类似于C语言头文件中的“#ifndef XXX | #define XXX”的语句,可以防止该插件被执行多次。因此,把这个插件拷贝到$HOME/.vim/plugin中(这个目录在runtimepath中排在最前面),它将先于VIM的缺省插件被加载;而它加载后,VIM的缺省文件类型插件就不会再被加载了。这就达到了我们修改设置的目的。

不过我们通常不用这种方法。如果这样做,一旦VIM的缺省插件做了改变,我们也要更新我们改过的插件才行。我们可以在载入全局插件以后否决一些设置。在Unix 上,我们可以把我们的设置放在~/.vim/after/ftplugin/目录中,这个目录中的脚本会在VIM的缺省脚本后执行。这样就可以修改配置,或增加我们自己的定义。

举个例子,在多人一起开发项目时,为了使代码风格尽量保持一致,一般不允许在代码使用TAB符,而以4个空格代之。我们可以编辑一个文件,包含下面的内容:

set shiftwidth=4
set expandtab
把这个文件保存为~/.vim/after/ftplugin/c.vim。这样,每次在编辑c文件时,它的自动缩进为4个空格;当你在插入模式下使用CTRL-DCTRL-T缩进时,它也会调整4个空格的缩进;当你按TAB键时,它将会插入8个空格……如果你想上面的设置对h文件也生效的话,需要把它另存一份:~/.vim/after/ftplugin/cpp.vim,因为h文件的文件类型被设为cpp

我们知道,VIM在设置文件类型时,会触发FileType自动命令,因此,上面的例子可以用下面的自动命令来实现:

autocmd FileType c,cpp set shiftwidth=4 | set expandtab
把这个命令放在你的vimrc中,可以起到和上例同样的效果。

VIM的语法高亮功能,也要用到文件类型,来对不同的关键字进行染色。这我们将在下一篇文章中介绍。

[参考文档]

1. VIM帮助文件

2.

 

阅读(511) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~