Make :Gblame a proper subcommand
This commit is contained in:
parent
d1033e756e
commit
0392f64a93
@ -4598,7 +4598,7 @@ function! s:BlameCommitFileLnum(...) abort
|
|||||||
let lnum = +matchstr(line, ' \zs\d\+\ze \%((\| *\d\+)\)')
|
let lnum = +matchstr(line, ' \zs\d\+\ze \%((\| *\d\+)\)')
|
||||||
let path = matchstr(line, '^\^\=\x* \+\%(\d\+ \+\d\+ \+\)\=\zs.\{-\}\ze\s\+\%(\%( \d\+ \)\@<!([^()]*\w \d\+)\|\d\+ \)')
|
let path = matchstr(line, '^\^\=\x* \+\%(\d\+ \+\d\+ \+\)\=\zs.\{-\}\ze\s\+\%(\%( \d\+ \)\@<!([^()]*\w \d\+)\|\d\+ \)')
|
||||||
if empty(path) && lnum
|
if empty(path) && lnum
|
||||||
let path = fugitive#Path(bufname(a:0 ? a:2 : s:BlameBufnr()), '')
|
let path = a:0 ? a:2 : get(s:TempState(), 'blame_file', '')
|
||||||
endif
|
endif
|
||||||
return [commit, path, lnum]
|
return [commit, path, lnum]
|
||||||
endfunction
|
endfunction
|
||||||
@ -4625,16 +4625,20 @@ function! s:BlameQuit() abort
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:BlameComplete(A, L, P) abort
|
function! s:BlameComplete(A, L, P) abort
|
||||||
return s:CompleteSub('blame', a:A, a:L, a:P, [])
|
return s:CompleteSub('blame', a:A, a:L, a:P)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:BlameCommand(line1, line2, range, count, bang, mods, reg, arg, args) abort
|
function! s:BlameSubcommand(line1, count, range, bang, mods, args) abort
|
||||||
if has_key(s:TempState(), 'blame_flags')
|
|
||||||
return substitute(s:BlameLeave(), '^$', 'bdelete', '')
|
|
||||||
endif
|
|
||||||
exe s:DirCheck()
|
exe s:DirCheck()
|
||||||
let flags = copy(a:args)
|
let flags = copy(a:args)
|
||||||
let i = 0
|
let i = 0
|
||||||
|
let raw = 0
|
||||||
|
let commits = []
|
||||||
|
let files = []
|
||||||
|
let ranges = []
|
||||||
|
if a:line1 > 0 && a:count > 0 && a:range != 1
|
||||||
|
call extend(ranges, ['-L', a:line1 . ',' . a:count])
|
||||||
|
endif
|
||||||
while i < len(flags)
|
while i < len(flags)
|
||||||
let match = matchlist(flags[i], '^\(-[a-zABDFH-KN-RT-Z]\)\ze\(.*\)')
|
let match = matchlist(flags[i], '^\(-[a-zABDFH-KN-RT-Z]\)\ze\(.*\)')
|
||||||
if len(match) && len(match[2])
|
if len(match) && len(match[2])
|
||||||
@ -4643,9 +4647,21 @@ function! s:BlameCommand(line1, line2, range, count, bang, mods, reg, arg, args)
|
|||||||
continue
|
continue
|
||||||
endif
|
endif
|
||||||
let arg = flags[i]
|
let arg = flags[i]
|
||||||
if arg =~# '^-[Lp]$\|^--\%(help\|porcelain\|line-porcelain\|incremental\|contents\)$'
|
if arg =~# '^-p$\|^--\%(help\|porcelain\|line-porcelain\|incremental\)$'
|
||||||
return 'echoerr ' . string('fugitive: blame ' . arg . ' unsupported')
|
let raw = 1
|
||||||
elseif arg =~# '^-[GLS]$\|^--\%(date\|encoding\)$'
|
elseif arg ==# '--contents' && i + 1 < len(flags)
|
||||||
|
call extend(commits, remove(flags, i, i+1))
|
||||||
|
continue
|
||||||
|
elseif arg ==# '-L' && i + 1 < len(flags)
|
||||||
|
call extend(ranges, remove(flags, i, i+1))
|
||||||
|
continue
|
||||||
|
elseif arg =~# '^--contents='
|
||||||
|
call add(commits, remove(flags, i))
|
||||||
|
continue
|
||||||
|
elseif arg =~# '^-L.'
|
||||||
|
call add(ranges, remove(flags, i))
|
||||||
|
continue
|
||||||
|
elseif arg =~# '^-[GLS]$\|^--\%(date\|encoding\|contents\)$'
|
||||||
let i += 1
|
let i += 1
|
||||||
if i == len(flags)
|
if i == len(flags)
|
||||||
echohl ErrorMsg
|
echohl ErrorMsg
|
||||||
@ -4654,32 +4670,58 @@ function! s:BlameCommand(line1, line2, range, count, bang, mods, reg, arg, args)
|
|||||||
return ''
|
return ''
|
||||||
endif
|
endif
|
||||||
elseif arg !~# '^-'
|
elseif arg !~# '^-'
|
||||||
return 'echoerr ' . string("fugitive: '-' required for all blame options")
|
if index(flags, '--') >= 0
|
||||||
elseif arg ==# '--'
|
call add(commits, remove(flags, i))
|
||||||
call remove(flags, i)
|
|
||||||
continue
|
continue
|
||||||
endif
|
endif
|
||||||
|
if s:HasOpt(flags, '--reverse') && arg =~# '\.\.' && empty(commits)
|
||||||
|
call add(commits, remove(flags, i))
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
try
|
||||||
|
let dcf = s:DirCommitFile(fugitive#Find(arg))
|
||||||
|
if len(dcf[1]) && empty(dcf[2])
|
||||||
|
call add(commits, remove(flags, i))
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
catch /^fugitive:/
|
||||||
|
endtry
|
||||||
|
call add(files, remove(flags, i))
|
||||||
|
continue
|
||||||
|
elseif arg ==# '--'
|
||||||
|
if i + 1 < len(flags)
|
||||||
|
call extend(files, remove(flags, i + 1, -1))
|
||||||
|
endif
|
||||||
|
call remove(flags, i)
|
||||||
|
break
|
||||||
|
endif
|
||||||
let i += 1
|
let i += 1
|
||||||
endwhile
|
endwhile
|
||||||
try
|
if empty(ranges + commits + files) && has_key(s:TempState(), 'blame_flags')
|
||||||
if empty(s:Relative('/'))
|
return substitute(s:BlameLeave(), '^$', 'bdelete', '')
|
||||||
call s:throw('file or blob required')
|
|
||||||
endif
|
endif
|
||||||
let commit = matchstr(s:DirCommitFile(@%)[1], '^\x\x\+$')
|
let file = substitute(get(files, 0, get(s:TempState(), 'blame_file', s:Relative('./'))), '^\.\%(/\|$\)', '', '')
|
||||||
|
if empty(commits) && len(files) > 1
|
||||||
|
call add(commits, remove(files, 1))
|
||||||
|
endif
|
||||||
|
try
|
||||||
let cmd = ['--no-pager', '-c', 'blame.coloring=none', '-c', 'blame.blankBoundary=false', 'blame', '--show-number']
|
let cmd = ['--no-pager', '-c', 'blame.coloring=none', '-c', 'blame.blankBoundary=false', 'blame', '--show-number']
|
||||||
call extend(cmd, filter(copy(flags), 'v:val !~# "\\v^%(-b|--%(no-)=color-.*|--progress)$"'))
|
call extend(cmd, filter(copy(flags), 'v:val !~# "\\v^%(-b|--%(no-)=color-.*|--progress)$"'))
|
||||||
if a:count > 0
|
if a:count > 0 && empty(ranges)
|
||||||
let cmd += ['-L', (a:line1 ? a:line1 : line('.')) . ',' . (a:line1 ? a:line1 : line('.'))]
|
let cmd += ['-L', (a:line1 ? a:line1 : line('.')) . ',' . (a:line1 ? a:line1 : line('.'))]
|
||||||
endif
|
endif
|
||||||
if len(commit)
|
call extend(cmd, ranges)
|
||||||
let cmd += [commit]
|
if len(commits)
|
||||||
elseif !s:HasOpt(flags, '--reverse')
|
let cmd += commits
|
||||||
|
elseif empty(files) && len(matchstr(s:DirCommitFile(@%)[1], '^\x\x\+$'))
|
||||||
|
let cmd += [matchstr(s:DirCommitFile(@%)[1], '^\x\x\+$')]
|
||||||
|
elseif empty(files) && !s:HasOpt(flags, '--reverse')
|
||||||
let cmd += ['--contents', '-']
|
let cmd += ['--contents', '-']
|
||||||
endif
|
endif
|
||||||
let cmd += ['--', expand('%:p')]
|
let basecmd = escape(fugitive#Prepare(cmd) . ' -- ' . s:shellesc(len(files) ? files : file), '!#%')
|
||||||
let basecmd = escape(fugitive#Prepare(cmd), '!#%')
|
let tempname = tempname()
|
||||||
let error = tempname()
|
let error = tempname . '.err'
|
||||||
let temp = error.'.fugitiveblame'
|
let temp = tempname . (raw ? '' : '.fugitiveblame')
|
||||||
if &shell =~# 'csh'
|
if &shell =~# 'csh'
|
||||||
silent! execute '%write !('.basecmd.' > '.temp.') >& '.error
|
silent! execute '%write !('.basecmd.' > '.temp.') >& '.error
|
||||||
else
|
else
|
||||||
@ -4707,12 +4749,22 @@ function! s:BlameCommand(line1, line2, range, count, bang, mods, reg, arg, args)
|
|||||||
endfor
|
endfor
|
||||||
return ''
|
return ''
|
||||||
endif
|
endif
|
||||||
if a:count > 0
|
if (a:line1 == 0 || a:range == 1) && a:count > 0
|
||||||
let edit = s:Mods(a:mods) . get(['edit', 'split', 'pedit', 'vsplit', 'tabedit'], a:count - (a:line1 ? a:line1 : 1), 'split')
|
let edit = s:Mods(a:mods) . get(['edit', 'split', 'pedit', 'vsplit', 'tabedit'], a:count - (a:line1 ? a:line1 : 1), 'split')
|
||||||
return s:BlameCommit(edit, get(readfile(temp), 0, ''), bufnr(''))
|
return s:BlameCommit(edit, get(readfile(temp), 0, ''), file)
|
||||||
else
|
else
|
||||||
let temp = s:Resolve(temp)
|
let temp = s:Resolve(temp)
|
||||||
let s:temp_files[s:cpath(temp)] = {'dir': s:Dir(), 'filetype': 'fugitiveblame', 'blame_flags': flags, 'modifiable': 0}
|
let s:temp_files[s:cpath(temp)] = {'dir': s:Dir(), 'filetype': (raw ? '' : 'fugitiveblame'), 'blame_flags': flags, 'blame_file': file, 'modifiable': 0}
|
||||||
|
if len(ranges + commits + files) || raw
|
||||||
|
if a:count != 0
|
||||||
|
exe 'silent keepalt split ' . s:fnameescape(temp)
|
||||||
|
elseif !&modified || a:bang || &bufhidden ==# 'hide' || (empty(&bufhidden) && &hidden)
|
||||||
|
exe 'silent edit' . (a:bang ? '! ' : ' ') . s:fnameescape(temp)
|
||||||
|
else
|
||||||
|
return 'edit ' . s:fnameescape(temp)
|
||||||
|
endif
|
||||||
|
return ''
|
||||||
|
endif
|
||||||
for winnr in range(winnr('$'),1,-1)
|
for winnr in range(winnr('$'),1,-1)
|
||||||
if getwinvar(winnr, '&scrollbind')
|
if getwinvar(winnr, '&scrollbind')
|
||||||
call setwinvar(winnr, '&scrollbind', 0)
|
call setwinvar(winnr, '&scrollbind', 0)
|
||||||
@ -4742,7 +4794,7 @@ function! s:BlameCommand(line1, line2, range, count, bang, mods, reg, arg, args)
|
|||||||
endif
|
endif
|
||||||
let top = line('w0') + &scrolloff
|
let top = line('w0') + &scrolloff
|
||||||
let current = line('.')
|
let current = line('.')
|
||||||
exe 'keepalt' (a:bang ? 'split' : 'leftabove vsplit') s:fnameescape(temp)
|
exe 'silent keepalt' (a:bang ? 'split' : 'leftabove vsplit') s:fnameescape(temp)
|
||||||
let w:fugitive_leave = restore
|
let w:fugitive_leave = restore
|
||||||
execute top
|
execute top
|
||||||
normal! zt
|
normal! zt
|
||||||
@ -4773,7 +4825,7 @@ function! s:BlameCommit(cmd, ...) abort
|
|||||||
if commit =~# '^0*$'
|
if commit =~# '^0*$'
|
||||||
return 'echoerr ' . string('fugitive: no commit')
|
return 'echoerr ' . string('fugitive: no commit')
|
||||||
endif
|
endif
|
||||||
let cmd = s:Open((&splitbelow ? "botright " : "topleft ") . a:cmd, 0, '', commit, [commit])
|
let cmd = s:Open((s:BlameBufnr() < 0 ? '' : &splitbelow ? "botright " : "topleft ") . a:cmd, 0, '', commit, [commit])
|
||||||
if cmd =~# '^echoerr'
|
if cmd =~# '^echoerr'
|
||||||
return cmd
|
return cmd
|
||||||
endif
|
endif
|
||||||
@ -4822,8 +4874,11 @@ function! s:BlameJump(suffix) abort
|
|||||||
let suffix = ''
|
let suffix = ''
|
||||||
endif
|
endif
|
||||||
let offset = line('.') - line('w0')
|
let offset = line('.') - line('w0')
|
||||||
let bufnr = bufnr('%')
|
let flags = get(s:TempState(), 'blame_flags', [])
|
||||||
let winnr = bufwinnr(s:BlameBufnr())
|
let blame_bufnr = s:BlameBufnr()
|
||||||
|
if blame_bufnr > 0
|
||||||
|
let bufnr = bufnr('')
|
||||||
|
let winnr = bufwinnr(blame_bufnr)
|
||||||
if winnr > 0
|
if winnr > 0
|
||||||
exe winnr.'wincmd w'
|
exe winnr.'wincmd w'
|
||||||
endif
|
endif
|
||||||
@ -4832,9 +4887,20 @@ function! s:BlameJump(suffix) abort
|
|||||||
if winnr > 0
|
if winnr > 0
|
||||||
exe bufnr.'bdelete'
|
exe bufnr.'bdelete'
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
if exists(':Gblame')
|
if exists(':Gblame')
|
||||||
let flags = get(s:TempState(), 'blame_flags', [])
|
let my_bufnr = bufnr('')
|
||||||
execute 'Gblame ' . s:fnameescape(flags)
|
if blame_bufnr < 0
|
||||||
|
let blame_args = flags + [commit . suffix, '--', path]
|
||||||
|
let result = s:BlameSubcommand(0, 0, 0, 0, '', blame_args)
|
||||||
|
else
|
||||||
|
let blame_args = flags
|
||||||
|
let result = s:BlameSubcommand(-1, -1, 0, 0, '', blame_args)
|
||||||
|
endif
|
||||||
|
if bufnr('') == my_bufnr
|
||||||
|
return result
|
||||||
|
endif
|
||||||
|
execute result
|
||||||
execute lnum
|
execute lnum
|
||||||
let delta = line('.') - line('w0') - offset
|
let delta = line('.') - line('w0') - offset
|
||||||
if delta > 0
|
if delta > 0
|
||||||
@ -4842,7 +4908,9 @@ function! s:BlameJump(suffix) abort
|
|||||||
elseif delta < 0
|
elseif delta < 0
|
||||||
execute 'normal! '.(-delta)."\<C-Y>"
|
execute 'normal! '.(-delta)."\<C-Y>"
|
||||||
endif
|
endif
|
||||||
syncbind
|
keepjumps syncbind
|
||||||
|
redraw
|
||||||
|
echo ':Gblame' s:fnameescape(blame_args)
|
||||||
endif
|
endif
|
||||||
return ''
|
return ''
|
||||||
endfunction
|
endfunction
|
||||||
@ -4951,14 +5019,12 @@ endfunction
|
|||||||
augroup fugitive_blame
|
augroup fugitive_blame
|
||||||
autocmd!
|
autocmd!
|
||||||
autocmd FileType fugitiveblame call s:BlameFileType()
|
autocmd FileType fugitiveblame call s:BlameFileType()
|
||||||
autocmd User Fugitive
|
|
||||||
\ if get(b:, 'fugitive_type') =~# '^\%(file\|blob\)$' || s:BlameBufnr() > 0 || filereadable(@%) |
|
|
||||||
\ exe "command! -buffer -bar -bang -range=-1 -nargs=* -complete=customlist,s:BlameComplete Gblame :execute s:BlameCommand(<line1>,<line2>,+'<range>',<count>,<bang>0,'<mods>',<q-reg>,<q-args>,[<f-args>])" |
|
|
||||||
\ endif
|
|
||||||
autocmd ColorScheme,GUIEnter * call s:BlameRehighlight()
|
autocmd ColorScheme,GUIEnter * call s:BlameRehighlight()
|
||||||
autocmd BufWinLeave * execute getwinvar(+bufwinnr(+expand('<abuf>')), 'fugitive_leave')
|
autocmd BufWinLeave * execute getwinvar(+bufwinnr(+expand('<abuf>')), 'fugitive_leave')
|
||||||
augroup END
|
augroup END
|
||||||
|
|
||||||
|
call s:command('-buffer -bang -range=-1 -nargs=? -complete=customlist,s:BlameComplete Gblame', 'blame')
|
||||||
|
|
||||||
" Section: :Gbrowse
|
" Section: :Gbrowse
|
||||||
|
|
||||||
call s:command("-bar -bang -range=-1 -nargs=* -complete=customlist,fugitive#CompleteObject Gbrowse", "Browse")
|
call s:command("-bar -bang -range=-1 -nargs=* -complete=customlist,fugitive#CompleteObject Gbrowse", "Browse")
|
||||||
|
@ -211,6 +211,11 @@ that are part of Git repositories).
|
|||||||
~ reblame at [count]th first grandparent
|
~ reblame at [count]th first grandparent
|
||||||
P reblame at [count]th parent (like HEAD^[count])
|
P reblame at [count]th parent (like HEAD^[count])
|
||||||
|
|
||||||
|
:[range]Gblame [flags] If a range is given, just that part of the file will
|
||||||
|
:Gblame [flags] {file} be blamed, and a horizontal split without
|
||||||
|
scrollbinding is used. You can also give an arbitrary
|
||||||
|
filename.
|
||||||
|
|
||||||
*fugitive-:Gbrowse*
|
*fugitive-:Gbrowse*
|
||||||
:Gbrowse Open the current file, blob, tree, commit, or tag
|
:Gbrowse Open the current file, blob, tree, commit, or tag
|
||||||
in your browser at the upstream hosting provider.
|
in your browser at the upstream hosting provider.
|
||||||
|
Loading…
Reference in New Issue
Block a user