Bram Moolenaar | c236c16 | 2008-07-13 17:41:49 +0000 | [diff] [blame] | 1 | *diff.txt* For Vim version 7.2b. Last change: 2006 Oct 02 |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 2 | |
| 3 | |
| 4 | VIM REFERENCE MANUAL by Bram Moolenaar |
| 5 | |
| 6 | |
| 7 | *diff* *vimdiff* *gvimdiff* *diff-mode* |
| 8 | This file describes the +diff feature: Showing differences between two or |
| 9 | three versions of the same file. |
| 10 | |
| 11 | The basics are explained in section |08.7| of the user manual. |
| 12 | |
| 13 | 1. Starting diff mode |vimdiff| |
| 14 | 2. Viewing diffs |view-diffs| |
| 15 | 3. Jumping to diffs |jumpto-diffs| |
| 16 | 4. Copying diffs |copy-diffs| |
| 17 | 5. Diff options |diff-options| |
| 18 | |
| 19 | {not in Vi} |
| 20 | |
| 21 | ============================================================================== |
| 22 | 1. Starting diff mode |
| 23 | |
| 24 | The easiest way to start editing in diff mode is with the "vimdiff" command. |
| 25 | This starts Vim as usual, and additionally sets up for viewing the differences |
| 26 | between the arguments. > |
| 27 | |
| 28 | vimdiff file1 file2 [file3 [file4]] |
| 29 | |
| 30 | This is equivalent to: > |
| 31 | |
| 32 | vim -d file1 file2 [file3 [file4]] |
| 33 | |
| 34 | You may also use "gvimdiff" or "vim -d -g". The GUI is started then. |
| 35 | You may also use "viewdiff" or "gviewdiff". Vim starts in readonly mode then. |
| 36 | "r" may be prepended for restricted mode (see |-Z|). |
| 37 | |
| 38 | The second and following arguments may also be a directory name. Vim will |
| 39 | then append the file name of the first argument to the directory name to find |
| 40 | the file. |
| 41 | |
| 42 | This only works when a standard "diff" command is available. See 'diffexpr'. |
| 43 | |
Bram Moolenaar | 7e8fd63 | 2006-02-18 22:14:51 +0000 | [diff] [blame] | 44 | Diffs are local to the current tab page |tab-page|. You can't see diffs with |
| 45 | a window in another tab page. This does make it possible to have several |
| 46 | diffs at the same time, each in their own tab page. |
| 47 | |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 48 | What happens is that Vim opens a window for each of the files. This is like |
| 49 | using the |-O| argument. This uses vertical splits. If you prefer horizontal |
| 50 | splits add the |-o| argument: > |
| 51 | |
| 52 | vimdiff -o file1 file2 [file3] |
| 53 | |
Bram Moolenaar | 7d47b6e | 2006-03-15 22:59:18 +0000 | [diff] [blame] | 54 | If you always prefer horizontal splits include "horizontal" in 'diffopt'. |
| 55 | |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 56 | In each of the edited files these options are set: |
| 57 | |
| 58 | 'diff' on |
| 59 | 'scrollbind' on |
| 60 | 'scrollopt' includes "hor" |
| 61 | 'wrap' off |
| 62 | 'foldmethod' "diff" |
Bram Moolenaar | 7d47b6e | 2006-03-15 22:59:18 +0000 | [diff] [blame] | 63 | 'foldcolumn' value from 'diffopt', default is 2 |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 64 | |
| 65 | These options are set local to the window. When editing another file they are |
| 66 | reset to the global value. |
| 67 | |
| 68 | The differences shown are actually the differences in the buffer. Thus if you |
| 69 | make changes after loading a file, these will be included in the displayed |
| 70 | diffs. You might have to do ":diffupdate" now and then, not all changes are |
| 71 | immediately taken into account. |
| 72 | |
| 73 | In your .vimrc file you could do something special when Vim was started in |
| 74 | diff mode. You could use a construct like this: > |
| 75 | |
| 76 | if &diff |
| 77 | setup for diff mode |
| 78 | else |
| 79 | setup for non-diff mode |
| 80 | endif |
| 81 | |
| 82 | While already in Vim you can start diff mode in three ways. |
| 83 | |
| 84 | *E98* |
| 85 | :diffsplit {filename} *:diffs* *:diffsplit* |
| 86 | Open a new window on the file {filename}. The options are set |
| 87 | as for "vimdiff" for the current and the newly opened window. |
| 88 | Also see 'diffexpr'. |
| 89 | |
| 90 | *:difft* *:diffthis* |
| 91 | :diffthis Make the current window part of the diff windows. This sets |
Bram Moolenaar | 2df6dcc | 2004-07-12 15:53:54 +0000 | [diff] [blame] | 92 | the options like for "vimdiff". |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 93 | |
| 94 | :diffpatch {patchfile} *:diffp* *:diffpatch* |
| 95 | Use the current buffer, patch it with the diff found in |
| 96 | {patchfile} and open a buffer on the result. The options are |
| 97 | set as for "vimdiff". |
| 98 | {patchfile} can be in any format that the "patch" program |
| 99 | understands or 'patchexpr' can handle. |
| 100 | Note that {patchfile} should only contain a diff for one file, |
| 101 | the current file. If {patchfile} contains diffs for other |
| 102 | files as well, the results are unpredictable. Vim changes |
| 103 | directory to /tmp to avoid files in the current directory |
| 104 | accidentally being patched. But it may still result in |
| 105 | various ".rej" files to be created. And when absolute path |
| 106 | names are present these files may get patched anyway. |
| 107 | |
| 108 | To make these commands use a vertical split, prepend |:vertical|. Examples: > |
| 109 | |
| 110 | :vert diffsplit main.c~ |
| 111 | :vert diffpatch /tmp/diff |
Bram Moolenaar | 7d47b6e | 2006-03-15 22:59:18 +0000 | [diff] [blame] | 112 | |
| 113 | If you always prefer a vertical split include "vertical" in 'diffopt'. |
| 114 | |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 115 | *E96* |
| 116 | There can be up to four buffers with 'diff' set. |
| 117 | |
| 118 | Since the option values are remembered with the buffer, you can edit another |
| 119 | file for a moment and come back to the same file and be in diff mode again. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 120 | |
Bram Moolenaar | 2df6dcc | 2004-07-12 15:53:54 +0000 | [diff] [blame] | 121 | *:diffo* *:diffoff* |
| 122 | :diffoff Switch off diff mode for the current window. |
| 123 | |
Bram Moolenaar | 7e8fd63 | 2006-02-18 22:14:51 +0000 | [diff] [blame] | 124 | :diffoff! Switch off diff mode for all windows in the current tab page. |
Bram Moolenaar | 2df6dcc | 2004-07-12 15:53:54 +0000 | [diff] [blame] | 125 | |
| 126 | The ":diffoff" command resets the relevant options to their default value. |
| 127 | This may be different from what the values were before diff mode was started, |
| 128 | the old values are not remembered. |
| 129 | |
| 130 | 'diff' off |
| 131 | 'scrollbind' off |
| 132 | 'scrollopt' without "hor" |
| 133 | 'wrap' on |
| 134 | 'foldmethod' "manual" |
| 135 | 'foldcolumn' 0 |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 136 | |
| 137 | ============================================================================== |
| 138 | 2. Viewing diffs *view-diffs* |
| 139 | |
| 140 | The effect is that the diff windows show the same text, with the differences |
| 141 | highlighted. When scrolling the text, the 'scrollbind' option will make the |
| 142 | text in other windows to be scrolled as well. With vertical splits the text |
| 143 | should be aligned properly. |
| 144 | |
| 145 | The alignment of text will go wrong when: |
| 146 | - 'wrap' is on, some lines will be wrapped and occupy two or more screen |
| 147 | lines |
| 148 | - folds are open in one window but not another |
| 149 | - 'scrollbind' is off |
| 150 | - changes have been made to the text |
| 151 | - "filler" is not present in 'diffopt', deleted/inserted lines makes the |
| 152 | alignment go wrong |
| 153 | |
| 154 | All the buffers edited in a window where the 'diff' option is set will join in |
| 155 | the diff. This is also possible for hidden buffers. They must have been |
| 156 | edited in a window first for this to be possible. |
| 157 | |
Bram Moolenaar | 9964e46 | 2007-05-05 17:54:07 +0000 | [diff] [blame] | 158 | *:DiffOrig* *diff-original-file* |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 159 | Since 'diff' is a window-local option, it's possible to view the same buffer |
| 160 | in diff mode in one window and "normal" in another window. It is also |
Bram Moolenaar | 9964e46 | 2007-05-05 17:54:07 +0000 | [diff] [blame] | 161 | possible to view the changes you have made to a buffer since the file was |
| 162 | loaded. Since Vim doesn't allow having two buffers for the same file, you |
| 163 | need another buffer. This command is useful: > |
| 164 | command DiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis |
| 165 | \ | wincmd p | diffthis |
| 166 | (this is in |vimrc_example.vim|). Use ":DiffOrig" to see the differences |
| 167 | between the current buffer and the file it was loaded from. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 168 | |
| 169 | A buffer that is unloaded cannot be used for the diff. But it does work for |
| 170 | hidden buffers. You can use ":hide" to close a window without unloading the |
Bram Moolenaar | 111ff9f | 2005-03-08 22:40:03 +0000 | [diff] [blame] | 171 | buffer. If you don't want a buffer to remain used for the diff do ":set |
| 172 | nodiff" before hiding it. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 173 | |
| 174 | *:diffu* *:diffupdate* |
Bram Moolenaar | a7fc010 | 2005-05-18 22:17:12 +0000 | [diff] [blame] | 175 | :diffu[pdate] Update the diff highlighting and folds. |
| 176 | |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 177 | Vim attempts to keep the differences updated when you make changes to the |
| 178 | text. This mostly takes care of inserted and deleted lines. Changes within a |
| 179 | line and more complicated changes do not cause the differences to be updated. |
| 180 | To force the differences to be updated use: > |
| 181 | |
| 182 | :diffupdate |
| 183 | |
| 184 | |
| 185 | Vim will show filler lines for lines that are missing in one window but are |
| 186 | present in another. These lines were inserted in another file or deleted in |
| 187 | this file. Removing "filler" from the 'diffopt' option will make Vim not |
| 188 | display these filler lines. |
| 189 | |
| 190 | |
| 191 | Folds are used to hide the text that wasn't changed. See |folding| for all |
| 192 | the commands that can be used with folds. |
| 193 | |
| 194 | The context of lines above a difference that are not included in the fold can |
| 195 | be set with the 'diffopt' option. For example, to set the context to three |
| 196 | lines: > |
| 197 | |
| 198 | :set diffopt=filler,context:3 |
| 199 | |
| 200 | |
| 201 | The diffs are highlighted with these groups: |
| 202 | |
| 203 | |hl-DiffAdd| DiffAdd Added (inserted) lines. These lines exist in |
| 204 | this buffer but not in another. |
| 205 | |hl-DiffChange| DiffChange Changed lines. |
| 206 | |hl-DiffText| DiffText Changed text inside a Changed line. Vim |
| 207 | finds the first character that is different, |
| 208 | and the last character that is different |
| 209 | (searching from the end of the line). The |
| 210 | text in between is highlighted. This means |
| 211 | that parts in the middle that are still the |
Bram Moolenaar | 9e54a0e | 2006-04-14 20:42:25 +0000 | [diff] [blame] | 212 | same are highlighted anyway. Only "iwhite" of |
| 213 | 'diffopt' is used here. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 214 | |hl-DiffDelete| DiffDelete Deleted lines. Also called filler lines, |
| 215 | because they don't really exist in this |
| 216 | buffer. |
| 217 | |
| 218 | ============================================================================== |
| 219 | 3. Jumping to diffs *jumpto-diffs* |
| 220 | |
| 221 | Two commands can be used to jump to diffs: |
| 222 | *[c* |
| 223 | [c Jump backwards to the previous start of a change. |
| 224 | When a count is used, do it that many times. |
| 225 | *]c* |
| 226 | ]c Jump forwards to the next start of a change. |
| 227 | When a count is used, do it that many times. |
| 228 | |
| 229 | It is an error if there is no change for the cursor to move to. |
| 230 | |
| 231 | ============================================================================== |
| 232 | 4. Diff copying *copy-diffs* *E99* *E100* *E101* *E102* *E103* |
Bram Moolenaar | 1e01546 | 2005-09-25 22:16:38 +0000 | [diff] [blame] | 233 | *merge* |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 234 | There are two commands to copy text from one buffer to another. The result is |
| 235 | that the buffers will be equal within the specified range. |
| 236 | |
| 237 | *:diffg* *:diffget* |
| 238 | :[range]diffg[et] [bufspec] |
| 239 | Modify the current buffer to undo difference with another |
| 240 | buffer. If [bufspec] is given, that buffer is used. |
| 241 | Otherwise this only works if there is one other buffer in diff |
| 242 | mode. |
| 243 | See below for [range]. |
| 244 | |
Bram Moolenaar | 9964e46 | 2007-05-05 17:54:07 +0000 | [diff] [blame] | 245 | *:diffpu* *:diffput* *E793* |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 246 | :[range]diffpu[t] [bufspec] |
| 247 | Modify another buffer to undo difference with the current |
| 248 | buffer. Just like ":diffget" but the other buffer is modified |
| 249 | instead of the current one. |
Bram Moolenaar | 1e01546 | 2005-09-25 22:16:38 +0000 | [diff] [blame] | 250 | When [bufspec] is omitted and there is more than one other |
| 251 | buffer in diff mode where 'modifiable' is set this fails. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 252 | See below for [range]. |
| 253 | |
| 254 | *do* |
| 255 | do Same as ":diffget" without argument or range. The "o" stands |
| 256 | for "obtain" ("dg" can't be used, it could be the start of |
| 257 | "dgg"!). |
| 258 | |
| 259 | *dp* |
| 260 | dp Same as ":diffput" without argument or range. |
| 261 | |
| 262 | When no [range] is given, the diff at the cursor position or just above it is |
| 263 | affected. When [range] is used, Vim tries to only put or get the specified |
| 264 | lines. When there are deleted lines, this may not always be possible. |
| 265 | |
| 266 | There can be deleted lines below the last line of the buffer. When the cursor |
| 267 | is on the last line in the buffer and there is no diff above this line, the |
| 268 | ":diffget" and "do" commands will obtain lines from the other buffer. |
| 269 | |
| 270 | To be able to get those lines from another buffer in a [range] it's allowed to |
| 271 | use the last line number plus one. This command gets all diffs from the other |
| 272 | buffer: > |
| 273 | |
| 274 | :1,$+1diffget |
| 275 | |
| 276 | Note that deleted lines are displayed, but not counted as text lines. You |
| 277 | can't move the cursor into them. To fill the deleted lines with the lines |
| 278 | from another buffer use ":diffget" on the line below them. |
Bram Moolenaar | 910f66f | 2006-04-05 20:41:53 +0000 | [diff] [blame] | 279 | *E787* |
| 280 | When the buffer that is about to be modified is read-only and the autocommand |
| 281 | that is triggered by |FileChangedRO| changes buffers the command will fail. |
| 282 | The autocommand must not change buffers. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 283 | |
| 284 | The [bufspec] argument above can be a buffer number, a pattern for a buffer |
| 285 | name or a part of a buffer name. Examples: |
| 286 | |
| 287 | :diffget Use the other buffer which is in diff mode |
| 288 | :diffget 3 Use buffer 3 |
| 289 | :diffget v2 Use the buffer which matches "v2" and is in |
| 290 | diff mode (e.g., "file.c.v2") |
| 291 | |
| 292 | ============================================================================== |
| 293 | 5. Diff options *diff-options* |
| 294 | |
| 295 | Also see |'diffopt'| and the "diff" item of |'fillchars'|. |
| 296 | |
| 297 | |
| 298 | FINDING THE DIFFERENCES *diff-diffexpr* |
| 299 | |
| 300 | The 'diffexpr' option can be set to use something else than the standard |
| 301 | "diff" program to compare two files and find the differences. |
| 302 | |
| 303 | When 'diffexpr' is empty, Vim uses this command to find the differences |
| 304 | between file1 and file2: > |
| 305 | |
| 306 | diff file1 file2 > outfile |
| 307 | |
| 308 | The ">" is replaced with the value of 'shellredir'. |
| 309 | |
| 310 | The output of "diff" must be a normal "ed" style diff. Do NOT use a context |
| 311 | diff. This example explains the format that Vim expects: > |
| 312 | |
| 313 | 1a2 |
| 314 | > bbb |
| 315 | 4d4 |
| 316 | < 111 |
| 317 | 7c7 |
| 318 | < GGG |
| 319 | --- |
| 320 | > ggg |
| 321 | |
| 322 | The "1a2" item appends the line "bbb". |
| 323 | The "4d4" item deletes the line "111". |
| 324 | The '7c7" item replaces the line "GGG" with "ggg". |
| 325 | |
| 326 | When 'diffexpr' is not empty, Vim evaluates to obtain a diff file in the |
| 327 | format mentioned. These variables are set to the file names used: |
| 328 | |
| 329 | v:fname_in original file |
| 330 | v:fname_new new version of the same file |
| 331 | v:fname_out resulting diff file |
| 332 | |
| 333 | Additionally, 'diffexpr' should take care of "icase" and "iwhite" in the |
| 334 | 'diffopt' option. 'diffexpr' cannot change the value of 'lines' and |
| 335 | 'columns'. |
| 336 | |
| 337 | Example (this does almost the same as 'diffexpr' being empty): > |
| 338 | |
| 339 | set diffexpr=MyDiff() |
| 340 | function MyDiff() |
| 341 | let opt = "" |
| 342 | if &diffopt =~ "icase" |
| 343 | let opt = opt . "-i " |
| 344 | endif |
| 345 | if &diffopt =~ "iwhite" |
| 346 | let opt = opt . "-b " |
| 347 | endif |
| 348 | silent execute "!diff -a --binary " . opt . v:fname_in . " " . v:fname_new . |
| 349 | \ " > " . v:fname_out |
| 350 | endfunction |
| 351 | |
| 352 | The "-a" argument is used to force comparing the files as text, comparing as |
| 353 | binaries isn't useful. The "--binary" argument makes the files read in binary |
| 354 | mode, so that a CTRL-Z doesn't end the text on DOS. |
| 355 | |
| 356 | *E97* |
| 357 | Vim will do a test if the diff output looks alright. If it doesn't, you will |
| 358 | get an error message. Possible causes: |
| 359 | - The "diff" program cannot be executed. |
| 360 | - The "diff" program doesn't produce normal "ed" style diffs (see above). |
| 361 | - The 'shell' and associated options are not set correctly. Try if filtering |
| 362 | works with a command like ":!sort". |
| 363 | - You are using 'diffexpr' and it doesn't work. |
Bram Moolenaar | 71fe80d | 2006-01-22 23:25:56 +0000 | [diff] [blame] | 364 | If it's not clear what the problem is set the 'verbose' option to one or more |
| 365 | to see more messages. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 366 | |
Bram Moolenaar | 5eb86f9 | 2004-07-26 12:53:41 +0000 | [diff] [blame] | 367 | The self-installing Vim includes a diff program. If you don't have it you |
| 368 | might want to download a diff.exe. For example from |
| 369 | http://jlb.twu.net/code/unixkit.php. |
| 370 | |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 371 | |
| 372 | USING PATCHES *diff-patchexpr* |
| 373 | |
| 374 | The 'patchexpr' option can be set to use something else than the standard |
| 375 | "patch" program. |
| 376 | |
| 377 | When 'patchexpr' is empty, Vim will call the "patch" program like this: > |
| 378 | |
| 379 | patch -o outfile origfile < patchfile |
| 380 | |
| 381 | This should work fine with most versions of the "patch" program. Note that a |
| 382 | CR in the middle of a line may cause problems, it is seen as a line break. |
| 383 | |
| 384 | If the default doesn't work for you, set the 'patchexpr' to an expression that |
| 385 | will have the same effect. These variables are set to the file names used: |
| 386 | |
| 387 | v:fname_in original file |
| 388 | v:fname_diff patch file |
| 389 | v:fname_out resulting patched file |
| 390 | |
| 391 | Example (this does the same as 'patchexpr' being empty): > |
| 392 | |
Bram Moolenaar | 7d47b6e | 2006-03-15 22:59:18 +0000 | [diff] [blame] | 393 | set patchexpr=MyPatch() |
| 394 | function MyPatch() |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 395 | :call system("patch -o " . v:fname_out . " " . v:fname_in . |
| 396 | \ " < " . v:fname_diff) |
| 397 | endfunction |
| 398 | |
| 399 | Make sure that using the "patch" program doesn't have unwanted side effects. |
| 400 | For example, watch out for additionally generated files, which should be |
| 401 | deleted. It should just patch the file and nothing else. |
| 402 | Vim will change directory to "/tmp" or another temp directory before |
| 403 | evaluating 'patchexpr'. This hopefully avoids that files in the current |
| 404 | directory are accidentally patched. Vim will also delete files starting with |
| 405 | v:fname_in and ending in ".rej" and ".orig". |
| 406 | |
| 407 | vim:tw=78:ts=8:ft=help:norl: |