closes: #17857 Signed-off-by: Hirohito Higashi <h.east.727@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
		
			
				
	
	
		
			663 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			663 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| *diff.txt*      For Vim version 9.1.  Last change: 2025 Aug 06
 | |
| 
 | |
| 
 | |
| 		  VIM REFERENCE MANUAL    by Bram Moolenaar
 | |
| 
 | |
| 
 | |
| 				*diff* *vimdiff* *gvimdiff* *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.
 | |
| 
 | |
| 1. Starting diff mode		|start-vimdiff|
 | |
| 2. Viewing diffs		|view-diffs|
 | |
| 3. Jumping to diffs		|jumpto-diffs|
 | |
| 4. Copying diffs		|copy-diffs|
 | |
| 5. Diff anchors			|diff-anchors|
 | |
| 6. Diff options			|diff-options|
 | |
| 
 | |
| ==============================================================================
 | |
| 1. Starting diff mode					*start-vimdiff*
 | |
| 
 | |
| 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.
 | |
| 
 | |
| 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 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, 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 "vimdiff" 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 like for "vimdiff".
 | |
| 
 | |
| :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.  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.
 | |
| 		Using the "patch" command is not allowed in |restricted-mode|.
 | |
| 
 | |
| 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
 | |
| 
 | |
| 'foldenable' will most-likely be reset to off.  That is when 'foldmethod' is
 | |
| is restored to "manual".  The folds themselves are not cleared but they should
 | |
| not show up, resetting 'foldenable' is the best way to do that.
 | |
| 
 | |
| ==============================================================================
 | |
| 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 bt=nofile | r ++edit # | 0d_
 | |
| 		\ | diffthis | wincmd p | diffthis
 | |
