diff --git a/doc/fugitive.txt b/doc/fugitive.txt index 725e271..73aeeca 100644 --- a/doc/fugitive.txt +++ b/doc/fugitive.txt @@ -50,7 +50,8 @@ that are part of Git repositories). *fugitive-:Gstatus* :Gstatus Bring up the output of git-status in the preview window. Press - to stage or unstage the file on the - cursor line. Press C to invoke |:Gcommit|. + cursor line. Press p to do so on a per hunk basis + (--patch). Press C to invoke |:Gcommit|. *fugitive-:Gcommit* :Gcommit [args] A wrapper around git-commit. If there is nothing diff --git a/plugin/fugitive.vim b/plugin/fugitive.vim index 686c49a..eed7c22 100644 --- a/plugin/fugitive.vim +++ b/plugin/fugitive.vim @@ -552,6 +552,56 @@ function! s:StageToggle(lnum1,lnum2) abort return 'checktime' endfunction +function! s:StagePatch(lnum1,lnum2) abort + let add = [] + let reset = [] + + for lnum in range(a:lnum1,a:lnum2) + let line = getline(lnum) + if line == '# Changes to be committed:' + return 'Git reset --patch' + elseif line == '# Changed but not updated:' + return 'Git add --patch' + endif + let filename = matchstr(line,'^#\t[[:alpha:] ]\+: *\zs.*') + if filename ==# '' + let filename = matchstr(line,'^#\t\zs.*') + endif + if filename ==# '' + continue + endif + if !exists('first_filename') + let first_filename = filename + endif + execute lnum + let section = getline(search('^# .*:$','bnW')) + if line =~# '^#\trenamed:' && filename =~ ' -> ' + let reset += [split(filename,' -> ')[1]] + elseif section =~? ' to be ' + let reset += [filename] + elseif line !~# '^#\tdeleted:' + let add += [filename] + endif + endfor + try + if !empty(add) + execute "Git add --patch -- ".join(map(add,'s:shellesc(v:val)')) + endif + if !empty(reset) + execute "Git reset --patch -- ".join(map(add,'s:shellesc(v:val)')) + endif + if exists('first_filename') + silent! edit! + 1 + redraw + call search('^#\t\%([[:alpha:] ]\+: *\)\=\V'.first_filename.'\$','W') + endif + catch /^fugitive:/ + return 'echoerr v:errmsg' + endtry + return 'checktime' +endfunction + " }}}1 " Gcommit {{{1 @@ -1183,6 +1233,8 @@ function! s:BufReadIndex() nnoremap i :let b:fugitive_display_format -= 1exe BufReadIndex() nnoremap - :execute StageToggle(line('.'),line('.')+v:count1-1) xnoremap - :execute StageToggle(line("'<"),line("'>")) + nnoremap p :execute StagePatch(line('.'),line('.')+v:count1-1) + xnoremap p :execute StagePatch(line("'<"),line("'>")) call s:JumpInit() nunmap P nunmap ~