vimdiff : 라인 내부의 다음 차이점으로 이동?


35

vimdiff파일을 비교하는 데 매우 편리합니다. 그러나 종종 줄이 길고 줄 내부의 차이가 거의없는 파일에 사용합니다.

vimdiff는 라인 내부의 차이점 (분홍색, 다른 문자)을 올바르게 강조 표시합니다. 이 경우 라인 내부의 다음 차이점으로 넘어갈 수있는 것이 좋습니다 .

"다음 차이"( ]c)로 이동할 수 있지만 차이 가있는 다음 줄로 건너 뜁니다.

현재 줄에서 다음으로 다른 문자로 이동하는 방법이 있습니까?

답변:


8

두 가지 해결책이 있습니다.

  1. 줄에서 빨간색 부분으로 이동하려면 현재 구문 강조를 테스트해야합니다.
  2. 두 버퍼에서 현재 줄을 추출하고 커서를 올바르게 배치하기 위해 다른 첫 번째 문자를 찾아야합니다.

두 솔루션 모두] 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

나는 그것을 달성하는 쉬운 방법이없는 것처럼 보이기 때문에 이것을 포기했습니다. 귀하의 답변이 내가 원하는 것을하는 것처럼 보이므로 감사합니다.
sleske

2
그 이후로 코드를이 스크립트 code.google.com/p/lh-vim/source/browse/misc/trunk/plugin/…에 넣었 습니다. 때때로 발생하는 무한 루프를 관찰했습니다. 결국 고칠 것입니다.
Luc Hermitte

12

이것은 쉬운 해결 방법입니다.

사용할 수 있습니다 set wrap.

차이로 인해 텍스트가 다른 줄로 줄 바꿈되는 경우 문제가 발생합니다.


1
빠르고 더러 웠지만 그것은 나를 위해 일했습니다.
Mobius

2

나는 이것을 수행하는 방법을 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

1

문서로 판단하면 할 수 없습니다.


2
흥미 롭군 문서에서 어디서 찾았습니까? 나는 거기에서 아무것도 찾을 수 없었다.
sleske

1
Vim에서 나는 다음을 입력했다 ::help vimdiff
Nathan Fellman
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.