4

If I have a diff file open in vim (not vimdiff), is there a way to jump to the line under the cursor?

Something like this:

  • Detect the hunk of text under the cursor.
  • Open a buffer for the file containing the hunk
    (perhaps an existing buffer if one is already open, although this is a detail).
  • Move to the line which was under the cursor.

Is there a way to do this in vim?


I've seen this in other software.

  • QtCreator supports this by double-clicking on the line of the diff.
  • Emacs diff viewer has diff-goto-source.

1 Answer 1

3

I'm a little surprised that gf doesn't already support this, but it doesn't. There's a plugin that does, though: gf-diff (GitHub mirror).

Someone also wrote a blog post with a more ad-hoc solution, reproduced below. Credit to the blog author, Kana Natsuno.

" git-diff-aware version of gf commands.
nnoremap <expr> gf  <SID>do_git_diff_aware_gf('gf')
nnoremap <expr> gF  <SID>do_git_diff_aware_gf('gF')
nnoremap <expr> <C-w>f  <SID>do_git_diff_aware_gf('<C-w>f')
nnoremap <expr> <C-w><C-f>  <SID>do_git_diff_aware_gf('<C-w><C-f>')
nnoremap <expr> <C-w>F  <SID>do_git_diff_aware_gf('<C-w>F')
nnoremap <expr> <C-w>gf  <SID>do_git_diff_aware_gf('<C-w>gf')
nnoremap <expr> <C-w>gF  <SID>do_git_diff_aware_gf('<C-w>gF')

function! s:do_git_diff_aware_gf(command)
  let target_path = expand('<cfile>')
  if target_path =~# '^[ab]/'  " with a peculiar prefix of git-diff(1)?
    if filereadable(target_path) || isdirectory(target_path)
      return a:command
    else
      " BUGS: Side effect - Cursor position is changed.
      let [_, c] = searchpos('\f\+', 'cenW')
      return c . '|' . 'v' . (len(target_path) - 2 - 1) . 'h' . a:command
    endif
  else
    return a:command
  endif
endfunction

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.