代码之家  ›  专栏  ›  技术社区  ›  Bruno De Fraine

更智能的VIM恢复?

  •  46
  • Bruno De Fraine  · 技术社区  · 16 年前

    当前一个VIM会话崩溃时,您会收到“交换文件…已经存在!”对于在上一个会话中打开的每个文件。

    你能让这个VIM恢复提示更智能吗?(不关闭恢复!)具体来说,我想:

    • 如果交换的版本不包含未保存的更改,并且编辑过程不再运行,可以使VIM自动删除交换文件吗?
    • 您是否可以自动执行建议的以新名称保存恢复的文件、将其与磁盘上的文件合并,然后删除旧的交换文件的过程,从而使所需的交互最少?尤其是当交换版本和磁盘版本相同时,一切都应该是自动的。

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

    7 回复  |  直到 8 年前
        1
  •  35
  •   Andy Lester    16 年前

    我让vim将交换文件存储在一个本地目录中,方法是将其保存在.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窗口中显示,这样我就可以合并未保存的更改。

    ——Chouser

        2
  •  20
  •   Jack Senechal    16 年前

    我刚刚发现了:

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

    我复制并将difforig命令粘贴到我的.vimrc文件中,它的工作方式很迷人。这大大简化了交换文件的恢复。我不知道为什么vim中没有默认包含它。

    这是给那些匆忙的人的命令:

     command DiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis
        \ | wincmd p | diffthis
    
        3
  •  16
  •   coppit    13 年前

    对于一个非常重要的用例,公认的答案是错误的。假设你创建了一个新的缓冲区,输入了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
    
        4
  •  4
  •   kzh    10 年前

    好的尖端差异是完美的。下面是我在当前目录下的每个交换文件上运行的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
    

    也许可以使用更多的错误检查和引用,但迄今为止已经奏效了。

        5
  •  0
  •   Mario Aguilera    11 年前

    我宁愿不在.vimrc中设置我的vim工作目录。这里是对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
    
        6
  •  0
  •   Miguel    10 年前

    我的.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 echo "Backup file kept as:" $bakf
    

    有点像

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

    但我没有时间来测试它。

    希望它有帮助。

        7
  •  0
  •   Community Egal    7 年前

    查找。/-类型F-名称“.*sw[klmnop]”-删除

    学分:@shwaydogg https://superuser.com/questions/480367/whats-the-easiest-way-to-delete-vim-swapfiles-ive-already-recovered-from

    先导航到目录