diff --git a/autoload/gitgutter.vim b/autoload/gitgutter.vim index 1ea2888..b9f48f6 100644 --- a/autoload/gitgutter.vim +++ b/autoload/gitgutter.vim @@ -19,7 +19,7 @@ function! gitgutter#process_buffer(file, realtime) endif try if !a:realtime || gitgutter#utility#has_fresh_changes(a:file) - let diff = gitgutter#diff#run_diff(a:realtime || gitgutter#utility#has_unsaved_changes(a:file), 1) + let diff = gitgutter#diff#run_diff(a:realtime || gitgutter#utility#has_unsaved_changes(a:file), 1, 0) call gitgutter#hunk#set_hunks(gitgutter#diff#parse_diff(diff)) let modified_lines = gitgutter#diff#process_hunks(gitgutter#hunk#hunks()) @@ -156,17 +156,11 @@ function! gitgutter#stage_hunk() " It doesn't make sense to stage a hunk otherwise. silent write - " find current hunk - let current_hunk = gitgutter#hunk#current_hunk() - if empty(current_hunk) - return - endif - " construct a diff - let diff_for_hunk = gitgutter#diff#generate_diff_for_hunk(current_hunk, 1) + let diff_for_hunk = gitgutter#diff#generate_diff_for_hunk(1, 1) " apply the diff - call gitgutter#utility#system(gitgutter#utility#command_in_directory_of_file('git apply --cached --unidiff-zero - '), diff_for_hunk) + call gitgutter#utility#system(gitgutter#utility#command_in_directory_of_file('git apply --cached --recount --allow-overlap - '), diff_for_hunk) " refresh gitgutter's view of buffer silent execute "GitGutter" @@ -179,17 +173,11 @@ function! gitgutter#revert_hunk() " It doesn't make sense to stage a hunk otherwise. silent write - " find current hunk - let current_hunk = gitgutter#hunk#current_hunk() - if empty(current_hunk) - return - endif - " construct a diff - let diff_for_hunk = gitgutter#diff#generate_diff_for_hunk(current_hunk, 1) + let diff_for_hunk = gitgutter#diff#generate_diff_for_hunk(1, 1) " apply the diff - call gitgutter#utility#system(gitgutter#utility#command_in_directory_of_file('git apply --reverse --unidiff-zero - '), diff_for_hunk) + call gitgutter#utility#system(gitgutter#utility#command_in_directory_of_file('git apply --reverse - '), diff_for_hunk) " reload file silent edit @@ -200,14 +188,8 @@ function! gitgutter#preview_hunk() if gitgutter#utility#is_active() silent write - " find current hunk - let current_hunk = gitgutter#hunk#current_hunk() - if empty(current_hunk) - return - endif - " construct a diff - let diff_for_hunk = gitgutter#diff#generate_diff_for_hunk(current_hunk, 0) + let diff_for_hunk = gitgutter#diff#generate_diff_for_hunk(0, 0) " preview the diff silent! wincmd P diff --git a/autoload/gitgutter/diff.vim b/autoload/gitgutter/diff.vim index c7eb200..2fddf47 100644 --- a/autoload/gitgutter/diff.vim +++ b/autoload/gitgutter/diff.vim @@ -3,7 +3,7 @@ let s:grep_command = ' | ' . (g:gitgutter_escape_grep ? '\grep' : 'grep') . ' -e let s:hunk_re = '^@@ -\(\d\+\),\?\(\d*\) +\(\d\+\),\?\(\d*\) @@' -function! gitgutter#diff#run_diff(realtime, use_external_grep) +function! gitgutter#diff#run_diff(realtime, use_external_grep, lines_of_context) " Wrap compound command in parentheses to make Windows happy. let cmd = '(git ls-files --error-unmatch ' . gitgutter#utility#shellescape(gitgutter#utility#filename()) . ' && (' @@ -11,9 +11,9 @@ function! gitgutter#diff#run_diff(realtime, use_external_grep) let blob_name = ':' . gitgutter#utility#shellescape(gitgutter#utility#file_relative_to_repo_root()) let blob_file = tempname() let cmd .= 'git show ' . blob_name . ' > ' . blob_file . - \ ' && diff -U0 ' . g:gitgutter_diff_args . ' ' . blob_file . ' - ' + \ ' && diff -U'.a:lines_of_context.' ' . g:gitgutter_diff_args . ' ' . blob_file . ' - ' else - let cmd .= 'git diff --no-ext-diff --no-color -U0 ' . g:gitgutter_diff_args . ' ' . gitgutter#utility#shellescape(gitgutter#utility#filename()) + let cmd .= 'git diff --no-ext-diff --no-color -U'.a:lines_of_context.' ' . g:gitgutter_diff_args . ' ' . gitgutter#utility#shellescape(gitgutter#utility#filename()) endif if a:use_external_grep && s:grep_available @@ -182,22 +182,24 @@ function! gitgutter#diff#process_modified_and_removed(modifications, from_count, let a:modifications[-1] = [a:to_line + offset - 1, 'modified_removed'] endfunction -function! gitgutter#diff#generate_diff_for_hunk(hunk, keep_header) - let diff = gitgutter#diff#discard_hunks(gitgutter#diff#run_diff(0, 0), a:hunk, a:keep_header) +function! gitgutter#diff#generate_diff_for_hunk(keep_header, lines_of_context) + let diff = gitgutter#diff#run_diff(0, 0, a:lines_of_context) + let diff_for_hunk = gitgutter#diff#discard_hunks(diff, a:keep_header) if !a:keep_header " Discard summary line - let diff = join(split(diff, '\n')[1:-1], "\n") + let diff_for_hunk = join(split(diff_for_hunk, '\n')[1:-1], "\n") endif - return diff + return diff_for_hunk endfunction -function! gitgutter#diff#discard_hunks(diff, hunk_to_keep, keep_header) +" diff - with non-zero lines of context +function! gitgutter#diff#discard_hunks(diff, keep_header) let modified_diff = [] let keep_line = a:keep_header for line in split(a:diff, '\n') let hunk_info = gitgutter#diff#parse_hunk(line) if len(hunk_info) == 4 " start of new hunk - let keep_line = (hunk_info == a:hunk_to_keep) + let keep_line = gitgutter#hunk#cursor_in_hunk(hunk_info) endif if keep_line call add(modified_diff, line) diff --git a/autoload/gitgutter/hunk.vim b/autoload/gitgutter/hunk.vim index 0f49691..7ee0ae6 100644 --- a/autoload/gitgutter/hunk.vim +++ b/autoload/gitgutter/hunk.vim @@ -67,15 +67,9 @@ endfunction " hunk. function! gitgutter#hunk#current_hunk() let current_hunk = [] - let current_line = line('.') for hunk in s:hunks - if current_line == 1 && hunk[2] == 0 - let current_hunk = hunk - break - endif - - if current_line >= hunk[2] && current_line < hunk[2] + (hunk[3] == 0 ? 1 : hunk[3]) + if gitgutter#hunk#cursor_in_hunk(hunk) let current_hunk = hunk break endif @@ -86,3 +80,17 @@ function! gitgutter#hunk#current_hunk() endif endfunction +function! gitgutter#hunk#cursor_in_hunk(hunk) + let current_line = line('.') + + if current_line == 1 && a:hunk[2] == 0 + return 1 + endif + + if current_line >= a:hunk[2] && current_line < a:hunk[2] + (a:hunk[3] == 0 ? 1 : a:hunk[3]) + return 1 + endif + + return 0 +endfunction +