Friday, June 18, 2010

diff and synchronisation

Hello,

I was wondering if there was a way to know the set of matching lines when in diff mode (after a ]c)

After a ]c (/[c), I've first tried to go from one window to the other, but then the cursor is not on the same lines in the two (or more) synched windows.

I've quickly discarded any solution where I could directly play with "ln = line('.') ; focus on next window ; l2 = getline(ln)" as the diffed buffers won't have the same number of lines.

Then, I've noticed that both windows have their first line synchronized. I though at first I could directly use " ln = winline() ; ^Ww ; exe 'normal '.ln.'H'". Unfortunately, winline() counts the fake lines than are introduced by diff-mode, while H works on actual lines, ignoring the fake ones.

So, is there a solution other than iteratively moving down until both winline() results are equal ?


NB: I'm trying to solve this "puzzle": http://superuser.com/questions/145940/vimdiff-jump-to-next-difference-inside-line
The current, incomplete and not working code is:
------------------ >% -----------------
nnoremap <expr> <silent> <F3> (&diff ? "]c:call \<sid>NextDiff()\<cr>" : ":cn\<cr>")

function! s:NextDiff()
if ! &diffopt =~ 'filler' | return | endif

let ignore_blanks = &diffopt =~ 'iwhite'

" Assert: called just after a ]c or a [c
" Forces the cursors to be synchronized in all synced windows
" let diff_l = line()
let w_l = winline() " problematic with ignored lines (from diff...)
echomsg w_l.'|'.line('.').'|'.getline('.')

"
let lines = {}
windo if &diff | exe 'normal! '.w_l.' H' | let lines[winnr()]=getline('.') | endif
echomsg string(lines)
if len(lines) < 2 | return | endif

let indices = repeat([0], len(lines))
let tLines = values(lines)
let found = 0
while ! found
let c = ''
let next_idx = []
let i = 0
while i != len(indices)
let crt_line = tLines[i]
let n = indices[i]
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
echomsg string(indices)
endfunction
------------------ >% -----------------

--
Luc Hermitte
http://lh-vim.googlecode.com/
http://hermitte.free.fr/vim/

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

No comments: