質問

以前の Vim セッションがクラッシュすると、「ファイルをスワップ...」というメッセージが表示されます。すでに存在します!」というメッセージが、前のセッションで開かれていたすべてのファイルに表示されます。

この Vim 回復プロンプトをもっとスマートにすることはできますか?(回復をオフにすることなく!) 具体的には、次のことを考えています。

  • スワップされたバージョンに未保存の変更が含まれておらず、編集プロセスが実行されていない場合、Vim にスワップ ファイルを自動的に削除させることはできますか?
  • 回復したファイルを新しい名前で保存し、ディスク上のファイルとマージし、古いスワップ ファイルを削除するという推奨プロセスを自動化して、最小限の操作で済むようにすることはできますか?特にスワップ バージョンとディスク バージョンが同じ場合は、すべてが自動的に行われる必要があります。

私が発見したのは、 SwapExists autocommand を使用できますが、これらのタスクに役立つかどうかはわかりません。

役に立ちましたか?

解決

これを .vimrc に含めることで、vim にスワップ ファイルを単一のローカル ディレクトリに保存させます。

set directory=~/.vim/swap,.

これにより、スワップ ファイルを一度に簡単に見つけられるようになります。今では、ラップトップの電源が切れたり、その他の理由で、大量のスワップ ファイルが残った状態でバックアップを開始したときに、 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

これにより、実際のファイルと同じ最新のスワップ ファイルがすべて削除されます。一致しないものは vimdiff ウィンドウに表示されるので、保存されていない変更をマージできます。

--チョーザー

他のヒント

私はちょうどこれを発見しました:

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

DiffOrig コマンドをコピーして .vimrc ファイルに貼り付けると、まるで魔法のように機能します。これにより、スワップ ファイルのリカバリが大幅に容易になります。なぜデフォルトで VIM に含まれていないのかわかりません。

急いでいる人向けのコマンドは次のとおりです。

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

受け入れられた回答は、非常に重要なユースケースに関しては無効です。新しいバッファを作成し、保存せずに 2 時間入力した後、ラップトップがクラッシュしたとします。提案されたスクリプトを実行すると、 唯一のレコードである .swp スワップ ファイルが削除されます。. 。何が正しい修正なのかはわかりませんが、この場合 diff コマンドは同じファイルをそれ自体と比較することになるようです。以下の編集バージョンは、このケースをチェックし、ユーザーにファイルをどこかに保存する機会を与えます。

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

素晴らしいヒント DiffOrig は完璧です。現在のディレクトリ内の各スワップ ファイルで実行するために使用する bash スクリプトは次のとおりです。

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

おそらく、もう少しエラーチェックと引用を使用できるかもしれませんが、これまでのところ機能しています。

VIM 作業ディレクトリを .vimrc に設定しないことを好みます。これは、スワップ ファイルをオンデマンドでスワップ パスにコピーして重複をチェックし、それらを調整する選択者のスクリプトの変更です。これは急いで書かれたものです。実際に使用する前に必ず評価してください。

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

これは .bashrc ファイルにあります。このコードの一部に適切なクレジットを与えたいのですが、どこから入手したか忘れてしまいました。

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 }

これをプロジェクトのルートで実行すると、ファイルが異なる場合は vim diff が開きます。その後、最後に保存されたファイルが保持されます。完璧にするには、最後の else を置き換えるだけです。

else echo "Backup file kept as:" $bakf

のようなものによって

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

しかし、適切にテストする時間がありませんでした。

それが役に立てば幸い。

find ./ -type f -name ".*sw[klmnop]" -delete

クレジット:@シュウェイドッグhttps://superuser.com/questions/480367/whats-the-easyest-way-to-delete-vim-swapfiles-ive-already-recovered-from

最初にディレクトリに移動します

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top