From 44bb472bac2fa96c1444fcc02ad981152e56735b Mon Sep 17 00:00:00 2001 From: Andy Stewart Date: Fri, 27 Sep 2019 16:49:14 +0100 Subject: [PATCH] Add changed indicator for closed folds Closes #655. --- README.mkd | 16 ++++++++++++++++ autoload/gitgutter/fold.vim | 31 +++++++++++++++++++++++++++++++ test/test_gitgutter.vim | 18 ++++++++++++++++++ 3 files changed, 65 insertions(+) diff --git a/README.mkd b/README.mkd index e9e84aa..b3bdf53 100644 --- a/README.mkd +++ b/README.mkd @@ -17,6 +17,7 @@ Features: * Provides a hunk text object. * Diffs against index (default) or any commit. * Allows folding all unchanged text. +* Provides fold text showing whether folded lines have been changed. * Can load all hunk locations into quickfix list. * Handles line endings correctly, even with repos that do CRLF conversion. * Optional line highlighting. @@ -256,6 +257,21 @@ Use the `GitGutterFold` command to fold all unchanged lines, leaving just the hu Execute `GitGutterFold` a second time to restore the previous view. +Use `gitgutter#fold#foldtext()` to augment the default `foldtext()` with an indicator of whether the folded lines have been changed. + +```viml +set foldtext=gitgutter#fold#foldtext() +``` + +For a closed fold with changed lines: + +``` +Default foldtext(): +-- 45 lines: abcdef +gitgutter#fold#foldtext(): +-- 45 lines (*): abcdef +``` + +You can use `gitgutter#fold#is_changed()` in your own `foldtext` expression to find out whether the folded lines have been changed. + ### Customisation diff --git a/autoload/gitgutter/fold.vim b/autoload/gitgutter/fold.vim index ffc7691..4c1e30e 100644 --- a/autoload/gitgutter/fold.vim +++ b/autoload/gitgutter/fold.vim @@ -31,6 +31,37 @@ function! gitgutter#fold#level(lnum) endfunction +function! gitgutter#fold#foldtext() + if !gitgutter#fold#is_changed() + return foldtext() + endif + + return substitute(foldtext(), ':', ' (*):', '') +endfunction + + +" Returns 1 if any of the folded lines have been changed +" (added, removed, or modified), 0 otherwise. +function! gitgutter#fold#is_changed() + for hunk in gitgutter#hunk#hunks(bufnr('')) + let hunk_begin = hunk[2] + let hunk_end = hunk[2] + (hunk[3] == 0 ? 1 : hunk[3]) + + if hunk_end < v:foldstart + continue + endif + + if hunk_begin > v:foldend + break + endif + + return 1 + endfor + + return 0 +endfunction + + " A line in a hunk has a fold level of 0. " A line within 3 lines of a hunk has a fold level of 1. " All other lines have a fold level of 2. diff --git a/test/test_gitgutter.vim b/test/test_gitgutter.vim index 7e20623..502f989 100644 --- a/test/test_gitgutter.vim +++ b/test/test_gitgutter.vim @@ -63,6 +63,7 @@ function SetUp() " FIXME why won't vim autoload the file? execute 'source' '../../autoload/gitgutter/diff_highlight.vim' + execute 'source' '../../autoload/gitgutter/fold.vim' endfunction function TearDown() @@ -1050,3 +1051,20 @@ function Test_split() call assert_equal(['foobar', ''], gitgutter#diff_highlight#split('foobarbaz', 'baz')) call assert_equal(['1', '2'], gitgutter#diff_highlight#split('1~2', '~')) endfunction + + +function Test_foldtext() + 8d + call s:trigger_gitgutter() + call assert_equal(0, gitgutter#fold#is_changed()) + + let v:foldstart = 5 + let v:foldend = 9 + call assert_equal(1, gitgutter#fold#is_changed()) + call assert_equal('+- 5 lines (*): e', gitgutter#fold#foldtext()) + + let v:foldstart = 1 + let v:foldend = 3 + call assert_equal(0, gitgutter#fold#is_changed()) + call assert_equal('+- 3 lines: a', gitgutter#fold#foldtext()) +endfunction