aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Kifer1995-10-06 01:01:08 +0000
committerMichael Kifer1995-10-06 01:01:08 +0000
commit87c668b46d3e0188db77d4c814cf53fe4a7e803e (patch)
tree5049c361a26843b36dfe275edf623787051d2c36
parent6853a9373580494f1841f7761fa7b243612e0215 (diff)
downloademacs-87c668b46d3e0188db77d4c814cf53fe4a7e803e.tar.gz
emacs-87c668b46d3e0188db77d4c814cf53fe4a7e803e.zip
(ediff-files,ediff-merge-files): better file-name defaults.
(ediff-split-string): new function. (ediff-exec-process): now handles diff args separated by space. (ediff-backup-extension): new variable. Replaced -hooks with -hook. (ediff-revision-key): variable deleted. Moved menubar definitions to a new file, ediff-hook.el
-rw-r--r--lisp/ediff.el1431
1 files changed, 522 insertions, 909 deletions
diff --git a/lisp/ediff.el b/lisp/ediff.el
index bee087450ad..d0a41a33be9 100644
--- a/lisp/ediff.el
+++ b/lisp/ediff.el
@@ -5,8 +5,8 @@
5;; Created: February 2, 1994 5;; Created: February 2, 1994
6;; Keywords: comparing, merging, patching, version control. 6;; Keywords: comparing, merging, patching, version control.
7 7
8(defconst ediff-version "2.26" "The current version of Ediff") 8(defconst ediff-version "2.46" "The current version of Ediff")
9(defconst ediff-date "June 3, 1995" "Date of last update") 9(defconst ediff-date "September 28, 1995" "Date of last update")
10 10
11;; This file is part of GNU Emacs. 11;; This file is part of GNU Emacs.
12 12
@@ -39,6 +39,11 @@
39;; through them. You can also copy difference regions from one buffer to 39;; through them. You can also copy difference regions from one buffer to
40;; another (and recover old differences if you change your mind). 40;; another (and recover old differences if you change your mind).
41 41
42;; Ediff also supports merging operations on files and buffers, including
43;; merging using ancestor versions. Both comparison and merging operations can
44;; be performed on directories, i.e., by pairwise comparison of files in those
45;; directories.
46
42;; In addition, Ediff can apply a patch to a file and then let you step 47;; In addition, Ediff can apply a patch to a file and then let you step
43;; though both files, the patched and the original one, simultaneously, 48;; though both files, the patched and the original one, simultaneously,
44;; difference-by-difference. You can even apply a patch right out of a 49;; difference-by-difference. You can even apply a patch right out of a
@@ -52,23 +57,20 @@
52;; files with their older versions. Ediff can also work with remote and 57;; files with their older versions. Ediff can also work with remote and
53;; compressed files. Details are given below. 58;; compressed files. Details are given below.
54 59
55;; This package builds upon the ideas borrowed from emerge.el and 60;; Finally, Ediff supports directory-level comparison and merging operations.
56;; several Ediff's functions are adaptations from emerge.el. 61;; See the on-line manual for details.
57;; Much of the functionality of Ediff is also influenced by emerge.el.
58 62
59;; The present version of Ediff supersedes Emerge. It provides a superior 63;; This package builds upon the ideas borrowed from emerge.el and several
60;; user interface and has many features not found in Emerge. In particular, 64;; Ediff's functions are adaptations from emerge.el. Much of the functionality
61;; it can do patching and 2-way and 3-way file comparison in addition to 65;; Ediff provides is also influenced by emerge.el.
62;; merging. 66
67;; The present version of Ediff supersedes Emerge. It provides a superior user
68;; interface and has numerous major features not found in Emerge. In
69;; particular, it can do patching, and 2-way and 3-way file comparison,
70;; merging, and directory operations.
63 71
64 72
65 73
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.
71;;
72;;; Bugs: 74;;; Bugs:
73;; ----- 75;; -----
74 76
@@ -89,634 +91,25 @@
89;; hilit19.el or font-lock.el packages. If this residual highlighting gets 91;; 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 92;; 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 93;; provide commands for unhighlighting buffers. You can either place these
92;; commands in `ediff-prepare-buffer-hooks' (which will unhighlight every 94;; commands in `ediff-prepare-buffer-hook' (which will unhighlight every
93;; buffer used by Ediff) or you can execute them interactively, at any time 95;; buffer used by Ediff) or you can execute them interactively, at any time
94;; and on any buffer. 96;; and on any buffer.
95;; 97;;
96 98
97;;; Change Log:
98;; ----------
99
100;; Thu Feb 3, 1994
101
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.
137;;
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.)
155;;
156;; Cleanups in ediff-patch-file. Protected ediff-copy-diff against
157;; a bug that Emacs has in kill-region.
158;;
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.)
188;;
189;; Further fixes in the XEmacs part. Changed highlighted region in
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.
212;; Hitting `h' (ediff-toggle-hilit) on a dumb terminal will toggle
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.
241;; Made Ediff execute diff and patch using Bourne Shell, which
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
247;; slow goto-line by forward-line.
248;; Converted demarkation of difference regions
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
255;; current difference in bright colors. Improved XEmacs support.
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.
264;; Added commands `ga', `gb' to jump directly to the closest diff in
265;; buffer A and B, respectively.
266
267;; Fri April 11, 1994
268
269;; Added `ediff-update-diffs', a function that lets the user recompute
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.
293;; Added Ediff to the File menu on the menu bar (FSF's version).
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
305;; Fixed ediff-keep-window-config (thanks to Norbert Kiesel
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
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
332;; <Job.Ganzevoort@cwi.nl>).
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
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
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
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
386;; If ediff-save-buffer is invoked with `wd', it'll save the diff
387;; output in a file.
388
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.
404
405;; Thu September 1, 1994
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
412;; Thu September 8, 1994
413
414;; Added ediff-revision-key, ediff-load-version-control and streamlined
415;; vc/rcs-ediff[-internal]. Eliminated dependency on emerge.el.
416
417;; Fri September 23, 1994
418
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.
422
423;; Tue September 27, 1994
424
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.
428
429;; Fri September 30, 1994
430
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.
434
435;; Fri October 7, 1994
436
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.
449
450;; Wed October 12, 1994
451
452;; ediff-window-visible-p now makes a call to frame-visible-p
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.
465
466;; Thu October 20, 1994
467
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.
479
480;; Fri October 28, 1994
481
482;; Fixed bugs in ediff-next/previous-difference, ediff-set-visible-region
483;; Changed/added ediff-word-[1-4].
484
485;; Tue November 1, 1994
486
487;; Made ediff-revision delete the temporary version files it creates.
488
489;; Tue November 29, 1994
490
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.
495
496;; Thu December 1, 1994
497
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.
505
506;; Thu December 8, 1994
507
508;; Added ediff-toggle-wide-display. In plain display, help message is
509;; now centered correctly.
510
511;; Fri December 9, 1994
512
513;; Added ediff-toggle-multiframe.
514;; Fixed ediff-pop-diff and ediff-copy-diff, so that they will
515;; invoke auto-refining, if necessary.
516
517;; Mon December 12, 1994
518
519;; Modified ediff-toggle-wide-display so it would funcall
520;; ediff-make-wide-display-function.
521
522;; Tue December 13, 1994
523
524;; Ediff now chooses its surrogate minibuffer from frame A.
525
526;; Mon December 20, 1994
527
528;; Added ediff-keymap-setup-hooks.
529
530;; Fri December 23, 1994
531
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
608;; Added ediff-undo-selective-display (thanks to Stig <stig@hackvan.com>).
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
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
647
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.
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 99
669;;; Acknowledgements: 100;;; Acknowledgements:
670 101
671;; Special thanks to Alastair Burt <burt@dfki.uni-kl.de>, Kevin Broadey 102;; Ediff was inspired by Dale R. Worley's <drw@math.mit.edu> emerge.el.
672;; <KevinB@bartley.demon.co.uk>, Harald Boegeholz 103;; Ediff would not have been possible without the help and encouragement of
673;; <hwb@machnix.mathematik.uni-stuttgart.de>, Jin S. Choi" <jin@atype.com>, 104;; its many users. See Ediff on-line Info for the full list of those who
674;; Eric Eide <eeide@asylum.cs.utah.edu>, Kevin Esler <esler@ch.hp.com>, Robert 105;; helped. Improved defaults in Ediff file-name reading commands.
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>,
680;; Karl Heuer <kwzh@gnu.ai.mit.edu>, <irvine@lks.csi.com>,
681;; <jaffe@chipmunk.cita.utoronto.ca>, David Karr
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 106
704 107
705;;; Code: 108;;; Code:
706 109
707(require 'ediff-init) 110(require 'ediff-init)
111(require 'ediff-meta)
708 112
709(defvar ediff-version-control-package 'vc
710 "Version control package used.
711Currently, Ediff supports vc.el and rcs.el. Set this to `rcs' if you have
712rcs.el and want to use it instead of the standard vc.el.
713
714Note: both packages provide access to RCS, but only vc.el comes with Emacs
715distribution.")
716
717(defvar ediff-revision-key nil
718 "Key to which `ediff-revision' is to be bound.")
719
720(defvar ediff-use-last-dir nil 113(defvar ediff-use-last-dir nil
721 "*If t, Ediff uses previous directory as default when reading file name.") 114 "*If t, Ediff uses previous directory as default when reading file name.")
722 115
@@ -733,16 +126,22 @@ distribution.")
733 126
734;;; Patching 127;;; Patching
735 128
129(defvar ediff-backup-extension
130 (if (memq system-type '(vax-vms axp-vms emx ms-dos windows-nt windows-95))
131 "_orig" ".orig")
132 "Default backup extension for the patch program.")
133
736;;;###autoload 134;;;###autoload
737(defun ediff-patch-file (source-filename &optional startup-hooks job-name) 135(defun ediff-patch-file (source-filename &optional startup-hooks job-name)
738 "Run Ediff by patching FILE-TP-PATCH." 136 "Run Ediff by patching FILE-TP-PATCH."
739 ;; This now returns the control buffer 137 ;; This now returns the control buffer
740 (interactive 138 (interactive
741 (list (ediff-read-file-name "File to patch" 139 (list (ediff-read-file-name
742 (if ediff-use-last-dir 140 "File to patch"
743 ediff-last-dir-patch 141 (if ediff-use-last-dir
744 default-directory) 142 ediff-last-dir-patch
745 nil))) 143 default-directory)
144 (ediff-get-default-file-name))))
746 145
747 (setq source-filename (expand-file-name source-filename)) 146 (setq source-filename (expand-file-name source-filename))
748 (ediff-get-patch-buffer 147 (ediff-get-patch-buffer
@@ -753,7 +152,7 @@ distribution.")
753 152
754 (let* ((backup-extension 153 (let* ((backup-extension
755 ;; if the user specified a -b option, extract the backup 154 ;; if the user specified a -b option, extract the backup
756 ;; extension from there; else use `_orig' 155 ;; extension from there; else use ediff-backup-extension
757 (substring ediff-patch-options 156 (substring ediff-patch-options
758 (if (string-match "-b[ \t]+" ediff-patch-options) 157 (if (string-match "-b[ \t]+" ediff-patch-options)
759 (match-end 0) 0) 158 (match-end 0) 0)
@@ -768,9 +167,10 @@ distribution.")
768 (target-filename source-filename) 167 (target-filename source-filename)
769 target-buf buf-to-patch file-name-magic-p ctl-buf) 168 target-buf buf-to-patch file-name-magic-p ctl-buf)
770 169
771 ;; if the user didn't specify a backup extension, use _orig 170 ;; if the user didn't specify a backup extension, use
171 ;; ediff-backup-extension
772 (if (string= backup-extension "") 172 (if (string= backup-extension "")
773 (setq backup-extension "_orig")) 173 (setq backup-extension ediff-backup-extension))
774 174
775 ;; Make a temp file, if source-filename has a magic file handler (or if 175 ;; 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). 176 ;; it is handled via auto-mode-alist and similar magic).
@@ -792,7 +192,8 @@ distribution.")
792 (ediff-toggle-read-only buf-to-patch)) 192 (ediff-toggle-read-only buf-to-patch))
793 193
794 (ediff-eval-in-buffer ediff-patch-diagnostics 194 (ediff-eval-in-buffer ediff-patch-diagnostics
795 (message "Applying patch ... ")(sit-for 0) 195 (message "Applying patch ... ")
196 ;;(sit-for 0)
796 ;; always pass patch the -f option, so it won't ask any questions 197 ;; always pass patch the -f option, so it won't ask any questions
797 (shell-command-on-region 198 (shell-command-on-region
798 (point-min) (point-max) 199 (point-min) (point-max)
@@ -801,9 +202,9 @@ distribution.")
801 backup-extension 202 backup-extension
802 (expand-file-name true-source-filename)) 203 (expand-file-name true-source-filename))
803 t)) 204 t))
804 (message "Applying patch ... done")(sit-for 0) 205 ;;(message "Applying patch ... done")(sit-for 0)
805 (switch-to-buffer ediff-patch-diagnostics) 206 (switch-to-buffer ediff-patch-diagnostics)
806 (sit-for 0) ; synchronize 207 (sit-for 0) ; synchronize - let the user see diagnostics
807 208
808 (or (file-exists-p (concat true-source-filename backup-extension)) 209 (or (file-exists-p (concat true-source-filename backup-extension))
809 (error "Patch failed or didn't modify the original file")) 210 (error "Patch failed or didn't modify the original file"))
@@ -848,7 +249,7 @@ distribution.")
848 (setq ctl-buf 249 (setq ctl-buf
849 (ediff-buffers-internal 250 (ediff-buffers-internal
850 buf-to-patch target-buf nil 251 buf-to-patch target-buf nil
851 startup-hooks '(or job-name ediff-patch-file))) 252 startup-hooks (or job-name 'ediff-patch-file)))
852 253
853 (bury-buffer ediff-patch-diagnostics) 254 (bury-buffer ediff-patch-diagnostics)
854 (message "Patch diagnostics are available in buffer %s" 255 (message "Patch diagnostics are available in buffer %s"
@@ -860,6 +261,18 @@ distribution.")
860 (ediff-eval-in-buffer ediff-buffer-A 261 (ediff-eval-in-buffer ediff-buffer-A
861 (toggle-read-only 1))) 262 (toggle-read-only 1)))
862 263
264;; Return a plausible default for ediff's first file:
265;; In dired, return the file name under the point, unless it is a directory
266;; If the buffer has a file name, return that file name.
267(defun ediff-get-default-file-name ()
268 (cond ((eq major-mode 'dired-mode)
269 (let ((f (dired-get-filename nil 'no-error)))
270 (if (and (stringp f) (not (file-directory-p f)))
271 f)))
272 ((buffer-file-name (current-buffer))
273 (file-name-nondirectory (buffer-file-name (current-buffer))))
274 ))
275
863;;;###autoload 276;;;###autoload
864(defalias 'epatch 'ediff-patch-file) 277(defalias 'epatch 'ediff-patch-file)
865;;;###autoload 278;;;###autoload
@@ -875,7 +288,9 @@ distribution.")
875 ediff-last-dir-A 288 ediff-last-dir-A
876 default-directory)) 289 default-directory))
877 dir-B f) 290 dir-B f)
878 (list (setq f (ediff-read-file-name "File A to compare" dir-A nil)) 291 (list (setq f (ediff-read-file-name
292 "File A to compare" dir-A
293 (ediff-get-default-file-name)))
879 (ediff-read-file-name "File B to compare" 294 (ediff-read-file-name "File B to compare"
880 (setq dir-B 295 (setq dir-B
881 (if ediff-use-last-dir 296 (if ediff-use-last-dir
@@ -883,7 +298,7 @@ distribution.")
883 (file-name-directory f))) 298 (file-name-directory f)))
884 (progn 299 (progn
885 (setq file-name-history 300 (setq file-name-history
886 (cons (abbreviate-file-name 301 (cons (ediff-abbreviate-file-name
887 (expand-file-name 302 (expand-file-name
888 (file-name-nondirectory f) 303 (file-name-nondirectory f)
889 dir-B)) 304 dir-B))
@@ -907,7 +322,9 @@ distribution.")
907 ediff-last-dir-A 322 ediff-last-dir-A
908 default-directory)) 323 default-directory))
909 dir-B dir-C f ff) 324 dir-B dir-C f ff)
910 (list (setq f (ediff-read-file-name "File A to compare" dir-A nil)) 325 (list (setq f (ediff-read-file-name
326 "File A to compare" dir-A
327 (ediff-get-default-file-name)))
911 (setq ff (ediff-read-file-name "File B to compare" 328 (setq ff (ediff-read-file-name "File B to compare"
912 (setq dir-B 329 (setq dir-B
913 (if ediff-use-last-dir 330 (if ediff-use-last-dir
@@ -916,7 +333,7 @@ distribution.")
916 (progn 333 (progn
917 (setq file-name-history 334 (setq file-name-history
918 (cons 335 (cons
919 (abbreviate-file-name 336 (ediff-abbreviate-file-name
920 (expand-file-name 337 (expand-file-name
921 (file-name-nondirectory f) 338 (file-name-nondirectory f)
922 dir-B)) 339 dir-B))
@@ -928,7 +345,7 @@ distribution.")
928 (file-name-directory ff))) 345 (file-name-directory ff)))
929 (progn 346 (progn
930 (setq file-name-history 347 (setq file-name-history
931 (cons (abbreviate-file-name 348 (cons (ediff-abbreviate-file-name
932 (expand-file-name 349 (expand-file-name
933 (file-name-nondirectory ff) 350 (file-name-nondirectory ff)
934 dir-C)) 351 dir-C))
@@ -963,8 +380,10 @@ deleted."
963 (let* ((file (symbol-value file-var)) 380 (let* ((file (symbol-value file-var))
964 (file-magic (find-file-name-handler file 'find-file-noselect)) 381 (file-magic (find-file-name-handler file 'find-file-noselect))
965 (temp-file-name-prefix (file-name-nondirectory file))) 382 (temp-file-name-prefix (file-name-nondirectory file)))
966 (if (not (file-readable-p file)) 383 (cond ((not (file-readable-p file))
967 (error "File `%s' does not exist or is not readable" file)) 384 (error "File `%s' does not exist or is not readable" file))
385 ((file-directory-p file)
386 (error "File `%s' is a directory" file)))
968 387
969 ;; some of the command, below, require full file name 388 ;; some of the command, below, require full file name
970 (setq file (expand-file-name file)) 389 (setq file (expand-file-name file))
@@ -981,13 +400,17 @@ deleted."
981 (cond (file-magic ;; file has handler, such as jka-compr-handler or 400 (cond (file-magic ;; file has handler, such as jka-compr-handler or
982 ;; ange-ftp-hook-function--arrange for temp file 401 ;; ange-ftp-hook-function--arrange for temp file
983 (ediff-verify-file-buffer 'magic) 402 (ediff-verify-file-buffer 'magic)
984 (setq file (ediff-make-temp-file temp-file-name-prefix)) 403 (setq file
404 (ediff-make-temp-file
405 (current-buffer) temp-file-name-prefix))
985 (set hooks-var (cons (` (lambda () (delete-file (, file)))) 406 (set hooks-var (cons (` (lambda () (delete-file (, file))))
986 (symbol-value hooks-var)))) 407 (symbol-value hooks-var))))
987 ;; file processed via auto-mode-alist, a la uncompress.el 408 ;; file processed via auto-mode-alist, a la uncompress.el
988 ((not (equal (file-truename file) 409 ((not (equal (file-truename file)
989 (file-truename (buffer-file-name)))) 410 (file-truename (buffer-file-name))))
990 (setq file (ediff-make-temp-file temp-file-name-prefix)) 411 (setq file
412 (ediff-make-temp-file
413 (current-buffer) temp-file-name-prefix))
991 (set hooks-var (cons (` (lambda () (delete-file (, file)))) 414 (set hooks-var (cons (` (lambda () (delete-file (, file))))
992 (symbol-value hooks-var)))) 415 (symbol-value hooks-var))))
993 (t ;; plain file---just check that the file matches the buffer 416 (t ;; plain file---just check that the file matches the buffer
@@ -996,13 +419,16 @@ deleted."
996 419
997(defun ediff-files-internal (file-A file-B file-C startup-hooks job-name) 420(defun ediff-files-internal (file-A file-B file-C startup-hooks job-name)
998 (let (buf-A buf-B buf-C) 421 (let (buf-A buf-B buf-C)
999 (message "Reading file %s ... " file-A)(sit-for 0) 422 (message "Reading file %s ... " file-A)
423 ;;(sit-for 0)
1000 (ediff-find-file 'file-A 'buf-A 'ediff-last-dir-A 'startup-hooks) 424 (ediff-find-file 'file-A 'buf-A 'ediff-last-dir-A 'startup-hooks)
1001 (message "Reading file %s ... " file-B)(sit-for 0) 425 (message "Reading file %s ... " file-B)
426 ;;(sit-for 0)
1002 (ediff-find-file 'file-B 'buf-B 'ediff-last-dir-B 'startup-hooks) 427 (ediff-find-file 'file-B 'buf-B 'ediff-last-dir-B 'startup-hooks)
1003 (if (and (stringp file-C) (not ediff-merge-job)) 428 (if (stringp file-C)
1004 (progn 429 (progn
1005 (message "Reading file %s ... " file-C)(sit-for 0) 430 (message "Reading file %s ... " file-C)
431 ;;(sit-for 0)
1006 (ediff-find-file 432 (ediff-find-file
1007 'file-C 'buf-C 433 'file-C 'buf-C
1008 (if (eq job-name 'ediff-merge-files-with-ancestor) 434 (if (eq job-name 'ediff-merge-files-with-ancestor)
@@ -1088,16 +514,10 @@ deleted."
1088 (if (stringp buf-C-file-name) 514 (if (stringp buf-C-file-name)
1089 (setq buf-C-file-name (file-name-nondirectory buf-C-file-name))) 515 (setq buf-C-file-name (file-name-nondirectory buf-C-file-name)))
1090 516
1091 ;; these three need to be evaluated in their buffers, since 517 (setq file-A (ediff-make-temp-file buf-A buf-A-file-name))
1092 ;; ediff-make-temp-file checks the current buffer when assigning file 518 (setq file-B (ediff-make-temp-file buf-B buf-B-file-name))
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 519 (if buf-C-is-alive
1099 (ediff-eval-in-buffer buf-C 520 (setq file-C (ediff-make-temp-file buf-C buf-C-file-name)))
1100 (setq file-C (ediff-make-temp-file buf-C-file-name))))
1101 521
1102 (ediff-setup (get-buffer buf-A) file-A 522 (ediff-setup (get-buffer buf-A) file-A
1103 (get-buffer buf-B) file-B 523 (get-buffer buf-B) file-B
@@ -1111,7 +531,264 @@ deleted."
1111 startup-hooks) 531 startup-hooks)
1112 (list (cons 'ediff-job-name job-name)) 532 (list (cons 'ediff-job-name job-name))
1113 ))) 533 )))
1114 534
535
536;;; Directory and file group operations
537
538;; Get appropriate default name for directory:
539;; If ediff-use-last-dir, use ediff-last-dir-A.
540;; In dired mode, use the directory that is under the point (if any);
541;; otherwise, use default-directory
542(defun ediff-get-default-directory-name ()
543 (cond (ediff-use-last-dir ediff-last-dir-A)
544 ((eq major-mode 'dired-mode)
545 (let ((f (dired-get-filename nil 'noerror)))
546 (if (and (stringp f) (file-directory-p f))
547 f
548 default-directory)))
549 (t default-directory)))
550
551
552;;;###autoload
553(defun ediff-directories (dir1 dir2 regexp)
554 "Run Ediff on a pair of directories, DIR1 and DIR2, comparing files that have
555the same name in both. The third argument, REGEXP, is a regular expression that
556further filters the file names."
557 (interactive
558 (let ((dir-A (ediff-get-default-directory-name))
559 f)
560 (list (setq f (ediff-read-file-name "Directory A to compare" dir-A nil))
561 (ediff-read-file-name "Directory B to compare"
562 (if ediff-use-last-dir
563 ediff-last-dir-B
564 (ediff-strip-last-dir f))
565 nil)
566 (read-string "Filter through regular expression: "
567 nil ediff-filtering-regexp-history)
568 )))
569 (ediff-directories-internal
570 dir1 dir2 nil regexp 'ediff-files 'ediff-directories
571 ))
572
573;;;###autoload
574(defalias 'edirs 'ediff-directories)
575
576
577;;;###autoload
578(defun ediff-directory-revisions (dir1 regexp)
579 "Run Ediff on a directory, DIR1, comparing its files with their revisions.
580The second argument, REGEXP, is a regular expression that filters the file
581names. Only the files that are under revision control are taken into account."
582 (interactive
583 (let ((dir-A (ediff-get-default-directory-name)))
584 (list (ediff-read-file-name
585 "Directory to compare with revision" dir-A nil)
586 (read-string "Filter through regular expression: "
587 nil ediff-filtering-regexp-history)
588 )))
589 (ediff-directory-revisions-internal
590 dir1 regexp 'ediff-revision 'ediff-directory-revisions
591 ))
592
593;;;###autoload
594(defalias 'edir-revisions 'ediff-directory-revisions)
595
596
597;;;###autoload
598(defun ediff-directories3 (dir1 dir2 dir3 regexp)
599 "Run Ediff on three directories, DIR1, DIR2, and DIR3, comparing files that
600have the same name in all three. The last argument, REGEXP, is a regular
601expression that further filters the file names."
602 (interactive
603 (let ((dir-A (ediff-get-default-directory-name))
604 f)
605 (list (setq f (ediff-read-file-name "Directory A to compare" dir-A nil))
606 (setq f (ediff-read-file-name "Directory B to compare"
607 (if ediff-use-last-dir
608 ediff-last-dir-B
609 (ediff-strip-last-dir f))
610 nil))
611 (ediff-read-file-name "Directory C to compare"
612 (if ediff-use-last-dir
613 ediff-last-dir-C
614 (ediff-strip-last-dir f))
615 nil)
616 (read-string "Filter through regular expression: "
617 nil ediff-filtering-regexp-history)
618 )))
619 (ediff-directories-internal
620 dir1 dir2 dir3 regexp 'ediff-files3 'ediff-directories3
621 ))
622
623;;;###autoload
624(defalias 'edirs3 'ediff-directories3)
625
626;;;###autoload
627(defun ediff-merge-directories (dir1 dir2 regexp)
628 "Run Ediff on a pair of directories, DIR1 and DIR2, merging files that have
629the same name in both. The third argument, REGEXP, is a regular expression that
630further filters the file names."
631 (interactive
632 (let ((dir-A (ediff-get-default-directory-name))
633 f)
634 (list (setq f (ediff-read-file-name "Directory A to merge" dir-A nil))
635 (ediff-read-file-name "Directory B to merge"
636 (if ediff-use-last-dir
637 ediff-last-dir-B
638 (ediff-strip-last-dir f))
639 nil)
640 (read-string "Filter through regular expression: "
641 nil ediff-filtering-regexp-history)
642 )))
643 (ediff-directories-internal
644 dir1 dir2 nil regexp 'ediff-merge-files 'ediff-merge-directories
645 ))
646
647;;;###autoload
648(defalias 'edirs-merge 'ediff-merge-directories)
649
650;;;###autoload
651(defun ediff-merge-directories-with-ancestor (dir1 dir2 dir3 regexp)
652 "Run Ediff on a pair of directories, DIR1 and DIR2, merging files that have
653the same name in both. The third argument, REGEXP, is a regular expression that
654further filters the file names."
655 (interactive
656 (let ((dir-A (ediff-get-default-directory-name))
657 f)
658 (list (setq f (ediff-read-file-name "Directory A to merge" dir-A nil))
659 (setq f (ediff-read-file-name "Directory B to merge"
660 (if ediff-use-last-dir
661 ediff-last-dir-B
662 (ediff-strip-last-dir f))
663 nil))
664 (ediff-read-file-name "Ancestor directory: "
665 (if ediff-use-last-dir
666 ediff-last-dir-C
667 (ediff-strip-last-dir f))
668 nil)
669 (read-string "Filter through regular expression: "
670 nil ediff-filtering-regexp-history)
671 )))
672 (ediff-directories-internal
673 dir1 dir2 dir3 regexp
674 'ediff-merge-files-with-ancestor 'ediff-merge-directories-with-ancestor
675 ))
676
677;;;###autoload
678(defun ediff-merge-directory-revisions (dir1 regexp)
679 "Run Ediff on a directory, DIR1, merging its files with their revisions.
680The second argument, REGEXP, is a regular expression that filters the file
681names. Only the files that are under revision control are taken into account."
682 (interactive
683 (let ((dir-A (ediff-get-default-directory-name)))
684 (list (ediff-read-file-name
685 "Directory to merge with revisions" dir-A nil)
686 (read-string "Filter through regular expression: "
687 nil ediff-filtering-regexp-history)
688 )))
689 (ediff-directory-revisions-internal
690 dir1 regexp 'ediff-merge-revisions 'ediff-merge-directory-revisions
691 ))
692
693;;;###autoload
694(defalias 'edir-merge-revisions 'ediff-merge-directory-revisions)
695
696;;;###autoload
697(defun ediff-merge-directory-revisions-with-ancestor (dir1 regexp)
698 "Run Ediff on a directory, DIR1, merging its files with their revisions and ancestors.
699The second argument, REGEXP, is a regular expression that filters the file
700names. Only the files that are under revision control are taken into account."
701 (interactive
702 (let ((dir-A (ediff-get-default-directory-name)))
703 (list (ediff-read-file-name
704 "Directory to merge with revisions and ancestors" dir-A nil)
705 (read-string "Filter through regular expression: "
706 nil ediff-filtering-regexp-history)
707 )))
708 (ediff-directory-revisions-internal
709 dir1 regexp 'ediff-merge-revisions-with-ancestor
710 'ediff-merge-directory-revisions-with-ancestor
711 ))
712
713;;;###autoload
714(defalias
715 'edir-merge-revisions-with-ancestor
716 'ediff-merge-directory-revisions-with-ancestor)
717
718;;;###autoload
719(defalias 'edirs-merge-with-ancestor 'ediff-merge-directories-with-ancestor)
720
721;; Run ediff-action (ediff-files, ediff-merge, ediff-merge-with-ancestors)
722;; on a pair of directories (three directories, in case of ancestor).
723;; The third argument, REGEXP, is a regular expression that further filters the
724;; file names.
725;; JOBNAME is the symbol indicating the meta-job to be performed.
726(defun ediff-directories-internal (dir1 dir2 dir3 regexp
727 action jobname
728 &optional startup-hooks)
729 ;; ediff-read-file-name is set to attach a previously entered file name if
730 ;; the currently entered file is a directory. This code takes care of that.
731 (setq dir1 (if (file-directory-p dir1) dir1 (file-name-directory dir1))
732 dir2 (if (file-directory-p dir2) dir2 (file-name-directory dir2)))
733
734 (if (stringp dir3)
735 (setq dir3 (if (file-directory-p dir3) dir3 (file-name-directory dir3))))
736
737 (cond ((string= dir1 dir2)
738 (error "Directories A and B are the same: %s" dir1))
739 ((and (eq jobname 'ediff-directories3)
740 (string= dir1 dir3))
741 (error "Directories A and C are the same: %s" dir1))
742 ((and (eq jobname 'ediff-directories3)
743 (string= dir2 dir3))
744 (error "Directories B and C are the same: %s" dir1)))
745
746 (let (diffs ; var where ediff-intersect-directories returns the diff list
747 file-list meta-buf)
748 (setq file-list (ediff-intersect-directories
749 jobname 'diffs regexp dir1 dir2 dir3))
750 (setq startup-hooks
751 ;; this sets various vars in the meta buffer inside
752 ;; ediff-prepare-meta-buffer
753 (cons (` (lambda ()
754 ;; tell what to do if the user clicks on a session record
755 (setq ediff-session-action-function (quote (, action)))
756 ;; set ediff-dir-difference-list
757 (setq ediff-dir-difference-list (quote (, diffs)))))
758 startup-hooks))
759 (setq meta-buf (ediff-prepare-meta-buffer
760 'ediff-dir-action
761 file-list
762 "*Ediff Session Group Panel"
763 'ediff-redraw-directory-group-buffer
764 jobname
765 startup-hooks))
766 (ediff-show-meta-buffer meta-buf)
767 ))
768
769(defun ediff-directory-revisions-internal (dir1 regexp action jobname
770 &optional startup-hooks)
771 (setq dir1 (if (file-directory-p dir1) dir1 (file-name-directory dir1)))
772 (let (file-list meta-buf)
773 (setq file-list
774 (ediff-get-directory-files-under-revision jobname regexp dir1))
775 (setq startup-hooks
776 ;; this sets various vars in the meta buffer inside
777 ;; ediff-prepare-meta-buffer
778 (cons (` (lambda ()
779 ;; tell what to do if the user clicks on a session record
780 (setq ediff-session-action-function (quote (, action)))
781 ))
782 startup-hooks))
783 (setq meta-buf (ediff-prepare-meta-buffer
784 'ediff-dir-action
785 file-list
786 "*Ediff Session Group Panel"
787 'ediff-redraw-directory-group-buffer
788 jobname
789 startup-hooks))
790 (ediff-show-meta-buffer meta-buf)
791 ))
1115 792
1116 793
1117;;; Compare regions and windows 794;;; Compare regions and windows
@@ -1297,15 +974,13 @@ Continue anyway? (y/n) "))
1297 (if word-mode 974 (if word-mode
1298 (ediff-wordify beg-A end-A buffer-A tmp-buffer) 975 (ediff-wordify beg-A end-A buffer-A tmp-buffer)
1299 (ediff-copy-to-buffer beg-A end-A buffer-A tmp-buffer)) 976 (ediff-copy-to-buffer beg-A end-A buffer-A tmp-buffer))
1300 (ediff-eval-in-buffer tmp-buffer 977 (setq file-A (ediff-make-temp-file tmp-buffer "regA"))
1301 (setq file-A (ediff-make-temp-file "regA")))
1302 978
1303 ;; make file-B 979 ;; make file-B
1304 (if word-mode 980 (if word-mode
1305 (ediff-wordify beg-B end-B buffer-B tmp-buffer) 981 (ediff-wordify beg-B end-B buffer-B tmp-buffer)
1306 (ediff-copy-to-buffer beg-B end-B buffer-B tmp-buffer)) 982 (ediff-copy-to-buffer beg-B end-B buffer-B tmp-buffer))
1307 (ediff-eval-in-buffer tmp-buffer 983 (setq file-B (ediff-make-temp-file tmp-buffer "regB"))
1308 (setq file-B (ediff-make-temp-file "regB")))
1309 984
1310 (setq overl-A (ediff-make-bullet-proof-overlay beg-A end-A buffer-A)) 985 (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)) 986 (setq overl-B (ediff-make-bullet-proof-overlay beg-B end-B buffer-B))
@@ -1341,7 +1016,9 @@ Continue anyway? (y/n) "))
1341 ediff-last-dir-A 1016 ediff-last-dir-A
1342 default-directory)) 1017 default-directory))
1343 dir-B f) 1018 dir-B f)
1344 (list (setq f (ediff-read-file-name "File A to merge" dir-A nil)) 1019 (list (setq f (ediff-read-file-name
1020 "File A to merge" dir-A
1021 (ediff-get-default-file-name)))
1345 (ediff-read-file-name "File B to merge" 1022 (ediff-read-file-name "File B to merge"
1346 (setq dir-B 1023 (setq dir-B
1347 (if ediff-use-last-dir 1024 (if ediff-use-last-dir
@@ -1349,7 +1026,7 @@ Continue anyway? (y/n) "))
1349 (file-name-directory f))) 1026 (file-name-directory f)))
1350 (progn 1027 (progn
1351 (setq file-name-history 1028 (setq file-name-history
1352 (cons (abbreviate-file-name 1029 (cons (ediff-abbreviate-file-name
1353 (expand-file-name 1030 (expand-file-name
1354 (file-name-nondirectory f) 1031 (file-name-nondirectory f)
1355 dir-B)) 1032 dir-B))
@@ -1375,7 +1052,9 @@ Continue anyway? (y/n) "))
1375 ediff-last-dir-A 1052 ediff-last-dir-A
1376 default-directory)) 1053 default-directory))
1377 dir-B dir-ancestor f ff) 1054 dir-B dir-ancestor f ff)
1378 (list (setq f (ediff-read-file-name "File A to merge" dir-A nil)) 1055 (list (setq f (ediff-read-file-name
1056 "File A to merge" dir-A
1057 (ediff-get-default-file-name)))
1379 (setq ff (ediff-read-file-name "File B to merge" 1058 (setq ff (ediff-read-file-name "File B to merge"
1380 (setq dir-B 1059 (setq dir-B
1381 (if ediff-use-last-dir 1060 (if ediff-use-last-dir
@@ -1384,7 +1063,7 @@ Continue anyway? (y/n) "))
1384 (progn 1063 (progn
1385 (setq file-name-history 1064 (setq file-name-history
1386 (cons 1065 (cons
1387 (abbreviate-file-name 1066 (ediff-abbreviate-file-name
1388 (expand-file-name 1067 (expand-file-name
1389 (file-name-nondirectory f) 1068 (file-name-nondirectory f)
1390 dir-B)) 1069 dir-B))
@@ -1397,7 +1076,7 @@ Continue anyway? (y/n) "))
1397 (file-name-directory ff))) 1076 (file-name-directory ff)))
1398 (progn 1077 (progn
1399 (setq file-name-history 1078 (setq file-name-history
1400 (cons (abbreviate-file-name 1079 (cons (ediff-abbreviate-file-name
1401 (expand-file-name 1080 (expand-file-name
1402 (file-name-nondirectory ff) 1081 (file-name-nondirectory ff)
1403 dir-ancestor)) 1082 dir-ancestor))
@@ -1469,67 +1148,137 @@ Continue anyway? (y/n) "))
1469 1148
1470 1149
1471;;;###autoload 1150;;;###autoload
1472(defun ediff-merge-revisions (rev1 rev2 &optional startup-hooks) 1151(defun ediff-merge-revisions (&optional file startup-hooks)
1473 "Run Ediff by merging two revisions of a file. 1152 "Run Ediff by merging two revisions of a file.
1474The file is the one visited by the current buffer." 1153The file is the optional FILE argument or the file visited by the current
1475 (interactive 1154buffer."
1476 "sVersion 1 to merge (default is the latest version): \nsVersion 2 to merge (default is the latest version): ") 1155 (interactive)
1477 (ediff-load-version-control) 1156 (ediff-load-version-control)
1478 (let (buf1 buf2) 1157 (if (stringp file) (find-file file))
1479 (if (eq ediff-version-control-package 'vc) 1158 (let (rev1 rev2 buf1 buf2)
1480 (progn 1159 (setq rev1
1160 (read-string
1161 (format
1162 "Version 1 to merge (default: %s's latest version): "
1163 (if (stringp file)
1164 (file-name-nondirectory file) "current buffer")))
1165 rev2
1166 (read-string
1167 (format
1168 "Version 2 to merge (default: %s): "
1169 (if (stringp file)
1170 (file-name-nondirectory file) "current buffer"))))
1171 (cond ((eq ediff-version-control-package 'vc)
1481 (save-excursion 1172 (save-excursion
1482 (vc-version-other-window rev1) 1173 (vc-version-other-window rev1)
1483 (setq buf1 (current-buffer))) 1174 (setq buf1 (current-buffer)))
1484 (save-excursion 1175 (save-excursion
1485 (vc-version-other-window rev2) 1176 (or (string= rev2 "")
1177 (vc-version-other-window rev2))
1486 (setq buf2 (current-buffer))) 1178 (setq buf2 (current-buffer)))
1487 (setq startup-hooks 1179 (setq startup-hooks
1488 (list (` (lambda () 1180 (cons
1489 (delete-file (, (buffer-file-name buf1))) 1181 (` (lambda ()
1490 (delete-file (, (buffer-file-name buf2)))))))) 1182 (delete-file (, (buffer-file-name buf1)))
1491 (setq buf1 (rcs-ediff-view-revision rev1) 1183 (or (, (string= rev2 ""))
1492 buf2 (rcs-ediff-view-revision rev2))) 1184 (delete-file (, (buffer-file-name buf2))))))
1185 startup-hooks)))
1186 ((eq ediff-version-control-package 'rcs)
1187 (setq buf1 (rcs-ediff-view-revision rev1)
1188 buf2 (if (string= rev2 "")
1189 (current-buffer)
1190 (rcs-ediff-view-revision rev2))))
1191 ((eq ediff-version-control-package 'generic-sc)
1192 (save-excursion
1193 (if (string= rev1 "")
1194 (setq rev1 (generic-sc-get-latest-rev)))
1195 (sc-visit-previous-revision rev1)
1196 (setq buf1 (current-buffer)))
1197 (save-excursion
1198 (or (string= rev2 "")
1199 (sc-visit-previous-revision rev2))
1200 (setq buf2 (current-buffer))))
1201 ) ; cond
1493 (ediff-merge-buffers buf1 buf2 startup-hooks 'ediff-merge-revisions))) 1202 (ediff-merge-buffers buf1 buf2 startup-hooks 'ediff-merge-revisions)))
1494 1203
1495 1204
1496;;;###autoload 1205;;;###autoload
1497(defun ediff-merge-revisions-with-ancestor (rev1 1206(defun ediff-merge-revisions-with-ancestor (&optional file startup-hooks)
1498 rev2 ancestor-rev 1207 "Run Ediff by merging two revisions of a file with a common ancestor.
1499 &optional startup-hooks) 1208The file is the the optional FILE argument or the file visited by the current
1500 "Run Ediff by merging with ancestor of two revisions of a file. 1209buffer."
1501The file is the one visited by the current buffer." 1210 (interactive)
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) 1211 (ediff-load-version-control)
1505 (let (buf1 buf2 ancestor-buf) 1212 (if (stringp file) (find-file file))
1506 (if (eq ediff-version-control-package 'vc) 1213 (let (rev1 rev2 ancestor-rev buf1 buf2 ancestor-buf)
1507 (progn 1214 (setq rev1
1215 (read-string
1216 (format
1217 "Version 1 to merge (default: %s's latest version): "
1218 (if (stringp file)
1219 (file-name-nondirectory file) "current buffer")))
1220 rev2
1221 (read-string
1222 (format
1223 "Version 2 to merge (default: %s): "
1224 (if (stringp file)
1225 (file-name-nondirectory file) "current buffer")))
1226 ancestor-rev
1227 (read-string
1228 (format
1229 "Ancestor version (default: %s): "
1230 (if (stringp file)
1231 (file-name-nondirectory file) "current buffer"))))
1232 (cond ((eq ediff-version-control-package 'vc)
1508 (save-excursion 1233 (save-excursion
1509 (vc-version-other-window rev1) 1234 (vc-version-other-window rev1)
1510 (setq buf1 (current-buffer))) 1235 (setq buf1 (current-buffer)))
1511 (save-excursion 1236 (save-excursion
1512 (vc-version-other-window rev2) 1237 (or (string= rev2 "")
1238 (vc-version-other-window rev2))
1513 (setq buf2 (current-buffer))) 1239 (setq buf2 (current-buffer)))
1514 (save-excursion 1240 (save-excursion
1515 (vc-version-other-window ancestor-rev) 1241 (or (string= ancestor-rev "")
1242 (vc-version-other-window ancestor-rev))
1516 (setq ancestor-buf (current-buffer))) 1243 (setq ancestor-buf (current-buffer)))
1517 (setq startup-hooks 1244 (setq startup-hooks
1518 (list (` (lambda () 1245 (cons
1519 (delete-file (, (buffer-file-name buf1))) 1246 (` (lambda ()
1520 (delete-file (, (buffer-file-name buf2))) 1247 (delete-file (, (buffer-file-name buf1)))
1521 (delete-file (, (buffer-file-name ancestor-buf))) 1248 (or (, (string= rev2 ""))
1522 ))))) 1249 (delete-file (, (buffer-file-name buf2))))
1523 (setq buf1 (rcs-ediff-view-revision rev1) 1250 (or (, (string= ancestor-rev ""))
1524 buf2 (rcs-ediff-view-revision rev2) 1251 (delete-file (, (buffer-file-name ancestor-buf))))))
1525 ancestor-buf (rcs-ediff-view-revision ancestor-rev))) 1252 startup-hooks)))
1253 ((eq ediff-version-control-package 'rcs)
1254 (setq buf1 (rcs-ediff-view-revision rev1)
1255 buf2 (if (string= rev2 "")
1256 (current-buffer)
1257 (rcs-ediff-view-revision rev2))
1258 ancestor-buf (if (string= ancestor-rev "")
1259 (current-buffer)
1260 (rcs-ediff-view-revision ancestor-rev))))
1261 ((eq ediff-version-control-package 'generic-sc)
1262 (save-excursion
1263 (if (string= rev1 "")
1264 (setq rev1 (generic-sc-get-latest-rev)))
1265 (sc-visit-previous-revision rev1)
1266 (setq buf1 (current-buffer)))
1267 (save-excursion
1268 (or (string= rev2 "")
1269 (sc-visit-previous-revision rev2))
1270 (setq buf2 (current-buffer)))
1271 (save-excursion
1272 (or (string= ancestor-rev "")
1273 (sc-visit-previous-revision ancestor-rev))
1274 (setq ancestor-buf (current-buffer))))
1275 ) ; cond
1526 (ediff-merge-buffers-with-ancestor 1276 (ediff-merge-buffers-with-ancestor
1527 buf1 buf2 ancestor-buf 1277 buf1 buf2 ancestor-buf
1528 startup-hooks 'ediff-merge-revisions-with-ancestor))) 1278 startup-hooks 'ediff-merge-revisions-with-ancestor)))
1529 1279
1530 1280
1531;;; Apply patch 1281;;; Apply patch
1532
1533 1282
1534;;;###autoload 1283;;;###autoload
1535(defun ediff-patch-buffer (buffer-name &optional startup-hooks) 1284(defun ediff-patch-buffer (buffer-name &optional startup-hooks)
@@ -1544,7 +1293,7 @@ The file is the one visited by the current buffer."
1544 (setq file-name file-name-ok) 1293 (setq file-name file-name-ok)
1545 (ediff-eval-in-buffer buffer-name 1294 (ediff-eval-in-buffer buffer-name
1546 (setq default-dir default-directory) 1295 (setq default-dir default-directory)
1547 (setq file-name (ediff-make-temp-file)) 1296 (setq file-name (ediff-make-temp-file buffer-name))
1548 (set-visited-file-name file-name) 1297 (set-visited-file-name file-name)
1549 (setq buffer-auto-save-file-name nil) ; don't create auto-save file 1298 (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 1299 (rename-buffer buffer-name) ; don't confuse the user with new buf name
@@ -1597,40 +1346,30 @@ Else, read patch file into a new buffer."
1597;;; Versions Control functions 1346;;; Versions Control functions
1598 1347
1599;;;###autoload 1348;;;###autoload
1600(defun ediff-revision (arg) 1349(defun ediff-revision (&optional file startup-hooks)
1601 "Call `vc.el' or `rcs.el' depending on `ediff-version-control-package'. 1350 "Run Ediff by comparing versions of a file.
1602Without prefix argument, compares the current buffer with an older version. 1351The file is an optional FILE argument or the file visited by the current
1603With prefix argument, compares two older versions of the current buffer." 1352buffer. Use `vc.el' or `rcs.el' depending on `ediff-version-control-package'."
1353 ;; if buffer is non-nil, use that buffer instead of the current buffer
1604 (interactive "P") 1354 (interactive "P")
1355 (if (stringp file) (find-file file))
1605 (let (rev1 rev2) 1356 (let (rev1 rev2)
1606 (if arg 1357 (setq rev1
1607 (setq rev1 1358 (read-string
1608 (read-string 1359 (format "Version 1 to compare (default: %s's latest version): "
1609 "This buffer's version-1 to compare (default: the latest version): ") 1360 (if (stringp file)
1610 rev2 1361 (file-name-nondirectory file) "current buffer")))
1611 (read-string "This buffer's version-2 to compare (default: the latest version): ")) 1362 rev2
1612 (setq rev1 1363 (read-string
1613 (read-string "Version to compare the current buffer with (default: the latest version): "))) 1364 (format "Version 2 to compare (default: %s): "
1365 (if (stringp file)
1366 (file-name-nondirectory file) "current buffer"))))
1614 (ediff-load-version-control) 1367 (ediff-load-version-control)
1615 (funcall 1368 (funcall
1616 (intern (format "%S-ediff-internal" ediff-version-control-package)) 1369 (intern (format "%S-ediff-internal" ediff-version-control-package))
1617 rev1 rev2) 1370 rev1 rev2 startup-hooks)
1618 )) 1371 ))
1619 1372
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 "
1627You have invoked an obsolete function `vc-ediff' or `rcs-ediff'.
1628Please use `M-x ediff-revision' instead.
1629
1630Also, please check the variables `ediff-version-control-package'
1631and `ediff-revision-key' for customization.")))
1632
1633(defalias 'rcs-ediff 'vc-ediff)
1634 1373
1635;; Test if version control package is loaded and load if not 1374;; 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. 1375;; Is SILENT is non-nil, don't report error if package is not found.
@@ -1639,43 +1378,36 @@ and `ediff-revision-key' for customization.")))
1639 (if (locate-library (symbol-name ediff-version-control-package)) 1378 (if (locate-library (symbol-name ediff-version-control-package))
1640 (progn 1379 (progn
1641 (message "") ; kill the message from `locate-library' 1380 (message "") ; kill the message from `locate-library'
1642 (require ediff-version-control-package) 1381 (require ediff-version-control-package))
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)))
1649 (or silent 1382 (or silent
1650 (error "Version control package %S.el not found. Use vc.el instead" 1383 (error "Version control package %S.el not found. Use vc.el instead"
1651 ediff-version-control-package))))) 1384 ediff-version-control-package)))))
1652 1385
1653 1386
1654(defun vc-ediff-internal (rev1 &optional rev2) 1387(defun vc-ediff-internal (rev1 rev2 &optional startup-hooks)
1655 "Run Ediff on versions of the current buffer. 1388 "Run Ediff on versions of the current buffer.
1656If both REV1 and REV2 are given then these two versions are compared. 1389If REV2 is \"\" then compare current buffer with REV1.
1657If only REV1 is given then the current buffer is compared against version REV1.
1658If the current buffer is named `F', the version is named `F.~REV~'. 1390If the current buffer is named `F', the version is named `F.~REV~'.
1659If `F.~REV~' already exists, it is used instead of being re-created." 1391If `F.~REV~' already exists, it is used instead of being re-created."
1660 (let ((curbuf (current-buffer)) 1392 (let (file1 file2 rev1buf rev2buf)
1661 (curwind (selected-window)) 1393 (save-excursion
1662 file1 file2 1394 (vc-version-other-window rev1)
1663 rev1buf rev2buf) 1395 (setq rev1buf (current-buffer)
1664 (vc-version-other-window rev1) 1396 file1 (buffer-file-name)))
1665 (setq rev1buf (current-buffer) 1397 (save-excursion
1666 file1 (buffer-file-name)) 1398 (or (string= rev2 "") ; use current buffer
1667 (select-window curwind) 1399 (vc-version-other-window rev2))
1668 (if (not (stringp rev2))
1669 (setq rev2buf curbuf)
1670 (vc-version-other-window rev2)
1671 (setq rev2buf (current-buffer) 1400 (setq rev2buf (current-buffer)
1672 file2 (buffer-file-name))) 1401 file2 (buffer-file-name)))
1402 (setq startup-hooks
1403 (cons (` (lambda ()
1404 (delete-file (, file1))
1405 (or (, (string= rev2 "")) (delete-file (, file2)))
1406 ))
1407 startup-hooks))
1673 (ediff-buffers 1408 (ediff-buffers
1674 rev1buf rev2buf 1409 rev1buf rev2buf
1675 (list (` (lambda () 1410 startup-hooks
1676 (delete-file (, file1))
1677 (if (, file2) (delete-file (, file2)))
1678 )))
1679 'ediff-revision))) 1411 'ediff-revision)))
1680 1412
1681(defun rcs-ediff-view-revision (&optional rev) 1413(defun rcs-ediff-view-revision (&optional rev)
@@ -1715,160 +1447,41 @@ With prefix argument, prompts for a revision name."
1715 (erase-buffer)) 1447 (erase-buffer))
1716 buf)) 1448 buf))
1717 1449
1718(defun rcs-ediff-internal (rev1 &optional rev2) 1450(defun rcs-ediff-internal (rev1 rev2 &optional startup-hooks)
1719 "Run Ediff on the current buffer, comparing it with previous RCS revision." 1451 "Run Ediff on versions of the current buffer.
1720 (let ((rev2buf (if (stringp rev2) 1452If REV2 is \"\" then use current buffer."
1721 (rcs-ediff-view-revision rev2) 1453 (let ((rev2buf (if (string= rev2 "")
1722 (current-buffer))) 1454 (current-buffer)
1455 (rcs-ediff-view-revision rev2)))
1723 (rev1buf (rcs-ediff-view-revision rev1))) 1456 (rev1buf (rcs-ediff-view-revision rev1)))
1724 1457
1725 ;; rcs.el doesn't create temp version files, so we don't have to delete 1458 ;; rcs.el doesn't create temp version files, so we don't have to delete
1726 ;; anything in startup hooks to ediff-buffers 1459 ;; anything in startup hooks to ediff-buffers
1727 (ediff-buffers rev1buf rev2buf nil 'ediff-revision) 1460 (ediff-buffers rev1buf rev2buf startup-hooks 'ediff-revision)
1728 )) 1461 ))
1729 1462
1730;;; Menu bar 1463(defun generic-sc-get-latest-rev ()
1464 (cond ((eq sc-mode 'CCASE)
1465 (eval "main/LATEST"))
1466 (t (eval "")))
1467 )
1731 1468
1732;;; This is split in several parts to avoid 1469(defun generic-sc-ediff-internal (rev1 rev2 &optional startup-hooks)
1733;;; making a line in loaddefs.el that is too long for patch. 1470 "Run Ediff on versions of the current buffer.
1734;;; Note that autoload.el currently looks for cookies 1471If REV2 is \"\" then compare current buffer with REV1.
1735;;; only at top level in the file. 1472If the current buffer is named `F', the version is named `F.~REV~'.
1736;;; So I moved these to top level. But the conditionals on 1473If `F.~REV~' already exists, it is used instead of being re-created."
1737;;; purify-flag make these no-ops when you load ediff. 1474 (let (rev1buf rev2buf)
1738;;; They only do something in loaddefs.el. 1475 (save-excursion
1739 1476 (if (or (not rev1) (string= rev1 ""))
1740;;;###autoload 1477 (setq rev1 (generic-sc-get-latest-rev)))
1741(if purify-flag 1478 (sc-visit-previous-revision rev1)
1742 ;; explicit string-match, as ediff-xemacs-p is not defined at build time 1479 (setq rev1buf (current-buffer)))
1743 (if (string-match "\\(Lucid\\|Xemacs\\)" emacs-version) 1480 (save-excursion
1744 () 1481 (or (string= rev2 "") ; use current buffer
1745 (defvar menu-bar-epatch-menu (make-sparse-keymap "Epatch")) 1482 (sc-visit-previous-revision rev2))
1746 (fset 'menu-bar-epatch-menu (symbol-value 'menu-bar-epatch-menu)) 1483 (setq rev2buf (current-buffer)))
1747 (defvar menu-bar-ediff-merge-menu (make-sparse-keymap "Ediff merge")) 1484 (ediff-buffers rev1buf rev2buf startup-hooks 'ediff-revision)))
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))
1752 ))
1753
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
1763
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))
1771 (define-key menu-bar-ediff-menu [separator-ediff-files] '("--"))
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 ))
1781
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 ()
1787 (define-key menu-bar-ediff-menu [separator-ediff-regions] '("--"))
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))
1792 (define-key menu-bar-ediff-menu [separator-ediff-windows] '("--"))
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
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))
1809 (define-key menu-bar-ediff-merge-menu [separator-ediff-merge] '("--"))
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 ))
1819
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 ))
1830
1831
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)
1836 (progn
1837 (defvar ediff-menu
1838 '("Compare"
1839 ["Two Files ..." ediff-files t]
1840 ["Two Buffers ..." ediff-buffers t]
1841 ["Three Files ..." ediff-files3 t]
1842 ["Three Buffers ..." ediff-buffers3 t]
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]))
1851 (defvar ediff-merge-menu
1852 '("Merge"
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]
1858 "---"
1859 ["Revisions ..." ediff-merge-revisions t]
1860 ["Revisions with Ancestor ..."
1861 ediff-merge-revisions-with-ancestor t]))
1862 (defvar epatch-menu
1863 '("Apply Patch"
1864 ["To a file ..." ediff-patch-file t]
1865 ["To a buffer ..." ediff-patch-buffer t]))
1866 (add-submenu '("Tools") ediff-menu "VC")
1867 (add-submenu '("Tools") ediff-merge-menu "VC")
1868 (add-submenu '("Tools") epatch-menu "VC")
1869 ;; Display a solid horizontal line
1870 (add-menu-button '("Tools") ["---" nil nil] "VC")
1871 )))
1872 1485
1873 1486
1874(provide 'ediff) 1487(provide 'ediff)