Search code examples
javascripthtmlvimformattingscript-tag

vim automatically formatting html files with tidy and <script> tag with Jsbeautifull


How can I format html files in vim using tidy and format just the contents of the script tags using Jsbeautifull?

I have this command: :%!tidy -i -xml --char-encoding utf8 --wrap 0 --show-errors 0 2>/dev/null for formatting html files,

and this :call g:Jsbeautify() for formatting the js file. How can I call g:Jsbeautifull() just on the contents of the script tags? Jsbeautifull(js_script, options) can take the js source as argument.

And I want to map it to <C-S-f>.


Solution

  • So when nobody answers my question, I had to learn some vim scripting and I made it!

    I have copied the ~/.vim/plugin/jsbeautify.vim to ~/.vim/plugin/jsbeautify_replace.vim and modify it. Here is a diff jsbeautify.vim jsbeautify_replace.vim:

    1c1
    < if &cp || exists("loaded_jsbeautify")
    ---
    > if &cp || exists("loaded_jsbeautify_replace")
    4c4
    < let loaded_jsbeautify = 3
    ---
    > let loaded_jsbeautify_replace = 3
    286,291c286
    < "function! g:Jsbeautify(js_source_text)
    < function! g:Jsbeautify()
    <   if !s:is_js()
    <       echo "Not a JS file."
    <       return
    <   endif
    ---
    > function! Jsbeautify_replace(js_source_text, indent)
    310c305
    <   let lines = getline(1, "$")
    ---
    >   "let lines = getline(1, "$")
    312,313c307,308
    <   let s:input = join(lines, "\n")
    <   "let s:input = a:js_source_text
    ---
    >   "let s:input = join(lines, "\n")
    >   let s:input = a:js_source_text
    617c612
    <   
    ---
    > 
    619,622c614,615
    <   :g/.*/d
    <   let @0 = ret
    <   :put!0
    < endfunction
    ---
    >   let lines = split(ret, '\n')
    >   let result = ""
    624c617,624
    < nnoremap <silent> <leader>ff :call g:Jsbeautify()<cr>
    ---
    >   for line in lines
    >       let result .= a:indent."  ".line."\n"
    >   endfor
    >   ":g/.*/d
    >   "let @0 = ret
    >   ":put!0
    >   return a:indent."<script type=\"text/javascript\">\n".result.a:indent."</script>"
    > endfunction
    

    And have written some script in ~/.vim/plugin/tidy_jsbeautify.vim:

    function! g:tidy_js()
        %!tidy -i -xml --char-encoding utf8 --wrap 0 --show-errors 0 2>/dev/null
        %s#\(\s*\)<script\_\s*type="text/[jJ]ava[sS]cript"\_\s*>\(\_.\{-1,}\)</script>#\= Jsbeautify_replace(submatch(2),submatch(1))#g
    endfunction
    

    This calls tidy on my buffer and then on all script tag contents the jsbeautify + the indent of the script tag will be added. And then in ~/.vim/ftplugin/html.vim:

    :map <buffer> <C-f> :call g:tidy_js()
    

    And now is my whole html file nicely formated just with a shortcut CTRL+F ENTER :)