为何~/.vim/scripts.vim无法将Bash脚本的Vim文件类型设为bash?
问题背景
我正在解决Vim的一个问题:Bash脚本(非SH脚本)被自动分配为sh文件类型,而我希望它被识别为bash类型。
- 已确认Vim支持bash文件类型:执行
:setfiletype CTRL+d或:echo getcompletion('ba', 'filetype')可验证。 - 环境:Linux主机,
~/.vimrc仅包含filetype on,无~/.gvimrc文件。
已解决的场景:.bash后缀文件
编辑后缀为.bash的文件时,已通过创建~/.vim/filetype.vim解决文件类型设为bash的问题,配置如下:
Listing 1. ~/.vim/filetype.vim
" ~/.vim/filetype.vim if exists("did_load_filetypes") finish endif augroup filetypedetect au! BufRead,BufNewFile *.bash let b:is_bash = 1 | setfiletype bash augroup END
未解决的场景:带特定Shebang的无后缀文件
编辑首行为以下任意shebang的文本文件时,希望Vim将其文件类型设为bash而非sh,但此场景尚未解决:
#!/bin/bash #!/usr/bin/bash #!/bin/env bash #!/usr/bin/env bash
尝试过的无效方案
我按照Vim帮助文档new-filetype-scripts的说明创建~/.vim/scripts.vim,但脚本未生效,Vim仍将此类文件设为sh类型。先后尝试了多种写法:
1. 暴力设置版本
Listing 2. "Brute force" version of ~/.vim/scripts.vim (method 1)
" ~/.vim/scripts.vim setfiletype bash
Listing 3. "Brute force" version of ~/.vim/scripts.vim (method 2)
" ~/.vim/scripts.vim set filetype=bash
2. 基于帮助示例的正则匹配版本
Listing 4. ~/.vim/scripts.vim example based on the Vim help example new-filetype-scripts
if did_filetype() finish endif if getline(1) =~# '^#!.*/bin/env\s\<bash\>' setfiletype bash elseif getline(1) =~# '^#!.*/bin/bash' setfiletype bash endif
3. 精确字符串匹配版本
Listing 5. ~/.vim/scripts.vim whose if statements use "exact match" conditional expressions
if did_filetype() finish endif if getline(1) == '#!/bin/env bash' setfiletype bash elseif getline(1) == '#!/usr/bin/env bash' setfiletype bash elseif getline(1) == '#!/bin/bash' setfiletype bash elseif getline(1) == '#!/usr/bin/bash' setfiletype bash endif
疑问
Vim帮助明确说明scripts.vim会在默认文件类型检查前加载,规则优先级更高,但实际未生效。请问我存在哪些误解?为何~/.vim/scripts.vim无法将文件类型设为bash?
内容的提问来源于stack exchange,提问作者Jim Fischer

