vimdiff

En alguna ocasión tenemos 2 ficheros que en principio son iguales pero tienen algunas diferencias, por ejemplo cuando programamos y un fichero lo modificamos o cuando tenemos un texto y hemos modificado parte o en general cuando queremos comparar dos documentos pero no solo queremos ver las diferencias si no que además queremos ajustar esas diferencias o reducirlas.

Con el comando diff podemos ver las diferencias de 2 ficheros (incluso de más) pero no es mejor ver esas diferencias y poder modificar todo en tiempo real ?

Supongamos que tenemos 1 fichero (extraído de un fichero C como ejemplo):

//----------------------------------------------------------------------------
//      MagnifyEventLoopTimer
//
//      Our magnification timer. Ideally we should be event based, but we can't
//      detect every event that might cause a screen update (window move, etc.)
//      so we resort to this.
//----------------------------------------------------------------------------

pascal void
MagnifyEventLoopTimer(EventLoopTimerRef /*inTimer*/, void *inUserData)
{
        WindowRef       window = (WindowRef)inUserData;
        Point           mouse;
        GrafPtr         windowPort;
        GrafPtr         savePort;
        Rect            sourceRect;
        Rect            destRect;
        Rect            portBounds;
        SInt16          distance;
    static Point        sLastMouse = { -1, -1};

        GetPort( &savePort );
        windowPort = GetWindowPort(window);

        GetPortBounds( windowPort, &portBounds );

al cual vamos a hacer algunas modificaciones:

//----------------------------------------------------------------------------
//      MagnifyEventLoopTimer
//
//      Our magnification timer. Ideally we should be event based, but we can't
//      detect every event that might cause a screen update (window move)
//      so we resort to this.
//----------------------------------------------------------------------------

pascal void
MagnifyEventLoopTimer(EventLoopTimerRef /*inTimer*/, void *inUserData)
{
        WindowRef       window = (WindowRef)inUserData;
        Point           mouse;
        GrafPtr         windowPort;
         Rect            sourceRect;
        Rect            destRect;
        Rect            portBounds;
        SInt            distance;
    static Point        sLastMouse = { -1, -1};

        GetPort( &savePortLocal );
        windowPort =  GetWindowPort(window);

        GetPortBounds( windowPort, &portBounds );

así a simple vista es complicado ver las diferencias, para eso tenemos el comando diff:

5c5
< //      detect every event that might cause a screen update (window move, etc.)
---
> //      detect every event that might cause a screen update (window move)
15,17c15,16
<         GrafPtr         savePort;
<         Rect            sourceRect;
<         Rect            destRect;
---
>          Rect            sourceRect;
>         Rect            destRect;
19c18
<         SInt16          distance;
---
>         SInt            distance;
22,23c21,22
<         GetPort( &savePort );
<         windowPort = GetWindowPort(window);
---
>         GetPort( &savePortLocal );
>         windowPort =  GetWindowPort(window);
aunque al ser código C es mejor verlas así:
@@ -2,7 +2,7 @@
 //      MagnifyEventLoopTimer
 //
 //      Our magnification timer. Ideally we should be event based, but we can't
-//      detect every event that might cause a screen update (window move, etc.)
+//      detect every event that might cause a screen update (window move)
 //      so we resort to this.
 //----------------------------------------------------------------------------

@@ -12,15 +12,14 @@
         WindowRef       window = (WindowRef)inUserData;
         Point           mouse;
         GrafPtr         windowPort;
-        GrafPtr         savePort;
-        Rect            sourceRect;
-        Rect            destRect;
+         Rect            sourceRect;
+        Rect            destRect;
         Rect            portBounds;
-        SInt16          distance;
+        SInt            distance;
     static Point        sLastMouse = { -1, -1};

-        GetPort( &savePort );
-        windowPort = GetWindowPort(window);
+        GetPort( &savePortLocal );
+        windowPort =  GetWindowPort(window);

         GetPortBounds( windowPort, &portBounds );

con lo que vemos que se ha modificado y ahora deberíamos editar los ficheros y modificarlos por separado con nuestro editor favorito que si es vim podemos hacer algo mucho mejor y es ver las diferencias mientras los modificamos con el comando vimdiff:

ejemplo de vimdiff

Lo que vemos con fondo rosa son líneas que tiene alguna diferencia, con fondo azul oscuro línaes que se han añadido, con fondo azul claro líneas que faltan, con fondo rojo los caracteres que cambian.

Como podemos ver en el cuadro de la izquierda tenemos una línea con fondo azul oscuro y en la parte derecha una con azul claro, indicando que hay una línea en la parte izquierda que no está en la derecha. Y con fondo rojo los cambios en un lado y otro.

Aquí estamos en el editor vim así que podemos usar todas las combinaciones de teclas y demás opciones del vim y según vayamos editando se irán comparando los dos ficheros y mostrando las diferencias.

  • CtrlW + CtrlW (DOS VECES ^w) – para pasar de una ventana a otra
  • dp – ‘pone’ la diferencia en la otra ventana, si existe lo borra, si no lo copia.
  • do – ‘obtiene’ la diferencia de la otra ventana, si no existe borra lo actual y si no lo copia.
  • ]c – va ala siguiente diferencia.
  • [c – va a la anterior diferencia.
  • zo – ‘abre’ una sección de texto que ha sido ocultada (folded), también sirve la tecla "espacio".
  • zc – ‘cierra’ una sección de texto que ha sido mostrada (unfolded).
  • zr – ‘abre’ todas las secciones de texto que han sido ocultadas (folded).
  • :diffupdate – actualiza el diff en base a los cambios
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Colores para vimdiff
" AÑADIDO fondo verde texto blanco
highlight DiffAdd    cterm=NONE ctermfg=15 ctermbg=2
" BORRADO
highlight DiffDelete cterm=NONE ctermfg=0  ctermbg=1
" DIFERENCIA LINEA ENTERA
highlight DiffChange cterm=bold ctermfg=fg ctermbg=3
" DIFERENCIA EXACTA
highlight DiffText   cterm=bold ctermfg=0 ctermbg=11
vimdiff scp://usuario@ip/fichero_remoto fichero_local

Cambiamos usuario e ip por los que sean y tanto el fichero remoto como local pueden ir precedidos de su PATH completo.

IMPORTANTE: entre ip y fichero_remoto debe haber una barra / en vez de : (como es lo normal), además de la barra de raiz en caso de que esté, por ejemplo: 1.2.3.4//tmp/fichero o 1.2.3.4/–/fichero.

Retro

Lugares

Redes

Sistemas

Varios