From 02029e1ae1ea96b62dfe12f733ca0aecaa25e765 Mon Sep 17 00:00:00 2001 From: yemai Date: Thu, 15 Aug 2019 16:06:20 +0800 Subject: [PATCH] feat: add fold --- ftplugin/vue/fold.vim | 107 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 ftplugin/vue/fold.vim diff --git a/ftplugin/vue/fold.vim b/ftplugin/vue/fold.vim new file mode 100644 index 0000000..7b18206 --- /dev/null +++ b/ftplugin/vue/fold.vim @@ -0,0 +1,107 @@ +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" +" Config {{{ +" +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +let s:use_foldexpr = !exists("g:vim_vue_plugin_use_foldexpr") + \ || g:vim_vue_plugin_use_foldexpr == 1 +"}}} + +if !s:use_foldexpr | finish | endif + +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" +" Settings {{{ +" +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +setlocal foldmethod=expr +setlocal foldexpr=GetVueFold(v:lnum) +"}}} + +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" +" Variables {{{ +" +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +let s:empty_line = '\v^\s*$' +let s:block_end = '\v^\s*}|]|\)' +let s:vue_tag_start = '\v^\s*\<(script|style|template)' +let s:vue_tag_end = '\v^\s*\<\/(script|style|template)' +"}}} + +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" +" Functions {{{ +" +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" 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 next_line = getline(a:lnum + 1) + if a:lnum > 1 + let prev_line = getline(a:lnum - 1) + endif + + " Handle empty or comment lines + if this_line =~ s:empty_line + return -1 + endif + if this_line =~ s:vue_tag_start + return '>1' + endif + if this_line =~ s:vue_tag_end + return '<1' + endif + + " Use (indentLevel + 1) as fold level + let this_indent = s:IndentLevel(a:lnum) + let next_indent = s:IndentLevel(s:NextNonBlankLine(a:lnum)) + + if a:lnum > 1 + let prev_indent = s:IndentLevel(a:lnum - 1) + + if this_line =~ s:block_end && (this_indent < prev_indent) + return prev_indent + endif + endif + + if this_indent >= next_indent + return this_indent + elseif this_indent < next_indent + return '>'.next_indent + endif +endfunction + +function! s:IndentLevel(lnum) + " Add 1 to enable vue tags to fold + return indent(a:lnum) / &shiftwidth + 1 +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