Pregunta

Cuando una sesión anterior de Vim falla, aparece el mensaje "Archivo de intercambio...¡ya existe!" para todos y cada uno de los archivos que se abrieron en la sesión anterior.

¿Puedes hacer que este mensaje de recuperación de Vim sea más inteligente?(¡Sin desactivar la recuperación!) Específicamente, estoy pensando en:

  • Si la versión intercambiada no contiene cambios no guardados y el proceso de edición ya no se ejecuta, ¿puede hacer que Vim elimine automáticamente el archivo de intercambio?
  • ¿Puede automatizar el proceso sugerido de guardar el archivo recuperado con un nuevo nombre, fusionarlo con el archivo en el disco y luego eliminar el archivo de intercambio anterior, de modo que se requiera una interacción mínima?Especialmente cuando la versión de intercambio y la versión de disco son las mismas, todo debería ser automático.

descubrí el SwapExists autocommand pero no sé si puede ayudar con estas tareas.

¿Fue útil?

Solución

Tengo vim para almacenar mis archivos de intercambio en un único directorio local, teniendo esto en mi .vimrc:

set directory=~/.vim/swap,.

Entre otros beneficios, esto hace que los archivos de intercambio sean fáciles de encontrar todos a la vez.Ahora, cuando mi computadora portátil se queda sin energía o lo que sea y empiezo a reiniciar con un montón de archivos de intercambio por ahí, simplemente ejecuto mi cleanswap guion:

