0

Stated Purpose

I'm trying to override Vim's HTML attribute indent behavior. This question is specific to ft=html.

Vim has always inserted too many spaces when indenting HTML:

<div>
    <div style="
                background-color: red;
                ">
    </div>
</div>

I'd rather Vim insert fewer indentation characters when indenting attribute strings:

<div>
    <div style="
        background-color: red;
    ">
    </div>
</div>

The indent of the "> line would be nice to have, but it's not necessary.

Caveat: Vim will indent the <div> with the attribute differently if its start tag is on the first line of the file.

What I've tried

The code in indent/html.vim seems to indicate that I can override how many spaces attributes are indented by declaring a my own function b:html_indent_tag_string_func:

" indent/html.vim line 921
if exists('b:html_indent_tag_string_func')
    return b:html_indent_tag_string_func(lnum)
endif

Try 1: I tried adding function! b:html_indent_tag_string_func(lnum) in ~/.vim/ftplugin/html/vars.vim, but that's a syntax error:

E884: Function name cannot contain a colon: b:html_indent_tag_string_func(lnum)

Try 2: I also tried function! html_indent_tag_string_func(lnum), another syntax error:

E128: Function name must start with a capital or "s:": html_indent_tag_string_func(lnum)

Try 3: Then I tried using a variable in the b: space:

" ~/.vim/ftplugin/html/vars.vim
function! Html_indent_tag_string_func(lnum)
    return shiftwidth() + indent(a:lnum - 1)
endfunction
let b:html_indent_tag_string_func='Html_indent_tag_string_func'

However this always sets the indent to 0 without errors printed. I found out that this is because b:html_indent_tag_string_func is not :call-able; running :echo b:html_indent_tag_string_func(3) gives the error:

E1085: Not a callable type: b:html_indent_tag_string_func

How do I make this work?

1 Answer 1

0

I figured it out. One can turn a function into a first-class datatype using let var = function(<name>):

" ~/.vim/ftplugin/html/vars.vim
function! s:my_html_indent_tag_string_func(lnum)
    return shiftwidth() + indent(a:lnum - 1)
endfunction
let b:html_indent_tag_string_func=function('s:my_html_indent_tag_string_func')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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