Récupération vim plus intelligente?

quand une session Vim précédente s'est écrasée, vous êtes accueilli avec le fichier "Swap"... il existe déjà!"pour chaque fichier ouvert lors de la session précédente.

pouvez-vous rendre cette invite de récupération Vim plus intelligente? (Sans désactiver la récupération!) Plus précisément, je pense à:

  • si la version échangée ne contient pas de modifications non sauvegardées et que le processus d'édition n'est plus en cours, pouvez-vous faire supprimer automatiquement Vim fichier d'échange?
  • pouvez-vous automatiser le processus suggéré pour enregistrer le fichier récupéré sous un nouveau nom, le fusionner avec le fichier sur le disque et ensuite supprimer l'ancien fichier de pagination, de sorte que l'interaction minimale est nécessaire? Surtout quand la version swap et la version disque sont identiques, tout devrait être automatique.

j'ai découvert le SwapExists autocommand mais je ne sais pas s'il peut aider avec ces tâches.

46
demandé sur Bruno De Fraine 2008-09-15 17:57:47

7 réponses

j'ai vim stocker mes fichiers swap dans un répertoire local unique, en ayant ceci dans mon .vimrc:

set directory=~/.vim/swap,.

entre autres avantages, cela rend les fichiers de pagination faciles à trouver tous en même temps. Maintenant, quand mon ordinateur portable perd de la puissance ou quoi que ce soit et que je commence à revenir avec un tas de fichiers de pagination qui traînent, je lance juste mon script cleanswap :

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

cela supprimera tous les fichiers swap qui sont à jour avec les fichiers réels. Tous ceux qui ne correspondent pas sont élevés dans une fenêtre vimdiff pour que je puisse fusionner dans mes changements non sauvegardés.

--chou

35
répondu Chouser 2008-10-21 02:16:50

je viens de découvrir ceci:

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

j'ai copié et collé la commande DiffOrig dans mon .fichiers vimrc et il fonctionne comme un charme. Cela facilite grandement la récupération des fichiers swap. Je n'ai aucune idée pourquoi il n'est pas inclus par défaut dans VIM.

Voici l'ordre pour ceux qui sont pressés:

 command DiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis
    \ | wincmd p | diffthis
20
répondu Jack Senechal 2008-10-21 02:10:53

la réponse acceptée est grillée pour un cas d'utilisation très important. Disons que vous créez un nouveau tampon et tapez pendant 2 heures sans jamais enregistrer, puis votre ordinateur s'écrase. Si vous exécutez le script suggéré il supprimera votre seul et unique enregistrement, le .swp fichier d'échange . Je ne sais pas quelle est la bonne solution, mais il semble que la commande diff finisse par comparer le même fichier à lui-même dans ce cas. La version éditée ci-dessous vérifie ce cas et donne une chance à l'utilisateur pour sauver le fichier quelque part.

#!/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
16
répondu coppit 2011-04-29 01:05:06

Grand bout DiffOrig est parfait. Voici un script bash que j'utilise pour l'exécuter sur chaque fichier d'échange dans le répertoire courant:

#!/bin/bash

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

for s in $swap_files ; do
        orig_file=`echo $s | perl -pe 's!/\.([^/]*).swp$!/!' `
        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

pourrait probablement utiliser un peu plus de vérification d'erreur et de citation, mais a fonctionné jusqu'à présent.

4
répondu Mark Grimes 2014-08-30 23:30:48

je préfère ne pas mettre mon répertoire de travail VIM dans le .vimrc. Voici une modification du script de chou qui copie les fichiers de swap vers le chemin de swap à la demande en vérifiant s'il y a des doublons et puis les réconcilie. Ceci a été écrit précipitamment, assurez-vous de l'évaluer avant de le mettre en pratique.

#!/bin/bash

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

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

echo looking for duplicate file names in hierarchy
swaps="$(find  -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  -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  -name '.*.swp' | while read file; do echo $(basename $file); done | sort | uniq -c | egrep '^[[:space:]]*[2-9][0-9]*.*'
fi
0
répondu Mario Aguilera 2013-05-24 20:16:50

j'ai ceci sur mon .dossier bashrc. J'aimerais donner le crédit approprié à une partie de ce code mais j'ai oublié d'où je l'ai obtenu.

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 }

je viens d'exécuter ceci sur la racine de mon projet et, si le fichier est différent, il ouvre vim diff. Puis, le dernier fichier enregistré sera conservé. Pour qu'il soit parfait, il suffit de remplacer le dernier autre:

else echo "Backup file kept as:" $bakf

par quelque chose comme

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

mais je ne l'ai pas fait le temps de le tester correctement.

J'espère que ça aidera.

0
répondu Miguel 2014-04-11 15:08:13

trouver ./ - type f-name".* sw[klmnop]" -supprimer

Crédit: @Shwaydogg https://superuser.com/questions/480367/whats-the-easiest-way-to-delete-vim-swapfiles-ive-already-recovered-from

Naviguer vers le répertoire du premier

0
répondu user3386050 2017-03-20 10:18:27