| (this is in |defaults.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.
 | |
| 
 | |
| 						*: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.  Exact
 | |
| 				behavior depends on the `inline:` setting in
 | |
| 				'diffopt'.
 | |
| 				With `inline:` set to "simple", 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.
 | |
| 				With `inline:` set to "char" or "word", Vim
 | |
| 				uses the internal diff library to perform a
 | |
| 				detailed diff between the changed blocks and
 | |
| 				highlight the exact difference between the
 | |
| 				two.  Will respect any 'diffopt' flag that
 | |
| 				affects internal diff.
 | |
| 				Not used when `inline:` is set to "none".
 | |
| |hl-DiffTextAdd|  DiffTextAdd	Added text inside a Changed line.  Similar to
 | |
| 				DiffText, but used when there is no
 | |
| 				corresponding text in other buffers.  Not used
 | |
| 				when `inline:` is set to "simple" or "none".
 | |
| |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.  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, and no [range] is given, the diff below the cursor position will be used
 | |
| instead.
 | |
| 
 | |
| When [range] is used, Vim tries to only put or get the specified lines.  When
 | |
| there are deleted lines, they will be used if they are between the lines
 | |
| specified by [range].
 | |
| 
 | |
| To be able to put or get those lines to/from another buffer in a [range] it's
 | |
| allowed to use 0 and the last line number plus one.  This command gets all
 | |
| diffs from the other buffer: >
 | |
| 
 | |
| 	:0,$+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 anchors						*diff-anchors*
 | |
| 
 | |
| Diff anchors allow you to control where the diff algorithm aligns and
 | |
| synchronize text across files.  Each anchor matches each other in each file,
 | |
| allowing you to control the output of a diff.
 | |
| 
 | |
| This is useful when a change involves complicated edits.  For example, if a
 | |
| function was moved to another location and further edited.  By default, the
 | |
| algorithm aims to create the smallest diff, which results in that entire
 | |
| function being considered to be deleted and added on the other side, making it
 | |
| hard to see what the actual edit on it was.  You can use diff anchors to pin
 | |
| that function so the diff algorithm will align based on it.
 | |
| 
 | |
| To use it, set anchors using 'diffanchors' which is a comma-separated list of
 | |
| {address} in each file, and then add "anchor" to 'diffopt'.  Internaly, Vim
 | |
| splits each file up into sections split by the anchors.  It performs the diff
 | |
| on each pair of sections separately before merging the results back.
 | |
| 
 | |
| Setting 'diffanchors' will update the diff immediately.  If an anchor is tied
 | |
| to a mark, and you change what the mark is pointed to, you need to manually
 | |
| call |:diffupdate| afterwards to get the updated diff results.
 | |
| 
 | |
| Example:
 | |
| 
 | |
| Let's say we have the following files, side-by-side.  We are interested in the
 | |
| change that happened to the function `foo()`, which was both edited and moved.
 | |
| 
 | |
| File A: >
 | |
| 	int foo() {
 | |
| 	    int n = 1;
 | |
| 	    return n;
 | |
| 	}
 | |
| 
 | |
| 	int g = 1;
 | |
| 
 | |
| 	int bar(int a) {
 | |
| 	    a *= 2;
 | |
| 	    a += 3;
 | |
| 	    return a;
 | |
| 	}
 | |
| <File B: >
 | |
| 	int bar(int a) {
 | |
| 	    a *= 2;
 | |
| 	    a += 3;
 | |
| 	    return a;
 | |
| 	}
 | |
| 
 | |
| 	int foo() {
 | |
| 	    int n = 999;
 | |
| 	    return n;
 | |
| 	}
 | |
| 
 | |
| 	int g = 1;
 | |
| <
 | |
| A normal diff will usually align the diff result as such: >
 | |
| 
 | |
| 	int foo() {     |----------------
 | |
| 	    int n = 1;  |----------------
 | |
| 	    return n;   |----------------
 | |
| 	}               |----------------
 | |
| 	                |----------------
 | |
| 	int g = 1;      |----------------
 | |
| 	                |----------------
 | |
| 	int bar(int a) {|int bar(int a) {
 | |
| 	    a *= 2;     |    a *= 2;
 | |
| 	    a += 3;     |    a += 3;
 | |
| 	    return a;   |    return a;
 | |
| 	}               |}
 | |
| 	----------------|
 | |
| 	----------------|int foo() {
 | |
| 	----------------|    int n = 999;
 | |
| 	----------------|    return n;
 | |
| 	----------------|}
 | |
| 	----------------|
 | |
| 	----------------|int g = 1;
 | |
| <
 | |
| What we want is to instead ask the diff to align on `foo()`: >
 | |
| 
 | |
| 	----------------|int bar(int a) {
 | |
| 	----------------|    a *= 2;
 | |
| 	----------------|    a += 3;
 | |
| 	----------------|    return a;
 | |
| 	----------------|}
 | |
| 	----------------|
 | |
| 	int foo() {     |int foo() {
 | |
| 	    int n = 1;  |    int n = 999;
 | |
| 	    return n;   |    return n;
 | |
| 	}               |}
 | |
| 	                |
 | |
| 	int g = 1;      |int g = 1;
 | |
| 	                |----------------
 | |
| 	int bar(int a) {|----------------
 | |
| 	    a *= 2;     |----------------
 | |
| 	    a += 3;     |----------------
 | |
| 	    return a;   |----------------
 | |
| 	}               |----------------
 | |
| <
 | |
| 
 | |
| Below are some ways of setting diff anchors to get the above result.  In each
 | |
| example, 'diffopt' needs to have `anchor` set for this to take effect.
 | |
| 
 | |
| Marks: Set the |'a| mark on the `int foo()` lines in each file first before
 | |
| setting the anchors: >
 | |
| 	set diffanchors='a
 | |
| 
 | |
| Pattern: Specify the anchor using a |pattern| (see |:/|).  Here, we make sure
 | |
| to always start search from line 1 for consistency: >
 | |
| 	set diffanchors=1/int\ foo(/
 | |
| <
 | |
| Selection: Use visual mode to select the entire `foo()` function body in each
 | |
| file.  Here, we use two anchors.  This does a better job of making sure only
 | |
| the function bodies are anchored against each other but not the lines after
 | |
| it.  Note the `'>+1` below.  The "+1" is necessary as we want the split to
 | |
| happen below the last line of the function, not above: >
 | |
| 	set diffanchors='<,'>+1
 | |
| <
 | |
| Manually set two anchors using line numbers via buffer-local options: >
 | |
| 	setlocal diffanchors=1,5
 | |
| 	wincmd w
 | |
| 	setlocal diffanchors=7,11
 | |
| <
 | |
| ==============================================================================
 | |
| 6. 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. *E959*
 | |
| 
 | |
| 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'.
 | |
| 
 | |
| The advantage of using a function call without arguments is that it is faster,
 | |
| see |expr-option-function|.
 | |
| 
 | |
| 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.
 | |
| 
 | |
| If the 'diffexpr' expression starts with s: or |<SID>|, then it is replaced
 | |
| with the script ID (|local-function|). Example: >
 | |
| 		set diffexpr=s:MyDiffExpr()
 | |
| 		set diffexpr=<SID>SomeDiffExpr()
 | |
| Otherwise, the expression is evaluated in the context of the script where the
 | |
| option was set, thus script-local items are available.
 | |
| 
 | |
| 						*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
 | |
| 
 | |
| The advantage of using a function call without arguments is that it is faster,
 | |
| see |expr-option-function|.
 | |
| 
 | |
| 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".
 | |
| 
 | |
| If the 'patchexpr' expression starts with s: or |<SID>|, then it is replaced
 | |
| with the script ID (|local-function|). Example: >
 | |
| 		set patchexpr=s:MyPatchExpr()
 | |
| 		set patchexpr=<SID>SomePatchExpr()
 | |
| Otherwise, the expression is evaluated in the context of the script where the
 | |
| option was set, thus script-local items are available.
 | |
| 
 | |
| 
 | |
| DIFF FUNCTION EXAMPLES				*diff-func-examples*
 | |
| 
 | |
| Some examples for using the |diff()| function to compute the diff indices
 | |
| between two Lists of strings are below.
 | |
| >
 | |
|   " some lines are changed
 | |
|   :echo diff(['abc', 'def', 'ghi'], ['abx', 'rrr', 'xhi'], {'output': 'indices'})
 | |
|    [{'from_idx': 0, 'from_count': 3, 'to_idx': 0, 'to_count': 3}]
 | |
| 
 | |
|   " few lines added at the beginning
 | |
|   :echo diff(['ghi'], ['abc', 'def', 'ghi'], {'output': 'indices'})
 | |
|    [{'from_idx': 0, 'from_count': 0, 'to_idx': 0, 'to_count': 2}]
 | |
| 
 | |
|   " few lines removed from the beginning
 | |
|   :echo diff(['abc', 'def', 'ghi'], ['ghi'], {'output': 'indices'})
 | |
|    [{'from_idx': 0, 'from_count': 2, 'to_idx': 0, 'to_count': 0}]
 | |
| 
 | |
|   " few lines added in the middle
 | |
|   :echo diff(['abc', 'jkl'], ['abc', 'def', 'ghi', 'jkl'], {'output': 'indices'})
 | |
|    [{'from_idx': 1, 'from_count': 0, 'to_idx': 1, 'to_count': 2}]
 | |
| 
 | |
|   " few lines removed in the middle
 | |
|   :echo diff(['abc', 'def', 'ghi', 'jkl'], ['abc', 'jkl'], {'output': 'indices'})
 | |
|    [{'from_idx': 1, 'from_count': 2, 'to_idx': 1, 'to_count': 0}]
 | |
| 
 | |
|   " few lines added at the end
 | |
|   :echo diff(['abc'], ['abc', 'def', 'ghi'], {'output': 'indices'})
 | |
|    [{'from_idx': 1, 'from_count': 0, 'to_idx': 1, 'to_count': 2}]
 | |
| 
 | |
|   " few lines removed from the end
 | |
|   :echo diff(['abc', 'def', 'ghi'], ['abc'], {'output': 'indices'})
 | |
|    [{'from_idx': 1, 'from_count': 2, 'to_idx': 1, 'to_count': 0}]
 | |
| 
 | |
|   " disjointed changes
 | |
|   :echo diff(['ab', 'def', 'ghi', 'jkl'], ['abc', 'def', 'ghi', 'jk'], {'output': 'indices', 'context': 0})
 | |
|    [{'from_idx': 0, 'from_count': 1, 'to_idx': 0, 'to_count': 1},
 | |
|     {'from_idx': 3, 'from_count': 1, 'to_idx': 3, 'to_count': 1}]
 | |
| 
 | |
|   " disjointed changes with context length 1
 | |
|   :echo diff(['ab', 'def', 'ghi', 'jkl'], ['abc', 'def', 'ghi', 'jk'], {'output': 'indices', 'context': 1})
 | |
|    [{'from_idx': 0, 'from_count': 4, 'to_idx': 0, 'to_count': 4}]
 | |
| 
 | |
| <
 | |
| 
 | |
|  vim:tw=78:ts=8:noet:ft=help:norl:
 |