今天遇到一个奇怪的问题:明明我在.vimrc中开启了expandtab选项,但是当我编辑Makefile文件时,敲入的TAB就是无法被VIM自动转换为四个空格(已经设置tabstop=4,shiftwidth=4),通过":set expandtab?"查看该选项值也居然是"noexpandtab";编辑其他文件(如.c、.h文件甚至是无扩展名的文件)时expandtab却都是开启的,TAB也可被自动转换,百思不得其解!

最初怀疑是compatible的设置对expandtab产生了影响。打开我的.vimrc,发现我设置的是“set nocompatible”,“compatible”已经被关掉,不会对expandtab产生影响。又想了想,假设受影响,那么所有文件都应该受到影响才对,不应该只有Makefile这类文件受影响。

想到这里,突然开了窍!是不是我开启的文件类型检测导致的呢?我在.vimrc设置了"filetype plugin on"。又看了一下这个设置的相关Manual,虽然没有直接给出答案,但是顺藤摸瓜,我也找到了原因。

因为开启了文件类型检测,Vim在打开或新建一个文件时会自动判断文件的扩展名以确定文件类型,在$VIMRUNTIME/filetype.vim中搜索"Makefile",可看到如下脚本语句:
" Makefile
au BufNewFile,BufRead *[mM]akefile,*.mk,*.mak,*.dsp setf make

Vim将Makefile划归为"make"类型(setf make)。在$VIMRUNTIME/ftplugin下有一堆xxx.vim文件,我们从中可以找到make.vim,这个文件就是VIM针对make类型文件的设置,在打开或新建make类型文件时被VIM自动加载。

这个make.vim文件中有一行设置如下:
" Make sure a hard TAB is used, required for most make programs
setlocal noexpandtab softtabstop=0

见文知义!果不其然,就是这个问题。又试验了一下,将.vimrc中的“filetype plugin on”注释掉,再打开Makefile文件,TAB就可以被自动转换为四个空格了。

回头一想,VIM针对make类型文件设置了noexpandtab也不无道理,编写过Makefile的朋友都知道,Makefile的基本组成结构就是:
target … : prerequisites …
    command
    …
    …
其中Makefile语法要求command前面必须放置一个TAB!否则解析失败!

这回真相大白了^_^

© 2010, bigwhite. 版权所有.

Related posts:

  1. 重新定制VIM
  2. VIM“重装上阵”
  3. Ubuntu扫盲
  4. Bash文件描述符重定向符号的另类理解
  5. 彻底迁移到Ubuntu