Map <CR> in blobs to jump to blamed commit

This commit is contained in:
Tim Pope 2018-07-25 00:29:03 -04:00
parent 8edc9cd006
commit 4b0475f9d8
2 changed files with 57 additions and 40 deletions

View File

@ -2285,7 +2285,10 @@ augroup fugitive_blame
autocmd! autocmd!
autocmd FileType fugitiveblame setlocal nomodeline | if exists('b:git_dir') | let &l:keywordprg = s:Keywordprg() | endif autocmd FileType fugitiveblame setlocal nomodeline | if exists('b:git_dir') | let &l:keywordprg = s:Keywordprg() | endif
autocmd Syntax fugitiveblame call s:BlameSyntax() autocmd Syntax fugitiveblame call s:BlameSyntax()
autocmd User Fugitive if s:buffer().type('file', 'blob', 'blame') | exe "command! -buffer -bar -bang -range=0 -nargs=* Gblame :execute s:Blame(<bang>0,<line1>,<line2>,<count>,[<f-args>])" | endif autocmd User Fugitive
\ if get(b:, 'fugitive_type') =~# '^\%(file\|blob\|blame\)$' |
\ exe "command! -buffer -bar -bang -range=0 -nargs=* Gblame :execute s:Blame(<bang>0,<line1>,<line2>,<count>,'<mods>',[<f-args>])" |
\ endif
autocmd ColorScheme,GUIEnter * call s:RehighlightBlame() autocmd ColorScheme,GUIEnter * call s:RehighlightBlame()
autocmd BufWinLeave * execute getwinvar(+bufwinnr(+expand('<abuf>')), 'fugitive_leave') autocmd BufWinLeave * execute getwinvar(+bufwinnr(+expand('<abuf>')), 'fugitive_leave')
augroup END augroup END
@ -2300,7 +2303,7 @@ function! s:linechars(pattern) abort
return chars return chars
endfunction endfunction
function! s:Blame(bang,line1,line2,count,args) abort function! s:Blame(bang, line1, line2, count, mods, args) abort
if exists('b:fugitive_blamed_bufnr') if exists('b:fugitive_blamed_bufnr')
return 'bdelete' return 'bdelete'
endif endif
@ -2312,7 +2315,11 @@ function! s:Blame(bang,line1,line2,count,args) abort
call s:throw('unsupported option') call s:throw('unsupported option')
endif endif
call map(a:args,'s:sub(v:val,"^\\ze[^-]","-")') call map(a:args,'s:sub(v:val,"^\\ze[^-]","-")')
let cmd = ['--no-pager', 'blame', '--show-number'] + a:args let cmd = ['--no-pager', 'blame', '--show-number']
if a:count
let cmd += ['-L', a:line1 . ',' . a:line1]
endif
let cmd += a:args
if s:DirCommitFile(@%)[1] =~# '\D\|..' if s:DirCommitFile(@%)[1] =~# '\D\|..'
let cmd += [s:DirCommitFile(@%)[1]] let cmd += [s:DirCommitFile(@%)[1]]
else else
@ -2322,27 +2329,29 @@ function! s:Blame(bang,line1,line2,count,args) abort
let basecmd = escape(call('fugitive#Prepare', cmd), '!#%') let basecmd = escape(call('fugitive#Prepare', cmd), '!#%')
try try
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd' let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
if !s:repo().bare() let tree = FugitiveTreeForGitDir(b:git_dir)
let dir = getcwd() if len(tree) && s:cpath(tree) !=# s:cpath(getcwd())
execute cd s:fnameescape(s:repo().tree()) let cwd = getcwd()
execute cd s:fnameescape(tree)
endif
let error = s:tempname()
let temp = error.'.fugitiveblame'
if &shell =~# 'csh'
silent! execute '%write !('.basecmd.' > '.temp.') >& '.error
else
silent! execute '%write !'.basecmd.' > '.temp.' 2> '.error
endif
if exists('l:cwd')
execute cd s:fnameescape(cwd)
unlet cwd
endif
if v:shell_error
call s:throw(join(readfile(error),"\n"))
endif endif
if a:count if a:count
execute 'write !'.substitute(basecmd,' blame ',' blame -L '.a:line1.','.a:line2.' ','g') let edit = substitute(a:mods, '^<mods>$', '', '') . get(['edit', 'split', 'pedit'], a:line2 - a:line1, ' split')
return s:BlameCommit(edit, get(readfile(temp), 0, ''))
else else
let error = s:tempname()
let temp = error.'.fugitiveblame'
if &shell =~# 'csh'
silent! execute '%write !('.basecmd.' > '.temp.') >& '.error
else
silent! execute '%write !'.basecmd.' > '.temp.' 2> '.error
endif
if exists('l:dir')
execute cd s:fnameescape(dir)
unlet dir
endif
if v:shell_error
call s:throw(join(readfile(error),"\n"))
endif
for winnr in range(winnr('$'),1,-1) for winnr in range(winnr('$'),1,-1)
call setwinvar(winnr, '&scrollbind', 0) call setwinvar(winnr, '&scrollbind', 0)
if exists('+cursorbind') if exists('+cursorbind')
@ -2408,8 +2417,8 @@ function! s:Blame(bang,line1,line2,count,args) abort
syncbind syncbind
endif endif
finally finally
if exists('l:dir') if exists('l:cwd')
execute cd s:fnameescape(dir) execute cd s:fnameescape(cwd)
endif endif
endtry endtry
return '' return ''
@ -2418,8 +2427,8 @@ function! s:Blame(bang,line1,line2,count,args) abort
endtry endtry
endfunction endfunction
function! s:BlameCommit(cmd) abort function! s:BlameCommit(cmd, ...) abort
let line = getline('.') let line = a:0 ? a:1 : getline('.')
if line =~# '^0\{4,40\} ' if line =~# '^0\{4,40\} '
return 'echoerr ' . string('Not Committed Yet') return 'echoerr ' . string('Not Committed Yet')
endif endif
@ -2430,9 +2439,12 @@ function! s:BlameCommit(cmd) abort
let lnum = matchstr(line, ' \zs\d\+\ze\s\+[([:digit:]]') let lnum = matchstr(line, ' \zs\d\+\ze\s\+[([:digit:]]')
let path = matchstr(line, '^\^\=\x\+\s\+\zs.\{-\}\ze\s*\d\+ ') let path = matchstr(line, '^\^\=\x\+\s\+\zs.\{-\}\ze\s*\d\+ ')
if path ==# '' if path ==# ''
let path = fugitive#Path(bufname(b:fugitive_blamed_bufnr), '') let path = fugitive#Path(a:0 ? @% : bufname(b:fugitive_blamed_bufnr), '')
endif endif
execute cmd execute cmd
if a:cmd ==# 'pedit'
return ''
endif
if search('^diff .* b/\M'.escape(path,'\').'$','W') if search('^diff .* b/\M'.escape(path,'\').'$','W')
call search('^+++') call search('^+++')
let head = line('.') let head = line('.')
@ -3087,12 +3099,29 @@ function! s:NavigateUp(count) abort
endfunction endfunction
function! fugitive#MapJumps(...) abort function! fugitive#MapJumps(...) abort
nnoremap <buffer> <silent> <CR> :<C-U>exe <SID>GF("edit")<CR> if get(b:, 'fugitive_type', '') ==# 'blob'
nnoremap <buffer> <silent> <CR> :<C-U>.Gblame<CR>
else
nnoremap <buffer> <silent> <CR> :<C-U>exe <SID>GF("edit")<CR>
endif
if !&modifiable if !&modifiable
nnoremap <buffer> <silent> o :<C-U>exe <SID>GF("split")<CR> nnoremap <buffer> <silent> o :<C-U>exe <SID>GF("split")<CR>
nnoremap <buffer> <silent> S :<C-U>exe <SID>GF("vsplit")<CR> nnoremap <buffer> <silent> S :<C-U>exe <SID>GF("vsplit")<CR>
nnoremap <buffer> <silent> O :<C-U>exe <SID>GF("tabedit")<CR> nnoremap <buffer> <silent> O :<C-U>exe <SID>GF("tabedit")<CR>
nnoremap <buffer> <silent> p :<C-U>exe <SID>GF("pedit")<CR> nnoremap <buffer> <silent> o :<C-U>exe <SID>GF("split")<CR>
nnoremap <buffer> <silent> S :<C-U>exe <SID>GF("vsplit")<CR>
nnoremap <buffer> <silent> O :<C-U>exe <SID>GF("tabedit")<CR>
if get(b:, 'fugitive_type', '') ==# 'blob'
nnoremap <buffer> <silent> o :<C-U>.,.+1Gblame<CR>
nnoremap <buffer> <silent> S :<C-U>vertical .,.+1Gblame<CR>
nnoremap <buffer> <silent> O :<C-U>tab .,.+1Gblame<CR>
nnoremap <buffer> <silent> p :<C-U>.,.+2Gblame<CR>
else
nnoremap <buffer> <silent> o :<C-U>exe <SID>GF("split")<CR>
nnoremap <buffer> <silent> S :<C-U>exe <SID>GF("vsplit")<CR>
nnoremap <buffer> <silent> O :<C-U>exe <SID>GF("tabedit")<CR>
nnoremap <buffer> <silent> p :<C-U>exe <SID>GF("pedit")<CR>
endif
nnoremap <buffer> <silent> - :<C-U>exe <SID>Edit('edit',0,'',<SID>NavigateUp(v:count1))<Bar> if getline(1) =~# '^tree \x\{40\}$' && empty(getline(2))<Bar>call search('^'.escape(expand('#:t'),'.*[]~\').'/\=$','wc')<Bar>endif<CR> nnoremap <buffer> <silent> - :<C-U>exe <SID>Edit('edit',0,'',<SID>NavigateUp(v:count1))<Bar> if getline(1) =~# '^tree \x\{40\}$' && empty(getline(2))<Bar>call search('^'.escape(expand('#:t'),'.*[]~\').'/\=$','wc')<Bar>endif<CR>
nnoremap <buffer> <silent> P :<C-U>exe <SID>Edit('edit',0,'',<SID>ContainingCommit().'^'.v:count1.<SID>Relative(':'))<CR> nnoremap <buffer> <silent> P :<C-U>exe <SID>Edit('edit',0,'',<SID>ContainingCommit().'^'.v:count1.<SID>Relative(':'))<CR>
nnoremap <buffer> <silent> ~ :<C-U>exe <SID>Edit('edit',0,'',<SID>ContainingCommit().'~'.v:count1.<SID>Relative(':'))<CR> nnoremap <buffer> <silent> ~ :<C-U>exe <SID>Edit('edit',0,'',<SID>ContainingCommit().'~'.v:count1.<SID>Relative(':'))<CR>
@ -3152,16 +3181,6 @@ function! s:cfile() abort
elseif treebase !~# '^\d\=:' && getline(1) =~# '^tree ' && empty(getline(2)) && line('.') >= 2 elseif treebase !~# '^\d\=:' && getline(1) =~# '^tree ' && empty(getline(2)) && line('.') >= 2
return [treebase . s:sub(getline('.'),'/$','')] return [treebase . s:sub(getline('.'),'/$','')]
elseif get(b:, 'fugitive_type', '') ==# 'blob'
let ref = expand("<cfile>")
try
let sha1 = s:repo().rev_parse(ref)
catch /^fugitive:/
endtry
if exists('sha1')
return [ref]
endif
else else
let dcmds = [] let dcmds = []

View File

@ -235,8 +235,6 @@ 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] Run git-blame on the given range.
*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.