mirror of
https://github.com/tpope/vim-fugitive.git
synced 2025-11-13 22:03:51 -05:00
Improve :Gstatus support for renames
Closes https://github.com/tpope/vim-fugitive/issues/1175
This commit is contained in:
@@ -2117,11 +2117,13 @@ function! s:StageInfo(...) abort
|
|||||||
let index += 1
|
let index += 1
|
||||||
endif
|
endif
|
||||||
endwhile
|
endwhile
|
||||||
|
let text = matchstr(getline(lnum), '^[A-Z?] \zs.*')
|
||||||
return {'section': section,
|
return {'section': section,
|
||||||
\ 'heading': getline(slnum),
|
\ 'heading': getline(slnum),
|
||||||
\ 'sigil': sigil,
|
\ 'sigil': sigil,
|
||||||
\ 'offset': offset,
|
\ 'offset': offset,
|
||||||
\ 'filename': matchstr(getline(lnum), '^[A-Z?] \zs.*'),
|
\ 'filename': text,
|
||||||
|
\ 'paths': reverse(split(text, ' -> ')),
|
||||||
\ 'commit': matchstr(getline(lnum), '^\%(\%(\x\x\x\)\@!\l\+\s\+\)\=\zs[0-9a-f]\{4,\}\ze '),
|
\ 'commit': matchstr(getline(lnum), '^\%(\%(\x\x\x\)\@!\l\+\s\+\)\=\zs[0-9a-f]\{4,\}\ze '),
|
||||||
\ 'status': matchstr(getline(lnum), '^[A-Z?]\ze \|^\%(\x\x\x\)\@!\l\+\ze [0-9a-f]'),
|
\ 'status': matchstr(getline(lnum), '^[A-Z?]\ze \|^\%(\x\x\x\)\@!\l\+\ze [0-9a-f]'),
|
||||||
\ 'index': index}
|
\ 'index': index}
|
||||||
@@ -2325,7 +2327,7 @@ function! s:StageInline(mode, ...) abort
|
|||||||
let lnum = lnum1 + 1
|
let lnum = lnum1 + 1
|
||||||
if a:0 > 1 && a:2 == 0
|
if a:0 > 1 && a:2 == 0
|
||||||
let info = s:StageInfo(lnum - 1)
|
let info = s:StageInfo(lnum - 1)
|
||||||
if empty(info.filename) && len(info.section)
|
if empty(info.paths) && len(info.section)
|
||||||
while len(getline(lnum))
|
while len(getline(lnum))
|
||||||
let lnum += 1
|
let lnum += 1
|
||||||
endwhile
|
endwhile
|
||||||
@@ -2355,7 +2357,7 @@ function! s:StageInline(mode, ...) abort
|
|||||||
endif
|
endif
|
||||||
continue
|
continue
|
||||||
endif
|
endif
|
||||||
if !has_key(b:fugitive_diff, info.section) || info.status !~# '^[ADM]$' || a:mode ==# 'hide'
|
if !has_key(b:fugitive_diff, info.section) || info.status !~# '^[ADMR]$' || a:mode ==# 'hide'
|
||||||
continue
|
continue
|
||||||
endif
|
endif
|
||||||
let mode = ''
|
let mode = ''
|
||||||
@@ -2372,9 +2374,9 @@ function! s:StageInline(mode, ...) abort
|
|||||||
endif
|
endif
|
||||||
let start = index
|
let start = index
|
||||||
let mode = 'head'
|
let mode = 'head'
|
||||||
elseif mode ==# 'head' && substitute(line, "\t$", '', '') ==# '--- ' . info.filename
|
elseif mode ==# 'head' && substitute(line, "\t$", '', '') ==# '--- ' . info.paths[-1]
|
||||||
let mode = 'await'
|
let mode = 'await'
|
||||||
elseif mode ==# 'head' && substitute(line, "\t$", '', '') ==# '+++ ' . info.filename
|
elseif mode ==# 'head' && substitute(line, "\t$", '', '') ==# '+++ ' . info.paths[0]
|
||||||
let mode = 'await'
|
let mode = 'await'
|
||||||
elseif mode ==# 'capture'
|
elseif mode ==# 'capture'
|
||||||
call add(diff, line)
|
call add(diff, line)
|
||||||
@@ -2414,32 +2416,31 @@ function! s:StageDiff(diff) abort
|
|||||||
let lnum = line('.')
|
let lnum = line('.')
|
||||||
let info = s:StageInfo(lnum)
|
let info = s:StageInfo(lnum)
|
||||||
let prefix = info.offset > 0 ? '+' . info.offset : ''
|
let prefix = info.offset > 0 ? '+' . info.offset : ''
|
||||||
if empty(info.filename) && info.section ==# 'Staged'
|
if empty(info.paths) && info.section ==# 'Staged'
|
||||||
return 'Git! diff --no-ext-diff --cached'
|
return 'Git! diff --no-ext-diff --cached'
|
||||||
elseif empty(info.filename)
|
elseif empty(info.paths)
|
||||||
return 'Git! diff --no-ext-diff'
|
return 'Git! diff --no-ext-diff'
|
||||||
elseif info.filename =~# ' -> '
|
elseif len(info.paths) > 1
|
||||||
let [old, new] = split(info.filename,' -> ')
|
execute 'Gedit' . prefix s:fnameescape(':0:' . info.paths[0])
|
||||||
execute 'Gedit' . prefix s:fnameescape(':0:'.new)
|
return a:diff.' HEAD:'.s:fnameescape(info.paths[1])
|
||||||
return a:diff.' HEAD:'.s:fnameescape(old)
|
|
||||||
elseif info.section ==# 'Staged' && info.sigil ==# '-'
|
elseif info.section ==# 'Staged' && info.sigil ==# '-'
|
||||||
execute 'Gedit' prefix s:fnameescape('@:'.info.filename)
|
execute 'Gedit' prefix s:fnameescape('@:'.info.paths[0])
|
||||||
return a:diff.'! :0'
|
return a:diff.'! :0'
|
||||||
elseif info.section ==# 'Staged'
|
elseif info.section ==# 'Staged'
|
||||||
execute 'Gedit' prefix s:fnameescape(':0:'.info.filename)
|
execute 'Gedit' prefix s:fnameescape(':0:'.info.paths[0])
|
||||||
return a:diff . (info.sigil ==# '+' ? '!' : '') . ' -'
|
return a:diff . (info.sigil ==# '+' ? '!' : '') . ' -'
|
||||||
elseif info.sigil ==# '-'
|
elseif info.sigil ==# '-'
|
||||||
execute 'Gedit' prefix s:fnameescape(':0:'.info.filename)
|
execute 'Gedit' prefix s:fnameescape(':0:'.info.paths[0])
|
||||||
return a:diff . '!'
|
return a:diff . '!'
|
||||||
else
|
else
|
||||||
execute 'Gedit' prefix s:fnameescape(':(top)'.info.filename)
|
execute 'Gedit' prefix s:fnameescape(':(top)'.info.paths[0])
|
||||||
return a:diff . (info.sigil ==# '+' ? '!' : '')
|
return a:diff . (info.sigil ==# '+' ? '!' : '')
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:StageDiffEdit() abort
|
function! s:StageDiffEdit() abort
|
||||||
let info = s:StageInfo(line('.'))
|
let info = s:StageInfo(line('.'))
|
||||||
let arg = (empty(info.filename) ? '.' : info.filename)
|
let arg = (empty(info.paths) ? '.' : info.paths[0])
|
||||||
if info.section ==# 'Staged'
|
if info.section ==# 'Staged'
|
||||||
return 'Git! diff --no-ext-diff --cached '.s:shellesc(arg)
|
return 'Git! diff --no-ext-diff --cached '.s:shellesc(arg)
|
||||||
elseif info.status ==# '?'
|
elseif info.status ==# '?'
|
||||||
@@ -2451,6 +2452,9 @@ function! s:StageDiffEdit() abort
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:StageApply(info, reverse, extra) abort
|
function! s:StageApply(info, reverse, extra) abort
|
||||||
|
if a:info.status ==# 'R'
|
||||||
|
call s:throw('fugitive: patching renamed file not yet supported')
|
||||||
|
endif
|
||||||
let cmd = ['apply', '-p0', '--recount'] + a:extra
|
let cmd = ['apply', '-p0', '--recount'] + a:extra
|
||||||
let info = a:info
|
let info = a:info
|
||||||
let start = info.patch
|
let start = info.patch
|
||||||
@@ -2531,7 +2535,7 @@ function! s:StageDelete(lnum, count) abort
|
|||||||
exe s:ReloadStatus()
|
exe s:ReloadStatus()
|
||||||
let @@ = hash
|
let @@ = hash
|
||||||
return 'checktime|redraw|echomsg ' .
|
return 'checktime|redraw|echomsg ' .
|
||||||
\ string('To restore, :Git cat-file blob '.hash[0:6].' > '.info.filename)
|
\ string('To restore, :Git cat-file blob '.hash[0:6].' > '.info.paths[0])
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:DoToggleHeadHeader(value) abort
|
function! s:DoToggleHeadHeader(value) abort
|
||||||
@@ -2628,20 +2632,18 @@ function! s:StagePatch(lnum1,lnum2) abort
|
|||||||
|
|
||||||
for lnum in range(a:lnum1,a:lnum2)
|
for lnum in range(a:lnum1,a:lnum2)
|
||||||
let info = s:StageInfo(lnum)
|
let info = s:StageInfo(lnum)
|
||||||
if empty(info.filename) && info.section ==# 'Staged'
|
if empty(info.paths) && info.section ==# 'Staged'
|
||||||
return 'Git reset --patch'
|
return 'Git reset --patch'
|
||||||
elseif empty(info.filename) && info.section ==# 'Unstaged'
|
elseif empty(info.paths) && info.section ==# 'Unstaged'
|
||||||
return 'Git add --patch'
|
return 'Git add --patch'
|
||||||
elseif info.filename ==# ''
|
elseif empty(info.paths) ==# ''
|
||||||
continue
|
continue
|
||||||
endif
|
endif
|
||||||
execute lnum
|
execute lnum
|
||||||
if info.filename =~ ' -> '
|
if info.section ==# 'Staged'
|
||||||
let reset += [split(info.filename,' -> ')[1]]
|
let reset += info.paths
|
||||||
elseif info.section ==# 'Staged'
|
|
||||||
let reset += [info.filename]
|
|
||||||
elseif info.status !~# '^D'
|
elseif info.status !~# '^D'
|
||||||
let add += [info.filename]
|
let add += info.paths
|
||||||
endif
|
endif
|
||||||
endfor
|
endfor
|
||||||
try
|
try
|
||||||
@@ -4398,16 +4400,16 @@ function! s:StatusCfile(...) abort
|
|||||||
let lead = s:cpath(tree, getcwd()) ? './' : tree . '/'
|
let lead = s:cpath(tree, getcwd()) ? './' : tree . '/'
|
||||||
let info = s:StageInfo()
|
let info = s:StageInfo()
|
||||||
let line = getline('.')
|
let line = getline('.')
|
||||||
if len(info.sigil) && len(info.section) && len(info.filename)
|
if len(info.sigil) && len(info.section) && len(info.paths)
|
||||||
if info.section ==# 'Unstaged' && info.sigil !=# '-'
|
if info.section ==# 'Unstaged' && info.sigil !=# '-'
|
||||||
return [lead . info.filename, info.offset, 'normal!zv']
|
return [lead . info.paths[0], info.offset, 'normal!zv']
|
||||||
elseif info.section ==# 'Staged' && info.sigil ==# '-'
|
elseif info.section ==# 'Staged' && info.sigil ==# '-'
|
||||||
return ['@:' . info.filename, info.offset, 'normal!zv']
|
return ['@:' . info.paths[0], info.offset, 'normal!zv']
|
||||||
else
|
else
|
||||||
return [':0:' . info.filename, info.offset, 'normal!zv']
|
return [':0:' . info.paths[0], info.offset, 'normal!zv']
|
||||||
endif
|
endif
|
||||||
elseif len(info.filename)
|
elseif len(info.paths)
|
||||||
return [lead . info.filename]
|
return [lead . info.paths[0]]
|
||||||
elseif len(info.commit)
|
elseif len(info.commit)
|
||||||
return [info.commit]
|
return [info.commit]
|
||||||
elseif line =~# '^\%(Head\|Merge\|Rebase\|Upstream\|Pull\|Push\): '
|
elseif line =~# '^\%(Head\|Merge\|Rebase\|Upstream\|Pull\|Push\): '
|
||||||
|
|||||||
Reference in New Issue
Block a user