Support nearly all git-blame flags
This commit is contained in:
parent
7686b7dc5c
commit
4daa0c558c
@ -4558,7 +4558,7 @@ augroup fugitive_blame
|
||||
autocmd FileType fugitiveblame setlocal nomodeline | if len(s:Dir()) | let &l:keywordprg = s:Keywordprg() | endif
|
||||
autocmd User Fugitive
|
||||
\ if get(b:, 'fugitive_type') =~# '^\%(file\|blob\)$' || s:BlameBufnr() > 0 || filereadable(@%) |
|
||||
\ exe "command! -buffer -bar -bang -range=-1 -nargs=* Gblame :execute s:BlameCommand(<line1>,<line2>,+'<range>',<count>,<bang>0,'<mods>',<q-reg>,<q-args>,[<f-args>])" |
|
||||
\ 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:RehighlightBlame()
|
||||
autocmd BufWinLeave * execute getwinvar(+bufwinnr(+expand('<abuf>')), 'fugitive_leave')
|
||||
@ -4583,6 +4583,20 @@ function! s:BlameBufnr(...) abort
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:BlameCommitFileLnum(...) abort
|
||||
let line = a:0 ? a:1 : getline('.')
|
||||
let commit = matchstr(line, '^\^\=\zs\x\+')
|
||||
if commit =~# '^0\+$'
|
||||
let commit = ''
|
||||
endif
|
||||
let lnum = +matchstr(line, ' \zs\d\+\ze \%((\| *\d\+)\)')
|
||||
let path = matchstr(line, '^\^\=\x* \+\%(\d\+ \+\d\+ \+\)\=\zs.\{-\}\ze\s\+\%(\%( \d\+ \)\@<!([^()]*\w \d\+)\|\d\+ \)')
|
||||
if empty(path) && lnum
|
||||
let path = fugitive#Path(bufname(a:0 ? a:2 : s:BlameBufnr()), '')
|
||||
endif
|
||||
return [commit, path, lnum]
|
||||
endfunction
|
||||
|
||||
function! s:BlameLeave() abort
|
||||
let bufwinnr = bufwinnr(s:BlameBufnr())
|
||||
if bufwinnr > 0
|
||||
@ -4604,29 +4618,56 @@ function! s:BlameQuit() abort
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:BlameComplete(A, L, P) abort
|
||||
return s:CompleteSub('blame', a:A, a:L, a:P, [])
|
||||
endfunction
|
||||
|
||||
function! s:BlameCommand(line1, line2, range, count, bang, mods, reg, arg, args) abort
|
||||
if exists('b:fugitive_blame_arguments')
|
||||
if has_key(s:TempState(), 'blame_flags')
|
||||
return substitute(s:BlameLeave(), '^$', 'bdelete', '')
|
||||
endif
|
||||
exe s:DirCheck()
|
||||
let flags = copy(a:args)
|
||||
let i = 0
|
||||
while i < len(flags)
|
||||
let match = matchlist(flags[i], '^\(-[a-zABDFH-KN-RT-Z]\)\ze\(.*\)')
|
||||
if len(match) && len(match[2])
|
||||
call insert(flags, match[1])
|
||||
let flags[i+1] = '-' . match[2]
|
||||
continue
|
||||
endif
|
||||
let arg = flags[i]
|
||||
if arg =~# '^-[Lp]$\|^--\%(help\|porcelain\|line-porcelain\|incremental\|contents\)$'
|
||||
return 'echoerr ' . string('fugitive: blame ' . arg . ' unsupported')
|
||||
elseif arg =~# '^-[GLS]$\|^--\%(date\|encoding\)$'
|
||||
let i += 1
|
||||
if i == len(flags)
|
||||
echohl ErrorMsg
|
||||
echo s:ChompError(['blame', arg])[0]
|
||||
echohl NONE
|
||||
return ''
|
||||
endif
|
||||
elseif arg !~# '^-'
|
||||
return 'echoerr ' . string("fugitive: '-' required for all blame options")
|
||||
elseif arg ==# '--'
|
||||
call remove(flags, i)
|
||||
continue
|
||||
endif
|
||||
let i += 1
|
||||
endwhile
|
||||
try
|
||||
if empty(s:Relative('/'))
|
||||
call s:throw('file or blob required')
|
||||
endif
|
||||
let commit = matchstr(s:DirCommitFile(@%)[1], '^\x\x\+$')
|
||||
if filter(copy(a:args),'v:val !~# "^-"') != []
|
||||
call s:throw("'-' required for all options")
|
||||
elseif filter(copy(a:args),'v:val !~# "^\\%(--abbrev=\\d*\\|--relative-date\\|--first-parent\\|--root\\|--show-name' . (len(commit) ? '\\|--reverse' : '') . '\\|-\\%([ltfnsew]\\|[MC]\\d*\\)\\+\\)$"') != []
|
||||
call s:throw('unsupported option' . commit)
|
||||
endif
|
||||
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)$"'))
|
||||
if a:count > 0
|
||||
let cmd += ['-L', (a:line1 ? a:line1 : line('.')) . ',' . (a:line1 ? a:line1 : line('.'))]
|
||||
endif
|
||||
let cmd += a:args
|
||||
if len(commit)
|
||||
let cmd += [commit]
|
||||
else
|
||||
elseif !s:HasOpt(flags, '--reverse')
|
||||
let cmd += ['--contents', '-']
|
||||
endif
|
||||
let cmd += ['--', expand('%:p')]
|
||||
@ -4638,16 +4679,34 @@ function! s:BlameCommand(line1, line2, range, count, bang, mods, reg, arg, args)
|
||||
else
|
||||
silent! execute '%write !'.basecmd.' > '.temp.' 2> '.error
|
||||
endif
|
||||
redraw
|
||||
try
|
||||
if v:shell_error
|
||||
call s:throw(join(readfile(error),"\n"))
|
||||
let lines = readfile(error)
|
||||
if empty(lines)
|
||||
let lines = readfile(temp)
|
||||
endif
|
||||
for i in range(len(lines))
|
||||
if lines[i] =~# '^error: \|^fatal: '
|
||||
echohl ErrorMsg
|
||||
echon lines[i]
|
||||
echohl NONE
|
||||
break
|
||||
else
|
||||
echon lines[i]
|
||||
endif
|
||||
if i != len(lines) - 1
|
||||
echon "\n"
|
||||
endif
|
||||
endfor
|
||||
return ''
|
||||
endif
|
||||
if a:count > 0
|
||||
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(''))
|
||||
else
|
||||
let temp = s:Resolve(temp)
|
||||
let s:temp_files[s:cpath(temp)] = {'dir': s:Dir(), 'filetype': 'fugitiveblame', 'args': cmd, 'modifiable': 0}
|
||||
let s:temp_files[s:cpath(temp)] = {'dir': s:Dir(), 'filetype': 'fugitiveblame', 'blame_flags': flags, 'modifiable': 0}
|
||||
for winnr in range(winnr('$'),1,-1)
|
||||
if getwinvar(winnr, '&scrollbind')
|
||||
call setwinvar(winnr, '&scrollbind', 0)
|
||||
@ -4679,7 +4738,6 @@ function! s:BlameCommand(line1, line2, range, count, bang, mods, reg, arg, args)
|
||||
let current = line('.')
|
||||
exe 'keepalt' (a:bang ? 'split' : 'leftabove vsplit') s:fnameescape(temp)
|
||||
let w:fugitive_leave = restore
|
||||
let b:fugitive_blame_arguments = join(a:args,' ')
|
||||
execute top
|
||||
normal! zt
|
||||
execute current
|
||||
@ -4705,9 +4763,9 @@ function! s:BlameCommand(line1, line2, range, count, bang, mods, reg, arg, args)
|
||||
nnoremap <buffer> <silent> P :<C-U>exe <SID>BlameJump('^'.v:count1)<CR>
|
||||
nnoremap <buffer> <silent> ~ :<C-U>exe <SID>BlameJump('~'.v:count1)<CR>
|
||||
nnoremap <buffer> <silent> i :<C-U>exe <SID>BlameCommit("exe <SID>BlameLeave()<Bar>edit")<CR>
|
||||
nnoremap <buffer> <silent> o :<C-U>exe <SID>BlameCommit((&splitbelow ? "botright" : "topleft")." split")<CR>
|
||||
nnoremap <buffer> <silent> o :<C-U>exe <SID>BlameCommit("split")<CR>
|
||||
nnoremap <buffer> <silent> O :<C-U>exe <SID>BlameCommit("tabedit")<CR>
|
||||
nnoremap <buffer> <silent> p :<C-U>exe <SID>Open((&splitbelow ? "botright" : "topleft").' pedit', 0, '', matchstr(getline('.'), '\x\+'), [matchstr(getline('.'), '\x\+')])<CR>
|
||||
nnoremap <buffer> <silent> p :<C-U>exe <SID>BlameCommit("pedit")<CR>
|
||||
nnoremap <buffer> <silent> A :<C-u>exe "vertical resize ".(<SID>linechars('.\{-\}\ze [0-9:/+-][0-9:/+ -]* \d\+)')+1+v:count)<CR>
|
||||
nnoremap <buffer> <silent> C :<C-u>exe "vertical resize ".(<SID>linechars('^\S\+')+1+v:count)<CR>
|
||||
nnoremap <buffer> <silent> D :<C-u>exe "vertical resize ".(<SID>linechars('.\{-\}\ze\d\ze\s\+\d\+)')+1-v:count)<CR>
|
||||
@ -4722,24 +4780,16 @@ function! s:BlameCommand(line1, line2, range, count, bang, mods, reg, arg, args)
|
||||
endfunction
|
||||
|
||||
function! s:BlameCommit(cmd, ...) abort
|
||||
let line = a:0 ? a:1 : getline('.')
|
||||
if line =~# '^0\{4,\} '
|
||||
return 'echoerr ' . string('Not Committed Yet')
|
||||
let [commit, path, lnum] = call('s:BlameCommitFileLnum', a:000)
|
||||
if commit =~# '^0*$'
|
||||
return 'echoerr ' . string('fugitive: no commit')
|
||||
endif
|
||||
let cmd = s:Open(a:cmd, 0, '', matchstr(line, '\x\+'), [matchstr(line, '\x\+')])
|
||||
let cmd = s:Open((&splitbelow ? "botright " : "topleft ") . a:cmd, 0, '', commit, [commit])
|
||||
if cmd =~# '^echoerr'
|
||||
return cmd
|
||||
endif
|
||||
let lnum = matchstr(line, ' \zs\d\+\ze\s\+[([:digit:]]')
|
||||
let path = matchstr(line, '^\^\=\x\+\s\+\zs.\{-\}\ze\s*\d\+ ')
|
||||
if empty(path)
|
||||
let path = fugitive#Path(bufname(a:0 ? a:2 : s:BlameBufnr()), '')
|
||||
endif
|
||||
if empty(path)
|
||||
return 'echoerr ' . string('fugitive: could not determine filename for blame')
|
||||
endif
|
||||
execute cmd
|
||||
if a:cmd ==# 'pedit'
|
||||
if a:cmd ==# 'pedit' || empty(path)
|
||||
return ''
|
||||
endif
|
||||
if search('^diff .* b/\M'.escape(path,'\').'$','W')
|
||||
@ -4773,25 +4823,18 @@ function! s:BlameCommit(cmd, ...) abort
|
||||
endfunction
|
||||
|
||||
function! s:BlameJump(suffix) abort
|
||||
let commit = matchstr(getline('.'),'^\^\=\zs\x\+')
|
||||
let suffix = a:suffix
|
||||
if commit =~# '^0\+$'
|
||||
let commit = 'HEAD'
|
||||
let suffix = ''
|
||||
endif
|
||||
let lnum = matchstr(getline('.'),' \zs\d\+\ze\s\+[([:digit:]]')
|
||||
let path = matchstr(getline('.'),'^\^\=\x\+\s\+\zs.\{-\}\ze\s*\d\+ ')
|
||||
let original_bufnr = s:BlameBufnr()
|
||||
if empty(path)
|
||||
let path = fugitive#Path(bufname(original_bufnr), '')
|
||||
endif
|
||||
let [commit, path, lnum] = s:BlameCommitFileLnum()
|
||||
if empty(path)
|
||||
return 'echoerr ' . string('fugitive: could not determine filename for blame')
|
||||
endif
|
||||
let args = get(b:, 'fugitive_blame_arguments', '')
|
||||
if commit =~# '^0*$'
|
||||
let commit = 'HEAD'
|
||||
let suffix = ''
|
||||
endif
|
||||
let offset = line('.') - line('w0')
|
||||
let bufnr = bufnr('%')
|
||||
let winnr = bufwinnr(original_bufnr)
|
||||
let winnr = bufwinnr(s:BlameBufnr())
|
||||
if winnr > 0
|
||||
exe winnr.'wincmd w'
|
||||
endif
|
||||
@ -4801,7 +4844,8 @@ function! s:BlameJump(suffix) abort
|
||||
exe bufnr.'bdelete'
|
||||
endif
|
||||
if exists(':Gblame')
|
||||
execute 'Gblame '.args
|
||||
let flags = get(s:TempState(), 'blame_flags', [])
|
||||
execute 'Gblame ' . s:fnameescape(flags)
|
||||
execute lnum
|
||||
let delta = line('.') - line('w0') - offset
|
||||
if delta > 0
|
||||
@ -4819,10 +4863,11 @@ let s:hash_colors = {}
|
||||
function! fugitive#BlameSyntax() abort
|
||||
let conceal = has('conceal') ? ' conceal' : ''
|
||||
let config = fugitive#Config()
|
||||
let flags = get(s:TempState(), 'blame_flags', [])
|
||||
syn match FugitiveblameBlank "^\s\+\s\@=" nextgroup=FugitiveblameAnnotation,FugitiveblameScoreDebug,FugitiveblameOriginalFile,FugitiveblameOriginalLineNumber skipwhite
|
||||
syn match FugitiveblameHash "\%(^\^\=\)\@<=\<\x\{7,\}\>" nextgroup=FugitiveblameAnnotation,FugitiveblameScoreDebug,FugitiveblameOriginalLineNumber,FugitiveblameOriginalFile skipwhite
|
||||
syn match FugitiveblameUncommitted "\%(^\^\=\)\@<=\<0\{7,\}\>" nextgroup=FugitiveblameAnnotation,FugitiveblameScoreDebug,FugitiveblameOriginalLineNumber,FugitiveblameOriginalFile skipwhite
|
||||
if get(get(config, 'blame.blankboundary', ['x']), 0, 'x') =~# '^$\|^true$'
|
||||
if get(get(config, 'blame.blankboundary', ['x']), 0, 'x') =~# '^$\|^true$' || s:HasOpt(flags, '-b')
|
||||
syn match FugitiveblameBoundaryIgnore "^\^\x\{7,\}\>" nextgroup=FugitiveblameAnnotation,FugitiveblameScoreDebug,FugitiveblameOriginalLineNumber,FugitiveblameOriginalFile skipwhite
|
||||
else
|
||||
syn match FugitiveblameBoundary "^\^"
|
||||
@ -4831,9 +4876,9 @@ function! fugitive#BlameSyntax() abort
|
||||
syn region FugitiveblameAnnotation matchgroup=FugitiveblameDelimiter start="(" end="\%(\s\d\+\)\@<=)" contained keepend oneline
|
||||
syn match FugitiveblameTime "[0-9:/+-][0-9:/+ -]*[0-9:/+-]\%(\s\+\d\+)\)\@=" contained containedin=FugitiveblameAnnotation
|
||||
exec 'syn match FugitiveblameLineNumber "\s*\d\+)\@=" contained containedin=FugitiveblameAnnotation' conceal
|
||||
exec 'syn match FugitiveblameOriginalFile "\s\%(\f\+\D\@<=\|\D\@=\f\+\)\%(\%(\s\+\d\+\)\=\s\%((\|\s*\d\+)\)\)\@=" contained nextgroup=FugitiveblameOriginalLineNumber,FugitiveblameAnnotation skipwhite' conceal
|
||||
exec 'syn match FugitiveblameOriginalLineNumber "\s*\d\+\%(\s(\)\@=" contained nextgroup=FugitiveblameAnnotation skipwhite' conceal
|
||||
exec 'syn match FugitiveblameOriginalLineNumber "\s*\d\+\%(\s\+\d\+)\)\@=" contained nextgroup=FugitiveblameShort skipwhite' conceal
|
||||
exec 'syn match FugitiveblameOriginalFile "\s\%(\f\+\D\@<=\|\D\@=\f\+\)\%(\%(\s\+\d\+\)\=\s\%((\|\s*\d\+)\)\)\@=" contained nextgroup=FugitiveblameOriginalLineNumber,FugitiveblameAnnotation skipwhite' (s:HasOpt(flags, '--show-name', '-f') ? '' : conceal)
|
||||
exec 'syn match FugitiveblameOriginalLineNumber "\s*\d\+\%(\s(\)\@=" contained nextgroup=FugitiveblameAnnotation skipwhite' (s:HasOpt(flags, '--show-number', '-n') ? '' : conceal)
|
||||
exec 'syn match FugitiveblameOriginalLineNumber "\s*\d\+\%(\s\+\d\+)\)\@=" contained nextgroup=FugitiveblameShort skipwhite' (s:HasOpt(flags, '--show-number', '-n') ? '' : conceal)
|
||||
syn match FugitiveblameShort " \d\+)" contained contains=FugitiveblameLineNumber
|
||||
syn match FugitiveblameNotCommittedYet "(\@<=Not Committed Yet\>" contained containedin=FugitiveblameAnnotation
|
||||
hi def link FugitiveblameBoundary Keyword
|
||||
@ -4848,7 +4893,7 @@ function! fugitive#BlameSyntax() abort
|
||||
hi def link FugitiveblameShort FugitiveblameDelimiter
|
||||
hi def link FugitiveblameDelimiter Delimiter
|
||||
hi def link FugitiveblameNotCommittedYet Comment
|
||||
if !get(g:, 'fugitive_dynamic_colors', 1)
|
||||
if !get(g:, 'fugitive_dynamic_colors', 1) && !s:HasOpt(flags, '--color-lines') || s:HasOpt(flags, '--no-color-lines')
|
||||
return
|
||||
endif
|
||||
let seen = {}
|
||||
|
@ -193,11 +193,10 @@ that are part of Git repositories).
|
||||
:Gremove Like :Gdelete, but keep the (now empty) buffer around.
|
||||
|
||||
*fugitive-:Gblame*
|
||||
:Gblame [flags] Run git-blame on the file and open the results in a
|
||||
scroll-bound vertical split. You can give any of
|
||||
-ltsewMC as flags, and they will be passed along to
|
||||
git-blame. The following maps, which work on the
|
||||
cursor line commit where sensible, are provided:
|
||||
:Gblame [flags] Run git-blame [flags] on the current file and open the
|
||||
results in a scroll-bound vertical split. The
|
||||
following maps, which work on the cursor line commit
|
||||
where sensible, are provided:
|
||||
|
||||
g? show this help
|
||||
A resize to end of author column
|
||||
|
Loading…
Reference in New Issue
Block a user