关于VIM自动缩进失效(filetype indent on无效)的详细分析

来源:互联网 发布:mysql 标记锁 解除 编辑:程序博客网 时间:2024/05/05 15:27

最近用vim编辑一些xml和html文件,在某些版本的VIM上出现了不能根据文件类型自动缩进的问题,经过多次试验摸索,总算是找到了症结所在,特此记录下来供大家参考。

1 vim 自动缩进原理

vim不依赖于插件的情况下也能支持几种简单的缩进,例如

:set cindent:set smartindent:set autoindent

这些缩进方式是与文件类型无关系的,对于程序员来说用处不大,毕竟向我这样的码农编辑的都是特定类型的文件,如C、C++源文件、html文件,php文件等。

这种于特定文件类型相关联的缩进叫做filetype indent,对于每一种文件类型都要有一个对应的插件文件来支持,例如:对于c源码,对应的缩进支持插件为

/usr/share/vim/vim74/indent/c.vim

对于php源码,对应的缩进支持插件为:

/usr/share/vim/vim74/indent/php.vim

VIM本身能够根据编辑的文件名字后缀来探测文件类型,例如VIM会把test.html探测确定为html文件类型。当然我们也可以手动为VIM指定当前编辑文件的类型:

:set filetype=html

这主要用于一些没有文件名后缀的文件。

默认情况下,VIM并不会自动根据文件类型来加载对于的缩进插件。需要如下命令开启自动加载功能:

:filetype indent on

打开这个开关后,VIM将会根据文件类型自动加载对应的缩进插件,从而用户就可以享受自动缩进功能了。

2 缩进失效的现象与分析

2.1 现象

今天新建立了一个名为test.xml的文件,但是在用vim编辑时却无法实现自动缩进。

之后通过命令确认vim正确的识别了文件类型:

输入 :set filetype输出 filetype=xml

然后查看文件类型缩进开关是否打开:

输入 :filetype输出 filetype detection:ON  plugin:ON  indent:OFF 

好像找到原因了,原来文件类型缩进开关没打开。马上使用如下命令开启之。

:filetype indent on  

然后再查看:

输入 :filetype输出 filetype detection:ON  plugin:ON  indent:ON

这下确认了,文件类型缩进已经开启。

到目前为止,(1)文件类型已经识别;(2)文件类型缩进已经开启。然而不能自动缩进的问题仍然存在,没有丝毫改变。

2.2 分析

一开始还以为是版本的问题,后来在Linux和Mac上都进行了同样的试验,结果一样,均都是无法自动缩进。

剩下最后的办法了,看看缩进插件是否被VIM加载了。运行如下命令查看已经加载的插件:

输入 :scriptenames输出  1: /etc/vimrc  2: /usr/share/vim/vim74/syntax/syntax.vim  3: /usr/share/vim/vim74/syntax/synload.vim  4: /usr/share/vim/vim74/syntax/syncolor.vim  5: /usr/share/vim/vim74/filetype.vim  6: /usr/share/vim/vim74/ftplugin.vim  7: ~/.vimrc  8: /usr/share/vim/vim74/plugin/getscriptPlugin.vim  9: /usr/share/vim/vim74/plugin/gzip.vim 10: /usr/share/vim/vim74/plugin/matchparen.vim 11: /usr/share/vim/vim74/plugin/netrwPlugin.vim 12: /usr/share/vim/vim74/plugin/rrhelper.vim 13: /usr/share/vim/vim74/plugin/spellfile.vim 14: /usr/share/vim/vim74/plugin/tarPlugin.vim 15: /usr/share/vim/vim74/plugin/tohtml.vim 16: /usr/share/vim/vim74/plugin/vimballPlugin.vim 17: /usr/share/vim/vim74/plugin/zipPlugin.vim 18: /usr/share/vim/vim74/syntax/xml.vim 19: /usr/share/vim/vim74/syntax/dtd.vim 20: /usr/share/vim/vim74/ftplugin/xml.vim 21: /usr/share/vim/vim74/indent.vim

可见,并没有找到xml的缩进插件 /usr/share/vim/vim74/indent/xml.vim。难道没有这个文件?通过文件系统查看这个插件文件确实存在,只是VIM并没有加载它。

这就奇怪了,VIM为什么不加载它呢?难道是VIM的BUG?非也!通过实验发现,filetype indent on 这个命令只能打开文件类型缩进开关,并不能触发VIM去加载对应的缩进插件。 只有VIM在识别文件类型时,才能触发加载此插件,而实际的过程中,VIM在识别xml文件类型时,filetype indent 是关闭的,所以那个时候没有加载缩进插件。当后来 filetype indent on 开启时,VIM并不会重新去识别文件类型,也就没有加载缩进插件。

知道了这个原因,我们就可以手动让VIM重新去识别文件类型,从而触发加载缩进插件的动作。

:set filetype=xml

试验发现,此时VIM仍然不会去加载缩进插件,因为之前VIM已经识别成了XML类型,上述命令并没有改变它,所以VIM不会有任何动作。

总而言之,VIM加载文件类型缩进插件的条件是:在VIM识别文件类型动作之前,filetype indent 必须已经处于 on 状态。

3 解决方法

知道了原因,解决起来就非常简单了。有两种方式来解决这个问题:
(1)把 filetype indent on 这个命令加入 /etc/vimrc 启动配置文件,因为VIM会首先加载这个文件,然后才会去识别文件类型,所以能保证识别文件类型之前已经把filetype indent 置于 on。
(2)执行如下命令,强迫VIM重新识别文件类型。

:set filetype=php:set filetype=xml

或者

:filetype detect

首先把文件类型强制改为php,然后再改回xml,这样文件类型就发生了变化,从而导致VIM重新识别,进而加载缩进插件。

此时,再查看VIM已经加载的插件,发现xml缩进插件确实已经被加载:

输入 :scriptenames输出  1: /etc/vimrc  2: /usr/share/vim/vim74/syntax/syntax.vim  3: /usr/share/vim/vim74/syntax/synload.vim  4: /usr/share/vim/vim74/syntax/syncolor.vim  5: /usr/share/vim/vim74/filetype.vim  6: /usr/share/vim/vim74/ftplugin.vim  7: ~/.vimrc  8: /usr/share/vim/vim74/plugin/getscriptPlugin.vim  9: /usr/share/vim/vim74/plugin/gzip.vim 10: /usr/share/vim/vim74/plugin/matchparen.vim 11: /usr/share/vim/vim74/plugin/netrwPlugin.vim 12: /usr/share/vim/vim74/plugin/rrhelper.vim 13: /usr/share/vim/vim74/plugin/spellfile.vim 14: /usr/share/vim/vim74/plugin/tarPlugin.vim 15: /usr/share/vim/vim74/plugin/tohtml.vim 16: /usr/share/vim/vim74/plugin/vimballPlugin.vim 17: /usr/share/vim/vim74/plugin/zipPlugin.vim 18: /usr/share/vim/vim74/syntax/xml.vim 19: /usr/share/vim/vim74/syntax/dtd.vim 20: /usr/share/vim/vim74/ftplugin/xml.vim 21: /usr/share/vim/vim74/indent.vim 22: /usr/share/vim/vim74/indent/xml.vim

当然,xml缩进功能也非常正常了。

0 0