| *diff.txt* For Vim version 7.3. Last change: 2011 Apr 14 |
| |
| |
| VIM REFERENCE MANUAL by Bram Moolenaar |
| |
| |
| *diff* *vimdiff* *gvimdiff* *diff-mode* |
| This file describes the |+diff| feature: Showing differences between two, |
| three or four versions of the same file. |
| |
| The basics are explained in section |08.7| of the user manual. |
| |
| 1. Starting diff mode |vimdiff| |
| 2. Viewing diffs |view-diffs| |
| 3. Jumping to diffs |jumpto-diffs| |
| 4. Copying diffs |copy-diffs| |
| 5. Diff options |diff-options| |
| |
| {not in Vi} |
| |
| ============================================================================== |
| 1. Starting diff mode |
| |
| The easiest way to start editing in diff mode is with the "vimdiff" command. |
| This starts Vim as usual, and additionally sets up for viewing the differences |
| between the arguments. > |
| |
| vimdiff file1 file2 [file3 [file4]] |
| |
| This is equivalent to: > |
| |
| vim -d file1 file2 [file3 [file4]] |
| |
| You may also use "gvimdiff" or "vim -d -g". The GUI is started then. |
| You may also use "viewdiff" or "gviewdiff". Vim starts in readonly mode then. |
| "r" may be prepended for restricted mode (see |-Z|). |
| |
| The second and following arguments may also be a directory name. Vim will |
| then append the file name of the first argument to the directory name to find |
| the file. |
| |
| This only works when a standard "diff" command is available. See 'diffexpr'. |
| |
| Diffs are local to the current tab page |tab-page|. You can't see diffs with |
| a window in another tab page. This does make it possible to have several |
| diffs at the same time, each in their own tab page. |
| |
| What happens is that Vim opens a window for each of the files. This is like |
| using the |-O| argument. This uses vertical splits. If you prefer horizontal |
| splits add the |-o| argument: > |
| |
| vimdiff -o file1 file2 [file3 [file4]] |
| |
| If you always prefer horizontal splits include "horizontal" in 'diffopt'. |
| |
| In each of the edited files these options are set: |
| |
| 'diff' on |
| 'scrollbind' on |
| 'cursorbind' on |
| 'scrollopt' includes "hor" |
| 'wrap' off |
| 'foldmethod' "diff" |
| 'foldcolumn' value from 'diffopt', default is 2 |
| |
| These options are set local to the window. When editing another file they are |
| reset to the global value. |
| The options can still be overruled from a modeline when re-editing the file. |
| However, 'foldmethod' and 'wrap' won't be set from a modeline when 'diff' is |
| set. |
| |
| The differences shown are actually the differences in the buffer. Thus if you |
| make changes after loading a file, these will be included in the displayed |
| diffs. You might have to do ":diffupdate" now and then, not all changes are |
| immediately taken into account. |
| |
| In your .vimrc file you could do something special when Vim was started in |
| diff mode. You could use a construct like this: > |
| |
| if &diff |
| setup for diff mode |
| else |
| setup for non-diff mode |
| endif |
| |
| While already in Vim you can start diff mode in three ways. |
| |
| *E98* |
| :diffsplit {filename} *:diffs* *:diffsplit* |
| Open a new window on the file {filename}. The options are set |
| as for "vimdiff" for the current and the newly opened window. |
| Also see 'diffexpr'. |
| |
| *:difft* *:diffthis* |
| :diffthis Make the current window part of the diff windows. This sets |
| the options like for "vimdiff". |
| |
| :diffpatch {patchfile} *E816* *:diffp* *:diffpatch* |
| Use the current buffer, patch it with the diff found in |
| {patchfile} and open a buffer on the result. The options are |
| set as for "vimdiff". |
| {patchfile} can be in any format that the "patch" program |
| understands or 'patchexpr' can handle. |
| Note that {patchfile} should only contain a diff for one file, |
| the current file. If {patchfile} contains diffs for other |
| files as well, the results are unpredictable. Vim changes |
| directory to /tmp to avoid files in the current directory |
| accidentally being patched. But it may still result in |
| various ".rej" files to be created. And when absolute path |
| names are present these files may get patched anyway. |
| |
| To make these commands use a vertical split, prepend |:vertical|. Examples: > |
| |
| :vert diffsplit main.c~ |
| :vert diffpatch /tmp/diff |
| |
| If you always prefer a vertical split include "vertical" in 'diffopt'. |
| |
| *E96* |
| There can be up to four buffers with 'diff' set. |
| |
| Since the option values are remembered with the buffer, you can edit another |
| file for a moment and come back to the same file and be in diff mode again. |
| |
| *:diffo* *:diffoff* |
| :diffoff Switch off diff mode for the current window. |
| |
| :diffoff! Switch off diff mode for the current window and in all windows |
| in the current tab page where 'diff' is set. |
| |
| The ":diffoff" command resets the relevant options to their default value. |
| This may be different from what the values were before diff mode was started, |
| the old values are not remembered. |
| |
| 'diff' off |
| 'scrollbind' off |
| 'cursorbind' off |
| 'scrollopt' without "hor" |
| 'wrap' on |
| 'foldmethod' "manual" |
| 'foldcolumn' 0 |
| |
| ============================================================================== |
| 2. Viewing diffs *view-diffs* |
| |
| The effect is that the diff windows show the same text, with the differences |
| highlighted. When scrolling the text, the 'scrollbind' option will make the |
| text in other windows to be scrolled as well. With vertical splits the text |
| should be aligned properly. |
| |
| The alignment of text will go wrong when: |
| - 'wrap' is on, some lines will be wrapped and occupy two or more screen |
| lines |
| - folds are open in one window but not another |
| - 'scrollbind' is off |
| - changes have been made to the text |
| - "filler" is not present in 'diffopt', deleted/inserted lines makes the |
| alignment go wrong |
| |
| All the buffers edited in a window where the 'diff' option is set will join in |
| the diff. This is also possible for hidden buffers. They must have been |
| edited in a window first for this to be possible. |
| |
| *:DiffOrig* *diff-original-file* |
| Since 'diff' is a window-local option, it's possible to view the same buffer |
| in diff mode in one window and "normal" in another window. It is also |
| possible to view the changes you have made to a buffer since the file was |
| loaded. Since Vim doesn't allow having two buffers for the same file, you |
| need another buffer. This command is useful: > |
| command DiffOrig vert new | set bt=nofile | r ++edit # | 0d_ |
| \ | diffthis | wincmd p | diffthis |
| (this is in |vimrc_example.vim|). Use ":DiffOrig" to see the differences |
| between the current buffer and the file it was loaded from. |
| |
| A buffer that is unloaded cannot be used for the diff. But it does work for |
| hidden buffers. You can use ":hide" to close a window without unloading the |
| buffer. If you don't want a buffer to remain used for the diff do ":set |
| nodiff" before hiding it. |
| |
| *:diffu* *:diffupdate* |
| :diffu[pdate] Update the diff highlighting and folds. |
| |
| Vim attempts to keep the differences updated when you make changes to the |
| text. This mostly takes care of inserted and deleted lines. Changes within a |
| line and more complicated changes do not cause the differences to be updated. |
| To force the differences to be updated use: > |
| |
| :diffupdate |
| |
| |
| Vim will show filler lines for lines that are missing in one window but are |
| present in another. These lines were inserted in another file or deleted in |
| this file. Removing "filler" from the 'diffopt' option will make Vim not |
| display these filler lines. |
| |
| |
| Folds are used to hide the text that wasn't changed. See |folding| for all |
| the commands that can be used with folds. |
| |
| The context of lines above a difference that are not included in the fold can |
| be set with the 'diffopt' option. For example, to set the context to three |
| lines: > |
| |
| :set diffopt=filler,context:3 |
| |
| |
| The diffs are highlighted with these groups: |
| |
| |hl-DiffAdd| DiffAdd Added (inserted) lines. These lines exist in |
| this buffer but not in another. |
| |hl-DiffChange| DiffChange Changed lines. |
| |hl-DiffText| DiffText Changed text inside a Changed line. Vim |
| finds the first character that is different, |
| and the last character that is different |
| (searching from the end of the line). The |
| text in between is highlighted. This means |
| that parts in the middle that are still the |
| same are highlighted anyway. Only "iwhite" of |
| 'diffopt' is used here. |
| |hl-DiffDelete| DiffDelete Deleted lines. Also called filler lines, |
| because they don't really exist in this |
| buffer. |
| |
| ============================================================================== |
| 3. Jumping to diffs *jumpto-diffs* |
| |
| Two commands can be used to jump to diffs: |
| *[c* |
| [c Jump backwards to the previous start of a change. |
| When a count is used, do it that many times. |
| *]c* |
| ]c Jump forwards to the next start of a change. |
| When a count is used, do it that many times. |
| |
| It is an error if there is no change for the cursor to move to. |
| |
| ============================================================================== |
| 4. Diff copying *copy-diffs* *E99* *E100* *E101* *E102* *E103* |
| *merge* |
| There are two commands to copy text from one buffer to another. The result is |
| that the buffers will be equal within the specified range. |
| |
| *:diffg* *:diffget* |
| :[range]diffg[et] [bufspec] |
| Modify the current buffer to undo difference with another |
| buffer. If [bufspec] is given, that buffer is used. If |
| [bufspec] refers to the current buffer then nothing happens. |
| Otherwise this only works if there is one other buffer in diff |
| mode. |
| See below for [range]. |
| |
| *:diffpu* *:diffput* *E793* |
| :[range]diffpu[t] [bufspec] |
| Modify another buffer to undo difference with the current |
| buffer. Just like ":diffget" but the other buffer is modified |
| instead of the current one. |
| When [bufspec] is omitted and there is more than one other |
| buffer in diff mode where 'modifiable' is set this fails. |
| See below for [range]. |
| |
| *do* |
| do Same as ":diffget" without argument or range. The "o" stands |
| for "obtain" ("dg" can't be used, it could be the start of |
| "dgg"!). Note: this doesn't work in Visual mode. |
| |
| *dp* |
| dp Same as ":diffput" without argument or range. |
| Note: this doesn't work in Visual mode. |
| |
| |
| When no [range] is given, the diff at the cursor position or just above it is |
| affected. When [range] is used, Vim tries to only put or get the specified |
| lines. When there are deleted lines, this may not always be possible. |
| |
| There can be deleted lines below the last line of the buffer. When the cursor |
| is on the last line in the buffer and there is no diff above this line, the |
| ":diffget" and "do" commands will obtain lines from the other buffer. |
| |
| To be able to get those lines from another buffer in a [range] it's allowed to |
| use the last line number plus one. This command gets all diffs from the other |
| buffer: > |
| |
| :1,$+1diffget |
| |
| Note that deleted lines are displayed, but not counted as text lines. You |
| can't move the cursor into them. To fill the deleted lines with the lines |
| from another buffer use ":diffget" on the line below them. |
| *E787* |
| When the buffer that is about to be modified is read-only and the autocommand |
| that is triggered by |FileChangedRO| changes buffers the command will fail. |
| The autocommand must not change buffers. |
| |
| The [bufspec] argument above can be a buffer number, a pattern for a buffer |
| name or a part of a buffer name. Examples: |
| |
| :diffget Use the other buffer which is in diff mode |
| :diffget 3 Use buffer 3 |
| :diffget v2 Use the buffer which matches "v2" and is in |
| diff mode (e.g., "file.c.v2") |
| |
| ============================================================================== |
| 5. Diff options *diff-options* |
| |
| Also see |'diffopt'| and the "diff" item of |'fillchars'|. |
| |
| |
| FINDING THE DIFFERENCES *diff-diffexpr* |
| |
| The 'diffexpr' option can be set to use something else than the standard |
| "diff" program to compare two files and find the differences. |
| |
| When 'diffexpr' is empty, Vim uses this command to find the differences |
| between file1 and file2: > |
| |
| diff file1 file2 > outfile |
| |
| The ">" is replaced with the value of 'shellredir'. |
| |
| The output of "diff" must be a normal "ed" style diff. Do NOT use a context |
| diff. This example explains the format that Vim expects: > |
| |
| 1a2 |
| > bbb |
| 4d4 |
| < 111 |
| 7c7 |
| < GGG |
| --- |
| > ggg |
| |
| The "1a2" item appends the line "bbb". |
| The "4d4" item deletes the line "111". |
| The '7c7" item replaces the line "GGG" with "ggg". |
| |
| When 'diffexpr' is not empty, Vim evaluates it to obtain a diff file in the |
| format mentioned. These variables are set to the file names used: |
| |
| v:fname_in original file |
| v:fname_new new version of the same file |
| v:fname_out resulting diff file |
| |
| Additionally, 'diffexpr' should take care of "icase" and "iwhite" in the |
| 'diffopt' option. 'diffexpr' cannot change the value of 'lines' and |
| 'columns'. |
| |
| Example (this does almost the same as 'diffexpr' being empty): > |
| |
| set diffexpr=MyDiff() |
| function MyDiff() |
| let opt = "" |
| if &diffopt =~ "icase" |
| let opt = opt . "-i " |
| endif |
| if &diffopt =~ "iwhite" |
| let opt = opt . "-b " |
| endif |
| silent execute "!diff -a --binary " . opt . v:fname_in . " " . v:fname_new . |
| \ " > " . v:fname_out |
| endfunction |
| |
| The "-a" argument is used to force comparing the files as text, comparing as |
| binaries isn't useful. The "--binary" argument makes the files read in binary |
| mode, so that a CTRL-Z doesn't end the text on DOS. |
| |
| *E810* *E97* |
| Vim will do a test if the diff output looks alright. If it doesn't, you will |
| get an error message. Possible causes: |
| - The "diff" program cannot be executed. |
| - The "diff" program doesn't produce normal "ed" style diffs (see above). |
| - The 'shell' and associated options are not set correctly. Try if filtering |
| works with a command like ":!sort". |
| - You are using 'diffexpr' and it doesn't work. |
| If it's not clear what the problem is set the 'verbose' option to one or more |
| to see more messages. |
| |
| The self-installing Vim for MS-Windows includes a diff program. If you don't |
| have it you might want to download a diff.exe. For example from |
| http://gnuwin32.sourceforge.net/packages/diffutils.htm. |
| |
| |
| USING PATCHES *diff-patchexpr* |
| |
| The 'patchexpr' option can be set to use something else than the standard |
| "patch" program. |
| |
| When 'patchexpr' is empty, Vim will call the "patch" program like this: > |
| |
| patch -o outfile origfile < patchfile |
| |
| This should work fine with most versions of the "patch" program. Note that a |
| CR in the middle of a line may cause problems, it is seen as a line break. |
| |
| If the default doesn't work for you, set the 'patchexpr' to an expression that |
| will have the same effect. These variables are set to the file names used: |
| |
| v:fname_in original file |
| v:fname_diff patch file |
| v:fname_out resulting patched file |
| |
| Example (this does the same as 'patchexpr' being empty): > |
| |
| set patchexpr=MyPatch() |
| function MyPatch() |
| :call system("patch -o " . v:fname_out . " " . v:fname_in . |
| \ " < " . v:fname_diff) |
| endfunction |
| |
| Make sure that using the "patch" program doesn't have unwanted side effects. |
| For example, watch out for additionally generated files, which should be |
| deleted. It should just patch the file and nothing else. |
| Vim will change directory to "/tmp" or another temp directory before |
| evaluating 'patchexpr'. This hopefully avoids that files in the current |
| directory are accidentally patched. Vim will also delete files starting with |
| v:fname_in and ending in ".rej" and ".orig". |
| |
| vim:tw=78:ts=8:ft=help:norl: |