Can I see changes before I save my file in Vim?

前端 未结 14 1754
刺人心
刺人心 2020-12-07 07:33

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?

相关标签:
14条回答
  • 2020-12-07 07:47

    Changes you just edited [buffer], i.e. those that differ from last saved version (in working directory), these may differ with last index version (Git). I mapped both:

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

    Example of vimdiff vs Gdiff.

    • vimdiff:
    • Gdiff: Commiting changes, you see only Gdiff, what might, or might have same changes as vimdiff:

    Furthermore, to easy vimdiff homonym file in other path:

        " 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
    
    0 讨论(0)
  • 2020-12-07 07:48

    You can make vim create a last backup and original backup with:

    :set backup
    :set patchmode=.orig 
    

    Thereafter, you can open them in a split:

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

    And from there do:

    :vimdiff in each buffer
    

    If you're dead set on no leftovers but want vimdiff, you could also do:

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

    and then do :diffthis on each split

    0 讨论(0)
  • 2020-12-07 07:52

    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()
    
    0 讨论(0)
  • 2020-12-07 07:53

    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?

    0 讨论(0)
  • 2020-12-07 07:57

    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:

    1. The syntax for saving a file in vim is:

      :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 %
      

      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.

    4. The program diff is able to read from standard input (stdin). Its man page states the following:

      [...] If a FILE is '-', read standard input. [...]

    5. 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)

    0 讨论(0)
  • 2020-12-07 07:58

    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...

    0 讨论(0)
提交回复
热议问题