summaryrefslogtreecommitdiff
path: root/start/signify/autoload/sy/fold.vim
diff options
context:
space:
mode:
Diffstat (limited to 'start/signify/autoload/sy/fold.vim')
-rw-r--r--start/signify/autoload/sy/fold.vim125
1 files changed, 125 insertions, 0 deletions
diff --git a/start/signify/autoload/sy/fold.vim b/start/signify/autoload/sy/fold.vim
new file mode 100644
index 0000000..e3afb97
--- /dev/null
+++ b/start/signify/autoload/sy/fold.vim
@@ -0,0 +1,125 @@
+" vim: et sw=2 sts=2
+
+" Function: SignifyFoldExpr {{{1
+function! SignifyFoldExpr(lnum)
+ return s:levels[a:lnum]
+endfunction
+
+" Function: SignifyFoldText {{{1
+function! SignifyFoldText()
+ let linelen = &textwidth ? &textwidth : 80
+ let marker = &foldmarker[:stridx(&foldmarker, ',')-1]
+ let range = foldclosedend(v:foldstart) - foldclosed(v:foldstart) + 1
+
+ let left = substitute(getline(v:foldstart), marker, '', '')
+ let leftlen = len(left)
+
+ let right = printf('%d [%d]', range, v:foldlevel)
+ let rightlen = len(right)
+
+ let tmp = strpart(left, 0, linelen - rightlen)
+ let tmplen = len(tmp)
+
+ if leftlen > tmplen
+ let left = strpart(tmp, 0, tmplen - 4) . '... '
+ let leftlen = tmplen
+ endif
+
+ let fill = repeat(' ', linelen - (leftlen + rightlen))
+
+ " return left . fill . right . repeat(' ', 100)
+ return left . fill . right
+endfunction
+
+" Function: #dispatch {{{1
+function! sy#fold#dispatch(do_tab) abort
+ if a:do_tab
+ call sy#fold#enable(1)
+ else
+ call sy#fold#toggle()
+ endif
+endfunction
+
+" Function: #enable {{{1
+function! sy#fold#enable(do_tab) abort
+ execute sy#util#return_if_no_changes()
+
+ if a:do_tab
+ tabedit %
+ endif
+
+ let [s:context0, s:context1] = get(g:, 'signify_fold_context', [3, 8])
+ let s:levels = s:get_levels(s:get_lines())
+
+ setlocal foldexpr=SignifyFoldExpr(v:lnum)
+ setlocal foldtext=SignifyFoldText()
+ setlocal foldmethod=expr
+ setlocal foldlevel=0
+endfunction
+
+" Function: #disable {{{1
+function! sy#fold#disable() abort
+ let &l:foldmethod = b:sy_folded.method
+ let &l:foldtext = b:sy_folded.text
+ normal! zv
+endfunction
+
+" Function: #toggle {{{1
+function! sy#fold#toggle() abort
+ if exists('b:sy_folded')
+ call sy#fold#disable()
+ if b:sy_folded.method == 'manual'
+ loadview
+ endif
+ unlet b:sy_folded
+ else
+ let b:sy_folded = { 'method': &foldmethod, 'text': &foldtext }
+ if &foldmethod == 'manual'
+ let old_vop = &viewoptions
+ mkview
+ let &viewoptions = old_vop
+ endif
+ call sy#fold#enable(0)
+ endif
+
+ redraw!
+ call sy#start()
+endfunction
+
+" Function: s:get_lines {{{1
+function! s:get_lines() abort
+ let signlist = sy#util#execute('sign place buffer='. b:sy.buffer)
+
+ let lines = []
+ for line in split(signlist, '\n')[2:]
+ call insert(lines, matchlist(line, '\v^\s+line\=(\d+)')[1], 0)
+ endfor
+
+ return reverse(lines)
+endfunction
+" }}}
+
+" Function: s:get_levels {{{1
+function! s:get_levels(lines) abort
+ let levels = {}
+
+ for line in range(1, line('$'))
+ let levels[line] = 2
+ endfor
+
+ for line in a:lines
+ for l in range(line - s:context1, line + s:context1)
+ if (l < 1) || (l > line('$'))
+ continue
+ endif
+ if levels[l] == 2
+ let levels[l] = 1
+ endif
+ for ll in range(line - s:context0, line + s:context0)
+ let levels[ll] = 0
+ endfor
+ endfor
+ endfor
+
+ return levels
+endfunction