48 votes

vimdiff : Sauter à la différence suivante à l'intérieur de la ligne ?

vimdiff est très pratique pour comparer des fichiers. Cependant, je l'utilise souvent sur des fichiers comportant de longues lignes et relativement peu de différences à l'intérieur des lignes.

vimdiff met correctement en évidence les différences à l'intérieur d'une ligne (ligne entière en rose, caractères différents en rouge). Dans ce cas, il serait intéressant de pouvoir passer à la différence suivante à l'intérieur de la ligne .

Vous pouvez passer à la "différence suivante" ( ]c ), mais cela permet de passer à la ligne suivante avec une différence.

Existe-t-il un moyen de passer au caractère différent suivant à l'intérieur de la ligne actuelle ?

19voto

Parag Jain Points 191

Il s'agit d'une solution facile à mettre en œuvre :

Vous pouvez utiliser set wrap .

Cela posera des problèmes si la différence entraîne un nombre inégal de lignes pour le texte.

11voto

Wes P Points 3153

Je vois deux solutions :

  1. il faudrait tester la coloration syntaxique actuelle pour passer à la partie rouge de la ligne.
  2. il faudrait extraire la ligne en cours dans les deux tampons et trouver le premier caractère qui diffère pour positionner correctement le curseur

Les deux solutions doivent être exécutées après le ]c, et nécessitent l'utilisation du script vim.

EDIT : Voici une première version qui semble fonctionner :

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

2voto

David Winiecki Points 303

Je n'arrive pas à comprendre comment faire avec vimdiff mais vous pouvez aussi consulter le site wdiff au lieu de cela. Il montre les différences entre deux fichiers, un mot à la fois.

J'ai dû le compiler à partir des sources :

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

1voto

Nathan Fellman Points 8972

À en juger par la documentation, c'est impossible.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X