通过 VIM 可以自动设置对齐方式,例如使用 Tab 还是空格,使用四个字节还是八个字节等等,而且,可以根据不同的语言设置不同的格式。
空格 VS. 制表符
使用空格还是 Tab 在 Coders 中争论已久,使用空格代码格式就已经固定了,不会再因为设置的 Tab 宽度不同而影响美观;如果使用 Tab 且提前约定好了宽度,其实也是可以的,还会节省字节。
在 VIM 中,主要通过如下几个配置项来设置:
tabstop
设置 Tab 字符的显示宽度,并不影响 Tab 键的行为,需要关闭expandtab
选项,否则看不出来。softtabstop
会影响 Tab 键的行为,但是不修改 Tab 字符的宽度。expandtab
把插入的 Tab 转换为特定数目的空格。
其中 softtabstop
会影响插入模式中按下 Tab 键实际得到的字符,可能是插入指定数目的空格,也有可能就是一个 Tab 字符,根 tabstop
和 expandtab
的设置有关。
- 只使用空格,需要设置
expandtab
选项,插入模式中写入Tab
会转换为tabstop
个字符。 - 只使用
Tab
,需要关闭expandtab
选项,同时将softtabstop
和tabstop
设置为相同值。 - 混合模式,需要关闭
expandtab
选项,同时将softtabstop
设置为小于tabstop
的值,下面将详细介绍。
对于前两种方式不做过多介绍了,这里仅介绍最后一种场景,这种方式的使用场景不多,一般是,希望在编辑模式时使用 4 个空格宽度,但是对于一些注释等信息,仍然使用 8 个空格宽度。
例如配置为 softtabstop=4 tabstop=8
时,第一次按下 Tab
键会转换为 4 个空格,再次按下 Tab
键之后会显示一个 Tab
字符,宽度为 8 个空格。
制表符和空格转换
可以通过 :set expandtab/noexpandtab
命令设置使用空格替换/不进行替换 Tab,对于已保存的文件,可以使用下面的方法进行空格和 Tab 的替换。
----- TAB替换为空格
:set ts=4
:set expandtab
:%retab!
----- 空格替换为TAB
:set ts=4
:set noexpandtab
:%retab!
加 !
用于处理非空白字符之后的 TAB
,即所有的 TAB
,若不加 !
,则只处理行首的 TAB
。假设配置文件中使用了 set expandtab
,如果想要输入 TAB
,Linux 下使用 Ctrl-V + TAB
,Win 下使用 Ctrl-Q + TAB
。
缩进模式
包括了 autoindent
smartindent
cindent
几种方式,也就是在新增一行时如何进行处理,包括了在 insert
状态用回车新增一个新行,或者在 normal
状态用 o/O
插入新行,都会根据配置的不同模式,进行不同的缩进。
autoindent
会自动将当前行的缩进拷贝到新行,如果在新行没有输入任何字符,那么这个缩进将自动删除。smartindent
对autoindent
进行了一些改进,可以识别一些基本的语法,例如遇到}
则取消缩进,注释开头则不使用缩进。cindent
会识别语言的语法,自动地调整缩进的长度。
可以与上述配置共存。比如,当输入了半条语句然后回车时,缩进会自动增加一个 TABSTOP
值,当你键入了一个右花括号时,会自动减少一个 TABSTOP
值。
另外,可以通过 indentexpr
设置不同的模式,在此不详述,详见 vim reference manual 。
简介
通过 set list
可以在文本中显示当前格式,包括了 Tab、空格、换行等,与对齐相关配置可以通过如下方式配置。
set autoindent " 设置自动缩进
set smartindent " 对autoindent进行了一些改进
set shiftwidth=4 " 自动缩进所使用的空白长度
set tabstop=4 " 定义tab所等同的空格长度
set softtabstop=4 " 详见如下的解释
set expandtab " 将TAB自动替换为空格
set listchars=tab:▸\ ,trail:-,extends:>,precedes:<,eol:¬ " 设置不可见字符的显示方式
set nolist " 不显示TAB、空格、回车等不可见字符
filetype indent on " 可以通过如下的设置,根据文件类型自动进行设置
autocmd FileType python setlocal expandtab smarttab shiftwidth=4 softtabstop=4
autocmd FileType javascript,less set shiftwidth=2 | set tabstop=2 | set shiftwidth=2 | set expandtab
设置对齐方式
通过如下方式设置 C 语言的缩进方式,具体配置可查看 Vim documentation: indent 。
set cinoptions={0,1s,t0,n-2,p2s,(03s,=.5s,>;1s,=1s,:1s
常用命令
----- 执行缩进,前面可以加数字进行多节缩进
>> # Normal模式下,增加当前行的缩进
<< # Normal模式下,减少当前行的缩进
CTRL+SHIFT+T # Insert模式下,增加当前行缩进
CTRL+SHIFT+D # Insert模式下,减小当前行缩进
= # Visual模式下,对选中的部分进行自动缩进
: set list # 查看不可见字符,包括TAB、空格、回车等
问题排查
自动对齐失效
上述介绍的 cindent
smartindent
autoindent
是不依赖插件的,而通常根据代码类型的缩进是针对插件的,例如 /usr/share/vim/vim74/indent/c.vim
是针对 C 语言的,可以通过如下方式确认已经开启。
----- 默认会根据后缀自动识别,可以查看并手动设置
:set filetype
:set filetype=html
----- 默认不会开启根据文件类型加载缩进插件
:filetype indent on
有时候会发现自动对齐失效了,那么可以通过如下方式查看。
----- 确认是否正确时别文件类型
:set filetype
----- 文件类型缩进是否打开
:filetype
----- 对应文件类型是否加载,可以过滤或者导出到某个文件中
:filter /indent/ scriptnames
:redir > /tmp/vim.txt
:scriptnames
:redir END
----- 重新识别
:filetype detect
最佳实践
针对不同的语言会分别进行设置,如下是常见的规范。
" 两字节对齐,使用空格
autocmd FileType html setlocal expandtab ts=2 sw=2 sts=0
" 四个字节对齐,使用Tab
autocmd Filetype javascript,coffeescript setlocal ts=4 sw=4 sts=0 noexpandtab