diff --git a/README.md b/README.md index 9367688..8330bb5 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,7 @@ By default, the latter one is used because it allows to display modified lines. This resembles the default: ```vim -let g:lightline#gitdiff#algorithm = +let g:LightlineGitDiffAlgorithm = \ { buffer -> lightline#gitdiff#algorithms#word_diff_porcelain#calculate(buffer) } ``` @@ -115,6 +115,12 @@ provide your own. Take a look at the source of both functions for inspiration or consult me if you need help. I am happy to bundle additional faster and more feature-rich algorithms in the package. +You can show empty indicators (i.e. `A: 0 D: 0 M: 0`) in the following way: + +```vim +let g:lightline#gitdiff#show_empty_indicators = 1 +``` + # How it works / performance In the background, `lightline#gitdiff#get()` calls `git --numstat` or `git diff --git a/autoload/lightline/gitdiff.vim b/autoload/lightline/gitdiff.vim index a8ae45b..5cdd315 100644 --- a/autoload/lightline/gitdiff.vim +++ b/autoload/lightline/gitdiff.vim @@ -34,12 +34,23 @@ endfunction function! lightline#gitdiff#write_calculation_to_cache(buffer, soft) abort if a:soft && has_key(g:lightline#gitdiff#cache, a:buffer) " b/c there is something in the cache already - return + return endif - let l:Calculation = get(g:, 'lightline#gitdiff#algorithm', - \ { buffer -> lightline#gitdiff#algorithms#word_diff_porcelain#calculate(buffer) }) - let g:lightline#gitdiff#cache[a:buffer] = l:Calculation(a:buffer) + let l:indicator_values = get(g:, 'LightlineGitDiffAlgorithm', + \ { buffer -> lightline#gitdiff#algorithms#word_diff_porcelain#calculate(buffer) })(a:buffer) + + " If the user doesn't want to show empty indicators, + " then remove the empty indicators returned from the algorithm + if !get(g:, 'lightline#gitdiff#show_empty_indicators', 0) + for key in keys(l:indicator_values) + if l:indicator_values[key] == 0 + unlet l:indicator_values[key] + endif + endfor + endif + + let g:lightline#gitdiff#cache[a:buffer] = l:indicator_values endfunction " format() {{{1 returns the calculated changes of the current buffer in a @@ -62,7 +73,7 @@ endfunction " " In fact, an arbitrary number of changes can be supported. This depends on " the algorithm that is used for calculation -" (`g:lightline#gitdiff#algorithm`). However, this function takes only these +" (`g:LightlineGitDiffAlgorithm`). However, this function takes only these " types of changes into account b/c it only provides default indicators for " these types. If an algorithm does not support a particular type, this is not " an issue; if it supports more types than this function, the additional types diff --git a/autoload/lightline/gitdiff/algorithms/numstat.vim b/autoload/lightline/gitdiff/algorithms/numstat.vim index 4fed527..ae665c3 100644 --- a/autoload/lightline/gitdiff/algorithms/numstat.vim +++ b/autoload/lightline/gitdiff/algorithms/numstat.vim @@ -17,17 +17,5 @@ function! lightline#gitdiff#algorithms#numstat#calculate(buffer) abort return {} endif - let l:ret = {} - - " lines added - if l:stats[0] !=# '0' - let l:ret['A'] = l:stats[0] - endif - - " lines deleted - if l:stats[1] !=# '0' - let l:ret['D'] = l:stats[1] - endif - - return l:ret + return { 'A': l:stats[0], 'D': l:stats[1] } endfunction diff --git a/autoload/lightline/gitdiff/algorithms/word_diff_porcelain.vim b/autoload/lightline/gitdiff/algorithms/word_diff_porcelain.vim index 3dd6cda..7a7f432 100644 --- a/autoload/lightline/gitdiff/algorithms/word_diff_porcelain.vim +++ b/autoload/lightline/gitdiff/algorithms/word_diff_porcelain.vim @@ -16,21 +16,7 @@ function! lightline#gitdiff#algorithms#word_diff_porcelain#calculate(buffer) abo let l:lines_deleted = len(filter(copy(l:changes), { idx, val -> val ==# 'D' })) let l:lines_modified = len(filter(copy(l:changes), { idx, val -> val ==# 'M' })) - let l:ret = {} - - if l:lines_added > 0 - let l:ret['A'] = l:lines_added - endif - - if l:lines_deleted > 0 - let l:ret['D'] = l:lines_deleted - endif - - if l:lines_modified > 0 - let l:ret['M'] = l:lines_modified - endif - - return l:ret + return { 'A': l:lines_added, 'D': l:lines_deleted, 'M': l:lines_modified} endfunction " get_diff_porcelain {{{1 returns the output of git's word-diff as list. The diff --git a/test/lightline-gitdiff.vader b/test/lightline-gitdiff.vader index 09aa45e..b09c653 100644 --- a/test/lightline-gitdiff.vader +++ b/test/lightline-gitdiff.vader @@ -1,2 +1,194 @@ Include (Algorithms): algorithm/parse_indicator_group.vader Include (Utils): utils/group_at.vader + +Before : + if exists('g:LightlineGitDiffAlgorithm') + unlet g:LightlineGitDiffAlgorithm + endif + +" no show_empty_indicators variable +Execute(write_calculation_to_cache(): given no show_empty_indicators variable and an empty result): + let g:LightlineGitDiffAlgorithm = { -> { 'A': 0, 'D': 0, 'M':0 } } + call g:lightline#gitdiff#write_calculation_to_cache(1, 0) + let actual = get(g:, 'lightline#gitdiff#cache')[1] +Then (should return no empty indicators): + AssertEqual {}, actual + +Execute(write_calculation_to_cache(): given no show_empty_indicators variable with only added lines): + let g:LightlineGitDiffAlgorithm = { -> { 'A': 1, 'D': 0, 'M': 0 } } + call g:lightline#gitdiff#write_calculation_to_cache(1, 0) + let actual = get(g:, 'lightline#gitdiff#cache')[1] +Then (should remove all indicators but 'A'): + AssertEqual { 'A': 1 }, actual + +Execute(write_calculation_to_cache(): given no show_empty_indicators variable with only deleted lines): + let g:LightlineGitDiffAlgorithm = { -> { 'A': 0, 'D': 1, 'M': 0 } } + call g:lightline#gitdiff#write_calculation_to_cache(1, 0) + let actual = get(g:, 'lightline#gitdiff#cache')[1] +Then (should remove all indicators but 'D'): + AssertEqual { 'D': 1 }, actual + +Execute(write_calculation_to_cache(): given no show_empty_indicators variable with only modified lines): + let g:LightlineGitDiffAlgorithm = { -> { 'A': 0, 'D': 0, 'M': 1 } } + call g:lightline#gitdiff#write_calculation_to_cache(1, 0) + let actual = get(g:, 'lightline#gitdiff#cache')[1] +Then (should remove all indicators but 'M'): + AssertEqual { 'M': 1 }, actual + +Execute(write_calculation_to_cache(): given no show_empty_indicators variable with added and modified lines): + let g:LightlineGitDiffAlgorithm = { -> { 'A': 3, 'D': 0, 'M': 1 } } + call g:lightline#gitdiff#write_calculation_to_cache(1, 0) + let actual = get(g:, 'lightline#gitdiff#cache')[1] +Then (should remove only the 'D' indicator): + AssertEqual { 'A': 3, 'M': 1 }, actual + +Execute(write_calculation_to_cache(): given no show_empty_indicators variable with deleted and modified lines): + let g:LightlineGitDiffAlgorithm = { -> { 'A': 0, 'D': 2, 'M': 1 } } + call g:lightline#gitdiff#write_calculation_to_cache(1, 0) + let actual = get(g:, 'lightline#gitdiff#cache')[1] +Then (should remove only the 'A' indicator): + AssertEqual { 'D': 2, 'M': 1 }, actual + +Execute(write_calculation_to_cache(): given no show_empty_indicators variable with added and deleted lines): + let g:LightlineGitDiffAlgorithm = { -> { 'A': 4, 'D': 5, 'M': 0 } } + call g:lightline#gitdiff#write_calculation_to_cache(1, 0) + let actual = get(g:, 'lightline#gitdiff#cache')[1] +Then (should remove only the 'M' indicator): + AssertEqual { 'A': 4, 'D': 5 }, actual + +Execute(write_calculation_to_cache(): given no show_empty_indicators variable with added, deleted, and modified lines): + let g:LightlineGitDiffAlgorithm = { -> { 'A': 9, 'D': 10, 'M': 7 } } + call g:lightline#gitdiff#write_calculation_to_cache(1, 0) + let actual = get(g:, 'lightline#gitdiff#cache')[1] +Then (should not remove any indicators): + AssertEqual { 'A': 9, 'D': 10, 'M': 7 }, actual + +" show_empty_indicators variable == 0 +Execute(write_calculation_to_cache(): given the show_empty_indicators variable equals 0 with an empty result): + let g:LightlineGitDiffAlgorithm = { -> { 'A': 0, 'D': 0, 'M':0 } } + let g:lightline#gitdiff#show_empty_indicators = 0 + call g:lightline#gitdiff#write_calculation_to_cache(1, 0) + let actual = get(g:, 'lightline#gitdiff#cache')[1] +Then (should return no empty indicators): + AssertEqual {}, actual + +Execute(write_calculation_to_cache(): given the show_empty_indicators variable equals 0 with only added lines): + let g:LightlineGitDiffAlgorithm = { -> { 'A': 1, 'D': 0, 'M': 0 } } + let g:lightline#gitdiff#show_empty_indicators = 0 + call g:lightline#gitdiff#write_calculation_to_cache(1, 0) + let actual = get(g:, 'lightline#gitdiff#cache')[1] +Then (should remove all indicators but 'A'): + AssertEqual { 'A': 1 }, actual + +Execute(write_calculation_to_cache(): given the show_empty_indicators variable equals 0 with only deleted lines): + let g:LightlineGitDiffAlgorithm = { -> { 'A': 0, 'D': 1, 'M': 0 } } + let g:lightline#gitdiff#show_empty_indicators = 0 + call g:lightline#gitdiff#write_calculation_to_cache(1, 0) + let actual = get(g:, 'lightline#gitdiff#cache')[1] +Then (should remove all indicators but 'D'): + AssertEqual { 'D': 1 }, actual + +Execute(write_calculation_to_cache(): given the show_empty_indicators variable equals 0 with only modified lines): + let g:LightlineGitDiffAlgorithm = { -> { 'A': 0, 'D': 0, 'M': 1 } } + let g:lightline#gitdiff#show_empty_indicators = 0 + call g:lightline#gitdiff#write_calculation_to_cache(1, 0) + let actual = get(g:, 'lightline#gitdiff#cache')[1] +Then (should remove all indicators but 'M'): + AssertEqual { 'M': 1 }, actual + +Execute(write_calculation_to_cache(): given the show_empty_indicators variable equals 0 with added and modified lines): + let g:LightlineGitDiffAlgorithm = { -> { 'A': 3, 'D': 0, 'M': 1 } } + let g:lightline#gitdiff#show_empty_indicators = 0 + call g:lightline#gitdiff#write_calculation_to_cache(1, 0) + let actual = get(g:, 'lightline#gitdiff#cache')[1] +Then (should remove only the 'D' indicator): + AssertEqual { 'A': 3, 'M': 1 }, actual + +Execute(write_calculation_to_cache(): given the show_empty_indicators variable equals 0 with deleted and modified lines): + let g:LightlineGitDiffAlgorithm = { -> { 'A': 0, 'D': 2, 'M': 1 } } + let g:lightline#gitdiff#show_empty_indicators = 0 + call g:lightline#gitdiff#write_calculation_to_cache(1, 0) + let actual = get(g:, 'lightline#gitdiff#cache')[1] +Then (should remove only the 'A' indicator): + AssertEqual { 'D': 2, 'M': 1 }, actual + +Execute(write_calculation_to_cache(): given the show_empty_indicators variable equals 0 with added and deleted lines): + let g:LightlineGitDiffAlgorithm = { -> { 'A': 4, 'D': 5, 'M': 0 } } + let g:lightline#gitdiff#show_empty_indicators = 0 + call g:lightline#gitdiff#write_calculation_to_cache(1, 0) + let actual = get(g:, 'lightline#gitdiff#cache')[1] +Then (should remove only the 'M' indicator): + AssertEqual { 'A': 4, 'D': 5 }, actual + +Execute(write_calculation_to_cache(): given the show_empty_indicators variable equals 0 with added, deleted, and modified lines): + let g:LightlineGitDiffAlgorithm = { -> { 'A': 9, 'D': 10, 'M': 7 } } + let g:lightline#gitdiff#show_empty_indicators = 0 + call g:lightline#gitdiff#write_calculation_to_cache(1, 0) + let actual = get(g:, 'lightline#gitdiff#cache')[1] +Then (should not remove any indicators): + AssertEqual { 'A': 9, 'D': 10, 'M': 7 }, actual + +" show_empty_indicators variable == 1 +Execute(write_calculation_to_cache(): given the show_empty_indicators variable equals 1 with an empty result): + let g:LightlineGitDiffAlgorithm = { -> { 'A': 0, 'D': 0, 'M':0 } } + let g:lightline#gitdiff#show_empty_indicators = 1 + call g:lightline#gitdiff#write_calculation_to_cache(1, 0) + let actual = get(g:, 'lightline#gitdiff#cache')[1] +Then (should return all indicators): + AssertEqual { 'A': 0, 'D': 0, 'M':0 }, actual + +Execute(write_calculation_to_cache(): given the show_empty_indicators variable equals 1 with only added lines): + let g:LightlineGitDiffAlgorithm = { -> { 'A': 1, 'D': 0, 'M': 0 } } + let g:lightline#gitdiff#show_empty_indicators = 1 + call g:lightline#gitdiff#write_calculation_to_cache(1, 0) + let actual = get(g:, 'lightline#gitdiff#cache')[1] +Then (should remove all indicators): + AssertEqual { 'A': 1, 'D': 0, 'M': 0 }, actual + +Execute(write_calculation_to_cache(): given the show_empty_indicators variable equals 1 with only deleted lines): + let g:LightlineGitDiffAlgorithm = { -> { 'A': 0, 'D': 1, 'M': 0 } } + let g:lightline#gitdiff#show_empty_indicators = 1 + call g:lightline#gitdiff#write_calculation_to_cache(1, 0) + let actual = get(g:, 'lightline#gitdiff#cache')[1] +Then (should return all indicators): + AssertEqual { 'A': 0, 'D': 1, 'M': 0 }, actual + +Execute(write_calculation_to_cache(): given the show_empty_indicators variable equals 1 with only modified lines): + let g:LightlineGitDiffAlgorithm = { -> { 'A': 0, 'D': 0, 'M': 1 } } + let g:lightline#gitdiff#show_empty_indicators = 1 + call g:lightline#gitdiff#write_calculation_to_cache(1, 0) + let actual = get(g:, 'lightline#gitdiff#cache')[1] +Then (should return all indicators): + AssertEqual { 'A': 0, 'D': 0, 'M': 1 }, actual + +Execute(write_calculation_to_cache(): given the show_empty_indicators variable equals 1 with added and modified lines): + let g:LightlineGitDiffAlgorithm = { -> { 'A': 3, 'D': 0, 'M': 1 } } + let g:lightline#gitdiff#show_empty_indicators = 1 + call g:lightline#gitdiff#write_calculation_to_cache(1, 0) + let actual = get(g:, 'lightline#gitdiff#cache')[1] +Then (should return all indicators): + AssertEqual { 'A': 3, 'D': 0, 'M': 1 }, actual + +Execute(write_calculation_to_cache(): given the show_empty_indicators variable equals 1 with deleted and modified lines): + let g:LightlineGitDiffAlgorithm = { -> { 'A': 0, 'D': 2, 'M': 1 } } + let g:lightline#gitdiff#show_empty_indicators = 1 + call g:lightline#gitdiff#write_calculation_to_cache(1, 0) + let actual = get(g:, 'lightline#gitdiff#cache')[1] +Then (should return all indicators): + AssertEqual { 'A': 0, 'D': 2, 'M': 1 }, actual + +Execute(write_calculation_to_cache(): given the show_empty_indicators variable equals 1 with added and deleted lines): + let g:LightlineGitDiffAlgorithm = { -> { 'A': 4, 'D': 5, 'M': 0 } } + let g:lightline#gitdiff#show_empty_indicators = 1 + call g:lightline#gitdiff#write_calculation_to_cache(1, 0) + let actual = get(g:, 'lightline#gitdiff#cache')[1] +Then (should return all indicators): + AssertEqual { 'A': 4, 'D': 5, 'M': 0 }, actual + +Execute(write_calculation_to_cache(): given the show_empty_indicators variable equals 1 with added, deleted, and modified lines): + let g:LightlineGitDiffAlgorithm = { -> { 'A': 9, 'D': 10, 'M': 7 } } + let g:lightline#gitdiff#show_empty_indicators = 1 + call g:lightline#gitdiff#write_calculation_to_cache(1, 0) + let actual = get(g:, 'lightline#gitdiff#cache')[1] +Then (should return all indicators): + AssertEqual { 'A': 9, 'D': 10, 'M': 7 }, actual