代码之家  ›  专栏  ›  技术社区  ›  Eugene Yarmash

如果文件已从外部更改,我如何使VIM自动检查?

vim
  •  9
  • Eugene Yarmash  · 技术社区  · 14 年前

    我通常在选项卡中打开许多文件 vim -p . 是否可以检查自编辑开始后是否在VIM之外更改了任何文件?

    6 回复  |  直到 8 年前
        1
  •  10
  •   Eugene Yarmash    8 年前

    将这些行添加到 .vimrc :

    au FocusGained,BufEnter * :silent! checktime
    au FocusLost,WinLeave * :silent! w
    

    基本上,当VIM或当前缓冲区获得焦点时,检查并重新加载(或放弃)外部更改,或者在离开焦点时自动保存。

    资料来源: Vim Wiki .

        2
  •  6
  •   ezpz    14 年前

    今天我遇到了一个与这个问题有关的有趣的发现…

    隐藏在 /usr/share/vim/vim71/vimrc_example.vim 有以下命令:

    " Convenient command to see the difference between the current buffer and the
    " file it was loaded from, thus the changes you made.
    command DiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis
            \ | wincmd p | diffthis
    

    它将打开一个 vimdiff -类似于窗口,当前缓冲区和底层文件突出显示了这两者之间的所有更改。

        3
  •  3
  •   Josh    14 年前

    如果它检测到文件的外部更改,VIM通常会自动警告我;但是,通过仔细阅读文档,您似乎可以使用 :checktime

    不幸的是,我不知道如何禁用前面提到的自动检查来测试,看看检查时间是否做了正确的事情,所以这个答案可能完全是错误的。

        4
  •  2
  •   ezpz    14 年前

    使用 :edit

    :help :edit 更多信息。

        5
  •  1
  •   nelstrom    14 年前

    您可以通过运行以下命令来确定活动窗口中的缓冲区是否被修改:

    :set mod?
    

    如果它回来 nomodified ,然后缓冲区的内容与相应文件的内容匹配。如果它回来 modified ,则缓冲区具有未保存的更改。

    默认情况下,状态行显示 [+] 符号表示当前缓冲区已被修改。状态行通常只有在有拆分窗口的情况下才可见。如果要显示状态行,即使只有一个窗口,也要运行:

    :set laststatus=2
    

    有一篇关于 customizing your status line 关于VIM配方。

        6
  •  0
  •   ZyX    14 年前
    let s:pid=system("ps -p $$ -o ppid=")+0
    if !exists('g:watches')
        let g:watches={}
    else
        finish
    endif
    function! ModWatch(fname, match)
        let fname=fnamemodify(a:fname, ':p')
        if has_key(g:watches, fname)
            return
        endif
        let shellscript=
                    \"while true ; do".
                    \"    inotifywait ".shellescape(fname)." ; ".
                    \"    kill -WINCH ".s:pid." ; ".
                    \"done"
        echo shellscript
        echo shellescape(shellscript)
        let pid=system("sh -c ".shellescape(shellscript)." &>/dev/null & echo $!")+0
        call extend(g:watches, { fname : pid })
        augroup ModWatch
            execute "autocmd! BufWipeOut ".a:match
            execute "autocmd BufWipeOut ".a:match.' call DeleteWatch("'.
                        \escape(fname, '\"|').'")'
        augroup END
    endfunction
    function! DeleteWatch(fname)
        call system("kill ".g:watches[a:fname])
        unlet g:watches[a:fname]
    endfunction
    augroup ModWatch
        autocmd!
        autocmd VimResized * checktime
        autocmd BufNew * call ModWatch(expand("<afile>"), expand("<amatch>"))
    augroup END