TMPDIR=$(mktemp -d) || exit 1
RECTXT="$TMPDIR/vim.recovery.$USER.txt"
RECFN="$TMPDIR/vim.recovery.$USER.fn"
trap 'rm -f "$RECTXT" "$RECFN"; rmdir "$TMPDIR"' 0 1 2 3 15
for q in ~/.vim/swap/.*sw? ~/.vim/swap/*; do
  [[ -f $q ]] || continue
  rm -f "$RECTXT" "$RECFN"
  vim -X -r "$q" \
      -c "w! $RECTXT" \
      -c "let fn=expand('%')" \
      -c "new $RECFN" \
      -c "exec setline( 1, fn )" \
      -c w\! \
      -c "qa"
  if [[ ! -f $RECFN ]]; then
    echo "nothing to recover from $q"
    rm -f "$q"
    continue
  fi
  CRNT="$(cat $RECFN)"
  if diff --strip-trailing-cr --brief "$CRNT" "$RECTXT"; then
      echo "removing redundant $q"
      echo "  for $CRNT"
      rm -f "$q"
  else
      echo $q contains changes
      vim -n -d "$CRNT" "$RECTXT"
      rm -i "$q" || exit
  fi
done

Esto eliminará cualquier archivo de intercambio que esté actualizado con los archivos reales.Cualquiera que no coincida aparece en una ventana de vimdiff para que pueda fusionar mis cambios no guardados.

--Chouser

Otros consejos

Acabo de descubrir esto:

http://vimdoc.sourceforge.net/htmldoc/diff.html#:DiffOrig

Copié y pegué el comando DiffOrig en mi archivo .vimrc y funciona de maravilla.Esto facilita enormemente la recuperación de archivos de intercambio.No tengo idea de por qué no está incluido de forma predeterminada en VIM.

Aquí está el comando para los que tienen prisa:

 command DiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis
    \ | wincmd p | diffthis

La respuesta aceptada es errónea para un caso de uso muy importante.Digamos que crea un nuevo búfer y escribe durante 2 horas sin guardarlo, luego su computadora portátil falla.Si ejecuta el script sugerido eliminará su único registro, el archivo de intercambio .swp.No estoy seguro de cuál es la solución correcta, pero parece que el comando diff termina comparando el mismo archivo consigo mismo en este caso.La versión editada a continuación comprueba este caso y le da al usuario la oportunidad de guardar el archivo en algún lugar.

#!/bin/bash

SWAP_FILE_DIR=~/temp/vim_swp
IFS=$'\n'

TMPDIR=$(mktemp -d) || exit 1
RECTXT="$TMPDIR/vim.recovery.$USER.txt"
RECFN="$TMPDIR/vim.recovery.$USER.fn"
trap 'rm -f "$RECTXT" "$RECFN"; rmdir "$TMPDIR"' 0 1 2 3 15
for q in $SWAP_FILE_DIR/.*sw? $SWAP_FILE_DIR/*; do
  echo $q
  [[ -f $q ]] || continue
  rm -f "$RECTXT" "$RECFN"
  vim -X -r "$q" \
      -c "w! $RECTXT" \
      -c "let fn=expand('%')" \
      -c "new $RECFN" \
      -c "exec setline( 1, fn )" \
      -c w\! \
      -c "qa"
  if [[ ! -f $RECFN ]]; then
    echo "nothing to recover from $q"
    rm -f "$q"
    continue
  fi
  CRNT="$(cat $RECFN)"
  if [ "$CRNT" = "$RECTXT" ]; then
      echo "Can't find original file. Press enter to open vim so you can save the file. The swap file will be deleted afterward!"
      read
      vim "$CRNT"
      rm -f "$q"
  else if diff --strip-trailing-cr --brief "$CRNT" "$RECTXT"; then
      echo "Removing redundant $q"
      echo "  for $CRNT"
      rm -f "$q"
  else
      echo $q contains changes, or there may be no original saved file
      vim -n -d "$CRNT" "$RECTXT"
      rm -i "$q" || exit
  fi
  fi
done

Gran consejo DiffOrig es perfecto.Aquí hay un script bash que uso para ejecutarlo en cada archivo de intercambio en el directorio actual:

#!/bin/bash

swap_files=`find . -name "*.swp"`

for s in $swap_files ; do
        orig_file=`echo $s | perl -pe 's!/\.([^/]*).swp$!/$1!' `
        echo "Editing $orig_file"
        sleep 1
        vim -r $orig_file -c "DiffOrig"
        echo -n "  Ok to delete swap file? [y/n] "
        read resp
        if [ "$resp" == "y" ] ; then
                echo "  Deleting $s"
                rm $s
        fi
done

Probablemente le vendría bien un poco más de verificación de errores y citas, pero hasta ahora ha funcionado.

Prefiero no configurar mi directorio de trabajo VIM en .vimrc.Aquí hay una modificación del script de chouser que copia los archivos de intercambio a la ruta de intercambio a pedido, verifica si hay duplicados y luego los concilia.Esto fue escrito apresuradamente, asegúrese de evaluarlo antes de ponerlo en práctica.

#!/bin/bash

if [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then
   echo "Moves VIM swap files under <base-path> to ~/.vim/swap and reconciles differences"
   echo "usage: $0 <base-path>"
   exit 0
fi

if [ -z "$1" ] || [ ! -d "$1" ]; then
   echo "directory path not provided or invalid, see $0 -h"
   exit 1
fi

echo looking for duplicate file names in hierarchy
swaps="$(find $1 -name '.*.swp' | while read file; do echo $(basename $file); done | sort | uniq -c | egrep -v "^[[:space:]]*1")"
if [ -z "$swaps" ]; then
   echo no duplicates found
   files=$(find $1 -name '.*.swp')
   if [ ! -d ~/.vim/swap ]; then mkdir ~/.vim/swap; fi
   echo "moving files to swap space ~./vim/swap"
   mv $files ~/.vim/swap
   echo "executing reconciliation"
   TMPDIR=$(mktemp -d) || exit 1
   RECTXT="$TMPDIR/vim.recovery.$USER.txt"
   RECFN="$TMPDIR/vim.recovery.$USER.fn"
   trap 'rm -f "$RECTXT" "$RECFN"; rmdir "$TMPDIR"' 0 1 2 3 15
   for q in ~/.vim/swap/.*sw? ~/.vim/swap/*; do
     [[ -f $q ]] || continue
     rm -f "$RECTXT" "$RECFN"
     vim -X -r "$q" \
         -c "w! $RECTXT" \
         -c "let fn=expand('%')" \
         -c "new $RECFN" \
         -c "exec setline( 1, fn )" \
         -c w\! \
         -c "qa"
     if [[ ! -f $RECFN ]]; then
       echo "nothing to recover from $q"
       rm -f "$q"
       continue
     fi
     CRNT="$(cat $RECFN)"
     if diff --strip-trailing-cr --brief "$CRNT" "$RECTXT"; then
         echo "removing redundant $q"
         echo "  for $CRNT"
         rm -f "$q"
     else
         echo $q contains changes
         vim -n -d "$CRNT" "$RECTXT"
         rm -i "$q" || exit
     fi
   done
else
   echo duplicates found, please address their swap reconciliation manually:
   find $1 -name '.*.swp' | while read file; do echo $(basename $file); done | sort | uniq -c | egrep '^[[:space:]]*[2-9][0-9]*.*'
fi

Tengo esto en mi archivo .bashrc.Me gustaría dar el crédito apropiado a parte de este código pero olvidé de dónde lo saqué.

mswpclean(){

for i in `find -L -name '*swp'`
do
    swpf=$i
    aux=${swpf//"/."/"/"}
    orif=${aux//.swp/}
    bakf=${aux//.swp/.sbak}

    vim -r $swpf -c ":wq! $bakf" && rm $swpf
    if cmp "$bakf" "$orif" -s
    then rm $bakf && echo "Swap file was not different: Deleted" $swpf
    else vimdiff $bakf $orif
    fi
done

for i in `find -L -name '*sbak'`
do
    bakf=$i
    orif=${bakf//.sbak/}
    if test $orif -nt $bakf
    then rm $bakf && echo "Backup file deleted:" $bakf
    else echo "Backup file kept as:" $bakf
    fi
done }

Simplemente ejecuto esto en la raíz de mi proyecto y, SI el archivo es diferente, abre vim diff.Luego, se conservará el último archivo que se guardó.Para hacerlo perfecto solo necesitaría reemplazar lo último:

else echo "Backup file kept as:" $bakf

por algo como

else vim $bakf -c ":wq! $orif" && echo "Backup file kept and saved as:" $orif

pero no tuve tiempo de probarlo adecuadamente.

Espero eso ayude.

buscar ./ ​​-tipo f -nombre ".*sw[klmnop]" -eliminar

Crédito:@shwaydogghttps://superuser.com/questions/480367/cuál-es-la-forma-más-fácil-de-eliminar-vim-swapfiles-ive-already-recovered-from

Navegue al directorio primero

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top