diffchar.vim
diffchar.vim copied to clipboard
Modifications to a line are indicated differently depending on whether the line before or after was deleted
Consider the following:
123
456
789
When I change it to
123
456 x
the x is indicated as added. However, when I change it to:
456 x
789
the whole line with the x is indicated as changed.
It's the same kind of change and imho should be indicated the same, but because a line was deleted before and not after, it isn't. Is there anything you can do about that?
Which lines are indicated as added/deleted/changed are depending on the diff algorithm which vim is using. My plugin actually follows that. You can try to set different algorithms in the diffopt
option.
Bummer. Tried all the algorithms available and combined the different options. Nothing helped. Now this is a toy example, but I encounter this kind of diff quite often. Also tried googling for more options, but couldn't find anything. If you have any more tips based on your experience, I'd be very grateful!
You may find some useful option of diff command which would help you and can set it usingdiffexpr
option. If you know which range of lines should be compared between two (in your example, line '456' and '456 x'), my another plugin spotdiff.vim might help you.
Thanks for the suggestion. Just tried it, but I think I prefer https://github.com/AndrewRadev/linediff.vim especially because I can't diff side-by-side with spotdiff(or did I miss anything?).
Regarding my original problem, I think I would need two diff blocks, one for the deletion of 123
and one for the change. But is seems like all algorithms try to minimize the number of blocks...
FYI, this is a sample code to implement a line-by-line comparison in vimdiff.
set diffexpr=LineByLineCmp()
function! LineByLineCmp()
let [f1, f2, fo] = [readfile(v:fname_in), readfile(v:fname_new), []]
let eq = ''
for ln in range(min([len(f1), len(f2)]))
let eq .= (f1[ln] == f2[ln]) ? '=' : '!'
endfor
let ln = 1
for ed in split(eq, '\%(=\+\|!\+\)\zs')
let en = len(ed)
if ed[0] == '!'
let cs = (1 < en) ? ln . ',' . (ln + en - 1) : ln
let fo += [cs . 'c' . cs]
endif
let ln += en
endfor
call writefile(fo, v:fname_out)
endfunction