Highlighting in vim: distinguish the lines with comment delimiter followed by special string

In some cases, for example with the scripts for HPC clusters, when using SGE, TORQUE or Slurm we can have a shell script (like bash) with comment lines denoted by # but grid commands in lines with #$, #PBS, or #SBATCH.

What is an easy way to keep the same highlighting used for bash but excluding #SomeString from being considered a comment?


Start by examining the definitions for comments in the shell syntax script:

:syn list shComment
--- Syntax items ---
shComment      xxx match /^\s*\zs#.*$/  contains=@shCommentGroup
                match /\s\zs#.*$/  contains=@shCommentGroup
                match /#.*$/  contained contains=@shCommentGroup
                links to Comment

Extend syntax cluster

There, you see what patterns for comments need to be overridden. But wait! That syntax script offers an extension mechanism via the :help :syn-cluster; the contains=@shCommentGroup

syn match shHPC "PBS" contained

That would highlight PBS anywhere inside a comment. If additional stuff can follow, append .*$ to the pattern. If the PBS keyword must directly follow the #, add a positive lookbehind assertion:

syn match shHPC "#\@<=PBS" contained

You can all the other keywords via additional :syn match commands, or by using regular expression branches: "#\@<=\(PBS\|SBATCH\|...\)".

Finally, that new syntax group has to be included in the syntax cluster for comments, and given a highlighting so you see it:

syn cluster shCommentGroup add=shHPC
hi link shHPC PreProc

Define overriding syntax match

Alternatively, you may want to skip the cluster and overwrite the comment syntax. For example, when the special keywords can only appear at the beginning of the line, but now after Bash commands. Or if you can't stand the fact that the cluster method will keep the # in the original highlighting.

syn match shHPC "^\s*\zs#PBS"
hi link shHPC PreProc


As these commands extend the built-in syntax, they need to be executed after them. The place for that is ~/.vim/after/syntax/sh.vim. If you want to only conditionally activate them for certain projects, you can write a filetype detection that sets a marker variable, e.g. b:is_HPC, and then make the above code check that flag.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.