Vim恢复更智能?

时间:2020-03-05 18:53:32  来源:igfitidea点击:

当上一个Vim会话崩溃时,会出现"交换文件...已经存在!"的字样。在上一个会话中打开的每个文件。

我们可以使此Vim恢复提示更加智能吗? (无需关闭恢复!)具体来说,我在考虑:

  • 如果交换版本不包含未保存的更改,并且编辑过程不再运行,我们可以使Vim自动删除交换文件吗?
  • 我们是否可以自动执行建议的过程,将恢复的文件保存为新名称,将其与磁盘上的文件合并,然后删除旧的交换文件,以使交互作用降到最低?尤其是当交换版本和磁盘版本相同时,所有内容都应该是自动的。

我发现了SwapExists自动命令,但我不知道它是否可以帮助完成这些任务。

解决方案

回答

我通过在.vimrc中将交换文件存储在单个本地目录中:

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

回答

大提示DiffOrig非常完美。这是一个bash脚本,我用它在当前目录下的每个交换文件上运行它:

#!/bin/bash

swap_files=`find . -name "*.swp"`

for s in $swap_files ; do
        orig_file=`echo $s | perl -pe 's!/\.([^/]*).swp$!/!' `
        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

可能可以使用更多的错误检查和引用,但到目前为止已经奏效。