![vimdiff:跳转到行内的下一个差异?](https://linux22.com/image/1706971/vimdiff%EF%BC%9A%E8%B7%B3%E8%BD%AC%E5%88%B0%E8%A1%8C%E5%86%85%E7%9A%84%E4%B8%8B%E4%B8%80%E4%B8%AA%E5%B7%AE%E5%BC%82%EF%BC%9F.png)
vimdiff
对于比较文件来说非常方便。不过,我经常将它用于行数较长且行内差异较少的文件。
vimdiff 会正确突出显示行内的差异(整行粉红色,不同字符红色)。在这些情况下,能够跳转到下一个差异会很好线内。
您可以跳转到“下一个差异”(]c),但这将跳转到下一行有差异的内容。
有没有办法转到当前行内的下一个不同字符?
答案1
我看到两种解决方案:
- 您必须测试当前的语法高亮才能跳转到该行的红色部分。
- 您必须在两个缓冲区中提取当前行,并找到不同的第一个字符,以正确定位光标
这两种解决方案都需要在]c 之后执行,并且需要 vim 脚本。
编辑:这是看起来可行的初稿:
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
答案2
这是一个简单的解决方法:
您可以使用set wrap
。
如果这种差异导致文本换行的行数不一致,就会产生问题。
答案3
我不知道该怎么做vimdiff
,但你可以看看wdiff
它会逐字逐句地显示两个文件之间的差异。
我必须从源代码进行编译:
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
答案4
根据文档判断,这是无法做到的。