Vim语法不一致地突出显示bash文件
当我用vim打开一些bash脚本文件时,它有时会将它们标识为Vim语法不一致地突出显示bash文件,vim,syntax-highlighting,vim-syntax-highlighting,Vim,Syntax Highlighting,Vim Syntax Highlighting,当我用vim打开一些bash脚本文件时,它有时会将它们标识为conf文件,没关系,我可以通过使用:setf sh将文件类型设置为sh来纠正这一点 太好了,不过我注意到这并不能完全解决问题: 请注意,shopt在左侧正确高亮显示,但在右侧没有,我在右侧手动将文件类型设置为sh 这意味着,当vim将文件标识为bash或sh时,它会将文件类型设置为sh,但随后会执行一些额外的步骤,这是我手动设置文件类型时没有执行的步骤 有人知道这可能是什么,以及我如何修复它吗?尝试查看有效的语法设置 :windo
conf
文件,没关系,我可以通过使用:setf sh
将文件类型设置为sh
来纠正这一点
太好了,不过我注意到这并不能完全解决问题:
请注意,shopt
在左侧正确高亮显示,但在右侧没有,我在右侧手动将文件类型设置为sh
这意味着,当vim将文件标识为bash
或sh
时,它会将文件类型设置为sh
,但随后会执行一些额外的步骤,这是我手动设置文件类型时没有执行的步骤
有人知道这可能是什么,以及我如何修复它吗?尝试查看有效的语法设置
:windo echo b:current_syntax
(我希望第一个窗口显示bash
,第二个窗口显示sh
。)
还可以尝试使用synatx同步:
:windo syn sync fromstart
:windo syn sync minlines=300
大体上
:he syn-sync
更多信息
附言 长镜头,但其他一些突出显示可能会干扰:
:windo se @/=''
:match none
:2match none
:3match none
事实证明,
syntax/sh.vim
包括对Korn、Bash和sh的特定突出显示,您只需告诉它您正在使用哪个。这分别通过b:is_kornshell
、b:is_bash
和b:is_sh
完成
根据具体情况,我想我将使用以下方法:
ftdetect/bash.vim:
模型线:
键映射
nmap b:let g:is_bash=1:setf sh
默认情况下,vim已经识别了许多文件类型。它们中的大多数都是通过文件扩展名工作的,但在这种情况下,vim还将分析文件的内容以猜测正确的类型
vim自动为特定文件名设置文件类型,如.bashrc
、.tcshrc
等。但是扩展名为.sh
的文件将被识别为csh、ksh或bash脚本。为了确定这到底是什么类型的脚本,vim读取文件的第一行以查看#!线路
如果第一行包含单词bash
,则该文件被标识为bash脚本。通常你会看到#/bin/bash
如果要直接执行脚本,那么对于其他一些shell配置文件,应该使用文件扩展名.bash
vim中的帮助在
:help ft bash syntax
中也解释了这一点。您还可以在.vimrc中使用let g:is_bash=1
使bash语法突出显示所有文件的默认值filetype=sh
。如果您想查看详细信息,这是在$VIMRUNTIME/filetype.vim
中实现的,类似于Peter Coulton的解决方案,并在“filetype”vim帮助的“new filetype”部分中记录了该解决方案。~/.vim/filetype.vim
文件可能包含以下代码:
if exists("did_load_filetypes")
finish
endif
augroup filetypedetect
au! BufRead,BufNewFile *bash* let b:is_bash = 1 | setfiletype sh
augroup END
这种方法具有以下含义:
~/.vim/ftdetect
目录下,每个文件类型都有一个~/.vim/filetype.vim
文件,而不是一个b:is\u bash
变量称为g:is\u bash
将其设置为缓冲区的本地变量,而不是全局变量+1个甜点!modeline方法将是我的最爱。(如果我真的很在意这样的小偏差:)@Peter Coulton:你不是想将
b:is_bash
变量设置为缓冲区的局部变量,而不是g:is_bash
变量的全局变量吗。至少您的代码片段没有反映这种情况。您还可以将两个au
命令连接在一起,方法是在第一个命令末尾加上let b:is_bash=1 | setfiletype sh
。我不认为每次加载文件名为“bash”的文件时设置全局值有什么好处,而只需在中设置一次.vimrc
并完成它。不幸的是,在这个用例中,无法在modeline.Non-ideal中设置变量。全局启用g:is_bash=1
为所有非bash shell脚本缓冲区(例如Bourne、Korn)启用特定于bash的语法高亮显示,这很糟糕。本地启用b:is_bash=1
是非常可取的。同样,每个文件类型ftdetect/
文件在很大程度上已被统一所有文件类型检测的单个filetype.vim
文件淘汰。对于解决这两个问题的解决方案,请参阅。我将此标记为答案,因为它很好地解释了原因,并提供了一个完全合理的解决方案。我还添加了一个答案,详细说明了我自己的解决方案。虽然介绍性概要很有帮助,但给出的解决方案(例如,.vimrc
中的let g:is_bash=1
)没有帮助。为什么?因为这样做会强制非Bash shell脚本缓冲区(例如,Bourne、Korn)使用Bash特定的语法高亮显示。换个角度考虑。@ CeCulCury,这就是为什么我添加了一个公平的警告,它会影响到每个文件的<代码>文件类型= SH < /代码>。实际上,我刚刚复制了:help ft bash syntax
建议添加到.vimrc
中的内容,以使其成为全局默认值。它不会对所有shell文件强制使用此语法。一个更具体的shebang,比如#/bin/ksh
仍将覆盖此默认选择,因此我无法重现您的担忧。
# vim:let g:is_bash=1:set filetype=sh:
nmap <silent> <leader>b :let g:is_bash=1<cr> :setf sh<cr>
if exists("did_load_filetypes")
finish
endif
augroup filetypedetect
au! BufRead,BufNewFile *bash* let b:is_bash = 1 | setfiletype sh
augroup END