@@ -4315,14 +4315,8 @@ function! s:StageInfo(...) abort
4315
4315
let sigil = matchstr (getline (lnum), ' ^[ @\+-]' )
4316
4316
let offset = -1
4317
4317
if len (sigil)
4318
- let type = sigil == # ' -' ? ' -' : ' +'
4319
- while lnum > 0 && getline (lnum) !~# ' ^@'
4320
- if getline (lnum) = ~# ' ^[ ' .type .' ]'
4321
- let offset += 1
4322
- endif
4323
- let lnum -= 1
4324
- endwhile
4325
- let offset += matchstr (getline (lnum), type .' \zs\d\+' )
4318
+ let [lnum, old_lnum, new_lnum] = s: HunkPosition (lnum)
4319
+ let offset = sigil == # ' -' ? old_lnum : new_lnum
4326
4320
while getline (lnum) = ~# ' ^[ @\+-]'
4327
4321
let lnum -= 1
4328
4322
endwhile
@@ -7513,6 +7507,25 @@ function! s:ParseDiffHeader(str) abort
7513
7507
return [fugitive#Unquote (get (list , 1 , ' ' )), fugitive#Unquote (get (list , 2 , ' ' ))]
7514
7508
endfunction
7515
7509
7510
+ function ! s: HunkPosition (lnum) abort
7511
+ let lnum = a: lnum + get ({' @' : 1 , ' \' : -1 }, getline (a: lnum )[0 ], 0 )
7512
+ let offsets = {' ' : -1 , ' +' : 0 , ' -' : 0 }
7513
+ let sigil = getline (lnum)[0 ]
7514
+ let line_char = sigil
7515
+ while has_key (offsets, line_char)
7516
+ let offsets[line_char] += 1
7517
+ let lnum -= 1
7518
+ let line_char = getline (lnum)[0 ]
7519
+ endwhile
7520
+ let starts = matchlist (getline (lnum), ' ^@@\+[ 0-9,-]* -\(\d\+\),\d\+ +\(\d\+\),' )
7521
+ if empty (starts)
7522
+ return [0 , 0 , 0 ]
7523
+ endif
7524
+ return [lnum,
7525
+ \ sigil == # ' +' ? 0 : starts[1 ] + offsets[' ' ] + offsets[' -' ],
7526
+ \ sigil == # ' -' ? 0 : starts[2 ] + offsets[' ' ] + offsets[' +' ]]
7527
+ endfunction
7528
+
7516
7529
function ! s: MapMotion (lhs, rhs) abort
7517
7530
let maps = [
7518
7531
\ s: Map (' n' , a: lhs , " :<C-U>" . a: rhs . " <CR>" , " <silent>" ),
@@ -7844,22 +7857,17 @@ function! s:cfile() abort
7844
7857
let dcmds = [' ' , ' Gdiffsplit! >' . myhash . ' ^:' . fnameescape (files [0 ])]
7845
7858
endif
7846
7859
7847
- elseif getline (' .' ) = ~# ' ^[+-]\{3\} "\=[abciow12]\=/'
7848
- let ref = fugitive#Unquote (getline (' .' )[4 :])
7849
-
7850
- elseif getline (' .' ) = ~# ' ^[+-]' && search (' ^@@ -\d\+\%(,\d\+\)\= +\d\+' ,' bnW' )
7851
- let type = getline (' .' )[0 ]
7852
- let lnum = line (' .' ) - 1
7853
- let offset = 0
7854
- while getline (lnum) !~# ' ^@@ -\d\+\%(,\d\+\)\= +\d\+'
7855
- if getline (lnum) = ~# ' ^[ ' .type .' ]'
7856
- let offset += 1
7857
- endif
7858
- let lnum -= 1
7859
- endwhile
7860
- let offset += matchstr (getline (lnum), type .' \zs\d\+' )
7861
- let ref = fugitive#Unquote (getline (search (' ^' .type .' \{3\} "\=[abciow12]/' ,' bnW' ))[4 :-1 ])
7862
- let dcmds = [offset, ' normal!zv' ]
7860
+ elseif getline (' .' ) = ~# ' ^[+-]'
7861
+ let [header_lnum, old_lnum, new_lnum] = s: HunkPosition (line (' .' ))
7862
+ if new_lnum > 0
7863
+ let ref = s: ParseDiffHeader (getline (search (s: diff_header_pattern , ' bnW' )))[1 ]
7864
+ let dcmds = [new_lnum, ' normal!zv' ]
7865
+ elseif old_lnum > 0
7866
+ let ref = s: ParseDiffHeader (getline (search (s: diff_header_pattern , ' bnW' )))[0 ]
7867
+ let dcmds = [old_lnum, ' normal!zv' ]
7868
+ else
7869
+ let ref = fugitive#Unquote (matchstr (getline (' .' ), ' \C[+-]\{3\} \zs"\=[abciow12]/.*' ))
7870
+ endif
7863
7871
7864
7872
elseif getline (' .' ) = ~# ' ^rename from '
7865
7873
let ref = ' a/' .getline (' .' )[12 :]
0 commit comments