diff --git a/autoload/tagbar.vim b/autoload/tagbar.vim index dc927d6..787407b 100644 --- a/autoload/tagbar.vim +++ b/autoload/tagbar.vim @@ -1031,6 +1031,8 @@ function! s:MapKeys() abort \ ['togglefold', 'ToggleFold()'], \ ['openallfolds', 'SetFoldLevel(99, 1)'], \ ['closeallfolds', 'SetFoldLevel(0, 1)'], + \ ['incrementfolds', 'ChangeFoldLevel(1, 1)'], + \ ['decrementfolds', 'ChangeFoldLevel(-1, 1)'], \ ['nextfold', 'GotoNextFold()'], \ ['prevfold', 'GotoPrevFold()'], \ @@ -3097,6 +3099,8 @@ function! s:PrintHelp() abort silent put ='\" ' . s:get_map_str('togglefold') . ': Toggle fold' silent put ='\" ' . s:get_map_str('openallfolds') . ': Open all folds' silent put ='\" ' . s:get_map_str('closeallfolds') . ': Close all folds' + silent put ='\" ' . s:get_map_str('incrementfolds') . ': Increment fold level by 1' + silent put ='\" ' . s:get_map_str('decrementfolds') . ': Decrement fold level by 1' silent put ='\" ' . s:get_map_str('nextfold') . ': Go to next fold' silent put ='\" ' . s:get_map_str('prevfold') . ': Go to previous fold' silent put ='\"' @@ -3494,6 +3498,46 @@ function! s:ToggleFold() abort call s:RenderKeepView(newline) endfunction +" s:ChangeFoldLevel() {{{2 +function! s:ChangeFoldLevel(diff, force) abort + let fileinfo = s:TagbarState().getCurrent(0) + if empty(fileinfo) + return + endif + + if fileinfo.foldlevel == 99 + call s:MinimizeMaxFoldLevel(fileinfo, fileinfo.getTags()) + endif + + let level = fileinfo.foldlevel + let level = level + a:diff + if level < 0 + call s:warning('Foldlevel can''t be negative') + return + endif + + call s:SetFoldLevelRecursive(fileinfo, fileinfo.getTags(), level) + + let typeinfo = fileinfo.typeinfo + + " Apply foldlevel to 'kind's + if level == 0 + for kind in typeinfo.kinds + call fileinfo.closeKindFold(kind) + endfor + else + for kind in typeinfo.kinds + if a:force || !kind.fold + call fileinfo.openKindFold(kind) + endif + endfor + endif + + let fileinfo.foldlevel = level + + call s:RenderContent() +endfunction + " s:SetFoldLevel() {{{2 function! s:SetFoldLevel(level, force) abort if a:level < 0 @@ -3544,6 +3588,23 @@ function! s:SetFoldLevelRecursive(fileinfo, tags, level) abort endfor endfunction +" s:MinimizeMaxFoldLevel() {{{2 +" Set the file's fold level to the lowest value that still shows all tags +function! s:MinimizeMaxFoldLevel(fileinfo, tags) abort + let maxlvl = 0 + let tags = copy(a:tags) + + for tag in tags + if maxlvl < tag.depth + let maxlvl = tag.depth + endif + call tag.setFolded(0) + call extend(tags, tag.getChildren()) + endfor + + let a:fileinfo.foldlevel = maxlvl +endfunction + " s:OpenParents() {{{2 function! s:OpenParents(...) abort if a:0 == 1 diff --git a/doc/tagbar.txt b/doc/tagbar.txt index 4adbd02..51b71f0 100644 --- a/doc/tagbar.txt +++ b/doc/tagbar.txt @@ -346,6 +346,12 @@ o/za Toggle the fold under the cursor or the current one if there is Map option: tagbar_map_openallfolds =/zM Close all folds by setting foldlevel to 0. Map option: tagbar_map_closeallfolds +zr Increase the fold level of the buffer by 1. Opens all folds one + level. + Map option: tagbar_map_incrementfolds +zm Decrease the fold level of the buffer by 1. Closes all folds one + level. + Map option: tagbar_map_decrementfolds zj Go to the start of the next fold, like the standard Vim |zj|. Map option: tagbar_map_nextfold zk Go to the end of the previous fold, like the standard Vim |zk|. diff --git a/plugin/tagbar.vim b/plugin/tagbar.vim index cc03e38..e921def 100644 --- a/plugin/tagbar.vim +++ b/plugin/tagbar.vim @@ -108,6 +108,8 @@ function! s:setup_keymaps() abort \ ['togglefold', ['o', 'za']], \ ['openallfolds', ['*', '', 'zR']], \ ['closeallfolds', ['=', 'zM']], + \ ['incrementfolds', ['zr']], + \ ['decrementfolds', ['zm']], \ ['nextfold', 'zj'], \ ['prevfold', 'zk'], \