diff --git a/README.mkd b/README.mkd index f6b9e9a..511793d 100644 --- a/README.mkd +++ b/README.mkd @@ -7,7 +7,7 @@ Features: * Shows signs for added, modified, and removed lines. * Ensures signs are always as up to date as possible (but without running more than necessary). * Quick jumping between blocks of changed lines ("hunks"). -* Stage/revert individual hunks. +* Stage/revert/preview individual hunks. * Optional line highlighting. * Fully customisable (signs, sign column, line highlights, mappings, extra git-diff arguments, etc). * Can be toggled on/off. @@ -103,6 +103,12 @@ nmap ha GitGutterStageHunk nmap hu GitGutterRevertHunk ``` +And you can preview a hunk's changes with `hp`. You can of course change this mapping, e.g: + +```viml +nmap hv GitGutterPreviewHunk +``` + If you don't want vim-gitgutter to set up any mappings at all, use this: ```viml diff --git a/autoload/diff.vim b/autoload/diff.vim index aab514a..16081b1 100644 --- a/autoload/diff.vim +++ b/autoload/diff.vim @@ -178,13 +178,18 @@ function! diff#process_modified_and_removed(modifications, from_count, to_count, let a:modifications[-1] = [a:to_line + offset - 1, 'modified_removed'] endfunction -function! diff#generate_diff_for_hunk(hunk) - return diff#discard_hunks(diff#run_diff(0, 0), a:hunk) +function! diff#generate_diff_for_hunk(hunk, keep_header) + let diff = diff#discard_hunks(diff#run_diff(0, 0), a:hunk, a:keep_header) + if !a:keep_header + " Discard summary line + let diff = join(split(diff, '\n')[1:-1], "\n") + endif + return diff endfunction -function! diff#discard_hunks(diff, hunk_to_keep) +function! diff#discard_hunks(diff, hunk_to_keep, keep_header) let modified_diff = [] - let keep_line = 1 " start by keeping header + let keep_line = a:keep_header for line in split(a:diff, '\n') let hunk_info = diff#parse_hunk(line) if len(hunk_info) == 4 " start of new hunk diff --git a/autoload/gitgutter.vim b/autoload/gitgutter.vim index ce3b0d2..e10b7ea 100644 --- a/autoload/gitgutter.vim +++ b/autoload/gitgutter.vim @@ -119,7 +119,7 @@ function! gitgutter#stage_hunk() endif " construct a diff - let diff_for_hunk = diff#generate_diff_for_hunk(current_hunk) + let diff_for_hunk = diff#generate_diff_for_hunk(current_hunk, 1) " apply the diff call system(utility#command_in_directory_of_file('git apply --cached --unidiff-zero - '), diff_for_hunk) @@ -142,7 +142,7 @@ function! gitgutter#revert_hunk() endif " construct a diff - let diff_for_hunk = diff#generate_diff_for_hunk(current_hunk) + let diff_for_hunk = diff#generate_diff_for_hunk(current_hunk, 1) " apply the diff call system(utility#command_in_directory_of_file('git apply --reverse --unidiff-zero - '), diff_for_hunk) @@ -152,4 +152,32 @@ function! gitgutter#revert_hunk() endif endfunction +function! gitgutter#preview_hunk() + if utility#is_active() + silent write + + " find current hunk + let current_hunk = hunk#current_hunk() + if empty(current_hunk) + return + endif + + " construct a diff + let diff_for_hunk = diff#generate_diff_for_hunk(current_hunk, 0) + + " preview the diff + silent! wincmd P + if !&previewwindow + execute 'bo ' . &previewheight . ' new' + set previewwindow + setlocal filetype=diff buftype=nowrite + endif + + execute "%delete_" + call append(0, split(diff_for_hunk, "\n")) + + wincmd p + endif +endfunction + " }}} diff --git a/doc/gitgutter.txt b/doc/gitgutter.txt index fc3938d..5c91404 100644 --- a/doc/gitgutter.txt +++ b/doc/gitgutter.txt @@ -105,6 +105,9 @@ Commands for staging or reverting individual hunks: :GitGutterRevertHunk *:GitGutterRevertHunk* Revert the hunk the cursor is in. + :GitGutterPreviewHunk *:GitGutterPreviewHunk* + Preview the hunk the cursor is in. + =============================================================================== 5. CUSTOMISATION *GitGutterCustomisation* diff --git a/plugin/gitgutter.vim b/plugin/gitgutter.vim index d6126e7..41d6f6e 100644 --- a/plugin/gitgutter.vim +++ b/plugin/gitgutter.vim @@ -77,8 +77,9 @@ command GitGutterSignsToggle call gitgutter#signs_toggle() command -count=1 GitGutterNextHunk call hunk#next_hunk() command -count=1 GitGutterPrevHunk call hunk#prev_hunk() -command GitGutterStageHunk call gitgutter#stage_hunk() -command GitGutterRevertHunk call gitgutter#revert_hunk() +command GitGutterStageHunk call gitgutter#stage_hunk() +command GitGutterRevertHunk call gitgutter#revert_hunk() +command GitGutterPreviewHunk call gitgutter#preview_hunk() " Returns the git-diff hunks for the file or an empty list if there " aren't any hunks. @@ -127,8 +128,9 @@ if g:gitgutter_map_keys endif -nnoremap GitGutterStageHunk :GitGutterStageHunk -nnoremap GitGutterRevertHunk :GitGutterRevertHunk +nnoremap GitGutterStageHunk :GitGutterStageHunk +nnoremap GitGutterRevertHunk :GitGutterRevertHunk +nnoremap GitGutterPreviewHunk :GitGutterPreviewHunk if g:gitgutter_map_keys if !hasmapto('GitGutterStageHunk') && maparg('hs', 'n') ==# '' @@ -137,6 +139,9 @@ if g:gitgutter_map_keys if !hasmapto('GitGutterRevertHunk') && maparg('hr', 'n') ==# '' nmap hr GitGutterRevertHunk endif + if !hasmapto('GitGutterPreviewHunk') && maparg('hp', 'n') ==# '' + nmap hp GitGutterPreviewHunk + endif endif " }}}