comparison lisp/ediff.el @ 7424:9169ca1bcb95

New version from Kifer.
author Richard M. Stallman <rms@gnu.org>
date Tue, 10 May 1994 00:48:00 +0000
parents 0d0a01a0310c
children 315fb6386b54
comparison
equal deleted inserted replaced
7423:4a5d0d109242 7424:9169ca1bcb95
1 ;;; ediff.el --- a visual interface to diff & patch 1 ;;; ediff.el --- a visual interface to diff & patch
2 ;;; Copyright (C) 1994 Free Software Foundation, Inc. 2 ;;; Copyright (C) 1994 Free Software Foundation, Inc.
3 3
4 ;; Author: Michael Kifer <kifer@cs.sunysb.edu> 4 ;; Author: Michael Kifer <kifer@cs.sunysb.edu>
5 ;; Created: February 2, 1994 5 ;; Created: February 2, 1994
6 ;; Version: 1.31 6 ;; Version: 1.52
7 ;; Keywords: comparing, merging, patching, version control. 7 ;; Keywords: tools
8 8
9 ;; This file is part of GNU Emacs. 9 ;; This file is part of GNU Emacs.
10 10
11 ;; GNU Emacs is free software; you can redistribute it and/or modify 11 ;; GNU Emacs is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by 12 ;; it under the terms of the GNU General Public License as published by
44 ;; Since Ediff lets you copy differences between buffers, you can, in 44 ;; Since Ediff lets you copy differences between buffers, you can, in
45 ;; effect, apply patches selectively (i.e., you can copy a difference 45 ;; effect, apply patches selectively (i.e., you can copy a difference
46 ;; region from file.orig to file, thereby undoing any particular patch that 46 ;; region from file.orig to file, thereby undoing any particular patch that
47 ;; you don't like). 47 ;; you don't like).
48 48
49 ;; This package is based on emerge.el. It uses a few utilities and 49 ;; This package builds upon the ideas borrowed from emerge.el. It is still
50 ;; variables defined there and several other Ediff's functions are 50 ;; using half a dozen of functions defined there. Several other Ediff's
51 ;; adaptations from emerge.el. 51 ;; functions are adaptations from emerge.el. Ediff requires, at least,
52 52 ;; Version 5 of emerge.el. This version comes with standard distributions
53 ;; Ediff is complimentary to Emerge. While Emerge is better at heavy-duty 53 ;; of Emacs and Lemacs. Make sure you don't have some stray old copy of
54 ;; tasks that involve merging of files, Ediff is by far superior 54 ;; Emerge on your load path.
55 ;; for browsing through files compared via diff and for patching files 55
56 ;; with patch. Furthermore, I feel that Ediff is more convenient for 56 ;; Ediff is complimentary to Emerge. While Emerge is primarily intended
57 ;; merging tasks where one of the files is a designated output. This 57 ;; for merging of files, Ediff is by far superior for browsing through
58 ;; situation arises while patching files or when comparing an old version 58 ;; files compared via diff and for patching files with patch.
59 ;; of a file with a newer version (in such cases, it is often desirable to 59 ;; Furthermore, Ediff is more convenient even for merging, when one of the
60 ;; selectively revert some portions of the new file to its old state). 60 ;; files is a designated output. This situation arises while patching
61 61 ;; files or when comparing an old version of a file with a newer version
62 ;; This version of Ediff is much faster than the previous ones and than 62 ;; (in such cases, it is often desirable to selectively revert some
63 ;; Emerge (in Emacs 19.23, Emerge will become much faster as well). 63 ;; portions of the new file to its old state).
64 ;; The difference in startup time is dramatic for large files with many 64
65 ;; differences. 65 ;; Ediff also supports version control via vc.el (in the standard
66 ;; distribution of Emacs 19) and rcs.el. The latter is a package written by
67 ;; Sebastian Kremer <sk@thp.Uni-Koeln.DE>, which is available in
68 ;;
69 ;; ftp.cs.buffalo.edu:pub/Emacs/rcs.tar.Z
70 ;; ftp.uni-koeln.de:/pub/gnu/emacs/rcs.tar.Z
71 ;;
72
66 73
67 ;; Window configuration: 74 ;; Window configuration:
68 ;; ---------------------- 75 ;; ----------------------
69 76
70 ;; By default, Ediff sets things up in one frame, splitting it between a 77 ;; By default, Ediff sets things up in one frame, splitting it between a
87 ;; arranging files A and B to be seen in different frames. Ediff 94 ;; arranging files A and B to be seen in different frames. Ediff
88 ;; respects these arrangements, automatically adapting itself to 95 ;; respects these arrangements, automatically adapting itself to
89 ;; the multi-frame mode. 96 ;; the multi-frame mode.
90 97
91 98
92 ;; A note to heavy-duty users: 99 ;; To those who like to go where noone has gone before:
93 100
94 ;; Ediff lets the user run multiple sessions at once, i.e., you can invoke 101 ;; Ediff lets the user run multiple sessions at once, i.e., you can invoke
95 ;; Ediff on different functions several times in a row, without exiting 102 ;; Ediff on different functions several times in a row, without exiting
96 ;; the previous Ediff sessions. Different sessions may even operate on the 103 ;; the previous Ediff sessions. Different sessions may even operate on the
97 ;; same pair of files. So, in principle, it is possible to do, say, 104 ;; same pair of files. So, in principle, it is possible to do, say,
110 ;; thing should be kept in mind: each time you invoke Ediff on a buffer that 117 ;; thing should be kept in mind: each time you invoke Ediff on a buffer that
111 ;; already participates in another Ediff session, that buffer should not 118 ;; already participates in another Ediff session, that buffer should not
112 ;; have any ASCII Ediff flags in it. (Highlighting with faces is OK.) If 119 ;; have any ASCII Ediff flags in it. (Highlighting with faces is OK.) If
113 ;; flags are not removed, difference overlays won't be set correctly 120 ;; flags are not removed, difference overlays won't be set correctly
114 ;; for the second invocation of Ediff. The simplest way to remove ASCII 121 ;; for the second invocation of Ediff. The simplest way to remove ASCII
115 ;; flags from an Ediff buffer is to switch to that buffer and try to insert 122 ;; flags from an Ediff buffer is to hit `h' and thus switch to highlighting
116 ;; or delete something. If ASCII flags have been inserted by an Ediff 123 ;; with faces (unhighlighting on a dumb terminal).
117 ;; session, Ediff will ignore this first editing operation, but it will
118 ;; remove all flags and notify you that this buffer can now be edited.
119 ;;
120 ;; To rehighlight Ediff buffers, hit 'c' in ediff-control buffer.
121 124
122 125
123 ;;; Remarks: 126 ;;; Remarks:
124 ;; ------- 127 ;; -------
125 128
126 ;; 1. Ediff is unlikely to run under Emacs 18 without some further work. 129 ;; 1. Ediff is heavily dependent on the new features of Emacs 19.
130 ;; It won't run under Emacs 18 at all.
127 ;; 2. If running Lucid Emacs, Ediff requires at least version 19.9. 131 ;; 2. If running Lucid Emacs, Ediff requires at least version 19.9.
128 ;; 3. I didn't test Ediff on Emacs versions older than 19.19. 132 ;; 3. The function vc-ediff requires the vc.el version that comes with
129 ;; 4. The function vc-ediff requires the vc.el version that comes with
130 ;; Emacs 19.22. 133 ;; Emacs 19.22.
131 134
132 135
133 ;;; Installation and use: 136 ;;; Installation and use:
134 ;; -------------------- 137 ;; --------------------
137 ;; 140 ;;
138 ;; ediff-buffers - compare buffers 141 ;; ediff-buffers - compare buffers
139 ;; ediff (alias for ediff-files) 142 ;; ediff (alias for ediff-files)
140 ;; ediff-files - compare files 143 ;; ediff-files - compare files
141 ;; ediff-patch-file - patch file then compare 144 ;; ediff-patch-file - patch file then compare
142 ;; epatch (alias for ediff-patch-file) 145 ;; epatch - alias for ediff-patch-file
143 ;; ediff-patch-buffer - patch buffer then compare 146 ;; ediff-patch-buffer - patch buffer then compare
147 ;; epatch-buffer - alias for ediff-patch-buffer
144 ;; vc-ediff - compare buffer & version 148 ;; vc-ediff - compare buffer & version
145 ;; using vc.el package 149 ;; using vc.el package
146 ;; (Emacs 19.22 and up). 150 ;; (Emacs 19.22 and up).
147 ;; rcs-ediff - same using rcs.el; rcs.el 151 ;; rcs-ediff - same using rcs.el; rcs.el
148 ;; is not part of the 152 ;; is not part of the
154 ;; To use Ediff, put this in your .emacs file: 158 ;; To use Ediff, put this in your .emacs file:
155 ;; 159 ;;
156 ;; (autoload 'ediff-buffers "ediff" "Visual interface to diff" t) 160 ;; (autoload 'ediff-buffers "ediff" "Visual interface to diff" t)
157 ;; (autoload 'ediff "ediff" "Visual interface to diff" t) 161 ;; (autoload 'ediff "ediff" "Visual interface to diff" t)
158 ;; (autoload 'ediff-files "ediff" "Visual interface to diff" t) 162 ;; (autoload 'ediff-files "ediff" "Visual interface to diff" t)
159 ;; (autoload 'ediff-files-remote "ediff" "Visual interface to diff")
160 ;; (autoload 'epatch "ediff" "Visual interface to patch" t) 163 ;; (autoload 'epatch "ediff" "Visual interface to patch" t)
161 ;; (autoload 'ediff-patch-file "ediff" "Visual interface to patch" t) 164 ;; (autoload 'ediff-patch-file "ediff" "Visual interface to patch" t)
162 ;; (autoload 'ediff-patch-buffer "ediff" "Visual interface to patch" t) 165 ;; (autoload 'ediff-patch-buffer "ediff" "Visual interface to patch" t)
166 ;; (autoload 'epatch-buffer "ediff" "Visual interface to patch" t)
163 ;; (autoload 'vc-ediff "ediff" 167 ;; (autoload 'vc-ediff "ediff"
164 ;; "Interface to diff & version control via vc.el" t) 168 ;; "Interface to diff & version control via vc.el" t)
165 ;; (autoload 'rcs-ediff "ediff" 169 ;; (autoload 'rcs-ediff "ediff"
166 ;; "Interface to diff & version control via rcs.el" t) 170 ;; "Interface to diff & version control via rcs.el" t)
167 ;; 171 ;;
178 ;;; Compilation 182 ;;; Compilation
179 ;; ----------- 183 ;; -----------
180 ;; 184 ;;
181 ;; When you byte-compile Ediff, you will get some warnings about functions 185 ;; When you byte-compile Ediff, you will get some warnings about functions
182 ;; being undefined. These can be safely ignored. 186 ;; being undefined. These can be safely ignored.
187 ;;
188 ;; Important:
189 ;; =========
190 ;;
191 ;; If you are using advice.el (directly or indirectly, via one of the
192 ;; other packages), Ediff may not compile properly. In this case, you
193 ;; should do:
194 ;;
195 ;; M-x ad-deactivate-all RET
196 ;;
197 ;; M-x byte-compile-file RET ediff.el RET
198 ;;
199 ;; M-x ad-activate-all RET
200 ;;
201 ;; This precaution will not be needed starting with GNU Emacs 19.23 and
202 ;; Lucid Emacs 19.10, due to fixing a bug in advice.el.
183 203
184 ;;; Customization: 204 ;;; Customization:
185 ;; ------------- 205 ;; -------------
186 206
207 ;; Hooks:
208 ;; -----
187 ;; If you don't like the default setting, you can change it through the 209 ;; If you don't like the default setting, you can change it through the
188 ;; various variables and hooks. In particular, the following hooks are 210 ;; various variables and hooks. In particular, the following hooks are
189 ;; available: 211 ;; available:
190 212
191 ;; ediff-load-hooks 213 ;; ediff-load-hooks
206 ;; *ediff-control* buffers. Take a look at ediff-default-suspend-hook and 228 ;; *ediff-control* buffers. Take a look at ediff-default-suspend-hook and
207 ;; ediff-default-quit-hook to see what's involved. 229 ;; ediff-default-quit-hook to see what's involved.
208 ;; The hooks in ediff-prepare-buffer-hooks are executed for each Ediff buffer 230 ;; The hooks in ediff-prepare-buffer-hooks are executed for each Ediff buffer
209 ;; (A and B) right after these buffers are arranged. 231 ;; (A and B) right after these buffers are arranged.
210 ;; 232 ;;
233 ;; Highlighting of difference regions
234 ;; ----------------------------------
211 ;; The second group of Ediff variables that could be changed, if you so 235 ;; The second group of Ediff variables that could be changed, if you so
212 ;; wish, is: 236 ;; wish, is:
213 ;; 237 ;;
214 ;; ediff-before-flag-eol 238 ;; ediff-before-flag-eol
215 ;; ediff-after-flag-eol 239 ;; ediff-after-flag-eol
216 ;; ediff-before-flag-mol 240 ;; ediff-before-flag-mol
217 ;; ediff-after-flag-mol 241 ;; ediff-after-flag-mol
218 ;; 242 ;;
219 ;; ediff-current-diff-face-A 243 ;; ediff-current-diff-face-A
220 ;; ediff-current-diff-face-B 244 ;; ediff-current-diff-face-B
245 ;; ediff-fine-diff-face-A
246 ;; ediff-fine-diff-face-B
221 ;; ediff-even-diff-face-A 247 ;; ediff-even-diff-face-A
222 ;; ediff-even-diff-face-B 248 ;; ediff-even-diff-face-B
223 ;; ediff-odd-diff-face-A 249 ;; ediff-odd-diff-face-A
224 ;; ediff-odd-diff-face-B 250 ;; ediff-odd-diff-face-B
225 ; 251 ;
229 ;; middle of a line. 255 ;; middle of a line.
230 256
231 ;; The rest are the faces used to highlight text on X displays. On X 257 ;; The rest are the faces used to highlight text on X displays. On X
232 ;; displays, Ediff uses ediff-current-diff-face-A and 258 ;; displays, Ediff uses ediff-current-diff-face-A and
233 ;; ediff-current-diff-face-B to highlight the current difference regions. 259 ;; ediff-current-diff-face-B to highlight the current difference regions.
260 ;; The faces ediff-fine-diff-face-A and ediff-fine-diff-face-B
261 ;; are used to show the fine differences between the current differences
262 ;; regions in buffer A and B.
234 ;; Other (non-current) difference regions are displayed in alternating 263 ;; Other (non-current) difference regions are displayed in alternating
235 ;; faces: ediff-even/odd-diff-face-A/B. The odd and the even 264 ;; faces: ediff-even/odd-diff-face-A/B. The odd and the even
236 ;; faces are actually identical on monochrome displays, because it is 265 ;; faces are actually identical on monochrome displays, because it is
237 ;; rather poor in what you can do on such a display. So, I chose to use 266 ;; rather poor in what you can do on such a display. So, I chose to use
238 ;; italics to highlight other differences. Any ideas would be welcome. 267 ;; italics to highlight other differences. Any ideas would be welcome. (In
239 ;; 268 ;; Lucid Emacs, the faces are different because it supports pixmaps.)
240 ;; There are two ways to change the default setting for highlighting faces: 269 ;; There are two ways to change the default setting for highlighting faces:
241 ;; either change the variables, as in 270 ;; either change the variables, as in
242 ;; 271 ;;
243 ;; (setq ediff-current-diff-face-A (internal-get-face 'bold-italic)) 272 ;; (setq ediff-current-diff-face-A (internal-get-face 'bold-italic))
244 ;; 273 ;;
252 ;; (make-face-italic ediff-current-diff-face-B)))) 281 ;; (make-face-italic ediff-current-diff-face-B))))
253 ;; 282 ;;
254 ;; You may also want to take a look at how the above faces are defined in 283 ;; You may also want to take a look at how the above faces are defined in
255 ;; Ediff. 284 ;; Ediff.
256 ;; 285 ;;
257 ;; The last pair of variables in this group, 286 ;; The last group of variables in this group,
258 ;; 287 ;;
259 ;; ediff-want-faces 288 ;; ediff-want-faces
260 ;; ediff-highlight-selected-only 289 ;; ediff-highlight-all-diffs
290 ;; ediff-want-default-menus
261 ;; 291 ;;
262 ;; indicate whether---on a window system---you want differences to be 292 ;; indicate whether---on a window system---you want differences to be
263 ;; marked using ASCII strings (like on a dumb terminal) or using colors and 293 ;; marked using ASCII strings (like on a dumb terminal) or using colors and
264 ;; highlighting. If ediff-want-faces is t, then highlighting with faces is 294 ;; highlighting. If ediff-want-faces is t, then highlighting with faces is
265 ;; used. Normally, Ediff highlights all differences, but the selected 295 ;; used. Normally, Ediff highlights all differences, but the selected
266 ;; difference is highlighted more visibly. If you prefer that unselected 296 ;; difference is highlighted more visibly. You can cycle through various
267 ;; differences won't be highlighted, you can set 297 ;; modes of highlighting by hitting `h'. By default, Ediff starts in the
268 ;; ediff-highlight-selected-only to t. 298 ;; mode where all difference regions are highlighted. If you prefer to
299 ;; start in the mode where unselected differences are not highlighted, you
300 ;; should set ediff-highlight-all-diffs to nil.
301 ;; You will still be able to turn on highlighting of all differences by
302 ;; hitting `h'.
303 ;; The variable `ediff-want-default-menus', if true, will cause Ediff to
304 ;; set up a pair of menues in the menu bar, so you can invoke it from there.
305 ;; If you don't like the look of the default menus, set this variable to
306 ;; nil and design your own menus.
269 ;; 307 ;;
270 ;; If you plan on changing these variables, they must be set 308 ;; If you plan on changing these variables, they must be set
271 ;; BEFORE ediff.el is loaded. 309 ;; BEFORE ediff.el is loaded.
272 ;; 310 ;;
273 ;; Note: Ediff lets you switch between the two types of highlighting. That 311 ;; Note: Ediff lets you switch between the two types of highlighting. That
274 ;; is you can switch, interactively, from highlighting using faces to 312 ;; is you can switch, interactively, from highlighting using faces to
275 ;; highlighting using ASCII flags, and back. Of course, toggling has 313 ;; highlighting using ASCII flags, and back. Of course, toggling has
276 ;; effect only on a window system. On a dumb terminal or in an xterm 314 ;; effect only on a window system. On a dumb terminal or in an xterm
277 ;; window, the only available option is highlighting with ASCII flags. 315 ;; window, the only available option is highlighting with ASCII flags.
278 ;; 316 ;;
279 ;; The third group of variables controls miscellaneous functions: 317 ;; Refining difference regions
318 ;; ---------------------------
319 ;; There are also variables that control the way fine differences are
320 ;; highlighted. This feature lets the user highlight the exact words that
321 ;; make the difference regions in buffer A and B different. This process
322 ;; ignores spaces, tabs, and newlines.
323 ;;
324 ;; ediff-auto-refine
325 ;; ediff-auto-refine-limit
326 ;;
327 ;; By default, `ediff-auto-refine' is `'on', which means that fine differences
328 ;; within regions will be highlighted automatically. On a slow system, this
329 ;; feature may be undesirable. In any case, the user can always toggle
330 ;; auto-refining on/off/nix by hitting `@'. When auto-refining is off, fine
331 ;; differences will be shown only for regions for which these differences
332 ;; have been computed and saved before. If auto-refining is nixed, fine
333 ;; differences will not be shown at all. Hitting `*' will compute and
334 ;; display fine differences for the current difference region regardless of
335 ;; whether auto-refining is on, off, or nixed.
336 ;; If auto-refining is on, the variable `ediff-auto-refine-limit' limits
337 ;; the size of the regions to be auto-refined. This variable guards against
338 ;; possible slow-down that may be caused by an extraordinary large
339 ;; difference region. However, the user can always force refining by
340 ;; hitting `*'.
341 ;;
342 ;; ediff-fine-diff-program
343 ;; ediff-fine-diff-options
344 ;; ediff-wordify-function
345 ;;
346 ;; These variables let the user control how fine differences are computed.
347 ;; `ediff-fine-diff-program' is diff, by default. However, you can use
348 ;; any function as long as it produces output consistent with diff.
349 ;; `ediff-wordify-function' is a lisp function that determines how the
350 ;; current difference region is split into words. (Fine diferences are
351 ;; computed by first splitting the current difference region into words and
352 ;; then passing this along to `ediff-fine-diff-program'. For the default
353 ;; wordify function, `ediff-wordify', a word is a string consisting of
354 ;; letters, `-', or `_', or a string consisting of symbols that are neither
355 ;; space, nor a letter.)
356 ;;
357 ;; Patch and diff programs
358 ;; -----------------------
359 ;; The next group of variables determines the programs to be used for
360 ;; applying patches and for computing the main difference regions (not the
361 ;; fine difference regions):
280 ;; 362 ;;
281 ;; ediff-patch-program 363 ;; ediff-patch-program
282 ;; ediff-patch-options 364 ;; ediff-patch-options
283 ;; ediff-diff-program 365 ;; ediff-diff-program
284 ;; ediff-diff-options 366 ;; ediff-diff-options
293 ;; has several other useful options (type 'man diff' to find out). 375 ;; has several other useful options (type 'man diff' to find out).
294 ;; 376 ;;
295 ;; The output from diff is found in *ediff-diff* buffer. However, this 377 ;; The output from diff is found in *ediff-diff* buffer. However, this
296 ;; makes sense only if you also intend to use Ediff to browse through the 378 ;; makes sense only if you also intend to use Ediff to browse through the
297 ;; diff'ed files before sending the patch. This is because diff.el is much 379 ;; diff'ed files before sending the patch. This is because diff.el is much
298 ;; faster in yielding the output of diff ;; (Ediff is a big gun, if used 380 ;; faster in yielding the output of diff (Ediff is a big gun, if used
299 ;; for this simple purpose). 381 ;; for this simple purpose).
300 ;; 382 ;;
383 ;; Miscellaneous
384 ;; -------------
301 ;; The last set of variables that can be modified is 385 ;; The last set of variables that can be modified is
302 ;; 386 ;;
303 ;; ediff-split-window-function 387 ;; ediff-split-window-function
304 ;; ediff-use-last-dir 388 ;; ediff-use-last-dir
305 ;; ediff-nix-help-in-control-buffer 389 ;; ediff-no-help-in-control-buffer
306 ;; 390 ;;
307 ;; ediff-split-window-function controls the way you want the window be 391 ;; ediff-split-window-function controls the way you want the window be
308 ;; split between file-A and file-B. It defaults to vertical split, but you 392 ;; split between file-A and file-B. It defaults to vertical split, but you
309 ;; can set it to 'split-window-horizontally, if you want. Ediff lets you 393 ;; can set it to 'split-window-horizontally, if you want. Ediff lets you
310 ;; toggle the way windows are split, so you can try different settings 394 ;; toggle the way windows are split, so you can try different settings
325 ;; default directory when it prompts the user for files to compare. If nil, 409 ;; default directory when it prompts the user for files to compare. If nil,
326 ;; Ediff will use the default directory of the current buffer when it 410 ;; Ediff will use the default directory of the current buffer when it
327 ;; prompts the user for file names. Otherwise, it will use the 411 ;; prompts the user for file names. Otherwise, it will use the
328 ;; directories it had previously used for file-A and file-B. 412 ;; directories it had previously used for file-A and file-B.
329 ;; 413 ;;
330 ;; The ediff-nix-help-in-control-buffer, if set to t, makes C-h behave like 414 ;; The ediff-no-help-in-control-buffer, if set to t, makes C-h behave like
331 ;; the DEL key, i.e., it will move you back to the previous difference 415 ;; the DEL key, i.e., it will move you back to the previous difference
332 ;; rather than invoking help. This is useful when, in an xterm window or on 416 ;; rather than invoking help. This is useful when, in an xterm window or on
333 ;; a dumb terminal, the Backspace key is bound to C-h and is positioned 417 ;; a dumb terminal, the Backspace key is bound to C-h and is positioned
334 ;; more conveniently than the DEL key. 418 ;; more conveniently than the DEL key.
335 419
340 ;; All Ediff commands are displayed in a help window, unless you hit '?' to 424 ;; All Ediff commands are displayed in a help window, unless you hit '?' to
341 ;; shrink it to just one line. You can redisplay the help window by hitting 425 ;; shrink it to just one line. You can redisplay the help window by hitting
342 ;; '?' again. 426 ;; '?' again.
343 ;; 427 ;;
344 ;; Many Ediff commands take numeric prefix arguments. For instance, if you 428 ;; Many Ediff commands take numeric prefix arguments. For instance, if you
345 ;; hit a number, n, and then 'j' (ediff-jump-to-difference), Ediff will 429 ;; hit a number, N, and then 'j' (ediff-jump-to-difference), Ediff will
346 ;; take you to Nth difference. Hitting a number, n, and then 'ab' 430 ;; take you to Nth difference. Hitting a number, N, and then 'ab'
347 ;; (ediff-diff-to-diff) will copy Nth difference from buffer A to buffer B. 431 ;; (ediff-diff-to-diff) will copy Nth difference from buffer A to buffer B.
348 ;; Hitting 'ba' does copying in the other direction. 432 ;; Hitting 'ba' does copying in the other direction.
349 ;; Likewise, a number, n, followed by 'ra' will restore the Nth difference 433 ;; Likewise, a number, N, followed by 'ra' will restore the Nth difference
350 ;; region in buffer A (if it was previously saved as a result of copying 434 ;; region in buffer A (if it was previously saved as a result of copying
351 ;; from B to A). 435 ;; from B to A).
352 ;; 436 ;;
353 ;; Without the prefix argument, all commands operate on the current 437 ;; Without the prefix argument, all commands operate on the current
354 ;; difference region. 438 ;; difference region.
386 ;; ---- 470 ;; ----
387 471
388 ;; 1. The undo command doesn't restore deleted regions well. That is, if 472 ;; 1. The undo command doesn't restore deleted regions well. That is, if
389 ;; you delete all characters in a difference region and then invoke 473 ;; you delete all characters in a difference region and then invoke
390 ;; `undo', the reinserted text will most likely be reinserted outside of 474 ;; `undo', the reinserted text will most likely be reinserted outside of
391 ;; what Ediff thinks is the current difference region. 475 ;; what Ediff thinks is the current difference region. (This problem
392 476 ;; doesn't seem to exist with Lucid Emacs.)
393 ;; 2. You may get an error if your colormap doesn't have the colors requested 477 ;;
394 ;; by Ediff (on a color display). If this happens, you should create your 478 ;; If at any point you feel that difference regions are no longer correct,
395 ;; own faces using available colors. See `ediff-current-diff-face-A', 479 ;; you can hit '!' to recompute the differences.
396 ;; ediff-current-diff-face-B, ediff-even-diff-face-A, ediff-even-diff-face-B, 480
397 ;; ediff-odd-diff-face-A, and ediff-odd-diff-face-B to get an idea on how 481 ;; 2. Emacs 19.xx, where xx < 23, has several bugs related to overlays and
398 ;; to do this. 482 ;; faces. Somethimes, these may cause highlighting of the refinements or
483 ;; of the unselected differences to disappear. Hitting `!' will bring them
484 ;; back. In version 19.23, these problems no longer occur.
485
486 ;; 3. On a monochrome display, the repertoire of faces with which to
487 ;; highlight fine differences is limited. By default, Ediff is using
488 ;; underlining. However, if the region is already underlied by some other
489 ;; overlays, there is no simple way to temporarily remove that residual
490 ;; underlining. This problem occurs when a buffer is highlighted with
491 ;; hilit19.el or font-lock.el packages. If this residual highlighting gets
492 ;; in the way, you can do the following. Both font-lock.el and hilit19.el
493 ;; provide commands for unhighlighting buffers. You can either place these
494 ;; commands in `ediff-prepare-buffer-hooks' (which will unhighlight every
495 ;; buffer used by Ediff) or you can execute them interactively, at any time
496 ;; and on any buffer.
497
498 ;; 4. In Lucid Emacs (statically linked with Motif libraries), emerge.el
499 ;; and hence ediff.el won't start, unless you set (setq scrollbar-width 0).
500 ;; This is a Motif-related bug, I was told.
399 501
400 502
401 ;;; Change Log: 503 ;;; Change Log:
402 ;; ---------- 504 ;; ----------
403 505
580 682
581 ;; Fixed bugs related to writing buffers A and B. 683 ;; Fixed bugs related to writing buffers A and B.
582 ;; Added commands 'ga', 'gb' to jump directly to the closest diff in 684 ;; Added commands 'ga', 'gb' to jump directly to the closest diff in
583 ;; buffer A and B, respectively. 685 ;; buffer A and B, respectively.
584 686
687 ;; Fri April 11, 1994
688
689 ;; Added `ediff-recompute-diffs', a function that lets the user recompute
690 ;; difference regions after extensive editing done to buffers A and B
691 ;; (bound to `!').
692
693 ;; Wed April 13, 1994
694
695 ;; Added the new feature: refining the current difference region.
696 ;; This would highlight the precise differences between the regions in
697 ;; buffer A and B. (A way to implement this was suggested by Boris
698 ;; Goldowsky <boris@cs.rochester.edu>.)
699 ;;
700 ;; Fixed Ediff to be immune to several different versions of rcs.el
701 ;; that are currently in distribution.
702
703 ;; Thu April 14, 1994
704
705 ;; Ediff now respects X resources for the faces it uses. It no longer
706 ;; barks when the colormap has no colors it is using; or when face
707 ;; fonts can't be italicized, etc.
708
709 ;; Fri April 15, 1994
710
711 ;; Changed `ediff-setup-windows' to minimize the need to delete and
712 ;; create windows. Now jumps faster from diff to diff.
713
714 ;; Sat April 16, 1994
715
716 ;; Added Ediff to the File menu on the menu bar (FSF's version).
717
718 ;; Mon April 18, 1994
719
720 ;; Fixed to work with OS/2's PM-Emacs.
721
722 ;; Thu April 21, 1994
723
724 ;; Lemacs' menus added (thanks to Alastair Burt for the help).
725
726 ;; Wed April 28, 1994
727
728 ;; Fixed ediff-leave-window-config (thanks to Norbert Kiesel
729 ;; <norbert@i3.informatik.rwth-aachen.de>), ediff-shell and
730 ;; ediff-protect-metachars (thanks to Richard Stanton
731 ;; <stanton@haas.berkeley.edu>). Made access to difference
732 ;; overlays structure-independent, making it less bug-prone.
733 ;; Patched ediff-read-file-name to work more intuitively with directory
734 ;; names (thanks to Kevin Broadey <KevinB@bartley.demon.co.uk>).
735
736 ;; Mon May 2, 1994
737
738 ;; Added `ediff-frame-has-menubar' to guard against the possibility that
739 ;; the current frame has no menu bar.
740
741 ;; Fri May 6, 1994
742
743 ;; Fixed buglet in vc-ediff (thanks to Ray Nickson <nickson@cs.uq.oz.au>).
744
745
746 ;;; Acknowledgements:
747
748 ;; Special thanks to Alastair Burt <burt@dfki.uni-kl.de>, Kevin Esler
749 ;; <esler@ch.hp.com>, Kevin Broadey <KevinB@bartley.demon.co.uk>,
750 ;; Eric Freudenthal <freudent@jan.ultra.nyu.edu>, Job Ganzevoort
751 ;; <Job.Ganzevoort@cwi.nl>, Boris Goldowsky <boris@cs.rochester.edu>,
752 ;; Allan Gottlieb <gottlieb@allan.ultra.nyu.edu>, Xiaoli Huang
753 ;; <hxl@epic.com>, irvine@lks.csi.com, jaffe@chipmunk.cita.utoronto.ca,
754 ;; David Karr, <dkarr@nmo.gtegsc.com>, Norbert Kiesel
755 ;; <norbert@i3.informatik.rwth-aachen.de>, Heinz Knutzen
756 ;; <hk@informatik.uni-kiel.d400.de>, Martin Maechler
757 ;; <maechler@stat.math.ethz.ch>, Richard Mlynarik <mly@adoc.xerox.com>,
758 ;; Ray Nickson <nickson@cs.uq.oz.au>, Andy Scott <ascott@pcocd2.intel.com>,
759 ;; Richard Stanton <stanton@haas.berkeley.edu>, for contributing ideas,
760 ;; patches and bug reports.
761 ;;
762 ;; Thanks also to many others who felt obliged to drop a thanks note.
763
764
585 765
586 ;;; Code: 766 ;;; Code:
587 767
588 (require 'emerge) ;; Ediff is based on emerge 768 (require 'emerge) ;; Ediff uses some functions defined in emerge.el
589 769
590 770
591 ;;; Macros 771 ;;; Macros
592 (defmacro ediff-if-lucid () 772 (defmacro ediff-if-lucid ()
593 (` (string-match "Lucid" emacs-version))) 773 (` (string-match "Lucid" emacs-version)))
774
594 (defmacro ediff-odd-p (arg) 775 (defmacro ediff-odd-p (arg)
595 (` (eq (logand (, arg) 1) 1))) 776 (` (eq (logand (, arg) 1) 1)))
777
596 (defmacro ediff-buffer-live-p (buf) 778 (defmacro ediff-buffer-live-p (buf)
597 (` (and (, buf) (get-buffer (, buf)) (buffer-name (get-buffer (, buf)))))) 779 (` (and (, buf) (get-buffer (, buf)) (buffer-name (get-buffer (, buf))))))
598 780
781 (defmacro ediff-get-buffer (arg)
782 (` (cond ((eq (, arg) 'A) ediff-A-buffer)
783 ((eq (, arg) 'B) ediff-B-buffer)
784 )
785 ))
786
787 (defmacro ediff-char-to-buftype (arg)
788 (` (cond ((eq (, arg) ?a) 'A)
789 ((eq (, arg) ?b) 'B)
790 )
791 ))
792
793 (defmacro ediff-get-difference (n)
794 (` (aref ediff-difference-vector (, n))))
795
796 (defmacro ediff-get-diff-overlay-from-vector (vec buf-type)
797 (` (aref (, vec)
798 (cond ((eq (, buf-type) 'A) 0)
799 ((eq (, buf-type) 'B) 1)
800 )
801 )))
802
803 (defmacro ediff-get-diff-overlay (n buf-type)
804 (` (ediff-get-diff-overlay-from-vector
805 (ediff-get-difference (, n))
806 (, buf-type))))
807
808 (defmacro ediff-get-fine-diff-vector-from-vec (current-diff-vec)
809 (` (aref (, current-diff-vec) 2)))
810
811 (defmacro ediff-set-fine-diff-vector (n fine-vec)
812 (` (aset (ediff-get-difference (, n)) 2 (, fine-vec))))
813
814 (defmacro ediff-get-fine-diff-vector (n)
815 (` (ediff-get-fine-diff-vector-from-vec (ediff-get-difference (, n)))))
816
817 (defmacro ediff-frame-has-menubar ()
818 (if (ediff-if-lucid)
819 current-menubar
820 (< 0 (cdr (assq 'menu-bar-lines (frame-parameters (selected-frame)))))
821 ))
822
823
824 ;;; Functions
599 825
600 (defun ediff-mode () 826 (defun ediff-mode ()
601 "Ediff mode is used by the Ediff file-difference package. 827 "Ediff mode is used by the Ediff file-difference package.
602 It is entered only through one of the following commands: 828 It is entered only through one of the following commands:
603 `ediff' 829 `ediff'
604 `ediff-files' 830 `ediff-files'
605 `ediff-buffers' 831 `ediff-buffers'
606 `epatch' 832 `epatch'
607 `ediff-patch-file' 833 `ediff-patch-file'
608 `ediff-patch-buffer' 834 `ediff-patch-buffer'
835 `epatch-buffer'
609 `vc-ediff' 836 `vc-ediff'
610 `rcs-ediff' 837 `rcs-ediff'
611 or through a non-interactive Emacs Lisp function 838 or through a non-interactive Emacs Lisp function
612 `ediff-files-remote' 839 `ediff-files-remote'
613 840
616 (interactive) 843 (interactive)
617 (kill-all-local-variables) 844 (kill-all-local-variables)
618 (setq major-mode 'ediff-mode) 845 (setq major-mode 'ediff-mode)
619 (setq mode-name "Ediff")) 846 (setq mode-name "Ediff"))
620 847
621 (defvar ediff-version "1.31" 848 (defvar ediff-version "1.52"
622 "The current version of Ediff.") 849 "The current version of Ediff.")
623 850
624 (defun ediff-version () 851 (defun ediff-version ()
625 "Return string describing the version of Ediff. 852 "Return string describing the version of Ediff.
626 When called interactively, displays the version." 853 When called interactively, displays the version."
631 858
632 859
633 ;; Hook variables 860 ;; Hook variables
634 861
635 (defvar ediff-before-setup-windows-hooks nil 862 (defvar ediff-before-setup-windows-hooks nil
636 "* Hooks to run before Ediff sets its own window config. 863 "*Hooks to run before Ediff sets its own window config.
637 This can be used to save the previous window config, which can be 864 This can be used to save the previous window config, which can be restored
638 restored by `ediff-quit' or `ediff-suspend'.") 865 on ediff-quit or ediff-suspend.")
639
640 (defvar ediff-startup-hooks nil 866 (defvar ediff-startup-hooks nil
641 "*Hooks to run in the control buffer after Ediff has been set up.") 867 "*Hooks to run in the control buffer after Ediff has been set up.")
642 (defvar ediff-select-hooks nil 868 (defvar ediff-select-hooks nil
643 "*Hooks to run after a difference has been selected.") 869 "*Hooks to run after a difference has been selected.")
644 (defvar ediff-unselect-hooks nil 870 (defvar ediff-unselect-hooks nil
646 (defvar ediff-prepare-buffer-hooks nil 872 (defvar ediff-prepare-buffer-hooks nil
647 "*Hooks called after buffers A and B are set up.") 873 "*Hooks called after buffers A and B are set up.")
648 (defvar ediff-load-hooks nil 874 (defvar ediff-load-hooks nil
649 "*Hook run after Ediff is loaded. Can be used to change defaults.") 875 "*Hook run after Ediff is loaded. Can be used to change defaults.")
650 876
651 (defvar ediff-suspend-hooks 'ediff-default-suspend-hook 877 (defvar ediff-suspend-hooks (list 'ediff-default-suspend-hook)
652 "*Hooks to run in the Ediff control buffer when Ediff is suspended.") 878 "*Hooks to run in the Ediff control buffer when Ediff is suspended.")
653 (defvar ediff-quit-hooks 'ediff-default-quit-hook 879 (defvar ediff-quit-hooks (list 'ediff-default-quit-hook)
654 "*Hooks to run in the Ediff control buffer after finishing Ediff.") 880 "*Hooks to run in the Ediff control buffer after finishing Ediff.")
655 881
656 (make-variable-buffer-local 'local-write-file-hooks) 882 (make-variable-buffer-local 'local-write-file-hooks)
657 (make-variable-buffer-local 'before-change-function) 883 (make-variable-buffer-local 'before-change-function)
658 884
659 ;; Help messages 885 ;; Help messages
660 886
661 (defconst ediff-help-message-long 887 (defconst ediff-help-message-long
662 "p,DEL - prev diff c - recenter ab - diff A to B l - line numbers 888 "p,DEL - prev diff v/V - scroll up/dn * - refine diff ! - recomp diffs
663 n,SPC - next diff v/V - scroll up/dn ba - diff B to A f - file names 889 n,SPC - next diff </> - scroll lt/rt ab - diff A to B l - line numbers
664 j - jump to diff </> - scroll lt/rt ra - restore A z - suspend Ediff 890 j - jump to diff s - toggle split ba - diff B to A f - file names
665 ga - goto pt in A s - toggle split rb - restore B q - quit Ediff 891 ga/gb - goto pt in A/B h - toggle hilit ra - restore A z - suspend Ediff
666 gb - goto pt in B h - toggle hilit 892 c - recenter @ - toggle refine rb - restore B q - quit Ediff
667 wa/wb - save buf A/B A/B - toggle read-only buf A/B ? - toggle help") 893 wa/wb - save buf A/B A/B - toggle read-only in buffers A/B ? - toggle help")
668 894
669 (defconst ediff-help-message-short 895 (defconst ediff-help-message-short
670 " ? - toggle help window") 896 " ? - toggle help window")
671 897
672 (defvar ediff-help-message ediff-help-message-long 898 (defvar ediff-help-message ediff-help-message-long
673 "*The actual help message.") 899 "*The actual help message.")
674 900
675 901 ;; diff stuff.
676 (defvar ediff-diff-program "diff" 902 (defvar ediff-diff-program "diff"
677 "*Name of the program that compares two files.") 903 "*Name of the program that compares two files.")
678 (defvar ediff-diff-options "" 904 (defvar ediff-diff-options ""
679 "*Options to pass to `ediff-diff-program'.") 905 "*Options to pass to `ediff-diff-program'.")
680 906
907 ;; Find diff stuff.
908 (defvar ediff-wordify-function 'ediff-wordify
909 "*Function to call to split current diff region into separate words.")
910
911 (defvar ediff-fine-diff-program "diff"
912 "*Name of the program that compares the current diff regions for fine differences.
913
914 This program should produce output in the format of diff. One could
915 possibly use `spiff' here if appropriate options are set.")
916
917 (defvar ediff-fine-diff-options ""
918 "*Options to pass to `ediff-fine-diff-program'.")
919
920 (defvar ediff-whitespace " \n\t\j"
921 "*White space. Used to split strings into words.")
922
923 (defvar ediff-word-1 "a-zA-Z---_`'.?!:"
924 "*Characters constituting type 1 words.
925
926 Ediff is using a very simple schema for splitting text into words, which is
927 used to determine fine differences between regions. There are two types of
928 words. One consists entirely out of characters in `ediff-word-1' and
929 another out of characters matching `ediff-word-1'.")
930
931 (defvar ediff-word-2 "^a-zA-Z---_`'.?!: \t\n\j"
932 "*Characters matching this regexp constitute words of type 2.
933 See `ediff-word-1' for more details.")
934
681 935
682 ;; Support for patches 936 ;; Support for patches
683 937
684 (defvar ediff-patch-program "patch" 938 (defvar ediff-patch-program "patch"
685 "*Name of the program that applies patches.") 939 "*Name of the program that applies patches.")
686 (defvar ediff-patch-options "" 940 (defvar ediff-patch-options ""
687 "*Options to pass to ediff-patch-program.") 941 "*Options to pass to ediff-patch-program.")
688 942
689 (defvar ediff-shell "sh" 943 (defvar ediff-shell (cond ((eq system-type 'emx) "cmd") ;; OS/2
690 "*The shell used to run diff and patch. 944 (t "sh")) ;; unix
691 If user's .profile or .cshrc files are set up correctly, any shell will do. 945 "*The shell used to run diff and patch. If user's .profile or
692 However, some people set `$prompt' or other things incorrectly, which 946 .cshrc files are set up correctly, any shell will do. However, some people
693 leads to undesirable output messages. These may cause Ediff to fail. 947 set $prompt or other things incorrectly, which leads to undesirable output
694 In such a case, set `ediff-shell' to a shell that you are not using or, 948 messages. These may cause Ediff to fail. In such a case, set ediff-shell
695 better, fix your shell's startup file.") 949 to a shell that you are not using or, better, fix your shell's startup file.")
696 950
697 (defvar ediff-diff-ok-lines-regexp 951 (defvar ediff-diff-ok-lines-regexp
698 "^\\([0-9,]+[acd][0-9,]+$\\|[<>] \\|---\\|Warning:\\)" 952 "^\\([0-9,]+[acd][0-9,]+$\\|[<>] \\|---\\|Warning:\\)"
699 "*Regexp that matches normal output lines from `ediff-diff-program'. 953 "*Regexp that matches normal output lines from `ediff-diff-program'.
700 This is mostly lifted from Emerge, except that Ediff also considers the 954 This is mostly lifted from Emerge, except that Ediff also considers the
701 'Missing newline' message to be 'normal output.' 955 'Missing newline' message to be 'normal output.'
702 Lines that do not match are assumed to be error messages.") 956 Lines that do not match are assumed to be error messages.")
703 957
958 (defvar ediff-fine-diff-ok-lines-regexp
959 "^\\([0-9,]+[acd][0-9,]+$\\|[<>] \\|---\\|Warning:\\)"
960 "*Regexp that matches normal output lines from `ediff-fine-diff-program'.
961 This is mostly lifted from Emerge, except that Ediff also considers the
962 'Missing newline' message to be 'normal output.'
963 Lines that do not match are assumed to be error messages.")
964
704 (defvar ediff-match-diff-line (let ((x "\\([0-9]+\\)\\(\\|,\\([0-9]+\\)\\)")) 965 (defvar ediff-match-diff-line (let ((x "\\([0-9]+\\)\\(\\|,\\([0-9]+\\)\\)"))
705 (concat "^" x "\\([acd]\\)" x "$")) 966 (concat "^" x "\\([acd]\\)" x "$"))
706 "*Pattern to match lines produced by diff that describe differences.") 967 "*Pattern to match lines produced by diff that describe differences.")
707 968
708 (defvar ediff-patch-buf nil 969 (defvar ediff-patch-buf nil
712 973
713 974
714 ;; Copying diffs betw buffers. 975 ;; Copying diffs betw buffers.
715 976
716 (emerge-defvar-local ediff-killed-diffs-alist nil 977 (emerge-defvar-local ediff-killed-diffs-alist nil
717 "A list of killed diffs. 978 "A list of killed diffs.
718 A diff is saved here if it is replaced by a diff 979 A diff is saved here if it is replaced by a diff
719 from another buffer. This alist has the form: 980 from another buffer. This alist has the form:
720 \((num (A . diff) (B . diff)) ...), 981 ((num (A . diff) (B . diff)) ...),
721 where A or B parts may be missing.") 982 where A or B parts may be missing.")
722 983
723 984
724 ;; Highlighting 985 ;; Highlighting
725 (defvar ediff-before-flag-bol 986 (defvar ediff-before-flag-bol
726 ;"vvvvvvvvvvvvvvvv---- ediff ----vvvvvvvvvvvvvvv\n" 987 ;"vvvvvvvvvvvvvvvv---- ediff ----vvvvvvvvvvvvvvv\n"
727 ">>--->>>\n" 988 ">>--->>>\n"
728 "*Flag placed above the highlighted block of differences. 989 "*Flag placed above the highlighted block of differences.
729 Must end with newline. Must be set before Ediff is loaded. 990 Must end with newline. Must be set before Ediff is loaded.")
730 nil means use a default flag string.")
731 (defvar ediff-after-flag-bol 991 (defvar ediff-after-flag-bol
732 ;"^^^^^^^^^^^^^^^^---- ediff ----^^^^^^^^^^^^^^^\n" 992 ;"^^^^^^^^^^^^^^^^---- ediff ----^^^^^^^^^^^^^^^\n"
733 "<<<---<<\n" 993 "<<<---<<\n"
734 "*Flag placed below the highlighted block of differences. 994 "*Flag placed below the highlighted block of differences.
735 Must end with newline. Must be set before Ediff is loaded. 995 Must end with newline. Must be set before Ediff is loaded.")
736 nil means use a default flag string.")
737 996
738 (defvar ediff-before-flag-mol ">>--->>>" 997 (defvar ediff-before-flag-mol ">>--->>>"
739 "*Like ediff-before-flag, used when a difference starts in mid-line.") 998 "*Like ediff-before-flag, used when a difference starts in mid-line.")
740 (defvar ediff-after-flag-mol "<<<---<<" 999 (defvar ediff-after-flag-mol "<<<---<<"
741 "*Like ediff-after-flag, used when a difference starts in mid-line.") 1000 "*Like ediff-after-flag, used when a difference starts in mid-line.")
766 "If t, differences are highlighted using faces on a window system. 1025 "If t, differences are highlighted using faces on a window system.
767 If nil, they are highlighted using ASCII flags, ediff-before-flag 1026 If nil, they are highlighted using ASCII flags, ediff-before-flag
768 and ediff-after-flag. On a non-window system, differences are always 1027 and ediff-after-flag. On a non-window system, differences are always
769 highlighted using ASCII flags. 1028 highlighted using ASCII flags.
770 1029
771 This is not a user option. Can be set either in .emacs or toggled 1030 This variable can be set either in .emacs or toggled interactively, using
772 interactively, using ediff-toggle-hilit.") 1031 ediff-toggle-hilit.")
773 1032
774 (emerge-defvar-local ediff-highlight-selected-only nil 1033 (emerge-defvar-local ediff-want-default-menus t
775 "If t, only the selected differences are highlighted. 1034 "If t, Ediff will set up menus in the menu bar.
776 This is not a user option. Can be set either in `.emacs' or toggled 1035 This variable must be set before Ediff is loaded. If you don't like the
777 interactively, using `ediff-toggle-hilit'.") 1036 look of the default menus, set this variable to nil and make your own
1037 menus.")
1038
1039 (emerge-defvar-local ediff-auto-refine 'on
1040 "If `'on', Ediff auto-highlights fine diffs for the current diff region.
1041 If `off', auto-highlighting is not used. If `'nix', no fine diffs are shown
1042 at all, unless the user force-refines the region by hitting `*'.
1043
1044 This variable can be set either in .emacs or toggled interactively, using
1045 ediff-toggle-hilit.")
1046
1047 (emerge-defvar-local ediff-auto-refine-limit 700
1048 "Auto-refine only those regions that are smaller than this number of bytes.")
1049
1050 (emerge-defvar-local ediff-highlight-all-diffs t
1051 "If nil, only the selected differences are highlighted.
1052 This variable can be set either in .emacs or toggled interactively, using
1053 ediff-toggle-hilit.")
778 1054
779 (emerge-defvar-local ediff-highlighting-style nil 1055 (emerge-defvar-local ediff-highlighting-style nil
780 "A var local to each ediff-control buffer. 1056 "A var local to each ediff-control buffer.
781 Indicates highlighting style in effect for this buffer: `face', `ascii', 1057 Indicates highlighting style in effect for this buffer: `face', `ascii',
782 nil -- temporarily unhighlighted, `off' -- turned off \(on a dumb 1058 nil -- temporarily unhighlighted, `off' -- turned off \(on a dumb
793 (emerge-defvar-local ediff-B-buffer nil 1069 (emerge-defvar-local ediff-B-buffer nil
794 "The buffer in which the B variant is stored.") 1070 "The buffer in which the B variant is stored.")
795 (emerge-defvar-local ediff-control-buffer nil 1071 (emerge-defvar-local ediff-control-buffer nil
796 "The control buffer of ediff. ") 1072 "The control buffer of ediff. ")
797 1073
798 (emerge-defvar-local ediff-control-buffer-suffix nil 1074 ;(emerge-defvar-local ediff-control-buffer-suffix nil
799 "The suffix of the control buffer name. ") 1075 ; "The suffix of the control buffer name. ")
800 1076
801 (defvar ediff-control-window nil 1077 (emerge-defvar-local ediff-control-window nil
802 "The control window.") 1078 "The control window.")
1079 (emerge-defvar-local ediff-window-config-saved ""
1080 "Ediff's window configuration.
1081 Used to minimize the need to rearrange windows.")
803 1082
804 1083
805 (emerge-defvar-local ediff-A-buffer-values nil 1084 (emerge-defvar-local ediff-A-buffer-values nil
806 "Keeps working values of ediff-saved-variables for ediff-A-buffer.") 1085 "Keeps working values of ediff-saved-variables for ediff-A-buffer.")
807 (emerge-defvar-local ediff-B-buffer-values nil 1086 (emerge-defvar-local ediff-B-buffer-values nil
811 "Remembers ediff-saved-variables for ediff-A-buffer as they were at setup.") 1090 "Remembers ediff-saved-variables for ediff-A-buffer as they were at setup.")
812 (emerge-defvar-local ediff-B-buffer-values-setup nil 1091 (emerge-defvar-local ediff-B-buffer-values-setup nil
813 "Remembers ediff-saved-variables for ediff-B-buffer as they were at setup.") 1092 "Remembers ediff-saved-variables for ediff-B-buffer as they were at setup.")
814 1093
815 (emerge-defvar-local ediff-difference-vector nil 1094 (emerge-defvar-local ediff-difference-vector nil
816 "Vector of differences between the variants. 1095 "Vector of differences between the variants.
817 Each difference is represented by a vector of two overlays. The first 1096 Each difference is represented by a vector of two overlays. The first
818 overlays the difference section in the A buffer and the second 1097 overlays the difference section in the A buffer and the second overlays the
819 overlays the diff in the B buffer. If a difference section is empty, 1098 diff in the B buffer. If a difference section is empty, the corresponding
820 the corresponding overlay's endpoints councide. ") 1099 overlay's endpoints coincide. ")
821 1100
822 (emerge-defvar-local ediff-current-difference -1 1101 (emerge-defvar-local ediff-current-difference -1
823 "The difference that is currently selected.") 1102 "The difference that is currently selected.")
824 (emerge-defvar-local ediff-number-of-differences nil 1103 (emerge-defvar-local ediff-number-of-differences nil
825 "Number of differences found.") 1104 "Number of differences found.")
826 1105
827 (emerge-defvar-local ediff-diff-buffer nil 1106 (emerge-defvar-local ediff-diff-buffer nil
828 "Buffer containing the output of diff, used by Ediff to step through files.") 1107 "Buffer containing the output of diff, which is used by Ediff to step
829 (emerge-defvar-local ediff-diff-error-buffer nil 1108 through files.")
830 "Buffer containing the output of diff, when diff returns errors.") 1109 (emerge-defvar-local ediff-tmp-buffer nil
831 1110 "Temporary buffer used for computing fine differences.")
1111 (emerge-defvar-local ediff-error-buffer nil
1112 "Buffer containing the output of diff when diff returns errors.")
1113
832 (emerge-defvar-local ediff-this-buffer-control-sessions nil 1114 (emerge-defvar-local ediff-this-buffer-control-sessions nil
833 "List of ediff-control buffers associated with each buffer A/B.") 1115 "List of ediff-control buffers associated with each buffer A/B.")
834 1116
835 (defvar ediff-disturbed-overlays nil 1117 (defvar ediff-disturbed-overlays nil
836 "List of difference overlays disturbed by working with the current diff.") 1118 "List of difference overlays disturbed by working with the current diff.")
867 (if (ediff-if-lucid) 1149 (if (ediff-if-lucid)
868 (progn 1150 (progn
869 (fset 'ediff-select-frame (symbol-function 'select-screen)) 1151 (fset 'ediff-select-frame (symbol-function 'select-screen))
870 (fset 'ediff-window-frame (symbol-function 'window-screen)) 1152 (fset 'ediff-window-frame (symbol-function 'window-screen))
871 (fset 'ediff-display-color-p (symbol-function 'x-color-display-p)) 1153 (fset 'ediff-display-color-p (symbol-function 'x-color-display-p))
1154 (fset 'ediff-valid-color-p (symbol-function 'x-valid-color-name-p))
872 (fset 'ediff-get-face (symbol-function 'get-face))) 1155 (fset 'ediff-get-face (symbol-function 'get-face)))
873 (fset 'ediff-window-frame (symbol-function 'window-frame)) 1156 (fset 'ediff-window-frame (symbol-function 'window-frame))
874 (fset 'ediff-select-frame (symbol-function 'select-frame)) 1157 (fset 'ediff-select-frame (symbol-function 'select-frame))
875 (fset 'ediff-display-color-p (symbol-function 'x-display-color-p)) 1158 (fset 'ediff-display-color-p (symbol-function 'x-display-color-p))
1159
1160 ;; This is a temporary fix for OS/2 users
1161 ;; pm-win.el in PM-Emacs should be fixed.
1162 (if (eq window-system 'pm)
1163 (fset 'ediff-valid-color-p
1164 (function (lambda (color) (assoc color pm-color-alist))))
1165 (fset 'ediff-valid-color-p (symbol-function 'x-color-defined-p))
1166 )
1167
876 (fset 'ediff-get-face (symbol-function 'internal-get-face))) 1168 (fset 'ediff-get-face (symbol-function 'internal-get-face)))
877 ;; not a window system 1169 ;; not a window system
878 (fset 'ediff-window-frame (function (lambda (wind) (if wind 1 nil)) )) 1170 (fset 'ediff-window-frame (function (lambda (wind) (if wind 1 nil)) ))
879 (fset 'ediff-select-frame (symbol-function 'identity)) 1171 (fset 'ediff-select-frame (symbol-function 'identity))
880 (fset 'ediff-make-current-diff-overlay (function (lambda (type) nil))) 1172 (fset 'ediff-make-current-diff-overlay (function (lambda (type) nil)))
881 (fset 'ediff-unhighlight-diffs-totally (function (lambda () nil)))) 1173 (fset 'ediff-unhighlight-diffs-totally (function (lambda () nil))))
882 1174
883 1175
884 (if (not window-system) 1176 (if (not window-system)
885 () 1177 ()
1178 (defun ediff-set-face (ground face color)
1179 "Sets face foreground/background. If color unavailable, guides the user."
1180 (if (ediff-valid-color-p color)
1181 (if (eq ground 'foreground)
1182 (set-face-foreground face color)
1183 (set-face-background face color))
1184 (cond ((memq face
1185 '(ediff-current-diff-face-A ediff-current-diff-face-B))
1186 (copy-face 'highlight face))
1187 ((memq face
1188 '(ediff-fine-diff-face-A ediff-fine-diff-face-B))
1189 (copy-face 'secondary-selection face)
1190 (set-face-underline-p face t))
1191 ((memq face
1192 '(ediff-odd-diff-face-A ediff-odd-diff-face-B
1193 ediff-even-diff-face-A ediff-even-diff-face-B))
1194 (copy-face 'secondary-selection face)))))
1195
886 (defvar ediff-current-diff-face-A 1196 (defvar ediff-current-diff-face-A
887 (progn 1197 (progn
888 (make-face 'ediff-current-diff-face-A) 1198 (make-face 'ediff-current-diff-face-A)
889 (cond ((ediff-display-color-p) 1199 (or (face-differs-from-default-p 'ediff-current-diff-face-A)
890 (set-face-foreground 'ediff-current-diff-face-A "firebrick") 1200 (cond ((ediff-display-color-p)
891 (set-face-background 'ediff-current-diff-face-A "pale green")) 1201 (ediff-set-face
892 (t 1202 'foreground 'ediff-current-diff-face-A "firebrick")
893 (if (ediff-if-lucid) 1203 (ediff-set-face
894 (copy-face 'modeline 'ediff-current-diff-face-A) 1204 'background 'ediff-current-diff-face-A "pale green"))
895 (copy-face 'highlight 'ediff-current-diff-face-A)) 1205 (t
896 )) 1206 (if (ediff-if-lucid)
1207 (copy-face 'modeline 'ediff-current-diff-face-A)
1208 (copy-face 'highlight 'ediff-current-diff-face-A))
1209 )))
897 (ediff-get-face 'ediff-current-diff-face-A)) 1210 (ediff-get-face 'ediff-current-diff-face-A))
898 "Face for highlighting the currently selected difference in buffer A of 1211 "Face for highlighting the selected difference in buffer A.")
899 the Ediff display")
900 1212
901 (defvar ediff-current-diff-face-B 1213 (defvar ediff-current-diff-face-B
902 (progn 1214 (progn
903 (make-face 'ediff-current-diff-face-B) 1215 (make-face 'ediff-current-diff-face-B)
904 (cond ((ediff-display-color-p) 1216 (or (face-differs-from-default-p 'ediff-current-diff-face-B)
905 (set-face-foreground 'ediff-current-diff-face-B "DarkOrchid") 1217 (cond ((ediff-display-color-p)
906 (set-face-background 'ediff-current-diff-face-B "Yellow")) 1218 (ediff-set-face
907 (t 1219 'foreground 'ediff-current-diff-face-B "DarkOrchid")
908 (if (ediff-if-lucid) 1220 (ediff-set-face
909 (copy-face 'modeline 'ediff-current-diff-face-B) 1221 'background 'ediff-current-diff-face-B "Yellow"))
910 (copy-face 'highlight 'ediff-current-diff-face-B)) 1222 (t
911 )) 1223 (if (ediff-if-lucid)
1224 (copy-face 'modeline 'ediff-current-diff-face-B)
1225 (copy-face 'highlight 'ediff-current-diff-face-B))
1226 )))
912 (ediff-get-face 'ediff-current-diff-face-B)) 1227 (ediff-get-face 'ediff-current-diff-face-B))
913 "Face for highlighting the currently selected difference in buffer B of 1228 "Face for highlighting the selected difference in buffer B.")
914 the Ediff display") 1229
1230 (defvar ediff-fine-diff-face-A
1231 (progn
1232 (make-face 'ediff-fine-diff-face-A)
1233 (or (face-differs-from-default-p 'ediff-fine-diff-face-A)
1234 (cond ((ediff-display-color-p)
1235 (ediff-set-face 'foreground 'ediff-fine-diff-face-A
1236 "Navy")
1237 (ediff-set-face 'background 'ediff-fine-diff-face-A
1238 "sky blue"))
1239 (t (set-face-underline-p 'ediff-fine-diff-face-A t))))
1240 (ediff-get-face 'ediff-fine-diff-face-A))
1241 "Face for highlighting the refinement of the selected diff in buffer A.")
1242
1243 (defvar ediff-fine-diff-face-B
1244 (progn
1245 (make-face 'ediff-fine-diff-face-B)
1246 (or (face-differs-from-default-p 'ediff-fine-diff-face-B)
1247 (cond ((ediff-display-color-p)
1248 (ediff-set-face 'foreground 'ediff-fine-diff-face-B "Black")
1249 (ediff-set-face 'background 'ediff-fine-diff-face-B "cyan"))
1250 (t (set-face-underline-p 'ediff-fine-diff-face-B t))))
1251 (ediff-get-face 'ediff-fine-diff-face-B))
1252 "Face for highlighting the refinement of the selected diff in buffer B.")
1253
915 1254
916 (defvar ediff-even-diff-face-A 1255 (defvar ediff-even-diff-face-A
917 (progn 1256 (progn
918 (make-face 'ediff-even-diff-face-A) 1257 (make-face 'ediff-even-diff-face-A)
919 (cond ((ediff-display-color-p) 1258 (or (face-differs-from-default-p 'ediff-even-diff-face-A)
920 (set-face-background 'ediff-even-diff-face-A "light grey")) 1259 (cond ((ediff-display-color-p)
921 (t 1260 (ediff-set-face
922 (if (ediff-if-lucid) 1261 'foreground 'ediff-even-diff-face-A "black")
923 (progn 1262 (ediff-set-face
924 (copy-face 'highlight 'ediff-even-diff-face-A) 1263 'background 'ediff-even-diff-face-A "light grey"))
925 (invert-face 'ediff-even-diff-face-A)) 1264 (t
926 (make-face-italic 'ediff-even-diff-face-A)))) 1265 (if (ediff-if-lucid)
1266 (progn
1267 (copy-face 'highlight 'ediff-even-diff-face-A)
1268 (invert-face 'ediff-even-diff-face-A))
1269 (copy-face 'italic 'ediff-even-diff-face-A)))))
927 (ediff-get-face 'ediff-even-diff-face-A)) 1270 (ediff-get-face 'ediff-even-diff-face-A))
928 "Face used to highlight even-numbered differences in buffer A.") 1271 "Face used to highlight even-numbered differences in buffer A.")
929 1272
930 (defvar ediff-even-diff-face-B 1273 (defvar ediff-even-diff-face-B
931 (progn 1274 (progn
932 (make-face 'ediff-even-diff-face-B) 1275 (make-face 'ediff-even-diff-face-B)
933 (cond ((ediff-display-color-p) 1276 (or (face-differs-from-default-p 'ediff-even-diff-face-B)
934 (set-face-foreground 'ediff-even-diff-face-B "White") 1277 (cond ((ediff-display-color-p)
935 (set-face-background 'ediff-even-diff-face-B "Gray")) 1278 (ediff-set-face
936 (t 1279 'foreground 'ediff-even-diff-face-B "White")
937 (if (ediff-if-lucid) 1280 (ediff-set-face
938 (copy-face 'highlight 'ediff-even-diff-face-B) 1281 'background 'ediff-even-diff-face-B "Gray"))
939 (make-face-italic 'ediff-even-diff-face-B)))) 1282 (t
1283 (if (ediff-if-lucid)
1284 (copy-face 'highlight 'ediff-even-diff-face-B)
1285 (copy-face 'italic 'ediff-even-diff-face-B)))))
940 (ediff-get-face 'ediff-even-diff-face-B)) 1286 (ediff-get-face 'ediff-even-diff-face-B))
941 "Face used to highlight even-numbered differences in buffer B.") 1287 "Face used to highlight even-numbered differences in buffer B.")
942 1288
943 (defvar ediff-odd-diff-face-A 1289 (defvar ediff-odd-diff-face-A
944 (progn 1290 (progn
945 (make-face 'ediff-odd-diff-face-A) 1291 (make-face 'ediff-odd-diff-face-A)
946 (cond ((ediff-display-color-p) 1292 (or (face-differs-from-default-p 'ediff-odd-diff-face-A)
947 (set-face-foreground 'ediff-odd-diff-face-A "White") 1293 (cond ((ediff-display-color-p)
948 (set-face-background 'ediff-odd-diff-face-A "Gray")) 1294 (ediff-set-face
949 (t 1295 'foreground 'ediff-odd-diff-face-A "White")
950 (if (ediff-if-lucid) 1296 (ediff-set-face
951 (copy-face 'highlight 'ediff-odd-diff-face-A) 1297 'background 'ediff-odd-diff-face-A "Gray"))
952 (make-face-italic 'ediff-odd-diff-face-A)))) 1298 (t
953 (ediff-get-face 'ediff-odd-diff-face-A)) 1299 (if (ediff-if-lucid)
1300 (copy-face 'highlight 'ediff-odd-diff-face-A)
1301 (copy-face 'italic 'ediff-odd-diff-face-A)))))
1302 (ediff-get-face 'ediff-odd-diff-face-A))
954 "Face used to highlight odd-numbered differences in buffer A.") 1303 "Face used to highlight odd-numbered differences in buffer A.")
955 1304
956 (defvar ediff-odd-diff-face-B 1305 (defvar ediff-odd-diff-face-B
957 (progn 1306 (progn
958 (make-face 'ediff-odd-diff-face-B) 1307 (make-face 'ediff-odd-diff-face-B)
959 (cond ((ediff-display-color-p) 1308 (or (face-differs-from-default-p 'ediff-odd-diff-face-B)
960 (set-face-foreground 'ediff-odd-diff-face-B "Black") 1309 (cond ((ediff-display-color-p)
961 (set-face-background 'ediff-odd-diff-face-B "light grey")) 1310 (ediff-set-face
962 (t 1311 'foreground 'ediff-odd-diff-face-B "Black")
963 (if (ediff-if-lucid) 1312 (ediff-set-face
964 (progn 1313 'background 'ediff-odd-diff-face-B "light grey"))
965 (copy-face 'highlight 'ediff-odd-diff-face-B) 1314 (t
966 (invert-face 'ediff-odd-diff-face-B)) 1315 (if (ediff-if-lucid)
967 (make-face-italic 'ediff-odd-diff-face-B)))) 1316 (progn
1317 (copy-face 'highlight 'ediff-odd-diff-face-B)
1318 (invert-face 'ediff-odd-diff-face-B))
1319 (copy-face 'italic 'ediff-odd-diff-face-B)))))
968 (ediff-get-face 'ediff-odd-diff-face-B)) 1320 (ediff-get-face 'ediff-odd-diff-face-B))
969 "Face used to highlight odd-numbered differences in buffer B.") 1321 "Face used to highlight odd-numbered differences in buffer B.")
970 1322
971
972 ;; Create *-var faces. These are the actual faces used to highlight 1323 ;; Create *-var faces. These are the actual faces used to highlight
973 ;; odd-numbered difference regions. 1324 ;; odd-numbered difference regions.
974 ;; They are used as follows: when highlighting is turned on, 1325 ;; They are used as follows: when highlighting is turned on,
975 ;; ediff-odd/even-diff-face-A/B are copied 1326 ;; ediff-odd/even-diff-face-A/B are copied
976 ;; into ediff-odd/even-diff-face-A/B-var, and all odd/even overlays become 1327 ;; into ediff-odd/even-diff-face-A/B-var, and all odd/even overlays become
982 (make-face 'ediff-odd-diff-face-A-var) 1333 (make-face 'ediff-odd-diff-face-A-var)
983 (make-face 'ediff-odd-diff-face-B-var) 1334 (make-face 'ediff-odd-diff-face-B-var)
984 1335
985 ;; initialize *-var faces 1336 ;; initialize *-var faces
986 (defun ediff-init-var-faces () 1337 (defun ediff-init-var-faces ()
987 (copy-face (if (and ediff-want-faces (null ediff-highlight-selected-only)) 1338 (copy-face (if (and ediff-want-faces ediff-highlight-all-diffs)
988 ediff-even-diff-face-A 'default) 1339 ediff-even-diff-face-A 'default)
989 'ediff-even-diff-face-A-var) 1340 'ediff-even-diff-face-A-var)
990 (copy-face (if (and ediff-want-faces (null ediff-highlight-selected-only)) 1341 (copy-face (if (and ediff-want-faces ediff-highlight-all-diffs)
991 ediff-even-diff-face-B 'default) 1342 ediff-even-diff-face-B 'default)
992 'ediff-even-diff-face-B-var) 1343 'ediff-even-diff-face-B-var)
993 (copy-face (if (and ediff-want-faces (null ediff-highlight-selected-only)) 1344 (copy-face (if (and ediff-want-faces ediff-highlight-all-diffs)
994 ediff-odd-diff-face-A 'default) 1345 ediff-odd-diff-face-A 'default)
995 'ediff-odd-diff-face-A-var) 1346 'ediff-odd-diff-face-A-var)
996 (copy-face (if (and ediff-want-faces (null ediff-highlight-selected-only)) 1347 (copy-face (if (and ediff-want-faces ediff-highlight-all-diffs)
997 ediff-odd-diff-face-B 'default) 1348 ediff-odd-diff-face-B 'default)
998 'ediff-odd-diff-face-B-var)) 1349 'ediff-odd-diff-face-B-var))
999 1350
1000 1351
1001 ;;; Overlays 1352 ;;; Overlays
1007 1358
1008 (defun ediff-make-current-diff-overlay (type) 1359 (defun ediff-make-current-diff-overlay (type)
1009 (let ((overlay (if (eq type 'A) 1360 (let ((overlay (if (eq type 'A)
1010 'ediff-current-diff-overlay-A 1361 'ediff-current-diff-overlay-A
1011 'ediff-current-diff-overlay-B)) 1362 'ediff-current-diff-overlay-B))
1012 (buffer (if (eq type 'A) ediff-A-buffer ediff-B-buffer)) 1363 (buffer (ediff-get-buffer type))
1013 (face (if (eq type 'A) 1364 (face (if (eq type 'A)
1014 (face-name ediff-current-diff-face-A) 1365 (face-name ediff-current-diff-face-A)
1015 (face-name ediff-current-diff-face-B)))) 1366 (face-name ediff-current-diff-face-B))))
1016 (set overlay (ediff-make-overlay (point-max) (point-max) buffer)) 1367 (set overlay (ediff-make-overlay (point-max) (point-max) buffer))
1017 (ediff-overlay-put (eval overlay) 'face face) 1368 (ediff-overlay-put (eval overlay) 'face face)
1047 ;;; Misc 1398 ;;; Misc
1048 1399
1049 (defvar ediff-split-window-function 'split-window-vertically 1400 (defvar ediff-split-window-function 'split-window-vertically
1050 "*The function to split the main window between buffer-A and buffer-B. 1401 "*The function to split the main window between buffer-A and buffer-B.
1051 You can set it to be split horizontally instead of the 1402 You can set it to be split horizontally instead of the
1052 default verstical split by setting this variable to 1403 default vertical split by setting this variable to
1053 'split-window-horizontally. You can also have your own function for fancy 1404 'split-window-horizontally. You can also have your own function for fancy
1054 splits. This variable has no effect when buffer-A and buffer-B are shown in 1405 splits. This variable has no effect when buffer-A and buffer-B are shown in
1055 different frames. In this case, Ediff will use those frames to display 1406 different frames. In this case, Ediff will use those frames to display
1056 these buffers.") 1407 these buffers.")
1057 1408
1083 Do not start with `~/' or `~user-name/'.") 1434 Do not start with `~/' or `~user-name/'.")
1084 1435
1085 (defvar ediff-temp-file-mode 384 ; u=rw only 1436 (defvar ediff-temp-file-mode 384 ; u=rw only
1086 "*Mode for Ediff temporary files.") 1437 "*Mode for Ediff temporary files.")
1087 1438
1439 (emerge-defvar-local ediff-temp-file-A nil
1440 "Temporary file used for refining difference regions in buffer B.")
1441 (emerge-defvar-local ediff-temp-file-B nil
1442 "Temporary file used for refining difference regions in buffer B.")
1443
1088 (defvar ediff-last-dir-A nil 1444 (defvar ediff-last-dir-A nil
1089 "Last directory used by an Ediff command for file-A.") 1445 "Last directory used by an Ediff command for file-A.")
1090 (defvar ediff-last-dir-B nil 1446 (defvar ediff-last-dir-B nil
1091 "Last directory used by an Ediff command for file-B.") 1447 "Last directory used by an Ediff command for file-B.")
1092 1448
1093 ;; Build keymaps 1449 ;; Build keymaps
1094 1450
1095 (defvar ediff-mode-map nil 1451 (defvar ediff-mode-map nil
1096 "Local keymap used in Ediff mode.") 1452 "Local keymap used in Ediff mode.")
1453
1454 (if (and window-system ediff-want-default-menus (ediff-frame-has-menubar))
1455 (if (ediff-if-lucid)
1456 (progn ;; Lucid menu bars
1457 (defvar ediff-menu
1458 '(""
1459 ["Between Files ..." ediff-files t]
1460 ["Between Buffers ..." ediff-buffers t]
1461 ["With a Revision via VC ..." vc-ediff t]
1462 ["With a Revision via RCS ..." rcs-ediff t]))
1463 (defvar epatch-menu
1464 '(""
1465 ["To a File ..." ediff-patch-file t]
1466 ["To a Buffer ..." ediff-patch-buffer t]))
1467 (add-menu '("File") "Find Differences"
1468 ediff-menu
1469 "Delete Screen")
1470 (add-menu '("File") "Apply Patch"
1471 epatch-menu
1472 "Delete Screen")
1473 ;; Displays as a solid horizontal line
1474 (add-menu-item '("File") "---" nil nil "Delete Screen")
1475 )
1476 ;; FSF menu bars
1477 ;;;###autoload
1478 (defvar menu-bar-epatch-menu (make-sparse-keymap "menu-bar-epatch-map"))
1479 ;;;###autoload
1480 (fset 'menu-bar-epatch-menu (symbol-value 'menu-bar-epatch-menu))
1481 ;;;###autoload
1482 (defvar menu-bar-ediff-menu (make-sparse-keymap "menu-bar-ediff-map"))
1483 ;;;###autoload
1484 (fset 'menu-bar-ediff-menu (symbol-value 'menu-bar-ediff-menu))
1485
1486 ;;;###autoload
1487 (define-key menu-bar-ediff-menu [rcs-ediff]
1488 '("With a Revision via RCS ..." . rcs-ediff))
1489 ;;;###autoload
1490 (define-key menu-bar-ediff-menu [vc-ediff]
1491 '("With a Revision via VC ..." . vc-ediff))
1492 ;;;###autoload
1493 (define-key menu-bar-ediff-menu [ediff-buffers]
1494 '("Between Buffers ..." . ediff-buffers))
1495 ;;;###autoload
1496 (define-key menu-bar-ediff-menu [ediff-files]
1497 '("Between Files ..." . ediff-files))
1498
1499 ;;;###autoload
1500 (define-key menu-bar-epatch-menu [ediff-patch-buffer]
1501 '("To a Buffer ..." . ediff-patch-buffer))
1502 ;;;###autoload
1503 (define-key menu-bar-epatch-menu [ediff-patch-file]
1504 '("To a File ..." . ediff-patch-file))
1505
1506 (define-key menu-bar-file-menu [epatch]
1507 '("Apply Patch" . menu-bar-epatch-menu))
1508 (define-key menu-bar-file-menu [ediff]
1509 '("Find Differences" . menu-bar-ediff-menu))
1510 ))
1097 1511
1098 1512
1099 (defun ediff-setup-keymap () 1513 (defun ediff-setup-keymap ()
1100 "Set up the keymap used in the control buffer of Ediff." 1514 "Set up the keymap used in the control buffer of Ediff."
1101 (setq ediff-mode-map (make-sparse-keymap)) 1515 (setq ediff-mode-map (make-sparse-keymap))
1102 (suppress-keymap ediff-mode-map) 1516 (suppress-keymap ediff-mode-map)
1103 1517
1104 (define-key ediff-mode-map "p" 'ediff-previous-difference) 1518 (define-key ediff-mode-map "p" 'ediff-previous-difference)
1105 (define-key ediff-mode-map "\C-?" 'ediff-previous-difference) 1519 (define-key ediff-mode-map "\C-?" 'ediff-previous-difference)
1106 (define-key ediff-mode-map "\C-h" (if ediff-nix-help-in-control-buffer 1520 (define-key ediff-mode-map "\C-h" (if ediff-no-help-in-control-buffer
1107 'ediff-previous-difference nil)) 1521 'ediff-previous-difference nil))
1108 (define-key ediff-mode-map "n" 'ediff-next-difference) 1522 (define-key ediff-mode-map "n" 'ediff-next-difference)
1109 (define-key ediff-mode-map " " 'ediff-next-difference) 1523 (define-key ediff-mode-map " " 'ediff-next-difference)
1110 (define-key ediff-mode-map "j" 'ediff-jump-to-difference) 1524 (define-key ediff-mode-map "j" 'ediff-jump-to-difference)
1111 (define-key ediff-mode-map "g" nil) 1525 (define-key ediff-mode-map "g" nil)
1114 (define-key ediff-mode-map "q" 'ediff-quit) 1528 (define-key ediff-mode-map "q" 'ediff-quit)
1115 (define-key ediff-mode-map "z" 'ediff-suspend) 1529 (define-key ediff-mode-map "z" 'ediff-suspend)
1116 (define-key ediff-mode-map "c" 'ediff-recenter) 1530 (define-key ediff-mode-map "c" 'ediff-recenter)
1117 (define-key ediff-mode-map "s" 'ediff-toggle-split) 1531 (define-key ediff-mode-map "s" 'ediff-toggle-split)
1118 (define-key ediff-mode-map "h" 'ediff-toggle-hilit) 1532 (define-key ediff-mode-map "h" 'ediff-toggle-hilit)
1533 (define-key ediff-mode-map "@" 'ediff-toggle-autorefine)
1119 (define-key ediff-mode-map "v" 'ediff-scroll-up) 1534 (define-key ediff-mode-map "v" 'ediff-scroll-up)
1120 (define-key ediff-mode-map "\C-v" 'ediff-scroll-up) 1535 (define-key ediff-mode-map "\C-v" 'ediff-scroll-up)
1121 (define-key ediff-mode-map "^" 'ediff-scroll-down) 1536 (define-key ediff-mode-map "^" 'ediff-scroll-down)
1122 (define-key ediff-mode-map "\M-v" 'ediff-scroll-down) 1537 (define-key ediff-mode-map "\M-v" 'ediff-scroll-down)
1123 (define-key ediff-mode-map "V" 'ediff-scroll-down) 1538 (define-key ediff-mode-map "V" 'ediff-scroll-down)
1124 (define-key ediff-mode-map "<" 'ediff-scroll-left) 1539 (define-key ediff-mode-map "<" 'ediff-scroll-left)
1125 (define-key ediff-mode-map ">" 'ediff-scroll-right) 1540 (define-key ediff-mode-map ">" 'ediff-scroll-right)
1126 (define-key ediff-mode-map "f" 'ediff-file-names) 1541 (define-key ediff-mode-map "f" 'ediff-file-names)
1127 (define-key ediff-mode-map "l" 'ediff-line-numbers) 1542 (define-key ediff-mode-map "l" 'ediff-line-numbers)
1128 (define-key ediff-mode-map "?" 'ediff-toggle-help) 1543 (define-key ediff-mode-map "?" 'ediff-toggle-help)
1544 (define-key ediff-mode-map "!" 'ediff-recompute-diffs)
1545 (define-key ediff-mode-map "*" 'ediff-make-fine-diffs)
1129 (define-key ediff-mode-map "a" nil) 1546 (define-key ediff-mode-map "a" nil)
1130 (define-key ediff-mode-map "ab" 'ediff-diff-to-diff) 1547 (define-key ediff-mode-map "ab" 'ediff-diff-to-diff)
1131 (define-key ediff-mode-map "b" nil) 1548 (define-key ediff-mode-map "b" nil)
1132 (define-key ediff-mode-map "ba" 'ediff-diff-to-diff) 1549 (define-key ediff-mode-map "ba" 'ediff-diff-to-diff)
1133 (define-key ediff-mode-map "r" nil) 1550 (define-key ediff-mode-map "r" nil)
1176 ;; Verify that the file matches the buffer 1593 ;; Verify that the file matches the buffer
1177 (emerge-verify-file-buffer))))) 1594 (emerge-verify-file-buffer)))))
1178 1595
1179 (defun ediff-files-internal (file-A file-B &optional startup-hooks) 1596 (defun ediff-files-internal (file-A file-B &optional startup-hooks)
1180 (let (buffer-A buffer-B) 1597 (let (buffer-A buffer-B)
1181 (message "Ediff: Reading file %s ... " file-A)(sit-for .5) 1598 (message "Reading file %s ... " file-A)(sit-for .5)
1182 (ediff-find-file file-A 'buffer-A 'ediff-last-dir-A) 1599 (ediff-find-file file-A 'buffer-A 'ediff-last-dir-A)
1183 (message "Ediff: Reading file %s ... " file-B)(sit-for .5) 1600 (message "Reading file %s ... " file-B)(sit-for .5)
1184 (ediff-find-file file-B 'buffer-B 'ediff-last-dir-B) 1601 (ediff-find-file file-B 'buffer-B 'ediff-last-dir-B)
1185 (ediff-setup buffer-A file-A buffer-B file-B startup-hooks))) 1602 (ediff-setup buffer-A file-A buffer-B file-B startup-hooks)))
1186 1603
1187 (defun ediff-get-patch-buffer (dir) 1604 (defun ediff-get-patch-buffer (dir)
1188 "Obtain patch buffer. If patch is already in a buffer---use it. 1605 "Obtain patch buffer. If patch is already in a buffer---use it.
1216 (ediff-mode) ;; in control buffer only 1633 (ediff-mode) ;; in control buffer only
1217 (setq buffer-read-only nil) 1634 (setq buffer-read-only nil)
1218 (setq ediff-A-buffer buffer-A) 1635 (setq ediff-A-buffer buffer-A)
1219 (setq ediff-B-buffer buffer-B) 1636 (setq ediff-B-buffer buffer-B)
1220 (setq ediff-control-buffer control-buffer) 1637 (setq ediff-control-buffer control-buffer)
1221 (setq ediff-control-buffer-suffix 1638 ; (setq ediff-control-buffer-suffix
1222 (if (string-match "<[0-9]*>" control-buffer-name) 1639 ; (if (string-match "<[0-9]*>" control-buffer-name)
1223 (substring control-buffer-name 1640 ; (substring control-buffer-name
1224 (match-beginning 0) (match-end 0)) 1641 ; (match-beginning 0) (match-end 0))
1225 "<1>")) 1642 ; "<1>"))
1643 (setq ediff-error-buffer (get-buffer-create (emerge-unique-buffer-name
1644 "*ediff-errors" "*")))
1226 (ediff-remember-buffer-characteristics t) ;; remember at setup 1645 (ediff-remember-buffer-characteristics t) ;; remember at setup
1227 1646
1228 (ediff-set-keys) 1647 (ediff-set-keys)
1229 (setq ediff-difference-vector (ediff-make-diff-list file-A file-B)) 1648 (setq ediff-difference-vector (ediff-setup-diff-regions file-A file-B))
1230 (setq ediff-number-of-differences (length ediff-difference-vector)) 1649 (setq ediff-number-of-differences (length ediff-difference-vector))
1231 (setq ediff-current-difference -1) 1650 (setq ediff-current-difference -1)
1232 (ediff-make-current-diff-overlay 'A) 1651 (ediff-make-current-diff-overlay 'A)
1233 (ediff-make-current-diff-overlay 'B) 1652 (ediff-make-current-diff-overlay 'B)
1234 (if window-system 1653 (if window-system
1262 1681
1263 (emerge-eval-in-buffer control-buffer 1682 (emerge-eval-in-buffer control-buffer
1264 (run-hooks 'startup-hooks 'ediff-startup-hooks) 1683 (run-hooks 'startup-hooks 'ediff-startup-hooks)
1265 (setq buffer-read-only t))))) 1684 (setq buffer-read-only t)))))
1266 1685
1267 ;; Generate the Ediff difference list between two files 1686 ;; Generate the difference vector and overlays for the two files
1268 (defun ediff-make-diff-list (file-A file-B) 1687 ;; With optional arg `refine', create refining difference regions
1269 (setq ediff-diff-buffer 1688 (defun ediff-setup-diff-regions (file-A file-B
1270 (get-buffer-create (emerge-unique-buffer-name "*ediff-diff" "*"))) 1689 &optional use-old refine-region
1690 diff-program diff-options
1691 diff-ok-lines-regexp)
1692
1693 (setq diff-program (or diff-program ediff-diff-program)
1694 diff-options (or diff-options ediff-diff-options)
1695 diff-ok-lines-regexp
1696 (or diff-ok-lines-regexp ediff-diff-ok-lines-regexp))
1697
1698 (or use-old (setq ediff-diff-buffer
1699 (get-buffer-create
1700 (emerge-unique-buffer-name "*ediff-diff" "*"))))
1271 (emerge-eval-in-buffer 1701 (emerge-eval-in-buffer
1272 ediff-diff-buffer 1702 ediff-diff-buffer
1273 (erase-buffer) 1703 (erase-buffer)
1274 ;; shell-command tends to display old shell command buffers even when it 1704 ;; shell-command tends to display old shell command buffers even when it
1275 ;; puts output in another buffer---probably an Emacs bug. 1705 ;; puts output in another buffer---probably an Emacs bug.
1276 (ediff-kill-buffer-carefully "*Shell Command Output*") 1706 (ediff-kill-buffer-carefully "*Shell Command Output*")
1277 (let ((shell-file-name ediff-shell)) 1707 (let ((shell-file-name ediff-shell))
1278 (message "Ediff: Computing differences ...")(sit-for .5) 1708 (if refine-region
1709 (message "Refining difference region %d ..." (1+ refine-region))
1710 (message "Computing differences ...")(sit-for .5))
1279 (shell-command 1711 (shell-command
1280 (format "%s %s %s %s" 1712 (format "%s %s %s %s"
1281 ediff-diff-program ediff-diff-options 1713 diff-program diff-options
1282 (emerge-protect-metachars file-A) 1714 (ediff-protect-metachars file-A)
1283 (emerge-protect-metachars file-B)) 1715 (ediff-protect-metachars file-B))
1284 t) 1716 t)
1285 )) 1717 ))
1286 (ediff-prepare-error-list ediff-diff-ok-lines-regexp) 1718 (ediff-prepare-error-list diff-ok-lines-regexp)
1287 (message "Ediff: Computing differences ... Done.")(sit-for .5) 1719 (if refine-region
1288 (ediff-convert-diffs-to-overlays 1720 (message "Refining difference region %d ... Done." (1+ refine-region))
1289 ediff-A-buffer ediff-B-buffer 1721 (message "Computing differences ... Done.")(sit-for .5))
1290 (ediff-extract-diffs ediff-diff-buffer ediff-A-buffer ediff-B-buffer))) 1722 (if refine-region
1723 (ediff-convert-diffs-to-overlays-refine
1724 ediff-A-buffer ediff-B-buffer
1725 (ediff-extract-diffs ediff-diff-buffer)
1726 refine-region)
1727 (ediff-convert-diffs-to-overlays
1728 ediff-A-buffer ediff-B-buffer
1729 (ediff-extract-diffs ediff-diff-buffer ediff-A-buffer ediff-B-buffer)))
1730 )
1731
1291 1732
1292 (defun ediff-prepare-error-list (ok-regexp) 1733 (defun ediff-prepare-error-list (ok-regexp)
1293 (let ((diff-buff ediff-diff-buffer)) 1734 (let ((diff-buff ediff-diff-buffer))
1294 (setq ediff-diff-error-buffer
1295 (get-buffer-create (emerge-unique-buffer-name
1296 "*ediff-diff-errors" "*")))
1297 (emerge-eval-in-buffer 1735 (emerge-eval-in-buffer
1298 ediff-diff-error-buffer 1736 ediff-error-buffer
1299 (erase-buffer) 1737 (erase-buffer)
1300 (insert-buffer diff-buff) 1738 (insert-buffer diff-buff)
1301 (delete-matching-lines ok-regexp)))) 1739 (delete-matching-lines ok-regexp))))
1302 1740
1303 ;;; Function to start Ediff by patching a file 1741 ;;; Function to start Ediff by patching a file
1304 1742
1305 ;;;###autoload 1743 ;;;###autoload
1306 (defun ediff-patch-file (file-to-patch &optional startup-hooks) 1744 (defun ediff-patch-file (file-to-patch &optional startup-hooks)
1307 "Run Ediff by patching FILE-TO-PATCH." 1745 "Run Ediff by patching FILE-TP-PATCH."
1308 (interactive "fFile to patch: ") 1746 (interactive "fFile to patch: ")
1309 1747
1310 (ediff-get-patch-buffer (file-name-directory file-to-patch)) 1748 (ediff-get-patch-buffer (file-name-directory file-to-patch))
1311 (let ((buf (get-file-buffer file-to-patch))) 1749 (let ((buf (get-file-buffer file-to-patch)))
1312 (if buf 1750 (if buf
1322 (set-buffer-modified-p nil)) 1760 (set-buffer-modified-p nil))
1323 (ediff-kill-buffer-carefully buf)))) 1761 (ediff-kill-buffer-carefully buf))))
1324 (emerge-eval-in-buffer 1762 (emerge-eval-in-buffer
1325 ediff-patch-diagnostics 1763 ediff-patch-diagnostics
1326 (let ((shell-file-name ediff-shell)) 1764 (let ((shell-file-name ediff-shell))
1327 (message "Ediff: Applying patch ... ")(sit-for .5) 1765 (message "Applying patch ... ")(sit-for .5)
1766 ;; always pass patch the -f option, so it won't ask any questions
1328 (shell-command-on-region 1767 (shell-command-on-region
1329 (point-min) (point-max) 1768 (point-min) (point-max)
1330 (format "%s %s %s" 1769 (format "%s %s %s"
1331 ediff-patch-program ediff-patch-options 1770 ediff-patch-program (concat "-f " ediff-patch-options)
1332 (expand-file-name file-to-patch)) 1771 (expand-file-name file-to-patch))
1333 t) 1772 t)
1334 (message "Ediff: Applying patch ... Done.")(sit-for .5) 1773 (message "Applying patch ... Done.")(sit-for .5)
1335 )) 1774 ))
1336 (switch-to-buffer ediff-patch-diagnostics) 1775 (switch-to-buffer ediff-patch-diagnostics)
1337 (sit-for 0) ;; synchronize 1776 (sit-for 0) ;; synchronize
1338 1777
1339 (setq startup-hooks (cons 'ediff-toggle-read-only-A startup-hooks)) 1778 (setq startup-hooks (cons 'ediff-toggle-read-only-A startup-hooks))
1340 (ediff-files (format "%s.orig" file-to-patch) file-to-patch startup-hooks) 1779 (if (file-exists-p (format "%s.orig" file-to-patch))
1780 (ediff-files
1781 (format "%s.orig" file-to-patch) file-to-patch startup-hooks)
1782 (error "Patch failed or didn't modify the original file."))
1341 1783
1342 (bury-buffer ediff-patch-diagnostics) 1784 (bury-buffer ediff-patch-diagnostics)
1343 (message "Patch diagnostics available in buffer %s." 1785 (message "Patch diagnostics available in buffer %s."
1344 (buffer-name ediff-patch-diagnostics))) 1786 (buffer-name ediff-patch-diagnostics)))
1345 1787
1346 (defalias 'epatch 'ediff-patch-file) 1788 (defalias 'epatch 'ediff-patch-file)
1789 (defalias 'epatch-buffer 'ediff-patch-buffer)
1347 1790
1348 ;;; Function to start Ediff on files 1791 ;;; Function to start Ediff on files
1349 1792
1350 ;;;###autoload 1793 ;;;###autoload
1351 (defun ediff-files (file-A file-B &optional startup-hooks) 1794 (defun ediff-files (file-A file-B &optional startup-hooks)
1360 (ediff-read-file-name "File B to compare" 1803 (ediff-read-file-name "File B to compare"
1361 (if ediff-use-last-dir 1804 (if ediff-use-last-dir
1362 ediff-last-dir-B nil) 1805 ediff-last-dir-B nil)
1363 f f) 1806 f f)
1364 ))) 1807 )))
1365 (ediff-files-internal file-A file-B startup-hooks)) 1808 (ediff-files-internal file-A
1809 (if (file-directory-p file-B)
1810 (expand-file-name
1811 (file-name-nondirectory file-A) file-B)
1812 file-B)
1813 startup-hooks))
1366 1814
1367 1815
1368 (defalias 'ediff 'ediff-files) 1816 (defalias 'ediff 'ediff-files)
1369 1817
1370 1818
1372 1820
1373 ;;;###autoload 1821 ;;;###autoload
1374 (defun ediff-buffers (buffer-A buffer-B &optional startup-hooks) 1822 (defun ediff-buffers (buffer-A buffer-B &optional startup-hooks)
1375 "Run Ediff on a pair of buffers, BUFFER-A and BUFFER-B." 1823 "Run Ediff on a pair of buffers, BUFFER-A and BUFFER-B."
1376 (interactive "bBuffer A to compare: \nbBuffer B to compare: ") 1824 (interactive "bBuffer A to compare: \nbBuffer B to compare: ")
1377 (let (ediff-file-A ediff-file-B) 1825 (let (file-A file-B)
1378 (emerge-eval-in-buffer 1826 (emerge-eval-in-buffer
1379 buffer-A 1827 buffer-A
1380 (setq ediff-file-A 1828 (setq file-A (ediff-make-temp-file)))
1381 (ediff-make-temp-file
1382 (format ".%s." (file-name-nondirectory (buffer-name)))))
1383 (write-region (point-min) (point-max) ediff-file-A nil 'no-message))
1384 (emerge-eval-in-buffer 1829 (emerge-eval-in-buffer
1385 buffer-B 1830 buffer-B
1386 (setq ediff-file-B 1831 (setq file-B (ediff-make-temp-file)))
1387 (ediff-make-temp-file 1832 (ediff-setup (get-buffer buffer-A) file-A
1388 (format ".%s." (file-name-nondirectory (buffer-name))))) 1833 (get-buffer buffer-B) file-B
1389 (write-region (point-min) (point-max) ediff-file-B nil 'no-message))
1390 (ediff-setup (get-buffer buffer-A) ediff-file-A
1391 (get-buffer buffer-B) ediff-file-B
1392 (cons (` (lambda () 1834 (cons (` (lambda ()
1393 (delete-file (, ediff-file-A)) 1835 (delete-file (, file-A))
1394 (delete-file (, ediff-file-B)))) 1836 (delete-file (, file-B))))
1395 startup-hooks) 1837 startup-hooks)
1396 ))) 1838 )))
1397 1839
1398 ;;;###autoload 1840 ;;;;###autoload
1399 (defun ediff-patch-buffer (buffer-name &optional startup-hooks) 1841 (defun ediff-patch-buffer (buffer-name &optional startup-hooks)
1400 "Run Ediff by patching BUFFER-NAME." 1842 "Run Ediff by patching BUFFER-NAME."
1401 (interactive "bBuffer to patch: ") 1843 (interactive "bBuffer to patch: ")
1402 1844
1403 (let* ((file-buffer (get-buffer buffer-name)) 1845 (let* ((file-buffer (get-buffer buffer-name))
1411 1853
1412 ;;; Versions Control functions 1854 ;;; Versions Control functions
1413 1855
1414 ;;;###autoload 1856 ;;;###autoload
1415 (defun vc-ediff (rev) 1857 (defun vc-ediff (rev)
1858 ;; Note: this function will work only with Emacs 19.22 and higher.
1416 "Run ediff on version REV of the current buffer in another window. 1859 "Run ediff on version REV of the current buffer in another window.
1417 If the current buffer is named `F', the version is named `F.~REV~'. 1860 If the current buffer is named `F', the version is named `F.~REV~'.
1418 If `F.~REV~' already exists, it is used instead of being re-created." 1861 If `F.~REV~' already exists, it is used instead of being re-created."
1419 (interactive "sVersion to ediff with (default is the latest version): ") 1862 (interactive "sVersion to ediff with (default is the latest version): ")
1420 (or (featurep 'vc) 1863 (or (featurep 'vc)
1423 (require 'vc-hooks) 1866 (require 'vc-hooks)
1424 (define-key vc-prefix-map "=" 'vc-ediff)) 1867 (define-key vc-prefix-map "=" 'vc-ediff))
1425 (error "The VC package is apparently not installed."))) 1868 (error "The VC package is apparently not installed.")))
1426 (let ((newvers (current-buffer)) 1869 (let ((newvers (current-buffer))
1427 (oldvers (vc-version-other-window rev))) 1870 (oldvers (vc-version-other-window rev)))
1428 (ediff-buffers newvers oldvers) 1871 ;; current-buffer is supposed to contain the old version in another
1872 ;; window
1873 (ediff-buffers newvers (current-buffer))
1429 )) 1874 ))
1430 1875
1431 (defun rcs-ediff-view-revision (&optional rev) 1876 (defun rcs-ediff-view-revision (&optional rev)
1432 "View previous RCS revison of current file. 1877 "View previous RCS revision of current file.
1433 With prefix argument, prompts for a revision name." 1878 With prefix argument, prompts for a revision name."
1434 (interactive (list (if current-prefix-arg 1879 (interactive (list (if current-prefix-arg
1435 (read-string "Revision: ")))) 1880 (read-string "Revision: "))))
1436 (let* ((filename (buffer-file-name (current-buffer))) 1881 (let* ((filename (buffer-file-name (current-buffer)))
1437 (switches (append '("-p") 1882 (switches (append '("-p")
1439 (buff (concat (file-name-nondirectory filename) ".~" rev "~"))) 1884 (buff (concat (file-name-nondirectory filename) ".~" rev "~")))
1440 (message "Working...") 1885 (message "Working...")
1441 (setq filename (expand-file-name filename)) 1886 (setq filename (expand-file-name filename))
1442 (with-output-to-temp-buffer 1887 (with-output-to-temp-buffer
1443 buff 1888 buff
1444 (let ((output-buffer (rcs-get-output-buffer filename buff))) 1889 (let ((output-buffer (ediff-rcs-get-output-buffer filename buff)))
1445 (delete-windows-on output-buffer) 1890 (delete-windows-on output-buffer)
1446 (save-excursion 1891 (save-excursion
1447 (set-buffer output-buffer) 1892 (set-buffer output-buffer)
1448 (apply 'call-process "co" nil t nil 1893 (apply 'call-process "co" nil t nil
1449 ;; -q: quiet (no diagnostics) 1894 ;; -q: quiet (no diagnostics)
1450 (append switches rcs-default-co-switches 1895 (append switches rcs-default-co-switches
1451 (list "-q" filename))))) 1896 (list "-q" filename)))))
1452 (message "") 1897 (message "")
1453 buff))) 1898 buff)))
1899
1900 (defun ediff-rcs-get-output-buffer (file name)
1901 ;; Get a buffer for RCS output for FILE, make it writable and clean it up.
1902 ;; Optional NAME is name to use instead of `*RCS-output*'.
1903 ;; This is a mofified version from rcs.el v1.1. I use it here to make
1904 ;; Ediff immune to changes in rcs.el
1905 (let* ((default-major-mode 'fundamental-mode);; no frills!
1906 (buf (get-buffer-create name)))
1907 (save-excursion
1908 (set-buffer buf)
1909 (setq buffer-read-only nil
1910 default-directory (file-name-directory (expand-file-name file)))
1911 (erase-buffer))
1912 buf))
1454 1913
1455 ;;;###autoload 1914 ;;;###autoload
1456 (defun rcs-ediff (&optional rev) 1915 (defun rcs-ediff (&optional rev)
1457 "Run Ediff on the current buffer, comparing it with previous RCS revison. 1916 "Run Ediff on the current buffer, comparing it with previous RCS revision.
1458 With prefix argument, prompts for revision name." 1917 With prefix argument, prompts for revision name."
1459 (interactive (list (if current-prefix-arg 1918 (interactive (list (if current-prefix-arg
1460 (read-string "Revision: ")))) 1919 (read-string "Revision: "))))
1461 (or (featurep 'rcs) 1920 (or (featurep 'rcs)
1462 (if (locate-library "rcs") 1921 (if (locate-library "rcs")
1514 (defun ediff-setup-windows (buffer-A buffer-B control-buffer &optional pos) 1973 (defun ediff-setup-windows (buffer-A buffer-B control-buffer &optional pos)
1515 ;; Make sure we are not in the minibuffer window when we try to delete 1974 ;; Make sure we are not in the minibuffer window when we try to delete
1516 ;; all other windows. 1975 ;; all other windows.
1517 (if (eq (selected-window) (minibuffer-window)) 1976 (if (eq (selected-window) (minibuffer-window))
1518 (other-window 1)) 1977 (other-window 1))
1519 (delete-other-windows) 1978 (or (ediff-leave-window-config control-buffer)
1520 (switch-to-buffer control-buffer) 1979 (progn
1521 (ediff-refresh-mode-line) 1980 (delete-other-windows)
1522 1981 (switch-to-buffer control-buffer)
1523 (ediff-arrange-buffer buffer-A buffer-B (current-buffer) pos) 1982 (ediff-refresh-mode-line)
1524 (ediff-arrange-buffer buffer-B buffer-A (current-buffer) pos) 1983
1525 ;; ediff-arrange-buffer always leaves in ctl buffer 1984 (ediff-arrange-buffer buffer-A buffer-B (current-buffer) pos)
1526 ;; setup ctl wind if it is not set. 1985 (ediff-arrange-buffer buffer-B buffer-A (current-buffer) pos)
1527 (ediff-setup-control-window) 1986 ;; ediff-arrange-buffer always leaves in ctl buffer
1528 1987 ;; setup ctl wind if it is not set.
1529 ;; If diff reports errors, display them rather than then compare buffers. 1988 (ediff-setup-control-window)
1530 (if (/= 0 (emerge-eval-in-buffer ediff-diff-error-buffer (buffer-size))) 1989
1531 (let ((diff-output-buf ediff-diff-buffer)) 1990 ;; If diff reports errors, show them then quit.
1532 (switch-to-buffer ediff-diff-error-buffer) 1991 (if (/= 0 (emerge-eval-in-buffer ediff-error-buffer (buffer-size)))
1533 (ediff-kill-buffer-carefully control-buffer) 1992 (let ((diff-output-buf ediff-diff-buffer))
1534 (error "Errors found in diff output. Diff output buffer is %s" 1993 (switch-to-buffer ediff-error-buffer)
1535 diff-output-buf)))) 1994 (ediff-kill-buffer-carefully control-buffer)
1995 (error "Errors found in diff output. Diff output buffer is %s"
1996 diff-output-buf))))))
1536 1997
1537 1998
1538 ;; Arranges goal-buf on the screen. 1999 ;; Arranges goal-buf on the screen.
1539 (defun ediff-arrange-buffer (goal-buf other-buf ctl-buf &optional pos) 2000 (defun ediff-arrange-buffer (goal-buf other-buf ctl-buf &optional pos)
1540 (let* ((ctl-wind (get-buffer-window ctl-buf t)) 2001 (let* ((ctl-wind (get-buffer-window ctl-buf t))
1590 "Set up window for control buffer." 2051 "Set up window for control buffer."
1591 (erase-buffer) 2052 (erase-buffer)
1592 (insert ediff-help-message) 2053 (insert ediff-help-message)
1593 (shrink-window-if-larger-than-buffer) 2054 (shrink-window-if-larger-than-buffer)
1594 (setq ediff-control-window (selected-window)) 2055 (setq ediff-control-window (selected-window))
2056 (setq ediff-window-config-saved
2057 (format "%S%S%S%S"
2058 ediff-control-window
2059 (get-buffer-window ediff-A-buffer t)
2060 (get-buffer-window ediff-B-buffer t)
2061 ediff-split-window-function))
1595 (goto-char (point-min)) 2062 (goto-char (point-min))
1596 (skip-chars-forward " \t\n")) 2063 (skip-chars-forward ediff-whitespace))
2064
2065 (defun ediff-leave-window-config (control-buf)
2066 (and (eq control-buf (current-buffer))
2067 (/= (buffer-size) 0)
2068 (emerge-eval-in-buffer
2069 control-buf
2070 (string= ediff-window-config-saved
2071 (format "%S%S%S%S"
2072 (get-buffer-window ediff-control-buffer t)
2073 (get-buffer-window ediff-A-buffer t)
2074 (get-buffer-window ediff-B-buffer t)
2075 ediff-split-window-function)))))
1597 2076
1598 2077
1599 ;; Set up the keymap in the control buffer 2078 ;; Set up the keymap in the control buffer
1600 (defun ediff-set-keys () 2079 (defun ediff-set-keys ()
1601 "Set up Ediff keymap, if necessary." 2080 "Set up Ediff keymap, if necessary."
1611 2090
1612 (defun ediff-before-change-guard (start end) 2091 (defun ediff-before-change-guard (start end)
1613 "If buffer is highlighted with ASCII flags, remove highlighting. 2092 "If buffer is highlighted with ASCII flags, remove highlighting.
1614 Arguments, START and END are not used, but are provided 2093 Arguments, START and END are not used, but are provided
1615 because this is required by `before-change-function'." 2094 because this is required by `before-change-function'."
1616 (let (notify) 2095 (let (rehighlight-key)
1617 (save-window-excursion 2096 (save-window-excursion
1618 (mapcar 2097 (mapcar
1619 (function 2098 (function
1620 (lambda (buf) 2099 (lambda (buf)
1621 (if (ediff-buffer-live-p buf) 2100 (if (ediff-buffer-live-p buf)
1624 (if (eq ediff-highlighting-style 'ascii) 2103 (if (eq ediff-highlighting-style 'ascii)
1625 (progn 2104 (progn
1626 (ediff-unselect-and-select-difference 2105 (ediff-unselect-and-select-difference
1627 ediff-current-difference 2106 ediff-current-difference
1628 'unselect-only 'no-recenter) 2107 'unselect-only 'no-recenter)
1629 (setq notify t) 2108 (setq rehighlight-key
2109 (substitute-command-keys "\\[ediff-recenter]"))
1630 )))))) 2110 ))))))
1631 ediff-this-buffer-control-sessions) 2111 ediff-this-buffer-control-sessions)
1632 (if notify 2112 (if rehighlight-key
1633 (error "ASCII flags removed. You can edit now. Hit 'c' to rehighlight.")) 2113 (error
2114 "ASCII flags removed. You can edit now. Hit %S to rehighlight."
2115 rehighlight-key))
1634 ))) 2116 )))
1635 2117
2118 (defun ediff-recompute-diffs ()
2119 "Recompute difference regions in buffers A and B."
2120 (interactive)
2121 (let ((curr-diff ediff-current-difference)
2122 (point-A (emerge-eval-in-buffer ediff-A-buffer (point)))
2123 (point-B (emerge-eval-in-buffer ediff-B-buffer (point)))
2124 file-A file-B)
2125 (ediff-unselect-and-select-difference -1)
2126 (emerge-eval-in-buffer
2127 ediff-A-buffer
2128 (setq file-A (ediff-make-temp-file)))
2129 (emerge-eval-in-buffer
2130 ediff-B-buffer
2131 (setq file-B (ediff-make-temp-file)))
2132 (ediff-clear-diff-vector ediff-difference-vector 'fine-diffs-also)
2133 (setq ediff-killed-diffs-alist nil) ; saved kills will no longer be valid
2134 ; after recompute
2135 (setq ediff-difference-vector
2136 (ediff-setup-diff-regions file-A file-B 'use-old))
2137 (setq ediff-number-of-differences (length ediff-difference-vector))
2138 (delete-file file-A)
2139 (delete-file file-B)
2140 (emerge-eval-in-buffer ediff-A-buffer (goto-char point-A))
2141 (ediff-jump-to-difference (ediff-diff-at-point 'A))
2142 (beep 1)
2143 (if (y-or-n-p
2144 "Ediff is around last posn in buff A. Stay (or goto last posn in B)? ")
2145 ()
2146 (emerge-eval-in-buffer ediff-B-buffer (goto-char point-B))
2147 (ediff-jump-to-difference (ediff-diff-at-point 'B)))
2148 (message "")
2149 ))
1636 2150
1637 (defun ediff-remember-buffer-characteristics (&optional arg) 2151 (defun ediff-remember-buffer-characteristics (&optional arg)
1638 "Record certain properties of the buffers being compared. 2152 "Record certain properties of the buffers being compared.
1639 Must be called in the control buffer. Saves `read-only', `modified', 2153 Must be called in the control buffer. Saves `read-only', `modified',
1640 and `auto-save' properties in buffer local variables. Turns off 2154 and `auto-save' properties in buffer local variables. Turns off
1667 (emerge-eval-in-buffer ediff-B-buffer 2181 (emerge-eval-in-buffer ediff-B-buffer
1668 (emerge-restore-variables ediff-saved-variables 2182 (emerge-restore-variables ediff-saved-variables
1669 B-values)))) 2183 B-values))))
1670 2184
1671 2185
1672 (defun ediff-extract-diffs (diff-buffer A-buffer B-buffer) 2186 ;; if optional A-buffer and B-buffer are given, then construct a vector of
2187 ;; diff using point values. Otherwise, use line offsets.
2188 (defun ediff-extract-diffs (diff-buffer &optional A-buffer B-buffer)
1673 (let (diff-list 2189 (let (diff-list
1674 (a-prev 1) ;; this is needed to set the first diff line correctly 2190 (a-prev 1) ;; this is needed to set the first diff line correctly
1675 (b-prev 1)) 2191 (b-prev 1))
1676 (emerge-eval-in-buffer 2192
1677 A-buffer 2193 (if (and A-buffer B-buffer)
1678 (goto-char (point-min))) 2194 (progn ;; reset point in buffers A and B
1679 (emerge-eval-in-buffer 2195 (emerge-eval-in-buffer
1680 B-buffer 2196 A-buffer
1681 (goto-char (point-min))) 2197 (goto-char (point-min)))
2198 (emerge-eval-in-buffer
2199 B-buffer
2200 (goto-char (point-min)))))
2201
1682 (emerge-eval-in-buffer 2202 (emerge-eval-in-buffer
1683 diff-buffer 2203 diff-buffer
1684 (goto-char (point-min)) 2204 (goto-char (point-min))
1685 (while (re-search-forward ediff-match-diff-line nil t) 2205 (while (re-search-forward ediff-match-diff-line nil t)
1686 (let* ((a-begin (string-to-int (buffer-substring (match-beginning 1) 2206 (let* ((a-begin (string-to-int (buffer-substring (match-beginning 1)
1710 b-begin (1+ b-begin) 2230 b-begin (1+ b-begin)
1711 b-end b-begin) 2231 b-end b-begin)
1712 ;; (string-equal diff-type "c") 2232 ;; (string-equal diff-type "c")
1713 (setq a-end (1+ a-end) 2233 (setq a-end (1+ a-end)
1714 b-end (1+ b-end)))) 2234 b-end (1+ b-end))))
1715 ;; convert to relative line numbers 2235 (if (and A-buffer B-buffer)
1716 (emerge-eval-in-buffer 2236 (progn ;; computing main diff vector
1717 A-buffer 2237 ;; convert to relative line numbers
1718 (forward-line (- a-begin a-prev)) 2238 (emerge-eval-in-buffer
1719 (setq a-begin-pt (point)) 2239 A-buffer
1720 (forward-line (- a-end a-begin)) 2240 (forward-line (- a-begin a-prev))
1721 (setq a-end-pt (point) 2241 (setq a-begin-pt (point))
1722 a-prev a-end)) 2242 (forward-line (- a-end a-begin))
1723 (emerge-eval-in-buffer 2243 (setq a-end-pt (point)
1724 B-buffer 2244 a-prev a-end))
1725 (forward-line (- b-begin b-prev)) 2245 (emerge-eval-in-buffer
1726 (setq b-begin-pt (point)) 2246 B-buffer
1727 (forward-line (- b-end b-begin)) 2247 (forward-line (- b-begin b-prev))
1728 (setq b-end-pt (point) 2248 (setq b-begin-pt (point))
1729 b-prev b-end)) 2249 (forward-line (- b-end b-begin))
1730 (setq diff-list (nconc diff-list (list (vector a-begin-pt a-end-pt 2250 (setq b-end-pt (point)
1731 b-begin-pt b-end-pt)))) 2251 b-prev b-end))
1732 ))) 2252 (setq diff-list
2253 (nconc diff-list (list (vector a-begin-pt a-end-pt
2254 b-begin-pt b-end-pt)))))
2255 ;; computing refinement vector
2256 (setq diff-list
2257 (nconc diff-list (list (vector (- a-begin a-prev)
2258 (- a-end a-begin)
2259 (- b-begin b-prev)
2260 (- b-end b-begin))))
2261 a-prev a-end
2262 b-prev b-end))
2263
2264 ))) ;; end emerge-eval-in-buffer
1733 diff-list 2265 diff-list
1734 )) 2266 ))
1735 2267
1736 (defun ediff-convert-diffs-to-overlays (A-buffer B-buffer diff-list) 2268 (defun ediff-convert-diffs-to-overlays (A-buffer B-buffer diff-list)
1737 (let* ((current-diff -1) 2269 (let* ((current-diff -1)
1738 (total-diffs (length diff-list)) 2270 (total-diffs (length diff-list))
1739 (control-buffer-suffix ediff-control-buffer-suffix) 2271 ; (control-buffer-suffix ediff-control-buffer-suffix)
1740 diff-overlay-list list-element 2272 diff-overlay-list list-element
1741 a-begin a-end b-begin b-end 2273 a-begin a-end b-begin b-end
1742 a-overlay b-overlay) 2274 a-overlay b-overlay)
1743 2275
1744 (while diff-list 2276 (while diff-list
1749 b-begin (aref list-element 2) 2281 b-begin (aref list-element 2)
1750 b-end (aref list-element 3)) 2282 b-end (aref list-element 3))
1751 2283
1752 ;; place overlays at the appropriate places in the buffers 2284 ;; place overlays at the appropriate places in the buffers
1753 (setq a-overlay (ediff-make-overlay a-begin a-end A-buffer)) 2285 (setq a-overlay (ediff-make-overlay a-begin a-end A-buffer))
1754 ;; priority of a-overlay and b-overlay should be equal. otherwise it 2286 ;; priorities of overlays should be equal in all ediff-control
1755 ;; won't work due to Emacs bug---insert-in-front-hooks will be called 2287 ;; buffers. otherwise it won't work due to Emacs
2288 ;; bug---insert-in-front-hooks will be called
1756 ;; only on behalf of the buffer with higher priority. 2289 ;; only on behalf of the buffer with higher priority.
1757 (ediff-overlay-put a-overlay 'priority ediff-shaded-overlay-priority) 2290 (ediff-overlay-put a-overlay 'priority ediff-shaded-overlay-priority)
1758 (ediff-overlay-put a-overlay 'ediff-diff-num current-diff) 2291 (ediff-overlay-put a-overlay 'ediff-diff-num current-diff)
1759 (ediff-overlay-put a-overlay 2292 (ediff-overlay-put a-overlay
1760 'insert-in-front-hooks '(ediff-insert-in-front)) 2293 'insert-in-front-hooks '(ediff-insert-in-front))
1761 (ediff-overlay-put a-overlay 2294 ; (ediff-overlay-put a-overlay
1762 'ediff-control-buffer control-buffer-suffix) 2295 ; 'ediff-control-buffer control-buffer-suffix)
1763 (ediff-overlay-put a-overlay 2296 (ediff-overlay-put a-overlay
1764 'face (if (ediff-odd-p current-diff) ;; odd diff 2297 'face (if (ediff-odd-p current-diff) ;; odd diff
1765 'ediff-odd-diff-face-A-var 2298 'ediff-odd-diff-face-A-var
1766 'ediff-even-diff-face-A-var)) 2299 'ediff-even-diff-face-A-var))
1767 2300
1768 (setq b-overlay (ediff-make-overlay b-begin b-end B-buffer)) 2301 (setq b-overlay (ediff-make-overlay b-begin b-end B-buffer))
1769 (ediff-overlay-put b-overlay 'priority ediff-shaded-overlay-priority) 2302 (ediff-overlay-put b-overlay 'priority ediff-shaded-overlay-priority)
1770 (ediff-overlay-put b-overlay 'ediff-diff-num current-diff) 2303 (ediff-overlay-put b-overlay 'ediff-diff-num current-diff)
1771 (ediff-overlay-put b-overlay 2304 (ediff-overlay-put b-overlay
1772 'insert-in-front-hooks '(ediff-insert-in-front)) 2305 'insert-in-front-hooks '(ediff-insert-in-front))
1773 (ediff-overlay-put b-overlay 2306 ; (ediff-overlay-put b-overlay
1774 'ediff-control-buffer control-buffer-suffix) 2307 ; 'ediff-control-buffer control-buffer-suffix)
1775 (ediff-overlay-put b-overlay 2308 (ediff-overlay-put b-overlay
1776 'face (if (ediff-odd-p current-diff) ;; odd diff 2309 'face (if (ediff-odd-p current-diff) ;; odd diff
1777 'ediff-odd-diff-face-B-var 2310 'ediff-odd-diff-face-B-var
1778 'ediff-even-diff-face-B-var)) 2311 'ediff-even-diff-face-B-var))
1779 2312
1788 (ediff-overlay-put a-overlay 'end-open nil) 2321 (ediff-overlay-put a-overlay 'end-open nil)
1789 (ediff-overlay-put b-overlay 'end-open nil))) 2322 (ediff-overlay-put b-overlay 'end-open nil)))
1790 2323
1791 ;; record all overlays for this difference 2324 ;; record all overlays for this difference
1792 (setq diff-overlay-list 2325 (setq diff-overlay-list
1793 (nconc diff-overlay-list (list (vector a-overlay b-overlay))) 2326 (nconc diff-overlay-list (list (vector a-overlay b-overlay nil)))
1794 diff-list (cdr diff-list)) 2327 diff-list (cdr diff-list))
1795 (message "Ediff: Processing diff region %d of %d" 2328 (message "Processing diff region %d of %d"
1796 current-diff total-diffs) 2329 current-diff total-diffs)
1797 ) ;; while 2330 ) ;; while
1798 ;; this is just to avoid confusing the user with diff num < total-diffs 2331 ;; this is just to avoid confusing the user with diff num < total-diffs
1799 (message "Ediff: Processing diff region %d of %d" 2332 (message "Processing diff region %d of %d"
1800 (1+ current-diff) total-diffs) 2333 (1+ current-diff) total-diffs)
1801 ;; convert the list of difference information into a vector for 2334 ;; convert the list of difference information into a vector for
1802 ;; fast access 2335 ;; fast access
1803 (setq ediff-difference-vector 2336 (apply 'vector diff-overlay-list)))
1804 (apply 'vector diff-overlay-list))))
1805 2337
1806 2338
1807 2339
1808 ;;; Commands 2340 ;;; Commands
1809 2341
1869 (if (eq frame-A frame-B) 2401 (if (eq frame-A frame-B)
1870 (setq ediff-split-window-function 2402 (setq ediff-split-window-function
1871 (if (eq ediff-split-window-function 'split-window-vertically) 2403 (if (eq ediff-split-window-function 'split-window-vertically)
1872 'split-window-horizontally 2404 'split-window-horizontally
1873 'split-window-vertically)) 2405 'split-window-vertically))
1874 (message "Buffers A and B are residing in different frames. Why split?")) 2406 (message "No splitting: Buffers A and B are in different frames."))
1875 (ediff-recenter 'no-rehighlight))) 2407 (ediff-recenter 'no-rehighlight)))
1876 2408
1877 (defun ediff-toggle-hilit () 2409 (defun ediff-toggle-hilit ()
1878 "Switch between highlighting using ASCII flags and highlighting using faces. 2410 "Switch between highlighting using ASCII flags and highlighting using faces.
1879 On a dumb terminal, switches between ASCII highlighting and no highlighting." 2411 On a dumb terminal, switches between ASCII highlighting and no highlighting."
1888 (ediff-unselect-and-select-difference ediff-current-difference 2420 (ediff-unselect-and-select-difference ediff-current-difference
1889 'select-only)) 2421 'select-only))
1890 (ediff-unselect-and-select-difference ediff-current-difference 2422 (ediff-unselect-and-select-difference ediff-current-difference
1891 'unselect-only) 2423 'unselect-only)
1892 ;; cycle through highlighting 2424 ;; cycle through highlighting
1893 (cond ((and ediff-want-faces (null ediff-highlight-selected-only)) 2425 (cond ((and ediff-want-faces ediff-highlight-all-diffs)
1894 (message "Ediff: Unhighlighted unselected difference regions.") 2426 (message "Unhighlighting unselected difference regions.")
1895 (setq ediff-highlight-selected-only t)) 2427 (setq ediff-highlight-all-diffs nil))
1896 (ediff-want-faces 2428 (ediff-want-faces
1897 (message "Ediff: Now using ASCII flags only.") 2429 (message "Highlighting with ASCII flags.")
1898 (setq ediff-want-faces nil)) 2430 (setq ediff-want-faces nil))
1899 (t 2431 (t
1900 (message "Ediff: Re-highlighted all difference regions.") 2432 (message "Re-highlighting all difference regions.")
1901 (setq ediff-want-faces t 2433 (setq ediff-want-faces t
1902 ediff-highlight-selected-only nil))) 2434 ediff-highlight-all-diffs t)))
1903 2435
1904 (if (and ediff-want-faces (null ediff-highlight-selected-only)) 2436 (if (and ediff-want-faces ediff-highlight-all-diffs)
1905 (if (not (face-differs-from-default-p 'ediff-odd-diff-face-A-var)) 2437 (if (not (face-differs-from-default-p 'ediff-odd-diff-face-A-var))
1906 (progn 2438 (progn
1907 (copy-face ediff-odd-diff-face-A 'ediff-odd-diff-face-A-var) 2439 (copy-face ediff-odd-diff-face-A 'ediff-odd-diff-face-A-var)
1908 (copy-face ediff-odd-diff-face-B 'ediff-odd-diff-face-B-var) 2440 (copy-face ediff-odd-diff-face-B 'ediff-odd-diff-face-B-var)
1909 (copy-face ediff-even-diff-face-A 'ediff-even-diff-face-A-var) 2441 (copy-face ediff-even-diff-face-A 'ediff-even-diff-face-A-var)
1916 (ediff-unselect-and-select-difference 2448 (ediff-unselect-and-select-difference
1917 ediff-current-difference 'select-only)) 2449 ediff-current-difference 'select-only))
1918 (ediff-operate-on-flags 'insert) 2450 (ediff-operate-on-flags 'insert)
1919 ) 2451 )
1920 2452
2453 (defun ediff-toggle-autorefine ()
2454 "Toggle auto-refine mode."
2455 (interactive)
2456 (if window-system
2457 (cond ((eq ediff-auto-refine 'nix)
2458 (setq ediff-auto-refine 'on)
2459 (ediff-make-fine-diffs ediff-current-difference 'noforce)
2460 (message "Auto-refining is ON."))
2461 ((eq ediff-auto-refine 'on)
2462 (message "Auto-refining is OFF.")
2463 (setq ediff-auto-refine 'off))
2464 (t
2465 (ediff-set-fine-diff-properties ediff-current-difference 'default)
2466 (message "Refinements are HIDDEN.")
2467 (setq ediff-auto-refine 'nix))
2468 )))
2469
1921 (defun ediff-toggle-help () 2470 (defun ediff-toggle-help ()
1922 "Toggle short/long help message." 2471 "Toggle short/long help message."
1923 (interactive) 2472 (interactive)
1924 (let (buffer-read-only) 2473 (let (buffer-read-only)
1925 (erase-buffer) 2474 (erase-buffer)
1926 (if (string= ediff-help-message ediff-help-message-long) 2475 (if (string= ediff-help-message ediff-help-message-long)
1927 (setq ediff-help-message ediff-help-message-short) 2476 (setq ediff-help-message ediff-help-message-short)
1928 (setq ediff-help-message ediff-help-message-long))) 2477 (setq ediff-help-message ediff-help-message-long)))
2478 (setq ediff-window-config-saved "") ;; force redisplay
1929 (ediff-recenter 'no-rehighlight)) 2479 (ediff-recenter 'no-rehighlight))
1930 2480
1931 2481
1932 (defun ediff-toggle-read-only-A () 2482 (defun ediff-toggle-read-only-A ()
1933 "Used as a startup hook to set `.orig' patch file read-only." 2483 "Used as a startup hook to set `.orig' patch file read-only."
1943 2493
1944 ;;; Window scrolling operations 2494 ;;; Window scrolling operations
1945 ;; These operations are designed to scroll all three windows the same amount, 2495 ;; These operations are designed to scroll all three windows the same amount,
1946 ;; so as to keep the text in them aligned. 2496 ;; so as to keep the text in them aligned.
1947 2497
1948 ;; Perform some operation on two file windows (if they are showing). 2498 ;; Perform some operation on the two file windows (if they are showing).
1949 ;; Catches all errors on the operation in the A and B windows. 2499 ;; Catches all errors on the operation in the A and B windows.
1950 ;; Usually, errors come from scrolling off the 2500 ;; Usually, errors come from scrolling off the
1951 ;; beginning or end of the buffer, and this gives nice nice error messages. 2501 ;; beginning or end of the buffer, and this gives nice nice error messages.
1952 (defun ediff-operate-on-windows (operation arg) 2502 (defun ediff-operate-on-windows (operation arg)
1953 (let* ((buffer-A ediff-A-buffer) 2503 (let* ((buffer-A ediff-A-buffer)
2075 (/ default-amount 2) 2625 (/ default-amount 2)
2076 ;; no argument means default amount 2626 ;; no argument means default amount
2077 default-amount)))))) 2627 default-amount))))))
2078 2628
2079 (defun ediff-position-region (beg end pos) 2629 (defun ediff-position-region (beg end pos)
2080 "This is a variation on `emerge-position-region'. 2630 "This is a variation on `emerge-position-region'.
2081 The difference is that it always tries to align difference regions in 2631 The difference is that it always tries to align difference regions in
2082 buffer-A and buffer-B, so that it will be easier to compare them." 2632 buffer-A and buffer-B, so that it will be easier to compare them."
2083 (set-window-start (selected-window) beg) 2633 (set-window-start (selected-window) beg)
2084 (if (pos-visible-in-window-p end) 2634 (if (pos-visible-in-window-p end)
2085 ;; Determine the number of lines that the region occupies 2635 ;; Determine the number of lines that the region occupies
2097 2)))) 2647 2))))
2098 (goto-char pos) 2648 (goto-char pos)
2099 ) 2649 )
2100 2650
2101 2651
2102 (defun ediff-next-difference (arg) 2652 (defun ediff-next-difference (&optional arg)
2103 "Advance to the next difference. 2653 "Advance to the next difference.
2104 With a prefix argument, go back that many differences." 2654 With a prefix argument, go back that many differences."
2105 (interactive "P") 2655 (interactive "P")
2106 (if (< ediff-current-difference ediff-number-of-differences) 2656 (if (< ediff-current-difference ediff-number-of-differences)
2107 (let ((n (min ediff-number-of-differences 2657 (let ((n (min ediff-number-of-differences
2108 (+ ediff-current-difference (if arg arg 1)))) 2658 (+ ediff-current-difference (if arg arg 1))))
2109 (buffer-read-only nil)) 2659 (buffer-read-only nil))
2110 (ediff-unselect-and-select-difference n)) 2660 (ediff-unselect-and-select-difference n))
2111 (error "At end of the difference list."))) 2661 (error "At end of the difference list.")))
2112 2662
2113 (defun ediff-previous-difference (arg) 2663 (defun ediff-previous-difference (&optional arg)
2114 "Go to the previous difference. 2664 "Go to the previous difference.
2115 With a prefix argument, go back that many differences." 2665 With a prefix argument, go back that many differences."
2116 (interactive "P") 2666 (interactive "P")
2117 (if (> ediff-current-difference -1) 2667 (if (> ediff-current-difference -1)
2118 (let ((n (max -1 (- ediff-current-difference (if arg arg 1)))) 2668 (let ((n (max -1 (- ediff-current-difference (if arg arg 1))))
2131 (error "Bad difference number")))) 2681 (error "Bad difference number"))))
2132 2682
2133 (defun ediff-jump-to-difference-at-point () 2683 (defun ediff-jump-to-difference-at-point ()
2134 "Go to the difference closest to the point in buffer A or B. 2684 "Go to the difference closest to the point in buffer A or B.
2135 If this command is invoked via `ja' or `ga' then the point in buffer A is 2685 If this command is invoked via `ja' or `ga' then the point in buffer A is
2136 used. Otherwise, buffer B is used." 2686 used. Otherwise, buffer B is used."
2137 (interactive) 2687 (interactive)
2138 (let ((buffer-read-only nil) 2688 (let ((buffer-read-only nil)
2139 (buf-type (if (eq last-command-char ?a) 'A 'B))) 2689 (buf-type (ediff-char-to-buftype last-command-char)))
2140
2141 (ediff-jump-to-difference (ediff-diff-at-point buf-type)))) 2690 (ediff-jump-to-difference (ediff-diff-at-point buf-type))))
2142 2691
2143 2692
2144 ;; find region "most related to the current point position 2693 ;; find region "most related to the current point position
2145 2694
2146 (defun ediff-diff-at-point (buf-type) 2695 (defun ediff-diff-at-point (buf-type)
2147 (let ((buffer (if (eq buf-type 'A) ediff-A-buffer ediff-B-buffer)) 2696 (let ((buffer (ediff-get-buffer buf-type))
2148 (ctl-buffer ediff-control-buffer) 2697 (ctl-buffer ediff-control-buffer)
2149 (diff-no -1) 2698 (diff-no -1)
2150 (prev-beg 0) 2699 (prev-beg 0)
2151 (beg 0)) 2700 (prev-end 0)
2701 (beg 0)
2702 (end 0))
2152 2703
2153 (emerge-eval-in-buffer 2704 (emerge-eval-in-buffer
2154 buffer 2705 buffer
2155 (while (or (< (point) prev-beg) (> (point) beg)) 2706 (while (or (< (point) prev-beg) (> (point) beg))
2156 (setq diff-no (1+ diff-no)) 2707 (setq diff-no (1+ diff-no))
2157 (setq prev-beg beg) 2708 (setq prev-beg beg
2158 (setq beg (ediff-get-diff-posn buf-type 'beg diff-no ctl-buffer))) 2709 prev-end end)
2710 (setq beg (ediff-get-diff-posn buf-type 'beg diff-no ctl-buffer)
2711 end (ediff-get-diff-posn buf-type 'end diff-no ctl-buffer))
2712 )
2159 2713
2160 (if (< (abs (- (point) prev-beg)) 2714 (if (< (abs (- (point) prev-end))
2161 (abs (- (point) beg))) 2715 (abs (- (point) beg)))
2162 diff-no 2716 diff-no
2163 (1+ diff-no)) ;; jump-to-diff works with diff nums higher by 1 2717 (1+ diff-no)) ;; jump-to-diff works with diff nums higher by 1
2164 ))) 2718 )))
2165 2719
2171 Otherwise, copy the difference given by `ediff-current-difference'." 2725 Otherwise, copy the difference given by `ediff-current-difference'."
2172 (interactive "P") 2726 (interactive "P")
2173 (if arg 2727 (if arg
2174 (ediff-jump-to-difference arg)) 2728 (ediff-jump-to-difference arg))
2175 (ediff-copy-diff ediff-current-difference 2729 (ediff-copy-diff ediff-current-difference
2176 (if (eq last-command-char ?a) 'B 'A)) 2730 (ediff-char-to-buftype (aref (this-command-keys) 0))
2731 (ediff-char-to-buftype (aref (this-command-keys) 1)))
2177 (ediff-recenter 'no-rehighlight)) 2732 (ediff-recenter 'no-rehighlight))
2178 2733
2179 2734
2180 (defun ediff-copy-diff (n buf-type) 2735 (defun ediff-copy-diff (n from-buf-type to-buf-type)
2181 "Copy diff N from BUF-TYPE \(given as `A' or `B'\)." 2736 "Copy diff N from FROM-BUF-TYPE \(given as 'A or 'B\) to TO-BUF-TYPE."
2182 (let* ((other-buf (if (eq buf-type 'A) 2737 (let* ((to-buf (ediff-get-buffer to-buf-type))
2183 ediff-B-buffer ediff-A-buffer)) 2738 (from-buf (ediff-get-buffer from-buf-type))
2184 (buf (if (eq buf-type 'A)
2185 ediff-A-buffer ediff-B-buffer))
2186 (other-buf-type (if (eq buf-type 'A) 'B 'A))
2187 (ctrl-buf ediff-control-buffer) 2739 (ctrl-buf ediff-control-buffer)
2188 reg-to-copy reg-to-delete 2740 reg-to-copy reg-to-delete
2189 reg-to-delete-beg reg-to-delete-end) 2741 reg-to-delete-beg reg-to-delete-end)
2190 2742
2191 (ediff-operate-on-flags 'remove) 2743 (ediff-operate-on-flags 'remove)
2192 (setq reg-to-delete-beg 2744 (setq reg-to-delete-beg
2193 (ediff-get-diff-posn other-buf-type 'beg n ctrl-buf)) 2745 (ediff-get-diff-posn to-buf-type 'beg n ctrl-buf))
2194 (setq reg-to-delete-end 2746 (setq reg-to-delete-end
2195 (ediff-get-diff-posn other-buf-type 'end n ctrl-buf)) 2747 (ediff-get-diff-posn to-buf-type 'end n ctrl-buf))
2196 (setq reg-to-copy (emerge-eval-in-buffer 2748 (setq reg-to-copy (emerge-eval-in-buffer
2197 buf 2749 from-buf
2198 (buffer-substring (ediff-get-diff-posn 2750 (buffer-substring (ediff-get-diff-posn
2199 buf-type 'beg n ctrl-buf) 2751 from-buf-type 'beg n ctrl-buf)
2200 (ediff-get-diff-posn 2752 (ediff-get-diff-posn
2201 buf-type 'end n ctrl-buf)))) 2753 from-buf-type 'end n ctrl-buf))))
2202 (setq reg-to-delete (emerge-eval-in-buffer 2754 (setq reg-to-delete (emerge-eval-in-buffer
2203 other-buf 2755 to-buf
2204 (buffer-substring reg-to-delete-beg 2756 (buffer-substring reg-to-delete-beg
2205 reg-to-delete-end))) 2757 reg-to-delete-end)))
2206 (setq ediff-disturbed-overlays nil) ;; clear before use 2758 (setq ediff-disturbed-overlays nil) ;; clear before use
2207 2759
2208 (if (string= reg-to-delete reg-to-copy) 2760 (if (string= reg-to-delete reg-to-copy)
2209 (progn 2761 (progn
2210 (ding) 2762 (ding)
2211 (message 2763 (message
2212 "Diff regions %d are identical in buffers A and B. Nothing copied." 2764 "Diff regions %d are identical in buffers %S and %S. Nothing copied."
2213 (1+ n))) 2765 (1+ n) from-buf-type to-buf-type))
2214 2766
2215 ;; seems ok to copy 2767 ;; seems ok to copy
2216 (if (ediff-test-save-region n other-buf-type) 2768 (if (ediff-test-save-region n to-buf-type)
2217 (condition-case conds 2769 (condition-case conds
2218 (let (inhibit-read-only) 2770 (let (inhibit-read-only)
2219 (emerge-eval-in-buffer 2771 (emerge-eval-in-buffer
2220 other-buf 2772 to-buf
2221 ;; to prevent flags from interfering if buffer is writable 2773 ;; to prevent flags from interfering if buffer is writable
2222 (setq inhibit-read-only (null buffer-read-only)) 2774 (setq inhibit-read-only (null buffer-read-only))
2223 (let ((before-change-function nil)) 2775 (let ((before-change-function nil))
2224 (goto-char reg-to-delete-end) 2776 (goto-char reg-to-delete-end)
2225 (insert-before-markers reg-to-copy) 2777 (insert-before-markers reg-to-copy)
2235 reg-to-delete-beg))))) 2787 reg-to-delete-beg)))))
2236 (if (> reg-to-delete-end reg-to-delete-beg) 2788 (if (> reg-to-delete-end reg-to-delete-beg)
2237 (kill-region reg-to-delete-beg reg-to-delete-end) 2789 (kill-region reg-to-delete-beg reg-to-delete-end)
2238 (ediff-move-disturbed-overlays reg-to-delete-beg))) 2790 (ediff-move-disturbed-overlays reg-to-delete-beg)))
2239 )) 2791 ))
2240 (ediff-save-diff-region n other-buf-type reg-to-delete)) 2792 (ediff-save-diff-region n to-buf-type reg-to-delete))
2241 (error (message "%s %s" 2793 (error (message "%s %s"
2242 (car conds) 2794 (car conds)
2243 (mapconcat 'prin1-to-string (cdr conds) " ")) 2795 (mapconcat 'prin1-to-string (cdr conds) " "))
2244 (beep 1)))) 2796 (beep 1))))
2245 ) 2797 )
2247 )) 2799 ))
2248 2800
2249 (defun ediff-save-diff-region (n buf-type reg) 2801 (defun ediff-save-diff-region (n buf-type reg)
2250 "Save Nth diff of buffer BUF-TYPE \(`A' or `B'\). 2802 "Save Nth diff of buffer BUF-TYPE \(`A' or `B'\).
2251 That is to say, the Nth diff on the `ediff-killed-diffs-alist'. REG 2803 That is to say, the Nth diff on the `ediff-killed-diffs-alist'. REG
2252 is the region to save. It is redundant here,but is passed anyway, for 2804 is the region to save. It is redundant here, but is passed anyway, for
2253 convenience." 2805 convenience."
2254 2806
2255 (let* ((n-th-diff-saved (assoc n ediff-killed-diffs-alist)) 2807 (let* ((n-th-diff-saved (assoc n ediff-killed-diffs-alist))
2256 (this-buf-n-th-diff-saved (assoc buf-type (cdr n-th-diff-saved)))) 2808 (this-buf-n-th-diff-saved (assoc buf-type (cdr n-th-diff-saved))))
2257 2809
2262 (if n-th-diff-saved ;; n-th diff saved, but for another buffer 2814 (if n-th-diff-saved ;; n-th diff saved, but for another buffer
2263 (nconc n-th-diff-saved (list (cons buf-type reg))) 2815 (nconc n-th-diff-saved (list (cons buf-type reg)))
2264 (setq ediff-killed-diffs-alist ;; create record for n-th diff 2816 (setq ediff-killed-diffs-alist ;; create record for n-th diff
2265 (cons (list n (cons buf-type reg)) 2817 (cons (list n (cons buf-type reg))
2266 ediff-killed-diffs-alist)))) 2818 ediff-killed-diffs-alist))))
2267 (message "Saved diff region #%d for buffer %S. To recover hit '%s'." 2819 (message "Saved diff region #%d for buffer %S. To recover hit 'r%s'."
2268 (1+ n) buf-type (if (eq buf-type 'A) "ra" "rb")))) 2820 (1+ n) buf-type
2821 (downcase (symbol-name buf-type)))))
2269 2822
2270 (defun ediff-test-save-region (n buf-type) 2823 (defun ediff-test-save-region (n buf-type)
2271 "Test if saving Nth difference region of buffer BUF-TYPE is possible." 2824 "Test if saving Nth difference region of buffer BUF-TYPE is possible."
2272 (let* ((n-th-diff-saved (assoc n ediff-killed-diffs-alist)) 2825 (let* ((n-th-diff-saved (assoc n ediff-killed-diffs-alist))
2273 (this-buf-n-th-diff-saved (assoc buf-type (cdr n-th-diff-saved)))) 2826 (this-buf-n-th-diff-saved (assoc buf-type (cdr n-th-diff-saved))))
2274 2827
2275 (if this-buf-n-th-diff-saved 2828 (if this-buf-n-th-diff-saved
2276 (if (yes-or-no-p 2829 (if (yes-or-no-p
2277 (format 2830 (format
2278 "You've previously copied diff %d from %S to %S. Confirm. " 2831 "You've previously copied diff region %d to buffer %S. Confirm."
2279 (1+ n) (if (eq buf-type 'A) 'B 'A) buf-type)) 2832 (1+ n) buf-type))
2280 t 2833 t
2281 (error "Quit.")) 2834 (error "Quit."))
2282 t))) 2835 t)))
2283 2836
2284 (defun ediff-pop-diff (n buf-type) 2837 (defun ediff-pop-diff (n buf-type)
2285 "Pop last killed Nth diff region from buffer BUF-TYPE." 2838 "Pop last killed Nth diff region from buffer BUF-TYPE."
2286 (let* ((n-th-record (assoc n ediff-killed-diffs-alist)) 2839 (let* ((n-th-record (assoc n ediff-killed-diffs-alist))
2287 (saved-rec (assoc buf-type (cdr n-th-record))) 2840 (saved-rec (assoc buf-type (cdr n-th-record)))
2288 (buf (if (eq buf-type 'A) ediff-A-buffer ediff-B-buffer)) 2841 (buf (ediff-get-buffer buf-type))
2289 saved-diff reg-beg reg-end recovered) 2842 saved-diff reg-beg reg-end recovered)
2290 2843
2291 (if (cdr saved-rec) 2844 (if (cdr saved-rec)
2292 (setq saved-diff (cdr saved-rec)) 2845 (setq saved-diff (cdr saved-rec))
2293 (error "Nothing saved for diff %d in buffer %S." (1+ n) buf-type)) 2846 (if (> ediff-number-of-differences 0)
2847 (error "Nothing saved for diff %d in buffer %S." (1+ n) buf-type)
2848 (error "No differences found.")))
2294 2849
2295 (ediff-operate-on-flags 'remove) 2850 (ediff-operate-on-flags 'remove)
2296 2851
2297 (setq reg-beg (ediff-get-diff-posn buf-type 'beg n ediff-control-buffer)) 2852 (setq reg-beg (ediff-get-diff-posn buf-type 'beg n ediff-control-buffer))
2298 (setq reg-end (ediff-get-diff-posn buf-type 'end n ediff-control-buffer)) 2853 (setq reg-end (ediff-get-diff-posn buf-type 'end n ediff-control-buffer))
2327 2882
2328 (ediff-operate-on-flags 'insert) 2883 (ediff-operate-on-flags 'insert)
2329 (if recovered 2884 (if recovered
2330 (progn 2885 (progn
2331 (setq n-th-record (delq saved-rec n-th-record)) 2886 (setq n-th-record (delq saved-rec n-th-record))
2332 (message "Diff region %d restored for buffer %S." (1+ n) buf-type))) 2887 (message "Restored diff region %d in buffer %S." (1+ n) buf-type)))
2333 )) 2888 ))
2334 2889
2335 (defun ediff-restore-diff (arg) 2890 (defun ediff-restore-diff (arg)
2336 "Restore ARGth diff from `ediff-killed-diffs-alist'. 2891 "Restore ARGth diff from `ediff-killed-diffs-alist'.
2337 ARG is a prefix argument. If ARG is nil, restore current-difference." 2892 ARG is a prefix argument. If ARG is nil, restore current-difference."
2338 (interactive "P") 2893 (interactive "P")
2339 (if arg 2894 (if arg
2340 (ediff-jump-to-difference arg)) 2895 (ediff-jump-to-difference arg))
2341 (ediff-pop-diff ediff-current-difference 2896 (ediff-pop-diff ediff-current-difference
2342 (if (eq last-command-char ?a) 'A 'B)) 2897 (ediff-char-to-buftype last-command-char))
2343 (ediff-recenter 'no-rehighlight)) 2898 (ediff-recenter 'no-rehighlight))
2344 2899
2345 2900
2346 ;;; Quitting, suspending, etc. 2901 ;;; Quitting, suspending, etc.
2347 (defun ediff-quit () 2902 (defun ediff-quit ()
2353 (if (prog1 2908 (if (prog1
2354 (y-or-n-p "Do you really want to exit Ediff? ") 2909 (y-or-n-p "Do you really want to exit Ediff? ")
2355 (message "")) 2910 (message ""))
2356 (ediff-really-quit))) 2911 (ediff-really-quit)))
2357 2912
2913
2358 ;; Perform the quit operations. 2914 ;; Perform the quit operations.
2359 (defun ediff-really-quit () 2915 (defun ediff-really-quit ()
2360 (setq buffer-read-only nil)
2361 (ediff-unselect-and-select-difference -1)
2362 ;; null out the difference overlays so they won't slow down future editing
2363 ;; operations
2364 (mapcar (function (lambda (d)
2365 (ediff-delete-overlay (aref d 0))
2366 (ediff-delete-overlay (aref d 1))))
2367 ediff-difference-vector)
2368 ;; allow them to be garbage collected
2369 (setq ediff-difference-vector nil)
2370 (setq ediff-help-message ediff-help-message-long) 2916 (setq ediff-help-message ediff-help-message-long)
2371 (ediff-restore-buffer-characteristics t) ;; restore as they were at setup 2917 (ediff-restore-buffer-characteristics t) ;; restore as they were at setup
2372 (ediff-unhighlight-diffs-totally) 2918 (ediff-unhighlight-diffs-totally)
2919 (ediff-clear-diff-vector ediff-difference-vector 'fine-diffs-also)
2920 (if ediff-temp-file-A (delete-file ediff-temp-file-A))
2921 (if ediff-temp-file-B (delete-file ediff-temp-file-B))
2373 2922
2374 ;; restore buffer mode line id's in buffer-A/B 2923 ;; restore buffer mode line id's in buffer-A/B
2375 (let ((control-buffer ediff-control-buffer)) 2924 (let ((control-buffer ediff-control-buffer))
2376 (emerge-eval-in-buffer 2925 (emerge-eval-in-buffer
2377 ediff-A-buffer 2926 ediff-A-buffer
2404 ;; frame split between the two diff'ed files. 2953 ;; frame split between the two diff'ed files.
2405 (defun ediff-default-quit-hook () 2954 (defun ediff-default-quit-hook ()
2406 (let ((buff-A ediff-A-buffer) 2955 (let ((buff-A ediff-A-buffer)
2407 (buff-B ediff-B-buffer)) 2956 (buff-B ediff-B-buffer))
2408 (ediff-kill-buffer-carefully ediff-diff-buffer) 2957 (ediff-kill-buffer-carefully ediff-diff-buffer)
2409 (ediff-kill-buffer-carefully ediff-diff-error-buffer) 2958 (ediff-kill-buffer-carefully ediff-tmp-buffer)
2959 (ediff-kill-buffer-carefully ediff-error-buffer)
2410 (ediff-kill-buffer-carefully ediff-control-buffer) 2960 (ediff-kill-buffer-carefully ediff-control-buffer)
2411 (ediff-kill-buffer-carefully ediff-patch-diagnostics) 2961 (ediff-kill-buffer-carefully ediff-patch-diagnostics)
2412 (delete-other-windows) 2962 (delete-other-windows)
2413 (switch-to-buffer buff-B) 2963 (switch-to-buffer buff-B)
2414 (split-window-vertically) 2964 (split-window-vertically)
2419 (defun ediff-default-suspend-hook () 2969 (defun ediff-default-suspend-hook ()
2420 (let ((buf-A ediff-A-buffer) 2970 (let ((buf-A ediff-A-buffer)
2421 (buf-B ediff-B-buffer) 2971 (buf-B ediff-B-buffer)
2422 (buf-patch ediff-patch-buf) 2972 (buf-patch ediff-patch-buf)
2423 (buf-patch-diag ediff-patch-diagnostics) 2973 (buf-patch-diag ediff-patch-diagnostics)
2424 (buf-err ediff-diff-error-buffer) 2974 (buf-err ediff-error-buffer)
2425 (buf-diff ediff-diff-buffer)) 2975 (buf-diff ediff-diff-buffer))
2426 (bury-buffer) ;; ediff-control-buffer 2976 (bury-buffer) ;; ediff-control-buffer
2427 (delete-other-windows) 2977 (delete-other-windows)
2428 (bury-buffer buf-err) 2978 (bury-buffer buf-err)
2429 (bury-buffer buf-diff) 2979 (bury-buffer buf-diff)
2437 "Suspend Ediff. 2987 "Suspend Ediff.
2438 To resume, switch to the appropriate `*ediff-control*' 2988 To resume, switch to the appropriate `*ediff-control*'
2439 buffer and then type \\[ediff-recenter]. Ediff will automatically set 2989 buffer and then type \\[ediff-recenter]. Ediff will automatically set
2440 up an appropriate window config." 2990 up an appropriate window config."
2441 (interactive) 2991 (interactive)
2992 (let ((key (substitute-command-keys "\\[ediff-recenter]")))
2442 (run-hooks 'ediff-suspend-hooks) 2993 (run-hooks 'ediff-suspend-hooks)
2443 (message 2994 (message
2444 "To resume, switch to *ediff-control* and hit 'c' (ediff-recenter).")) 2995 "To resume Ediff, switch to *ediff-control* and hit '%S'" key)))
2445 2996
2446 2997
2447 (defun ediff-file-names () 2998 (defun ediff-file-names ()
2448 "Show the names of the buffers or files being operated on by Ediff. 2999 "Show the names of the buffers or files being operated on by Ediff.
2449 Hit \\[ediff-recenter] to reset the windows afterward." 3000 Hit \\[ediff-recenter] to reset the windows afterward."
2450 (interactive) 3001 (interactive)
2451 (with-output-to-temp-buffer "*Help*" 3002 (with-output-to-temp-buffer "*Help*"
2452 (emerge-eval-in-buffer ediff-A-buffer 3003 (emerge-eval-in-buffer ediff-A-buffer
2453 (if buffer-file-name 3004 (if buffer-file-name
2454 (progn 3005 (princ
2455 (princ "File A is: ") 3006 (format "File A is: %s\n" buffer-file-name))
2456 (princ buffer-file-name)) 3007 (princ
2457 (progn 3008 (format "Buffer A is: %s\n" (buffer-name)))))
2458 (princ "Buffer A is: ")
2459 (princ (buffer-name))))
2460 (princ "\n"))
2461 (emerge-eval-in-buffer ediff-B-buffer 3009 (emerge-eval-in-buffer ediff-B-buffer
2462 (if buffer-file-name 3010 (if buffer-file-name
2463 (progn 3011 (princ
2464 (princ "File B is: ") 3012 (format "File B is: %s\n" buffer-file-name))
2465 (princ buffer-file-name)) 3013 (princ
2466 (progn 3014 (format "Buffer B is: %s\n" (buffer-name)))))
2467 (princ "Buffer B is: ")
2468 (princ (buffer-name))))
2469 (princ "\n"))
2470 )) 3015 ))
2471 3016
2472 3017
2473 3018
2474 (defun ediff-line-numbers () 3019 (defun ediff-line-numbers ()
2498 (ediff-place-flags-in-buffer 'A ediff-A-buffer 3043 (ediff-place-flags-in-buffer 'A ediff-A-buffer
2499 ediff-control-buffer n) 3044 ediff-control-buffer n)
2500 (ediff-place-flags-in-buffer 'B ediff-B-buffer 3045 (ediff-place-flags-in-buffer 'B ediff-B-buffer
2501 ediff-control-buffer n)) 3046 ediff-control-buffer n))
2502 3047
3048 (if window-system
3049 (cond ((eq ediff-auto-refine 'on)
3050 (if (and
3051 (> ediff-auto-refine-limit
3052 (- (ediff-get-diff-posn 'A 'end n)
3053 (ediff-get-diff-posn 'A 'beg n)))
3054 (> ediff-auto-refine-limit
3055 (- (ediff-get-diff-posn 'B 'end n)
3056 (ediff-get-diff-posn 'B 'beg n))))
3057 (ediff-make-fine-diffs n 'noforce)
3058 (ediff-make-fine-diffs n 'skip)))
3059
3060 ((eq ediff-auto-refine 'off) ; highlight iff fine diffs
3061 (ediff-make-fine-diffs n 'skip)))) ; already exist
3062
2503 (ediff-restore-buffer-characteristics) 3063 (ediff-restore-buffer-characteristics)
2504 (run-hooks 'ediff-select-hooks)))) 3064 (run-hooks 'ediff-select-hooks))))
2505 3065
2506 3066
2507 ;; Unselect a difference by removing the ASCII flags in the buffers. 3067 ;; Unselect a difference by removing the ASCII flags in the buffers.
2524 (ediff-get-diff-posn 'B 'end n) 3084 (ediff-get-diff-posn 'B 'end n)
2525 ediff-before-flag-B ediff-after-flag-B))) 3085 ediff-before-flag-B ediff-after-flag-B)))
2526 3086
2527 (ediff-restore-buffer-characteristics) 3087 (ediff-restore-buffer-characteristics)
2528 (setq ediff-highlighting-style nil) 3088 (setq ediff-highlighting-style nil)
3089
3090 ;; unhighlight fine diffs
3091 (if window-system
3092 (ediff-set-fine-diff-properties
3093 ediff-current-difference 'default))
3094
2529 (run-hooks 'ediff-unselect-hooks)))) 3095 (run-hooks 'ediff-unselect-hooks))))
2530 3096
2531 3097
2532 ;; Unselects prev diff and selects a new one, if FLAG has value other than 3098 ;; Unselects prev diff and selects a new one, if FLAG has value other than
2533 ;; 'select-only or 'unselect-only. If FLAG is 'select-only, the 3099 ;; 'select-only or 'unselect-only. If FLAG is 'select-only, the
2541 ;; ASCII flags. 3107 ;; ASCII flags.
2542 ;; Instead, use `ediff-unselect-and-select-difference' with appropriate 3108 ;; Instead, use `ediff-unselect-and-select-difference' with appropriate
2543 ;; flags. 3109 ;; flags.
2544 3110
2545 (defun ediff-unselect-and-select-difference (n &optional flag no-recenter) 3111 (defun ediff-unselect-and-select-difference (n &optional flag no-recenter)
2546 (let ((wind (selected-window)) 3112 (let (;; save buf modified info
2547 ;; save buf modified info 3113 (control-buf ediff-control-buffer)
2548 (buf-A-modified (buffer-modified-p ediff-A-buffer)) 3114 (buf-A-modified (buffer-modified-p ediff-A-buffer))
2549 (buf-B-modified (buffer-modified-p ediff-B-buffer)) 3115 (buf-B-modified (buffer-modified-p ediff-B-buffer))
2550 ;; temporarily disable undo so highlighting won't confuse the user 3116 ;; temporarily disable undo so highlighting won't confuse the user
2551 buf-A-undo buf-B-undo) 3117 buf-A-undo buf-B-undo)
2552 3118
3119 (let ((ediff-current-difference n))
3120 (or no-recenter
3121 (ediff-recenter 'no-rehighlight)))
3122
3123 (emerge-eval-in-buffer
3124 ediff-A-buffer
3125 (setq buf-A-undo buffer-undo-list))
3126 (emerge-eval-in-buffer
3127 ediff-B-buffer
3128 (setq buf-B-undo buffer-undo-list))
3129
3130 (buffer-disable-undo ediff-A-buffer)
3131 (buffer-disable-undo ediff-B-buffer)
3132
3133 (unwind-protect ;; we don't want to lose undo info due to error
3134 (progn
3135 (or (eq flag 'select-only)
3136 (ediff-unselect-difference ediff-current-difference))
3137
3138 ;; Auto-save buffers while Ediff flags are temporarily removed.
3139 (emerge-eval-in-buffer
3140 ediff-A-buffer
3141 (if buf-A-modified
3142 (do-auto-save)))
3143 (emerge-eval-in-buffer
3144 ediff-B-buffer
3145 (if buf-B-modified
3146 (do-auto-save)))
3147
3148 (or (eq flag 'unselect-only)
3149 (ediff-select-difference n))
3150 (setq ediff-current-difference n)
3151 ) ;; end protected section
3152
3153 (emerge-eval-in-buffer
3154 control-buf
3155 (ediff-refresh-mode-line)
3156
3157 ;; restore undo and buffer-modified info
2553 (emerge-eval-in-buffer 3158 (emerge-eval-in-buffer
2554 ediff-A-buffer 3159 ediff-A-buffer
2555 (setq buf-A-undo buffer-undo-list)) 3160 (set-buffer-modified-p buf-A-modified)
3161 (setq buffer-undo-list buf-A-undo)))
3162
3163 (emerge-eval-in-buffer
3164 control-buf
2556 (emerge-eval-in-buffer 3165 (emerge-eval-in-buffer
2557 ediff-B-buffer 3166 ediff-B-buffer
2558 (setq buf-B-undo buffer-undo-list)) 3167 (set-buffer-modified-p buf-B-modified)
2559 3168 (setq buffer-undo-list buf-B-undo))
2560 (buffer-disable-undo ediff-A-buffer) 3169 ))))
2561 (buffer-disable-undo ediff-B-buffer)
2562
2563 (unwind-protect ;; we don't want to lose undo info due to error
2564 (progn
2565 (or (eq flag 'select-only)
2566 (ediff-unselect-difference ediff-current-difference))
2567
2568 ;; Auto-save buffers while Ediff flags are temporarily removed.
2569 (emerge-eval-in-buffer
2570 ediff-A-buffer
2571 (if buf-A-modified
2572 (do-auto-save)))
2573 (emerge-eval-in-buffer
2574 ediff-B-buffer
2575 (if buf-B-modified
2576 (do-auto-save)))
2577
2578 (or (eq flag 'unselect-only)
2579 (ediff-select-difference n))
2580 (setq ediff-current-difference n)
2581 ) ;; end protected section
2582
2583 (select-window wind) ;; must be before recenter!
2584 (ediff-refresh-mode-line)
2585 (or no-recenter
2586 (ediff-recenter 'no-rehighlight))
2587
2588 ;; restore undo and buffer-modified info
2589 (emerge-eval-in-buffer
2590 ediff-A-buffer
2591 (set-buffer-modified-p buf-A-modified)
2592 (setq buffer-undo-list buf-A-undo))
2593 (emerge-eval-in-buffer
2594 ediff-B-buffer
2595 (set-buffer-modified-p buf-B-modified)
2596 (setq buffer-undo-list buf-B-undo))
2597 )))
2598 3170
2599 ;; Revise the mode line to display which difference we have selected 3171 ;; Revise the mode line to display which difference we have selected
2600 3172
2601 (defun ediff-refresh-mode-line () 3173 (defun ediff-refresh-mode-line ()
2602 (setq mode-line-buffer-identification 3174 (setq mode-line-buffer-identification
2603 (list (format "Ediff: %%b diff %d of %d" 3175 (cond ((< ediff-current-difference 0)
2604 (1+ ediff-current-difference) 3176 (list (format "Ediff: %%b At start: %d diffs"
2605 ediff-number-of-differences))) 3177 ediff-number-of-differences)))
3178 ((>= ediff-current-difference ediff-number-of-differences)
3179 (list (format "Ediff: %%b At end: %d diffs"
3180 ediff-number-of-differences)))
3181 (t
3182 (list (format "Ediff: %%b diff %d of %d"
3183 (1+ ediff-current-difference)
3184 ediff-number-of-differences)))))
2606 ;; Force mode-line redisplay 3185 ;; Force mode-line redisplay
2607 (set-buffer-modified-p (buffer-modified-p))) 3186 (set-buffer-modified-p (buffer-modified-p)))
2608 3187
2609 3188
2610 3189
2612 (defun ediff-validate-difference () 3191 (defun ediff-validate-difference ()
2613 (if (not (and (>= ediff-current-difference 0) 3192 (if (not (and (>= ediff-current-difference 0)
2614 (< ediff-current-difference ediff-number-of-differences))) 3193 (< ediff-current-difference ediff-number-of-differences)))
2615 (error "No difference selected"))) 3194 (error "No difference selected")))
2616 3195
2617 ;; The following is added to take care of Lemacs.
2618
2619
2620 (defun ediff-read-file-name (prompt default-dir default-file A-file) 3196 (defun ediff-read-file-name (prompt default-dir default-file A-file)
2621 ; This is a modified version of a similar function in `emerge.el'. 3197 ; This is a modified version of a similar function in `emerge.el'.
2622 ; PROMPT should not have trailing ': ', so that it can be modified 3198 ; PROMPT should not have trailing ': ', so that it can be modified
2623 ; according to context. 3199 ; according to context.
2624 ; If both A-FILE and default-dir are set, the file constructed our of 3200 ; If both A-FILE and default-dir are set, the file constructed our of
2627 ; If A-FILE is set (but default-dir is not), it is used as default and 3203 ; If A-FILE is set (but default-dir is not), it is used as default and
2628 ; initial input. 3204 ; initial input.
2629 ; If default-file is set, it should be used as the default value. 3205 ; If default-file is set, it should be used as the default value.
2630 ; If default-dir is non-nil, use it as the default directory. 3206 ; If default-dir is non-nil, use it as the default directory.
2631 ; Otherwise, use the value in Emacs's var default-directory. 3207 ; Otherwise, use the value in Emacs's var default-directory.
2632 (cond 3208 (let (f)
2633 ((and A-file default-dir) 3209 (setq f
2634 (read-file-name (format "%s (default %s%s): " 3210 (cond
2635 prompt 3211 ((and A-file default-dir)
2636 (abbreviate-file-name 3212 (read-file-name (format "%s (default %s%s): "
2637 (expand-file-name default-dir)) 3213 prompt
2638 (file-name-nondirectory A-file)) 3214 (abbreviate-file-name
2639 (expand-file-name default-dir) 3215 (expand-file-name default-dir))
2640 (concat (expand-file-name default-dir) 3216 (file-name-nondirectory A-file))
2641 (file-name-nondirectory A-file)) 3217 (expand-file-name default-dir)
2642 'confirm (file-name-nondirectory A-file))) 3218 (concat (expand-file-name default-dir)
2643 (A-file 3219 (file-name-nondirectory A-file))
2644 (read-file-name (format "%s (default %s): " 3220 'confirm (file-name-nondirectory A-file)))
2645 prompt (file-name-nondirectory A-file)) 3221 (A-file
2646 (expand-file-name (file-name-directory A-file)) 3222 (read-file-name (format "%s (default %s): "
2647 A-file 3223 prompt (file-name-nondirectory A-file))
2648 'confirm (file-name-nondirectory A-file))) 3224 (expand-file-name (file-name-directory A-file))
2649 ;; If there is a default file, but no A-file, use it. 3225 A-file
2650 (default-file 3226 'confirm (file-name-nondirectory A-file)))
2651 (read-file-name (format "%s (default %s): " prompt default-file) 3227 ;; If there is a default file, but no A-file, use it.
2652 default-dir ;; if nil then default-directory. 3228 (default-file
2653 nil 'confirm)) 3229 (read-file-name (format "%s (default %s): " prompt default-file)
2654 (t 3230 default-dir;; if nil then default-directory.
2655 (read-file-name (concat prompt ": ") 3231 nil 'confirm))
2656 default-dir ;; if nil then default-directory. 3232 (t
2657 nil 'confirm)))) 3233 (read-file-name (concat prompt ": ")
2658 3234 default-dir;; if nil then default-directory.
2659 3235 nil 'confirm))))
2660 (defun ediff-make-temp-file (prefix) 3236 ;; If user enters a directory name, expand the default file in that
2661 (let ((f (make-temp-name (concat ediff-temp-file-prefix prefix)))) 3237 ;; directory. This allows the user to enter a directory name for the
3238 ;; B-file and diff against the A-file in that directory instead of a DIRED
3239 ;; listing!
3240 (if (and (file-directory-p f)
3241 (or A-file default-file))
3242 (setq f (expand-file-name
3243 (file-name-nondirectory (or A-file default-file)) f)))
3244 f))
3245
3246
3247 ;; If `prefix' is given, then it is used as a prefix for the temp file
3248 ;; name. Otherwise, `.buffer-name' is used. If `file' is given, use this
3249 ;; file and don't create a new one.
3250 (defun ediff-make-temp-file (&optional prefix given-file)
3251 (let ((f (or given-file
3252 (make-temp-name (concat
3253 ediff-temp-file-prefix
3254 (or prefix
3255 (format
3256 ".%s"
3257 (file-name-nondirectory
3258 (buffer-name)))))))))
2662 ;; create the file 3259 ;; create the file
2663 (write-region (point-min) (point-min) f nil 'no-message) 3260 (write-region (point-min) (point-max) f nil 'no-message)
2664 (set-file-modes f ediff-temp-file-mode) 3261 (set-file-modes f ediff-temp-file-mode)
2665 f)) 3262 f))
2666 3263
3264 ;; Quote metacharacters (using \) when executing diff in Unix, but not in
3265 ;; EMX OS/2
3266 (defun ediff-protect-metachars (str)
3267 (or (eq system-type 'emx)
3268 (let ((limit 0))
3269 (while (string-match emerge-metachars str limit)
3270 (setq str (concat (substring str 0 (match-beginning 0))
3271 "\\"
3272 (substring str (match-beginning 0))))
3273 (setq limit (1+ (match-end 0))))))
3274 str)
3275
3276
2667 (defun ediff-block-write-file () 3277 (defun ediff-block-write-file ()
2668 "Prevent writing files A and B directly." 3278 "Prevent writing files A and B directly."
2669 (if (ediff-check-for-ascii-flags) 3279 (if (ediff-check-for-ascii-flags)
2670 (error "Use 'wa' and 'wb' to save buffs A/B (first switch back to *ediff-control*."))) 3280 (error "Use 'wa' and 'wb' to save buffs A/B (first switch back to *ediff-control*.")))
2671 3281
2846 3456
2847 (defun ediff-get-diff-posn (buf-type pos &optional n control-buf) 3457 (defun ediff-get-diff-posn (buf-type pos &optional n control-buf)
2848 "Returns positions of difference sectors in the BUF-TYPE buffer. 3458 "Returns positions of difference sectors in the BUF-TYPE buffer.
2849 BUF-TYPE should be a symbol--either `A' or `B'. 3459 BUF-TYPE should be a symbol--either `A' or `B'.
2850 POS is either `beg' or `end'--it specifies whether you want the position at the 3460 POS is either `beg' or `end'--it specifies whether you want the position at the
2851 beginning of a difference of at the end. 3461 beginning of a difference or at the end.
2852 3462
2853 The optional argument N says which difference \(default: 3463 The optional argument N says which difference \(default:
2854 `ediff-current-difference'\). The optional argument CONTROL-BUF says 3464 `ediff-current-difference'\). The optional argument CONTROL-BUF says
2855 which control buffer is in effect in case it is not the current 3465 which control buffer is in effect in case it is not the current
2856 buffer." 3466 buffer."
2860 3470
2861 (emerge-eval-in-buffer 3471 (emerge-eval-in-buffer
2862 control-buf 3472 control-buf
2863 (or n (setq n ediff-current-difference)) 3473 (or n (setq n ediff-current-difference))
2864 (if (or (< n 0) (>= n ediff-number-of-differences)) 3474 (if (or (< n 0) (>= n ediff-number-of-differences))
2865 (error "There is no diff %d in this session. Valid diffs are 1 to %d." 3475 (if (> ediff-number-of-differences 0)
2866 (1+ n) ediff-number-of-differences)) 3476 (error "There is no diff %d. Valid diffs are 1 to %d."
2867 (setq diff-overlay (aref (aref ediff-difference-vector n) 3477 (1+ n) ediff-number-of-differences)
2868 (if (eq buf-type 'A) 0 1)))) 3478 (error "No differences found.")))
2869 3479 (setq diff-overlay (ediff-get-diff-overlay n buf-type)))
3480
2870 (if (ediff-overlay-get diff-overlay 'detached) 3481 (if (ediff-overlay-get diff-overlay 'detached)
2871 (ediff-move-overlay diff-overlay 3482 (ediff-move-overlay diff-overlay
2872 (ediff-overlay-get diff-overlay 'ediff-marker) 3483 (ediff-overlay-get diff-overlay 'ediff-marker)
2873 (ediff-overlay-get diff-overlay 'ediff-marker))) 3484 (ediff-overlay-get diff-overlay 'ediff-marker)))
2874 (if (eq pos 'beg) 3485 (if (eq pos 'beg)
2912 (ediff-overlay-put ediff-current-diff-overlay-A 'priority 3523 (ediff-overlay-put ediff-current-diff-overlay-A 'priority
2913 (ediff-highest-priority begin-A end-A-hilit ediff-A-buffer)) 3524 (ediff-highest-priority begin-A end-A-hilit ediff-A-buffer))
2914 (ediff-overlay-put ediff-current-diff-overlay-B 'priority 3525 (ediff-overlay-put ediff-current-diff-overlay-B 'priority
2915 (ediff-highest-priority begin-B end-B-hilit ediff-B-buffer)) 3526 (ediff-highest-priority begin-B end-B-hilit ediff-B-buffer))
2916 3527
2917 (if (and (not (face-differs-from-default-p 'ediff-odd-diff-face-A-var)) 3528 (or (face-differs-from-default-p 'ediff-odd-diff-face-A-var)
2918 (null ediff-highlight-selected-only)) 3529 (not ediff-highlight-all-diffs)
2919 (progn 3530 (progn
2920 (copy-face ediff-odd-diff-face-A 'ediff-odd-diff-face-A-var) 3531 (copy-face ediff-odd-diff-face-A 'ediff-odd-diff-face-A-var)
2921 (copy-face ediff-odd-diff-face-B 'ediff-odd-diff-face-B-var) 3532 (copy-face ediff-odd-diff-face-B 'ediff-odd-diff-face-B-var)
2922 (copy-face ediff-even-diff-face-A 'ediff-even-diff-face-A-var) 3533 (copy-face ediff-even-diff-face-A 'ediff-even-diff-face-A-var)
2923 (copy-face ediff-even-diff-face-B 'ediff-even-diff-face-B-var))) 3534 (copy-face ediff-even-diff-face-B 'ediff-even-diff-face-B-var)))
2924 3535
2925 ;; unhighlight the background overlay for the diff n so they won't 3536 ;; unhighlight the background overlay for the diff n so they won't
2926 ;; interfere with the current diff overlay 3537 ;; interfere with the current diff overlay
2927 (ediff-overlay-put (aref (aref ediff-difference-vector n) 0) 'face nil) 3538 (ediff-overlay-put (ediff-get-diff-overlay n 'A) 'face nil)
2928 (ediff-overlay-put (aref (aref ediff-difference-vector n) 1) 'face nil) 3539 (ediff-overlay-put (ediff-get-diff-overlay n 'B) 'face nil)
2929 3540
2930 (sit-for 0) ;; needs to synch for some reason 3541 (sit-for 0) ;; needs to synch for some reason
2931 )) 3542 ))
2932 3543
2933 3544
2937 (ediff-move-overlay ediff-current-diff-overlay-A 1 1) 3548 (ediff-move-overlay ediff-current-diff-overlay-A 1 1)
2938 (ediff-move-overlay ediff-current-diff-overlay-B 1 1) 3549 (ediff-move-overlay ediff-current-diff-overlay-B 1 1)
2939 3550
2940 ;; rehighlight the overlay in the background of the 3551 ;; rehighlight the overlay in the background of the
2941 ;; current difference region 3552 ;; current difference region
2942 (ediff-overlay-put (aref (aref ediff-difference-vector 3553 (ediff-overlay-put (ediff-get-diff-overlay ediff-current-difference 'A)
2943 ediff-current-difference)
2944 0)
2945 'face (if (ediff-odd-p ediff-current-difference) 3554 'face (if (ediff-odd-p ediff-current-difference)
2946 'ediff-odd-diff-face-A-var 3555 'ediff-odd-diff-face-A-var
2947 'ediff-even-diff-face-A-var)) 3556 'ediff-even-diff-face-A-var))
2948 (ediff-overlay-put (aref (aref ediff-difference-vector 3557 (ediff-overlay-put (ediff-get-diff-overlay ediff-current-difference 'B)
2949 ediff-current-difference)
2950 1)
2951 'face (if (ediff-odd-p ediff-current-difference) 3558 'face (if (ediff-odd-p ediff-current-difference)
2952 'ediff-odd-diff-face-B-var 3559 'ediff-odd-diff-face-B-var
2953 'ediff-even-diff-face-B-var)) 3560 'ediff-even-diff-face-B-var))
2954 ) 3561 )
2955 3562
2956 3563
3564 ;; delete highlighting overlays, restore faces to their original form
2957 (defun ediff-unhighlight-diffs-totally () 3565 (defun ediff-unhighlight-diffs-totally ()
3566 (setq buffer-read-only nil)
3567 (ediff-unselect-and-select-difference -1)
3568
2958 (if (and window-system ediff-want-faces) 3569 (if (and window-system ediff-want-faces)
2959 (let ((inhibit-quit t)) 3570 (let ((inhibit-quit t))
2960 (if (face-differs-from-default-p 'ediff-odd-diff-face-A-var) 3571 (if (face-differs-from-default-p 'ediff-odd-diff-face-A-var)
2961 (progn 3572 (progn
2962 (copy-face 'default 'ediff-odd-diff-face-A-var) 3573 (copy-face 'default 'ediff-odd-diff-face-A-var)
2966 (if (ediff-overlayp ediff-current-diff-overlay-A) 3577 (if (ediff-overlayp ediff-current-diff-overlay-A)
2967 (ediff-delete-overlay ediff-current-diff-overlay-A)) 3578 (ediff-delete-overlay ediff-current-diff-overlay-A))
2968 (setq ediff-current-diff-overlay-A nil) 3579 (setq ediff-current-diff-overlay-A nil)
2969 (if (ediff-overlayp ediff-current-diff-overlay-B) 3580 (if (ediff-overlayp ediff-current-diff-overlay-B)
2970 (ediff-delete-overlay ediff-current-diff-overlay-B)) 3581 (ediff-delete-overlay ediff-current-diff-overlay-B))
2971 (setq ediff-current-diff-overlay-B nil)))) 3582 (setq ediff-current-diff-overlay-B nil)))
2972 3583 )
3584
3585 (defun ediff-clear-diff-vector (vec &optional fin-diffs-also)
3586 ;; null out the difference overlays so they won't slow down future
3587 ;; editing operations
3588 (mapcar (function
3589 (lambda (elt)
3590 (ediff-delete-overlay (ediff-get-diff-overlay-from-vector elt 'A))
3591 (ediff-delete-overlay (ediff-get-diff-overlay-from-vector elt 'B))
3592 (if fin-diffs-also
3593 (ediff-clear-diff-vector
3594 (ediff-get-fine-diff-vector-from-vec elt)))
3595 ))
3596 vec)
3597 ;; allow them to be garbage collected
3598 (setq vec nil))
2973 3599
2974 (defun ediff-operate-on-flags (action) 3600 (defun ediff-operate-on-flags (action)
2975 "Re/unhighlights buffers A and B with all flags from all Ediff sessions. 3601 "Re/unhighlights buffers A and B with all flags from all Ediff sessions.
2976 This is usually needed only when a 3602 This is usually needed only when a
2977 buffer is involved in multiple Ediff sessions." 3603 buffer is involved in multiple Ediff sessions."
2983 ediff-this-buffer-control-sessions)) 3609 ediff-this-buffer-control-sessions))
2984 (sessions (ediff-union A-sessions B-sessions)) 3610 (sessions (ediff-union A-sessions B-sessions))
2985 (flag (if (eq action 'remove) 'unselect-only 'select-only))) 3611 (flag (if (eq action 'remove) 'unselect-only 'select-only)))
2986 3612
2987 (mapcar (function (lambda (buf) 3613 (mapcar (function (lambda (buf)
2988 (emerge-eval-in-buffer 3614 (if (ediff-buffer-live-p buf)
2989 buf 3615 (emerge-eval-in-buffer
2990 (or (if (eq action 'insert) 3616 buf
3617 (or (if (eq action 'insert)
2991 (memq ediff-highlighting-style '(ascii off)) 3618 (memq ediff-highlighting-style '(ascii off))
2992 (not (eq ediff-highlighting-style 'ascii))) 3619 (not (eq ediff-highlighting-style 'ascii)))
2993 (ediff-unselect-and-select-difference 3620 (ediff-unselect-and-select-difference
2994 ediff-current-difference 3621 ediff-current-difference
2995 flag 'no-recenter)) 3622 flag 'no-recenter))
2996 ))) 3623 ))))
2997 sessions))) 3624 sessions)))
3625
3626
3627
3628 ;;; Refinement of current diff
3629 ;; Split region along word boundaries. Each word will be on its own line.
3630 ;; Output to buffer out-buffer.
3631 (defun ediff-wordify (beg end in-buffer out-buffer)
3632 (let (sv-point string)
3633 (save-excursion
3634 (set-buffer in-buffer)
3635 (setq string (buffer-substring beg end))
3636
3637 (set-buffer out-buffer)
3638 (erase-buffer)
3639 (insert string)
3640 (goto-char (point-min))
3641 (skip-chars-forward ediff-whitespace)
3642 (delete-region (point-min) (point))
2998 3643
3644 (while (or (> (skip-chars-forward ediff-word-1) 0)
3645 (> (skip-chars-forward ediff-word-2) 0))
3646
3647 (setq sv-point (point))
3648 (skip-chars-forward ediff-whitespace)
3649 (delete-region sv-point (point))
3650 (insert "\n")))))
3651
3652
3653 ;; `n' is the diff region to work on.
3654 ;; if `flag' is 'noforce then make fine-diffs only if this region's fine
3655 ;; diffs have not been computed before.
3656 ;; if `flag' is 'skip then don't compute fine diffs for this region.
3657 (defun ediff-make-fine-diffs (&optional n flag)
3658 (interactive)
3659 (if (not window-system)
3660 (error "Non-window system."))
3661 (or n (setq n ediff-current-difference))
3662
3663 (if (< ediff-number-of-differences 1)
3664 (error "No differences found."))
3665
3666 (let ((file-A ediff-temp-file-A)
3667 (file-B ediff-temp-file-B))
3668
3669 (cond ((and (eq flag 'noforce) (ediff-get-fine-diff-vector n))
3670 nil)
3671 ((eq flag 'skip)
3672 (or (ediff-get-fine-diff-vector n)
3673 (eq ediff-auto-refine 'off)
3674 (message "Region %d is larger than auto-refine limit. Hit %S to force-refine."
3675 (1+ n)
3676 (substitute-command-keys "\\[ediff-make-fine-diffs]")
3677 )))
3678 (t
3679 ;; delete old fine diffs
3680 (ediff-clear-diff-vector (ediff-get-fine-diff-vector n))
3681 ;; recompute fine diffs
3682 (setq ediff-tmp-buffer (get-buffer-create "*ediff-tmp*"))
3683
3684 (funcall ediff-wordify-function
3685 (ediff-get-diff-posn 'A 'beg n)
3686 (ediff-get-diff-posn 'A 'end n)
3687 ediff-A-buffer
3688 ediff-tmp-buffer)
3689 (emerge-eval-in-buffer
3690 ediff-tmp-buffer
3691 (setq file-A (ediff-make-temp-file ".fine-diffs-A" file-A)))
3692
3693 (funcall ediff-wordify-function
3694 (ediff-get-diff-posn 'B 'beg n)
3695 (ediff-get-diff-posn 'B 'end n)
3696 ediff-B-buffer
3697 ediff-tmp-buffer)
3698 (emerge-eval-in-buffer
3699 ediff-tmp-buffer
3700 (setq file-B (ediff-make-temp-file ".fine-diffs-B" file-B)))
3701
3702 ;; save temp file names.
3703 (setq ediff-temp-file-A file-A
3704 ediff-temp-file-B file-B)
3705
3706 ;; set the new vector of fine diffs, if none exists
3707 (ediff-set-fine-diff-vector
3708 n
3709 (ediff-setup-diff-regions file-A file-B 'use-old-diff-buf n
3710 ediff-fine-diff-program
3711 ediff-fine-diff-options
3712 ediff-fine-diff-ok-lines-regexp))
3713 (if (eq (length (ediff-get-fine-diff-vector n)) 0)
3714 (message "No differences found in region %d, except for white space and line breaks."
3715 (1+ n))))
3716 ) ;; end cond
3717 (ediff-set-fine-diff-properties n)
3718 ))
3719
3720
3721 (defun ediff-set-fine-diff-properties (n &optional default)
3722 (let ((fine-diff-vector (ediff-get-fine-diff-vector n))
3723 (face-A (if default 'default (face-name ediff-fine-diff-face-A)))
3724 (face-B (if default 'default (face-name ediff-fine-diff-face-B)))
3725 (priority-A (if default
3726 0
3727 (1+ (ediff-overlay-get ediff-current-diff-overlay-A
3728 'priority))))
3729 (priority-B (if default
3730 0
3731 (1+ (ediff-overlay-get ediff-current-diff-overlay-B
3732 'priority)))))
3733 (mapcar
3734 (function (lambda (vec)
3735 (ediff-overlay-put
3736 (ediff-get-diff-overlay-from-vector vec 'A)
3737 'face face-A)
3738 (ediff-overlay-put
3739 (ediff-get-diff-overlay-from-vector vec 'A)
3740 'priority priority-A)
3741
3742 (ediff-overlay-put
3743 (ediff-get-diff-overlay-from-vector vec 'B)
3744 'face face-B)
3745 (ediff-overlay-put
3746 (ediff-get-diff-overlay-from-vector vec 'B)
3747 'priority priority-B)
3748 ))
3749 fine-diff-vector)
3750 ))
3751
3752 (defun ediff-convert-diffs-to-overlays-refine (A-buffer B-buffer
3753 diff-list refine-region)
3754 (let* ((current-diff -1)
3755 (reg-A-start (ediff-get-diff-posn 'A 'beg refine-region))
3756 (reg-B-start (ediff-get-diff-posn 'B 'beg refine-region))
3757 diff-overlay-list list-element
3758 a-begin a-end b-begin b-end
3759 a-overlay b-overlay)
3760
3761 (emerge-eval-in-buffer A-buffer (goto-char reg-A-start))
3762 (emerge-eval-in-buffer B-buffer (goto-char reg-B-start))
3763
3764 (while diff-list
3765 (setq current-diff (1+ current-diff)
3766 list-element (car diff-list)
3767 a-begin (aref list-element 0)
3768 a-end (aref list-element 1)
3769 b-begin (aref list-element 2)
3770 b-end (aref list-element 3))
3771
3772 ;; place overlays at the appropriate places in the buffers
3773 (setq a-overlay (ediff-make-overlay
3774 (ediff-goto-word (1+ a-begin) A-buffer)
3775 (ediff-goto-word a-end A-buffer 'end)
3776 A-buffer))
3777
3778 (setq b-overlay (ediff-make-overlay
3779 (ediff-goto-word (1+ b-begin) B-buffer)
3780 (ediff-goto-word b-end B-buffer 'end)
3781 B-buffer))
3782
3783 ;; record all overlays for this difference
3784 (setq diff-overlay-list (nconc diff-overlay-list
3785 (list (vector a-overlay b-overlay)))
3786 diff-list (cdr diff-list))
3787 ) ;; while
3788 ;; convert the list of difference information into a vector for
3789 ;; fast access
3790 (apply 'vector diff-overlay-list)))
3791
3792 ;; goto word #n starting at current position in buffer `buf'
3793 ;; For ediff, a word is either a string of a-z,A-Z, incl `-' and `_';
3794 ;; or a string of other non-blanks. A blank is a \n\t\j
3795 ;; If `flag' is non-nil, goto the end of the n-th word.
3796 (defun ediff-goto-word (n buf &optional flag)
3797 (emerge-eval-in-buffer
3798 buf
3799 (skip-chars-forward ediff-whitespace)
3800 (while (> n 1)
3801 (or (> (skip-chars-forward ediff-word-1) 0)
3802 (> (skip-chars-forward ediff-word-2) 0))
3803 (skip-chars-forward ediff-whitespace)
3804 (setq n (1- n)))
3805 ;(if flag
3806 (if (and flag (> n 0))
3807 (or (> (skip-chars-forward ediff-word-1) 0)
3808 (> (skip-chars-forward ediff-word-2) 0)))
3809 (point)))
3810
3811
3812
3813
3814
3815 ;;; Misc
3816
2999 (defun ediff-union (list1 list2) 3817 (defun ediff-union (list1 list2)
3000 "Combine LIST1 and LIST2 using a set-union operation. 3818 "Combine LIST1 and LIST2 using a set-union operation.
3001 The result list contains all items that appear in either LIST1 or LIST2. 3819 The result list contains all items that appear in either LIST1 or LIST2.
3002 This is a non-destructive function; it makes a copy of the data if necessary 3820 This is a non-destructive function; it makes a copy of the data if necessary
3003 to avoid corrupting the original LIST1 and LIST2. 3821 to avoid corrupting the original LIST1 and LIST2.
3012 (or (memq (car list2) list1) 3830 (or (memq (car list2) list1)
3013 (setq list1 (cons (car list2) list1))) 3831 (setq list1 (cons (car list2) list1)))
3014 (setq list2 (cdr list2))) 3832 (setq list2 (cdr list2)))
3015 list1))) 3833 list1)))
3016 3834
3017 (defun ediff-debug () 3835
3018 (interactive) 3836 ;(defun ediff-debug ()
3019 (with-output-to-temp-buffer "*ediff-debug*" 3837 ; (interactive)
3020 (princ 3838 ; (with-output-to-temp-buffer "*ediff-debug*"
3021 (format "Ctl buffer: %S\n\nediff-difference-vector:\n" 3839 ; (princ
3022 ediff-control-buffer)) 3840 ; (format "Ctl buffer: %S\n\nediff-difference-vector:\n"
3023 (mapcar (function 3841 ; ediff-control-buffer))
3024 (lambda (overl-vec) 3842 ; (mapcar (function
3025 (princ (format "Diff %d: %S %S %S\n\t %S %S %S\n" 3843 ; (lambda (overl-vec)
3026 (1+ (ediff-overlay-get (aref overl-vec 0) 3844 ; (princ (format "Diff %d: %S %S %S\n\t %S %S %S\n"
3027 'ediff-diff-num)) 3845 ; (1+ (ediff-overlay-get (aref overl-vec 0)
3028 (ediff-overlay-get (aref overl-vec 0) 3846 ; 'ediff-diff-num))
3029 'ediff-control-buffer) 3847 ; (ediff-overlay-get (aref overl-vec 0)
3030 (ediff-overlay-get (aref overl-vec 0) 3848 ; 'ediff-control-buffer)
3031 'insert-in-front-hooks) 3849 ; (ediff-overlay-get (aref overl-vec 0)
3032 (aref overl-vec 0) 3850 ; 'insert-in-front-hooks)
3033 (ediff-overlay-get (aref overl-vec 1) 3851 ; (aref overl-vec 0)
3034 'ediff-control-buffer) 3852 ; (ediff-overlay-get (aref overl-vec 1)
3035 (ediff-overlay-get (aref overl-vec 0) 3853 ; 'ediff-control-buffer)
3036 'insert-in-front-hooks) 3854 ; (ediff-overlay-get (aref overl-vec 0)
3037 (aref overl-vec 1) 3855 ; 'insert-in-front-hooks)
3038 )))) 3856 ; (aref overl-vec 1)
3039 ediff-difference-vector) 3857 ; ))))
3040 (princ "\nediff-disturbed-overlays:\n") 3858 ; ediff-difference-vector)
3041 (mapcar (function 3859 ; (princ "\nediff-disturbed-overlays:\n")
3042 (lambda (overl) 3860 ; (mapcar (function
3043 (princ (format "%S %S\n" 3861 ; (lambda (overl)
3044 (ediff-overlay-get overl 'ediff-control-buffer) 3862 ; (princ (format "%S %S\n"
3045 overl 3863 ; (ediff-overlay-get overl 'ediff-control-buffer)
3046 )))) 3864 ; overl
3047 ediff-disturbed-overlays))) 3865 ; ))))
3866 ; ediff-disturbed-overlays)))
3048 3867
3049 3868
3050 (run-hooks 'ediff-load-hooks) 3869 (run-hooks 'ediff-load-hooks)
3051 3870
3052 3871