2011-09-08 10 views
10

Eventuali duplicati:
(Vim)diff two subroutines in same fileC'è un modo per diff due registri in vim?

A volte vedo un blocco di codice ho il sospetto di essere identico a un altro blocco nello stesso file, ma è un po 'troppo lungo per l'ispezione visiva e Potrei semplicemente mancare qualcosa. Ho provato a selezionare visivamente il blocco e ad accedere al registro predefinito, mettere quel registro in/(find), ma non corrispondeva nemmeno al blocco originale.

C'è un modo per selezionare una sezione, strattonarla in un registro, selezionare un'altra sezione e diffare le due, senza creare un gruppo di nuovi file? Immagino l'apertura dei risultati in un nuovo buffer in una scheda o divisione.

MODIFICA: La mia domanda è fondamentalmente un duplicato di This one. Ho trovato this answer il più utile & più vicino a quello che stavo cercando. L'unica cosa che cambierei è di farla produrre in Unified format quindi sembra l'output diff a cui sono abituato (ha anche più informazioni). Suppongo che questo significhi utilizzare una diversa utilità di diff.

+0

Non so di uno quello è integrato ... Forse un piccolo script che farebbe qualcosa come ': tabnew" ap: vsplit l "bp'? –

risposta

5

ispirato la mia funzione lh#path#strip_common():

echo matchstr(@a.'@@'[email protected], '^\zs\(.*\)\ze.\{-}@@\1.*$') 

mostrerà ciò che è comune tra i registri @a e @b.

È possibile visualizzare ulteriori informazioni con:

function ShowDiff(a,b) 
    " I expect neither string to contain '@@' 
    let start = matchstr(a:a.'@@'.a:b, '^\zs\(.*\)\ze.\{-}@@\1.*$') 
    let end= matchstr(a:a.'@@'.a:b, '^.\{-}\zs\(.*\)\[email protected]@.\{-}\1$') 
    let a = a:a[len(start): -len(end)-1] 
    let b = a:b[len(start): -len(end)-1] 
    echo "identical beginning: ".strlen(start)." chars -> ".start 
    echo "identical ending : ".strlen(end)." chars -> ".end 
    echo "typical to a  : ".strlen(a)." chars -> ".a 
    echo "typical to b  : ".strlen(b)." chars -> ".b 
endfunction 

Usato con:

:call ShowDiff(@a, @b) 
3

è possibile utilizzare la seguente sequenza supponendo che i due segmenti sono già in registri, 'a e 'b. Potrebbe probabilmente essere messo in una macro o funzione.

new 
only 
put a 
diffthis 
vnew 
put b 
diffthis 

Questo crea un nuovo buffer, rende l'unico tampone visibile, mette 'a in esso, lo imposta da diff'd, poi apre un nuovo buffer in una spaccatura verticale, mette 'b in questo gruppo vuoto buffer e imposta anche su diff. Immediatamente vim (o gvim) mostrerà le differenze.

Al termine, il tipo :ls per ottenere l'elenco dei buffer, utilizzare :buffer *N* per tornare indietro al file originale e utilizzare :bdel! *N* per eliminare i buffer creati (denominati "[No Name]").

+0

AKAI lo capisco, l'OP non era interessato a "creare un sacco di nuovi file". (Devo ammettere che spesso desidero che tu abbia dettagliato nella risposta) –

+1

Questo non crea nuovi file, solo nuovi buffer all'interno della sessione vim esistente. I buffer non diventano file finché non viene scritto il buffer. – Arcege

+0

E puoi usare 'setlocal buftype = nofile' in modo che non venga scritto o chieda di salvare anche. – idbrii

3

Ecco una funzione per aprire due nuove finestre affiancate, ciascuna contenente il contenuto del registro specificato (chiamato come DiffRegs(@a, @1), ad esempio) e differirle. I nuovi buffer non verranno scritte o modificabile:

" A list for bookkeeping.. 
let g:diffreg_buffers = [] 

function! DiffRegs(reg1, reg2) 
    " Preserve the unnamed register 
    let s:nonamereg = @@ 
    let @@ = a:reg1 
    " new window 
    :new 
    normal P 
    setlocal nomodifiable 
    setlocal buftype=nofile 
    diffthis 
    call add(g:diffreg_buffers, bufnr('%')) 

    let @@ = a:reg2 
    :vsp +enew 
    normal P 
    setlocal nomodifiable 
    setlocal buftype=nofile 
    diffthis 
    call add(g:diffreg_buffers, bufnr('%')) 

    let @@ = s:nonamereg 
endfunction " DiffRegs(reg1, reg2) 

" Function to wipe all buffers we're diffing with the function above 
function! EndDiffs() 
    for buffer in g:diffreg_buffers 
     exe ':buffer ' . buffer 
     diffoff 
     quit 
    endfor 
    let g:diffreg_buffers = [] 
endfunction " EndDiffs() 

È possibile associare a quelle combinazioni di tasti di scelta, ma se non si chiama EndDiffs() dopo ogni chiamata a DiffRegs(), si incorrerà in problemi.

+0

Wow è abbastanza buono! Tuttavia, un paio di problemi: 1. non li differisce davvero, quindi se si trascinano le righe 2-100 in un buffer e 1-99 in un altro, si dice che qualcosa come 98 delle linee sono differenti, cioè non tiene conto per linee extra. 2. Eseguita quest'operazione circa il doppio, sembra non funzionare: errore rilevato durante l'elaborazione DiffRegs funzione: linea 9: 10 più linee riga 16: E96: Non può diff più di 4 tamponi 10 più linee Questo è super vicino a quello che sto cercando (i due nuovi buffer ecc.)! –

+0

Non riesco a risolvere veramente (1), ma non è così che funziona diff (in vim, anche) - sicuramente rappresenta le linee in più. Vedere la risposta aggiornata per una soluzione a (2). –

1

di confrontare rapidamente due diverse parti di un file, è possibile dividere la visualizzazione in due utilizzando:

  • :sp divisione orizzontale

o

  • :vsp spaccatura verticale

Dopo aver diviso lo schermo, è necessario utilizzare :diffthis in ciascuna finestra per evidenziare le differenze. (Poi :diffoff per uscire dalla modalità diff)

quindi tornare a una singola finestra è possibile uscire uno di loro con: q oppure utilizzare CTRLwo