Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

vimdiff is very handy for comparing files. However, I often use it on files with long lines and relatively few differences inside the lines.

vimdiff will correctly highlight differences inside a line (whole line pink, differing characters red). In these cases, it would be nice to be able to jump to the next difference inside the line.

You can jump to the "next difference" (]c), but this will jump to the next line with a difference.

Is there a way to go to the next different character inside the current line?

share|improve this question
up vote 8 down vote accepted

I see two solutions:

  1. you would have to test the current syntax highlighting to jump to the red part in the line.
  2. you would have to extract the current line in both buffers and find the first character that differs to position correctly the cursor

Both solutions need to be executed after the ]c, and require vim scripting.

EDIT: Here is a first draft that seems to work:

nnoremap <expr> <silent> <F3>   (&diff ? "]c:call \<sid>NextDiff()\<cr>" : ":cn\<cr>")

function! s:GotoWinline(w_l)
  normal! H
  while winline() < a:w_l
    normal! j
  " todo: beware of cases where the window is too little

" Better ]c, [c jump
function! s:NextDiff()
  if ! &diffopt =~ 'filler' | return | endif

  let ignore_blanks = &diffopt =~ 'iwhite'

  " Assert: called just after a ]c or a [c
  " Forces the cursos to be synchronized in all synced windows
  " let diff_l = line()
    let foldenable = &foldenable
    set nofoldenable

    let w_l = winline() " problematic with enabled lines (from diff...)
    " echomsg w_l.'|'.line('.').'|'.getline('.')

    let lines = {}
    windo if &diff | call <sid>GotoWinline(w_l) | let lines[winnr()]={'text':getline('.'), 'number':line('.')} | endif
    let &foldenable = foldenable

  " echomsg string(lines)
  if len(lines) < 2 | return | endif

  let indices = repeat([0], len(lines))
  let tLines = values(lines)
  let found = 0
  " infinite loop on two empty texts...
  while ! found
    let c = ''
    let next_idx = []
    let i = 0
    while i != len(indices)
      let crt_line = tLines[i].text
      let n = indices[i]
      if len(crt_line) == n
    let found = 1

      let c2 = (len(crt_line) == n) ? 'EOL' : crt_line[n]
      if empty(c) 
    let c = c2

      " checks match
      let n += 1
      if c =~ '\s'
    if (c2 != c) && (ignore_blanks && c2 !~ '\s')
      let found = 1
    else " advance
      while ignore_blanks && (n == len(crt_line) || crt_line[n] =~ '\s')
        let n += 1
    if c2 != c
      let found = 1
      let next_idx += [n]

      let i += 1
    if found | break | endif

    let indices = next_idx

  " now goto the right column
  let windows = keys(lines)
  " Assert len(windows) == len(indices)
  let w = 0
  while w != len(windows)
    " echomsg 'W#'.windows[w].' -> :'(tLines[w].number).'normal! '.(indices[w]+1).'|'
    exe windows[w].'wincmd w'
    silent! exe (tLines[w].number).'normal! 0'.(indices[w]).'l'
    let w += 1
  " echomsg string(indices)
share|improve this answer
I've given up on this, as it seems there's no easy way to accomplish it. Since your answer seems to do what I wanted, I'll accept it as a thanks. – sleske Dec 16 '10 at 12:32
Since then, I've put the code into this script… (that does a few others things), and unfortunately, I've observed an infinite loop that occurs time to time. I will eventually fix it. – Luc Hermitte Dec 16 '10 at 17:28

This is an easy workaround:

You can use set wrap.

This will create problems if the difference causes text to wrap in unequal number of lines.

share|improve this answer
Quick and dirty, but it did the job for me. – Mobius yesterday

Judging by the documentation, it can't be done.

share|improve this answer
Interesting. Where did you find this in the docs? I could not find anything there. – sleske Jun 17 '10 at 8:40
In Vim I typed: :help vimdiff – Nathan Fellman Jun 17 '10 at 9:53

I can't figure out how to do this with vimdiff either, but you might check out wdiff instead. It shows differences between two files one word at a time.

I had to compile it from source:

curl > wdiff-1.2.1.tar.gz
tar -xzvf wdiff-1.2.1.tar.gz
cd wdiff-1.2.1
make install
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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