在将文件保存到Vim之前,我能看到更改吗?

时间:2009-04-14 20:41:17

标签: diff vim preview

我使用Vim。 我打开一个文件。我编辑它,我希望在保存之前看到我编辑的内容。

我怎么能在Vim中做到这一点?

14 个答案:

答案 0 :(得分:140)

:w !diff % -

答案 1 :(得分:83)

因为有些人询问了命令的解释

:w !diff % -

这是我尝试撰写更详细的答案:

我假设你正在安装一个安装了catecho的系统(例如几乎任何GNU / Linux,Mac OS,BSD和其他类UNIX系统)。

以上命令的工作原理如下:

  1. 在vim中保存文件的语法是:

    :w <filename>
    
  2. 在vim中执行shell命令的语法是:

    :!<command>
    
  3. vim %发出的shell环境中恰好指向当前文件名。您可以通过执行以下操作来验证这一点:

    :!echo %
    

    这应该输出文件名(如果没有文件名运行vim,则输出错误。)

    使用cat我们也可以输出文件的内容:

    :!cat %
    

    这应该返回上次保存状态的文件内容,如果从未保存过,则返回错误。

  4. 程序diff能够从标准输入(stdin)读取。其手册页说明了以下内容:

      

    [...]如果文件是' - ',则读取标准输入。 [...]

  5. 执行不带文件名的save命令,而是执行后面的shell命令会导致vim将文件内容写入shell的stdin,而不是将其保存在物理文件中。您可以通过执行

    来验证这一点
    :w !cat
    

    这应该始终打印文件当前内容(本来可以写入文件)。

  6. 把它放在一起(或tl; dr):文件被“保存”到stdin,diff以文件名和stdin作为输入运行。

    知道这个也可以比较文件和vimdiff做这样的事情 - 这只是一个你不想这样做的想法:

    :w !cat > /tmp/tempFile && vimdiff /tmp/tempFile % && rm /tmp/tempFile
    

    (然后打开只读并使用:qall关闭vimdiff)

答案 2 :(得分:51)

http://vim.wikia.com/wiki/Diff_current_buffer_and_the_original_file

  

这是一个函数和命令,用于查看当前编辑的文件与文件系统中未修改版本之间的差异。只需将其放入vimrc或插件目录中,打开文件,进行一些修改而不保存它们,并执行:DiffSaved

function! s:DiffWithSaved()
  let filetype=&ft
  diffthis
  vnew | r # | normal! 1Gdd
  diffthis
  exe "setlocal bt=nofile bh=wipe nobl noswf ro ft=" . filetype
endfunction
com! DiffSaved call s:DiffWithSaved()
     

要退出差异视图,您可以使用:diffoff命令。

     

下面是一个类似的功能,适合模仿'cvs diff'命令......

答案 3 :(得分:9)

我一直很喜欢diffchanges - 很好,很简单,很有效。

答案 4 :(得分:9)

来自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.
if !exists(":DiffOrig")
  command DiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis
          \ | wincmd p | diffthis
endif

答案 5 :(得分:2)

获取以下内容并使用:DIFF命令

function! s:diff()
    let tmpa = tempname()
    let tmpb = tempname()
    earlier 100h
    exec 'w '.tmpa
    later 100h
    exec 'w '.tmpb
    update
    exec 'tabnew '.tmpa
    diffthis
    vert split
    exec 'edit '.tmpb
    diffthis
endfunction
command! -nargs=0 DIFF call <SID>diff()

答案 6 :(得分:2)

不完全是你想要的,但SCMDiff.vim真的很酷。一个按键,它使用源控件仓库中的头版本扩展当前文件。它意味着与许多SCMS合作。我在perforce中使用它。

答案 7 :(得分:1)

我可以推荐histwin插件。

虽然它没有与文件的当前保存的版本不同(如其他答案),但它可以 vimdiff更改,因为您开始编辑,甚至<强>重播您的更改顺序。差异显示您是否在中间保存。

