vimdiff: Jump to next difference inside line?
Solution 1
I see two solutions:
- you would have to test the current syntax highlighting to jump to the red part in the line.
- 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
endwhile
" todo: beware of cases where the window is too little
endfunction
" 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()
try
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
finally
let &foldenable = foldenable
endtry
" 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
break
endif
let c2 = (len(crt_line) == n) ? 'EOL' : crt_line[n]
if empty(c)
let c = c2
endif
" checks match
let n += 1
if c =~ '\s'
if (c2 != c) && (ignore_blanks && c2 !~ '\s')
let found = 1
break
else " advance
while ignore_blanks && (n == len(crt_line) || crt_line[n] =~ '\s')
let n += 1
endwhile
endif
else
if c2 != c
let found = 1
break
endif
endif
let next_idx += [n]
let i += 1
endwhile
if found | break | endif
let indices = next_idx
endwhile
" 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
endwhile
" echomsg string(indices)
endfunction
Solution 2
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.
Solution 3
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 http://ftp.gnu.org/gnu/wdiff/wdiff-1.2.1.tar.gz > wdiff-1.2.1.tar.gz
tar -xzvf wdiff-1.2.1.tar.gz
cd wdiff-1.2.1
./configure
make
make install
Solution 4
Judging by the documentation, it can't be done.
Related videos on Youtube
Comments
-
sleske over 1 year
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?
-
sleske almost 14 yearsInteresting. Where did you find this in the docs? I could not find anything there.
-
Nathan Fellman almost 14 yearsIn Vim I typed:
:help vimdiff
-
sleske over 13 yearsI'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.
-
Luc Hermitte over 13 yearsSince then, I've put the code into this script code.google.com/p/lh-vim/source/browse/misc/trunk/plugin/… (that does a few others things), and unfortunately, I've observed an infinite loop that occurs time to time. I will eventually fix it.
-
Mobius almost 8 yearsQuick and dirty, but it did the job for me.