8

I was wondering which is the best way to use syntax folding for HTML files. Specially if it can recognize javascript code within <script> tags.

I typed set foldmethod=syntax but it does not seem to do any folding. Do I have to add something else to my .vimrc?

I know for javascript, for instance, I need to add let javaScript_fold=1 but I am unsure whether I have to add something similar for HTML.

Thanks!

  • 5
    Yes, the default HTML syntax script provides folding. Unless you use an alternative script, that's the way to do syntax folding. Can it recognize JavaScript? Why don't you simply try? So, what's your question?! – Ingo Karkat Mar 1 '15 at 20:10
  • You are right. I edited the question, I want to enable the default HTML syntax folding. Am I missing something? – Sergio Mar 2 '15 at 22:19
10

The 'foldmethod' is a window-local option; setting it from your ~/.vimrc doesn't necessarily have the right effect.

Because syntax folding is bound to the html filetype, these settings belong to ~/.vim/after/ftplugin/html.vim:

setlocal foldmethod=syntax

This depends on having filetype plugin on in your ~/.vimrc, which you probably have. You can also configure other related options there, e.g. foldcolumn=4.


Also note that so far (as of Vim 7.4.1830), the default HTML syntax script only folds a multi-line tag itself, not the text between the opening and closing tag.

So, this gets folded:

<div
    class="foo"
    style="width: 100"
>

But this doesn't:

<div>
    <b>stuff in between</b>
</div>

To get this, you need to extend the syntax script, e.g. via the following, best placed into ~/.vim/after/syntax/html.vim:

Alternative 1

Folding is performed between all but void html elements (those which don't have a closing sibling, like <br>). Contributed by @zanona; thanks!

syntax region htmlFold start="<\z(\<\(area\|base\|br\|col\|command\|embed\|hr\|img\|input\|keygen\|link\|meta\|para\|source\|track\|wbr\>\)\@![a-z-]\+\>\)\%(\_s*\_[^/]\?>\|\_s\_[^>]*\_[^>/]>\)" end="</\z1\_s*>" fold transparent keepend extend containedin=htmlHead,htmlH\d

Alternative 2

Folding is performed between certain explicitly named structural (e.g. <head>), paragraph-level (e.g. <p>, <li>) and ancillary (e.g. <script>) HTML tags.

syntax region htmlFold start="<\z(p\|h\d\|i\?frame\|table\|colgroup\|thead\|tfoot\|tbody\|t[dhr]\|pre\|[diou]l\|li\|span\|div\|head\|script\|style\|blockquote\|form\)\%(\_s*\_[^/]\?>\|\_s\_[^>]*\_[^>/]>\)" end="</\z1\_s*>" fold transparent keepend extend containedin=htmlHead,htmlH\d
  • Hey Ingo, I am not sure if I am doing anything wrong, but there is no way I can get any HTML folding based on syntax method, nothing happens? I have an expr custom method which I use, however that disabled syntax folding for css and javascript. When using syntax javascript and css have folds as expected but none of the HTML tags do? Any ideas? – zanona May 30 '16 at 20:27
  • 1
    @zanona: Are the HTML tags properly colored? Sometimes a bad CSS or JavaScript element breaks syntax for the remainder of the document. The SyntaxAttr.vim - Show syntax highlighting attributes of character under cursor plugin helps with troubleshooting. Check the syntax group of the (failing to fold) HTML tag, then check that the corresponding syntax rule has fold in it. – Ingo Karkat May 31 '16 at 6:45
  • Thanks Ingo! I will try that out. I have tried many variations of starting with a fresh html file, removing all the plugins, etc but I still have no folding under HTML. I will have a look on the plugin you sent. Hopefully that will be able to help debugging. Thanks again for your help. – zanona May 31 '16 at 20:28
  • 1
    @zanona: Thanks for the detailed analysis; I think I know now what the problem is. The default HTML syntax only does folding of multi-line tags itself, but you want folding of stuff in between opening and closing tags. That needs a simple extension of the syntax script; see my edit. I actually had this in my Vim config for so long that I forgot about it! – Ingo Karkat Jun 2 '16 at 6:20
  • 1
    @zanona: Thanks! Your idea of reversing the selection criteria for the HTML tags adds a nice touch. I've added that to the answer as a (better) alternative. – Ingo Karkat Jun 3 '16 at 7:00

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.