更智能的Vim恢复?

当以前的Vim会话崩溃时,您会收到“Swap file … already exists! 对于上一个会话中打开的每个文件。

你可以让这个Vim恢复提示更聪明吗? (不closures恢复!)具体来说,我在想:

  • 如果交换版本不包含未保存的更改并且编辑过程不再运行,您可以让Vim自动删除交换文件吗?
  • 你可以自动化build议的过程中保存恢复的文件在一个新的名字,合并它与磁盘上的文件,然后删除旧的交换文件,以便最小的交互是必需的? 特别是当交换版本和磁盘版本相同时,一切都应该是自动的。

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

我有vim存储我的交换文件在一个单一的本地目录,通过在我的.vimrc中:

 set directory=~/.vim/swap,. 

除了其他好处之外,这使交换文件一次很容易find。 现在,当我的笔记本电脑失去了电源或者其他东西,我开始备份大量的交换文件,我只是运行我的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 )" \ -cw\! \ -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

我刚刚发现这个:

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

我复制并粘贴了DiffOrig命令到我的.vimrc文件,它的作用就像一个魅力。 这大大简化了交换文件的恢复。 我不知道为什么它没有被默认包含在VIM中。

下面是那些匆忙的人的命令:

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

被接受的答案是一个非常重要的用例。 假设您创build一个新的缓冲区并input2个小时而不需要保存,那么您的笔记本电脑就会崩溃。 如果您运行build议的脚本,它将删除您的唯一logging,即.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 )" \ -cw\! \ -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 

可能可以使用更多的错误检查和引用,但迄今为止工作。

我宁愿不要在.vimrc中设置我的VIM工作目录。 下面是对chouser脚本的修改,它将交换文件复制到交换path上,根据需要检查重复项,然后进行协调。 这是写的冲,确保评估之前,付诸实际使用。

 #!/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 )" \ -cw\! \ -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。 然后,保存最后一个文件将被保存。 为了使它完美,我只需要replace最后一个:

 else echo "Backup file kept as:" $bakf 

由类似的东西

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

但是我没有时间去正确地testing它。

希望能帮助到你。

find./ -type f -name“。* sw [klmnop]” – 删除

信用:@Shwaydogg https://superuser.com/questions/480367/whats-the-easiest-way-to-delete-vim-swapfiles-ive-already-recovered-from

先导航到目录