vimdiff: Chuyển đến sự khác biệt tiếp theo bên trong dòng?


35

vimdifflà rất thuận tiện để so sánh các tập tin. Tuy nhiên, tôi thường sử dụng nó trên các tệp có dòng dài và tương đối ít khác biệt bên trong các dòng.

vimdiff sẽ làm nổi bật chính xác sự khác biệt bên trong một dòng (toàn bộ dòng màu hồng, màu đỏ khác nhau). Trong những trường hợp này, thật tuyệt khi có thể chuyển sang sự khác biệt tiếp theo bên trong dòng .

Bạn có thể chuyển đến "sự khác biệt tiếp theo" ( ]c), nhưng điều này sẽ nhảy đến dòng tiếp theo với một sự khác biệt.

Có cách nào để đi đến nhân vật khác tiếp theo trong dòng hiện tại không?

Câu trả lời:


8

Tôi thấy hai giải pháp:

  1. bạn sẽ phải kiểm tra đánh dấu cú pháp hiện tại để chuyển sang phần màu đỏ trong dòng.
  2. bạn sẽ phải trích xuất dòng hiện tại trong cả hai bộ đệm và tìm ký tự đầu tiên khác với vị trí chính xác của con trỏ

Cả hai giải pháp cần được thực hiện sau] c và yêu cầu kịch bản vim.

EDIT: Đây là một dự thảo đầu tiên dường như hoạt động:

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

Tôi đã từ bỏ việc này, vì dường như không có cách nào dễ dàng để thực hiện nó. Vì câu trả lời của bạn dường như làm những gì tôi muốn, tôi sẽ chấp nhận nó như một lời cảm ơn.
sleske

2
Kể từ đó, tôi đã đưa mã vào kịch bản này code.google.com/p/lh-vim/source/browse/misc/trunk/plugin/... (mà không một vài người khác thứ), và không may, tôi đã quan sát một vòng lặp vô hạn xảy ra theo thời gian. Cuối cùng tôi sẽ sửa nó.
Luc Hermitte

12

Đây là một cách giải quyết dễ dàng:

Bạn có thể sử dụng set wrap.

Điều này sẽ tạo ra vấn đề nếu sự khác biệt làm cho văn bản có số lượng dòng không bằng nhau.


1
Nhanh và bẩn, nhưng nó đã làm việc cho tôi.
Mobius

2

Tôi không thể tìm ra cách để làm điều này với vimdiffmột trong hai, nhưng bạn có thể kiểm trawdiff thay thế. Nó cho thấy sự khác biệt giữa hai tệp một từ một lần.

Tôi đã phải biên dịch nó từ nguồn:

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

1

Đánh giá bằng các tài liệu, nó không thể được thực hiện.


2
Hấp dẫn. Nơi mà bạn tìm thấy điều này trong các tài liệu? Tôi không thể tìm thấy bất cứ điều gì ở đó.
sleske

1
Trong Vim tôi đã gõ::help vimdiff
Nathan Fellman
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.