diff --git a/README.mkd b/README.mkd index a7a2233..45cf212 100644 --- a/README.mkd +++ b/README.mkd @@ -14,6 +14,7 @@ Features: * Stage/undo/preview individual hunks. * Provides a hunk text object. * Diffs against index (default) or any commit. +* Allows folding all unchanged text. * Handles line endings correctly, even with repos that do CRLF conversion. * Optional line highlighting. * Fully customisable (signs, sign column, line highlights, mappings, extra git-diff arguments, etc). @@ -210,6 +211,11 @@ Finally, you can force vim-gitgutter to update its signs across all visible buff See the customisation section below for how to change the defaults. +### Folding + +Use the `GitGutterFold` command to fold all unchanged lines, leaving just the hunks visible. Use the command again to restore the previous view. + + ### Customisation You can customise: diff --git a/autoload/gitgutter/fold.vim b/autoload/gitgutter/fold.vim new file mode 100644 index 0000000..a3fb886 --- /dev/null +++ b/autoload/gitgutter/fold.vim @@ -0,0 +1,52 @@ +function! gitgutter#fold#enable() + call s:save_fold_state() + + setlocal foldexpr=gitgutter#fold#level(v:lnum) + setlocal foldmethod=expr + setlocal foldlevel=0 + setlocal foldenable + + call gitgutter#utility#setbufvar(bufnr(''), 'folded', 1) +endfunction + + +function! gitgutter#fold#disable() + call s:restore_fold_state() + call gitgutter#utility#setbufvar(bufnr(''), 'folded', 0) +endfunction + + +function! gitgutter#fold#toggle() + if s:folded() + call gitgutter#fold#disable() + else + call gitgutter#fold#enable() + endif +endfunction + + +function! gitgutter#fold#level(lnum) + return gitgutter#hunk#in_hunk(a:lnum) ? 0 : 1 +endfunction + + +function! s:save_fold_state() + call gitgutter#utility#setbufvar(bufnr(''), 'foldmethod', &foldmethod) + if &foldmethod ==# 'manual' + mkview + endif +endfunction + +function! s:restore_fold_state() + let &foldmethod = gitgutter#utility#getbufvar(bufnr(''), 'foldmethod') + if &foldmethod ==# 'manual' + loadview + else + normal! zx + endif +endfunction + +function! s:folded() + return gitgutter#utility#getbufvar(bufnr(''), 'folded') +endfunction + diff --git a/autoload/gitgutter/hunk.vim b/autoload/gitgutter/hunk.vim index 3c886dc..50ea5f4 100644 --- a/autoload/gitgutter/hunk.vim +++ b/autoload/gitgutter/hunk.vim @@ -123,6 +123,30 @@ function! gitgutter#hunk#cursor_in_hunk(hunk) abort return 0 endfunction + +function! gitgutter#hunk#in_hunk(lnum) + " Hunks are sorted in the order they appear in the buffer. + for hunk in gitgutter#hunk#hunks(bufnr('')) + " if in a hunk on first line of buffer + if a:lnum == 1 && hunk[2] == 0 + return 1 + endif + + " if in a hunk generally + if a:lnum >= hunk[2] && a:lnum < hunk[2] + (hunk[3] == 0 ? 1 : hunk[3]) + return 1 + endif + + " if hunk starts after the given line + if a:lnum < hunk[2] + return 0 + endif + endfor + + return 0 +endfunction + + function! gitgutter#hunk#text_object(inner) abort let hunk = s:current_hunk() diff --git a/doc/gitgutter.txt b/doc/gitgutter.txt index d0732c3..49d6d99 100644 --- a/doc/gitgutter.txt +++ b/doc/gitgutter.txt @@ -148,6 +148,11 @@ Commands for operating on a hunk:~ Use |:pclose| or |CTRL-W_CTRL-Z| to close the preview window. +Commands for folds:~ + + *gitgutter-:GitGutterFold* +:GitGutterFold Fold all unchanged lines. Execute again to undo. + =============================================================================== AUTOCOMMAND *gitgutter-autocommand* diff --git a/plugin/gitgutter.vim b/plugin/gitgutter.vim index 6567474..e0b0b92 100644 --- a/plugin/gitgutter.vim +++ b/plugin/gitgutter.vim @@ -166,6 +166,12 @@ endfunction " }}} +" Folds {{{ + +command! -bar GitGutterFold call gitgutter#fold#toggle() + +" }}} + command! -bar GitGutterDebug call gitgutter#debug#debug() " Maps {{{