如何在Vim中突出显示Bash脚本?

92

我的 Vim 编辑器会自动高亮显示 PHP 文件 (vim file.php)、HTML 文件 (vim file.html) 等等。

但是当我输入命令 vim file 并在其中编写 Bash 脚本时,它不会对其进行高亮显示。

我该如何告诉 Vim 将其作为 Bash 脚本进行高亮显示?

我在文件顶部开始输入 #!/bin/bash,但这并不能使其正常工作。

13个回答

98

您是否正确地为Shell脚本添加了.sh扩展名?Vim的自动语法选择基本上完全基于文件名(扩展名)检测。如果文件没有设置语法(或语法不正确),Vim不会仅因为您开始输入特定语言的脚本而自动更改为正确的语法。

作为一种临时解决方法,命令:set syn=sh将打开Shell脚本语法高亮显示。


4
大多数脚本没有.sh扩展名?我是否应该将其命名为.sh以使其正常工作?最佳实践是给脚本命名吗?而且它是Bash脚本,所以还是.sh扩展名吗? - never_had_a_name
4
@ajsie:我不确定你使用的是什么脚本,但我遇到的大多数bash脚本确实都有.sh后缀。如果要真正指定bash而不仅仅是sh,则应在.sh文件上使用#!/bin/bash shebang行。 - Mark Rushakoff
5
在许多圈子中,给bash脚本加上“.sh”扩展名被认为是不好的做法。例如,Freenode #bash频道使用的factoid机器人相关条目中提到了这一点:http://wooledge.org/~greybot/meta/.sh。 - Charles Duffy
5
引用原文:"不要为你的脚本使用扩展名。脚本定义了新命令,你可以运行这些命令,而命令通常不会给出扩展名。你运行 ls.elf 吗?另外:Bash 脚本不是 sh 脚本(所以不要使用 .sh),并且扩展名只会在脚本被重写成另一种语言时引起依赖问题。请参见 http://www.talisman.org/~erlkonig/documents/commandname-extensions-considered-harmful" - Charles Duffy
5
当脚本被用作“库”时(就像使用.py扩展名表示Python“模块”,而不是位于PATH中的Python“脚本”),为脚本添加扩展名是一种广泛接受的好习惯。但在这种情况下,扩展名应正确反映脚本可以正确解析的shell类型;.sh表示“与所有POSIX shell兼容”,这通常不适用于bash脚本。 - Charles Duffy
显示剩余3条评论

49
到目前为止,回答中提到的使用扩展名(如.sh)或者shebang行(如#!/bin/bash)来识别文件类型是正确的。如果没有以上两种情况,你仍然可以在文件的顶部或底部加上modeline注释来手动指定文件类型。
例如,如果你想将没有扩展名的脚本文件识别为shell脚本,你可以在文件顶部加上以下注释:
# vim: set filetype=sh :
或者
# vim: filetype=sh

这将告诉vim将该文件视为shell脚本。(您还可以在modeline中设置其他内容。在vim中键入:help modeline以获取更多信息)。


1
有趣的是,在我的环境中,最后的:使得这个模型行起作用,如果没有最后的:,这个模型行将无法起作用。帮助文档显示了一个不以:结尾的模型行形式。 - orluke
1
这很有趣。帮助文档(使用:help modeline)指出了两个区别:(1)带有最终的:版本“与某些Vi版本兼容”,(2)没有最终的:,您不使用set关键字。由于您可以在modeline后放置任何文本,因此最终的:可以与或不与set关键字一起使用。 - bryant
2
如果模型行似乎没有效果,请在~/.vimrc中尝试set modeline,请参见此答案 - Tino
2
正如我在另一个建议中所指出的那样,sh似乎突出显示POSIX shell而不是bash。值得注意的是,它将有效的bash语法标记为错误,这非常令人恼火。 - Thanatos

28
实际上,语法高亮是vim而不是vi的一个功能。尝试使用vim命令,然后执行 :syntax on

1
对我也是一样。你可以在你的 .vimrc 文件中添加 "syntax on" 这行代码。 - teu
4
这是我在 Mac OS X 10.10.3 上的解决方法。使用命令 vim ~/.vimrc 在我的主目录中添加了一个 .vimrc 文件,并在文件中添加了 syntax on,然后用 :x 命令保存并退出。 - James Owers

24

我来到这个答案,特别是寻找如何突出显示 bash 语法,而不是 POSIX shell。仅仅执行 set ft=sh (或等效命令)会导致文件被标记为 POSIX shell,这将导致在 bash 中有效的许多语法以红色高亮显示。要获得 bash 高亮,请执行以下操作:

" Set a variable on the buffer that tells the sh syntax highlighter
" that this is bash:
let b:is_bash = 1
" Set the filetype to sh
set ft=sh

请注意,如果您的ft已经是sh,那么您仍然需要使用set命令;否则,let不会立即生效。

您可以通过将变量设置为全局变量来使其成为全局默认值,即let g:is_bash = 1

:help ft-sh-syntax是我必须找到的手册页面;它解释了这个问题,以及如何触发其他类型shell的高亮。


一些版本的 sh 语法高亮器甚至将有效的 posix sh 代码标记为无效(例如 $(subshell))- 这也进行了更正。谢谢。 - Mahmoud Al-Qudsi
1
这正是我在这里寻找的,而且它完美地运行。非常感谢你。 - superboot

17

Vim还可以通过检查文件内容(例如,如果第一行包含bash shebang)来检测文件类型。以下是filetype.txt帮助文件中的一句话:

如果只有检查文件内容才能确定文件类型

创建您的用户运行时目录。您通常会使用'runtimepath'选项的第一项。Unix的示例:

:!mkdir ~/.vim

创建一个 Vim 脚本文件来完成这个任务。示例:
if did_filetype()   " filetype already set..
    finish      " ..don't do these checks
endif
if getline(1) =~ '^#!.*\<mine\>'
    setfiletype mine
elseif getline(1) =~? '\<drawing\>'
    setfiletype drawing
endif

查看 $VIMRUNTIME/scripts.vim 以获取更多示例。在用户运行时目录中将该文件命名为“scripts.vim”。例如,对于Unix:

:w ~/.vim/scripts.vim

检测将立即生效,无需重新启动Vim。
您的scripts.vim在默认检查文件类型之前加载,这意味着您的规则会覆盖$VIMRUNTIME/scripts.vim中的默认规则。

1
我已经尝试将其放入 .vimrc 和 .vim/scripts.vim,但都没有起作用。只有在我启动 vim 后手动输入命令才有效。我做错了什么? - Eddy
@Eddy 可能你需要在 ~/.vimrc 中添加 set modeline,请参考这个回答 - Tino

10

Vim可以通过读取第一行来检测文件类型。将以下行添加为第一行。

#!/bin/sh

1
看起来这个问题已经被解决了。在我看来,这是最好的答案。 - lacostenycoder

4

对于那些有类似问题的人,即如何在没有.sh扩展名的情况下自动启用bash文件的语法突出显示...

在你的.vimrc中添加 filetype on。这还可以通过考虑文件内容来启用文件类型检测。例如,bash脚本将设置为sh文件类型。然而,在使用vim创建新文件时,输入#!将不会触发文件类型检测,此时您需要使用set ft=sh。要了解更多信息,请在vim中键入:h filetype

如评论中所述,您需要与syntax enable一起使用以启用突出显示。

或者您可以使用:filetype detect。 从文档中可以看到:

如果您使用空文件并输入可检测文件类型的文本,请使用此选项。例如,当您在shell脚本中输入以下内容:“#!/bin/csh”。


1
命令是 filetype on,不需要设置,你还需要 syntax enable 来打开语法高亮。 - D. Ben Knoble

2

1

在编辑器内切换语法高亮的开/关。

打开

:syntax on

关闭

:syntax off

运行此命令,使vim打开时始终启用语法高亮。
echo ":syntax on" >> ~/.vimrc

0
如果您在打开脚本之前已经知道文件类型,或者正在创建一个没有扩展名的新脚本(这很常见),您可以在命令行中将其传递给vim,如下所示:
vim -c 'setfiletype sh' path/to/script
vim -c 'setfiletype python' path/to/script

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接