【发布时间】:2009-04-14 20:41:16
【问题描述】:
我使用 Vim。 我打开一个文件。我对其进行了编辑,我想在保存之前查看我编辑的内容。
如何在 Vim 中做到这一点?
【问题讨论】:
我使用 Vim。 我打开一个文件。我对其进行了编辑,我想在保存之前查看我编辑的内容。
如何在 Vim 中做到这一点?
【问题讨论】:
:w !diff % -
【讨论】:
diff 发起攻击。 % 指当前打开的文件路径。为什么这一切都是:w 命令的参数?另外,- 是如何分配给工作缓冲区的内容的?在 vim 中是自动的,缓冲区的内容(或者缓冲区中的特定范围)被分配给 stdin 以用于 shell 命令?
:w 的一个参数,因为我们正在将文件写入命令(在stdin)。在命令中,- 告诉它从stdin 读取。
:w !git diff % - 获得彩色版本!
:w !git diff % - 时收到错误fatal: bad flag '-' used after filename。
因为有人问了命令的解释
: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 命令会导致 vim 将文件内容写入 shell 的标准输入,而不是将其保存在物理文件中。您可以通过执行来验证这一点
:w !cat
这应该总是打印文件的当前内容(本来应该被写入文件)。
把它放在一起(或 tl;dr):文件“保存”到标准输入,diff 以文件名和标准输入作为输入运行。
知道这一点也可以用 vimdiff 做类似的事情来比较文件 - 这只是你不想这样做的一个想法:
:w !cat > /tmp/tempFile && vimdiff /tmp/tempFile % && rm /tmp/tempFile
(然后使用:qall打开只读并关闭vimdiff)
【讨论】:
vim - -c ":vnew $1 |windo diffthis" 的 shell 脚本,使其可执行,将其保存在 PATH 中,例如 vimdiffWithStdin,然后与以下命令进行比较在 vim 中::w !vimdiffWithStdin %
:w !vimdiff % /dev/stdin。我不知道windows是否存在类似的技巧。
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'命令...
【讨论】:
:w !diff % - 不是更好吗? (只要他们安装了 diff。)
我一直很喜欢diffchanges - 不错,简单,有效。
【讨论】:
:DiffChangesDiffToggle。
来自 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
【讨论】:
w !diff % - 相比,它的优势在于它也适用于远程源(例如:vim sftp://example.com/foo.txt)
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 真的很酷。一个按键,它会在源代码管理存储库中使用 head 修订版本突出显示您当前的文件。它适用于许多 SCMS。我将它与 perforce 一起使用。
【讨论】:
这里有一个插件,根据不同的答案:https://github.com/gangleri/vim-diffsaved
它提供了:w !diff % -方法和更多涉及的diffthis方法。
【讨论】:
我可以推荐histwin 插件。
虽然它与文件的 当前保存 版本没有差异(就像其他答案一样),但它可以 vimdiff 自从您开始编辑后发生的变化,甚至 按顺序重播您的更改。如果您中间保存,差异就会显示出来。
此外,它还显示所有撤消历史分支的列表,并允许您在它们之间切换或区分。
PS:虽然插件不会在每次文件更改后自动跟踪编辑历史记录中的时刻,但您可以明确地“标记”保存文件的时刻,以便以后可以根据需要使用它进行 vimdiff。也许这可以自动化?
【讨论】:
如果你想像 vimdiff 一样使用 vim 进行比较,你可以这样做:
编辑你的 .vimrc 并添加:
nmap <F8> :w !vim -M -R - -c ":vnew % \| windo diffthis"<CR><CR>
从那里您将看到您的更改,并可以使用qall 退出差异视图,就像在 vimdiff 中一样,在命令模式下按 F8。用你喜欢的任何键替换 F8。
编辑:添加 -M 以禁止任何修改,因为它不保存。
【讨论】:
Vim: Error reading input, exiting... 任何想法这里出了什么问题?
您可以使用以下命令使 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
【讨论】:
您刚刚编辑的更改 [buffer],即与上次保存的版本(在 工作目录ectory 中)不同的更改,这些可能与上次索引版本不同(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
【讨论】:
Gdiff,否则(例如不是一个Git项目)然后执行一个:vimdiff。与try-catch-endtry。但是这种方式:DiffWithSaved在一个Git项目中是缺少的。
按照上述建议我使用我非常喜欢的 git diff:
:w !git diff % -
【讨论】: