123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443 |
- *diff.txt* Nvim
- VIM REFERENCE MANUAL by Bram Moolenaar
- *diff* *diff-mode*
- This file describes the diff feature: Showing differences between two to
- eight versions of the same file.
- The basics are explained in section |08.7| of the user manual.
- Type |gO| to see the table of contents.
- ==============================================================================
- 1. Starting diff mode *start-vimdiff*
- To start editing in diff mode, run "nvim -d". This starts Nvim as usual, and
- additionally sets up for viewing the differences between the arguments. >
- nvim -d file1 file2 [file3 [file4]]
- In addition to the |-d| argument, |-R| may be used for readonly mode.
- 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.
- By default an internal diff library will be used. When 'diffopt' or
- 'diffexpr' has been set an external "diff" command will be used. This only
- works when such a diff program is available.
- 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 Nvim opens a window for each of the files. This is like
- using the |-O| argument. This uses vertical splits, but if you prefer
- horizontal splits use the |-o| argument instead: >
- nvim -d -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, or leave as-is if 'diffopt' includes "followwrap"
- '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.
- See `:diffoff` for an easy way to revert the options.
- 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, especially when using an external diff command.
- 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*
- :diffs[plit] {filename} *:diffs* *:diffsplit*
- Open a new window on the file {filename}. The options are set
- as for "nvim -d" for the current and the newly opened window.
- Also see 'diffexpr'.
- *:difft* *:diffthis*
- :difft[his] Make the current window part of the diff windows. This sets
- the options as for "nvim -d".
- :diffp[atch] {patchfile} *E816* *:diffp* *:diffpatch*
- Use the current buffer, patch it with the diff found in
- {patchfile} and open a buffer on the result. This sets the
- options as for "nvim -d".
- {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 eight 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*
- :diffo[ff] Switch off diff mode for the current window. Resets related
- options also when 'diff' was not set.
- :diffo[ff]! Switch off diff mode for the current window and in all windows
- in the current tab page where 'diff' is set. Resetting
- related options only happens in a window that has 'diff' set,
- if the current window does not have 'diff' set then no options
- in it are changed.
- Hidden buffers are also removed from the list of diff'ed
- buffers.
- The `:diffoff` command resets the relevant options to the values they had when
- using `:diffsplit`, `:diffpatch` , `:diffthis`. or starting Vim in diff mode.
- When using `:diffoff` twice the last saved values are restored.
- Otherwise they are set to their default value:
- 'diff' off
- 'scrollbind' off
- 'cursorbind' off
- 'scrollopt' without "hor"
- 'wrap' on, or leave as-is if 'diffopt' includes "followwrap"
- '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. To get rid of the hidden
- buffers use `:diffoff!`.
- *: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 buftype=nofile | read ++edit # | 0d_
- \ | diffthis | wincmd p | diffthis
- 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.
- *:dif* *:diff* *:diffupdate*
- :dif[fupdate][!] 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
- If the ! is included Vim will check if the file was changed externally and
- needs to be reloaded. It will prompt for each changed file, like `:checktime`
- was used.
- 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. The 'diffopt'
- flags "iwhite" and "icase" are 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*
- [count]do Same as ":diffget" without 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.
- If you give a [count], it is used as the [bufspec] argument
- for ":diffget".
- *dp*
- [count]dp Same as ":diffput" without range. Note: this doesn't work in
- Visual mode.
- If you give a [count], it is used as the [bufspec] argument
- for ":diffput".
- 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'|.
- *diff-slow* *diff_translations*
- For very long lines, the diff syntax highlighting might be slow, especially
- since it tries to match all different kind of localisations. To disable
- localisations and speed up the syntax highlighting, set the global variable
- g:diff_translations to zero: >
- let g:diff_translations = 0
- <
- After setting this variable, reload the syntax script: >
- set syntax=diff
- <
- FINDING THE DIFFERENCES *diff-diffexpr*
- The 'diffexpr' option can be set to use something else than the internal diff
- support or 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 or a unified diff. A
- context diff will NOT work. For a unified diff no context lines can be used.
- Using "diff -u" will NOT work, use "diff -U0".
- This example explains the format that Vim expects for the "ed" style diff: >
- 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 where to write the 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
- redraw!
- 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.
- The `redraw!` command may not be needed, depending on whether executing a
- shell command shows something on the display or not.
- *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
- https://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:noet:ft=help:norl:
|