2011-09-08 20 views
10

Duplicar posibles:
(Vim)diff two subroutines in same file¿Hay alguna forma de modificar dos registros en vim?

A veces veo un bloque de código Sospecho que ser idéntico a otro bloque en el mismo archivo, pero es un poco demasiado tiempo para la inspección visual y Es posible que me esté perdiendo algo. Intenté seleccionar visualmente el bloque y tirar al registro predeterminado, poner ese registro en/(buscar), pero no coincidía ni siquiera con el bloque original.

¿Hay alguna manera de seleccionar una sección, tirarla en un registro, seleccionar otra sección y luego distinguir las dos, sin crear un grupo de archivos nuevos? Imagino que los resultados de diferencias se abren en un nuevo búfer en una pestaña o división.

EDIT: Mi pregunta es básicamente un duplicado de This one. Encontré this answer para ser el más útil & más cercano a lo que estaba buscando. Lo único que cambiaría es hacerlo salir en Unified format para que se vea como la salida de diff a la que estoy acostumbrado (también tiene más información). Supongo que esto significa usar una utilidad de diferencia diferente.

+0

No sé de uno eso está incorporado ... Tal vez un pequeño script que haría algo como ': tabnew" ap: vsplit l "bp'? –

Respuesta

5

inspirado en mi función lh#path#strip_common():

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

mostrará lo que es común entre los registros @a y @b.

Puede mostrar más información 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 

Se utiliza con:

:call ShowDiff(@a, @b) 
3

podría utilizar la siguiente secuencia suponiendo que los dos segmentos ya están en registros, 'a y 'b. Probablemente podría incluirse en una macro o función.

new 
only 
put a 
diffthis 
vnew 
put b 
diffthis 

Esto crea un nuevo buffer, hace que sea el único amortiguador visible, pone 'a en él, lo configura para ser diff'd, a continuación, se abre un nuevo buffer en una división vertical, pone 'b en esta división vacía buffer y también lo configura en diff. Inmediatamente vim (o gvim) mostrará las diferencias.

Cuando haya terminado, tipo :ls para obtener la lista de buffers, utilice :buffer *N* para volver de nuevo al archivo original y utilizar :bdel! *N* para borrar las memorias intermedias creadas (llamadas "[Sin Nombre]").

+0

AKAI lo entiendo, al OP no le interesaba "crear un montón de archivos nuevos". (Debo admitir que a menudo quiero que tenga detalles en su respuesta) –

+1

Esto no crea nuevos archivos, solo nuevos almacenamientos intermedios dentro de la sesión de vim existente. Los búferes no se convierten en archivos hasta que se escribe el búfer. – Arcege

+0

Y puede usar 'setlocal buftype = nofile' para que no se escriba o pida guardar también. – idbrii

3

Aquí hay una función para abrir dos ventanas nuevas, una al lado de la otra, cada una con los contenidos de registro especificados (llamados DiffRegs(@a, @1), por ejemplo) y difirirlos. Los nuevos amortiguadores no serán escritos o modificable:

" 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() 

Puede enlazar aquellos a combinaciones de teclas de su elección, pero si usted no llama EndDiffs() después de cada llamada a DiffRegs(), se encontrará con problemas.

+0

¡Guau, eso es bastante bueno! Sin embargo, hay un par de problemas: 1. en realidad no los está distorsionando, por lo que si quitas las líneas 2-100 en un buffer y 1-99 en otro, te dice que algo así como 98 de las líneas son diferentes, es decir, no cuenta para líneas adicionales. 2. Después de ejecutarlo aproximadamente dos veces, parece no trabajar: Error detectado al procesamiento DiffRegs de función: línea 9: 10 más líneas línea 16: E96: No se puede diff más de 4 tampones 10 líneas más Este está muy cerca de lo que estoy buscando (los dos nuevos buffers, etc.) –

+0

Realmente no puedo resolver (1), pero así no es como funciona diff (en vim, también) - definitivamente da cuenta de líneas adicionales. Vea la respuesta actualizada para una solución a (2). –

1

para comparar rápidamente dos diferentes partes de un archivo, se puede dividir la vista en dos por el uso de:

  • :sp división horizontal

o

  • :vsp división vertical

Una vez que haya dividido la pantalla, debe usar :diffthis en cada ventana para resaltar las diferencias. (Luego :diffoff para salir del modo diff)

A continuación, volver a una sola ventana puede salir uno de ellos con: q o usar CTRLwo

Cuestiones relacionadas