我使用 Vim。我打开一个文件。我编辑它,我想在保存之前查看我编辑的内容。
我怎样才能在 Vim 中做到这一点?
:w !diff % -
因为有人问关于命令的解释
:w !diff % -
这是我尝试写一个更详细的答案:
我假设您正在使用cat
并echo
安装了一个系统(例如几乎所有 GNU/Linux、Mac OS、BSD 和其他类 UNIX 系统)。
上述命令的工作原理如下:
在 vim 中保存文件的语法是:
:w <filename>
在 vim 中执行 shell 命令的语法是:
:!<command>
vim发出的shell环境里面%
恰好指向当前文件名。您可以通过执行以下操作来验证这一点:
:!echo %
这应该输出文件名(或错误,如果 vim 运行时没有文件名)。
使用 cat 我们还可以输出文件的内容:
:!cat %
这应该返回上次保存状态的文件内容,如果从未保存过,则返回错误。
程序 diff 能够从标准输入(stdin)读取。它的手册页说明了以下内容:
[...] 如果 FILE 是“-”,则读取标准输入。[...]
执行不带文件名而是在其后面的 shell 命令的 save 命令会导致 vim 将文件内容写入 shell 的标准输入,而不是将其保存在物理文件中。您可以通过执行来验证这一点
:w !cat
这应该总是打印文件的当前内容(这将被写入文件)。
把它放在一起(或tl;dr):文件被“保存”到stdin,diff以文件名和stdin作为输入运行。
知道这一点也可以将文件与 vimdiff 做这样的事情进行比较——这只是一个你不想这样做的想法:
:w !cat > /tmp/tempFile && vimdiff /tmp/tempFile % && rm /tmp/tempFile
(然后打开 readonly 并使用关闭 vimdiff :qall
)
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'
命令...
我一直很喜欢diffchanges - 很好,很简单,很有效。
来自 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
git 支持以下命令
:w !git diff --no-index -- % -
通过将以下内容添加到 ~/.vimrc 将其映射到命令
command GitDiff execute "w !git diff --no-index -- % -"
现在执行:GitDiff
变成了一个方便的小命令,可以在每次保存之前快速显示差异。
获取以下内容并使用 :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()
不完全是你要找的,但SCMDiff.vim真的很酷。一个按键,它会在源代码控制 repo 中突出显示您当前的文件与头部修订。它适用于许多 SCMS。我将它与 perforce 一起使用。
有一个插件,基于不同的答案在这里:https ://github.com/gangleri/vim-diffsaved
它提供了:w !diff % -
方法和更多涉及的方法diffthis
。
除了那个undotree 还允许这样做,但还有更多(不同撤消检查点之间的差异)。类似于Gundo。
我可以推荐histwin插件。
虽然它与文件的当前保存版本没有差异(就像其他答案一样),但它可以vimdiff 更改,因为您开始 edting,甚至可以按顺序重播您的更改。如果您中间保存,差异就会显示出来。
此外,它显示所有撤消历史分支的列表,并允许您在它们之间切换或区分。
PS:虽然插件不会在每次文件更改后自动跟踪编辑历史记录中的时刻,但您可以明确地“标记”保存文件的时刻,以便以后可以根据需要使用它进行 vimdiff。也许这可以自动化?
如果你想像 vimdiff 那样使用 vim 进行比较,你可以这样做:
编辑您的 .vimrc 并添加:
nmap <F8> :w !vim -M -R - -c ":vnew % \| windo diffthis"<CR><CR>
从那里您将看到您的更改,并且可以qall
通过在命令模式下按 F8 在 vimdiff 中使用 like 退出差异视图。用您喜欢的任何键替换 F8。
编辑:添加 -M 以禁止任何修改,因为它不保存。
您可以使用以下命令使 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
您刚刚编辑的更改 [缓冲区],即与上次保存的版本(在工作目录中)不同的更改,这些可能与上次索引版本(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 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
按照上面的建议,我使用我非常喜欢的 git diff:
:w !git diff % -