<p>When a previous Vim session crashed, you are greeted with the "Swap file ... already exists!" for each and every file that was open in the previous session.</p>

<p>Can you make this Vim recovery prompt smarter? (Without switching off recovery!) Specifically, I'm thinking of:</p>

<ul>
<li>If the swapped version does not contain unsaved changes and the editing process is no longer running, can you make Vim automatically delete the swap file?</li>
<li>Can you automate the suggested process of saving the recovered file under a new name, merging it with file on disk and then deleting the old swap file, so that minimal interaction is required? Especially when the swap version and the disk version are the same, everything should be automatic.</li>
</ul>

<p>I discovered the <code>SwapExists</code> autocommand but I don't know if it can help with these tasks.</p>

[{'answer_id': 63341, 'author': 'Chouser', 'author_id': 7624, 'author_profile': 'https://Stackoverflow.com/users/7624', 'pm_score': 6, 'selected': True, 'text': '<p>I have vim store my swap files in a single local directory, by having this in my .vimrc:</p>\n\n<pre><code>set directory=~/.vim/swap,.\n</code></pre>\n\n<p>Among other benefits, this makes the swap files easy to find all at once.\nNow when my laptop loses power or whatever and I start back up with a bunch of swap files laying around, I just run my <code>cleanswap</code> script:</p>\n\n<pre><code>TMPDIR=$(mktemp -d) || exit 1\nRECTXT="$TMPDIR/vim.recovery.$USER.txt"\nRECFN="$TMPDIR/vim.recovery.$USER.fn"\ntrap \'rm -f "$RECTXT" "$RECFN"; rmdir "$TMPDIR"\' 0 1 2 3 15\nfor q in ~/.vim/swap/.*sw? ~/.vim/swap/*; do\n  [[ -f $q ]] || continue\n  rm -f "$RECTXT" "$RECFN"\n  vim -X -r "$q" \\\n      -c "w! $RECTXT" \\\n      -c "let fn=expand(\'%\')" \\\n      -c "new $RECFN" \\\n      -c "exec setline( 1, fn )" \\\n      -c w\\! \\\n      -c "qa"\n  if [[ ! -f $RECFN ]]; then\n    echo "nothing to recover from $q"\n    rm -f "$q"\n    continue\n  fi\n  CRNT="$(cat $RECFN)"\n  if diff --strip-trailing-cr --brief "$CRNT" "$RECTXT"; then\n      echo "removing redundant $q"\n      echo "  for $CRNT"\n      rm -f "$q"\n  else\n      echo $q contains changes\n      vim -n -d "$CRNT" "$RECTXT"\n      rm -i "$q" || exit\n  fi\ndone\n</code></pre>\n\n<p>This will remove any swap files that are up-to-date with the real files.  Any that don\'t match are brought up in a vimdiff window so I can merge in my unsaved changes.</p>\n\n<p>--Chouser</p>\n'}, {'answer_id': 220543, 'author': 'Jack Senechal', 'author_id': 29833, 'author_profile': 'https://Stackoverflow.com/users/29833', 'pm_score': 5, 'selected': False, 'text': '<p>I just discovered this:</p>\n\n<p><a href="http://vimdoc.sourceforge.net/htmldoc/diff.html#:DiffOrig" rel="noreferrer">http://vimdoc.sourceforge.net/htmldoc/diff.html#:DiffOrig</a></p>\n\n<p>I copied and pasted the DiffOrig command into my .vimrc file and it works like a charm. This greatly eases the recovery of swap files. I have no idea why it isn\'t included by default in VIM.</p>\n\n<p>Here\'s the command for those who are in a hurry:</p>\n\n<pre><code> command DiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis\n    \\ | wincmd p | diffthis\n</code></pre>\n'}, {'answer_id': 784372, 'author': 'Mark Grimes', 'author_id': 13233, 'author_profile': 'https://Stackoverflow.com/users/13233', 'pm_score': 2, 'selected': False, 'text': '<p>Great tip DiffOrig is perfect. Here is a bash script I use to run it on each swap file under the current directory:</p>\n\n<pre><code>#!/bin/bash\n\nswap_files=`find . -name "*.swp"`\n\nfor s in $swap_files ; do\n        orig_file=`echo $s | perl -pe \'s!/\\.([^/]*).swp$!/$1!\' `\n        echo "Editing $orig_file"\n        sleep 1\n        vim -r $orig_file -c "DiffOrig"\n        echo -n "  Ok to delete swap file? [y/n] "\n        read resp\n        if [ "$resp" == "y" ] ; then\n                echo "  Deleting $s"\n                rm $s\n        fi\ndone\n</code></pre>\n\n<p>Probably could use some more error checking and quoting but has worked so far.</p>\n'}, {'answer_id': 5826793, 'author': 'coppit', 'author_id': 730300, 'author_profile': 'https://Stackoverflow.com/users/730300', 'pm_score': 4, 'selected': False, 'text': '<p>The accepted answer is busted for a very important use case. Let\'s say you create a new buffer and type for 2 hours without ever saving, then your laptop crashes. If you run the suggested script <strong>it will delete your one and only record, the .swp swap file</strong>. I\'m not sure what the right fix is, but it looks like the diff command ends up comparing the same file to itself in this case. The edited version below checks for this case and gives the user a chance to save the file somewhere.</p>\n\n<pre><code>#!/bin/bash\n\nSWAP_FILE_DIR=~/temp/vim_swp\nIFS=$\'\\n\'\n\nTMPDIR=$(mktemp -d) || exit 1\nRECTXT="$TMPDIR/vim.recovery.$USER.txt"\nRECFN="$TMPDIR/vim.recovery.$USER.fn"\ntrap \'rm -f "$RECTXT" "$RECFN"; rmdir "$TMPDIR"\' 0 1 2 3 15\nfor q in $SWAP_FILE_DIR/.*sw? $SWAP_FILE_DIR/*; do\n  echo $q\n  [[ -f $q ]] || continue\n  rm -f "$RECTXT" "$RECFN"\n  vim -X -r "$q" \\\n      -c "w! $RECTXT" \\\n      -c "let fn=expand(\'%\')" \\\n      -c "new $RECFN" \\\n      -c "exec setline( 1, fn )" \\\n      -c w\\! \\\n      -c "qa"\n  if [[ ! -f $RECFN ]]; then\n    echo "nothing to recover from $q"\n    rm -f "$q"\n    continue\n  fi\n  CRNT="$(cat $RECFN)"\n  if [ "$CRNT" = "$RECTXT" ]; then\n      echo "Can\'t find original file. Press enter to open vim so you can save the file. The swap file will be deleted afterward!"\n      read\n      vim "$CRNT"\n      rm -f "$q"\n  else if diff --strip-trailing-cr --brief "$CRNT" "$RECTXT"; then\n      echo "Removing redundant $q"\n      echo "  for $CRNT"\n      rm -f "$q"\n  else\n      echo $q contains changes, or there may be no original saved file\n      vim -n -d "$CRNT" "$RECTXT"\n      rm -i "$q" || exit\n  fi\n  fi\ndone\n</code></pre>\n'}, {'answer_id': 16742978, 'author': 'Mario Aguilera', 'author_id': 289870, 'author_profile': 'https://Stackoverflow.com/users/289870', 'pm_score': 0, 'selected': False, 'text': '<p>I prefer to not set my VIM working directory in the .vimrc. Here\'s a modification of chouser\'s script that copies the swap files to the swap path on demand checking for duplicates and then reconciles them. This was written rushed, make sure to evaluate it before putting it to practical use.</p>\n\n<pre><code>#!/bin/bash\n\nif [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then\n   echo "Moves VIM swap files under &lt;base-path&gt; to ~/.vim/swap and reconciles differences"\n   echo "usage: $0 &lt;base-path&gt;"\n   exit 0\nfi\n\nif [ -z "$1" ] || [ ! -d "$1" ]; then\n   echo "directory path not provided or invalid, see $0 -h"\n   exit 1\nfi\n\necho looking for duplicate file names in hierarchy\nswaps="$(find $1 -name \'.*.swp\' | while read file; do echo $(basename $file); done | sort | uniq -c | egrep -v "^[[:space:]]*1")"\nif [ -z "$swaps" ]; then\n   echo no duplicates found\n   files=$(find $1 -name \'.*.swp\')\n   if [ ! -d ~/.vim/swap ]; then mkdir ~/.vim/swap; fi\n   echo "moving files to swap space ~./vim/swap"\n   mv $files ~/.vim/swap\n   echo "executing reconciliation"\n   TMPDIR=$(mktemp -d) || exit 1\n   RECTXT="$TMPDIR/vim.recovery.$USER.txt"\n   RECFN="$TMPDIR/vim.recovery.$USER.fn"\n   trap \'rm -f "$RECTXT" "$RECFN"; rmdir "$TMPDIR"\' 0 1 2 3 15\n   for q in ~/.vim/swap/.*sw? ~/.vim/swap/*; do\n     [[ -f $q ]] || continue\n     rm -f "$RECTXT" "$RECFN"\n     vim -X -r "$q" \\\n         -c "w! $RECTXT" \\\n         -c "let fn=expand(\'%\')" \\\n         -c "new $RECFN" \\\n         -c "exec setline( 1, fn )" \\\n         -c w\\! \\\n         -c "qa"\n     if [[ ! -f $RECFN ]]; then\n       echo "nothing to recover from $q"\n       rm -f "$q"\n       continue\n     fi\n     CRNT="$(cat $RECFN)"\n     if diff --strip-trailing-cr --brief "$CRNT" "$RECTXT"; then\n         echo "removing redundant $q"\n         echo "  for $CRNT"\n         rm -f "$q"\n     else\n         echo $q contains changes\n         vim -n -d "$CRNT" "$RECTXT"\n         rm -i "$q" || exit\n     fi\n   done\nelse\n   echo duplicates found, please address their swap reconciliation manually:\n   find $1 -name \'.*.swp\' | while read file; do echo $(basename $file); done | sort | uniq -c | egrep \'^[[:space:]]*[2-9][0-9]*.*\'\nfi\n</code></pre>\n'}, {'answer_id': 23016290, 'author': 'Miguel', 'author_id': 2773308, 'author_profile': 'https://Stackoverflow.com/users/2773308', 'pm_score': 0, 'selected': False, 'text': '<p>I have this on my .bashrc file. I would like to give appropriate credit to part of this code but I forgot where I got it from.</p>\n\n<pre><code>mswpclean(){\n\nfor i in `find -L -name \'*swp\'`\ndo\n    swpf=$i\n    aux=${swpf//"/."/"/"}\n    orif=${aux//.swp/}\n    bakf=${aux//.swp/.sbak}\n\n    vim -r $swpf -c ":wq! $bakf" &amp;&amp; rm $swpf\n    if cmp "$bakf" "$orif" -s\n    then rm $bakf &amp;&amp; echo "Swap file was not different: Deleted" $swpf\n    else vimdiff $bakf $orif\n    fi\ndone\n\nfor i in `find -L -name \'*sbak\'`\ndo\n    bakf=$i\n    orif=${bakf//.sbak/}\n    if test $orif -nt $bakf\n    then rm $bakf &amp;&amp; echo "Backup file deleted:" $bakf\n    else echo "Backup file kept as:" $bakf\n    fi\ndone }\n</code></pre>\n\n<p>I just run this on the root of my project and, IF the file is different, it opens vim diff. Then, the last file to be saved will be kept. To make it perfect I would just need to replace the last else:</p>\n\n<pre><code>else echo "Backup file kept as:" $bakf\n</code></pre>\n\n<p>by something like</p>\n\n<pre><code>else vim $bakf -c ":wq! $orif" &amp;&amp; echo "Backup file kept and saved as:" $orif\n</code></pre>\n\n<p>but I didn\'t get time to properly test it.</p>\n\n<p>Hope it helps.</p>\n'}, {'answer_id': 39894423, 'author': 'user3386050', 'author_id': 3386050, 'author_profile': 'https://Stackoverflow.com/users/3386050', 'pm_score': 0, 'selected': False, 'text': '<p>find ./ -type f -name ".*sw[klmnop]" -delete</p>\n\n<p>Credit: @Shwaydogg\n<a href="https://superuser.com/questions/480367/whats-the-easiest-way-to-delete-vim-swapfiles-ive-already-recovered-from">https://superuser.com/questions/480367/whats-the-easiest-way-to-delete-vim-swapfiles-ive-already-recovered-from</a></p>\n\n<p>Navigate to directory first</p>\n'}]
['https://Stackoverflow.com/questions/63104', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/6918/']