diff --git a/plugin/fugitive.vim b/plugin/fugitive.vim index 2aadaeb..a083d6e 100644 --- a/plugin/fugitive.vim +++ b/plugin/fugitive.vim @@ -679,6 +679,22 @@ function! fugitive#reload_status() abort endfor endfunction +function! s:stage_section(lnum) abort + let lnum = a:lnum + while lnum && getline(lnum) !~# '^#.*:$' + let lnum -= 1 + endwhile + if !lnum + return '' + elseif getline(lnum) ==# '# Changes to be committed:' + return 'staged' + elseif getline(lnum) ==# '# Untracked files:' + return 'untracked' + else + return 'unstaged' + endif +endfunction + function! s:StageReloadSeek(target,lnum1,lnum2) let jump = a:target let f = matchstr(getline(a:lnum1-1),'^#\t\%([[:alpha:] ]\+: *\)\=\zs.*') @@ -692,10 +708,10 @@ function! s:StageReloadSeek(target,lnum1,lnum2) endfunction function! s:StageDiff(diff) abort - let section = getline(search('^# .*:$','bcnW')) + let section = s:stage_section(line('.')) let line = getline('.') let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs.\{-\}\ze\%( (new commits)\)\=$') - if filename ==# '' && section ==# '# Changes to be committed:' + if filename ==# '' && section ==# 'staged' return 'Git! diff --cached' elseif filename ==# '' return 'Git! diff' @@ -703,7 +719,7 @@ function! s:StageDiff(diff) abort let [old, new] = split(filename,' -> ') execute 'Gedit '.s:fnameescape(':0:'.new) return a:diff.' HEAD:'.s:fnameescape(old) - elseif section ==# '# Changes to be committed:' + elseif section ==# 'staged' execute 'Gedit '.s:fnameescape(':0:'.filename) return a:diff.' -' else @@ -713,20 +729,20 @@ function! s:StageDiff(diff) abort endfunction function! s:StageDiffEdit() abort - let section = getline(search('^# .*:$','bcnW')) + let section = s:stage_section(line('.')) let line = getline('.') let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs.\{-\}\ze\%( (new commits)\)\=$') let arg = (filename ==# '' ? '.' : filename) - if section ==# '# Changes to be committed:' + if section ==# 'staged' return 'Git! diff --cached '.s:shellesc(arg) - elseif section ==# '# Untracked files:' + elseif section ==# 'untracked' let repo = s:repo() call repo.git_chomp_in_tree('add','--intent-to-add',arg) if arg ==# '.' silent! edit! 1 if !search('^# Change\%(d but not updated\|s not staged for commit\):$','W') - call search('^# Change','W') + call search('^# .*:$','W') endif else call s:StageReloadSeek(arg,line('.'),line('.')) @@ -743,28 +759,30 @@ function! s:StageToggle(lnum1,lnum2) abort for lnum in range(a:lnum1,a:lnum2) let line = getline(lnum) let repo = s:repo() - if line ==# '# Changes to be committed:' - call repo.git_chomp_in_tree('reset','-q') - silent! edit! - 1 - if !search('^# Untracked files:$','W') - call search('^# Change','W') + if line =~# '^# .*:$' + if section ==# 'staged' + call repo.git_chomp_in_tree('reset','-q') + silent! edit! + 1 + if !search('^# Untracked files:$','W') + call search('^# .*:$','W') + endif + return '' + elseif section ==# 'unstaged' + call repo.git_chomp_in_tree('add','-u') + silent! edit! + 1 + if !search('^# Untracked files:$','W') + call search('^# .*:$','W') + endif + return '' + else + call repo.git_chomp_in_tree('add','.') + silent! edit! + 1 + call search('^# .*:$','W') + return '' endif - return '' - elseif line =~# '^# Change\%(d but not updated\|s not staged for commit\):$' - call repo.git_chomp_in_tree('add','-u') - silent! edit! - 1 - if !search('^# Untracked files:$','W') - call search('^# Change','W') - endif - return '' - elseif line ==# '# Untracked files:' - call repo.git_chomp_in_tree('add','.') - silent! edit! - 1 - call search('^# Change','W') - return '' endif let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs.\{-\}\ze\%( (\a\+ [[:alpha:], ]\+)\)\=$') if filename ==# '' @@ -774,11 +792,11 @@ function! s:StageToggle(lnum1,lnum2) abort let first_filename = filename endif execute lnum - let section = getline(search('^# .*:$','bnW')) + let section = s:stage_section(line('.')) if line =~# '^#\trenamed:' && filename =~ ' -> ' let cmd = ['mv','--'] + reverse(split(filename,' -> ')) let filename = cmd[-1] - elseif section =~? ' to be ' + elseif section ==# 'staged' let cmd = ['reset','-q','--',filename] elseif line =~# '^#\tdeleted:' let cmd = ['rm','--',filename] @@ -816,10 +834,10 @@ function! s:StagePatch(lnum1,lnum2) abort let first_filename = filename endif execute lnum - let section = getline(search('^# .*:$','bnW')) + let section = s:stage_section(line('.')) if line =~# '^#\trenamed:' && filename =~ ' -> ' let reset += [split(filename,' -> ')[1]] - elseif section =~? ' to be ' + elseif section ==# 'staged' let reset += [filename] elseif line !~# '^#\tdeleted:' let add += [filename]