TL;DR: vim seems to be sourcing both indent/javascript.vim
and indent/html.vim
on editing html files; is this intentional or a bug? How can I make html files only source html.vim
?
Recently I found out that vim seems to be using indent filetype plugins for both javascript and html on editing html files, and I've done some testing based on this behaviour on minimal vim configurations.
Here is my one-line .vimrc
:
filetype plugin indent on
Inside my .vim
directory:
~ % tree .vim
.vim
└── indent
├── html.vim
└── javascript.vim
1 directory, 2 files
Where:
~ % cat .vim/indent/javascript.vim
setlocal formatprg=js-beautify
let g:testvar_js="js testvar"
let g:testvar="testvar defined in javascript.vim"
and
~ % cat .vim/indent/html.vim
setlocal formatprg=html-beautify
let g:testvar_html="html testvar"
let g:testvar="testvar defined in html.vim"
Then I open up a new, empty vim buffer with vim foo.html
, and tested with some commands:
:set filetype?
filetype=html
:set formatprg?
formatprg=js-beautify
:echo g:testvar
testvar defined in javascript.vim
:echo g:testvar_html
html testvar
:echo g:testvar_js
js testvar
As if vim sources both indent filetype plugins, with indent/html.vim
first and then indent/javascript.vim
.
Therefore, my questions are:
- Did I make any silly mistakes?
- If no, then is this an intentional design, a bug, or is that vim has nothing to do with this at all?
- Is there a way to make vim only source on
html.vim
when editing html files?
Some additional information that might be helpful:
- I'm on vim 8.2, macOS arm64, using Terminal.app
- Neovim exhibits the same behaviour; actually that's where I first note it
- This behaviour does not occur for
ftplugin/
, onlyindent/
- javascript files are not affected by
indent/html.vim
: variables defined inindent/html.vim
are all undefined in a javascript buffer formatprg
of html files is alwaysjs-beautify
on open, regardless of if there are any javascript code pieces or<script>
tags inside that html file- An
indent/css.vim
will not be involved at all when editing html - I've tested js-beautify
andhtml-beautify
are two separate executables (repository is here)bin % ls -n js-beautify lrwxr-xr-x 1 501 80 53 Apr 19 17:59 js-beautify -> ../lib/node_modules/js-beautify/js/bin/js-beautify.js bin % ls -n html-beautify lrwxr-xr-x 1 501 80 55 Apr 19 17:59 html-beautify -> ../lib/node_modules/js-beautify/js/bin/html-beautify.js
If you want me to do some additional tests or need more information, just shout.
Many thanks
CodePudding user response:
Here is a perfectly valid HTML sample:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Sample</title>
<script>
console.log('Hello, World!');
</script>
<style>
body {
background: orange;
}
</style>
</head>
<body>
<h1>Sample</h1>
</body>
</html>
You will notice it has a tiny bit of embedded JavaScript in it, which is a good enough reason for $VIMRUNTIME/indent/html.vim
to source $VIMRUNTIME/indent/javascript.vim
. After all, the javascript
indent script is supposed to know how to indent JavaScript, so why not use it in a html
buffer that can contain embedded JavaScript?
FWIW, here is the snippet responsible for that behaviour:
if !exists('*GetJavascriptIndent')
runtime! indent/javascript.vim
endif
Note that the maintainers of $VIMRUNTIME/indent/html.vim
chose the external route for javascript
and the internal one for css
. Maybe because $VIMRUNTIME/indent/css.vim
didn't fit the bill? I don't know and, frankly, I don't think it matters.
Now, let's go through your mistakes…
Filetype-specific scripts (indent, syntax, ftplugins) are sourced in this order:
~/.vim/indent/<filetype>.vim
,$VIMRUNTIME/indent/<filetype>.vim
~/.vim/after/indent/<filetype>.vim
If you are not very careful, stuff you put in an earlier script might be overwritten when a later script is sourced. For that reason, it makes a lot more sense to put your own stuff in scripts under
after/
.The following lines have nothing to do in indent scripts:
setlocal formatprg=js-beautify setlocal formatprg=html-beautify
They are supposed to be in ftplugins:
" after/ftplugin/javascript.vim setlocal formatprg=js-beautify " after/ftplugin/html.vim setlocal formatprg=html-beautify
So…
Did I make any silly mistakes?
Yes, see above.
If no, then is this an intentional design, a bug, or is that vim has nothing to do with this at all?
Well yes, this is an intentional design that works pretty well. It only caused problems because you misused it.
Is there a way to make vim only source on
html.vim
when editing html files?
indent/html.vim
? Yes, it certainly is possible but why would you want to do that?ftplugin/html.vim
? It already works the way you want and it is the right place for the things you mistakenly put inindent/html.vim
to begin with.