Récupération plus intelligente de Vim?
Question
Lorsqu’une session Vim précédente est bloquée, vous êtes accueilli par le fichier "Fichier d'échange ... déjà existant!". 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 enregistrées et que le processus d'édition n'est plus en cours, pouvez-vous faire en sorte que Vim supprime automatiquement le fichier d'échange?
- Pouvez-vous automatiser le processus suggéré consistant à enregistrer le fichier récupéré sous un nouveau nom, en le fusionnant avec un fichier sur disque, puis en supprimant l'ancien fichier d'échange, de sorte qu'une interaction minimale soit requise? Surtout lorsque la version d'échange et la version du disque sont identiques, tout doit être automatique.
J'ai découvert la commande automatique SwapExists
mais je ne sais pas si elle peut aider à ces tâches.
La solution
J'ai vim stocker mes fichiers d'échange dans un seul répertoire local, en l'ayant dans mon fichier .vimrc:
set directory=~/.vim/swap,.
Entre autres avantages, cela facilite la recherche des fichiers d'échange en une seule fois.
Désormais, lorsque mon ordinateur portable tombe en panne ou que je démarre et que je commence à sauvegarder avec un tas de fichiers d'échange, je lance simplement 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
Ceci supprimera tous les fichiers d'échange mis à jour avec les fichiers réels. Tous ceux qui ne correspondent pas sont affichés dans une fenêtre vimdiff afin que je puisse fusionner mes modifications non enregistrées.
- Chouser
Autres conseils
Je viens de découvrir ceci:
http://vimdoc.sourceforge.net/htmldoc/diff.html#: DiffOrig
J'ai copié et collé la commande DiffOrig dans mon fichier .vimrc et cela fonctionne comme un charme. Cela facilite grandement la récupération des fichiers d'échange. Je ne sais pas pourquoi il n'est pas inclus par défaut dans VIM.
Voici la commande pour ceux qui sont pressés:
command DiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis
\ | wincmd p | diffthis
La réponse acceptée est supprimée pour un cas d'utilisation très important. Supposons que vous créez un nouveau tampon et que vous tapez pendant 2 heures sans jamais enregistrer, votre ordinateur tombe en panne. Si vous exécutez le script suggéré , votre seul et unique enregistrement sera supprimé, le fichier d'échange .swp . Je ne suis pas sûr du correct correctif, mais il semblerait que la commande diff finisse par comparer le même fichier à lui-même dans ce cas. La version modifiée ci-dessous vérifie ce cas et donne à l'utilisateur la possibilité de sauvegarder 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
Excellent conseil DiffOrig est parfait. Voici un script bash que je utilise pour l'exécuter sur chaque fichier d'échange situé dans le répertoire actuel:
#!/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
Peut probablement utiliser davantage de vérifications d’erreur et de citations, mais a fonctionné jusqu’à présent.
Je préfère ne pas définir mon répertoire de travail VIM dans le fichier .vimrc. Voici une modification du script de chouser qui copie les fichiers d'échange dans le chemin d'échange à la demande en recherchant les doublons, puis en les réconciliant. Ceci a été écrit à la hâte, assurez-vous de l'évaluer avant de le mettre en pratique.
#!/bin/bash
if [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then
echo "Moves VIM swap files under <base-path> to ~/.vim/swap and reconciles differences"
echo "usage: <*> <base-path>"
exit 0
fi
if [ -z "$1" ] || [ ! -d "$1" ]; then
echo "directory path not provided or invalid, see <*> -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
J'ai ceci sur mon fichier .bashrc. Je souhaite attribuer un crédit approprié à une partie de ce code, mais j’ai oublié où je l’avais 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 à la racine de mon projet et, si le fichier est différent, il ouvre vim diff. Ensuite, le dernier fichier à sauvegarder sera conservé. Pour que ce soit parfait, il me suffirait de remplacer le dernier:
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 n'ai pas eu le temps de bien le tester.
J'espère que ça aide.
recherchez ./ -type f -name "". * sw [klmnop] " -delete
Crédit: @Shwaydogg https://superuser.com/ questions / 480367 / Quel est le moyen le plus simple de supprimer vim-swapfiles-ive-déjà-récupéré-de
Naviguez d'abord vers le répertoire