在 Vim 中保存文件之前可以看到更改吗?

我用 Vim。 我打开一个文件。我编辑它,我想看看我已经编辑之前,我保存它。

在 Vim 我怎么能这么做?

48321 次浏览
:w !diff % -

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()

要从 diff 视图中退出,可以使用 :diffoff命令。

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

来源和使用: 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()

我一直喜欢 变化-漂亮,简单,有效。

来自 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

虽然不是你想要的,但是 SCMDiff.vim确实很酷。只需按一下键盘,它就可以用源代码控制回购中的头部修订来突出显示当前文件。它意味着与许多 SCMS 工作。我使用它的力量。

我可以推荐 Hiswin插件。

虽然它没有差异到 保存电流版本的文件(像其他答案) ,它可以 自从你开始编辑 Vimdiff 就变了,甚至 重播您的变化顺序。区别在于是否中间保存。

此外,它还显示一个 全部撤销历史的分支列表,并允许您在它们之间切换或区分。

PS: 虽然这个插件不会自动跟踪每个文件更改后的编辑历史记录,但是你可以显式地“标记”保存文件的时刻,这样以后你就可以使用它来进行 vimdiff,如果你想这样做的话。也许这是自动的?

因为有些人问我对这个命令的解释

:w !diff % -

以下是我试图写出的更详细的答案:

我假设您正在使用一个安装了 catecho的系统(例如,几乎所有的 GNU/Linux、 Mac OS、 BSD 和其他类 UNIX 系统)。

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

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

    :w <filename>
    
  2. The syntax for executing a shell command in vim is:

    :!<command>
    
  3. Inside the shell environment issued by vim % happens to point to the current filename. You can verify this by executing the following:

    :!echo %
    

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

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

    :!cat %
    

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

  4. 程序 diff 能够从标准输入(stdin)读取。它的手册页声明如下:

    如果文件是“-”,则读取标准输入

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

    :w !cat
    

    这应该总是打印文件的当前内容(这将被写入一个文件,而不是)。

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

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

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

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

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

编辑你的.vimrc 并添加:

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

从那时起,您将看到您的变化,并可以退出差异视图使用 qall一样,在 vimdiff 中按 F8在命令模式。用您喜欢的任何键替换 F8。

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

这里有一个基于不同答案的插件: https://github.com/gangleri/vim-diffsaved

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

除此之外,Undotree也允许这样做,但是还有更多(不同撤销检查点之间的区别)。

遵循以上建议,我使用我非常喜欢的 git diff:

:w !git diff  % -

Git 支持以下命令

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

通过将以下内容添加到 ~/. vimrc,将其映射到命令

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

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

你可以让 vim 创建最后一个备份和原始备份:

:set backup
:set patchmode=.orig

然后,你可以把它们分开:

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

从那里开始:

:vimdiff in each buffer

如果你已经决定不吃剩菜,但是想要维姆迪夫,你也可以这样做:

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

然后这样做: 在每个分裂上区分这个

您刚刚编辑的更改[ 缓冲器] ,即那些与上一个保存版本(在 工作目录ectory 中)不同的更改,这些更改可能与上一个索引版本(饭桶)不同。我把两者都画下来了:

" 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
  • 格迪夫: 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

AFAIK,这就是“更改”命令的用途:

:changes

翻译: help change