我正在尝试解决 Vim 编辑器的一个恼人问题,其中 Bash 脚本(不是 SH 脚本)被分配文件类型
sh
而不是 bash
。 (出于我自己的目的,我希望文件类型为 bash
而不是 sh
。)
[注1。在 Vim 编辑器中,如果我输入
:setfiletype CTRL+d
:echo getcompletion('ba', 'filetype')
bash
列在可用/可识别的文件类型中。 —尾注]
[注2。我正在 Linux 主机上工作。对于下面的讨论,这两个 Vim 配置文件不存在:
~/.vimrc
~/.gvimrc
~/.vimrc
存在,并且仅包含一个命令:filetype on
~/.gvimrc
的文件。 —尾注]
场景 1) 当我使用 Vim 编辑文件扩展名为
.bash
的文件时,我希望 Vim 将文件类型 bash
而不是 sh
分配给文件的缓冲区。我通过创建文件 ~/.vim/filetype.vim
解决了这个问题,如清单 1 所示:
清单 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
场景2) 当我使用Vim编辑一个第一行为以下任意内容的文本文件时,
#!/bin/bash
#!/usr/bin/bash
#!/bin/env bash
#!/usr/bin/env bash
我希望 Vim 将文件类型
bash
,而不是 sh
,分配给文件的缓冲区。
这是我正在努力寻找解决方案的情况,并且希望获得一些帮助。
[注1。在接下来的讨论中,我删除了文件
~/.vim/filetype.vim
,以便它无法将文件类型 bash
分配给文件缓冲区的文件类型属性。 —尾注]
Vim 帮助主题 new-filetype-scripts 描述了创建用户定义的 Vim 脚本 (
~/.vim/scripts.vim
) 的过程,在我看来,这个解决方案应该可行。然而,当我尝试这种方法时,Vim 脚本没有任何效果。当 Vim 打开一个文本文件,其第一行(即 shebang 行 #!
)是上面显示的四行中的任何一行时,Vim 总是将文件类型 sh
分配给文件的缓冲区。
无论如何,我尝试了一种“强力”方法将文件类型设置为
bash
,如清单 2 和清单 3 所示,但 Vim 忽略了这一点,并将文件类型设置为 sh
:
清单 2. ~/.vim/scripts.vim 的“暴力破解”版本(方法 1)
" ~/.vim/scripts.vim
setfiletype bash
清单 3. ~/.vim/scripts.vim 的“暴力破解”版本(方法 2)
" ~/.vim/scripts.vim
set filetype=bash
Vim 帮助主题 new-filetype-scripts 明确指出,
你的scripts.vim在默认检查文件类型之前加载,这意味着你的规则会覆盖$VIMRUNTIME/scripts.vim中的默认规则。
所以,我不明白为什么 Vim 将文件缓冲区的 filetype 属性设置为
sh
而不是 bash
。
无论如何,我尝试创建一个基于 Vim 帮助主题 new-filetype-scripts 中显示的示例的 vim 脚本文件(参见 清单 4),但该版本也没有设置文件类型属性为
bash
:
清单 4. ~/.vim/scripts.vim 示例基于 Vim 帮助示例 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
当然,我尝试使用“完全匹配”字符串对
if
语句的条件表达式进行编码,如清单 5 所示。但与之前一样,文件缓冲区的 filetype 属性始终设置为 sh
而不是bash
:
清单 5. ~/.vim/scripts.vim 的 if 语句使用“完全匹配”条件表达式。
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
文件不将文件缓冲区的文件类型属性设置为 bash
?
$VIMRUNTIME/scripts.vim 负责委派你的scripts.vim,如果文件类型已经设置,它根本不会运行你的scripts.vim。
按照帮助文件中的另一个示例,
您还可以在命令中使用已检测到的文件类型。例如,要在检测到“pascal”时使用文件类型“mypascal”:
au BufRead,BufNewFile * if &ft == 'pascal' | set ft=mypascal | endif
怎么样:
au! BufRead,BufNewFile *
\ if &filetype == 'sh' && getline(1) =~# '\v^#!/(usr/)?bin/(env )?bash'
\ | set filetype=bash
\ | endif