Vim bash syntax highlighting with modeline

2.6k views Asked by At

According to much online documentation (e.g.), I should be able to enable bash syntax highlighting via modelines by adding a line like:

# vim:let g:is_bash=1:set filetype=sh:

And in .vimrc:

filetype plugin indent on
syntax on
set modeline
set modelines=4

Unfortunately, when I add those lines I receive an error message:

"packer/shunit2/include.sh" 85L, 2749C
Error detected while processing modelines:
line   85:
E518: Unknown option: let 

Where line 85 is of course the modeline from above. (And it is the last line in the file.)

Why does this not work despite so many pages suggesting that it should, and what does the error message mean, and how can I change this setup so that my bash scripts open with correct bash syntax highlighting?

2

There are 2 answers

1
Ingo Karkat On BEST ANSWER

No, that answer is wrong. You cannot define variables in a modeline, only (certain) options can be set there (for security reasons).

To achieve bash syntax highlighting, you have the following options:

  • Globally let g:is_bash = 1 in your ~/.vimrc. This is the easiest option, but only works if all you ever edit is Bash (not Korn shell or any other shell dialect).
  • Properly set the shebang to #!/bin/bash; the $VIMRUNTIME/syntax/sh.vim will then automatically detect it.
  • Write custom detection of Bash files. If you can do this according to the file location / name, :autocmd BufNew,BufRead {pattern} let b:is_bash = 1 will do. If you need to inspect the file contents, put the code in ~/.vim/ftplugin/sh_bashdetection.vim or so.
  • If all your Bash files are in certain projects / directories, a local vimrc plugin (I recommend the localrc plugin (especially with my own enhancements), which even allows local filetype-specific configuration). With that, you can put the command (let b:is_bash = 1) into a .lvimrc file in the root of that project, and it'll automatically apply the settings to all files within that subdirectory tree.
  • If you really want to go the modeline route, the let-modeline plugin enables this.
0
Hauleth On

Modeline doesn't allow you to run any code, just setting options. What you are trying to do is to run some Vimscropt that will set global variable. That's not gonna happen.