diff --git a/autoload/fugitive.vim b/autoload/fugitive.vim index 7b2a9f9..0c63c42 100644 --- a/autoload/fugitive.vim +++ b/autoload/fugitive.vim @@ -1551,8 +1551,11 @@ function! fugitive#BufReadStatus() abort nnoremap q :if bufnr('$') == 1quitelsebdeleteendif nnoremap r :exe ReloadStatus() nnoremap R :exe ReloadStatus() - nnoremap U :echoerr 'Changed to g' - nnoremap g :execute StageUndo() + nnoremap U :echoerr 'Changed to X' + nnoremap g :execute StageDelete(line('.'),v:count) + xnoremap g :execute StageDelete(line("'<"),line("'>")-line("'<")+1) + nnoremap X :execute StageDelete(line('.'),v:count) + xnoremap X :execute StageDelete(line("'<"),line("'>")-line("'<")+1) nnoremap . : =fnameescape(get(StatusCfile(),0,'')) nnoremap g? :help fugitive-:Gstatus nnoremap :help fugitive-:Gstatus @@ -2056,29 +2059,6 @@ function! s:StageReloadSeek(target,lnum1,lnum2) abort return '' endfunction -function! s:StageUndo() abort - let info = s:StageInfo(line('.')) - if empty(info.filename) - return '' - endif - let hash = s:TreeChomp('hash-object', '-w', './' . info.filename) - if !empty(hash) - if info.status ==# 'U' - call s:TreeChomp('rm', './' . info.filename) - elseif info.status ==# '?' - call s:TreeChomp('clean', '-f', './' . info.filename) - elseif info.section ==# 'Unstaged' - call s:TreeChomp('checkout', './' . info.filename) - else - call s:TreeChomp('checkout', 'HEAD^{}', './' . info.filename) - endif - call s:StageReloadSeek([info.filename, ''], line('.'), line('.')) - let @" = hash - return 'checktime|redraw|echomsg ' . - \ string('To restore, :Git cat-file blob '.hash[0:6].' > '.info.filename) - endif -endfunction - function! s:StageInline(mode, ...) abort let lnum1 = a:0 ? a:1 : line('.') let lnum = lnum1 + 1 @@ -2258,6 +2238,34 @@ function! s:StageApply(info, lnum1, count, reverse, extra) abort return v:shell_error ? output : '' endfunction +function! s:StageDelete(lnum, count) abort + let info = s:StageInfo(a:lnum) + if empty(info.filename) + return '' + endif + let hash = s:TreeChomp('hash-object', '-w', './' . info.filename) + if empty(hash) + return '' + elseif info.offset >= 0 + let output = s:StageApply(info, a:lnum, a:count, 1, info.section ==# 'Staged' ? ['--index'] : []) + if len(output) + return 'echoerr ' . string(output) + endif + elseif info.status ==# 'U' + call s:TreeChomp('rm', './' . info.filename) + elseif info.status ==# '?' + call s:TreeChomp('clean', '-f', './' . info.filename) + elseif info.section ==# 'Unstaged' + call s:TreeChomp('checkout', './' . info.filename) + else + call s:TreeChomp('checkout', 'HEAD^{}', './' . info.filename) + endif + exe s:ReloadStatus() + let @@ = hash + return 'redraw|echomsg ' . + \ string('To restore, :Git cat-file blob '.hash[0:6].' > '.info.filename) +endfunction + function! s:StageToggle(lnum1, count) abort if a:lnum1 == 1 && a:count == 0 return 'Gedit .git/|call search("^index$", "wc")' diff --git a/doc/fugitive.txt b/doc/fugitive.txt index c675f95..a781f18 100644 --- a/doc/fugitive.txt +++ b/doc/fugitive.txt @@ -58,14 +58,14 @@ that are part of Git repositories). dp |:Git| add --intent-to-add (untracked files) dv |:Gvdiff| gO |:Gvsplit| - g| |:Git| checkout - g| |:Git| checkout HEAD (staged files) - g| |:Git| clean (untracked files) - g| |:Git| rm (unmerged files) O |:Gtabedit| o |:Gsplit| P |:Git| add --patch P |:Git| reset --patch (staged files) + X |:Git| checkout + X |:Git| checkout HEAD (staged files) + X |:Git| clean (untracked files) + X |:Git| rm (unmerged files) q close status r reload status . enter |:| command line with file prepopulated