diff.txt (22492B)
1 *diff.txt* Nvim 2 3 4 VIM REFERENCE MANUAL by Bram Moolenaar 5 6 7 *diff* *diff-mode* 8 This file describes the diff feature: Showing differences between two to 9 eight versions of the same file. 10 11 The basics are explained in section |08.7| of the user manual. 12 13 Type |gO| to see the table of contents. 14 15 ============================================================================== 16 1. Starting diff mode *start-vimdiff* 17 18 To start editing in diff mode, run "nvim -d". This starts Nvim as usual, and 19 additionally sets up for viewing the differences between the arguments. > 20 21 nvim -d file1 file2 [file3 [file4]] 22 23 In addition to the |-d| argument, |-R| may be used for readonly mode. 24 25 The second and following arguments may also be a directory name. Vim will 26 then append the file name of the first argument to the directory name to find 27 the file. 28 29 By default an internal diff library will be used. When 'diffopt' or 30 'diffexpr' has been set an external "diff" command will be used. This only 31 works when such a diff program is available. 32 33 Diffs are local to the current tab page |tab-page|. You can't see diffs with 34 a window in another tab page. This does make it possible to have several 35 diffs at the same time, each in their own tab page. 36 37 What happens is that Nvim opens a window for each of the files. This is like 38 using the |-O| argument. This uses vertical splits, but if you prefer 39 horizontal splits use the |-o| argument instead: > 40 41 nvim -d -o file1 file2 [file3 [file4]] 42 43 If you always prefer horizontal splits include "horizontal" in 'diffopt'. 44 45 In each of the edited files these options are set: 46 47 'diff' on 48 'scrollbind' on 49 'cursorbind' on 50 'scrollopt' includes "hor" 51 'wrap' off, or leave as-is if 'diffopt' includes "followwrap" 52 'foldmethod' "diff" 53 'foldcolumn' value from 'diffopt', default is 2 54 55 These options are set local to the window. When editing another file they are 56 reset to the global value. 57 The options can still be overruled from a modeline when re-editing the file. 58 However, 'foldmethod' and 'wrap' won't be set from a modeline when 'diff' is 59 set. 60 See `:diffoff` for an easy way to revert the options. 61 62 The differences shown are actually the differences in the buffer. Thus if you 63 make changes after loading a file, these will be included in the displayed 64 diffs. You might have to do ":diffupdate" now and then, not all changes are 65 immediately taken into account, especially when using an external diff 66 command. 67 68 In your vimrc file you could do something special when Vim was started in 69 diff mode. You could use a construct like this: > 70 71 if &diff 72 setup for diff mode 73 else 74 setup for non-diff mode 75 endif 76 77 While already in Vim you can start diff mode in three ways. 78 79 *E98* 80 :diffs[plit] {filename} *:diffs* *:diffsplit* 81 Open a new window on the file {filename}. The options are set 82 as for "nvim -d" for the current and the newly opened window. 83 Also see 'diffexpr'. 84 85 *:difft* *:diffthis* 86 :difft[his] Make the current window part of the diff windows. This sets 87 the options as for "nvim -d". 88 89 :diffp[atch] {patchfile} *E816* *:diffp* *:diffpatch* 90 Use the current buffer, patch it with the diff found in 91 {patchfile} and open a buffer on the result. This sets the 92 options as for "nvim -d". 93 {patchfile} can be in any format that the "patch" program 94 understands or 'patchexpr' can handle. 95 Note that {patchfile} should only contain a diff for one file, 96 the current file. If {patchfile} contains diffs for other 97 files as well, the results are unpredictable. Vim changes 98 directory to /tmp to avoid files in the current directory 99 accidentally being patched. But it may still result in 100 various ".rej" files to be created. And when absolute path 101 names are present these files may get patched anyway. 102 103 To make these commands use a vertical split, prepend |:vertical|. Examples: > 104 105 :vert diffsplit main.c~ 106 :vert diffpatch /tmp/diff 107 108 If you always prefer a vertical split include "vertical" in 'diffopt'. 109 110 *E96* 111 There can be up to eight buffers with 'diff' set. 112 113 Since the option values are remembered with the buffer, you can edit another 114 file for a moment and come back to the same file and be in diff mode again. 115 116 *:diffo* *:diffoff* 117 :diffo[ff] Switch off diff mode for the current window. Resets related 118 options also when 'diff' was not set. 119 120 :diffo[ff]! Switch off diff mode for the current window and in all windows 121 in the current tab page where 'diff' is set. Resetting 122 related options only happens in a window that has 'diff' set, 123 if the current window does not have 'diff' set then no options 124 in it are changed. 125 Hidden buffers are also removed from the list of diff'ed 126 buffers. 127 128 The `:diffoff` command resets the relevant options to the values they had when 129 using `:diffsplit`, `:diffpatch`, `:diffthis`, or starting Vim in diff mode. 130 When using `:diffoff` twice the last saved values are restored. 131 Otherwise they are set to their default value: 132 133 'diff' off 134 'scrollbind' off 135 'cursorbind' off 136 'scrollopt' without "hor" 137 'wrap' on, or leave as-is if 'diffopt' includes "followwrap" 138 'foldmethod' "manual" 139 'foldcolumn' 0 140 141 'foldenable' will most-likely be reset to off. That is when 'foldmethod' is 142 restored to "manual". The folds themselves are not cleared but they should 143 not show up, resetting 'foldenable' is the best way to do that. 144 145 ============================================================================== 146 2. Viewing diffs *view-diffs* 147 148 The effect is that the diff windows show the same text, with the differences 149 highlighted. When scrolling the text, the 'scrollbind' option will make the 150 text in other windows to be scrolled as well. With vertical splits the text 151 should be aligned properly. 152 153 The alignment of text will go wrong when: 154 - 'wrap' is on, some lines will be wrapped and occupy two or more screen 155 lines 156 - folds are open in one window but not another 157 - 'scrollbind' is off 158 - changes have been made to the text 159 - "filler" is not present in 'diffopt', deleted/inserted lines makes the 160 alignment go wrong 161 162 All the buffers edited in a window where the 'diff' option is set will join in 163 the diff. This is also possible for hidden buffers. They must have been 164 edited in a window first for this to be possible. To get rid of the hidden 165 buffers use `:diffoff!`. 166 167 *:DiffOrig* *diff-original-file* 168 Since 'diff' is a window-local option, it's possible to view the same buffer 169 in diff mode in one window and "normal" in another window. It is also 170 possible to view the changes you have made to a buffer since the file was 171 loaded. Since Vim doesn't allow having two buffers for the same file, you 172 need another buffer. This command is useful: > 173 command DiffOrig vert new | set buftype=nofile | read ++edit # | 0d_ 174 \ | diffthis | wincmd p | diffthis 175 Use ":DiffOrig" to see the differences 176 between the current buffer and the file it was loaded from. 177 178 A buffer that is unloaded cannot be used for the diff. But it does work for 179 hidden buffers. You can use ":hide" to close a window without unloading the 180 buffer. If you don't want a buffer to remain used for the diff do ":set 181 nodiff" before hiding it. 182 183 *:dif* *:diff* *:diffupdate* 184 :dif[fupdate][!] Update the diff highlighting and folds. 185 186 Vim attempts to keep the differences updated when you make changes to the 187 text. This mostly takes care of inserted and deleted lines. Changes within a 188 line and more complicated changes do not cause the differences to be updated. 189 To force the differences to be updated use: > 190 191 :diffupdate 192 193 If the ! is included Vim will check if the file was changed externally and 194 needs to be reloaded. It will prompt for each changed file, like `:checktime` 195 was used. 196 197 Vim will show filler lines for lines that are missing in one window but are 198 present in another. These lines were inserted in another file or deleted in 199 this file. Removing "filler" from the 'diffopt' option will make Vim not 200 display these filler lines. 201 202 203 Folds are used to hide the text that wasn't changed. See |folding| for all 204 the commands that can be used with folds. 205 206 The context of lines above a difference that are not included in the fold can 207 be set with the 'diffopt' option. For example, to set the context to three 208 lines: > 209 210 :set diffopt=filler,context:3 211 212 213 The diffs are highlighted with these groups: 214 215 |hl-DiffAdd| DiffAdd Added (inserted) lines. These lines exist in 216 this buffer but not in another. 217 |hl-DiffChange| DiffChange Changed lines. 218 |hl-DiffText| DiffText Changed text inside a Changed line. Exact 219 behavior depends on the `inline:` setting in 220 'diffopt'. 221 With `inline:` set to "simple", Vim finds the 222 first character that is different, and the 223 last character that is different (searching 224 from the end of the line). The text in 225 between is highlighted. This means that parts 226 in the middle that are still the same are 227 highlighted anyway. The 'diffopt' flags 228 "iwhite" and "icase" are used here. 229 With `inline:` set to "char" or "word", Vim 230 uses the internal diff library to perform a 231 detailed diff between the changed blocks and 232 highlight the exact difference between the 233 two. Will respect any 'diffopt' flag that 234 affects internal diff. 235 Not used when `inline:` is set to "none". 236 |hl-DiffTextAdd| DiffTextAdd Added text inside a Changed line. Similar to 237 DiffText, but used when there is no 238 corresponding text in other buffers. Not used 239 when `inline:` is set to "simple" or "none". 240 |hl-DiffDelete| DiffDelete Deleted lines. Also called filler lines, 241 because they don't really exist in this 242 buffer. 243 244 ============================================================================== 245 3. Jumping to diffs *jumpto-diffs* 246 247 Two commands can be used to jump to diffs: 248 *[c* 249 [c Jump backwards to the previous start of a change. 250 When a count is used, do it that many times. 251 *]c* 252 ]c Jump forwards to the next start of a change. 253 When a count is used, do it that many times. 254 255 It is an error if there is no change for the cursor to move to. 256 257 ============================================================================== 258 4. Diff copying *copy-diffs* *E99* *E100* *E101* *E102* *E103* 259 *merge* 260 There are two commands to copy text from one buffer to another. The result is 261 that the buffers will be equal within the specified range. 262 263 *:diffg* *:diffget* 264 :[range]diffg[et] [bufspec] 265 Modify the current buffer to undo difference with another 266 buffer. If [bufspec] is given, that buffer is used. If 267 [bufspec] refers to the current buffer then nothing happens. 268 Otherwise this only works if there is one other buffer in diff 269 mode. 270 See below for [range]. 271 272 *:diffpu* *:diffput* *E793* 273 :[range]diffpu[t] [bufspec] 274 Modify another buffer to undo difference with the current 275 buffer. Just like ":diffget" but the other buffer is modified 276 instead of the current one. 277 When [bufspec] is omitted and there is more than one other 278 buffer in diff mode where 'modifiable' is set this fails. 279 See below for [range]. 280 281 *do* 282 [count]do Same as ":diffget" without range. The "o" stands for "obtain" 283 ("dg" can't be used, it could be the start of "dgg"!). Note: 284 this doesn't work in Visual mode. 285 If you give a [count], it is used as the [bufspec] argument 286 for ":diffget". 287 288 *dp* 289 [count]dp Same as ":diffput" without range. Note: this doesn't work in 290 Visual mode. 291 If you give a [count], it is used as the [bufspec] argument 292 for ":diffput". 293 294 295 When no [range] is given, the diff at the cursor position or just above it is 296 affected. There can be deleted lines below the last line of the buffer. When 297 the cursor is on the last line in the buffer and there is no diff above this 298 line, and no [range] is given, the diff below the cursor position will be used 299 instead. 300 301 When [range] is used, Vim tries to only put or get the specified lines. When 302 there are deleted lines, they will be used if they are between the lines 303 specified by [range]. 304 305 To be able to put or get those lines to/from another buffer in a [range] it's 306 allowed to use 0 and the last line number plus one. This command gets all 307 diffs from the other buffer: > 308 309 :0,$+1diffget 310 311 Note that deleted lines are displayed, but not counted as text lines. You 312 can't move the cursor into them. To fill the deleted lines with the lines 313 from another buffer use ":diffget" on the line below them. 314 *E787* 315 When the buffer that is about to be modified is read-only and the autocommand 316 that is triggered by |FileChangedRO| changes buffers the command will fail. 317 The autocommand must not change buffers. 318 319 The [bufspec] argument above can be a buffer number, a pattern for a buffer 320 name or a part of a buffer name. Examples: 321 322 :diffget Use the other buffer which is in diff mode 323 :diffget 3 Use buffer 3 324 :diffget v2 Use the buffer which matches "v2" and is in 325 diff mode (e.g., "file.c.v2") 326 327 ============================================================================== 328 5. Diff anchors *diff-anchors* 329 330 Diff anchors allow you to control where the diff algorithm aligns and 331 synchronize text across files. Each anchor matches each other in each file, 332 allowing you to control the output of a diff. 333 334 This is useful when a change involves complicated edits. For example, if a 335 function was moved to another location and further edited. By default, the 336 algorithm aims to create the smallest diff, which results in that entire 337 function being considered to be deleted and added on the other side, making it 338 hard to see what the actual edit on it was. You can use diff anchors to pin 339 that function so the diff algorithm will align based on it. 340 341 To use it, set anchors using 'diffanchors' which is a comma-separated list of 342 {address} in each file, and then add "anchor" to 'diffopt'. Internally, Vim 343 splits each file up into sections split by the anchors. It performs the diff 344 on each pair of sections separately before merging the results back. 345 346 Setting 'diffanchors' will update the diff immediately. If an anchor is tied 347 to a mark, and you change what the mark is pointed to, you need to manually 348 call |:diffupdate| afterwards to get the updated diff results. 349 350 Example: 351 352 Let's say we have the following files, side-by-side. We are interested in the 353 change that happened to the function `foo()`, which was both edited and moved. 354 355 File A: > 356 int foo() { 357 int n = 1; 358 return n; 359 } 360 361 int g = 1; 362 363 int bar(int a) { 364 a *= 2; 365 a += 3; 366 return a; 367 } 368 <File B: > 369 int bar(int a) { 370 a *= 2; 371 a += 3; 372 return a; 373 } 374 375 int foo() { 376 int n = 999; 377 return n; 378 } 379 380 int g = 1; 381 < 382 A normal diff will usually align the diff result as such: > 383 384 int foo() { |---------------- 385 int n = 1; |---------------- 386 return n; |---------------- 387 } |---------------- 388 |---------------- 389 int g = 1; |---------------- 390 |---------------- 391 int bar(int a) {|int bar(int a) { 392 a *= 2; | a *= 2; 393 a += 3; | a += 3; 394 return a; | return a; 395 } |} 396 ----------------| 397 ----------------|int foo() { 398 ----------------| int n = 999; 399 ----------------| return n; 400 ----------------|} 401 ----------------| 402 ----------------|int g = 1; 403 < 404 What we want is to instead ask the diff to align on `foo()`: > 405 406 ----------------|int bar(int a) { 407 ----------------| a *= 2; 408 ----------------| a += 3; 409 ----------------| return a; 410 ----------------|} 411 ----------------| 412 int foo() { |int foo() { 413 int n = 1; | int n = 999; 414 return n; | return n; 415 } |} 416 | 417 int g = 1; |int g = 1; 418 |---------------- 419 int bar(int a) {|---------------- 420 a *= 2; |---------------- 421 a += 3; |---------------- 422 return a; |---------------- 423 } |---------------- 424 < 425 426 Below are some ways of setting diff anchors to get the above result. In each 427 example, 'diffopt' needs to have `anchor` set for this to take effect. 428 429 Marks: Set the |'a| mark on the `int foo()` lines in each file first before 430 setting the anchors: > 431 set diffanchors='a 432 433 Pattern: Specify the anchor using a |pattern| (see |:/|). Here, we make sure 434 to always start search from line 1 for consistency: > 435 set diffanchors=1/int\ foo(/ 436 < 437 Selection: Use visual mode to select the entire `foo()` function body in each 438 file. Here, we use two anchors. This does a better job of making sure only 439 the function bodies are anchored against each other but not the lines after 440 it. Note the `'>+1` below. The "+1" is necessary as we want the split to 441 happen below the last line of the function, not above: > 442 set diffanchors='<,'>+1 443 < 444 Manually set two anchors using line numbers via buffer-local options: > 445 setlocal diffanchors=1,5 446 wincmd w 447 setlocal diffanchors=7,11 448 < 449 ============================================================================== 450 6. Diff options *diff-options* 451 452 Also see 'diffopt' and the "diff" item of 'fillchars'. 453 454 *diff-slow* *diff_translations* 455 For very long lines, the diff syntax highlighting might be slow, especially 456 since it tries to match all different kind of localisations. To disable 457 localisations and speed up the syntax highlighting, set the global variable 458 g:diff_translations to zero: > 459 460 let g:diff_translations = 0 461 < 462 After setting this variable, reload the syntax script: > 463 464 set syntax=diff 465 < 466 467 468 FINDING THE DIFFERENCES *diff-diffexpr* 469 470 The 'diffexpr' option can be set to use something else than the internal diff 471 support or the standard "diff" program to compare two files and find the 472 differences. 473 474 When 'diffexpr' is empty, Vim uses this command to find the differences 475 between file1 and file2: > 476 477 diff file1 file2 > outfile 478 479 The ">" is replaced with the value of 'shellredir'. 480 481 The output of "diff" must be a normal "ed" style diff or a unified diff. A 482 context diff will NOT work. For a unified diff no context lines can be used. 483 Using "diff -u" will NOT work, use "diff -U0". 484 485 This example explains the format that Vim expects for the "ed" style diff: > 486 487 1a2 488 > bbb 489 4d4 490 < 111 491 7c7 492 < GGG 493 --- 494 > ggg 495 496 The "1a2" item appends the line "bbb". 497 The "4d4" item deletes the line "111". 498 The "7c7" item replaces the line "GGG" with "ggg". 499 500 When 'diffexpr' is not empty, Vim evaluates it to obtain a diff file in the 501 format mentioned. These variables are set to the file names used: 502 503 v:fname_in original file 504 v:fname_new new version of the same file 505 v:fname_out where to write the resulting diff file 506 507 Additionally, 'diffexpr' should take care of "icase" and "iwhite" in the 508 'diffopt' option. 'diffexpr' cannot change the value of 'lines' and 509 'columns'. 510 511 The advantage of using a function call without arguments is that it is faster, 512 see |expr-option-function|. 513 514 Example (this does almost the same as 'diffexpr' being empty): > 515 516 set diffexpr=MyDiff() 517 function MyDiff() 518 let opt = "" 519 if &diffopt =~ "icase" 520 let opt = opt .. "-i " 521 endif 522 if &diffopt =~ "iwhite" 523 let opt = opt .. "-b " 524 endif 525 silent execute "!diff -a --binary " .. opt .. v:fname_in .. " " .. v:fname_new .. 526 \ " > " .. v:fname_out 527 redraw! 528 endfunction 529 530 The "-a" argument is used to force comparing the files as text, comparing as 531 binaries isn't useful. The "--binary" argument makes the files read in binary 532 mode, so that a CTRL-Z doesn't end the text on DOS. 533 534 The `redraw!` command may not be needed, depending on whether executing a 535 shell command shows something on the display or not. 536 537 If the 'diffexpr' expression starts with s: or |<SID>|, then it is replaced 538 with the script ID (|local-function|). Example: > 539 set diffexpr=s:MyDiffExpr() 540 set diffexpr=<SID>SomeDiffExpr() 541 Otherwise, the expression is evaluated in the context of the script where the 542 option was set, thus script-local items are available. 543 544 *E810* *E97* 545 Vim will do a test if the diff output looks alright. If it doesn't, you will 546 get an error message. Possible causes: 547 - The "diff" program cannot be executed. 548 - The "diff" program doesn't produce normal "ed" style diffs (see above). 549 - The 'shell' and associated options are not set correctly. Try if filtering 550 works with a command like ":!sort". 551 - You are using 'diffexpr' and it doesn't work. 552 If it's not clear what the problem is set the 'verbose' option to one or more 553 to see more messages. 554 555 The self-installing Vim for MS-Windows includes a diff program. If you don't 556 have it you might want to download a diff.exe. For example from 557 https://gnuwin32.sourceforge.net/packages/diffutils.htm. 558 559 560 USING PATCHES *diff-patchexpr* 561 562 The 'patchexpr' option can be set to use something else than the standard 563 "patch" program. 564 565 When 'patchexpr' is empty, Vim will call the "patch" program like this: > 566 567 patch -o outfile origfile < patchfile 568 569 This should work fine with most versions of the "patch" program. Note that a 570 CR in the middle of a line may cause problems, it is seen as a line break. 571 572 If the default doesn't work for you, set the 'patchexpr' to an expression that 573 will have the same effect. These variables are set to the file names used: 574 575 v:fname_in original file 576 v:fname_diff patch file 577 v:fname_out resulting patched file 578 579 The advantage of using a function call without arguments is that it is faster, 580 see |expr-option-function|. 581 582 Example (this does the same as 'patchexpr' being empty): > 583 584 set patchexpr=MyPatch() 585 function MyPatch() 586 :call system("patch -o " .. v:fname_out .. " " .. v:fname_in .. 587 \ " < " .. v:fname_diff) 588 endfunction 589 590 Make sure that using the "patch" program doesn't have unwanted side effects. 591 For example, watch out for additionally generated files, which should be 592 deleted. It should just patch the file and nothing else. 593 Vim will change directory to "/tmp" or another temp directory before 594 evaluating 'patchexpr'. This hopefully avoids that files in the current 595 directory are accidentally patched. Vim will also delete files starting with 596 v:fname_in and ending in ".rej" and ".orig". 597 598 If the 'patchexpr' expression starts with s: or |<SID>|, then it is replaced 599 with the script ID (|local-function|). Example: > 600 set patchexpr=s:MyPatchExpr() 601 set patchexpr=<SID>SomePatchExpr() 602 Otherwise, the expression is evaluated in the context of the script where the 603 option was set, thus script-local items are available. 604 605 606 vim:tw=78:ts=8:noet:ft=help:norl: