Fix foldexpr

This commit is contained in:
leafOfTree
2021-04-19 14:20:37 +08:00
parent 8f23970cf9
commit d080255fce

View File

@@ -1,40 +1,20 @@
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"
" Config {{{
"
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let s:config = vue#GetConfig('config', {}) let s:config = vue#GetConfig('config', {})
let s:enable_foldexpr = s:config.foldexpr let s:enable_foldexpr = s:config.foldexpr
"}}}
if !s:enable_foldexpr | finish | endif if !s:enable_foldexpr | finish | endif
" set debug=msg
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" function! VueFoldMain(...)
" if line('$') < 1000
" Settings {{{ let s:empty_line = '^\s*$'
" let s:vue_tag_start = '^<\w\+'
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" let s:vue_tag_end = '^<\/\w\+'
if line('$') < 1000
setlocal foldmethod=expr
endif
setlocal foldexpr=GetVueFold(v:lnum)
"}}}
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" setlocal foldexpr=GetVueFold(v:lnum)
" setlocal foldmethod=expr
" Variables {{{ endif
" endfunction
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let s:empty_line = '\v^\s*$'
let s:vue_tag_start = '\v^\s*\<\w+'
let s:vue_tag_end = '\v^\s*\<\/\w+'
"}}}
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"
" Functions {{{
"
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" see :h fold-expr " see :h fold-expr
" value meaning " value meaning
" 0 the line is not in a fold " 0 the line is not in a fold
@@ -50,55 +30,57 @@ let s:vue_tag_end = '\v^\s*\<\/\w+'
" "<1", "<2", .. a fold with this level ends at this line " "<1", "<2", .. a fold with this level ends at this line
function! GetVueFold(lnum) function! GetVueFold(lnum)
let this_line = getline(a:lnum) let this_line = getline(a:lnum)
let next_line = getline(a:lnum + 1) let value = s:FoldForSpecialLine(this_line)
if a:lnum > 1 if value == -2
let prev_line = getline(a:lnum - 1) " Fold by indent
endif let this_indent = s:IndentLevel(a:lnum)
" Handle empty lines " For <script> block
if this_line =~ s:empty_line if GetVueTag(a:lnum) == 'script'
return -1 let value = s:GetVueFoldForScript(a:lnum, this_line, this_indent)
else
let value = this_indent
endif
endif endif
call vue#LogWithLnum('foldlevel '.value)
return value
endfunction
" Handle start/end tags function! s:GetVueFoldForScript(lnum, this_line, this_indent)
if this_line =~ s:vue_tag_start let value = -2
return '>1'
endif
if this_line =~ s:vue_tag_end
" If return '<1', fold will get incorrect with prev line
return 1
endif
" Fold by indent
if a:lnum > 1 if a:lnum > 1
let prev_indent = s:IndentLevel(a:lnum - 1) let prev_indent = s:IndentLevel(a:lnum - 1)
else else
let prev_indent = 0 let prev_indent = 0
endif endif
let this_indent = s:IndentLevel(a:lnum) let next_indent = s:IndentLevel(nextnonblank(a:lnum))
let next_indent = s:IndentLevel(s:NextNonBlankLine(a:lnum))
" Handle <script> block specially
if GetVueTag(a:lnum) == 'script'
" Handle closing '}'
if this_line =~ '\v^\s*},?\s*$'
return '<'.prev_indent
endif
if a:this_line =~ '[]})],\?\s*$'
" Closing ']})'
let value = '<'.prev_indent
elseif a:this_indent < next_indent
" --this " --this
" ----next " ----next
if this_indent < next_indent let value = '>'.next_indent
return '>'.next_indent elseif a:this_indent >= next_indent
endif
" ----this " ----this
" --next " --next
if this_indent >= next_indent let value = a:this_indent
return this_indent endif
endif
return value
endfunction
function! s:FoldForSpecialLine(this_line)
if a:this_line =~ s:empty_line
return -1
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 else
" Handle other blocks return -2
return this_indent
endif endif
endfunction endfunction
@@ -106,20 +88,12 @@ function! s:IndentLevel(lnum)
" Add 1 to indentLevel, so start/end tags can fold properly " Add 1 to indentLevel, so start/end tags can fold properly
return indent(a:lnum) / &shiftwidth + 1 return indent(a:lnum) / &shiftwidth + 1
endfunction endfunction
function! s:NextNonBlankLine(lnum)
let next_line = a:lnum + 1
let last_line = line('$')
while next_line <= last_line
if getline(next_line) =~ '\v\S'
return next_line
endif
let next_line += 1
endwhile
return 0
endfunction
"}}} "}}}
" vim: fdm=marker
let s:test = exists('g:vim_vue_plugin_test')
let s:timer = exists('*timer_start') && !exists('SessionLoad') && !s:test
if s:timer
call timer_start(300, 'VueFoldMain')
else
call VueFoldMain()
endif