1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- let s:config = vue#GetConfig('config', {})
- let s:enable_foldexpr = s:config.foldexpr
- if !s:enable_foldexpr | finish | endif
- " Useful for debugging foldexpr
- " set debug=msg
- function! VueFoldMain(...)
- if line('$') < 1000
- let s:empty_line = '^\s*$'
- let s:vue_tag_start = '^<\w\+'
- let s:vue_tag_end = '^<\/\w\+'
- setlocal foldexpr=GetVueFold(v:lnum)
- setlocal foldmethod=expr
- endif
- endfunction
- " see :h fold-expr
- " value meaning
- " 0 the line is not in a fold
- " 1, 2, .. the line is in a fold with this level
- " -1 the fold level is undefined, use the fold level of a
- " line before or after this line, whichever is the
- " lowest.
- " "=" use fold level from the previous line
- " "a1", "a2", .. add one, two, .. to the fold level of the previous
- " line, use the result for the current line
- " "s1", "s2", .. subtract one, two, .. from the fold level of the
- " ">1", ">2", .. a fold with this level starts at this line
- " "<1", "<2", .. a fold with this level ends at this line
- function! GetVueFold(lnum)
- let this_line = getline(a:lnum)
- let value = s:FoldForSpecialLine(this_line)
- if value == -2
- " Fold by indent
- let this_indent = s:IndentLevel(a:lnum)
- " For <script> block
- if GetVueTag(a:lnum) == 'script'
- let value = s:FoldForScript(a:lnum, this_line, this_indent)
- else
- let value = this_indent
- endif
- endif
- call vue#LogWithLnum('foldlevel '.value)
- return value
- endfunction
- function! s:FoldForScript(lnum, this_line, this_indent)
- let value = -2
- if a:lnum > 1
- let prev_indent = s:IndentLevel(a:lnum - 1)
- else
- let prev_indent = 0
- endif
- let next_indent = s:IndentLevel(nextnonblank(a:lnum + 1))
- if a:this_line =~ '^\s*[]})]\+,\?\s*$'
- " Closing ']})'
- let value = '<'.prev_indent
- elseif a:this_indent < next_indent
- " --this
- " ----next
- let value = '>'.next_indent
- else
- " ----this
- " --next
- let value = a:this_indent
- endif
- return value
- endfunction
- function! s:FoldForSpecialLine(this_line)
- if a:this_line =~ s:empty_line
- return '='
- elseif a:this_line =~ s:vue_tag_start
- return '>1'
- elseif a:this_line =~ s:vue_tag_end
- " If return '<1', fold will get incorrect with prev line
- return 1
- else
- return -2
- endif
- endfunction
- function! s:IndentLevel(lnum)
- " Add 1 to indentLevel, so start/end tags can fold properly
- return indent(a:lnum) / &shiftwidth + 1
- endfunction
- "}}}
- call VueFoldMain()
|