Commit | Line | Data |
---|---|---|
0f0b0a86 | 1 | ;;; ediff.el --- a comprehensive visual interface to diff & patch |
732be465 | 2 | ;;; Copyright (C) 1994, 1995 Free Software Foundation, Inc. |
813f532d RS |
3 | |
4 | ;; Author: Michael Kifer <kifer@cs.sunysb.edu> | |
5 | ;; Created: February 2, 1994 | |
fcbadd58 | 6 | ;; Keywords: comparing, merging, patching, version control. |
813f532d | 7 | |
f1a5512a KH |
8 | (defconst ediff-version "2.26" "The current version of Ediff") |
9 | (defconst ediff-date "June 3, 1995" "Date of last update") | |
eaccd4d8 | 10 | |
813f532d RS |
11 | ;; This file is part of GNU Emacs. |
12 | ||
13 | ;; GNU Emacs is free software; you can redistribute it and/or modify | |
14 | ;; it under the terms of the GNU General Public License as published by | |
15 | ;; the Free Software Foundation; either version 2, or (at your option) | |
16 | ;; any later version. | |
17 | ||
18 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
19 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21 | ;; GNU General Public License for more details. | |
22 | ||
23 | ;; You should have received a copy of the GNU General Public License | |
24 | ;; along with GNU Emacs; see the file COPYING. If not, write to | |
25 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | |
26 | ||
813f532d RS |
27 | ;;; Commentary: |
28 | ;; ---------- | |
29 | ||
0f0b0a86 | 30 | ;; Never read that diff output again! |
08020d91 | 31 | ;; Apply patch selectively, like a pro! |
0f0b0a86 | 32 | ;; Merge with ease! |
813f532d | 33 | |
fcbadd58 | 34 | ;; This package provides a convenient way of simultaneous browsing through |
f1a5512a | 35 | ;; the differences between a pair (or a triple) of files or buffers. The |
0f0b0a86 KH |
36 | ;; files being compared, file-A, file-B, and file-C (if applicable) are |
37 | ;; shown in separate windows (side by side, one above the another, or in | |
38 | ;; separate frames), and the differences are highlighted as you step | |
39 | ;; through them. You can also copy difference regions from one buffer to | |
40 | ;; another (and recover old differences if you change your mind). | |
813f532d RS |
41 | |
42 | ;; In addition, Ediff can apply a patch to a file and then let you step | |
fcbadd58 | 43 | ;; though both files, the patched and the original one, simultaneously, |
813f532d RS |
44 | ;; difference-by-difference. You can even apply a patch right out of a |
45 | ;; mail buffer, i.e., patches received by mail don't even have to be saved. | |
46 | ;; Since Ediff lets you copy differences between buffers, you can, in | |
47 | ;; effect, apply patches selectively (i.e., you can copy a difference | |
0f0b0a86 | 48 | ;; region from file_orig to file, thereby undoing any particular patch that |
813f532d RS |
49 | ;; you don't like). |
50 | ||
f1a5512a KH |
51 | ;; Ediff is aware of version control, which lets the user compare |
52 | ;; files with their older versions. Ediff can also work with remote and | |
53 | ;; compressed files. Details are given below. | |
54 | ||
0f0b0a86 KH |
55 | ;; This package builds upon the ideas borrowed from emerge.el and |
56 | ;; several Ediff's functions are adaptations from emerge.el. | |
57 | ;; Much of the functionality of Ediff is also influenced by emerge.el. | |
813f532d | 58 | |
0f0b0a86 KH |
59 | ;; The present version of Ediff supersedes Emerge. It provides a superior |
60 | ;; user interface and has many features not found in Emerge. In particular, | |
61 | ;; it can do patching and 2-way and 3-way file comparison in addition to | |
62 | ;; merging. | |
fcbadd58 | 63 | |
813f532d | 64 | |
813f532d RS |
65 | |
66 | ;;; Compilation | |
67 | ;; ----------- | |
68 | ;; | |
69 | ;; When you byte-compile Ediff, you will get some warnings about functions | |
70 | ;; being undefined. These can be safely ignored. | |
b3a26225 | 71 | ;; |
813f532d | 72 | ;;; Bugs: |
0f0b0a86 | 73 | ;; ----- |
813f532d RS |
74 | |
75 | ;; 1. The undo command doesn't restore deleted regions well. That is, if | |
76 | ;; you delete all characters in a difference region and then invoke | |
0f0b0a86 | 77 | ;; `undo', the reinstated text will most likely be inserted outside of |
b3a26225 | 78 | ;; what Ediff thinks is the current difference region. (This problem |
0f0b0a86 | 79 | ;; doesn't seem to exist with XEmacs.) |
b3a26225 RS |
80 | ;; |
81 | ;; If at any point you feel that difference regions are no longer correct, | |
82 | ;; you can hit '!' to recompute the differences. | |
83 | ||
f1a5512a | 84 | ;; 2. On a monochrome display, the repertoire of faces with which to |
b3a26225 RS |
85 | ;; highlight fine differences is limited. By default, Ediff is using |
86 | ;; underlining. However, if the region is already underlied by some other | |
87 | ;; overlays, there is no simple way to temporarily remove that residual | |
88 | ;; underlining. This problem occurs when a buffer is highlighted with | |
89 | ;; hilit19.el or font-lock.el packages. If this residual highlighting gets | |
90 | ;; in the way, you can do the following. Both font-lock.el and hilit19.el | |
91 | ;; provide commands for unhighlighting buffers. You can either place these | |
92 | ;; commands in `ediff-prepare-buffer-hooks' (which will unhighlight every | |
93 | ;; buffer used by Ediff) or you can execute them interactively, at any time | |
94 | ;; and on any buffer. | |
f1a5512a | 95 | ;; |
813f532d RS |
96 | |
97 | ;;; Change Log: | |
98 | ;; ---------- | |
99 | ||
100 | ;; Thu Feb 3, 1994 | |
101 | ||
813f532d RS |
102 | ;; Fixed a bug in ediff-setup-windows that caused control window to |
103 | ;; appear in a wrong place when split-window-keep-point is nil | |
104 | ;; (Thanks to Kevin Broadey <KevinB@bartley.demon.co.uk>.) | |
105 | ;; | |
106 | ;; Added mechanism for using faces instead of before/after flags. This | |
107 | ;; looks much better on an X display, especially on a color one. | |
108 | ;; (Thanks to Boris Goldowsky <boris@cs.rochester.edu> for the code | |
109 | ;; that led to ediff-highlight-diff. | |
110 | ;; Also, thanks to Kevin Esler <esler@ch.hp.com> for suggestions | |
111 | ;; regarding highlighting differences on X displays.) | |
112 | ;; | |
113 | ;; Added functions to apply patches. | |
114 | ;; (Thanks to Kevin Broadey <KevinB@bartley.demon.co.uk> for this | |
115 | ;; suggestion.) | |
116 | ||
117 | ;; Fri Feb 4, 1994 | |
118 | ||
119 | ;; Added mechanism for toggling vertical/horizontal window split. | |
120 | ;; (Inspired by a suggestion from Allan Gottlieb | |
121 | ;; <gottlieb@allan.ultra.nyu.edu> -- thanks.) | |
122 | ;; | |
123 | ;; Added mechanism for toggling between highlighting using faces and | |
124 | ;; highlighting using ASCII flags. | |
125 | ;; | |
126 | ;; Fixed a problem with undo. Now, Ediff has smartened up and doesn't | |
127 | ;; keep undo info on ASCII flags inserted in buffer-A and buffer-B. | |
128 | ;; So, if you edit the files while browsing through them, undo behaves | |
129 | ;; as you would expect, i.e., faces/flags don't get in the way. | |
130 | ||
131 | ;; Sun Feb 6, 1994 | |
132 | ||
133 | ;; Added horizontal scrolling. Added ediff-position-region to ensure | |
134 | ;; that difference regions in buffer-A and buffer-B are aligned with | |
135 | ;; each other. Disabled ediff-toggle-split when buffers are displayed | |
136 | ;; in different frames. | |
0f0b0a86 | 137 | ;; |
813f532d RS |
138 | ;; Added toggle-window help (Suggested by Boris Goldowsky |
139 | ;; <boris@cs.rochester.edu>.) | |
140 | ;; Added functions to copy differences from one buffer to another and to | |
141 | ;; recover old differences. | |
142 | ;; Added prefix arguments to ediff-next-difference and | |
143 | ;; ediff-previous-difference. | |
144 | ||
145 | ;; Tue Feb 8, 1994 | |
146 | ||
147 | ;; Replaced text properties with overlays. Fixed ediff-setup-windows. | |
148 | ;; Added ediff-save-buffer to local-write-file-hooks to prevent user | |
149 | ;; from saving corrupted states. (Thanks to <boris@cs.rochester.edu> | |
150 | ;; for suggestion.) Instead, Ediff now has a pair of functions for | |
151 | ;; safe saving of buffers. | |
152 | ;; Changed ediff-read-file-name to be more intuitive on ediff-files. | |
153 | ;; Added ediff-prepare-buffer-hooks. (Thanks to Kevin Esler | |
154 | ;; <esler@ch.hp.com> for the idea.) | |
0f0b0a86 | 155 | ;; |
813f532d RS |
156 | ;; Cleanups in ediff-patch-file. Protected ediff-copy-diff against |
157 | ;; a bug that Emacs has in kill-region. | |
0f0b0a86 | 158 | ;; |
813f532d RS |
159 | ;; Added support for Lemacs. (Thanks to Alastair Burt |
160 | ;; <burt@dfki.uni-kl.de> for coercing Ediff into working under Lemacs.) | |
161 | ;; Added ediff-kill-buffer-carefully and other suggestions by Boris | |
162 | ;; Goldowsky <boris@cs.rochester.edu>. | |
163 | ;; Refined the protection against interference with highlighting caused | |
164 | ;; by Hilit19. Added the variable ediff-third-party-highlighting. | |
165 | ;; Added mechanisn for unhighlighting regions highlighted with Hilit19 | |
166 | ;; before hightlighting them with Ediff's overlays. (And for | |
167 | ;; rehighlighting them with Hilit19, when the current difference moves on.) | |
168 | ||
169 | ;; Sun Feb 13, 1994 | |
170 | ||
171 | ;; Added ediff-place-flags-in-buffer and ediff-remote-exit, which are | |
172 | ;; modifications of Emerge's similar functions. The difference is that | |
173 | ;; in Ediff they make ediff-before-flag and ediff-after-flag into | |
174 | ;; read-only regions, so the user can't change them by mistake. | |
175 | ;; | |
176 | ;; Adopted a suggestion by Boris Goldowsky <boris@cs.rochester.edu> | |
177 | ;; that led to a more elegant treatment of faces. | |
178 | ;; | |
179 | ;; Added protection against interference with Font-Lock highlighting | |
180 | ;; similar to that of Hilit19's protection. | |
181 | ||
182 | ;; Tue Feb 15, 1994 | |
183 | ||
184 | ;; Deleted spurious (auto-save-mode 1) in ediff-control-buffer, which | |
185 | ;; was causing this buffer to be auto-saved for no good reason. | |
186 | ;; Added read-only protection to ediff-before/after-flags in Lemacs. | |
187 | ;; (Thanks to Alastair Burt <burt@dfki.uni-kl.de> for help in testing.) | |
0f0b0a86 KH |
188 | ;; |
189 | ;; Further fixes in the XEmacs part. Changed highlighted region in | |
813f532d RS |
190 | ;; ediff-highlight-diff so that an extra character will be highlighted |
191 | ;; only if a difference is empty (thereby allowing the user to see where an | |
192 | ;; insertion or a deletion has taken place). | |
193 | ;; | |
194 | ;; Simplified interaction with other highlighting packages by giving | |
195 | ;; Ediff overlays the highest priority. (Taking a cue from | |
196 | ;; ediff-highlight-diff-lemacs written by Alastair Burt | |
197 | ;; <burt@dfki.uni-kl.de>.) Zapped ediff-third-party-highlighting | |
198 | ;; variable and hooks that were previously used to | |
199 | ;; unhighlight/rehighlight buffers when hilit19/font-lock are on. | |
200 | ||
201 | ;; Fri Feb 18, 1994 | |
202 | ||
203 | ;; Added a bit more sophistication to ediff-read-file-name. Now, | |
204 | ;; ediff-files remembers both, the file-A and the file-B directories. | |
205 | ;; They are offered as defaults when ediff-use-last-dir is set to t. | |
206 | ||
207 | ;; Fri Feb 22, 1994 | |
208 | ||
209 | ;; Added ediff-before-change-guard to remove ASCII highlighting when | |
210 | ;; the user attempts to change buffer-A/B. This is needed because | |
211 | ;; otherwise the undo info may become screwed up in those buffers. | |
0f0b0a86 | 212 | ;; Hitting `h' (ediff-toggle-hilit) on a dumb terminal will toggle |
813f532d RS |
213 | ;; between ASCII highlighting and no highlighting. |
214 | ||
215 | ;; Fri Feb 24, 1994 | |
216 | ||
217 | ;; Fixed problems with multiple Ediff sessions running simultaneously. | |
218 | ||
219 | ;; Tue Mar 1, 1994 | |
220 | ||
221 | ;; Added vc-ediff, the Ediff interface to vc.el. (Thanks to Eric | |
222 | ;; Freudenthal <freudent@jan.ultra.nyu.edu> for contributing this | |
223 | ;; function.) | |
224 | ||
225 | ;; Sun Mar 6, 1994 | |
226 | ||
227 | ;; Added rcs-ediff, an Ediff interface to RCS via rcs.el. (Thanks to | |
228 | ;; Alastair Burt <burt@dfki.uni-kl.de>.) | |
229 | ;; Some minor improvements. | |
230 | ||
231 | ;; Tue March 15, 1994 | |
232 | ||
233 | ;; Fixed a buglet in defining ediff-current-diff-face-A/B. | |
234 | ;; (Thanks to Job Ganzevoort <Job.Ganzevoort@cwi.nl>.) | |
235 | ||
236 | ;; Tue March 22, 1994 | |
237 | ||
238 | ;; Fixed a bug with ediffing narrowed buffers, reported by Kevin | |
239 | ;; Broadey <KevinB@bartley.demon.co.uk>. | |
240 | ;; Made Ediff to work with files that have incomplete last line. | |
08020d91 | 241 | ;; Made Ediff execute diff and patch using Bourne Shell, which |
813f532d RS |
242 | ;; should eliminate problems with $prompt that some people had. |
243 | ||
244 | ;; Thu March 24, 1994 | |
245 | ||
246 | ;; Achieved quadratic speedup in the size of the file by replacing the | |
0f0b0a86 KH |
247 | ;; slow goto-line by forward-line. |
248 | ;; Converted demarkation of difference regions | |
813f532d RS |
249 | ;; from markers to overlays. This will later allow us to highlight all |
250 | ;; diffs, not just the current one. | |
251 | ||
252 | ;; Wed March 30, 1994 | |
253 | ||
254 | ;; Under X, Ediff now highlights all differences in dim colors and the | |
0f0b0a86 | 255 | ;; current difference in bright colors. Improved XEmacs support. |
813f532d RS |
256 | ;; Changed toggle hilit to cycle through 3 states: highlighting all |
257 | ;; diffs, highlighting only the current diff, and highlighting using | |
258 | ;; ASCII flags. | |
259 | ;; Added support for difference regions that are not full lines. | |
260 | ||
261 | ;; Fri April 1, 1994 | |
262 | ||
263 | ;; Fixed bugs related to writing buffers A and B. | |
0f0b0a86 | 264 | ;; Added commands `ga', `gb' to jump directly to the closest diff in |
813f532d RS |
265 | ;; buffer A and B, respectively. |
266 | ||
b3a26225 RS |
267 | ;; Fri April 11, 1994 |
268 | ||
0f0b0a86 | 269 | ;; Added `ediff-update-diffs', a function that lets the user recompute |
b3a26225 RS |
270 | ;; difference regions after extensive editing done to buffers A and B |
271 | ;; (bound to `!'). | |
272 | ||
273 | ;; Wed April 13, 1994 | |
274 | ||
275 | ;; Added the new feature: refining the current difference region. | |
276 | ;; This would highlight the precise differences between the regions in | |
277 | ;; buffer A and B. (A way to implement this was suggested by Boris | |
278 | ;; Goldowsky <boris@cs.rochester.edu>.) | |
279 | ;; | |
280 | ;; Fixed Ediff to be immune to several different versions of rcs.el | |
281 | ;; that are currently in distribution. | |
282 | ||
283 | ;; Thu April 14, 1994 | |
284 | ||
285 | ;; Ediff now respects X resources for the faces it uses. It no longer | |
286 | ;; barks when the colormap has no colors it is using; or when face | |
287 | ;; fonts can't be italicized, etc. | |
288 | ||
289 | ;; Fri April 15, 1994 | |
290 | ||
291 | ;; Changed `ediff-setup-windows' to minimize the need to delete and | |
292 | ;; create windows. Now jumps faster from diff to diff. | |
f9ae5324 | 293 | ;; Added Ediff to the File menu on the menu bar (FSF's version). |
b3a26225 RS |
294 | |
295 | ;; Mon April 18, 1994 | |
296 | ||
297 | ;; Fixed to work with OS/2's PM-Emacs. | |
298 | ||
299 | ;; Thu April 21, 1994 | |
300 | ||
301 | ;; Lemacs' menus added (thanks to Alastair Burt for the help). | |
302 | ||
303 | ;; Wed April 28, 1994 | |
304 | ||
0f0b0a86 | 305 | ;; Fixed ediff-keep-window-config (thanks to Norbert Kiesel |
b3a26225 RS |
306 | ;; <norbert@i3.informatik.rwth-aachen.de>), ediff-shell and |
307 | ;; ediff-protect-metachars (thanks to Richard Stanton | |
308 | ;; <stanton@haas.berkeley.edu>). Made access to difference | |
309 | ;; overlays structure-independent, making it less bug-prone. | |
310 | ;; Patched ediff-read-file-name to work more intuitively with directory | |
311 | ;; names (thanks to Kevin Broadey <KevinB@bartley.demon.co.uk>). | |
312 | ||
313 | ;; Mon May 2, 1994 | |
314 | ||
315 | ;; Added `ediff-frame-has-menubar' to guard against the possibility that | |
316 | ;; the current frame has no menu bar. | |
317 | ||
318 | ;; Fri May 6, 1994 | |
319 | ||
320 | ;; Fixed buglet in vc-ediff (thanks to Ray Nickson <nickson@cs.uq.oz.au>). | |
321 | ||
fcbadd58 RS |
322 | ;; Wed May 18, 1994 |
323 | ||
324 | ;; Modified ediff-read-file-name to not put long file names in the | |
325 | ;; default prompt area, as suggested by KevinB@bartley.demon.co.uk. | |
326 | ;; Applied patch supplied by burt@dfki.uni-kl.de, fixing a problem with | |
327 | ;; ediff-diff-to-diff in Lemacs. | |
328 | ||
329 | ;; Tue May 31, 1994 | |
330 | ||
331 | ;; Added ediff-forward-word-function (as suggested by Job Ganzevoort | |
f1a5512a | 332 | ;; <Job.Ganzevoort@cwi.nl>). |
fcbadd58 RS |
333 | |
334 | ;; Thu Jun 2, 1994 | |
335 | ||
336 | ;; Added `ediff-toggle-regexp-match', which allows the user to step | |
337 | ;; through only those difference regions that match some regexp; or, | |
338 | ;; vice versa, to skip over regions that match a regexp. (This feature | |
339 | ;; was suggested by Andy Scott <ascott@pcocd2.intel.com>.) | |
340 | ;; Added ediff-eval-in-buffer, which is a modified emerge-eval-in-buffer. | |
341 | ;; The function ediff-status-info, bound to `i', now replaces and extends | |
342 | ;; ediff-file-names and ediff-line-numbers, which were bound to `f' | |
343 | ;; and `i', respectively. | |
344 | ||
fcbadd58 RS |
345 | |
346 | ;; Wed Jun 10, 1994 | |
347 | ||
348 | ;; Improved `ediff-read-file-name' and `ediff-buffers' so they are now | |
349 | ;; providing more intuitive defaults. Modified `ediff-read-file-name' | |
350 | ;; so it won't cause problems under OS/2. | |
351 | ||
352 | ;; Fri Jun 24, 1994 | |
353 | ||
354 | ;; Modified ediff-find-file, ediff-files-internal, and made | |
355 | ;; emerge-verify-file-buffer into ediff-verify-file-buffer so that | |
356 | ;; Ediff will work correctly with remote and compressed | |
357 | ;; files. (Suggested by Sandy Rutherford <sandy@ibm550.sissa.it>.) | |
358 | ||
359 | ;; Fri Jun 28, 1994 | |
360 | ||
361 | ;; Fixed ediff-patch-files to work with remote and compressed files. | |
362 | ||
f9ae5324 RS |
363 | ;; Wed July 20, 1994 |
364 | ||
365 | ;; Changed menu bar items per RMS's suggestion. Changed odd/even faces | |
366 | ;; in Lemacs to italic. Changed ediff-*-face-* variables so that they | |
367 | ;; will contain names of faces instead of the face internal | |
368 | ;; representation. (Copy-face works better with face names than with | |
369 | ;; face internal representation. With face internal representation, if | |
370 | ;; a face vector mentions a font explicitly, copy-face may attempt to | |
371 | ;; copy this font, which would cause an error if the font has a wrong | |
372 | ;; size for one of the existing frames.) Improved the way | |
373 | ;; mode-line-buffer-identification is set in ediff-setup so that Ediff | |
374 | ;; will accommodate the way buffers are identified in mode-line.el and | |
375 | ;; uniquify.el. | |
376 | ||
0691ced3 RS |
377 | ;; Fri August 5, 1994 |
378 | ||
379 | ;; Ediff can now automatically skip over regions that differ only in | |
380 | ;; the white space and line breaks. This is controled with the variable | |
381 | ;; `ediff-ignore-similar-regions' and can be toggled on/off by typing | |
382 | ;; `##'. | |
383 | ||
384 | ;; Mon August 8, 1994 | |
385 | ||
0f0b0a86 | 386 | ;; If ediff-save-buffer is invoked with `wd', it'll save the diff |
0691ced3 RS |
387 | ;; output in a file. |
388 | ||
eaccd4d8 RS |
389 | ;; Wed August 24, 1994 |
390 | ||
391 | ;; Fixed ediff-toggle-read-only and ediff-patch-file so that they will | |
392 | ;; check out version-controled files before modifying them. This will | |
393 | ;; permit checking the modified versions back in. In earlier | |
394 | ;; versions, such modifications could be lost, unless the user takes | |
395 | ;; special care of preserving them. | |
396 | ||
397 | ;; Tue August 30, 1994 | |
398 | ||
399 | ;; Added ediff-submit-report. | |
400 | ;; Introduced ediff-revision as a uniform way of calling vc.el and | |
401 | ;; rcs.el. This is controled by ediff-version-control-package | |
402 | ;; variable. Functions vc-ediff, rcs-ediff are replaced by their | |
403 | ;; internal versions. | |
eaccd4d8 | 404 | |
0f0b0a86 | 405 | ;; Thu September 1, 1994 |
eaccd4d8 RS |
406 | |
407 | ;; Made ediff-overlay-put and ediff-move-overlay into bona fide | |
408 | ;; functions (rather than fset symbols). These now check if overlay's | |
409 | ;; buffer is alive. If not, overlay is deleted. This overcomes some of | |
410 | ;; the problems with Lemacs. | |
411 | ||
0f0b0a86 | 412 | ;; Thu September 8, 1994 |
b3a26225 | 413 | |
0f0b0a86 KH |
414 | ;; Added ediff-revision-key, ediff-load-version-control and streamlined |
415 | ;; vc/rcs-ediff[-internal]. Eliminated dependency on emerge.el. | |
b3a26225 | 416 | |
0f0b0a86 | 417 | ;; Fri September 23, 1994 |
b3a26225 | 418 | |
0f0b0a86 KH |
419 | ;; Added ediff-windows and ediff-regions. |
420 | ;; Changed ediff-setup-windows and related procedures to create | |
421 | ;; a separate dedicated control frame for each invocation of Ediff. | |
b3a26225 | 422 | |
0f0b0a86 | 423 | ;; Tue September 27, 1994 |
813f532d | 424 | |
0f0b0a86 KH |
425 | ;; Added redraw-display everywhere before creating or deleting |
426 | ;; frames. It appears that this cures Emacs' bug where it trashes some | |
427 | ;; fonts which leads to crashes. Also, some code cleanups and bug fixes. | |
813f532d | 428 | |
0f0b0a86 | 429 | ;; Fri September 30, 1994 |
813f532d | 430 | |
0f0b0a86 KH |
431 | ;; Fixed ediff-update-diffs so it'll work correctly with |
432 | ;; ediff-windows and ediff-regions. Added narrowing and widening to the | |
433 | ;; suite of commands available for ediff-windows and ediff-regions. | |
813f532d | 434 | |
0f0b0a86 | 435 | ;; Fri October 7, 1994 |
b3a26225 | 436 | |
0f0b0a86 KH |
437 | ;; Changed ediff-setup-windows to funcall the actual window setting |
438 | ;; function, which is either ediff-setup-windows-multiframe or | |
439 | ;; ediff-setup-windows-plain. Changed all temp file names to use `_' | |
440 | ;; instead of `.'. Presumably, this makes VMS happier. | |
441 | ;; Ported to VMS (thanks to Richard Levitte <levitte@e.kth.se>). | |
442 | ;; Added ediff-prefer-long-help-message and changed defaults. | |
443 | ;; Fighting with XEmacs bugs. Made it possible to switch between plain | |
444 | ;; and multiframe display easier, but XEmacs is still getting confused | |
445 | ;; at times. Added ediff-check-version and ediff-set-help-message. | |
446 | ;; Made more sensible temp file names, which is important when | |
447 | ;; generating context diffs. Added ediff-make-frame-position and | |
448 | ;; ediff-control-frame-position-function. | |
b3a26225 | 449 | |
0f0b0a86 | 450 | ;; Wed October 12, 1994 |
813f532d | 451 | |
f1a5512a | 452 | ;; ediff-window-visible-p now makes a call to frame-visible-p |
0f0b0a86 KH |
453 | ;; only when window-system is non-nil. Rearranged the block of fset's |
454 | ;; so that the wrong things won't be defined when window-system is nil. | |
455 | ;; Added ediff-revert-buffers-then-recompute-diffs function. | |
456 | ;; Removed flag-argument from a background call to shell-command. | |
457 | ;; Added ediff-shell-command to enable custom diff execute in the | |
458 | ;; background and insert output in ediff-custom-diff-buffer. | |
459 | ;; Added ediff-shell-command-filter, because XEmacs doesn't have it. | |
460 | ;; Made ediff-revision set up ediff-job-name to `ediff-revision'. | |
461 | ;; This enables users do ediff-revision-specific actions on exiting | |
462 | ;; Ediff using ediff-quit-hooks. | |
463 | ;; Reshaffled some fset's so that functions for checking color and | |
464 | ;; faces won't be touched on a non-windowing display. | |
b3a26225 | 465 | |
0f0b0a86 | 466 | ;; Thu October 20, 1994 |
813f532d | 467 | |
0f0b0a86 KH |
468 | ;; Modified ediff-make-fine-diffs so that no fine diffs are computed if |
469 | ;; one of the diff regions is empty. Saves time and also works around | |
470 | ;; the buggy diff program in AIX. | |
471 | ;; ediff no longer loads the version control package | |
472 | ;; automatically---only when ediff-revision is called. | |
473 | ;; Enabled focusing/hiding diff regions that match both or just one of the | |
474 | ;; regexps. | |
475 | ;; Changed ediff-regions to ediff-small-regions. Added ediff-large-regions. | |
476 | ;; Modified ediff-next/previous-difference to work right when both | |
477 | ;; skipping regexp matches and skipping similar regions is enabled. | |
478 | ;; Fixed bugs in positioning the control frame. | |
813f532d | 479 | |
0f0b0a86 | 480 | ;; Fri October 28, 1994 |
b3a26225 | 481 | |
0f0b0a86 KH |
482 | ;; Fixed bugs in ediff-next/previous-difference, ediff-set-visible-region |
483 | ;; Changed/added ediff-word-[1-4]. | |
b3a26225 | 484 | |
0f0b0a86 | 485 | ;; Tue November 1, 1994 |
b3a26225 | 486 | |
0f0b0a86 | 487 | ;; Made ediff-revision delete the temporary version files it creates. |
813f532d | 488 | |
0f0b0a86 | 489 | ;; Tue November 29, 1994 |
813f532d | 490 | |
0f0b0a86 KH |
491 | ;; Added ediff-swap-buffers. Split ediff-difference-vector into |
492 | ;; ediff-difference-vector-A and ediff-difference-vector-B, which | |
493 | ;; allowed to factor out a lot of stuff. | |
494 | ;; Made the code buffer-C ready. | |
813f532d | 495 | |
0f0b0a86 | 496 | ;; Thu December 1, 1994 |
813f532d | 497 | |
0f0b0a86 KH |
498 | ;; Lotsa bug fixes. Further rationalized the code. |
499 | ;; Added ediff-display-help-hooks, ediff-mode-hooks. | |
500 | ;; Replaced almost identical ediff-scroll-up/down with | |
501 | ;; ediff-scroll-vertically. | |
502 | ;; Replaced almost identical ediff-scroll-left/right with | |
503 | ;; ediff-scroll-horizontally. | |
504 | ;; Made the code buffer-C ready. | |
813f532d | 505 | |
0f0b0a86 | 506 | ;; Thu December 8, 1994 |
813f532d | 507 | |
0f0b0a86 KH |
508 | ;; Added ediff-toggle-wide-display. In plain display, help message is |
509 | ;; now centered correctly. | |
813f532d | 510 | |
0f0b0a86 | 511 | ;; Fri December 9, 1994 |
813f532d | 512 | |
f1a5512a KH |
513 | ;; Added ediff-toggle-multiframe. |
514 | ;; Fixed ediff-pop-diff and ediff-copy-diff, so that they will | |
0f0b0a86 | 515 | ;; invoke auto-refining, if necessary. |
813f532d | 516 | |
0f0b0a86 | 517 | ;; Mon December 12, 1994 |
813f532d | 518 | |
0f0b0a86 KH |
519 | ;; Modified ediff-toggle-wide-display so it would funcall |
520 | ;; ediff-make-wide-display-function. | |
813f532d | 521 | |
0f0b0a86 | 522 | ;; Tue December 13, 1994 |
813f532d | 523 | |
0f0b0a86 | 524 | ;; Ediff now chooses its surrogate minibuffer from frame A. |
813f532d | 525 | |
0f0b0a86 | 526 | ;; Mon December 20, 1994 |
eaccd4d8 | 527 | |
0f0b0a86 | 528 | ;; Added ediff-keymap-setup-hooks. |
813f532d | 529 | |
0f0b0a86 | 530 | ;; Fri December 23, 1994 |
eaccd4d8 | 531 | |
0f0b0a86 KH |
532 | ;; Changed the representation in ediff-killed-diffs-alist so that |
533 | ;; ediff-save-diff-region and ediff-pop-diff won't be confused when the | |
534 | ;; user swaps buffers. | |
535 | ||
536 | ;; Mon December 26, 1994 | |
537 | ||
538 | ;; Placated OS/2 by making Ediff to synchronize the call to startup | |
539 | ;; hooks with the acynchronous process that computes custom diffs. | |
540 | ;; This has no effect on Unix installations (and VMS?), but | |
541 | ;; may increase Ediff's startup time under OS/2 by 1 or 2 seconds. | |
542 | ||
543 | ;; Thu December 29, 1994 | |
544 | ||
545 | ;; ediff-recenter now deactivates the mark, so that transient mark mode | |
546 | ;; highlighting won't interfere with Ediff's highlighting. | |
547 | ;; Also, ediff-recenter tries to not deiconify control frame, if it is | |
548 | ;; not needed. | |
549 | ||
550 | ;; Fri December 30, 1994 | |
551 | ||
552 | ;; Small bugs. Worked around the OS/2 bug where | |
553 | ;; modify-frame-parameters has no effect on iconified frames. Ediff | |
554 | ;; now remembers the iconification status of the control frame and uses | |
555 | ;; it as a preferred way of displaying it when help is toggled | |
556 | ;; off. (This can be observed only in Emacs (not XEmacs) and only if | |
557 | ;; the window manager lets icons accept keyboard input.) | |
558 | ||
559 | ;; Tue January 3, 1995 | |
560 | ||
561 | ;; Some futher work on incorporating buffer C in ediff-extract-diffs, | |
562 | ;; ediff-focus/hide-on-regexp-matches, and | |
563 | ;; ediff-setup-windows-plain/multiframe. The preceding two functions | |
564 | ;; now dispatch the appropriate setup function depending on whether the | |
565 | ;; current job is comparison or merge. | |
566 | ||
567 | ;; Wed January 4, 1995 | |
568 | ||
569 | ;; Made it work under Emacs built without the X support. | |
570 | ||
571 | ;; Fri January 6, 1995 | |
572 | ||
573 | ;; Slightly changed the prompting behavior of ediff-files. Bug fix in | |
574 | ;; mode-line-buffer-identification. | |
575 | ||
576 | ;; Wed January 18, 1995 | |
577 | ||
578 | ;; Added 3way comparison and support for diff3. Ported to NeXTStep | |
579 | ;; | |
580 | ;; Fri January 20, 1995 | |
581 | ||
582 | ;; Added ediff-merge-files, ediff-merge-buffers, | |
583 | ;; ediff-merge-files-with-ancestor, ediff-merge-buffers-with-ancestor, | |
584 | ;; ediff-merge-revisions, ediff-merge-revisions-with-ancestor. | |
585 | ||
586 | ;; Tue January 24, 1995 | |
587 | ||
588 | ;; Bug fixes. Split into several files. | |
589 | ||
590 | ;; Thu January 26, 1995 | |
591 | ||
592 | ;; `*' is now bound to ediff-make-or-kill-fine-diffs. This lets the | |
593 | ;; user to kill fine diffs for the current region (by providing a | |
594 | ;; negative prefix arg), if there are so many of them as to hamper | |
595 | ;; the viewing. | |
596 | ||
597 | ;; Mon January 30, 1995 | |
598 | ||
599 | ;; Changed ediff-selective-display to ediff-set-visible-region, | |
600 | ;; ediff-toggle-selective-display to ediff-toggle-narrow-region. | |
601 | ;; Ediff now turns selective display off before starting. Restores | |
602 | ;; selective display on exit. | |
603 | ;; In 2-way comparison, `a' now copies to buf `b' and `b' to buf `a'. | |
604 | ;; Previously, the bindings were `ab' and `ba'. | |
605 | ||
606 | ;; Wed February 1, 1995 | |
607 | ||
2b911848 | 608 | ;; Added ediff-undo-selective-display (thanks to Stig <stig@hackvan.com>). |
0f0b0a86 KH |
609 | ;; Rearranged autoloads. Renamed ediff-entry.el into ediff.el and |
610 | ;; ediff.el into ediff-util.el. | |
611 | ||
612 | ;; Fri February 3 | |
613 | ||
614 | ;; Added ediff-toggle-show-clashes-only, which is bound to `$'. | |
615 | ||
616 | ;; Fri February 19 | |
617 | ||
618 | ;; Some minor patches from Stig. Also, made ediff-xemacs-p and | |
619 | ;; ediff-*-job into variables for better performance. | |
620 | ;; In ediff-setup, diff regions are now computed after buffers A/B/C | |
621 | ;; are set up. Previously, it didn't work right with selective display. | |
622 | ;; Also, added ediff-profile to time Ediff commands and | |
623 | ;; ediff-debug-info for civilized display of the difference vectors | |
624 | ;; (and possibly more in the future). | |
625 | ||
f1a5512a KH |
626 | ;; Tue March 18 |
627 | ||
628 | ;; Fixed ediff-diff-at-point and ediff-toggle-multiframe. | |
629 | ;; Added ediff-destroy-control-frame, ediff-window-display-p. The latter | |
630 | ;; replaces window-system in many cases. Needed because in XEmacs 19.12 | |
631 | ;; window-system returns 'tty on a tty display. | |
632 | ;; Converted xemacs *screen* nomenclature to *frame*. | |
633 | ;; Made ediff-patch-buffer cope with buffers that don't visit any file. | |
634 | ;; Fixed ediff-toggle-read-only so it knows the difference between | |
635 | ;; version-controlled files and others. It also knows whether we are using | |
636 | ;; patch or not. | |
637 | ;; Renamed ediff-windows to ediff-windows-wordwise, added | |
638 | ;; ediff-windows-linewise. Changed ediff-small/large-regions to | |
639 | ;; ediff-regions-wordwise/linewise | |
640 | ||
641 | ;; Tue May 2 | |
642 | ||
643 | ;; Added ediff-documentation. Fixes for XEmacs 19.12. | |
644 | ;; Merge buffer now assumes the major mode of ediff-default-variant. | |
645 | ||
646 | ;; Mon May 31, 1995 | |
0f0b0a86 | 647 | |
f1a5512a KH |
648 | ;; Ediff-revision now takes a prefix argument. Can compare two versions of |
649 | ;; the same file. Cleaned up ediff-make-control-frame. | |
650 | ;; Fixed a bug in ediff-get-visible-buffer-window. | |
651 | ;; Added ediff-cleanup-hooks, ediff-janitor. | |
652 | ;; ediff-cleanup-hooks is called before ediff-quit-hooks. | |
0f0b0a86 KH |
653 | |
654 | ||
655 | ;;; TO DO: | |
656 | ;; ------ | |
657 | ;; | |
658 | ;; 1. Add support for multiple sessions. (At present, one can run | |
659 | ;; multiple Ediff sessions, but they won't be related.) The idea is to | |
660 | ;; have vars local to each control buffer, which will tell which buffer is | |
661 | ;; the next and which is the previous one. The user could then go forward | |
662 | ;; and backward by typing C-SPC and C-DEL (or C-n and C-p). | |
663 | ;; This will probably entail some minor modifications to ediff-setup. | |
664 | ;; The primary use of this feature would be comparing directories of | |
665 | ;; similarly named files and multi-file patch. For the latter, Ediff will | |
666 | ;; have to parse patches to extract the names of files. | |
667 | ||
668 | ||
669 | ;;; Acknowledgements: | |
670 | ||
671 | ;; Special thanks to Alastair Burt <burt@dfki.uni-kl.de>, Kevin Broadey | |
672 | ;; <KevinB@bartley.demon.co.uk>, Harald Boegeholz | |
673 | ;; <hwb@machnix.mathematik.uni-stuttgart.de>, Jin S. Choi" <jin@atype.com>, | |
674 | ;; Eric Eide <eeide@asylum.cs.utah.edu>, Kevin Esler <esler@ch.hp.com>, Robert | |
675 | ;; Estes <estes@ece.ucdavis.edu>, Eric Freudenthal | |
676 | ;; <freudent@jan.ultra.nyu.edu>, | |
677 | ;; Job Ganzevoort <Job.Ganzevoort@cwi.nl>, Boris Goldowsky | |
678 | ;; <boris@cs.rochester.edu>, Allan Gottlieb <gottlieb@allan.ultra.nyu.edu>, | |
679 | ;; Xiaoli Huang <hxl@epic.com>, Larry Gouge <larry@itginc.com>, | |
f1a5512a KH |
680 | ;; Karl Heuer <kwzh@gnu.ai.mit.edu>, <irvine@lks.csi.com>, |
681 | ;; <jaffe@chipmunk.cita.utoronto.ca>, David Karr | |
0f0b0a86 KH |
682 | ;; <dkarr@nmo.gtegsc.com>, Norbert Kiesel |
683 | ;; <norbert@i3.informatik.rwth-aachen.de>, Fritz Knabe <Fritz.Knabe@ecrc.de>, | |
684 | ;; Heinz Knutzen <hk@informatik.uni-kiel.d400.de>, Ken Laprade | |
685 | ;; <laprade@dw3f.ess.harris.com>, Richard Levitte | |
686 | ;; <levitte@e.kth.se>, Martin Maechler <maechler@stat.math.ethz.ch>, | |
687 | ;; Richard Mlynarik <mly@adoc.xerox.com>, Chris Murphy | |
688 | ;; <murphycm@sun.aston.ac.uk>, Eyvind Ness <Eyvind.Ness@hrp.no>, Ray Nickson | |
689 | ;; <nickson@cs.uq.oz.au>, Paul Raines <raines@slac.stanford.edu>, Tibor | |
690 | ;; Polgar <tlp00@spg.amdahl.com>, C.S. Roberson <roberson@aur.alcatel.com>, | |
691 | ;; Kevin Rodgers <kevin.rodgers@ihs.com>, Sandy Rutherford | |
692 | ;; <sandy@ibm550.sissa.it>, Heribert Schuetz <schuetz@ecrc.de>, Andy Scott | |
693 | ;; <ascott@pcocd2.intel.com>, Axel Seibert | |
694 | ;; <axel@tumbolia.ppp.informatik.uni-muenchen.de>, Richard Stallman | |
695 | ;; <rms@gnu.ai.mit.edu>, Richard Stanton <stanton@haas.berkeley.edu>, | |
696 | ;; Ake Stenhoff <etxaksf@aom.ericsson.se>, | |
697 | ;; Stig <stig@hackvan.com>, Peter Stout <Peter_Stout@cs.cmu.edu>, | |
698 | ;; Raymond Toy <toy@rtp.ericsson.se>, | |
699 | ;; and Ilya Zakharevich <ilya@math.ohio-state.edu> | |
700 | ;; for contributing ideas, patches, and bug reports. | |
701 | ;; | |
702 | ;; Thanks also to many others who felt obliged to drop a thank you note. | |
703 | ||
704 | ||
705 | ;;; Code: | |
706 | ||
707 | (require 'ediff-init) | |
eaccd4d8 RS |
708 | |
709 | (defvar ediff-version-control-package 'vc | |
710 | "Version control package used. | |
0f0b0a86 KH |
711 | Currently, Ediff supports vc.el and rcs.el. Set this to `rcs' if you have |
712 | rcs.el and want to use it instead of the standard vc.el. | |
713 | ||
714 | Note: both packages provide access to RCS, but only vc.el comes with Emacs | |
715 | distribution.") | |
716 | ||
d8e54b47 | 717 | (defvar ediff-revision-key nil |
0f0b0a86 | 718 | "Key to which `ediff-revision' is to be bound.") |
813f532d | 719 | |
0f0b0a86 KH |
720 | (defvar ediff-use-last-dir nil |
721 | "*If t, Ediff uses previous directory as default when reading file name.") | |
b3a26225 | 722 | |
813f532d RS |
723 | (defvar ediff-last-dir-A nil |
724 | "Last directory used by an Ediff command for file-A.") | |
725 | (defvar ediff-last-dir-B nil | |
726 | "Last directory used by an Ediff command for file-B.") | |
0f0b0a86 KH |
727 | (defvar ediff-last-dir-C nil |
728 | "Last directory used by an Ediff command for file-C.") | |
729 | (defvar ediff-last-dir-ancestor nil | |
730 | "Last directory used by an Ediff command for the ancestor file.") | |
fcbadd58 RS |
731 | (defvar ediff-last-dir-patch nil |
732 | "Last directory used by an Ediff command for file to patch.") | |
b3a26225 | 733 | |
0f0b0a86 | 734 | ;;; Patching |
813f532d RS |
735 | |
736 | ;;;###autoload | |
f1a5512a | 737 | (defun ediff-patch-file (source-filename &optional startup-hooks job-name) |
b3a26225 | 738 | "Run Ediff by patching FILE-TP-PATCH." |
f1a5512a | 739 | ;; This now returns the control buffer |
fcbadd58 RS |
740 | (interactive |
741 | (list (ediff-read-file-name "File to patch" | |
742 | (if ediff-use-last-dir | |
743 | ediff-last-dir-patch | |
744 | default-directory) | |
745 | nil))) | |
813f532d | 746 | |
0f0b0a86 | 747 | (setq source-filename (expand-file-name source-filename)) |
f1a5512a KH |
748 | (ediff-get-patch-buffer |
749 | (if (eq job-name 'ediff-patch-buffer) | |
750 | (ediff-eval-in-buffer (get-file-buffer source-filename) | |
751 | default-directory) | |
752 | (file-name-directory source-filename))) | |
0f0b0a86 | 753 | |
fcbadd58 RS |
754 | (let* ((backup-extension |
755 | ;; if the user specified a -b option, extract the backup | |
0f0b0a86 | 756 | ;; extension from there; else use `_orig' |
fcbadd58 RS |
757 | (substring ediff-patch-options |
758 | (if (string-match "-b[ \t]+" ediff-patch-options) | |
759 | (match-end 0) 0) | |
760 | (if (string-match "-b[ \t]+[^ \t]+" ediff-patch-options) | |
761 | (match-end 0) 0))) | |
fcbadd58 RS |
762 | (shell-file-name ediff-shell) |
763 | ;; ediff-find-file may use a temp file to do the patch | |
764 | ;; so, we save source-filename and true-source-filename as a var | |
765 | ;; that initially is source-filename but may be changed to a temp | |
766 | ;; file for the purpose of patching. | |
767 | (true-source-filename source-filename) | |
768 | (target-filename source-filename) | |
f1a5512a | 769 | target-buf buf-to-patch file-name-magic-p ctl-buf) |
0f0b0a86 KH |
770 | |
771 | ;; if the user didn't specify a backup extension, use _orig | |
772 | (if (string= backup-extension "") | |
773 | (setq backup-extension "_orig")) | |
fcbadd58 RS |
774 | |
775 | ;; Make a temp file, if source-filename has a magic file handler (or if | |
776 | ;; it is handled via auto-mode-alist and similar magic). | |
777 | ;; Check if there is a buffer visiting source-filename and if they are in | |
778 | ;; synch; arrange for the deletion of temp file. | |
779 | (ediff-find-file 'true-source-filename 'buf-to-patch | |
780 | 'ediff-last-dir-patch 'startup-hooks) | |
781 | ||
782 | ;; Check if source file name has triggered black magic, such as file name | |
783 | ;; handlers or auto mode alist, and make a note of it. | |
0f0b0a86 KH |
784 | ;; true-source-filename should be either the original name or a |
785 | ;; temporary file where we put the after-product of the file handler. | |
0691ced3 RS |
786 | (setq file-name-magic-p (not (equal (file-truename true-source-filename) |
787 | (file-truename source-filename)))) | |
fcbadd58 | 788 | |
f1a5512a | 789 | ;; Checkout orig file, if necessary, so that the patched file could be |
eaccd4d8 | 790 | ;; checked back in. |
f1a5512a KH |
791 | (if (ediff-file-checked-in-p (buffer-file-name buf-to-patch)) |
792 | (ediff-toggle-read-only buf-to-patch)) | |
eaccd4d8 | 793 | |
0f0b0a86 KH |
794 | (ediff-eval-in-buffer ediff-patch-diagnostics |
795 | (message "Applying patch ... ")(sit-for 0) | |
796 | ;; always pass patch the -f option, so it won't ask any questions | |
797 | (shell-command-on-region | |
798 | (point-min) (point-max) | |
799 | (format "%s -f %s -b %s %s" | |
800 | ediff-patch-program ediff-patch-options | |
801 | backup-extension | |
802 | (expand-file-name true-source-filename)) | |
803 | t)) | |
804 | (message "Applying patch ... done")(sit-for 0) | |
fcbadd58 | 805 | (switch-to-buffer ediff-patch-diagnostics) |
0f0b0a86 | 806 | (sit-for 0) ; synchronize |
fcbadd58 | 807 | |
0f0b0a86 KH |
808 | (or (file-exists-p (concat true-source-filename backup-extension)) |
809 | (error "Patch failed or didn't modify the original file")) | |
813f532d | 810 | |
fcbadd58 | 811 | ;; If black magic is involved, apply patch to a temp copy of the |
0f0b0a86 KH |
812 | ;; file. Otherwise, apply patch to the orig copy. If patch is applied |
813 | ;; to temp copy, we name the result old-name_patched for local files | |
814 | ;; and temp-copy_patched for remote files. The orig file name isn't | |
815 | ;; changed, and the temp copy of the original is later deleted. | |
fcbadd58 | 816 | ;; Without magic, the original file is renamed (usually into |
0f0b0a86 KH |
817 | ;; old-name_orig) and the result of patching will have the same name as |
818 | ;; the original. | |
fcbadd58 | 819 | (if (not file-name-magic-p) |
0f0b0a86 KH |
820 | (ediff-eval-in-buffer buf-to-patch |
821 | (set-visited-file-name (concat source-filename backup-extension)) | |
822 | (set-buffer-modified-p nil)) | |
823 | ||
824 | ;; Black magic in effect. | |
825 | ;; If orig file was remote, put the patched file in the temp directory. | |
826 | ;; If orig file is local, put the patched file in the directory of | |
827 | ;; the orig file. | |
828 | (setq target-filename | |
829 | (concat | |
830 | (if (ediff-file-remote-p (file-truename source-filename)) | |
831 | true-source-filename | |
832 | source-filename) | |
833 | "_patched")) | |
834 | ||
fcbadd58 RS |
835 | (rename-file true-source-filename target-filename t) |
836 | ||
837 | ;; arrange that the temp copy of orig will be deleted | |
0f0b0a86 | 838 | (rename-file (concat true-source-filename backup-extension) |
fcbadd58 RS |
839 | true-source-filename t)) |
840 | ||
841 | ;; make orig buffer read-only | |
eaccd4d8 | 842 | (setq startup-hooks |
f1a5512a | 843 | (cons 'ediff-set-read-only-in-buf-A startup-hooks)) |
eaccd4d8 | 844 | |
fcbadd58 | 845 | ;; set up a buf for the patched file |
f1a5512a | 846 | (setq target-buf (find-file-noselect target-filename)) |
fcbadd58 | 847 | |
f1a5512a KH |
848 | (setq ctl-buf |
849 | (ediff-buffers-internal | |
850 | buf-to-patch target-buf nil | |
851 | startup-hooks '(or job-name ediff-patch-file))) | |
813f532d | 852 | |
fcbadd58 | 853 | (bury-buffer ediff-patch-diagnostics) |
f1a5512a KH |
854 | (message "Patch diagnostics are available in buffer %s" |
855 | (buffer-name ediff-patch-diagnostics)) | |
856 | ctl-buf)) | |
0f0b0a86 | 857 | |
f1a5512a | 858 | (defun ediff-set-read-only-in-buf-A () |
0f0b0a86 | 859 | "Used as a startup hook to set `_orig' patch file read-only." |
f1a5512a KH |
860 | (ediff-eval-in-buffer ediff-buffer-A |
861 | (toggle-read-only 1))) | |
813f532d | 862 | |
0f0b0a86 | 863 | ;;;###autoload |
813f532d | 864 | (defalias 'epatch 'ediff-patch-file) |
0f0b0a86 | 865 | ;;;###autoload |
b3a26225 | 866 | (defalias 'epatch-buffer 'ediff-patch-buffer) |
813f532d | 867 | |
0f0b0a86 | 868 | ;;; Compare files/buffers |
813f532d RS |
869 | |
870 | ;;;###autoload | |
871 | (defun ediff-files (file-A file-B &optional startup-hooks) | |
0f0b0a86 | 872 | "Run Ediff on a pair of files, FILE-A and FILE-B." |
813f532d | 873 | (interactive |
0f0b0a86 KH |
874 | (let ((dir-A (if ediff-use-last-dir |
875 | ediff-last-dir-A | |
876 | default-directory)) | |
877 | dir-B f) | |
878 | (list (setq f (ediff-read-file-name "File A to compare" dir-A nil)) | |
813f532d | 879 | (ediff-read-file-name "File B to compare" |
0f0b0a86 KH |
880 | (setq dir-B |
881 | (if ediff-use-last-dir | |
882 | ediff-last-dir-B | |
883 | (file-name-directory f))) | |
884 | (progn | |
885 | (setq file-name-history | |
886 | (cons (abbreviate-file-name | |
887 | (expand-file-name | |
888 | (file-name-nondirectory f) | |
889 | dir-B)) | |
890 | file-name-history)) | |
891 | f)) | |
892 | ))) | |
893 | (ediff-files-internal file-A | |
894 | (if (file-directory-p file-B) | |
895 | (expand-file-name | |
896 | (file-name-nondirectory file-A) file-B) | |
897 | file-B) | |
898 | nil ; file-C | |
899 | startup-hooks | |
900 | 'ediff-files)) | |
901 | ||
902 | ;;;###autoload | |
903 | (defun ediff-files3 (file-A file-B file-C &optional startup-hooks) | |
904 | "Run Ediff on three files, FILE-A, FILE-B, and FILE-C." | |
905 | (interactive | |
906 | (let ((dir-A (if ediff-use-last-dir | |
907 | ediff-last-dir-A | |
908 | default-directory)) | |
909 | dir-B dir-C f ff) | |
910 | (list (setq f (ediff-read-file-name "File A to compare" dir-A nil)) | |
911 | (setq ff (ediff-read-file-name "File B to compare" | |
912 | (setq dir-B | |
913 | (if ediff-use-last-dir | |
914 | ediff-last-dir-B | |
915 | (file-name-directory f))) | |
916 | (progn | |
917 | (setq file-name-history | |
918 | (cons | |
919 | (abbreviate-file-name | |
920 | (expand-file-name | |
921 | (file-name-nondirectory f) | |
922 | dir-B)) | |
923 | file-name-history)) | |
924 | f))) | |
925 | (ediff-read-file-name "File C to compare" | |
926 | (setq dir-C (if ediff-use-last-dir | |
927 | ediff-last-dir-C | |
928 | (file-name-directory ff))) | |
929 | (progn | |
930 | (setq file-name-history | |
931 | (cons (abbreviate-file-name | |
932 | (expand-file-name | |
933 | (file-name-nondirectory ff) | |
934 | dir-C)) | |
935 | file-name-history)) | |
936 | ff)) | |
813f532d | 937 | ))) |
b3a26225 RS |
938 | (ediff-files-internal file-A |
939 | (if (file-directory-p file-B) | |
940 | (expand-file-name | |
941 | (file-name-nondirectory file-A) file-B) | |
942 | file-B) | |
0f0b0a86 KH |
943 | (if (file-directory-p file-C) |
944 | (expand-file-name | |
945 | (file-name-nondirectory file-A) file-C) | |
946 | file-C) | |
947 | startup-hooks | |
948 | 'ediff-files3)) | |
813f532d | 949 | |
0f0b0a86 KH |
950 | ;;;###autoload |
951 | (defalias 'ediff3 'ediff-files3) | |
813f532d | 952 | |
813f532d | 953 | |
0f0b0a86 KH |
954 | (defun ediff-find-file (file-var buffer-name &optional last-dir hooks-var) |
955 | "Visit FILE and arrange its buffer to Ediff's liking. | |
956 | FILE is actually a variable symbol that must contain a true file name. | |
957 | BUFFER-NAME is a variable symbol, which will get the buffer object into which | |
958 | FILE is read. LAST-DIR is the directory variable symbol where FILE's | |
959 | directory name should be returned. HOOKS is a variable symbol that will be | |
960 | assigned the hook to be executed after `ediff-startup' is finished. | |
961 | `ediff-find-file' arranges that the temp files it might create will be | |
962 | deleted." | |
963 | (let* ((file (symbol-value file-var)) | |
f1a5512a | 964 | (file-magic (find-file-name-handler file 'find-file-noselect)) |
0f0b0a86 KH |
965 | (temp-file-name-prefix (file-name-nondirectory file))) |
966 | (if (not (file-readable-p file)) | |
967 | (error "File `%s' does not exist or is not readable" file)) | |
968 | ||
969 | ;; some of the command, below, require full file name | |
970 | (setq file (expand-file-name file)) | |
971 | ||
972 | ;; Record the directory of the file | |
973 | (if last-dir | |
974 | (set last-dir (expand-file-name (file-name-directory file)))) | |
975 | ||
976 | ;; Setup the buffer | |
977 | (set buffer-name (find-file-noselect file)) | |
978 | ||
979 | (ediff-eval-in-buffer (symbol-value buffer-name) | |
980 | (widen) ; Make sure the entire file is seen | |
981 | (cond (file-magic ;; file has handler, such as jka-compr-handler or | |
982 | ;; ange-ftp-hook-function--arrange for temp file | |
983 | (ediff-verify-file-buffer 'magic) | |
984 | (setq file (ediff-make-temp-file temp-file-name-prefix)) | |
985 | (set hooks-var (cons (` (lambda () (delete-file (, file)))) | |
986 | (symbol-value hooks-var)))) | |
987 | ;; file processed via auto-mode-alist, a la uncompress.el | |
988 | ((not (equal (file-truename file) | |
989 | (file-truename (buffer-file-name)))) | |
990 | (setq file (ediff-make-temp-file temp-file-name-prefix)) | |
991 | (set hooks-var (cons (` (lambda () (delete-file (, file)))) | |
992 | (symbol-value hooks-var)))) | |
993 | (t ;; plain file---just check that the file matches the buffer | |
994 | (ediff-verify-file-buffer)))) | |
995 | (set file-var file))) | |
996 | ||
997 | (defun ediff-files-internal (file-A file-B file-C startup-hooks job-name) | |
998 | (let (buf-A buf-B buf-C) | |
999 | (message "Reading file %s ... " file-A)(sit-for 0) | |
1000 | (ediff-find-file 'file-A 'buf-A 'ediff-last-dir-A 'startup-hooks) | |
1001 | (message "Reading file %s ... " file-B)(sit-for 0) | |
1002 | (ediff-find-file 'file-B 'buf-B 'ediff-last-dir-B 'startup-hooks) | |
1003 | (if (and (stringp file-C) (not ediff-merge-job)) | |
1004 | (progn | |
1005 | (message "Reading file %s ... " file-C)(sit-for 0) | |
1006 | (ediff-find-file | |
1007 | 'file-C 'buf-C | |
1008 | (if (eq job-name 'ediff-merge-files-with-ancestor) | |
1009 | 'ediff-last-dir-ancestor 'ediff-last-dir-C) | |
1010 | 'startup-hooks))) | |
1011 | (ediff-setup buf-A file-A | |
1012 | buf-B file-B | |
1013 | buf-C file-C | |
1014 | startup-hooks | |
1015 | (list (cons 'ediff-job-name job-name))))) | |
1016 | ||
1017 | ||
1018 | ;;;###autoload | |
1019 | (defalias 'ediff 'ediff-files) | |
813f532d | 1020 | |
813f532d RS |
1021 | |
1022 | ;;;###autoload | |
0f0b0a86 | 1023 | (defun ediff-buffers (buffer-A buffer-B &optional startup-hooks job-name) |
813f532d | 1024 | "Run Ediff on a pair of buffers, BUFFER-A and BUFFER-B." |
fcbadd58 | 1025 | (interactive |
0f0b0a86 KH |
1026 | (let (bf) |
1027 | (list (setq bf (read-buffer "Buffer A to compare: " | |
1028 | (ediff-other-buffer "") t)) | |
1029 | (read-buffer "Buffer B to compare: " | |
1030 | (progn | |
1031 | ;; realign buffers so that two visible bufs will be | |
1032 | ;; at the top | |
1033 | (save-window-excursion (other-window 1)) | |
1034 | (ediff-other-buffer bf)) | |
1035 | t)))) | |
1036 | ||
1037 | (or job-name (setq job-name 'ediff-buffers)) | |
1038 | (ediff-buffers-internal buffer-A buffer-B nil startup-hooks job-name)) | |
1039 | ||
1040 | ;;;###autoload | |
1041 | (defun ediff-buffers3 (buffer-A buffer-B buffer-C | |
1042 | &optional startup-hooks job-name) | |
1043 | "Run Ediff on three buffers, BUFFER-A, BUFFER-B, and BUFFER-C." | |
1044 | (interactive | |
1045 | (let (bf bff) | |
1046 | (list (setq bf (read-buffer "Buffer A to compare: " | |
1047 | (ediff-other-buffer "") t)) | |
1048 | (setq bff (read-buffer "Buffer B to compare: " | |
1049 | (progn | |
1050 | ;; realign buffers so that two visible | |
1051 | ;; bufs will be at the top | |
1052 | (save-window-excursion (other-window 1)) | |
1053 | (ediff-other-buffer bf)) | |
1054 | t)) | |
1055 | (read-buffer "Buffer C to compare: " | |
1056 | (progn | |
1057 | ;; realign buffers so that three visible | |
1058 | ;; bufs will be at the top | |
1059 | (save-window-excursion (other-window 1)) | |
1060 | (ediff-other-buffer (list bf bff))) | |
1061 | t) | |
1062 | ))) | |
1063 | ||
1064 | (or job-name (setq job-name 'ediff-buffers3)) | |
1065 | (ediff-buffers-internal buffer-A buffer-B buffer-C startup-hooks job-name)) | |
1066 | ||
1067 | ||
1068 | ||
1069 | (defun ediff-buffers-internal (buf-A buf-B buf-C startup-hooks job-name) | |
1070 | (let* ((buf-A-file-name (buffer-file-name (get-buffer buf-A))) | |
1071 | (buf-B-file-name (buffer-file-name (get-buffer buf-B))) | |
1072 | (buf-C-is-alive (ediff-buffer-live-p buf-C)) | |
1073 | (buf-C-file-name (if buf-C-is-alive | |
1074 | (buffer-file-name (get-buffer buf-B)))) | |
1075 | file-A file-B file-C) | |
1076 | (if (not (ediff-buffer-live-p buf-A)) | |
1077 | (error "Buffer %S doesn't exist" buf-A)) | |
1078 | (if (not (ediff-buffer-live-p buf-B)) | |
1079 | (error "Buffer %S doesn't exist" buf-B)) | |
1080 | (let ((ediff-job-name job-name)) | |
1081 | (if (and ediff-3way-comparison-job | |
1082 | (not buf-C-is-alive)) | |
1083 | (error "Buffer %S doesn't exist" buf-C))) | |
1084 | (if (stringp buf-A-file-name) | |
1085 | (setq buf-A-file-name (file-name-nondirectory buf-A-file-name))) | |
1086 | (if (stringp buf-B-file-name) | |
1087 | (setq buf-B-file-name (file-name-nondirectory buf-B-file-name))) | |
1088 | (if (stringp buf-C-file-name) | |
1089 | (setq buf-C-file-name (file-name-nondirectory buf-C-file-name))) | |
1090 | ||
1091 | ;; these three need to be evaluated in their buffers, since | |
1092 | ;; ediff-make-temp-file checks the current buffer when assigning file | |
1093 | ;; names | |
1094 | (ediff-eval-in-buffer buf-A | |
1095 | (setq file-A (ediff-make-temp-file buf-A-file-name))) | |
1096 | (ediff-eval-in-buffer buf-B | |
1097 | (setq file-B (ediff-make-temp-file buf-B-file-name))) | |
1098 | (if buf-C-is-alive | |
1099 | (ediff-eval-in-buffer buf-C | |
1100 | (setq file-C (ediff-make-temp-file buf-C-file-name)))) | |
1101 | ||
1102 | (ediff-setup (get-buffer buf-A) file-A | |
1103 | (get-buffer buf-B) file-B | |
1104 | (if buf-C-is-alive (get-buffer buf-C)) | |
1105 | file-C | |
1106 | (cons (` (lambda () | |
1107 | (delete-file (, file-A)) | |
1108 | (delete-file (, file-B)) | |
1109 | (if (stringp (, file-C)) (delete-file (, file-C))) | |
1110 | )) | |
1111 | startup-hooks) | |
1112 | (list (cons 'ediff-job-name job-name)) | |
1113 | ))) | |
1114 | ||
1115 | ||
1116 | ||
1117 | ;;; Compare regions and windows | |
1118 | ||
1119 | ;;;###autoload | |
f1a5512a KH |
1120 | (defun ediff-windows-wordwise (dumb-mode &optional wind-A wind-B startup-hooks) |
1121 | "Compare WIND-A and WIND-B, which are selected by clicking, wordwise. | |
0f0b0a86 KH |
1122 | With prefix argument, DUMB-MODE, or on a non-windowing display, works as |
1123 | follows: | |
1124 | If WIND-A is nil, use selected window. | |
1125 | If WIND-B is nil, use window next to WIND-A." | |
0f0b0a86 | 1126 | (interactive "P") |
f1a5512a KH |
1127 | (ediff-windows dumb-mode wind-A wind-B |
1128 | startup-hooks 'ediff-windows-wordwise 'word-mode)) | |
1129 | ||
1130 | ;;;###autoload | |
1131 | (defun ediff-windows-linewise (dumb-mode &optional wind-A wind-B startup-hooks) | |
1132 | "Compare WIND-A and WIND-B, which are selected by clicking, linewise. | |
1133 | With prefix argument, DUMB-MODE, or on a non-windowing display, works as | |
1134 | follows: | |
1135 | If WIND-A is nil, use selected window. | |
1136 | If WIND-B is nil, use window next to WIND-A." | |
1137 | (interactive "P") | |
1138 | (ediff-windows dumb-mode wind-A wind-B | |
1139 | startup-hooks 'ediff-windows-linewise nil)) | |
0f0b0a86 | 1140 | |
f1a5512a KH |
1141 | ;; Compare WIND-A and WIND-B, which are selected by clicking. |
1142 | ;; With prefix argument, DUMB-MODE, or on a non-windowing display, | |
1143 | ;; works as follows: | |
1144 | ;; If WIND-A is nil, use selected window. | |
1145 | ;; If WIND-B is nil, use window next to WIND-A. | |
1146 | (defun ediff-windows (dumb-mode wind-A wind-B startup-hooks job-name word-mode) | |
1147 | (if (or dumb-mode (not (ediff-window-display-p))) | |
0f0b0a86 KH |
1148 | (setq wind-A (ediff-get-next-window wind-A nil) |
1149 | wind-B (ediff-get-next-window wind-B wind-A)) | |
1150 | (setq wind-A (ediff-get-window-by-clicking wind-A nil 1) | |
1151 | wind-B (ediff-get-window-by-clicking wind-B wind-A 2))) | |
1152 | ||
1153 | (let ((buffer-A (window-buffer wind-A)) | |
1154 | (buffer-B (window-buffer wind-B)) | |
1155 | beg-A end-A beg-B end-B) | |
1156 | ||
1157 | (save-excursion | |
1158 | (save-window-excursion | |
1159 | (sit-for 0) ; synch before using window-start/end -- a precaution | |
1160 | (select-window wind-A) | |
1161 | (setq beg-A (window-start) | |
1162 | end-A (window-end)) | |
1163 | (select-window wind-B) | |
1164 | (setq beg-B (window-start) | |
1165 | end-B (window-end)))) | |
1166 | (ediff-regions-internal | |
1167 | buffer-A beg-A end-A buffer-B beg-B end-B | |
f1a5512a | 1168 | startup-hooks job-name word-mode))) |
0f0b0a86 KH |
1169 | |
1170 | ;;;###autoload | |
f1a5512a | 1171 | (defun ediff-regions-wordwise (buffer-A buffer-B &optional startup-hooks) |
0f0b0a86 KH |
1172 | "Run Ediff on a pair of regions in two different buffers. |
1173 | Regions \(i.e., point and mark\) are assumed to be set in advance. | |
1174 | This function is effective only for relatively small regions, up to 200 | |
f1a5512a | 1175 | lines. For large regions, use `ediff-regions-linewise'." |
0f0b0a86 KH |
1176 | (interactive |
1177 | (let (bf) | |
1178 | (list (setq bf (read-buffer "Region's A buffer: " | |
1179 | (ediff-other-buffer "") t)) | |
1180 | (read-buffer "Region's B buffer: " | |
1181 | (progn | |
1182 | ;; realign buffers so that two visible bufs will be | |
1183 | ;; at the top | |
1184 | (save-window-excursion (other-window 1)) | |
1185 | (ediff-other-buffer bf)) | |
1186 | t)))) | |
1187 | (if (not (ediff-buffer-live-p buffer-A)) | |
1188 | (error "Buffer %S doesn't exist" buffer-A)) | |
1189 | (if (not (ediff-buffer-live-p buffer-B)) | |
1190 | (error "Buffer %S doesn't exist" buffer-B)) | |
1191 | ||
1192 | ||
1193 | (let (reg-A-beg reg-A-end reg-B-beg reg-B-end) | |
1194 | (save-excursion | |
1195 | (set-buffer buffer-A) | |
1196 | (setq reg-A-beg (region-beginning) | |
1197 | reg-A-end (region-end)) | |
1198 | (set-buffer buffer-B) | |
1199 | (setq reg-B-beg (region-beginning) | |
1200 | reg-B-end (region-end))) | |
1201 | ||
1202 | (ediff-regions-internal | |
1203 | (get-buffer buffer-A) reg-A-beg reg-A-end | |
1204 | (get-buffer buffer-B) reg-B-beg reg-B-end | |
f1a5512a | 1205 | startup-hooks 'ediff-regions-wordwise 'word-mode))) |
0f0b0a86 KH |
1206 | |
1207 | ;;;###autoload | |
f1a5512a | 1208 | (defun ediff-regions-linewise (buffer-A buffer-B &optional startup-hooks) |
0f0b0a86 KH |
1209 | "Run Ediff on a pair of regions in two different buffers. |
1210 | Regions \(i.e., point and mark\) are assumed to be set in advance. | |
1211 | Each region is enlarged to contain full lines. | |
1212 | This function is effective for large regions, over 100-200 | |
f1a5512a | 1213 | lines. For small regions, use `ediff-regions-wordwise'." |
0f0b0a86 KH |
1214 | (interactive |
1215 | (let (bf) | |
1216 | (list (setq bf (read-buffer "Region A's buffer: " | |
1217 | (ediff-other-buffer "") t)) | |
1218 | (read-buffer "Region B's buffer: " | |
1219 | (progn | |
1220 | ;; realign buffers so that two visible bufs will be | |
1221 | ;; at the top | |
1222 | (save-window-excursion (other-window 1)) | |
1223 | (ediff-other-buffer bf)) | |
1224 | t)))) | |
fcbadd58 | 1225 | (if (not (ediff-buffer-live-p buffer-A)) |
0f0b0a86 | 1226 | (error "Buffer %S doesn't exist" buffer-A)) |
fcbadd58 | 1227 | (if (not (ediff-buffer-live-p buffer-B)) |
0f0b0a86 KH |
1228 | (error "Buffer %S doesn't exist" buffer-B)) |
1229 | ||
1230 | (let (reg-A-beg reg-A-end reg-B-beg reg-B-end) | |
1231 | (save-excursion | |
1232 | (set-buffer buffer-A) | |
1233 | (setq reg-A-beg (region-beginning) | |
1234 | reg-A-end (region-end)) | |
1235 | ;; enlarge the region to hold full lines | |
1236 | (goto-char reg-A-beg) | |
1237 | (beginning-of-line) | |
1238 | (setq reg-A-beg (point)) | |
1239 | (goto-char reg-A-end) | |
1240 | (end-of-line) | |
1241 | (or (eobp) (forward-char)) ; include the newline char | |
1242 | (setq reg-A-end (point)) | |
fcbadd58 | 1243 | |
0f0b0a86 KH |
1244 | (set-buffer buffer-B) |
1245 | (setq reg-B-beg (region-beginning) | |
1246 | reg-B-end (region-end)) | |
1247 | ;; enlarge the region to hold full lines | |
1248 | (goto-char reg-A-beg) | |
1249 | (goto-char reg-B-beg) | |
1250 | (beginning-of-line) | |
1251 | (setq reg-B-beg (point)) | |
1252 | (goto-char reg-B-end) | |
1253 | (end-of-line) | |
1254 | (or (eobp) (forward-char)) ; include the newline char | |
1255 | (setq reg-B-end (point)) | |
1256 | ) ; save excursion | |
1257 | ||
1258 | (ediff-regions-internal | |
1259 | (get-buffer buffer-A) reg-A-beg reg-A-end | |
1260 | (get-buffer buffer-B) reg-B-beg reg-B-end | |
f1a5512a | 1261 | startup-hooks 'ediff-regions-linewise nil))) ; no word mode |
0f0b0a86 KH |
1262 | |
1263 | ;; compare region beg-A to end-A of buffer-A | |
1264 | ;; to regions beg-B -- end-B in buffer-B. | |
1265 | (defun ediff-regions-internal (buffer-A beg-A end-A buffer-B beg-B end-B | |
1266 | startup-hooks job-name word-mode) | |
1267 | (let ((tmp-buffer (get-buffer-create ediff-tmp-buffer)) | |
1268 | overl-A overl-B | |
1269 | file-A file-B) | |
1270 | ||
1271 | ;; in case beg/end-A/B aren't markers--make them into markers | |
1272 | (ediff-eval-in-buffer buffer-A | |
1273 | (setq beg-A (move-marker (make-marker) beg-A) | |
1274 | end-A (move-marker (make-marker) end-A))) | |
1275 | (ediff-eval-in-buffer buffer-B | |
1276 | (setq beg-B (move-marker (make-marker) beg-B) | |
1277 | end-B (move-marker (make-marker) end-B))) | |
1278 | ||
1279 | (if (and (eq buffer-A buffer-B) | |
1280 | (or (and (< beg-A end-B) (<= beg-B beg-A)) ; b-B b-A e-B | |
1281 | (and (< beg-B end-A) (<= end-A end-B)))) ; b-B e-A e-B | |
1282 | (progn | |
1283 | (with-output-to-temp-buffer ediff-msg-buffer | |
1284 | (princ " | |
1285 | You have requested to compare overlapping regions of the same buffer. | |
1286 | ||
1287 | In this case, Ediff's highlighting may be confusing---in the same window, | |
1288 | you may see highlighted regions that belong to different regions. | |
1289 | ||
1290 | Continue anyway? (y/n) ")) | |
1291 | ||
1292 | (if (y-or-n-p "Continue anyway? ") | |
1293 | () | |
1294 | (error "%S aborted" job-name)))) | |
1295 | ||
1296 | ;; make file-A | |
1297 | (if word-mode | |
1298 | (ediff-wordify beg-A end-A buffer-A tmp-buffer) | |
1299 | (ediff-copy-to-buffer beg-A end-A buffer-A tmp-buffer)) | |
1300 | (ediff-eval-in-buffer tmp-buffer | |
1301 | (setq file-A (ediff-make-temp-file "regA"))) | |
1302 | ||
1303 | ;; make file-B | |
1304 | (if word-mode | |
1305 | (ediff-wordify beg-B end-B buffer-B tmp-buffer) | |
1306 | (ediff-copy-to-buffer beg-B end-B buffer-B tmp-buffer)) | |
1307 | (ediff-eval-in-buffer tmp-buffer | |
1308 | (setq file-B (ediff-make-temp-file "regB"))) | |
1309 | ||
1310 | (setq overl-A (ediff-make-bullet-proof-overlay beg-A end-A buffer-A)) | |
1311 | (setq overl-B (ediff-make-bullet-proof-overlay beg-B end-B buffer-B)) | |
1312 | (ediff-setup buffer-A file-A | |
1313 | buffer-B file-B | |
1314 | nil nil ; buffer & file C | |
813f532d | 1315 | (cons (` (lambda () |
b3a26225 RS |
1316 | (delete-file (, file-A)) |
1317 | (delete-file (, file-B)))) | |
813f532d | 1318 | startup-hooks) |
0f0b0a86 KH |
1319 | (list (cons 'ediff-word-mode word-mode) |
1320 | (cons 'ediff-narrow-bounds (list overl-A overl-B)) | |
1321 | (cons 'ediff-job-name job-name)) | |
1322 | ) | |
1323 | )) | |
1324 | ||
1325 | ||
1326 | ;;; Merge files and buffers | |
1327 | ||
1328 | ;;;###autoload | |
1329 | (defalias 'ediff-merge 'ediff-merge-files) | |
1330 | ||
1331 | (defsubst ediff-merge-on-startup () | |
1332 | (ediff-do-merge 0) | |
1333 | (ediff-eval-in-buffer ediff-buffer-C | |
1334 | (set-buffer-modified-p nil))) | |
1335 | ||
1336 | ;;;###autoload | |
1337 | (defun ediff-merge-files (file-A file-B &optional startup-hooks) | |
1338 | "Merge two files without ancestor." | |
1339 | (interactive | |
1340 | (let ((dir-A (if ediff-use-last-dir | |
1341 | ediff-last-dir-A | |
1342 | default-directory)) | |
1343 | dir-B f) | |
1344 | (list (setq f (ediff-read-file-name "File A to merge" dir-A nil)) | |
1345 | (ediff-read-file-name "File B to merge" | |
1346 | (setq dir-B | |
1347 | (if ediff-use-last-dir | |
1348 | ediff-last-dir-B | |
1349 | (file-name-directory f))) | |
1350 | (progn | |
1351 | (setq file-name-history | |
1352 | (cons (abbreviate-file-name | |
1353 | (expand-file-name | |
1354 | (file-name-nondirectory f) | |
1355 | dir-B)) | |
1356 | file-name-history)) | |
1357 | f)) | |
1358 | ))) | |
1359 | (setq startup-hooks (cons 'ediff-merge-on-startup startup-hooks)) | |
1360 | (ediff-files-internal file-A | |
1361 | (if (file-directory-p file-B) | |
1362 | (expand-file-name | |
1363 | (file-name-nondirectory file-A) file-B) | |
1364 | file-B) | |
1365 | nil ; file-C | |
1366 | startup-hooks | |
1367 | 'ediff-merge-files)) | |
1368 | ||
1369 | ;;;###autoload | |
1370 | (defun ediff-merge-files-with-ancestor (file-A file-B file-ancestor | |
1371 | &optional startup-hooks) | |
1372 | "Merge two files with ancestor." | |
1373 | (interactive | |
1374 | (let ((dir-A (if ediff-use-last-dir | |
1375 | ediff-last-dir-A | |
1376 | default-directory)) | |
1377 | dir-B dir-ancestor f ff) | |
1378 | (list (setq f (ediff-read-file-name "File A to merge" dir-A nil)) | |
1379 | (setq ff (ediff-read-file-name "File B to merge" | |
1380 | (setq dir-B | |
1381 | (if ediff-use-last-dir | |
1382 | ediff-last-dir-B | |
1383 | (file-name-directory f))) | |
1384 | (progn | |
1385 | (setq file-name-history | |
1386 | (cons | |
1387 | (abbreviate-file-name | |
1388 | (expand-file-name | |
1389 | (file-name-nondirectory f) | |
1390 | dir-B)) | |
1391 | file-name-history)) | |
1392 | f))) | |
1393 | (ediff-read-file-name "Ancestor file" | |
1394 | (setq dir-ancestor | |
1395 | (if ediff-use-last-dir | |
1396 | ediff-last-dir-ancestor | |
1397 | (file-name-directory ff))) | |
1398 | (progn | |
1399 | (setq file-name-history | |
1400 | (cons (abbreviate-file-name | |
1401 | (expand-file-name | |
1402 | (file-name-nondirectory ff) | |
1403 | dir-ancestor)) | |
1404 | file-name-history)) | |
1405 | ff)) | |
1406 | ))) | |
1407 | (setq startup-hooks (cons 'ediff-merge-on-startup startup-hooks)) | |
1408 | (ediff-files-internal file-A | |
1409 | (if (file-directory-p file-B) | |
1410 | (expand-file-name | |
1411 | (file-name-nondirectory file-A) file-B) | |
1412 | file-B) | |
1413 | file-ancestor | |
1414 | startup-hooks | |
1415 | 'ediff-merge-files-with-ancestor)) | |
1416 | ||
1417 | ;;;###autoload | |
1418 | (defalias 'ediff-merge-with-ancestor 'ediff-merge-files-with-ancestor) | |
1419 | ||
1420 | ;;;###autoload | |
1421 | (defun ediff-merge-buffers (buffer-A buffer-B &optional startup-hooks job-name) | |
1422 | "Merge buffers without ancestor." | |
1423 | (interactive | |
1424 | (let (bf) | |
1425 | (list (setq bf (read-buffer "Buffer A to merge: " | |
1426 | (ediff-other-buffer "") t)) | |
1427 | (read-buffer "Buffer B to merge: " | |
1428 | (progn | |
1429 | ;; realign buffers so that two visible bufs will be | |
1430 | ;; at the top | |
1431 | (save-window-excursion (other-window 1)) | |
1432 | (ediff-other-buffer bf)) | |
1433 | t)))) | |
1434 | ||
1435 | (setq startup-hooks (cons 'ediff-merge-on-startup startup-hooks)) | |
1436 | (or job-name (setq job-name 'ediff-merge-buffers)) | |
1437 | (ediff-buffers-internal | |
1438 | buffer-A buffer-B nil startup-hooks job-name)) | |
1439 | ||
1440 | ;;;###autoload | |
1441 | (defun ediff-merge-buffers-with-ancestor (buffer-A | |
1442 | buffer-B buffer-ancestor | |
1443 | &optional startup-hooks job-name) | |
1444 | "Merge buffers with ancestor." | |
1445 | (interactive | |
1446 | (let (bf bff) | |
1447 | (list (setq bf (read-buffer "Buffer A to merge: " | |
1448 | (ediff-other-buffer "") t)) | |
1449 | (setq bff (read-buffer "Buffer B to merge: " | |
1450 | (progn | |
1451 | ;; realign buffers so that two visible | |
1452 | ;; bufs will be at the top | |
1453 | (save-window-excursion (other-window 1)) | |
1454 | (ediff-other-buffer bf)) | |
1455 | t)) | |
1456 | (read-buffer "Ancestor buffer: " | |
1457 | (progn | |
1458 | ;; realign buffers so that three visible | |
1459 | ;; bufs will be at the top | |
1460 | (save-window-excursion (other-window 1)) | |
1461 | (ediff-other-buffer (list bf bff))) | |
1462 | t) | |
1463 | ))) | |
1464 | ||
1465 | (setq startup-hooks (cons 'ediff-merge-on-startup startup-hooks)) | |
1466 | (or job-name (setq job-name 'ediff-merge-buffers-with-ancestor)) | |
1467 | (ediff-buffers-internal | |
1468 | buffer-A buffer-B buffer-ancestor startup-hooks job-name)) | |
1469 | ||
1470 | ||
1471 | ;;;###autoload | |
1472 | (defun ediff-merge-revisions (rev1 rev2 &optional startup-hooks) | |
1473 | "Run Ediff by merging two revisions of a file. | |
1474 | The file is the one visited by the current buffer." | |
1475 | (interactive | |
1476 | "sVersion 1 to merge (default is the latest version): \nsVersion 2 to merge (default is the latest version): ") | |
1477 | (ediff-load-version-control) | |
1478 | (let (buf1 buf2) | |
1479 | (if (eq ediff-version-control-package 'vc) | |
1480 | (progn | |
1481 | (save-excursion | |
1482 | (vc-version-other-window rev1) | |
1483 | (setq buf1 (current-buffer))) | |
1484 | (save-excursion | |
1485 | (vc-version-other-window rev2) | |
1486 | (setq buf2 (current-buffer))) | |
1487 | (setq startup-hooks | |
1488 | (list (` (lambda () | |
1489 | (delete-file (, (buffer-file-name buf1))) | |
1490 | (delete-file (, (buffer-file-name buf2)))))))) | |
1491 | (setq buf1 (rcs-ediff-view-revision rev1) | |
1492 | buf2 (rcs-ediff-view-revision rev2))) | |
1493 | (ediff-merge-buffers buf1 buf2 startup-hooks 'ediff-merge-revisions))) | |
1494 | ||
1495 | ||
1496 | ;;;###autoload | |
1497 | (defun ediff-merge-revisions-with-ancestor (rev1 | |
1498 | rev2 ancestor-rev | |
1499 | &optional startup-hooks) | |
1500 | "Run Ediff by merging with ancestor of two revisions of a file. | |
1501 | The file is the one visited by the current buffer." | |
1502 | (interactive | |
1503 | "sVersion 1 to merge (default: the latest version): \nsVersion 2 to merge (default: the latest version): \nsAncestor version (default: the latest version): ") | |
1504 | (ediff-load-version-control) | |
1505 | (let (buf1 buf2 ancestor-buf) | |
1506 | (if (eq ediff-version-control-package 'vc) | |
1507 | (progn | |
1508 | (save-excursion | |
1509 | (vc-version-other-window rev1) | |
1510 | (setq buf1 (current-buffer))) | |
1511 | (save-excursion | |
1512 | (vc-version-other-window rev2) | |
1513 | (setq buf2 (current-buffer))) | |
1514 | (save-excursion | |
1515 | (vc-version-other-window ancestor-rev) | |
1516 | (setq ancestor-buf (current-buffer))) | |
1517 | (setq startup-hooks | |
1518 | (list (` (lambda () | |
1519 | (delete-file (, (buffer-file-name buf1))) | |
1520 | (delete-file (, (buffer-file-name buf2))) | |
1521 | (delete-file (, (buffer-file-name ancestor-buf))) | |
1522 | ))))) | |
1523 | (setq buf1 (rcs-ediff-view-revision rev1) | |
1524 | buf2 (rcs-ediff-view-revision rev2) | |
1525 | ancestor-buf (rcs-ediff-view-revision ancestor-rev))) | |
1526 | (ediff-merge-buffers-with-ancestor | |
1527 | buf1 buf2 ancestor-buf | |
1528 | startup-hooks 'ediff-merge-revisions-with-ancestor))) | |
1529 | ||
1530 | ||
1531 | ;;; Apply patch | |
1532 | ||
1533 | ||
c8dfbe33 | 1534 | ;;;###autoload |
813f532d RS |
1535 | (defun ediff-patch-buffer (buffer-name &optional startup-hooks) |
1536 | "Run Ediff by patching BUFFER-NAME." | |
1537 | (interactive "bBuffer to patch: ") | |
1538 | ||
f1a5512a KH |
1539 | (let* ((buf-to-patch (get-buffer buffer-name)) |
1540 | (file-name-ok (if buf-to-patch (buffer-file-name buf-to-patch))) | |
1541 | (buf-mod-status (buffer-modified-p buf-to-patch)) | |
1542 | default-dir file-name ctl-buf) | |
1543 | (if file-name-ok | |
1544 | (setq file-name file-name-ok) | |
1545 | (ediff-eval-in-buffer buffer-name | |
1546 | (setq default-dir default-directory) | |
1547 | (setq file-name (ediff-make-temp-file)) | |
1548 | (set-visited-file-name file-name) | |
1549 | (setq buffer-auto-save-file-name nil) ; don't create auto-save file | |
1550 | (rename-buffer buffer-name) ; don't confuse the user with new buf name | |
1551 | (set-buffer-modified-p nil) | |
1552 | (set-visited-file-modtime) ; sync buffer and temp file | |
1553 | (setq default-directory default-dir) | |
1554 | )) | |
813f532d | 1555 | |
f1a5512a KH |
1556 | (setq ctl-buf |
1557 | (ediff-patch-file file-name startup-hooks 'ediff-patch-buffer)) | |
1558 | ||
1559 | (if file-name-ok | |
1560 | () | |
1561 | (ediff-eval-in-buffer ctl-buf | |
1562 | (delete-file (buffer-file-name ediff-buffer-A)) | |
1563 | (delete-file (buffer-file-name ediff-buffer-B)) | |
1564 | (ediff-eval-in-buffer ediff-buffer-A | |
1565 | (if default-dir (setq default-directory default-dir)) | |
1566 | (set-visited-file-name nil) | |
1567 | (rename-buffer buffer-name) | |
1568 | (set-buffer-modified-p buf-mod-status)) | |
1569 | (ediff-eval-in-buffer ediff-buffer-B | |
1570 | (setq buffer-auto-save-file-name nil) ; don't create auto-save file | |
1571 | (if default-dir (setq default-directory default-dir)) | |
1572 | (set-visited-file-name nil) | |
1573 | (rename-buffer (ediff-unique-buffer-name | |
1574 | (concat buffer-name "_patched") "")) | |
1575 | (set-buffer-modified-p t)))) | |
1576 | )) | |
0f0b0a86 KH |
1577 | |
1578 | ||
1579 | (defun ediff-get-patch-buffer (dir) | |
1580 | "Obtain patch buffer. If patch is already in a buffer---use it. | |
1581 | Else, read patch file into a new buffer." | |
1582 | (if (y-or-n-p "Is the patch file already in a buffer? ") | |
1583 | (setq ediff-patch-buf | |
1584 | (get-buffer (read-buffer "Patch buffer name: " nil t))) ;must match | |
1585 | (setq ediff-patch-buf | |
1586 | (find-file-noselect (read-file-name "Patch file name: " dir)))) | |
1587 | ||
0f0b0a86 KH |
1588 | (setq ediff-patch-diagnostics |
1589 | (get-buffer-create "*ediff patch diagnostics*")) | |
f1a5512a KH |
1590 | (ediff-eval-in-buffer ediff-patch-diagnostics |
1591 | (insert-buffer ediff-patch-buf))) | |
0f0b0a86 KH |
1592 | |
1593 | ||
813f532d RS |
1594 | |
1595 | ||
0f0b0a86 | 1596 | \f |
813f532d RS |
1597 | ;;; Versions Control functions |
1598 | ||
1599 | ;;;###autoload | |
f1a5512a | 1600 | (defun ediff-revision (arg) |
eaccd4d8 | 1601 | "Call `vc.el' or `rcs.el' depending on `ediff-version-control-package'. |
f1a5512a KH |
1602 | Without prefix argument, compares the current buffer with an older version. |
1603 | With prefix argument, compares two older versions of the current buffer." | |
1604 | (interactive "P") | |
1605 | (let (rev1 rev2) | |
1606 | (if arg | |
1607 | (setq rev1 | |
1608 | (read-string | |
1609 | "This buffer's version-1 to compare (default: the latest version): ") | |
1610 | rev2 | |
1611 | (read-string "This buffer's version-2 to compare (default: the latest version): ")) | |
1612 | (setq rev1 | |
1613 | (read-string "Version to compare the current buffer with (default: the latest version): "))) | |
1614 | (ediff-load-version-control) | |
1615 | (funcall | |
1616 | (intern (format "%S-ediff-internal" ediff-version-control-package)) | |
1617 | rev1 rev2) | |
1618 | )) | |
0f0b0a86 KH |
1619 | |
1620 | ;; Backward compatibility | |
1621 | ;;;###autoload | |
1622 | (defun vc-ediff () | |
1623 | (interactive) | |
1624 | (beep 1) | |
1625 | (with-output-to-temp-buffer ediff-msg-buffer | |
1626 | (princ " | |
1627 | You have invoked an obsolete function `vc-ediff' or `rcs-ediff'. | |
1628 | Please use `M-x ediff-revision' instead. | |
1629 | ||
1630 | Also, please check the variables `ediff-version-control-package' | |
1631 | and `ediff-revision-key' for customization."))) | |
1632 | ||
1633 | (defalias 'rcs-ediff 'vc-ediff) | |
1634 | ||
1635 | ;; Test if version control package is loaded and load if not | |
1636 | ;; Is SILENT is non-nil, don't report error if package is not found. | |
1637 | (defun ediff-load-version-control (&optional silent) | |
1638 | (or (featurep ediff-version-control-package) | |
1639 | (if (locate-library (symbol-name ediff-version-control-package)) | |
1640 | (progn | |
1641 | (message "") ; kill the message from `locate-library' | |
1642 | (require ediff-version-control-package) | |
d8e54b47 RS |
1643 | (if ediff-revision-key |
1644 | (define-key | |
1645 | (cond ((eq ediff-version-control-package 'vc) vc-prefix-map) | |
1646 | ((eq ediff-version-control-package 'rcs) global-map) | |
1647 | (t global-map)) | |
1648 | ediff-revision-key 'ediff-revision))) | |
0f0b0a86 | 1649 | (or silent |
f1a5512a | 1650 | (error "Version control package %S.el not found. Use vc.el instead" |
0f0b0a86 KH |
1651 | ediff-version-control-package))))) |
1652 | ||
eaccd4d8 | 1653 | |
f1a5512a KH |
1654 | (defun vc-ediff-internal (rev1 &optional rev2) |
1655 | "Run Ediff on versions of the current buffer. | |
1656 | If both REV1 and REV2 are given then these two versions are compared. | |
1657 | If only REV1 is given then the current buffer is compared against version REV1. | |
813f532d | 1658 | If the current buffer is named `F', the version is named `F.~REV~'. |
08020d91 | 1659 | If `F.~REV~' already exists, it is used instead of being re-created." |
f1a5512a KH |
1660 | (let ((curbuf (current-buffer)) |
1661 | (curwind (selected-window)) | |
1662 | file1 file2 | |
1663 | rev1buf rev2buf) | |
1664 | (vc-version-other-window rev1) | |
1665 | (setq rev1buf (current-buffer) | |
1666 | file1 (buffer-file-name)) | |
1667 | (select-window curwind) | |
1668 | (if (not (stringp rev2)) | |
1669 | (setq rev2buf curbuf) | |
1670 | (vc-version-other-window rev2) | |
1671 | (setq rev2buf (current-buffer) | |
1672 | file2 (buffer-file-name))) | |
1673 | (ediff-buffers | |
1674 | rev1buf rev2buf | |
1675 | (list (` (lambda () | |
1676 | (delete-file (, file1)) | |
1677 | (if (, file2) (delete-file (, file2))) | |
1678 | ))) | |
1679 | 'ediff-revision))) | |
813f532d RS |
1680 | |
1681 | (defun rcs-ediff-view-revision (&optional rev) | |
b3a26225 | 1682 | "View previous RCS revision of current file. |
813f532d RS |
1683 | With prefix argument, prompts for a revision name." |
1684 | (interactive (list (if current-prefix-arg | |
1685 | (read-string "Revision: ")))) | |
1686 | (let* ((filename (buffer-file-name (current-buffer))) | |
1687 | (switches (append '("-p") | |
1688 | (if rev (list (concat "-r" rev)) nil))) | |
1689 | (buff (concat (file-name-nondirectory filename) ".~" rev "~"))) | |
0f0b0a86 | 1690 | (message "Working ...") |
813f532d | 1691 | (setq filename (expand-file-name filename)) |
0691ced3 | 1692 | (with-output-to-temp-buffer buff |
b3a26225 | 1693 | (let ((output-buffer (ediff-rcs-get-output-buffer filename buff))) |
813f532d RS |
1694 | (delete-windows-on output-buffer) |
1695 | (save-excursion | |
1696 | (set-buffer output-buffer) | |
1697 | (apply 'call-process "co" nil t nil | |
1698 | ;; -q: quiet (no diagnostics) | |
1699 | (append switches rcs-default-co-switches | |
1700 | (list "-q" filename))))) | |
1701 | (message "") | |
1702 | buff))) | |
b3a26225 RS |
1703 | |
1704 | (defun ediff-rcs-get-output-buffer (file name) | |
1705 | ;; Get a buffer for RCS output for FILE, make it writable and clean it up. | |
1706 | ;; Optional NAME is name to use instead of `*RCS-output*'. | |
fcbadd58 | 1707 | ;; This is a modified version from rcs.el v1.1. I use it here to make |
b3a26225 | 1708 | ;; Ediff immune to changes in rcs.el |
0f0b0a86 | 1709 | (let* ((default-major-mode 'fundamental-mode) ; no frills! |
b3a26225 RS |
1710 | (buf (get-buffer-create name))) |
1711 | (save-excursion | |
1712 | (set-buffer buf) | |
1713 | (setq buffer-read-only nil | |
1714 | default-directory (file-name-directory (expand-file-name file))) | |
1715 | (erase-buffer)) | |
1716 | buf)) | |
813f532d | 1717 | |
f1a5512a | 1718 | (defun rcs-ediff-internal (rev1 &optional rev2) |
eaccd4d8 | 1719 | "Run Ediff on the current buffer, comparing it with previous RCS revision." |
f1a5512a KH |
1720 | (let ((rev2buf (if (stringp rev2) |
1721 | (rcs-ediff-view-revision rev2) | |
1722 | (current-buffer))) | |
1723 | (rev1buf (rcs-ediff-view-revision rev1))) | |
fcbadd58 | 1724 | |
0f0b0a86 KH |
1725 | ;; rcs.el doesn't create temp version files, so we don't have to delete |
1726 | ;; anything in startup hooks to ediff-buffers | |
f1a5512a | 1727 | (ediff-buffers rev1buf rev2buf nil 'ediff-revision) |
813f532d | 1728 | )) |
813f532d | 1729 | |
0f0b0a86 | 1730 | ;;; Menu bar |
eaccd4d8 | 1731 | |
0f0b0a86 KH |
1732 | ;;; This is split in several parts to avoid |
1733 | ;;; making a line in loaddefs.el that is too long for patch. | |
1734 | ;;; Note that autoload.el currently looks for cookies | |
1735 | ;;; only at top level in the file. | |
1736 | ;;; So I moved these to top level. But the conditionals on | |
1737 | ;;; purify-flag make these no-ops when you load ediff. | |
1738 | ;;; They only do something in loaddefs.el. | |
813f532d | 1739 | |
0f0b0a86 KH |
1740 | ;;;###autoload |
1741 | (if purify-flag | |
1742 | ;; explicit string-match, as ediff-xemacs-p is not defined at build time | |
1743 | (if (string-match "\\(Lucid\\|Xemacs\\)" emacs-version) | |
1744 | () | |
1745 | (defvar menu-bar-epatch-menu (make-sparse-keymap "Epatch")) | |
1746 | (fset 'menu-bar-epatch-menu (symbol-value 'menu-bar-epatch-menu)) | |
1747 | (defvar menu-bar-ediff-merge-menu (make-sparse-keymap "Ediff merge")) | |
1748 | (fset 'menu-bar-ediff-merge-menu | |
1749 | (symbol-value 'menu-bar-ediff-merge-menu)) | |
1750 | (defvar menu-bar-ediff-menu (make-sparse-keymap "Ediff")) | |
1751 | (fset 'menu-bar-ediff-menu (symbol-value 'menu-bar-ediff-menu)) | |
0f0b0a86 | 1752 | )) |
813f532d | 1753 | |
f1a5512a KH |
1754 | ;;; These must be placed in menu-bar.el in Emacs |
1755 | ;; | |
1756 | ;; (define-key menu-bar-tools-menu [epatch] | |
1757 | ;; '("Apply Patch" . menu-bar-epatch-menu)) | |
1758 | ;; (define-key menu-bar-tools-menu [ediff-merge] | |
1759 | ;; '("Merge" . menu-bar-ediff-merge-menu)) | |
1760 | ;; (define-key menu-bar-tools-menu [ediff] | |
1761 | ;; '("Compare" . menu-bar-ediff-menu)) | |
1762 | ||
813f532d | 1763 | |
0f0b0a86 KH |
1764 | ;;;###autoload |
1765 | (if purify-flag | |
1766 | ;; explicit string-match, as ediff-xemacs-p is not defined at build time | |
1767 | (if (string-match "\\(Lucid\\|Xemacs\\)" emacs-version) | |
1768 | () | |
1769 | (define-key menu-bar-ediff-menu [ediff-revision] | |
1770 | '("File with Revision ..." . ediff-revision)) | |
2ef2d897 | 1771 | (define-key menu-bar-ediff-menu [separator-ediff-files] '("--")) |
0f0b0a86 KH |
1772 | (define-key menu-bar-ediff-menu [ediff-buffers3] |
1773 | '("Three Buffers ..." . ediff-buffers3)) | |
1774 | (define-key menu-bar-ediff-menu [ediff-files3] | |
1775 | '("Three Files ..." . ediff-files3)) | |
1776 | (define-key menu-bar-ediff-menu [ediff-buffers] | |
1777 | '("Two Buffers ..." . ediff-buffers)) | |
1778 | (define-key menu-bar-ediff-menu [ediff-files] | |
1779 | '("Two Files ..." . ediff-files)) | |
1780 | )) | |
813f532d | 1781 | |
f1a5512a KH |
1782 | ;;;###autoload |
1783 | (if purify-flag | |
1784 | ;; explicit string-match, as ediff-xemacs-p is not defined at build time | |
1785 | (if (string-match "\\(Lucid\\|Xemacs\\)" emacs-version) | |
1786 | () | |
2ef2d897 | 1787 | (define-key menu-bar-ediff-menu [separator-ediff-regions] '("--")) |
f1a5512a KH |
1788 | (define-key menu-bar-ediff-menu [ediff-regions-linewise] |
1789 | '("Regions Line-by-line ..." . ediff-regions-linewise)) | |
1790 | (define-key menu-bar-ediff-menu [ediff-regions-wordwise] | |
1791 | '("Regions Word-by-word ..." . ediff-regions-wordwise)) | |
2ef2d897 | 1792 | (define-key menu-bar-ediff-menu [separator-ediff-windows] '("--")) |
f1a5512a KH |
1793 | (define-key menu-bar-ediff-menu [ediff-windows-linewise] |
1794 | '("Windows Line-by-line ..." . ediff-windows-linewise)) | |
1795 | (define-key menu-bar-ediff-menu [ediff-windows-wordwise] | |
1796 | '("Windows Word-by-word ..." . ediff-windows-wordwise)) | |
1797 | )) | |
1798 | ||
0f0b0a86 KH |
1799 | ;;;###autoload |
1800 | (if purify-flag | |
1801 | ;; explicit string-match, as ediff-xemacs-p is not defined at build time | |
1802 | (if (string-match "\\(Lucid\\|Xemacs\\)" emacs-version) | |
1803 | () | |
1804 | (define-key | |
1805 | menu-bar-ediff-merge-menu [ediff-merge-revisions-with-ancestor] | |
1806 | '("Revisions with Ancestor ..." . ediff-merge-revisions-with-ancestor)) | |
1807 | (define-key menu-bar-ediff-merge-menu [ediff-merge-revisions] | |
1808 | '("Revisions ..." . ediff-merge-revisions)) | |
2ef2d897 | 1809 | (define-key menu-bar-ediff-merge-menu [separator-ediff-merge] '("--")) |
0f0b0a86 KH |
1810 | (define-key menu-bar-ediff-merge-menu [ediff-merge-buffers-with-ancestor] |
1811 | '("Buffers with Ancestor ..." . ediff-merge-buffers-with-ancestor)) | |
1812 | (define-key menu-bar-ediff-merge-menu [ediff-merge-buffers] | |
1813 | '("Buffers ..." . ediff-merge-buffers)) | |
1814 | (define-key menu-bar-ediff-merge-menu [ediff-merge-files-with-ancestor] | |
1815 | '("Files with Ancestor ..." . ediff-merge-files-with-ancestor)) | |
1816 | (define-key menu-bar-ediff-merge-menu [ediff-merge-files] | |
1817 | '("Files ..." . ediff-merge-files)) | |
1818 | )) | |
b3a26225 | 1819 | |
0f0b0a86 KH |
1820 | ;;;###autoload |
1821 | (if purify-flag | |
1822 | ;; explicit string-match, as ediff-xemacs-p is not defined at build time | |
1823 | (if (string-match "\\(Lucid\\|Xemacs\\)" emacs-version) | |
1824 | () | |
1825 | (define-key menu-bar-epatch-menu [ediff-patch-buffer] | |
1826 | '("To a Buffer ..." . ediff-patch-buffer)) | |
1827 | (define-key menu-bar-epatch-menu [ediff-patch-file] | |
1828 | '("To a File ..." . ediff-patch-file)) | |
1829 | )) | |
813f532d | 1830 | |
813f532d | 1831 | |
0f0b0a86 KH |
1832 | ;;;###autoload |
1833 | (if purify-flag | |
1834 | ;; explicit string-match, as ediff-xemacs-p is not defined at build time | |
1835 | (if (string-match "\\(Lucid\\|Xemacs\\)" emacs-version) | |
813f532d | 1836 | (progn |
0f0b0a86 | 1837 | (defvar ediff-menu |
f1a5512a | 1838 | '("Compare" |
0f0b0a86 KH |
1839 | ["Two Files ..." ediff-files t] |
1840 | ["Two Buffers ..." ediff-buffers t] | |
1841 | ["Three Files ..." ediff-files3 t] | |
1842 | ["Three Buffers ..." ediff-buffers3 t] | |
f1a5512a KH |
1843 | "---" |
1844 | ["File with Revision ..." ediff-revision t] | |
1845 | "---" | |
1846 | ["Windows Word-by-word ..." ediff-windows-wordwise t] | |
1847 | ["Windows Line-by-line ..." ediff-windows-linewise t] | |
1848 | "---" | |
1849 | ["Regions Word-by-word ..." ediff-regions-wordwise t] | |
1850 | ["Regions Line-by-line ..." ediff-regions-linewise t])) | |
0f0b0a86 | 1851 | (defvar ediff-merge-menu |
f1a5512a | 1852 | '("Merge" |
0f0b0a86 KH |
1853 | ["Files ..." ediff-merge-files t] |
1854 | ["Files with Ancestor ..." ediff-merge-files-with-ancestor t] | |
1855 | ["Buffers ..." ediff-merge-buffers t] | |
1856 | ["Buffers with Ancestor ..." | |
1857 | ediff-merge-buffers-with-ancestor t] | |
f1a5512a | 1858 | "---" |
0f0b0a86 KH |
1859 | ["Revisions ..." ediff-merge-revisions t] |
1860 | ["Revisions with Ancestor ..." | |
1861 | ediff-merge-revisions-with-ancestor t])) | |
1862 | (defvar epatch-menu | |
f1a5512a | 1863 | '("Apply Patch" |
0f0b0a86 KH |
1864 | ["To a file ..." ediff-patch-file t] |
1865 | ["To a buffer ..." ediff-patch-buffer t])) | |
f1a5512a KH |
1866 | (add-submenu '("Tools") ediff-menu "VC") |
1867 | (add-submenu '("Tools") ediff-merge-menu "VC") | |
1868 | (add-submenu '("Tools") epatch-menu "VC") | |
0f0b0a86 | 1869 | ;; Display a solid horizontal line |
f1a5512a | 1870 | (add-menu-button '("Tools") ["---" nil nil] "VC") |
0f0b0a86 | 1871 | ))) |
b3a26225 | 1872 | |
813f532d RS |
1873 | |
1874 | (provide 'ediff) | |
0f0b0a86 | 1875 | (require 'ediff-util) |
813f532d RS |
1876 | |
1877 | ;;; ediff.el ends here |