How to highlight Bash scripts in Vim?

74,882

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.

Share:
74,882

Related videos on Youtube

never_had_a_name
Author by

never_had_a_name

Updated on March 13, 2021

Comments

  • never_had_a_name
    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
    never_had_a_name about 14 years
    but 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
    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 just sh, you would use the #!/bin/bash shebang line on a .sh file.
  • raimue
    raimue over 12 years
    Uhm, actually I wanted to post this somewhere else. But I guess the answer fits here as well :-)
  • orluke
    orluke over 11 years
    Interestingly, 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
    bryant over 11 years
    That 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 the set keyword. Since you can put any text after the modeline, the final : works with or without the set keyword.
  • Eddy
    Eddy over 11 years
    I'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
    osirisgothra over 9 years
    just 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
    Sukima about 9 years
    If 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 either ft=sh or ft=text in the case no shebang exists.
  • teu
    teu almost 9 years
    For me too. You can add the line "syntax on" to your .vimrc file.
  • James Owers
    James Owers over 8 years
    This was the solution for me on Mac OS X 10.10.3. Added a .vimrc file to my home directory using vim ~/.vimrc and adding syntax on to the file then closing with :x
  • Tino
    Tino over 8 years
    @Eddy Probably you need set modeline in ~/.vimrc, see this answer
  • Tino
    Tino over 8 years
    If the modeline seems to have no effect, try set modeline in ~/.vimrc, see this answer
  • Tino
    Tino over 8 years
    At my side ft=bash needs to read ft=sh. Also I needed set modeline in ~/.vimrc to make it work, see this answer
  • Charles Duffy
    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
    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
    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
    Thanatos about 7 years
    The sh syntax appears to highlight POSIX shell; it does not highlight Bash-specific syntax.
  • Thanatos
    Thanatos about 7 years
    As 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
    harry about 6 years
    Some versions of the sh syntax highlighter even mark valid posix sh code as invalid (e.g. $(subshell)) - this corrects that too. Thanks.
  • lacostenycoder
    lacostenycoder about 5 years
    looks like this was fixed. This is the best answer IMHO.
  • D. Ben Knoble
    D. Ben Knoble about 4 years
    The command is filetype on, without set, and you also need syntax enable to turn on highlighting.
  • superboot
    superboot over 2 years
    This is exactly what I came here looking for, and it works perfectly. Thank you very much.