How to highlight Bash scripts in Vim?
Solution 1
Are you correctly giving the shell script a .sh
extension? Vim's automatic syntax selection is almost completely based on file name (extension) detection. If a file doesn't have a syntax set (or is the wrong syntax), Vim won't automatically change to the correct syntax just because you started typing a script in a given language.
As a temporary workaround, the command :set syn=sh
will turn on shell-script syntax highlighting.
Solution 2
The answers so far are correct that you can use the extension (like .sh
) or a shebang line (like #!/bin/bash
) to identify the file type. If you don't have one of those, you can still specify the file type manually by using a modeline comment at the top or bottom of your file.
For instance, if you want to identify a script without an extension as a shell script, you could add this comment to the top of your file:
# vim: set filetype=sh :
or
# vim: filetype=sh
That will tell vim to treat the file as a shell script. (You can set other things in the modeline, too. In vim type :help modeline
for more info.)
Solution 3
Actually syntax highlighting is a feature of vim not vi. Try using vim command and then do
:syntax on
.
Solution 4
I came to this answer looking for specifically how to highlight bash
syntax, not POSIX shell. Simply doing a set ft=sh
(or equivalent) will result in the file being highlighted for POSIX shell, which leaves a lot of syntax that's valid in bash
highlighted in red. To get bash highlighting:
" 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
Note that if your ft
is already sh
, you still need the set
command; otherwise the let
doesn't take effect immediately.
You can make this a global default by making the variable global, i.e., let g:is_bash = 1
.
:help ft-sh-syntax
is the manual page I had to find; it explains this, and how to trigger highlighting of other flavors of shell.
Solution 5
Vim can also detect file types by inspecting their contents (like for example if the first line contains a bash shebang), here is a quote from filetype.txt
help file:
If your filetype can only be detected by inspecting the contents of the file
Create your user runtime directory. You would normally use the first item of the 'runtimepath' option. Example for Unix:
:!mkdir ~/.vim
Create a vim script file for doing this. Example:
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
See $VIMRUNTIME/scripts.vim for more examples. Write this file as "scripts.vim" in your user runtime directory. For example, for Unix:
:w ~/.vim/scripts.vim
The detection will work right away, no need to restart Vim.
Your scripts.vim is loaded before the default checks for file types, which means that your rules override the default rules in $VIMRUNTIME/scripts.vim.
Related videos on Youtube
never_had_a_name
Updated on March 13, 2021Comments
-
never_had_a_name about 3 years
My Vim editor auto highlights PHP files (
vim file.php
), HTML files (vim file.html
) and so on.But when I type:
vim file
and inside it write a Bash script, it doesn't highlight it.How can I tell Vim to highlight it as a Bash script?
I start typing
#!/bin/bash
at the top of the file, but it doesn't make it work. -
never_had_a_name about 14 yearsbut the most scripts dont have a .sh extension? should i put it as a .sh extension just to make it work? is it best practice to name your scripts? and its bash...so its still .sh?
-
Ralph Sinsuat about 14 years@ajsie: I'm not sure what scripts you're using, but most
bash
scripts I encounter do indeed have a.sh
suffix. To really specify bash as opposed to justsh
, you would use the#!/bin/bash
shebang line on a.sh
file. -
raimue over 12 yearsUhm, actually I wanted to post this somewhere else. But I guess the answer fits here as well :-)
-
orluke over 11 yearsInterestingly, in my environment, the final
:
makes this modeline work, whereas without the final:
, this modeline doesn't register. The help documentation shows a form of a modeline that does not end in:
. -
bryant over 11 yearsThat is interesting. The help documentation (with
:help modeline
) tells two differences: (1) The version with the final:
"is compatible with some versions of Vi", and (2) without the final:
you don't use theset
keyword. Since you can put any text after the modeline, the final:
works with or without theset
keyword. -
Eddy over 11 yearsI've tried both putting this in the .vimrc and .vim/scripts.vim, but neither has worked. It only works if I manually type in the commands once I've started vim. What am I doing wrong?
-
osirisgothra over 9 yearsjust type :set ft=sh and your good to go, OR, prefix your script with a modeline: "# vim:ft=sh" without the quotes of course, AND, i suggest getting something better than the sh filetype highlighter for bash scripts because it does not recognize things properly, some examples are ${VAR: 1:2} substrings, ;& or ;;& <- end-of-case modifiers, and many of the bash-specific keywords are not recognized either. Of course, dont get one that is crappy because there ARE SOME BAD ONES circulating around out there, ive used a couple that were way worse than the sh.vim default.
-
Sukima about 9 yearsIf a file does not have an extension (as many shell scripts used as commands do) then Vim will look at the first line to see a shebang of either
#!/bin/sh
or#!/bin/bash
to determine the file type eitherft=sh
orft=text
in the case no shebang exists. -
teu almost 9 yearsFor me too. You can add the line "syntax on" to your .vimrc file.
-
James Owers over 8 yearsThis was the solution for me on Mac OS X 10.10.3. Added a .vimrc file to my home directory using
vim ~/.vimrc
and addingsyntax on
to the file then closing with:x
-
Tino over 8 years
-
Tino over 8 years
-
Tino over 8 yearsAt my side
ft=bash
needs to readft=sh
. Also I neededset modeline
in~/.vimrc
to make it work, see this answer -
Charles Duffy almost 8 years@MarkRushakoff, giving bash scripts a
.sh
extension is in many circles considered poor form. See for instance the factoid bot used by the Freenode #bash channel's relevant entry: wooledge.org/~greybot/meta/.sh -
Charles Duffy almost 8 years...to quote: "Don't use extensions for your scripts. Scripts define new commands that you can run, and commands are generally not given extensions. Do you run
ls.elf
? Also: bash scripts are not sh scripts (so don't use.sh
) and the extension will only cause dependencies headaches if the script gets rewritten in another language. See talisman.org/~erlkonig/documents/…" -
Charles Duffy almost 8 years...extensions on shell scripts are universally accepted as a Good Idea when a script is intended to be sourced as a library (just as one uses a
.py
extension for Python modules but not Python scripts located in the PATH) -- but in that case the extension should correctly reflect which shell the script can be correctly parsed by;.sh
implies "compatible with all POSIX shells", which is not generally accurate for a bash script. -
Thanatos about 7 yearsThe
sh
syntax appears to highlight POSIX shell; it does not highlight Bash-specific syntax. -
Thanatos about 7 yearsAs I noted on the other answer that suggests this,
sh
appears to highlight POSIX shell, not bash. Notably, it flags valid bash syntax as errors, which is rather annoying. -
harry about 6 yearsSome versions of the
sh
syntax highlighter even mark valid posix sh code as invalid (e.g.$(subshell)
) - this corrects that too. Thanks. -
lacostenycoder about 5 yearslooks like this was fixed. This is the best answer IMHO.
-
D. Ben Knoble about 4 yearsThe command is
filetype on
, without set, and you also needsyntax enable
to turn on highlighting. -
superboot over 2 yearsThis is exactly what I came here looking for, and it works perfectly. Thank you very much.