51

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

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

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

自動コマンドを発見しましたSwapExistsが、これらのタスクに役立つかどうかはわかりません。

4

7 に答える 7

38

これを.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 ウィンドウに表示されるので、保存していない変更をマージできます。

--Chouser

于 2008-09-15T14:20:29.417 に答える
23

私はこれを発見しました:

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

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

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

 command DiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis
    \ | wincmd p | diffthis
于 2008-10-21T02:10:53.033 に答える
16

受け入れられた回答は、非常に重要なユースケースで破棄されます。新しいバッファを作成し、保存せずに 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
于 2011-04-29T01:05:06.963 に答える
4

素晴らしいヒント 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

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

于 2009-04-24T03:03:14.973 に答える
0

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

クレジット: @Shwaydogg https://superuser.com/questions/480367/whats-the-easiest-way-to-delete-vim-swapfiles-ive-already-recovered-from

最初にディレクトリに移動

于 2016-10-06T11:10:55.503 に答える
0

VIM 作業ディレクトリを .vimrc に設定したくありません。これはchouserのスクリプトを変更したもので、スワップファイルを必要に応じてスワップパスにコピーし、重複をチェックしてからそれらを調整します。ざっくばらんに書いたので、実用化する前に必ず評価してください。

#!/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
于 2013-05-24T20:16:50.920 に答える