2008-09-15 23 views
46

Önceki bir Vim oturumu kilitlendiğinde, "Takas dosyası ... zaten var!" Ile karşılaşırsınız. önceki oturumda açık olan her dosya için.Daha akıllı Vim kurtarma?

Bu Vim kurtarma işlemini daha akıllı hale getirebilir misiniz? Eğer Vim takas dosyasını silin yapabilir, takas sürüm kaydedilmemiş değişiklikler içermiyorsa

  • ve düzenleme süreci artık çalışıyor: (! kurtarma kapatarak olmadan) Özellikle, düşünüyorum?
  • Kurtarılan dosyayı yeni bir ad altında kaydetme, diskteki dosyayla birleştirme ve eski takas dosyasını silme gibi işlemleri otomatikleştirebilir misiniz, böylece minimum etkileşim gerekir? Özellikle takas versiyonu ve disk versiyonu aynı olduğunda, her şey otomatik olmalıdır.

SwapExists autocommand'ı keşfettim ancak bu görevlerde yardımcı olup olmayacağını bilmiyorum.

+0

Bkz: http: // valmikam. Bir kopyalanabilir bir çözüm için blogspot.com/2010/09/vim-auto-backup-configuration.html. –

cevap

35

benim .vimrc bu alarak, tek bir yerel dizinde vim dükkanını benim takas dosyaları var: diğer yararlarının yanı sıra

set directory=~/.vim/swap,. 

, bu takas tek seferde bulmak kolay dosyaları yapar. Bu kadar güncel olan herhangi takas dosyaları kaldıracaktır

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 

: Şimdi benim laptop güç ya da her türlü kaybettiğinde ve ben etrafta geri takas dosyaları bir grup ile başlatmak, sadece benim cleanswap komut dosyasını çalıştırın gerçek dosyaları ile. Eşleşmeyen herhangi bir vimdiff penceresine getirildi, böylece kaydedilmemiş değişikliklerimi birleştirebilirim.

--Chouser

+0

Aynı adda iki dosyayı düzenlerseniz, örneğin bir SVN deposunun iki dalında –

+1

Aynı adla birden fazla dosya düzenlerken, Vim uzantılar için alfabede geriye doğru gider (* .swp, *. swo, * .swn, vb. Bu yöntemin kullanılması, "takas dosyası var" özelliğini devre dışı bıraktığına dikkat edilmelidir. Yani, yukarıda sağlanan 'cleanswap' komutunu kullanmak için * gerekir *. – matpie

+0

ayrıca, yazılmamış tamponları kaydetmesi gereken @coppit cevabına bakın. – alxndr

20

Sadece bu keşfetti:

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

Ben kopyalanan ve benim .vimrc dosyasına DiffOrig komutu yapıştırılan ve bir cazibe gibi çalışır. Bu, takas dosyalarının kurtarılmasını büyük ölçüde kolaylaştırır. VIM'de neden varsayılan olarak bulunmadığına dair hiçbir fikrim yok.

Burada acele olanlar için komut var:

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

Bu nedenle takas dosyasını yükledikten sonra DiffOrig'i mi çağırıyorsunuz? –

+6

Evet, komut istemi geldiğinde "kurtar" tuşuna basıp, ardından şunu yazın: DiffOrig. Sonra işiniz bittiğinde arabelleği kurtarırsınız. Daha sonra takas dosyasını silmek için (bir dahaki sefere hala oyalanacak ve hata yapacağınız için), sadece şunu yazın: e, bu komut istemini tekrar getirir ve "sil" tuşuna basabilirsiniz. –

+1

Bu şimdi Vim –

4

Büyük uç DiffOrig mükemmeldir.

#!/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 

Muhtemelen biraz daha hata denetimi ve alıntı ama şimdiye kadar çalıştı kullanabilirsiniz: İşte bu karar doğrultusunda her takas dosyası üzerinde çalıştırmak için kullandığımız bir bash script.

+0

Oh ile birlikte iyilik, çok yararlı ve basit. 'Set directory = ~/.vim/swap, .' ile bağlanmış ve bu güzel çalışıyor. –

+0

Diğer swap uzantılarını desteklemek için birkaç değişikliğe ihtiyaç duysa da, "swo | swn" gibi –

16

Kabul edilen cevap çok önemli bir kullanım durumu için bozulur. Yeni bir arabellek oluşturduğunuzu ve kaydetmeden 2 saat yazmaya başladığınızı varsayalım, dizüstü bilgisayarınız çöküyor. Önerilen betiği çalıştırırsanız, bir ve yalnızca kayıtlarınızı siler, .swp swap dosyasını. Doğru düzeltmenin ne olduğundan emin değilim, fakat bu komutta aynı dosyayı kendi başına karşılaştıran diff komutu gibi görünüyor. Aşağıdaki düzenlenmiş sürüm bu durumu kontrol eder ve kullanıcıya dosyayı bir yere kaydetme şansı verir.

#!/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 
+1

İki saat kaydetmeden mi? Davranışınızı kaydetme, kabul edilmeyen senaryolara göre düzeltmelisiniz. Düşünmek için beklediğimde otomatik olarak kaydediyorum. – ZyX

+18

İki saat ya da iki saniye olsun, sessizce veri kaybetmek kabul edilemez ve düzeltmek kesinlikle haklıydı. Küçümseme gerek yok. – cecilkorik

+0

Tehlike: Eğer bu komut dosyasını .swp dosyalarında merkezi bir takas dosyası dir (örn., SWAP_FILE_DIR 'yi '.' olarak değiştirmeden) kullanmaya çalışırsanız, dosyalarınızın birçoğu ** silinecektir. Öyleyse yapma. Veya 'for' döngüsündeki' $ SWAP_FILE_DIR/* 'değerini alın. – Dan

0

VIM çalışma dizinimi .vimrc'ye ayarlamamayı tercih ediyorum. Burada, yinelenen dosyaları kontrol etmek için takas dosyalarını takas yoluna kopyalar ve sonra bunları birleştirir. Bu yazılı olarak yazıldı, pratik kullanıma koymadan önce bunu değerlendirdiğinizden emin olun.

#!/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 
0

Bunu, .bashrc dosyamda var. Bu kodun bir kısmına uygun bir kredi vermek istiyorum ancak nereden aldığımı unuttum.

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 } 

Sadece bunu projemin kökü üzerinde çalıştırıyorum ve dosya farklıysa, vim diff'i açar. Daha sonra kaydedilecek son dosya korunur.

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

gibi bir şey tarafından

else echo "Backup file kept as:" $bakf 

ama düzgün test etmek için zaman alamadım: mükemmel Sadece geçen başka yerini alması gerekiyor yapmak.

Yardım edin.