From af07ac67e6906c3f5b2863eff376e31784dbd088 Mon Sep 17 00:00:00 2001 From: Maksim Odnoletkov Date: Sun, 10 Feb 2019 21:47:59 +0000 Subject: [PATCH] Extend :GBrowse to support line anchors for commits In commit buffers :GBrowse with range will include 'diff' dictionary with 'path', 'line1' and 'line2' values for the range on the '---' side of the diff. Root 'path', 'line1' and 'line2' values specify range on the '+++' side. Line number is 0 when position on the corresponding side of the diff is ambiguous because it is inside deleted hunk. --- autoload/fugitive.vim | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/autoload/fugitive.vim b/autoload/fugitive.vim index 3ea0480701..cc28f11650 100644 --- a/autoload/fugitive.vim +++ b/autoload/fugitive.vim @@ -7400,8 +7400,8 @@ function! fugitive#BrowseCommand(line1, count, range, bang, mods, arg, ...) abor endif endif - let line1 = a:count > 0 && type ==# 'blob' ? a:line1 : 0 - let line2 = a:count > 0 && type ==# 'blob' ? a:count : 0 + let line1 = a:count > 0 && type ==# 'blob' || type ==# 'commit' ? a:line1 : 0 + let line2 = a:count > 0 && type ==# 'blob' || type ==# 'commit' ? a:count : 0 if empty(commit) && path !~# '^\.git/' if a:count < 0 && !empty(merge) let commit = merge @@ -7465,6 +7465,21 @@ function! fugitive#BrowseCommand(line1, count, range, bang, mods, arg, ...) abor \ 'line1': line1, \ 'line2': line2} + if type ==# 'commit' && a:count + let pos1 = s:DiffLines(line1) + let pos2 = s:DiffLines(line2) + if !empty(pos1) && !empty(pos2) + let pattern = ' \(\/dev\/null\|[abciow12]\/\)\zs.*' + let opts.path = matchstr(getline(search('^+++'.pattern,'bnW')), '^+++'.pattern) + let opts.line1 = getline(line1)[0] == '-' ? 0 : pos1.new + let opts.line2 = getline(line2)[0] == '-' ? 0 : pos2.new + let opts.ancestor = {} + let opts.ancestor.path = matchstr(getline(search('^---'.pattern,'bnW')), '^---'.pattern) + let opts.ancestor.line1 = getline(line1)[0] == '+' ? 0 : pos1.old + let opts.ancestor.line2 = getline(line2)[0] == '+' ? 0 : pos2.old + endif + endif + let url = '' for Handler in get(g:, 'fugitive_browse_handlers', []) let url = call(Handler, [copy(opts)]) @@ -7483,6 +7498,23 @@ function! fugitive#BrowseCommand(line1, count, range, bang, mods, arg, ...) abor endtry endfunction +function! s:DiffLines(line) abort + try + let offsets = {' ':0,'+':0,'-':0} + let offsets[getline(a:line)[0]] -= 0 " throw if on hunk header + let lnum = a:line - 1 + while getline(lnum) !~# '^@@ -\d\+\%(,\d\+\)\= +\d\+' + let offsets[getline(lnum)[0]] += 1 + let lnum -= 1 + endwhile + return { + \ 'old': offsets['-'] + offsets[' '] + matchstr(getline(lnum), '-\zs\d\+'), + \ 'new': offsets['+'] + offsets[' '] + matchstr(getline(lnum), '+\zs\d\+'), + \} + catch /^Vim\%((\a\+)\)\=:E734/ + endtry +endfunction + " Section: Go to file let s:ref_header = '\%(Merge\|Rebase\|Upstream\|Pull\|Push\)'