问题
I use Vim. I open a file. I edit it and I want to see what I've edited before I save it.
How can I do this in Vim?
回答1:
http://vim.wikia.com/wiki/Diff_current_buffer_and_the_original_file
Here is a function and command to see a diff between the currently edited file and its unmodified version in the filesystem. Just put this in your vimrc or in the plugin directory, open a file, make some modifications without saving them, and do
: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()
To get out of diff view you can use the
:diffoff
command.Below is a similar function, adapted to mimic the
'cvs diff'
command...
回答2:
:w !diff % -
回答3:
Because some people asked about an explanation for the command
:w !diff % -
Here is my attempt on writing a more detailed answer:
I am assuming that you are working on a system with cat
and echo
installed (e.g. almost any GNU/Linux, Mac OS, BSD and other UNIX-like systems).
The above command works as follows:
The syntax for saving a file in vim is:
:w <filename>
The syntax for executing a shell command in vim is:
:!<command>
Inside the shell environment issued by vim
%
happens to point to the current filename. You can verify this by executing the following::!echo %
This should output the filename (or an error, if vim was run without a filename).
Using cat we can also output the content of the file:
:!cat %
This should return the files content in its last saved state or an error if it has never been saved.
The program diff is able to read from standard input (stdin). Its man page states the following:
[...] If a FILE is '-', read standard input. [...]
Executing the save command without a filename but rather a shell command behind it causes vim to write the files content to stdin of the shell instead of saving it in a physical file. You can verify this by executing
:w !cat
This should always print the files current content (which would have been written to a file instead).
Putting it together (or tl;dr): The file is "saved" to stdin, diff is run with the filename and stdin as input.
Knowing this one could also compare files with vimdiff doing something like this - this is just an idea you do not want to do this:
:w !cat > /tmp/tempFile && vimdiff /tmp/tempFile % && rm /tmp/tempFile
(Then open readonly and close vimdiff using :qall
)
回答4:
I've always likes diffchanges - nice, simple, works.
回答5:
from 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
回答6:
Source the following and use :DIFF command
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()
回答7:
Not exactly what you're looking for but SCMDiff.vim is really cool. One keypress, and it diff-highlights your current file with the head revision in a source control repo. It's meant to work with many SCMS. I use it with perforce.
回答8:
There is a plugin, based on different answers here: https://github.com/gangleri/vim-diffsaved
It provides the :w !diff % -
method and the more involved diffthis
one.
Apart from that undotree allows this as well, but also much more (diffs between different undo checkpoints). Similar to Gundo.
回答9:
I can recommend the histwin plugin.
While it doesn't diff to the current saved version of the file (like the other answers), it can vimdiff changes since you started edting, and even replay your changes in order. The difference shows if you save intermediately.
Additionally, it displays a list of all undo history branches and allows you to switch or diff between them.
PS: While the plugin doesn't automatically track moments in the edit history since every file change, you can explicitly "tag" the moment when you save the file such that you can later vimdiff with it, if you want that. Maybe this could be automated?
回答10:
If you want to use vim for comparison like in vimdiff, you could do something like this:
Edit your .vimrc and add:
nmap <F8> :w !vim -M -R - -c ":vnew % \| windo diffthis"<CR><CR>
From there on you will see your changes and can quit the diff view using qall
like in vimdiff by pressing F8 in command mode. Replace F8 with any key you like.
Edit: Added -M to disallow any modification, because it is not save.
回答11:
git supports the following command
:w !git diff --no-index -- % -
map it to a command by adding the following to your ~/.vimrc
command GitDiff execute "w !git diff --no-index -- % -"
Now executing :GitDiff
becomes a handy little command to quickly show the diff before each save.
回答12:
Follow the above suggests I use git diff that I like much:
:w !git diff % -
来源:https://stackoverflow.com/questions/749297/can-i-see-changes-before-i-save-my-file-in-vim