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


76

Vim编辑器会自动突出显示PHP文件(vim file.php),HTML文件(vim file.html)等。

但是,当我键入:vim file并在其中编写一个Bash脚本时,它不会突出显示它。

如何告诉Vim将其突出显示为Bash脚本?

我开始#!/bin/bash在文件的顶部键入内容,但无法正常工作。

Answers:


85

您是否正确地给shell脚本.sh扩展名?Vim的自动语法选择几乎完全基于文件名(扩展名)检测。如果文件没有设置语法(或语法错误),Vim不会仅仅因为您开始以给定语言键入脚本而自动更改为正确的语法。

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


4
但是大多数脚本都没有.sh扩展名?我应该把它作为.sh扩展名只是为了使其工作吗?命名脚本是最佳做法吗?和它的重击...所以它仍然.sh?
never_had_a_name

3
@ajsie:我不确定您使用的是什么脚本,但是bash我遇到的大多数脚本确实都有.sh后缀。要真正指定bash而不是just sh,可以#!/bin/bash.sh文件上使用shebang行。
Mark Rushakoff'4

5
@MarkRushakoff,给bash脚本一个.sh扩展名,在许多圈子中都被认为是较差的形式。例如,请参阅Freenode #bash频道的相关条目所使用的事实
Charles Duffy,

4
...引用:“不要在脚本中使用扩展名。脚本定义了可以运行的新命令,并且命令通常没有扩展名。您可以运行ls.elf吗?而且:bash脚本不是sh脚本(所以不要使用.sh),并且扩展名只会在脚本用另一种语言重写时才引起依赖项的麻烦。请参阅talisman.org/~erlkonig/documents/…
查尔斯·达菲

3
...当打算将脚本作为库来源时,将Shell脚本的扩展名作为一个好主意被普遍接受(就像一个人使用.pyPython模块的扩展名,但不使用位于PATH中的Python脚本一样),但是在这种情况下扩展名应正确反映可以正确解析脚本的外壳程序;.sh暗示“与所有POSIX shell兼容”,这对于bash脚本通常不准确。
查尔斯·达菲

37

到目前为止,答案是正确的,您可以使用扩展名(如.sh)或shebang行(如#!/bin/bash)来标识文件类型。如果您没有这些文件,您仍然可以通过在文件顶部或底部使用Modeline注释来手动指定文件类型。

例如,如果您想将不带扩展名的脚本标识为Shell脚本,则可以将此注释添加到文件顶部:

# vim: set filetype=sh :

要么

# vim: filetype=sh

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


有趣的是,在我的环境中,final:使此modeline工作,而没有final :,此modeline不会注册。帮助文档显示了不以结尾的Modeline形式:
orluke 2012年

这太有趣了。帮助文档(带有:help modeline)说明了两个区别:(1)带有最终:“与Vi的某些版本兼容”的版本,以及(2)没有最终版本的:您不使用set关键字。由于您可以在modeline之后放置任何文本,因此:无论是否带有set关键字,最终作品都可以使用。
bryant 2012年

2
如果模式似乎没有任何效果,尝试set modeline~/.vimrc,看到这个答案
蒂诺

2
正如我在暗示此问题的另一个答案上所指出的那样,它sh似乎突出了POSIX shell,而不是bash。值得注意的是,它将有效的bash语法标记为错误,这很烦人。
塔纳托斯(Thanatos)

23

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

:syntax on


1
我也是 您可以在“ .vimrc”文件中添加“ syntax on”行。
teu

4
这是我在Mac OS X 10.10.3上的解决方案。使用添加一个.vimrc文件到我的主目录,vim ~/.vimrc并添加syntax on到该文件,然后关闭:x
James Owers 2015年

18

我来到这个答案,专门寻找如何突出显示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是我必须找到的手册页;它解释了这一点,以及如何触发其他口味的贝壳的突出显示。


某些sh语法突出显示版本甚至将有效的posix sh代码标记为无效(例如$(subshell)),这也可以进行更正。谢谢。
Mahmoud Al-Qudsi '18

15

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可能您需要set modeline使用~/.vimrc,请参阅此答案
Tino



1

对于那些对此问题有所了解的人,例如,如何.sh在打开时自动对bash文件启用语法突出显示功能而无需扩展名...

加入filetype on您的.vimrc。这还可以通过考虑文件内容来进行文件类型检测。例如,bash脚本将设置为sh文件类型。但是,键入#!不会触发使用vim创建的新文件的文件类型检测,set ft=sh在这种情况下,您将需要使用它。有关更多信息,请输入:h filetypevim。

如评论中所述,您需要结合使用此功能syntax enable以打开突出显示。

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

如果您从一个空文件开始,然后键入文本来检测文件类型,请使用此选项。例如,当您在外壳程序脚本中输入“#!/ bin / csh”时。


1
该命令是filetype on,未设置,您还需要syntax enable打开突出显示。
D. Ben Knoble

0

默认情况下,vim已经可以识别许多文件类型。它们中的大多数都以文件扩展名工作,但是在这种情况下,vim还将分析文件的内容以猜测正确的类型。

VIM将像特定文件名的文件类型.bashrc.tcshrc自动等。但是带有.sh扩展名的文件将被识别为csh,ksh或bash脚本。为了确定这到底是哪种脚本,vim读取文件的第一行以查看#!。线。

如果第一行包含单词bash,则该文件被标识为bash脚本。通常,您会看到#!/bin/bash脚本是否打算直接执行,但是对于shell配置文件,使用简单脚本也可以# bash

如果您想查看细节,可以在中实现$VIMRUNTIME/filetype.vim


嗯,实际上我想将此发布到其他地方。但我想答案也适合这里:-)
raimue 2011年

0

在新文件上突出显示语法的最简单方法可能是在编写shebang行后重新加载它。一个简单的方法:w :e将写出文件,重新加载它,并解释您刚刚编写的shebang行,以为您提供适当的语法突出显示。


0

如果您在打开脚本之前已经知道文件类型,或者正在创建没有常见扩展名的新脚本,则可以在命令行上将其传递给vim,如下所示:

vim -c 'setfiletype sh' path/to/script
vim -c 'setfiletype python' path/to/script

-1

当您创建一个新文件时,只有文件名检测起作用。#!/bin/bash如果在创建新缓冲区后键入内容检测(),则内容检测()不适用。

明智的做法是,:set ft=bash第一次执行,下次编辑时,#!/bin/bash将自动设置正确的文件类型。


1
在我这边ft=bash需要阅读ft=sh。此外,我需要set modeline~/.vimrc让它工作,看到这个答案
蒂诺
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.