此外,它还会显示所有撤消历史记录分支的列表,并允许您在它们之间切换或区分。

PS:虽然每次更改文件后插件都不会自动跟踪编辑历史记录中的时刻,但您可以明确“标记”保存文件的时刻,以便稍后可以使用它进行vimdiff,如果需要的话。也许这可以自动化?

答案 8 :(得分:1)

如果你想像vimdiff一样使用vim进行比较,你可以这样做:

编辑.vimrc并添加:

nmap <F8> :w !vim -M -R - -c ":vnew % \| windo diffthis"<CR><CR>

从那里开始,您将看到您的更改,并且可以通过在命令模式下按F8,在vimdiff中使用qall退出差异视图。用你喜欢的任何键替换F8。

编辑:添加了-M以禁止任何修改,因为它不是保存。

答案 9 :(得分:1)

根据不同的答案,有一个插件:https://github.com/gangleri/vim-diffsaved

它提供了:w !diff % -方法和更为复杂的diffthis方法。

除了undotree允许这样做,还有更多(不同的撤销检查点之间的差异)。与Gundo类似。

答案 10 :(得分:0)

git支持以下命令

:w !git diff --no-index -- % -

通过将以下内容添加到您的〜/ .vimrc

中,将其映射到命令

command GitDiff execute "w !git diff --no-index -- % -"

现在执行:GitDiff成为一个方便的小命令,可以在每次保存之前快速显示差异。

答案 11 :(得分:0)

您可以使用以下命令使vim创建最后一个备份和原始备份:

:set backup
:set patchmode=.orig 

此后,您可以拆分它们:

:vsp %:p~ or :vsp %:.orig

然后从那里开始:

:vimdiff in each buffer

如果您死于没有剩菜,但是想要vimdiff,您也可以这样做:

ggVGy    # copy the whole buffer
:vnew    # open a split
CTRL-W w # switch to it
shift-P  # paste at start

然后在每个拆分上进行:diffthis

答案 12 :(得分:0)

您刚刚编辑的更改[缓冲区],即与上次保存的版本(在工作目录扇区中)不同的更改,这些更改可能与上一个索引版本( > Git )。我都映射了:

" Find diff inbetween currrent buffer and ... A{last index version} vs B{last saved version in working directory}
"  - A{last index version}: the file as you last commited it
    " git diff to vimdiff against the index version of the file:
    nnoremap <leader>gd <Esc>:Gvdiff<CR><Esc>:echo "currentBuffer vs lastIndexVersion (last commited)"<CR>
"  - B{last saved version in working directory}: the file you last :w,
"   not neccesary commited it (not commited for sure if it is in NO git project)
    " https://vim.fandom.com/wiki/Diff_current_buffer_and_the_original_file
    nnoremap <leader>gd2 <Esc>:DiffSaved<CR><Esc>:echo "currentBuffer vs lastSaved (not neccesary equal to last commited)"<CR>
    function! s:DiffWithSaved()
        let filetype=&ft
        diffthis
        vnew | r # | normal! 1Gdd
        diffthis
        exe "setlocal bt=nofile bh=wipe nobl noswf ro ft=" . filetype
    endfunction
    com! DiffSaved call s:DiffWithSaved()

vimdiff与Gdiff的示例。

  • vimdiff: :vimdiff
  • Gdiff: Gdiff 提交更改,您仅会看到Gdiff,以及与vimdiff可能相同或相同的更改: commiting changes, you see only Gdiff, what might, or might NOT have same changes as vimdiff

此外,在其他路径中简化vimdiff同音异义文件:

    " vimdiff homonym file 
   nnoremap <leader>dh  <Esc>:vsplit %:p:h/../__/%:t <bar> :windo diffthis<Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left>
        "E.g."$ vim /path01/proj02_pg064/processorder.php
        ":vsplit %:p:h/../proj01_pg05/%:t | :windo diffthis

答案 13 :(得分:-1)

按照上面的建议,我使用我非常喜欢的git diff:

:w !git diff  % -