Più intelligente Vim di recupero?
Domanda
Quando un precedente Vim sessione si è schiantato, si sono salutati con il "file di Swap ...esiste già!" per ogni file che è stato aperto nella sessione precedente.
Si può fare questo Vim prompt di ripristino più intelligente?(Senza spegnere il recupero!) In particolare, sto pensando a:
- Se il scambiato versione non contiene modifiche non salvate e il processo di editing non è più in esecuzione, si può fare Vim eliminare automaticamente i file di swap?
- Si può automatizzare il processo raccomandato di salvare il file recuperato sotto un nuovo nome, l'unione dei file su disco e quindi di eliminare il vecchio file di swap, in modo che il minimo è necessaria l'interazione?Soprattutto quando lo swap versione e la versione di disco sono gli stessi, dovrebbe essere tutto automatico.
Ho scoperto il SwapExists
autocommand, ma non so se si può aiutare con questi compiti.
Soluzione
Ho vim archiviare i miei file di swap in una singola directory locale, avendo nel mio .vimrc:
set directory=~/.vim/swap,.
Tra gli altri vantaggi, questo rende il file di swap facile trovare tutti in una volta.Ora, quando il mio portatile perde potenza o qualsiasi altra cosa e mi avvio per eseguire il backup con un sacco di file di swap, che in giro, ho appena eseguito le mie cleanswap
script:
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
Questo rimuoverà tutti i file di swap che sono up-to-date con il vero e proprio file.Qualsiasi che non corrispondono e sono cresciuto in un vimdiff finestra, così posso unire a mio modifiche non salvate.
--Chouser
Altri suggerimenti
Ho appena scoperto questo:
http://vimdoc.sourceforge.net/htmldoc/diff.html#:DiffOrig
Ho copiato e incollato il DiffOrig comando nel mio .file vimrc e funziona come un fascino.Questo facilita enormemente il recupero di file di swap.Non ho idea del perché non è incluso di default in VIM.
Ecco il comando per coloro che sono di fretta:
command DiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis
\ | wincmd p | diffthis
Accettato risposta è rotto per un uso molto importante caso.Diciamo che si crea un nuovo buffer e il tipo per 2 ore senza mai salvare, allora il vostro computer portatile si blocca.Se si esegue lo script suggerito elimina il tuo unico e solo record, il .swp file di swap.Io non sono sicuro di quale sia la giusta correzione, ma sembra che il comando diff finisce a confronto lo stesso file a se stesso in questo caso.La versione modificata sotto controllo per questo caso e dà all'utente la possibilità di salvare il file da qualche parte.
#!/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
Grande punta DiffOrig è perfetto.Qui è uno script bash che ho utilizzato per eseguire su ogni swap file sotto la directory corrente:
#!/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
Probabilmente potrebbe usare un po ' più di controllo di errore e di quotazione, ma ha funzionato finora.
Preferisco non impostare il mio VIM directory di lavoro in .vimrc.Ecco una modifica di chouser script che copia il file di swap swap percorso su richiesta di controllo duplicati e poi li riconcilia.Questo è stato scritto di fretta, assicurarsi di valutare prima di metterlo in pratica.
#!/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
Ho questo sul mio .bashrc.Vorrei dare credito appropriato di parte del codice, ma ho dimenticato dove l'ho preso da.
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 }
Ho appena eseguire il root del mio progetto e, SE il file è diverso, si apre vim diff.Poi, l'ultimo file salvato sarà mantenuta.Per rendere perfetto dovrei solo sostituire l'ultimo else:
else echo "Backup file kept as:" $bakf
da qualcosa come
else vim $bakf -c ":wq! $orif" && echo "Backup file kept and saved as:" $orif
ma non ho avuto il tempo necessario per eseguire il test.
Speranza che aiuta.
trovare ./ -type f -name ".*sw[klmnop]" -eliminare
Credito:@Shwaydogg https://superuser.com/questions/480367/whats-the-easiest-way-to-delete-vim-swapfiles-ive-already-recovered-from
Passare alla directory