├── img └── spacebars.png ├── ftdetect └── spacebars.vim ├── example.spacebars ├── ftplugin └── spacebars.vim ├── syntax └── spacebars.vim ├── README.md └── indent └── html.vim /img/spacebars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Slava/vim-spacebars/HEAD/img/spacebars.png -------------------------------------------------------------------------------- /ftdetect/spacebars.vim: -------------------------------------------------------------------------------- 1 | if has("autocmd") 2 | au BufNewFile,BufRead *.html,*.spacebars,*.mustache,*.handlebars,*.hbs,*.hogan,*.hulk,*.hjs set filetype=html syntax=spacebars | runtime! ftplugin/spacebars.vim ftplugin/spacebars*.vim ftplugin/spacebars/*.vim 3 | endif 4 | -------------------------------------------------------------------------------- /example.spacebars: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{title}} 6 | 7 | {{!}} 8 | 9 | 10 |
11 |

Mustache Showdown

12 | 13 | Basic mustache {{hello}} 14 | {{ hello}}, {{hello }} and {{ hello }} are OK 15 | 16 | {{d d d}} 17 | 18 | {{Everything will be hilighted here}} 19 | 20 | Mustaches hilighted in 21 | attribute value 22 | 23 | {{#repo align="left"}} 24 | This is an mustache [enumerable] section 25 | {{! some comments inside}} 26 |
  • {{ name }}
  • 27 | {{else}} 28 | ... 29 | {{/repo}} 30 | 31 | Inverted sections are supported too 32 | {{^repo somethingElse}} 33 | No repos :( 34 | {{/repo}} 35 | 36 | You can {{{yield}}} here 37 | 38 | {{! <> this is a comment TODO:}} 39 | 40 | This is a partial {{> partial1 arg="1" }} 41 | Yet another partial {{< partial2 }}, for ctemplate 42 | 43 | {{=<% %>=}}Sorry, cusomized delimiter not handled yet<%={{}}=%> 44 | 45 | {{#if some_helper}} 46 | And here is an example of handlebars if... 47 | {{else}} 48 | ... with optional else added. Try matchit `%` command over if/else/if. 49 | {{/if}} 50 | 51 | {{#with dataContext}} 52 | ... 53 | {{else}} 54 | ... 55 | {{/with}} 56 | 57 | Thanks goes to {{@defunkt}} 58 | Feedback/blames go to {{@juvenn}} 59 | {{Frustrations}} go to /dev/null 60 |
    61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /ftplugin/spacebars.vim: -------------------------------------------------------------------------------- 1 | let s:cpo_save = &cpo 2 | set cpo&vim 3 | 4 | " Matchit support for Mustache & Handlebars 5 | " extending HTML matchit groups 6 | if exists("loaded_matchit") && exists("b:match_words") 7 | let b:match_words = b:match_words 8 | \ . ',{:},[:],(:),' 9 | \ . '\%({{\)\@<=#\s*\%(if\|unless\)\s*.\{-}}}' 10 | \ . ':' 11 | \ . '\%({{\)\@<=\s*else\s*}}' 12 | \ . ':' 13 | \ . '\%({{\)\@<=/\s*\%(if\|unless\)\s*}},' 14 | \ . '\%({{\)\@<=[#^]\s*\([-0-9a-zA-Z_?!/.]\+\).\{-}}}' 15 | \ . ':' 16 | \ . '\%({{\)\@<=/\s*\1\s*}}' 17 | endif 18 | 19 | if exists("g:mustache_abbreviations") 20 | inoremap {{{ {{{}}} 21 | inoremap {{ {{}} 22 | inoremap {{! {{!}} 23 | inoremap {{< {{<}} 24 | inoremap {{> {{>}} 25 | inoremap {{# {{#}}{{/}} 26 | inoremap {{if {{#if }}{{/if}} 27 | inoremap {{ife {{#if }}{{else}}{{/if}} 28 | endif 29 | 30 | 31 | " Section movement 32 | " Adapted from vim-ruby - many thanks to the maintainers of that plugin 33 | 34 | function! s:sectionmovement(pattern,flags,mode,count) 35 | norm! m' 36 | if a:mode ==# 'v' 37 | norm! gv 38 | endif 39 | let i = 0 40 | while i < a:count 41 | let i = i + 1 42 | " saving current position 43 | let line = line('.') 44 | let col = col('.') 45 | let pos = search(a:pattern,'W'.a:flags) 46 | " if there's no more matches, return to last position 47 | if pos == 0 48 | call cursor(line,col) 49 | return 50 | endif 51 | endwhile 52 | endfunction 53 | 54 | nnoremap [[ :call sectionmovement('{{','b','n',v:count1) 55 | nnoremap ]] :call sectionmovement('{{','' ,'n',v:count1) 56 | xnoremap [[ :call sectionmovement('{{','b','v',v:count1) 57 | xnoremap ]] :call sectionmovement('{{','' ,'v',v:count1) 58 | 59 | 60 | " Operator pending mappings 61 | 62 | onoremap ie :call wrap_inside() 63 | onoremap ae :call wrap_around() 64 | xnoremap ie :call wrap_inside() 65 | xnoremap ae :call wrap_around() 66 | 67 | function! s:wrap_around() 68 | " If the cursor is at the end of the tag element, move back 69 | " so that the end tag can be detected. 70 | while getline('.')[col('.')-1] ==# '}' 71 | execute 'norm h' 72 | endwhile 73 | 74 | " Moves to the end of the closing tag 75 | let pos = search('}}','We') 76 | if pos != 0 77 | if getline('.')[col('.')] ==# '}' 78 | " Ending tag contains 3 closing brackets '}}}', 79 | " move to the last bracket. 80 | execute 'norm l' 81 | endif 82 | 83 | " select the whole tag 84 | execute 'norm v%' 85 | endif 86 | endfunction 87 | 88 | function! s:wrap_inside() 89 | " If the cursor is at the end of the tag element, move back 90 | " so that the end tag can be detected. 91 | while getline('.')[col('.')-1] ==# '}' 92 | execute 'norm h' 93 | endwhile 94 | 95 | " Moves to the end of the closing tag 96 | let pos = search('}}','W') 97 | if pos != 0 98 | " select only inside the tag 99 | execute 'norm v%loho' 100 | endif 101 | endfunction 102 | 103 | 104 | let &cpo = s:cpo_save 105 | unlet s:cpo_save 106 | 107 | " vim: nofoldenable 108 | -------------------------------------------------------------------------------- /syntax/spacebars.vim: -------------------------------------------------------------------------------- 1 | " Spacebars, Mustache & Handlebars syntax 2 | " Language: Spacebars, Mustache, Handlebars 3 | " Maintainer: Slava Kim 4 | " Original Maintainer: Juvenn Woo 5 | " References: 6 | " [Mustache](http://github.com/defunkt/mustache) 7 | " [Handlebars](https://github.com/wycats/handlebars.js) 8 | " [ctemplate](http://code.google.com/p/google-ctemplate/) 9 | " [ctemplate doc](http://google-ctemplate.googlecode.com/svn/trunk/doc/howto.html) 10 | " [et](http://www.ivan.fomichev.name/2008/05/erlang-template-engine-prototype.html) 11 | " [Spacebars](https://github.com/meteor/meteor/tree/devel/packages/spacebars) 12 | 13 | 14 | " Read the HTML syntax to start with 15 | if version < 600 16 | so :p:h/html.vim 17 | else 18 | runtime! syntax/html.vim 19 | unlet b:current_syntax 20 | endif 21 | 22 | if version < 600 23 | syntax clear 24 | elseif exists("b:current_syntax") 25 | finish 26 | endif 27 | 28 | " Standard HiLink will not work with included syntax files 29 | if version < 508 30 | command! -nargs=+ HtmlHiLink hi link 31 | else 32 | command! -nargs=+ HtmlHiLink hi def link 33 | endif 34 | 35 | syntax match spacebarsError '}}}\?' 36 | syntax match spacebarsInsideError '{{[{#<>=!\/]\?' 37 | syntax region spacebarsInside start=/{{/ end=/}}}\?/ keepend containedin=TOP,@htmlSpacebarsContainer 38 | syntax match spacebarsOperators '=\|\.\|/' contained containedin=spacebarsInside,@htmlSpacebarsContainer 39 | syntax region spacebarsSection start='{{[#^/]'lc=2 end='[} ]'me=e-1 contained containedin=spacebarsInside,@htmlSpacebarsContainer 40 | syntax region spacebarsPartial start=/{{[<>]\s*/lc=2 end=+[} ]+me=e-1 contained containedin=spacebarsInside,@htmlSpacebarsContainer 41 | syntax region spacebarsMarkerSet start=/{{=/lc=2 end=/=}}/me=e-2 contained containedin=spacebarsInside,@htmlSpacebarsContainer 42 | syntax match spacebarsHandlebars '{{\|}}' contained containedin=spacebarsInside,@htmlSpacebarsContainer 43 | syntax match spacebarsUnescape '{{{\|}}}' contained containedin=spacebarsInside,@htmlSpacebarsContainer 44 | syntax match spacebarsConditionals '\([/#]\(if\>\|unless\>\)\|\\)' contained containedin=spacebarsInside 45 | syntax match spacebarsHelpers '[/#]\(with\|each\)' contained containedin=spacebarsSection 46 | syntax region spacebarsComment start=/{{!/rs=s+2 end=/}}/re=e-2 contains=Todo contained containedin=spacebarsInside,@htmlSpacebarsContainer 47 | syntax region spacebarsBlockComment start=/{{!--/rs=s+2 end=/--}}/re=e-2 contains=Todo 48 | syntax region spacebarsQString start=/'/ skip=/\\'/ end=/'/ contained containedin=spacebarsInside 49 | syntax region spacebarsDQString start=/"/ skip=/\\"/ end=/"/ contained containedin=spacebarsInside 50 | 51 | syntax region spacebarsHelperRegion 52 | \ start=+{{#\z\([^ /!?<>"'{}]\+\)+ 53 | \ skip=+{{!\_.\{-}}}+ 54 | \ end=+{{/\z1\_\s\{-}}}+ 55 | \ fold 56 | \ contains=TOP,@htmlSpacebarsContainer,spacebarsError,spacebarsOperators,spacebarsSection,spacebarsPartial,spacebarsMarkerSet,spacebarsHandlebars,spacebarsUnescape,spacebarsConditionals,spacebarsHelpers,spacebarsComment,spacebarsBlockComment,spacebarsQString,spacebarsDQString,spacebarsHelperRegion 57 | \ keepend 58 | \ extend 59 | 60 | 61 | " Clustering 62 | syntax cluster htmlSpacebarsContainer add=htmlHead,htmlTitle,htmlString,htmlH1,htmlH2,htmlH3,htmlH4,htmlH5,htmlH6,htmlLink,htmlBold,htmlUnderline,htmlItalic,htmlValue 63 | 64 | 65 | " Hilighting 66 | " spacebarsInside hilighted as Number, which is rarely used in html 67 | " you might like change it to Function or Identifier 68 | HtmlHiLink spacebarsInside Number 69 | HtmlHiLink spacebarsVariable Number 70 | HtmlHiLink spacebarsVariableUnescape Number 71 | HtmlHiLink spacebarsPartial PreProc 72 | HtmlHiLink spacebarsSection PreProc 73 | HtmlHiLink spacebarsMarkerSet Number 74 | 75 | HtmlHiLink spacebarsComment Comment 76 | HtmlHiLink spacebarsBlockComment Comment 77 | HtmlHiLink spacebarsError Error 78 | HtmlHiLink spacebarsInsideError Error 79 | 80 | HtmlHiLink spacebarsHandlebars Special 81 | HtmlHiLink spacebarsUnescape Identifier 82 | HtmlHiLink spacebarsOperators Operator 83 | HtmlHiLink spacebarsConditionals Conditional 84 | HtmlHiLink spacebarsHelpers Repeat 85 | HtmlHiLink spacebarsQString String 86 | HtmlHiLink spacebarsDQString String 87 | 88 | syn region spacebarsScriptTemplate start=++me=s-1 keepend 90 | \ contains=spacebarsInside,@htmlSpacebarsContainer,htmlTag,htmlEndTag,htmlTagName,htmlSpecialChar 91 | 92 | let b:current_syntax = "spacebars" 93 | delcommand HtmlHiLink 94 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | spacebars and mustache and handlebars mode for vim 2 | ================================================== 3 | 4 | This is a fork of [vim-mustache-handlebars] adapted for [Spacebars]. In addition 5 | to the corrected syntax this fork also has folds defined and the correct 6 | indentation is in plans. 7 | 8 | [vim-mustache-handlebars]: https://github.com/mustache/vim-mustache-handlebars 9 | [Spacebars]: https://github.com/meteor/meteor/tree/master/packages/spacebars 10 | 11 | ![screenshot](./img/spacebars.png) 12 | 13 | The Readme of the original is following. For installation details, be sure to 14 | use the git-url of this fork (`git://github.com/Slava/vim-spacebars.git`) and 15 | the name `Slava/vim-spacebars` if you use Bundle/NeoBundle/Vundle. 16 | 17 | * * * 18 | 19 | A vim plugin for working with [mustache][mustache] and 20 | [handlebars][handlebars] templates. It has: 21 | 22 | - syntax highlighting 23 | - matchit support 24 | - mustache abbreviations (optional) 25 | - section movement mappings `[[` and `]]` 26 | - text objects `ie` (inside element) and `ae` (around element) 27 | 28 | **Note**: for compatibility reason #7, we've renamed the repo name from 29 | `vim-mode` to `vim-mustache-handlebars`. 30 | 31 | ### Install for pathogen 32 | 33 | cd ~/.vim/ 34 | git submodule add git://github.com/mustache/vim-mustache-handlebars.git bundle/mustache 35 | vim bundle/mustache/example.mustache 36 | 37 | Get [pathogen][pathogen]. 38 | 39 | ### Install for vundle 40 | 41 | Add `Bundle 'mustache/vim-mustache-handlebars'` to your `.vimrc` and do a `:BundleInstall`. 42 | 43 | ### Manually Install 44 | 45 | cd ~/.local/src 46 | git clone git://github.com/mustache/vim-mustache-handlebars.git mustache.vim 47 | cp -R mustache.vim/syntax/* ~/.vim/syntax/ 48 | cp -R mustache.vim/ftdetect/* ~/.vim/ftdetect/ 49 | cp -R mustache.vim/ftplugin/* ~/.vim/ftplugin/ 50 | vim mustache.vim/example.mustache 51 | 52 | ### Mustache Abbreviations 53 | 54 | You can activate mustache abbreviations by putting this line in your `.vimrc`: 55 | `let g:mustache_abbreviations = 1` 56 | 57 | Now you get a set of convenient abbreviations. Underscore `_` indicates where 58 | your cursor ends up after typing an abbreviation: 59 | - `{{` => `{{_}}` 60 | - `{{{` => `{{{_}}}` 61 | - `{{!` => `{{!_}}` 62 | - `{{>` => `{{>_}}` 63 | - `{{<` => `{{<_}}` 64 | - `{{#` produces 65 | 66 | ``` 67 | {{# _}} 68 | {{/}} 69 | ``` 70 | - `{{if` produces 71 | 72 | ``` 73 | {{#if _}} 74 | {{/if}} 75 | ``` 76 | - `{{ife` produces 77 | 78 | ``` 79 | {{#if _}} 80 | {{else}} 81 | {{/if}} 82 | ``` 83 | 84 | ### Section movement mappings 85 | 86 | Following the vim convention of jumping from section to section, `[[` and `]]` 87 | mappings are implemented for easier movement between mustache tags. 88 | 89 | - `]]` jumps to the first following tag 90 | - `[[` jumps to the first previous tag 91 | 92 | Count with section movements is supported: 93 | 94 | - `2]]` jumps to the second next tag 95 | 96 | ### Text objects 97 | 98 | Vim has a very powerful concept of "text objects". If you aren't using text objects, 99 | you can get familiar with it on [this vim help 100 | link](http://vimdoc.sourceforge.net/htmldoc/motion.html#text-objects). Learning 101 | text objects really speeds up the vim workflow. 102 | 103 | In that spirit, this plugin defines 2 text objects: 104 | - `ie` a mnemonic for `inside element`, selects all the text inside the 105 | mustache tag. 106 | For example, when used with `vie` it will visually select the 107 | bold text in the following snippets: {{**some_variable**}}, 108 | {{{**different_variable**}}}. 109 | - `ae` a mnemonic for `around element`, selects the whole mustache tag, 110 | including the curly braces. 111 | Example, `vae` visually selects the bold text in the following 112 | snippets: **{{some_variable}}** or **{{{another_variable}}}**. 113 | 114 | Here are other usage examples: 115 | - `dae` - deletes the whole mustache tag, including the curly braces 116 | - `die` - deletes **inside* the mustache tag, leaving only curly braces 117 | - `yae` - "yanks" the whole mustache tag - with curly braces 118 | - `cie` - deletes **inside** the mustache tag and goes in insert mode 119 | 120 | 121 | ## Maintainers 122 | 123 | * [Bruno Michel](http://github.com/nono) 124 | * [Bruno Sutic](http://github.com/bruno-) 125 | * [Juvenn Woo](http://github.com/juvenn) 126 | 127 | This is combined work from 128 | [juvenn/mustache.vim](http://github.com/juvenn/mustache.vim) and 129 | [nono/vim-handlebars](http://github.com/nono/vim-handlebars). 130 | 131 | ---- 132 | 133 | Thanks [@5long](http://github.com/5long) for adding matchit support. 134 | 135 | You're encouraged to propose ideas or have discussions via github 136 | issues. 137 | 138 | [mustache]: http://mustache.github.io 139 | [handlebars]: http://handlebarsjs.com 140 | [pathogen]: https://github.com/tpope/vim-pathogen 141 | -------------------------------------------------------------------------------- /indent/html.vim: -------------------------------------------------------------------------------- 1 | " Description: HTML5 and inline SVG indenter 2 | " Changed By: HT de Beer 3 | " Last Change: 20121013 4 | " Added the SVG elements to the list of indenting element. SVG elements 5 | " taken from http://www.w3.org/TR/SVG/eltindex.html 6 | " 7 | " Description: html5 (and html4) indenter 8 | " Changed By: Brian Gershon 9 | " Last Change: 30 Jan 2011 10 | " 11 | " 1. Started with vim72 html indent file authored by Johannes Zellner (below) 12 | " 2. Added html5 list as described here: 13 | " http://stackoverflow.com/questions/3232518/how-to-update-vim-to-color-code-new-html-elements 14 | " 3. Added this to a fork of https://github.com/othree/html5.vim 15 | " which already provides nice html5 syntax highlighting. 16 | " 17 | " Description: html indenter 18 | " Author: Johannes Zellner 19 | " Last Change: Mo, 05 Jun 2006 22:32:41 CEST 20 | " Restoring 'cpo' and 'ic' added by Bram 2006 May 5 21 | " Globals: 22 | " let g:html_indent_tags = 'html\|p\|time' 23 | " let g:html_exclude_tags = ['html', 'style', 'script', 'body'] 24 | 25 | 26 | " Only load this indent file when no other was loaded. 27 | if exists("b:did_indent") 28 | finish 29 | endif 30 | runtime! indent/javascript.vim 31 | let s:jsindent = &indentexpr 32 | unlet b:did_indent 33 | runtime! indent/css.vim 34 | let s:cssindent = &indentexpr 35 | let b:did_indent = 1 36 | 37 | " [-- local settings (must come before aborting the script) --] 38 | setlocal indentexpr=HtmlIndentGet(v:lnum) 39 | setlocal indentkeys=o,O,*,<>>,{,},!^F 40 | 41 | 42 | let s:tags = [] 43 | 44 | " [-- --] 45 | call add(s:tags, 'a') 46 | call add(s:tags, 'abbr') 47 | call add(s:tags, 'acronym') 48 | call add(s:tags, 'address') 49 | call add(s:tags, 'b') 50 | call add(s:tags, 'bdo') 51 | call add(s:tags, 'big') 52 | call add(s:tags, 'blockquote') 53 | call add(s:tags, 'button') 54 | call add(s:tags, 'caption') 55 | call add(s:tags, 'center') 56 | call add(s:tags, 'cite') 57 | call add(s:tags, 'code') 58 | call add(s:tags, 'colgroup') 59 | call add(s:tags, 'del') 60 | call add(s:tags, 'dfn') 61 | call add(s:tags, 'dir') 62 | call add(s:tags, 'div') 63 | call add(s:tags, 'dl') 64 | call add(s:tags, 'em') 65 | call add(s:tags, 'fieldset') 66 | call add(s:tags, 'font') 67 | call add(s:tags, 'form') 68 | call add(s:tags, 'frameset') 69 | call add(s:tags, 'h1') 70 | call add(s:tags, 'h2') 71 | call add(s:tags, 'h3') 72 | call add(s:tags, 'h4') 73 | call add(s:tags, 'h5') 74 | call add(s:tags, 'h6') 75 | call add(s:tags, 'i') 76 | call add(s:tags, 'iframe') 77 | call add(s:tags, 'ins') 78 | call add(s:tags, 'kbd') 79 | call add(s:tags, 'label') 80 | call add(s:tags, 'legend') 81 | call add(s:tags, 'li') 82 | call add(s:tags, 'map') 83 | call add(s:tags, 'menu') 84 | call add(s:tags, 'noframes') 85 | call add(s:tags, 'noscript') 86 | call add(s:tags, 'object') 87 | call add(s:tags, 'ol') 88 | call add(s:tags, 'optgroup') 89 | call add(s:tags, 'p') 90 | " call add(s:tags, 'pre') 91 | call add(s:tags, 'q') 92 | call add(s:tags, 's') 93 | call add(s:tags, 'samp') 94 | call add(s:tags, 'script') 95 | call add(s:tags, 'select') 96 | call add(s:tags, 'small') 97 | call add(s:tags, 'span') 98 | call add(s:tags, 'strong') 99 | call add(s:tags, 'style') 100 | call add(s:tags, 'sub') 101 | call add(s:tags, 'sup') 102 | call add(s:tags, 'table') 103 | call add(s:tags, 'textarea') 104 | call add(s:tags, 'title') 105 | call add(s:tags, 'tt') 106 | call add(s:tags, 'u') 107 | call add(s:tags, 'ul') 108 | call add(s:tags, 'var') 109 | 110 | " New HTML 5 elements 111 | call add(s:tags, 'article') 112 | call add(s:tags, 'aside') 113 | call add(s:tags, 'audio') 114 | call add(s:tags, 'canvas') 115 | call add(s:tags, 'datalist') 116 | call add(s:tags, 'details') 117 | call add(s:tags, 'figcaption') 118 | call add(s:tags, 'figure') 119 | call add(s:tags, 'footer') 120 | call add(s:tags, 'header') 121 | call add(s:tags, 'hgroup') 122 | call add(s:tags, 'main') 123 | call add(s:tags, 'mark') 124 | call add(s:tags, 'meter') 125 | call add(s:tags, 'nav') 126 | call add(s:tags, 'output') 127 | call add(s:tags, 'progress') 128 | call add(s:tags, 'rp') 129 | call add(s:tags, 'rt') 130 | call add(s:tags, 'ruby') 131 | call add(s:tags, 'section') 132 | call add(s:tags, 'summary') 133 | call add(s:tags, 'time') 134 | call add(s:tags, 'video') 135 | call add(s:tags, 'bdi') 136 | call add(s:tags, 'data') 137 | 138 | " Web Component 139 | call add(s:tags, 'template') 140 | 141 | " Common inline used SVG elements 142 | call add(s:tags, 'clipPath') 143 | call add(s:tags, 'defs') 144 | call add(s:tags, 'desc') 145 | call add(s:tags, 'filter') 146 | call add(s:tags, 'foreignObject') 147 | call add(s:tags, 'g') 148 | call add(s:tags, 'linearGradient') 149 | call add(s:tags, 'marker') 150 | call add(s:tags, 'mask') 151 | call add(s:tags, 'pattern') 152 | call add(s:tags, 'radialGradient') 153 | call add(s:tags, 'svg') 154 | call add(s:tags, 'switch') 155 | call add(s:tags, 'symbol') 156 | call add(s:tags, 'text') 157 | call add(s:tags, 'textPath') 158 | call add(s:tags, 'tref') 159 | call add(s:tags, 'tspan') 160 | 161 | call add(s:tags, 'html') 162 | call add(s:tags, 'head') 163 | call add(s:tags, 'body') 164 | 165 | call add(s:tags, 'thead') 166 | call add(s:tags, 'tbody') 167 | call add(s:tags, 'tfoot') 168 | call add(s:tags, 'tr') 169 | call add(s:tags, 'th') 170 | call add(s:tags, 'td') 171 | 172 | 173 | 174 | let s:omittable = [ 175 | \ ['address', 'article', 'aside', 'blockquote', 'dir', 'div', 'dl', 'fieldset', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hr', 'menu', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul'], 176 | \ ['dt', 'dd'], 177 | \ ['li'], 178 | \ ['thead', 'tbody', 'tfoot'], 179 | \ ['th', 'td'], 180 | \] 181 | 182 | if exists('g:html_exclude_tags') 183 | for tag in g:html_exclude_tags 184 | call remove(s:tags, index(s:tags, tag)) 185 | endfor 186 | endif 187 | let s:html_indent_tags = join(s:tags, '\|') 188 | if exists('g:html_indent_tags') 189 | let s:html_indent_tags = s:html_indent_tags.'\|'.g:html_indent_tags 190 | endif 191 | 192 | let s:cpo_save = &cpo 193 | set cpo-=C 194 | 195 | " [-- count indent-increasing spacebars tags of line a:lnum --] 196 | fun! SpacebarsIndentOpen(lnum) 197 | let s = substitute('x'.getline(a:lnum), 198 | \ '.\{-}\(\({{[#^]\)\)', "\1", 'g') 199 | let s = substitute(s, "[^\1].*$", '', '') 200 | return strlen(s) 201 | endfun 202 | 203 | " [-- count indent-decreasing spacebars tags of line a:lnum --] 204 | fun! SpacebarsIndentClose(lnum) 205 | let S = 'x'.getline(a:lnum) 206 | let s = substitute('x'.getline(a:lnum), 207 | \ '.\{-}\(\({{/\)\([^}]*\)\>}}\)', "\1", 'g') 208 | let s = substitute(s, "[^\1].*$", '', '') 209 | return strlen(s) 210 | endfun 211 | 212 | " [-- count indent-increasing tags of line a:lnum --] 213 | fun! HtmlIndentOpen(lnum, pattern) 214 | let s = substitute('x'.getline(a:lnum), 215 | \ '.\{-}\(\(<\)\('.a:pattern.'\)\>\)', "\1", 'g') 216 | let s = substitute(s, "[^\1].*$", '', '') 217 | return strlen(s) 218 | endfun 219 | 220 | " [-- count indent-decreasing tags of line a:lnum --] 221 | fun! HtmlIndentClose(lnum, pattern) 222 | let s = substitute('x'.getline(a:lnum), 223 | \ '.\{-}\(\(<\)/\('.a:pattern.'\)\>>\)', "\1", 'g') 224 | let s = substitute(s, "[^\1].*$", '', '') 225 | return strlen(s) 226 | endfun 227 | 228 | " [-- count indent-increasing '{' of (java|css) line a:lnum --] 229 | fun! HtmlIndentOpenAlt(lnum) 230 | return strlen(substitute(getline(a:lnum), '[^{]\+', '', 'g')) 231 | endfun 232 | 233 | " [-- count indent-decreasing '}' of (java|css) line a:lnum --] 234 | fun! HtmlIndentCloseAlt(lnum) 235 | return strlen(substitute(getline(a:lnum), '[^}]\+', '', 'g')) 236 | endfun 237 | 238 | " [-- return the sum of indents respecting the syntax of a:lnum --] 239 | fun! HtmlIndentSum(lnum, style) 240 | if a:style == match(getline(a:lnum), '^\s*\(<\|{{\)/') 241 | if a:style == match(getline(a:lnum), '^\s*\(\|{{/\)') 242 | let open = HtmlIndentOpen(a:lnum, s:html_indent_tags) 243 | let open = open + SpacebarsIndentOpen(a:lnum) 244 | let close = HtmlIndentClose(a:lnum, s:html_indent_tags) 245 | let close = close + SpacebarsIndentClose(a:lnum) 246 | if 0 != open || 0 != close 247 | return open - close 248 | endif 249 | endif 250 | endif 251 | 252 | if '' != &syntax && 253 | \ synIDattr(synID(a:lnum, 1, 1), 'name') =~ '\(css\|java\).*' && 254 | \ synIDattr(synID(a:lnum, strlen(getline(a:lnum)), 1), 'name') 255 | \ =~ '\(css\|java\).*' 256 | if a:style == match(getline(a:lnum), '^\s*}') 257 | return HtmlIndentOpenAlt(a:lnum) - HtmlIndentCloseAlt(a:lnum) 258 | endif 259 | endif 260 | return 0 261 | endfun 262 | 263 | fun! HtmlIndentGet(lnum) 264 | " Find a non-empty line above the current line. 265 | let lnum = prevnonblank(a:lnum - 1) 266 | 267 | " Hit the start of the file, use zero indent. 268 | if lnum == 0 269 | return 0 270 | endif 271 | 272 | let restore_ic = &ic 273 | setlocal ic " ignore case 274 | 275 | " [-- special handling for
    : no indenting --]
    276 |     if getline(a:lnum) =~ '\c
    ' 277 | \ || 0 < searchpair('\c
    ', '', '\c
    ', 'nWb') 278 | \ || 0 < searchpair('\c
    ', '', '\c
    ', 'nW') 279 | " we're in a line with or inside
     ... 
    280 | if restore_ic == 0 281 | setlocal noic 282 | endif 283 | return -1 284 | endif 285 | 286 | " [-- special handling for : use cindent --] 287 | let js = ', 05 Jun 2006 292 | " ZDR: This needs to be an AND (we are 'after the start of the pair' AND 293 | " we are 'before the end of the pair'). Otherwise, indentation 294 | " before the start of the script block will be affected; the end of 295 | " the pair will still match if we are before the beginning of the 296 | " pair. 297 | " 298 | if 0 < searchpair(js, '', jse, 'nWb') 299 | \ && 0 < searchpair(js, '', jse, 'nW') 300 | " we're inside javascript 301 | if getline(searchpair(js, '', '', 'nWb')) !~ '