aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1994-07-20 20:04:47 +0000
committerRichard M. Stallman1994-07-20 20:04:47 +0000
commitfcbadd58adee0da90604c659e8609eaa605c4aa5 (patch)
tree9b3b848a76197bf9463572c59759442b39fc6324
parent8a792f3ab26adaea3790d283a55635a1dcfe69d8 (diff)
downloademacs-fcbadd58adee0da90604c659e8609eaa605c4aa5.tar.gz
emacs-fcbadd58adee0da90604c659e8609eaa605c4aa5.zip
(Emacs 19 menu setup): Move back to top level and do it only if purify-flag.
(ediff-find-file, ediff-files-internal, ediff-patch-file): Modified to work with remote and compressed files. (ediff-read-file-name, ediff-buffers): Better defaults. (ediff-read-file-name) Handle OS/2. (ediff-forward-word-function) New function. (ediff-wordify-function): Variable deleted. (ediff-toggle-regexp-match, ediff-hide-regexp-matches): New functions. (ediff-focus-on-regexp-matches): New function. (ediff-status-info): New function. (ediff-file-names, ediff-line-numbers): Functions deleted.
-rw-r--r--lisp/ediff.el1299
1 files changed, 865 insertions, 434 deletions
diff --git a/lisp/ediff.el b/lisp/ediff.el
index 04934bb4e78..fdd86056b0e 100644
--- a/lisp/ediff.el
+++ b/lisp/ediff.el
@@ -3,11 +3,16 @@
3 3
4;; Author: Michael Kifer <kifer@cs.sunysb.edu> 4;; Author: Michael Kifer <kifer@cs.sunysb.edu>
5;; Created: February 2, 1994 5;; Created: February 2, 1994
6;; Version: 1.52 6;; Version: 1.64
7;; Keywords: tools 7;; Keywords: comparing, merging, patching, version control.
8 8
9;; This file is part of GNU Emacs. 9;; This file is part of GNU Emacs.
10 10
11;; LCD Archive Entry:
12;; ediff|Michael Kifer|kifer@cs.sunysb.edu|
13;; Visual interface to diff and patch.|
14;; 28-June-94|1.64|~/packages/ediff.el.Z|
15
11;; GNU Emacs is free software; you can redistribute it and/or modify 16;; GNU Emacs is free software; you can redistribute it and/or modify
12;; it under the terms of the GNU General Public License as published by 17;; it under the terms of the GNU General Public License as published by
13;; the Free Software Foundation; either version 2, or (at your option) 18;; the Free Software Foundation; either version 2, or (at your option)
@@ -29,7 +34,7 @@
29;; Never read those diff outputs again! 34;; Never read those diff outputs again!
30;; Apply patch selectively, like a pro! 35;; Apply patch selectively, like a pro!
31 36
32;; This package provides a convenient way of simultaneous brousing through 37;; This package provides a convenient way of simultaneous browsing through
33;; the differences between a pair of files or buffers. The two files being 38;; the differences between a pair of files or buffers. The two files being
34;; compared (file-A and file-B) are shown in separate windows (side by 39;; compared (file-A and file-B) are shown in separate windows (side by
35;; side, one above the another, or in separate frames), and the differences 40;; side, one above the another, or in separate frames), and the differences
@@ -38,7 +43,7 @@
38;; change your mind). 43;; change your mind).
39 44
40;; In addition, Ediff can apply a patch to a file and then let you step 45;; In addition, Ediff can apply a patch to a file and then let you step
41;; though both files, the patched and the original one, simultateously, 46;; though both files, the patched and the original one, simultaneously,
42;; difference-by-difference. You can even apply a patch right out of a 47;; difference-by-difference. You can even apply a patch right out of a
43;; mail buffer, i.e., patches received by mail don't even have to be saved. 48;; mail buffer, i.e., patches received by mail don't even have to be saved.
44;; Since Ediff lets you copy differences between buffers, you can, in 49;; Since Ediff lets you copy differences between buffers, you can, in
@@ -103,12 +108,12 @@
103;; the previous Ediff sessions. Different sessions may even operate on the 108;; the previous Ediff sessions. Different sessions may even operate on the
104;; same pair of files. So, in principle, it is possible to do, say, 109;; same pair of files. So, in principle, it is possible to do, say,
105;; pairwise comparison of three (or more) different files. Each session 110;; pairwise comparison of three (or more) different files. Each session
106;; would have its own *ediff-control* buffer and all the regarding a 111;; would have its own Ediff Control Panel and all the regarding a
107;; particular session is local to the associated *ediff-control* buffer. 112;; particular session is local to the associated control panel buffer.
108;; You can switch between sessions by suspending one session and then 113;; You can switch between sessions by suspending one session and then
109;; switching to another *ediff-control* buffer. (Different such buffers 114;; switching to another control panel. (Different control panel buffers
110;; are distinguished by a numerical suffix, e.g., *ediff-control*<3>.) 115;; are distinguished by a numerical suffix, e.g., Ediff Control Panel<3>.)
111;; This, if you would like to compare three files pairwise, you can do 116;; Thus, if you would like to compare three files pairwise, you can do
112;; this by preparing three different frames, each with its own control 117;; this by preparing three different frames, each with its own control
113;; window. (This would require a very wide screen, and I never claimed 118;; window. (This would require a very wide screen, and I never claimed
114;; that such 3-way comparison is very easy to do.) 119;; that such 3-way comparison is very easy to do.)
@@ -122,6 +127,33 @@
122;; flags from an Ediff buffer is to hit `h' and thus switch to highlighting 127;; flags from an Ediff buffer is to hit `h' and thus switch to highlighting
123;; with faces (unhighlighting on a dumb terminal). 128;; with faces (unhighlighting on a dumb terminal).
124 129
130;;; Remote and Compressed Files
131;; ---------------------------
132
133;; Ediff will work with remote files, compressed files, and, probably,
134;; with encrypted files. (I have only tested it with ange-ftp.el,
135;; jka-compr.el, and uncompress.el.) This means that you can compare files
136;; residing on another machine, or you can apply a patch to a file on
137;; another machine (even the patch itself can be a remote file!). This is
138;; provided that you access remote files via the usual find-file command
139;; using the syntax acceptable to ange-ftp (see Emacs Manual).
140;;
141;; The files to be compared or patched can be compressed or be both
142;; compressed and remote. To be able to handle compressed files, you
143;; should use uncompress.el or jka-compr.el. Ediff is designed so that it
144;; will interface to these packages. When patching compressed or remote
145;; files, Ediff doesn't rename the source file into source-file-name.orig
146;; (unlike what `patch' would usually do). Instead, the source file
147;; retains its name and the result of applying the patch is placed in a
148;; temporary file that has the suffix `.patched'. Generally, this applies
149;; to files that are handled using black magic, such as special file
150;; handlers (ange-ftp and some compression and encryption packages all
151;; use this method).
152;;
153;; Regular files are treated by `patch' in the usual manner, i.e., the
154;; original is renamed into source-name.orig and the result of the patch
155;; is placed into the file source-name.
156
125 157
126;;; Remarks: 158;;; Remarks:
127;; ------- 159;; -------
@@ -129,8 +161,8 @@
129;; 1. Ediff is heavily dependent on the new features of Emacs 19. 161;; 1. Ediff is heavily dependent on the new features of Emacs 19.
130;; It won't run under Emacs 18 at all. 162;; It won't run under Emacs 18 at all.
131;; 2. If running Lucid Emacs, Ediff requires at least version 19.9. 163;; 2. If running Lucid Emacs, Ediff requires at least version 19.9.
132;; 3. The function vc-ediff requires the vc.el version that comes with 164;; 3. The function vc-ediff requires the version of vc.el that comes with
133;; Emacs 19.22. 165;; Emacs 19.22 and later.
134 166
135 167
136;;; Installation and use: 168;;; Installation and use:
@@ -139,7 +171,7 @@
139;; You can invoke Ediff interactively using the following functions: 171;; You can invoke Ediff interactively using the following functions:
140;; 172;;
141;; ediff-buffers - compare buffers 173;; ediff-buffers - compare buffers
142;; ediff (alias for ediff-files) 174;; ediff - alias for ediff-files)
143;; ediff-files - compare files 175;; ediff-files - compare files
144;; ediff-patch-file - patch file then compare 176;; ediff-patch-file - patch file then compare
145;; epatch - alias for ediff-patch-file 177;; epatch - alias for ediff-patch-file
@@ -152,8 +184,6 @@
152;; is not part of the 184;; is not part of the
153;; standard Emacs distribution. 185;; standard Emacs distribution.
154;; 186;;
155;; There is also the function ediff-files-remote, which can be invoked only
156;; from within another Emacs Lisp function, i.e., non-interactively.
157;; 187;;
158;; To use Ediff, put this in your .emacs file: 188;; To use Ediff, put this in your .emacs file:
159;; 189;;
@@ -225,13 +255,59 @@
225;; ediff-quit-hooks can be used to save and then restore whatever window 255;; ediff-quit-hooks can be used to save and then restore whatever window
226;; configuration you want. However, make sure you understand what you are 256;; configuration you want. However, make sure you understand what you are
227;; doing. Many variables that drive Ediff are local to the different 257;; doing. Many variables that drive Ediff are local to the different
228;; *ediff-control* buffers. Take a look at ediff-default-suspend-hook and 258;; Ediff Control Panel buffers. Take a look at ediff-default-suspend-hook and
229;; ediff-default-quit-hook to see what's involved. 259;; ediff-default-quit-hook to see what's involved.
230;; The hooks in ediff-prepare-buffer-hooks are executed for each Ediff buffer 260;; The hooks in ediff-prepare-buffer-hooks are executed for each Ediff buffer
231;; (A and B) right after these buffers are arranged. 261;; (A and B) right after these buffers are arranged.
232;; 262;;
233;; Highlighting of difference regions 263;;
234;; ---------------------------------- 264;; Selective browsing: Control over stepping through difference regions
265;; -----------------------------------------------
266;;
267;; Sometimes it is convenient to be able to step through only some
268;; difference regions, those that satisfy certain conditions and to ignore
269;; all others. The commands `#f' and `#h' let the user specify regular
270;; expressions to control the way Ediff skips to the next or previous
271;; difference. Typing `#f' lets one specify a pair of regular expressions,
272;; regexp-A and regexp-B.
273;; Ediff will then start stepping only through those difference regions where
274;; the region in buffer A matches regexp-A and the region in buffer B
275;; matches regexp-B.
276;; Similarly, using `#h', one specifies expressions that match difference
277;; regions to be ignored while stepping through the differences. That is, if
278;; the buf A part matches regexp-A and the buf B part matches regexp B then
279;; the region will be ignored by ediff-next-difference and
280;; ediff-previous-difference commands.
281;;
282;; Hitting `#f' and `#h' toggles this feature on/off.
283;;
284;; Note that selective browsing affects only ediff-next-difference and
285;; ediff-previous-difference, i.e., the commands invoked by typing n/SPC
286;; and p/DEL. You can still jump directly (using `j' or `ga/gb') to any
287;; numbered difference. Also, it should be understood, that #f and #h do
288;; not change the position of the point in the buffers. The effect of these
289;; commands is seen only when the user types `n' or `p', i.e., when
290;; Ediff is told to jump to the next or previous difference.
291;;
292;; Users can supply their own functions that specify how Ediff should do
293;; selective browsing. To change the default Ediff function, add a function to
294;; ediff-load-hooks which will do the following assignments:
295;;
296;; (fset ediff-hide-regexp-matches 'your-hide-function)
297;; (fset ediff-focus-on-regexp-matches 'your-focus-function)
298;;
299;; Useful hints: To specify a regexp that matches everything, don't simply
300;; type RET in response to a prompt. Typing RET tells Ediff to accept the
301;; default value, which may not be what you want. Instead, one should enter
302;; something like `^' or `$' --- which would match every line.
303;;
304;; If the user doesn't remember if selective browsing is in effect and
305;; which regexps are being used, the status command, `i', will supply
306;; the requisite information.
307;;
308;;
309;; Highlighting difference regions
310;; -------------------------------
235;; The second group of Ediff variables that could be changed, if you so 311;; The second group of Ediff variables that could be changed, if you so
236;; wish, is: 312;; wish, is:
237;; 313;;
@@ -341,16 +417,16 @@
341;; 417;;
342;; ediff-fine-diff-program 418;; ediff-fine-diff-program
343;; ediff-fine-diff-options 419;; ediff-fine-diff-options
344;; ediff-wordify-function 420;; ediff-forward-word-function
345;; 421;;
346;; These variables let the user control how fine differences are computed. 422;; These variables let the user control how fine differences are computed.
347;; `ediff-fine-diff-program' is diff, by default. However, you can use 423;; `ediff-fine-diff-program' is diff, by default. However, you can use
348;; any function as long as it produces output consistent with diff. 424;; any function as long as it produces output consistent with diff.
349;; `ediff-wordify-function' is a lisp function that determines how the 425;; `ediff-forward-word-function' is a lisp function that determines how the
350;; current difference region is split into words. (Fine diferences are 426;; current difference region is split into words. (Fine diferences are
351;; computed by first splitting the current difference region into words and 427;; computed by first splitting the current difference region into words and
352;; then passing this along to `ediff-fine-diff-program'. For the default 428;; then passing this along to `ediff-fine-diff-program'. For the default
353;; wordify function, `ediff-wordify', a word is a string consisting of 429;; wordify function, `ediff-forward-word', a word is a string consisting of
354;; letters, `-', or `_', or a string consisting of symbols that are neither 430;; letters, `-', or `_', or a string consisting of symbols that are neither
355;; space, nor a letter.) 431;; space, nor a letter.)
356;; 432;;
@@ -452,17 +528,17 @@
452;; 528;;
453;; 1. file-A and file-B are in different frames (you have to put them into 529;; 1. file-A and file-B are in different frames (you have to put them into
454;; different frames manually); or 530;; different frames manually); or
455;; 2. *ediff-control* buffer is visible in one frame and one other file (A 531;; 2. Ediff Control Panel is visible in one frame and one other file (A
456;; or B) is visible in another frame. If, say, fileA is visible in a 532;; or B) is visible in another frame. If, say, fileA is visible in a
457;; different frame than *ediff-control*, fileB doesn't have to be 533;; different frame than Ediff Control Panel, fileB doesn't have to be
458;; visible. If it is, Ediff will continue displaying fileB in the frame 534;; visible. If it is, Ediff will continue displaying fileB in the frame
459;; where it was visible before. If it isn't then Ediff will arrange for 535;; where it was visible before. If it isn't then Ediff will arrange for
460;; fileB to share a frame with *ediff-control*. 536;; fileB to share a frame with Ediff Control Panel.
461;; 537;;
462;; If all three buffers are in separate frames, Ediff will switch to a 538;; If all three buffers are in separate frames, Ediff will switch to a
463;; 3-frame mode. If Ediff buffers are currently visible only in two 539;; 3-frame mode. If Ediff buffers are currently visible only in two
464;; frames, Ediff will work in a 2-frame mode. In this mode, one of the 540;; frames, Ediff will work in a 2-frame mode. In this mode, one of the
465;; frames will be shared by *ediff-control* and file-A or file-B 541;; frames will be shared by Ediff Control Panel and file-A or file-B
466;; (whichever is appropriate). 542;; (whichever is appropriate).
467 543
468 544
@@ -481,7 +557,7 @@
481;; 2. Emacs 19.xx, where xx < 23, has several bugs related to overlays and 557;; 2. Emacs 19.xx, where xx < 23, has several bugs related to overlays and
482;; faces. Somethimes, these may cause highlighting of the refinements or 558;; faces. Somethimes, these may cause highlighting of the refinements or
483;; of the unselected differences to disappear. Hitting `!' will bring them 559;; of the unselected differences to disappear. Hitting `!' will bring them
484;; back. In version 19.23, these problems no longer occur. 560;; back. In version 19.23 and later, these problems no longer occur.
485 561
486;; 3. On a monochrome display, the repertoire of faces with which to 562;; 3. On a monochrome display, the repertoire of faces with which to
487;; highlight fine differences is limited. By default, Ediff is using 563;; highlight fine differences is limited. By default, Ediff is using
@@ -713,7 +789,7 @@
713 789
714;; Sat April 16, 1994 790;; Sat April 16, 1994
715 791
716;; Added Ediff to the File menu on the menu bar (FSF's version). 792;; Added Ediff to the File menu on the menu bar (version).
717 793
718;; Mon April 18, 1994 794;; Mon April 18, 1994
719 795
@@ -742,12 +818,63 @@
742 818
743;; Fixed buglet in vc-ediff (thanks to Ray Nickson <nickson@cs.uq.oz.au>). 819;; Fixed buglet in vc-ediff (thanks to Ray Nickson <nickson@cs.uq.oz.au>).
744 820
821;; Wed May 18, 1994
822
823;; Modified ediff-read-file-name to not put long file names in the
824;; default prompt area, as suggested by KevinB@bartley.demon.co.uk.
825;; Applied patch supplied by burt@dfki.uni-kl.de, fixing a problem with
826;; ediff-diff-to-diff in Lemacs.
827
828;; Tue May 31, 1994
829
830;; Added ediff-forward-word-function (as suggested by Job Ganzevoort
831;; <Job.Ganzevoort@cwi.nl>). Modified ediff-default-quit-hook so it
832;; will clean things up in a more satisfactory way.
833
834;; Thu Jun 2, 1994
835
836;; Added `ediff-toggle-regexp-match', which allows the user to step
837;; through only those difference regions that match some regexp; or,
838;; vice versa, to skip over regions that match a regexp. (This feature
839;; was suggested by Andy Scott <ascott@pcocd2.intel.com>.)
840;; Added ediff-eval-in-buffer, which is a modified emerge-eval-in-buffer.
841;; The function ediff-status-info, bound to `i', now replaces and extends
842;; ediff-file-names and ediff-line-numbers, which were bound to `f'
843;; and `i', respectively.
844
845;; Wed Jun 8, 1994
846
847;; Made `ediff-frame-has-menubar' into a function; copied
848;; `emerge-defvar-local' and turned it into `ediff-defvar-local'
849;; This is supposed to make the same ediff.elc file work for both Emacs
850;; and Lucid Emacs, at least, if compiled under Lucid Emacs. (Thanks
851;; to Eric Eide <eeide@asylum.cs.utah.edu>.)
852
853;; Wed Jun 10, 1994
854
855;; Improved `ediff-read-file-name' and `ediff-buffers' so they are now
856;; providing more intuitive defaults. Modified `ediff-read-file-name'
857;; so it won't cause problems under OS/2.
858
859;; Fri Jun 24, 1994
860
861;; Modified ediff-find-file, ediff-files-internal, and made
862;; emerge-verify-file-buffer into ediff-verify-file-buffer so that
863;; Ediff will work correctly with remote and compressed
864;; files. (Suggested by Sandy Rutherford <sandy@ibm550.sissa.it>.)
865
866;; Fri Jun 28, 1994
867
868;; Fixed ediff-patch-files to work with remote and compressed files.
869
745 870
746;;; Acknowledgements: 871;;; Acknowledgements:
747 872
748;; Special thanks to Alastair Burt <burt@dfki.uni-kl.de>, Kevin Esler 873;; Special thanks to Alastair Burt <burt@dfki.uni-kl.de>, Kevin Esler
749;; <esler@ch.hp.com>, Kevin Broadey <KevinB@bartley.demon.co.uk>, 874;; <esler@ch.hp.com>, Kevin Broadey <KevinB@bartley.demon.co.uk>,
750;; Eric Freudenthal <freudent@jan.ultra.nyu.edu>, Job Ganzevoort 875;; Harald Boegeholz <hwb@machnix.mathematik.uni-stuttgart.de>,
876;; Robert Estes <estes@ece.ucdavis.edu>, Eric Eide <eeide@asylum.cs.utah.edu>,
877;; Eric Freudenthal <freudent@jan.ultra.nyu.edu>, Job Ganzevoort
751;; <Job.Ganzevoort@cwi.nl>, Boris Goldowsky <boris@cs.rochester.edu>, 878;; <Job.Ganzevoort@cwi.nl>, Boris Goldowsky <boris@cs.rochester.edu>,
752;; Allan Gottlieb <gottlieb@allan.ultra.nyu.edu>, Xiaoli Huang 879;; Allan Gottlieb <gottlieb@allan.ultra.nyu.edu>, Xiaoli Huang
753;; <hxl@epic.com>, irvine@lks.csi.com, jaffe@chipmunk.cita.utoronto.ca, 880;; <hxl@epic.com>, irvine@lks.csi.com, jaffe@chipmunk.cita.utoronto.ca,
@@ -755,9 +882,10 @@
755;; <norbert@i3.informatik.rwth-aachen.de>, Heinz Knutzen 882;; <norbert@i3.informatik.rwth-aachen.de>, Heinz Knutzen
756;; <hk@informatik.uni-kiel.d400.de>, Martin Maechler 883;; <hk@informatik.uni-kiel.d400.de>, Martin Maechler
757;; <maechler@stat.math.ethz.ch>, Richard Mlynarik <mly@adoc.xerox.com>, 884;; <maechler@stat.math.ethz.ch>, Richard Mlynarik <mly@adoc.xerox.com>,
758;; Ray Nickson <nickson@cs.uq.oz.au>, Andy Scott <ascott@pcocd2.intel.com>, 885;; Ray Nickson <nickson@cs.uq.oz.au>, Sandy Rutherford
759;; Richard Stanton <stanton@haas.berkeley.edu>, for contributing ideas, 886;; <sandy@ibm550.sissa.it>, Andy Scott <ascott@pcocd2.intel.com>,
760;; patches and bug reports. 887;; Richard Stanton <stanton@haas.berkeley.edu>, Peter Stout
888;; <Peter_Stout@cs.cmu.edu> for contributing ideas, patches and bug reports.
761;; 889;;
762;; Thanks also to many others who felt obliged to drop a thanks note. 890;; Thanks also to many others who felt obliged to drop a thanks note.
763 891
@@ -814,11 +942,36 @@
814(defmacro ediff-get-fine-diff-vector (n) 942(defmacro ediff-get-fine-diff-vector (n)
815 (` (ediff-get-fine-diff-vector-from-vec (ediff-get-difference (, n))))) 943 (` (ediff-get-fine-diff-vector-from-vec (ediff-get-difference (, n)))))
816 944
817(defmacro ediff-frame-has-menubar () 945(defmacro ediff-defvar-local (var value doc)
818 (if (ediff-if-lucid) 946 "Defines SYMBOL as an advertised local variable.
819 current-menubar 947Performs a defvar, then executes `make-variable-buffer-local' on
820 (< 0 (cdr (assq 'menu-bar-lines (frame-parameters (selected-frame))))) 948the variable. Also sets the `preserved' (Emacs) or `permanent-local' (Lucid)
821 )) 949property, so that `kill-all-local-variables' (called by major-mode setting
950commands) won't destroy Ediff control variables.
951
952This is a merge of `emerge-defvar-local' for Emacs and Lucid Emacs. It is
953needed to make the same ediff.elc work under both Emacsen."
954 (` (progn
955 (defvar (, var) (, value) (, doc))
956 (make-variable-buffer-local '(, var))
957 (put '(, var)
958 (if (ediff-if-lucid) 'permanent-local 'preserved)
959 t))))
960
961(defmacro ediff-eval-in-buffer (buffer &rest forms)
962 "Macro to switch to BUFFER, evaluate FORMS, returns to original buffer.
963Differs from `save-excursion' in that it doesn't save the point and mark.
964This is essentially `emerge-eval-in-buffer' with the test for live buffers."
965 (` (let ((StartBuffer (current-buffer)))
966 (if (ediff-buffer-live-p (, buffer))
967 (unwind-protect
968 (progn
969 (set-buffer (, buffer))
970 (,@ forms))
971 (set-buffer StartBuffer))
972 (beep 1)
973 (message "You seem to have killed an essential Ediff buffer---quit!"))
974 )))
822 975
823 976
824;;; Functions 977;;; Functions
@@ -835,8 +988,6 @@ It is entered only through one of the following commands:
835 `epatch-buffer' 988 `epatch-buffer'
836 `vc-ediff' 989 `vc-ediff'
837 `rcs-ediff' 990 `rcs-ediff'
838or through a non-interactive Emacs Lisp function
839 `ediff-files-remote'
840 991
841Commands: 992Commands:
842\\{ediff-mode-map}" 993\\{ediff-mode-map}"
@@ -845,8 +996,10 @@ Commands:
845 (setq major-mode 'ediff-mode) 996 (setq major-mode 'ediff-mode)
846 (setq mode-name "Ediff")) 997 (setq mode-name "Ediff"))
847 998
848(defvar ediff-version "1.52" 999(defvar ediff-version "1.64"
849 "The current version of Ediff.") 1000 "The current version of Ediff.")
1001(defvar ediff-date "June 28, 1994"
1002 "Date of last update.")
850 1003
851(defun ediff-version () 1004(defun ediff-version ()
852 "Return string describing the version of Ediff. 1005 "Return string describing the version of Ediff.
@@ -885,11 +1038,12 @@ on ediff-quit or ediff-suspend.")
885;; Help messages 1038;; Help messages
886 1039
887(defconst ediff-help-message-long 1040(defconst ediff-help-message-long
888 "p,DEL - prev diff v/V - scroll up/dn * - refine diff ! - recomp diffs 1041 "p,DEL - prev diff v/V - scroll up/dn ab - diff A to B * - refine diff
889n,SPC - next diff </> - scroll lt/rt ab - diff A to B l - line numbers 1042n,SPC - next diff </> - scroll lt/rt ba - diff B to A ! - recomp diffs
890 j - jump to diff s - toggle split ba - diff B to A f - file names 1043 j - jump to diff s - toggle split ra - restore A i - status info
891ga/gb - goto pt in A/B h - toggle hilit ra - restore A z - suspend Ediff 1044ga/gb - goto pt in A/B h - toggle hilit rb - restore B z - suspend Ediff
892 c - recenter @ - toggle refine rb - restore B q - quit Ediff 1045 c - recenter @ - toggle refine q - quit Ediff
1046 #f/#h - toggle focus/hide diff regions
893wa/wb - save buf A/B A/B - toggle read-only in buffers A/B ? - toggle help") 1047wa/wb - save buf A/B A/B - toggle read-only in buffers A/B ? - toggle help")
894 1048
895(defconst ediff-help-message-short 1049(defconst ediff-help-message-short
@@ -902,11 +1056,14 @@ wa/wb - save buf A/B A/B - toggle read-only in buffers A/B ? - toggle help")
902(defvar ediff-diff-program "diff" 1056(defvar ediff-diff-program "diff"
903 "*Name of the program that compares two files.") 1057 "*Name of the program that compares two files.")
904(defvar ediff-diff-options "" 1058(defvar ediff-diff-options ""
905 "*Options to pass to `ediff-diff-program'.") 1059 "*Options to pass to `ediff-diff-program'.
1060If diff\(1\) is used as `ediff-diff-program', then the most useful options are
1061`-w', to ignore space, and `-i', to ignore case of letters.")
906 1062
907;; Find diff stuff. 1063;; Fine differences
908(defvar ediff-wordify-function 'ediff-wordify 1064(defvar ediff-forward-word-function 'ediff-forward-word
909 "*Function to call to split current diff region into separate words.") 1065 "*Function to call to move to the next word.
1066Used for splitting difference regions into individual words.")
910 1067
911(defvar ediff-fine-diff-program "diff" 1068(defvar ediff-fine-diff-program "diff"
912 "*Name of the program that compares the current diff regions for fine differences. 1069 "*Name of the program that compares the current diff regions for fine differences.
@@ -915,9 +1072,11 @@ This program should produce output in the format of diff. One could
915possibly use `spiff' here if appropriate options are set.") 1072possibly use `spiff' here if appropriate options are set.")
916 1073
917(defvar ediff-fine-diff-options "" 1074(defvar ediff-fine-diff-options ""
918 "*Options to pass to `ediff-fine-diff-program'.") 1075 "*Options to pass to `ediff-fine-diff-program'.
1076If diff\(1\) is used as `ediff-diff-program', then the most useful options are
1077`-w', to ignore space, and `-i', to ignore case of letters.")
919 1078
920(defvar ediff-whitespace " \n\t\j" 1079(defvar ediff-whitespace " \n\t\C-j"
921 "*White space. Used to split strings into words.") 1080 "*White space. Used to split strings into words.")
922 1081
923(defvar ediff-word-1 "a-zA-Z---_`'.?!:" 1082(defvar ediff-word-1 "a-zA-Z---_`'.?!:"
@@ -928,9 +1087,24 @@ used to determine fine differences between regions. There are two types of
928words. One consists entirely out of characters in `ediff-word-1' and 1087words. One consists entirely out of characters in `ediff-word-1' and
929another out of characters matching `ediff-word-1'.") 1088another out of characters matching `ediff-word-1'.")
930 1089
931(defvar ediff-word-2 "^a-zA-Z---_`'.?!: \t\n\j" 1090(defvar ediff-word-2 "^a-zA-Z---_`'.?!: \t\n\C-j"
932 "*Characters matching this regexp constitute words of type 2. 1091 "*Characters matching this regexp constitute words of type 2.
933See `ediff-word-1' for more details.") 1092See `ediff-word-1' for more details.")
1093
1094;; Selective browsing
1095
1096(defconst ediff-skip-diff-region-function 'ediff-show-all-diffs
1097 "Function that determines the next/previous diff region to show.")
1098
1099(defconst ediff-regexp-focus-A ""
1100 "Regexp that determines buf A regions to focus on when skipping to diff.")
1101(defconst ediff-regexp-focus-B ""
1102 "Regexp that determines buf B regions to focus on when skipping to diff.")
1103
1104(defconst ediff-regexp-hide-A ""
1105 "Regexp that determines buf A regions to ignore when skipping to diff.")
1106(defconst ediff-regexp-hide-B ""
1107 "Regexp that determines buf B regions to ignore when skipping to diff.")
934 1108
935 1109
936;; Support for patches 1110;; Support for patches
@@ -974,7 +1148,7 @@ Lines that do not match are assumed to be error messages.")
974 1148
975;; Copying diffs betw buffers. 1149;; Copying diffs betw buffers.
976 1150
977(emerge-defvar-local ediff-killed-diffs-alist nil 1151(ediff-defvar-local ediff-killed-diffs-alist nil
978 "A list of killed diffs. 1152 "A list of killed diffs.
979A diff is saved here if it is replaced by a diff 1153A diff is saved here if it is replaced by a diff
980from another buffer. This alist has the form: 1154from another buffer. This alist has the form:
@@ -999,29 +1173,29 @@ Must end with newline. Must be set before Ediff is loaded.")
999(defvar ediff-after-flag-mol "<<<---<<" 1173(defvar ediff-after-flag-mol "<<<---<<"
1000 "*Like ediff-after-flag, used when a difference starts in mid-line.") 1174 "*Like ediff-after-flag, used when a difference starts in mid-line.")
1001 1175
1002(emerge-defvar-local ediff-before-flag-A nil 1176(ediff-defvar-local ediff-before-flag-A nil
1003 "This is the actual ASCII before-flag in effect in buffer A. 1177 "This is the actual ASCII before-flag in effect in buffer A.
1004It is either `ediff-before-flag-mol' or `ediff-before-flag-bol' depending 1178It is either `ediff-before-flag-mol' or `ediff-before-flag-bol' depending
1005on whether the selected difference region starts in the middle of a line 1179on whether the selected difference region starts in the middle of a line
1006or at the beginning of a line.") 1180or at the beginning of a line.")
1007(emerge-defvar-local ediff-after-flag-A nil 1181(ediff-defvar-local ediff-after-flag-A nil
1008 "This is the actual ASCII after-flag in effect in buffer A. 1182 "This is the actual ASCII after-flag in effect in buffer A.
1009It is either `ediff-before-flag-mol' or `ediff-before-flag-bol' depending 1183It is either `ediff-before-flag-mol' or `ediff-before-flag-bol' depending
1010on whether the selected difference region starts in the middle of a line 1184on whether the selected difference region starts in the middle of a line
1011or at the beginning of a line.") 1185or at the beginning of a line.")
1012(emerge-defvar-local ediff-before-flag-B nil 1186(ediff-defvar-local ediff-before-flag-B nil
1013 "This is the actual ASCII before-flag in effect in buffer B. 1187 "This is the actual ASCII before-flag in effect in buffer B.
1014It is either `ediff-before-flag-mol' or `ediff-before-flag-bol' depending 1188It is either `ediff-before-flag-mol' or `ediff-before-flag-bol' depending
1015on whether the selected difference region starts in the middle of a line 1189on whether the selected difference region starts in the middle of a line
1016or at the beginning of a line.") 1190or at the beginning of a line.")
1017(emerge-defvar-local ediff-after-flag-B nil 1191(ediff-defvar-local ediff-after-flag-B nil
1018 "This is the actual ASCII after-flag in effect in buffer B. 1192 "This is the actual ASCII after-flag in effect in buffer B.
1019It is either `ediff-before-flag-mol' or `ediff-before-flag-bol' depending 1193It is either `ediff-before-flag-mol' or `ediff-before-flag-bol' depending
1020on whether the selected difference region starts in the middle of a line 1194on whether the selected difference region starts in the middle of a line
1021or at the beginning of a line.") 1195or at the beginning of a line.")
1022 1196
1023 1197
1024(emerge-defvar-local ediff-want-faces t 1198(ediff-defvar-local ediff-want-faces t
1025 "If t, differences are highlighted using faces on a window system. 1199 "If t, differences are highlighted using faces on a window system.
1026If nil, they are highlighted using ASCII flags, ediff-before-flag 1200If nil, they are highlighted using ASCII flags, ediff-before-flag
1027and ediff-after-flag. On a non-window system, differences are always 1201and ediff-after-flag. On a non-window system, differences are always
@@ -1030,13 +1204,13 @@ highlighted using ASCII flags.
1030This variable can be set either in .emacs or toggled interactively, using 1204This variable can be set either in .emacs or toggled interactively, using
1031ediff-toggle-hilit.") 1205ediff-toggle-hilit.")
1032 1206
1033(emerge-defvar-local ediff-want-default-menus t 1207(ediff-defvar-local ediff-want-default-menus t
1034 "If t, Ediff will set up menus in the menu bar. 1208 "If t, Ediff will set up menus in the menu bar.
1035This variable must be set before Ediff is loaded. If you don't like the 1209This variable must be set before Ediff is loaded. If you don't like the
1036look of the default menus, set this variable to nil and make your own 1210look of the default menus, set this variable to nil and make your own
1037menus.") 1211menus.")
1038 1212
1039(emerge-defvar-local ediff-auto-refine 'on 1213(ediff-defvar-local ediff-auto-refine 'on
1040 "If `'on', Ediff auto-highlights fine diffs for the current diff region. 1214 "If `'on', Ediff auto-highlights fine diffs for the current diff region.
1041If `off', auto-highlighting is not used. If `'nix', no fine diffs are shown 1215If `off', auto-highlighting is not used. If `'nix', no fine diffs are shown
1042at all, unless the user force-refines the region by hitting `*'. 1216at all, unless the user force-refines the region by hitting `*'.
@@ -1044,16 +1218,16 @@ at all, unless the user force-refines the region by hitting `*'.
1044This variable can be set either in .emacs or toggled interactively, using 1218This variable can be set either in .emacs or toggled interactively, using
1045ediff-toggle-hilit.") 1219ediff-toggle-hilit.")
1046 1220
1047(emerge-defvar-local ediff-auto-refine-limit 700 1221(ediff-defvar-local ediff-auto-refine-limit 700
1048 "Auto-refine only those regions that are smaller than this number of bytes.") 1222 "Auto-refine only those regions that are smaller than this number of bytes.")
1049 1223
1050(emerge-defvar-local ediff-highlight-all-diffs t 1224(ediff-defvar-local ediff-highlight-all-diffs t
1051 "If nil, only the selected differences are highlighted. 1225 "If nil, only the selected differences are highlighted.
1052This variable can be set either in .emacs or toggled interactively, using 1226This variable can be set either in .emacs or toggled interactively, using
1053ediff-toggle-hilit.") 1227ediff-toggle-hilit.")
1054 1228
1055(emerge-defvar-local ediff-highlighting-style nil 1229(ediff-defvar-local ediff-highlighting-style nil
1056 "A var local to each ediff-control buffer. 1230 "A var local to each control panel buffer.
1057Indicates highlighting style in effect for this buffer: `face', `ascii', 1231Indicates highlighting style in effect for this buffer: `face', `ascii',
1058nil -- temporarily unhighlighted, `off' -- turned off \(on a dumb 1232nil -- temporarily unhighlighted, `off' -- turned off \(on a dumb
1059terminal only\).") 1233terminal only\).")
@@ -1064,55 +1238,55 @@ terminal only\).")
1064;; control buffer. 1238;; control buffer.
1065 1239
1066;; Mode variables 1240;; Mode variables
1067(emerge-defvar-local ediff-A-buffer nil 1241(ediff-defvar-local ediff-A-buffer nil
1068 "The buffer in which the A variant is stored.") 1242 "The buffer in which the A variant is stored.")
1069(emerge-defvar-local ediff-B-buffer nil 1243(ediff-defvar-local ediff-B-buffer nil
1070 "The buffer in which the B variant is stored.") 1244 "The buffer in which the B variant is stored.")
1071(emerge-defvar-local ediff-control-buffer nil 1245(ediff-defvar-local ediff-control-buffer nil
1072 "The control buffer of ediff. ") 1246 "The control buffer of ediff. ")
1073 1247
1074;(emerge-defvar-local ediff-control-buffer-suffix nil 1248;(ediff-defvar-local ediff-control-buffer-suffix nil
1075; "The suffix of the control buffer name. ") 1249; "The suffix of the control buffer name. ")
1076 1250
1077(emerge-defvar-local ediff-control-window nil 1251(ediff-defvar-local ediff-control-window nil
1078 "The control window.") 1252 "The control window.")
1079(emerge-defvar-local ediff-window-config-saved "" 1253(ediff-defvar-local ediff-window-config-saved ""
1080 "Ediff's window configuration. 1254 "Ediff's window configuration.
1081Used to minimize the need to rearrange windows.") 1255Used to minimize the need to rearrange windows.")
1082 1256
1083 1257
1084(emerge-defvar-local ediff-A-buffer-values nil 1258(ediff-defvar-local ediff-A-buffer-values nil
1085 "Keeps working values of ediff-saved-variables for ediff-A-buffer.") 1259 "Keeps working values of ediff-saved-variables for ediff-A-buffer.")
1086(emerge-defvar-local ediff-B-buffer-values nil 1260(ediff-defvar-local ediff-B-buffer-values nil
1087 "Keeps working values of ediff-saved-variables for ediff-B-buffer.") 1261 "Keeps working values of ediff-saved-variables for ediff-B-buffer.")
1088 1262
1089(emerge-defvar-local ediff-A-buffer-values-setup nil 1263(ediff-defvar-local ediff-A-buffer-values-setup nil
1090 "Remembers ediff-saved-variables for ediff-A-buffer as they were at setup.") 1264 "Remembers ediff-saved-variables for ediff-A-buffer as they were at setup.")
1091(emerge-defvar-local ediff-B-buffer-values-setup nil 1265(ediff-defvar-local ediff-B-buffer-values-setup nil
1092 "Remembers ediff-saved-variables for ediff-B-buffer as they were at setup.") 1266 "Remembers ediff-saved-variables for ediff-B-buffer as they were at setup.")
1093 1267
1094(emerge-defvar-local ediff-difference-vector nil 1268(ediff-defvar-local ediff-difference-vector nil
1095 "Vector of differences between the variants. 1269 "Vector of differences between the variants.
1096Each difference is represented by a vector of two overlays. The first 1270Each difference is represented by a vector of two overlays. The first
1097overlays the difference section in the A buffer and the second overlays the 1271overlays the difference section in the A buffer and the second overlays the
1098diff in the B buffer. If a difference section is empty, the corresponding 1272diff in the B buffer. If a difference section is empty, the corresponding
1099overlay's endpoints coincide. ") 1273overlay's endpoints coincide. ")
1100 1274
1101(emerge-defvar-local ediff-current-difference -1 1275(ediff-defvar-local ediff-current-difference -1
1102 "The difference that is currently selected.") 1276 "The difference that is currently selected.")
1103(emerge-defvar-local ediff-number-of-differences nil 1277(ediff-defvar-local ediff-number-of-differences nil
1104 "Number of differences found.") 1278 "Number of differences found.")
1105 1279
1106(emerge-defvar-local ediff-diff-buffer nil 1280(ediff-defvar-local ediff-diff-buffer nil
1107 "Buffer containing the output of diff, which is used by Ediff to step 1281 "Buffer containing the output of diff, which is used by Ediff to step
1108through files.") 1282through files.")
1109(emerge-defvar-local ediff-tmp-buffer nil 1283(ediff-defvar-local ediff-tmp-buffer nil
1110 "Temporary buffer used for computing fine differences.") 1284 "Temporary buffer used for computing fine differences.")
1111(emerge-defvar-local ediff-error-buffer nil 1285(ediff-defvar-local ediff-error-buffer nil
1112 "Buffer containing the output of diff when diff returns errors.") 1286 "Buffer containing the output of diff when diff returns errors.")
1113 1287
1114(emerge-defvar-local ediff-this-buffer-control-sessions nil 1288(ediff-defvar-local ediff-this-buffer-control-sessions nil
1115 "List of ediff-control buffers associated with each buffer A/B.") 1289 "List of ediff control panels associated with each buffer A/B.")
1116 1290
1117(defvar ediff-disturbed-overlays nil 1291(defvar ediff-disturbed-overlays nil
1118 "List of difference overlays disturbed by working with the current diff.") 1292 "List of difference overlays disturbed by working with the current diff.")
@@ -1351,9 +1525,9 @@ through files.")
1351 1525
1352 ;;; Overlays 1526 ;;; Overlays
1353 1527
1354 (emerge-defvar-local ediff-current-diff-overlay-A nil 1528 (ediff-defvar-local ediff-current-diff-overlay-A nil
1355 "Overlay in buffer A.") 1529 "Overlay in buffer A.")
1356 (emerge-defvar-local ediff-current-diff-overlay-B nil 1530 (ediff-defvar-local ediff-current-diff-overlay-B nil
1357 "Overlay in buffer B.") 1531 "Overlay in buffer B.")
1358 1532
1359 (defun ediff-make-current-diff-overlay (type) 1533 (defun ediff-make-current-diff-overlay (type)
@@ -1375,7 +1549,7 @@ through files.")
1375 ovr-list) 1549 ovr-list)
1376 (if (ediff-if-lucid) 1550 (if (ediff-if-lucid)
1377 (+ 2 mouse-highlight-priority) 1551 (+ 2 mouse-highlight-priority)
1378 (emerge-eval-in-buffer 1552 (ediff-eval-in-buffer
1379 buffer 1553 buffer
1380 (while (< pos (min (point-max) (1+ end))) 1554 (while (< pos (min (point-max) (1+ end)))
1381 (setq ovr-list (append (overlays-at pos) ovr-list)) 1555 (setq ovr-list (append (overlays-at pos) ovr-list))
@@ -1418,11 +1592,13 @@ these buffers.")
1418 "*If t, Ediff uses previous directory as default when reading file name.") 1592 "*If t, Ediff uses previous directory as default when reading file name.")
1419 1593
1420(defvar ediff-no-help-in-control-buffer nil 1594(defvar ediff-no-help-in-control-buffer nil
1421 "*Non-nil mean C-h should not invoke Emacs help. 1595 "*Non-nil means C-h should not invoke Emacs help in control buffer.
1422Instead, C-h jumps to previous difference.") 1596Instead, C-h jumps to previous difference.")
1423 1597
1424(defvar ediff-temp-file-prefix 1598(defvar ediff-temp-file-prefix
1425 (let ((env (getenv "TMPDIR")) 1599 (let ((env (or (getenv "TMPDIR")
1600 (getenv "TMP")
1601 (getenv "TEMP")))
1426 d) 1602 d)
1427 (setq d (if (and env (> (length env) 0)) 1603 (setq d (if (and env (> (length env) 0))
1428 env 1604 env
@@ -1436,72 +1612,84 @@ Do not start with `~/' or `~user-name/'.")
1436(defvar ediff-temp-file-mode 384 ; u=rw only 1612(defvar ediff-temp-file-mode 384 ; u=rw only
1437 "*Mode for Ediff temporary files.") 1613 "*Mode for Ediff temporary files.")
1438 1614
1439(emerge-defvar-local ediff-temp-file-A nil 1615(ediff-defvar-local ediff-temp-file-A nil
1440 "Temporary file used for refining difference regions in buffer B.") 1616 "Temporary file used for refining difference regions in buffer B.")
1441(emerge-defvar-local ediff-temp-file-B nil 1617(ediff-defvar-local ediff-temp-file-B nil
1442 "Temporary file used for refining difference regions in buffer B.") 1618 "Temporary file used for refining difference regions in buffer B.")
1443 1619
1444(defvar ediff-last-dir-A nil 1620(defvar ediff-last-dir-A nil
1445 "Last directory used by an Ediff command for file-A.") 1621 "Last directory used by an Ediff command for file-A.")
1446(defvar ediff-last-dir-B nil 1622(defvar ediff-last-dir-B nil
1447 "Last directory used by an Ediff command for file-B.") 1623 "Last directory used by an Ediff command for file-B.")
1624(defvar ediff-last-dir-patch nil
1625 "Last directory used by an Ediff command for file to patch.")
1448 1626
1449;; Build keymaps 1627;; Build keymaps
1450 1628
1451(defvar ediff-mode-map nil 1629(defvar ediff-mode-map nil
1452 "Local keymap used in Ediff mode.") 1630 "Local keymap used in Ediff mode.")
1453 1631
1632(defun ediff-frame-has-menubar ()
1633 (if (ediff-if-lucid)
1634 current-menubar
1635 (< 0 (cdr (assq 'menu-bar-lines (frame-parameters (selected-frame)))))
1636 ))
1637
1454;;; This is split in three parts to avoid 1638;;; This is split in three parts to avoid
1455;;; making a line in loaddefs.el that is too long for patch. 1639;;; making a line in loaddefs.el that is too long for patch.
1456;;; Note that autoload.el currently looks for cookies 1640;;; Note that autoload.el currently looks for cookies
1457;;; only at top level in the file. 1641;;; only at top level in the file.
1642;;; So I moved these to top level. But the conditionals on
1643;;; purify-flag make these no-ops when you load ediff.
1644;;; They only do something in loaddefs.el.
1458;;;###autoload 1645;;;###autoload
1459(progn 1646(if purify-flag
1460 (defvar menu-bar-epatch-menu (make-sparse-keymap "menu-bar-epatch-map")) 1647 (defvar menu-bar-epatch-menu
1648 (make-sparse-keymap "Epatch"))
1461 (fset 'menu-bar-epatch-menu (symbol-value 'menu-bar-epatch-menu)) 1649 (fset 'menu-bar-epatch-menu (symbol-value 'menu-bar-epatch-menu))
1462 (defvar menu-bar-ediff-menu (make-sparse-keymap "menu-bar-ediff-map")) 1650 (defvar menu-bar-ediff-menu (make-sparse-keymap "Ediff"))
1463 (fset 'menu-bar-ediff-menu (symbol-value 'menu-bar-ediff-menu))) 1651 (fset 'menu-bar-ediff-menu (symbol-value 'menu-bar-ediff-menu)))
1464 1652
1653
1465;;;###autoload 1654;;;###autoload
1466(progn 1655(if purify-flag
1467 (define-key menu-bar-ediff-menu [rcs-ediff] 1656 (define-key menu-bar-ediff-menu [rcs-ediff]
1468 '("With a Revision via RCS ..." . rcs-ediff)) 1657 '("Compare with a version via RCS ..." . rcs-ediff))
1469 (define-key menu-bar-ediff-menu [vc-ediff] 1658 (define-key menu-bar-ediff-menu [vc-ediff]
1470 '("With a Revision via VC ..." . vc-ediff)) 1659 '("Compare with a version via VC ..." . vc-ediff))
1471 (define-key menu-bar-ediff-menu [ediff-buffers] 1660 (define-key menu-bar-ediff-menu [ediff-buffers]
1472 '("Between Buffers ..." . ediff-buffers)) 1661 '("Compare buffers ..." . ediff-buffers))
1473 (define-key menu-bar-ediff-menu [ediff-files] 1662 (define-key menu-bar-ediff-menu [ediff-files]
1474 '("Between Files ..." . ediff-files))) 1663 '("Compare files ..." . ediff-files)))
1475 1664
1476;;;###autoload 1665;;;###autoload
1477(progn 1666(if purify-flag
1478 (define-key menu-bar-epatch-menu [ediff-patch-buffer] 1667 (define-key menu-bar-epatch-menu [ediff-patch-buffer]
1479 '("To a Buffer ..." . ediff-patch-buffer)) 1668 '("To a Buffer ..." . ediff-patch-buffer))
1480 (define-key menu-bar-epatch-menu [ediff-patch-file] 1669 (define-key menu-bar-epatch-menu [ediff-patch-file]
1481 '("To a File ..." . ediff-patch-file))) 1670 '("To a File ..." . ediff-patch-file)))
1482 1671
1483(if (and window-system ediff-want-default-menus (ediff-frame-has-menubar)) 1672(if (and window-system ediff-want-default-menus (ediff-frame-has-menubar)
1484 (if (ediff-if-lucid) 1673 (ediff-if-lucid))
1485 (progn ;; Lucid menu bars 1674 (progn ;; Lucid menu bars
1486 (defvar ediff-menu 1675 (defvar ediff-menu
1487 '("" 1676 '(""
1488 ["Between Files ..." ediff-files t] 1677 ["Compare files ..." ediff-files t]
1489 ["Between Buffers ..." ediff-buffers t] 1678 ["Compare buffers ..." ediff-buffers t]
1490 ["With a Revision via VC ..." vc-ediff t] 1679 ["Compare with a version via VC ..." vc-ediff t]
1491 ["With a Revision via RCS ..." rcs-ediff t])) 1680 ["Compare with a version via RCS ..." rcs-ediff t]))
1492 (defvar epatch-menu 1681 (defvar epatch-menu
1493 '("" 1682 '(""
1494 ["To a File ..." ediff-patch-file t] 1683 ["To a file ..." ediff-patch-file t]
1495 ["To a Buffer ..." ediff-patch-buffer t])) 1684 ["To a buffer ..." ediff-patch-buffer t]))
1496 (add-menu '("File") "Find Differences" 1685 (add-menu '("File") "Compare files"
1497 ediff-menu 1686 ediff-menu
1498 "Delete Screen") 1687 "New Screen")
1499 (add-menu '("File") "Apply Patch" 1688 (add-menu '("File") "Apply Patch"
1500 epatch-menu 1689 epatch-menu
1501 "Delete Screen") 1690 "New Screen")
1502 ;; Displays as a solid horizontal line 1691 ;; Displays as a solid horizontal line
1503 (add-menu-item '("File") "---" nil nil "Delete Screen") 1692 (add-menu-item '("File") "---" nil nil "New Screen")))
1504 )))
1505 1693
1506 1694
1507(defun ediff-setup-keymap () 1695(defun ediff-setup-keymap ()
@@ -1532,8 +1720,7 @@ Do not start with `~/' or `~user-name/'.")
1532 (define-key ediff-mode-map "V" 'ediff-scroll-down) 1720 (define-key ediff-mode-map "V" 'ediff-scroll-down)
1533 (define-key ediff-mode-map "<" 'ediff-scroll-left) 1721 (define-key ediff-mode-map "<" 'ediff-scroll-left)
1534 (define-key ediff-mode-map ">" 'ediff-scroll-right) 1722 (define-key ediff-mode-map ">" 'ediff-scroll-right)
1535 (define-key ediff-mode-map "f" 'ediff-file-names) 1723 (define-key ediff-mode-map "i" 'ediff-status-info)
1536 (define-key ediff-mode-map "l" 'ediff-line-numbers)
1537 (define-key ediff-mode-map "?" 'ediff-toggle-help) 1724 (define-key ediff-mode-map "?" 'ediff-toggle-help)
1538 (define-key ediff-mode-map "!" 'ediff-recompute-diffs) 1725 (define-key ediff-mode-map "!" 'ediff-recompute-diffs)
1539 (define-key ediff-mode-map "*" 'ediff-make-fine-diffs) 1726 (define-key ediff-mode-map "*" 'ediff-make-fine-diffs)
@@ -1544,6 +1731,9 @@ Do not start with `~/' or `~user-name/'.")
1544 (define-key ediff-mode-map "r" nil) 1731 (define-key ediff-mode-map "r" nil)
1545 (define-key ediff-mode-map "ra" 'ediff-restore-diff) 1732 (define-key ediff-mode-map "ra" 'ediff-restore-diff)
1546 (define-key ediff-mode-map "rb" 'ediff-restore-diff) 1733 (define-key ediff-mode-map "rb" 'ediff-restore-diff)
1734 (define-key ediff-mode-map "#" nil)
1735 (define-key ediff-mode-map "#h" 'ediff-toggle-regexp-match)
1736 (define-key ediff-mode-map "#f" 'ediff-toggle-regexp-match)
1547 (define-key ediff-mode-map "o" nil) 1737 (define-key ediff-mode-map "o" nil)
1548 (define-key ediff-mode-map "A" 'ediff-toggle-read-only) 1738 (define-key ediff-mode-map "A" 'ediff-toggle-read-only)
1549 (define-key ediff-mode-map "B" 'ediff-toggle-read-only) 1739 (define-key ediff-mode-map "B" 'ediff-toggle-read-only)
@@ -1558,41 +1748,52 @@ Do not start with `~/' or `~user-name/'.")
1558 1748
1559;;; Setup functions 1749;;; Setup functions
1560 1750
1561(defun ediff-find-file (file buffer &optional last-dir) 1751(defun ediff-find-file (file-var buffer &optional last-dir hooks-var)
1562 "Visits FILE for ediff. 1752 "Visit FILE and arrange its buffer to Ediff's liking.
1563BUFFER is a variable symbol that is supposed to 1753FILE is actually a variables symbol that must contain a true file name.
1564get the buffer into which FILE is read. LAST-DIR is the directory variable 1754BUFFER is a variable symbol, which will get the buffer object into which
1565symbol where FILE's dir name should be returned. 1755FILE is read. LAST-DIR is the directory variable symbol where FILE's
1566Arguments: (file 'buffer &optional 'last-dir)" 1756directory name should be returned. HOOKS is a variable symbol that will be
1567 (if (not (file-readable-p file)) 1757assigned the hook to be executed after `ediff-strartup' is finished.
1568 (error "File `%s' does not exist or is not readable" file)) 1758`ediff-find-file' arranges that the temp files it might create will be
1569 1759deleted.
1570 ;; Record the buffer 1760Arguments: (file buffer &optional last-dir hooks)"
1571 (set buffer (find-file-noselect file)) 1761 (let* ((file (eval file-var))
1572 ;; Record the directory of the file 1762 (file-magic (find-file-name-handler file 'find-file-noselect)))
1573 (if last-dir 1763 (if (not (file-readable-p file))
1574 (set last-dir (expand-file-name (file-name-directory file)))) 1764 (error "File `%s' does not exist or is not readable" file))
1575 1765
1576 ;; Make sure the entire file is seen, and it reflects what is on disk 1766 ;; Record the directory of the file
1577 (emerge-eval-in-buffer 1767 (if last-dir
1578 (eval buffer) 1768 (set last-dir (expand-file-name (file-name-directory file))))
1579 (widen) 1769
1580 (let ((temp (file-local-copy file)) 1770 ;; Setup the buffer
1581 startup-hooks) 1771 (set buffer (find-file-noselect file))
1582 (if temp 1772
1583 (setq file temp 1773 (ediff-eval-in-buffer
1584 startup-hooks 1774 (eval buffer)
1585 (cons (` (lambda () (delete-file (, file)))) 1775 (widen) ;; Make sure the entire file is seen
1586 startup-hooks)) 1776 (cond (file-magic ;; file has handler, such as jka-compr-handler or
1587 ;; Verify that the file matches the buffer 1777 ;; ange-ftp-hook-function--arrange for temp file
1588 (emerge-verify-file-buffer))))) 1778 (ediff-verify-file-buffer 'magic)
1779 (setq file (ediff-make-temp-file))
1780 (set hooks-var (cons (` (lambda () (delete-file (, file))))
1781 (eval hooks-var))))
1782 ;; file processed via auto-mode-alist, a la uncompress.el
1783 ((not (equal (expand-file-name file) (buffer-file-name)))
1784 (setq file (ediff-make-temp-file))
1785 (set hooks-var (cons (` (lambda () (delete-file (, file))))
1786 (eval hooks-var))))
1787 (t ;; plain file---just check that the file matches the buffer
1788 (ediff-verify-file-buffer))))
1789 (set file-var file)))
1589 1790
1590(defun ediff-files-internal (file-A file-B &optional startup-hooks) 1791(defun ediff-files-internal (file-A file-B &optional startup-hooks)
1591 (let (buffer-A buffer-B) 1792 (let (buffer-A buffer-B)
1592 (message "Reading file %s ... " file-A)(sit-for .5) 1793 (message "Reading file %s ... " file-A)(sit-for .5)
1593 (ediff-find-file file-A 'buffer-A 'ediff-last-dir-A) 1794 (ediff-find-file 'file-A 'buffer-A 'ediff-last-dir-A 'startup-hooks)
1594 (message "Reading file %s ... " file-B)(sit-for .5) 1795 (message "Reading file %s ... " file-B)(sit-for .5)
1595 (ediff-find-file file-B 'buffer-B 'ediff-last-dir-B) 1796 (ediff-find-file 'file-B 'buffer-B 'ediff-last-dir-B 'startup-hooks)
1596 (ediff-setup buffer-A file-A buffer-B file-B startup-hooks))) 1797 (ediff-setup buffer-A file-A buffer-B file-B startup-hooks)))
1597 1798
1598(defun ediff-get-patch-buffer (dir) 1799(defun ediff-get-patch-buffer (dir)
@@ -1602,14 +1803,13 @@ Else, read patch file into a new buffer."
1602 (setq ediff-patch-buf 1803 (setq ediff-patch-buf
1603 (get-buffer (read-buffer "Patch buffer name: " nil t))) ;must match 1804 (get-buffer (read-buffer "Patch buffer name: " nil t))) ;must match
1604 (setq ediff-patch-buf 1805 (setq ediff-patch-buf
1605 (find-file-noselect (read-file-name "Patch file name: " 1806 (find-file-noselect (read-file-name "Patch file name: " dir))))
1606 dir)))) 1807 (ediff-eval-in-buffer
1607 (emerge-eval-in-buffer
1608 ediff-patch-buf 1808 ediff-patch-buf
1609 (toggle-read-only 1)) 1809 (toggle-read-only 1))
1610 (setq ediff-patch-diagnostics 1810 (setq ediff-patch-diagnostics
1611 (get-buffer-create "*ediff patch diagnostics*")) 1811 (get-buffer-create "*ediff patch diagnostics*"))
1612 (emerge-eval-in-buffer 1812 (ediff-eval-in-buffer
1613 ediff-patch-diagnostics 1813 ediff-patch-diagnostics
1614 (insert-buffer ediff-patch-buf)) 1814 (insert-buffer ediff-patch-buf))
1615 ) 1815 )
@@ -1618,11 +1818,12 @@ Else, read patch file into a new buffer."
1618(defun ediff-setup (buffer-A file-A buffer-B file-B startup-hooks) 1818(defun ediff-setup (buffer-A file-A buffer-B file-B startup-hooks)
1619 (setq file-A (expand-file-name file-A)) 1819 (setq file-A (expand-file-name file-A))
1620 (setq file-B (expand-file-name file-B)) 1820 (setq file-B (expand-file-name file-B))
1621 (let* ((control-buffer-name (emerge-unique-buffer-name "*ediff-control" "*")) 1821 (let* ((control-buffer-name
1622 (control-buffer (emerge-eval-in-buffer 1822 (emerge-unique-buffer-name "Ediff Control Panel" ""))
1823 (control-buffer (ediff-eval-in-buffer
1623 buffer-A 1824 buffer-A
1624 (get-buffer-create control-buffer-name)))) 1825 (get-buffer-create control-buffer-name))))
1625 (emerge-eval-in-buffer 1826 (ediff-eval-in-buffer
1626 control-buffer 1827 control-buffer
1627 (ediff-mode) ;; in control buffer only 1828 (ediff-mode) ;; in control buffer only
1628 (setq buffer-read-only nil) 1829 (setq buffer-read-only nil)
@@ -1649,10 +1850,10 @@ Else, read patch file into a new buffer."
1649 (run-hooks 'ediff-before-setup-windows-hooks) 1850 (run-hooks 'ediff-before-setup-windows-hooks)
1650 (ediff-setup-windows buffer-A buffer-B control-buffer t) 1851 (ediff-setup-windows buffer-A buffer-B control-buffer t)
1651 1852
1652 ;; all these must be inside emerge-eval-in-buffer control-buffer, 1853 ;; all these must be inside ediff-eval-in-buffer control-buffer,
1653 ;; since these vars are local to control-buffer 1854 ;; since these vars are local to control-buffer
1654 ;; These won't run if there are errors in diff 1855 ;; These won't run if there are errors in diff
1655 (emerge-eval-in-buffer 1856 (ediff-eval-in-buffer
1656 ediff-A-buffer 1857 ediff-A-buffer
1657 (run-hooks 'ediff-prepare-buffer-hooks) 1858 (run-hooks 'ediff-prepare-buffer-hooks)
1658 (add-hook 'local-write-file-hooks 'ediff-block-write-file) 1859 (add-hook 'local-write-file-hooks 'ediff-block-write-file)
@@ -1662,7 +1863,7 @@ Else, read patch file into a new buffer."
1662 (setq ediff-this-buffer-control-sessions 1863 (setq ediff-this-buffer-control-sessions
1663 (cons control-buffer ediff-this-buffer-control-sessions))) 1864 (cons control-buffer ediff-this-buffer-control-sessions)))
1664 (setq mode-line-buffer-identification '("A: %b"))) 1865 (setq mode-line-buffer-identification '("A: %b")))
1665 (emerge-eval-in-buffer 1866 (ediff-eval-in-buffer
1666 ediff-B-buffer 1867 ediff-B-buffer
1667 (run-hooks 'ediff-prepare-buffer-hooks) 1868 (run-hooks 'ediff-prepare-buffer-hooks)
1668 (add-hook 'local-write-file-hooks 'ediff-block-write-file) 1869 (add-hook 'local-write-file-hooks 'ediff-block-write-file)
@@ -1673,7 +1874,7 @@ Else, read patch file into a new buffer."
1673 (cons control-buffer ediff-this-buffer-control-sessions))) 1874 (cons control-buffer ediff-this-buffer-control-sessions)))
1674 (setq mode-line-buffer-identification '("B: %b"))) 1875 (setq mode-line-buffer-identification '("B: %b")))
1675 1876
1676 (emerge-eval-in-buffer control-buffer 1877 (ediff-eval-in-buffer control-buffer
1677 (run-hooks 'startup-hooks 'ediff-startup-hooks) 1878 (run-hooks 'startup-hooks 'ediff-startup-hooks)
1678 (setq buffer-read-only t))))) 1879 (setq buffer-read-only t)))))
1679 1880
@@ -1692,7 +1893,7 @@ Else, read patch file into a new buffer."
1692 (or use-old (setq ediff-diff-buffer 1893 (or use-old (setq ediff-diff-buffer
1693 (get-buffer-create 1894 (get-buffer-create
1694 (emerge-unique-buffer-name "*ediff-diff" "*")))) 1895 (emerge-unique-buffer-name "*ediff-diff" "*"))))
1695 (emerge-eval-in-buffer 1896 (ediff-eval-in-buffer
1696 ediff-diff-buffer 1897 ediff-diff-buffer
1697 (erase-buffer) 1898 (erase-buffer)
1698 ;; shell-command tends to display old shell command buffers even when it 1899 ;; shell-command tends to display old shell command buffers even when it
@@ -1726,7 +1927,7 @@ Else, read patch file into a new buffer."
1726 1927
1727(defun ediff-prepare-error-list (ok-regexp) 1928(defun ediff-prepare-error-list (ok-regexp)
1728 (let ((diff-buff ediff-diff-buffer)) 1929 (let ((diff-buff ediff-diff-buffer))
1729 (emerge-eval-in-buffer 1930 (ediff-eval-in-buffer
1730 ediff-error-buffer 1931 ediff-error-buffer
1731 (erase-buffer) 1932 (erase-buffer)
1732 (insert-buffer diff-buff) 1933 (insert-buffer diff-buff)
@@ -1735,49 +1936,94 @@ Else, read patch file into a new buffer."
1735;;; Function to start Ediff by patching a file 1936;;; Function to start Ediff by patching a file
1736 1937
1737;;;###autoload 1938;;;###autoload
1738(defun ediff-patch-file (file-to-patch &optional startup-hooks) 1939(defun ediff-patch-file (source-filename &optional startup-hooks)
1739 "Run Ediff by patching FILE-TP-PATCH." 1940 "Run Ediff by patching FILE-TP-PATCH."
1740 (interactive "fFile to patch: ") 1941 (interactive
1942 (list (ediff-read-file-name "File to patch"
1943 (if ediff-use-last-dir
1944 ediff-last-dir-patch
1945 default-directory)
1946 nil)))
1741 1947
1742 (ediff-get-patch-buffer (file-name-directory file-to-patch)) 1948 (ediff-get-patch-buffer (file-name-directory source-filename))
1743 (let ((buf (get-file-buffer file-to-patch))) 1949 (let* ((backup-extension
1744 (if buf 1950 ;; if the user specified a -b option, extract the backup
1745 (progn 1951 ;; extension from there; else use `.orig'
1746 (emerge-eval-in-buffer 1952 (substring ediff-patch-options
1747 buf 1953 (if (string-match "-b[ \t]+" ediff-patch-options)
1748 (if (buffer-modified-p buf) 1954 (match-end 0) 0)
1749 (if (y-or-n-p 1955 (if (string-match "-b[ \t]+[^ \t]+" ediff-patch-options)
1750 (format 1956 (match-end 0) 0)))
1751 "File '%s' is already in buffer %s. Save before killing? " 1957 (backup-extension (if (string= backup-extension "")
1752 file-to-patch (buffer-name buf))) 1958 "orig" backup-extension))
1753 (save-buffer buf))) 1959 (shell-file-name ediff-shell)
1754 (set-buffer-modified-p nil)) 1960 ;; ediff-find-file may use a temp file to do the patch
1755 (ediff-kill-buffer-carefully buf)))) 1961 ;; so, we save source-filename and true-source-filename as a var
1756 (emerge-eval-in-buffer 1962 ;; that initially is source-filename but may be changed to a temp
1757 ediff-patch-diagnostics 1963 ;; file for the purpose of patching.
1758 (let ((shell-file-name ediff-shell)) 1964 (true-source-filename source-filename)
1965 (target-filename source-filename)
1966 target-buf buf-to-patch file-name-magic-p)
1967
1968 ;; Make a temp file, if source-filename has a magic file handler (or if
1969 ;; it is handled via auto-mode-alist and similar magic).
1970 ;; Check if there is a buffer visiting source-filename and if they are in
1971 ;; synch; arrange for the deletion of temp file.
1972 (ediff-find-file 'true-source-filename 'buf-to-patch
1973 'ediff-last-dir-patch 'startup-hooks)
1974
1975 ;; Check if source file name has triggered black magic, such as file name
1976 ;; handlers or auto mode alist, and make a note of it.
1977 (setq file-name-magic-p (not (equal (expand-file-name true-source-filename)
1978 (expand-file-name source-filename))))
1979
1980 (ediff-eval-in-buffer
1981 ediff-patch-diagnostics
1759 (message "Applying patch ... ")(sit-for .5) 1982 (message "Applying patch ... ")(sit-for .5)
1760 ;; always pass patch the -f option, so it won't ask any questions 1983 ;; always pass patch the -f option, so it won't ask any questions
1761 (shell-command-on-region 1984 (shell-command-on-region
1762 (point-min) (point-max) 1985 (point-min) (point-max)
1763 (format "%s %s %s" 1986 (format "%s -f %s %s"
1764 ediff-patch-program (concat "-f " ediff-patch-options) 1987 ediff-patch-program ediff-patch-options
1765 (expand-file-name file-to-patch)) 1988 (expand-file-name true-source-filename))
1766 t) 1989 t))
1767 (message "Applying patch ... Done.")(sit-for .5) 1990 (message "Applying patch ... Done.")(sit-for .5)
1768 )) 1991 (switch-to-buffer ediff-patch-diagnostics)
1769 (switch-to-buffer ediff-patch-diagnostics) 1992 (sit-for 0) ;; synchronize
1770 (sit-for 0) ;; synchronize 1993
1994 (or (file-exists-p (concat true-source-filename "." backup-extension))
1995 (error "Patch failed or didn't modify the original file."))
1771 1996
1772 (setq startup-hooks (cons 'ediff-toggle-read-only-A startup-hooks)) 1997 ;; If black magic is involved, apply patch to a temp copy of the
1773 (if (file-exists-p (format "%s.orig" file-to-patch)) 1998 ;; file. Otherwise, apply patch to the orig copy.
1774 (ediff-files 1999 ;; If patch is applied to temp copy, we name the result
1775 (format "%s.orig" file-to-patch) file-to-patch startup-hooks) 2000 ;; ***.patched. The orig file name isn't changed, and the temp copy of
1776 (error "Patch failed or didn't modify the original file.")) 2001 ;; the original is later deleted.
2002 ;; Without magic, the original file is renamed (usually into
2003 ;; old-name.orig) and the result of patching will have the
2004 ;; same name as the original.
2005 (if (not file-name-magic-p)
2006 (ediff-eval-in-buffer
2007 buf-to-patch
2008 (set-visited-file-name (concat source-filename "." backup-extension))
2009 (set-buffer-modified-p nil))
2010 (setq target-filename (concat true-source-filename ".patched"))
2011 (rename-file true-source-filename target-filename t)
2012
2013 ;; arrange that the temp copy of orig will be deleted
2014 (rename-file (concat true-source-filename "." backup-extension)
2015 true-source-filename t))
2016
2017 ;; make orig buffer read-only
2018 (setq startup-hooks (cons 'ediff-toggle-read-only-A startup-hooks))
2019 ;; set up a buf for the patched file
2020 (setq target-buf (find-file-noselect target-filename))
2021
2022 (ediff-buffers buf-to-patch target-buf startup-hooks)
1777 2023
1778 (bury-buffer ediff-patch-diagnostics) 2024 (bury-buffer ediff-patch-diagnostics)
1779 (message "Patch diagnostics available in buffer %s." 2025 (message "Patch diagnostics available in buffer %s."
1780 (buffer-name ediff-patch-diagnostics))) 2026 (buffer-name ediff-patch-diagnostics))))
1781 2027
1782(defalias 'epatch 'ediff-patch-file) 2028(defalias 'epatch 'ediff-patch-file)
1783(defalias 'epatch-buffer 'ediff-patch-buffer) 2029(defalias 'epatch-buffer 'ediff-patch-buffer)
@@ -1793,11 +2039,11 @@ Else, read patch file into a new buffer."
1793 (if ediff-use-last-dir 2039 (if ediff-use-last-dir
1794 ediff-last-dir-A 2040 ediff-last-dir-A
1795 default-directory) 2041 default-directory)
1796 nil nil)) 2042 nil))
1797 (ediff-read-file-name "File B to compare" 2043 (ediff-read-file-name "File B to compare"
1798 (if ediff-use-last-dir 2044 (if ediff-use-last-dir
1799 ediff-last-dir-B nil) 2045 ediff-last-dir-B nil)
1800 f f) 2046 f)
1801 ))) 2047 )))
1802 (ediff-files-internal file-A 2048 (ediff-files-internal file-A
1803 (if (file-directory-p file-B) 2049 (if (file-directory-p file-B)
@@ -1815,12 +2061,25 @@ Else, read patch file into a new buffer."
1815;;;###autoload 2061;;;###autoload
1816(defun ediff-buffers (buffer-A buffer-B &optional startup-hooks) 2062(defun ediff-buffers (buffer-A buffer-B &optional startup-hooks)
1817 "Run Ediff on a pair of buffers, BUFFER-A and BUFFER-B." 2063 "Run Ediff on a pair of buffers, BUFFER-A and BUFFER-B."
1818 (interactive "bBuffer A to compare: \nbBuffer B to compare: ") 2064 (interactive
2065 (list (read-buffer "Buffer A to compare: " (current-buffer) t)
2066 (read-buffer "Buffer B to compare: "
2067 (progn
2068 ;; realign buffers so that two visible bufs will be
2069 ;; at the top
2070 (save-window-excursion (other-window 1))
2071 (other-buffer (current-buffer) t))
2072 t)))
2073 (if (not (ediff-buffer-live-p buffer-A))
2074 (error "Buffer %S doesn't exist." buffer-A))
2075 (if (not (ediff-buffer-live-p buffer-B))
2076 (error "Buffer %S doesn't exist." buffer-B))
2077
1819 (let (file-A file-B) 2078 (let (file-A file-B)
1820 (emerge-eval-in-buffer 2079 (ediff-eval-in-buffer
1821 buffer-A 2080 buffer-A
1822 (setq file-A (ediff-make-temp-file))) 2081 (setq file-A (ediff-make-temp-file)))
1823 (emerge-eval-in-buffer 2082 (ediff-eval-in-buffer
1824 buffer-B 2083 buffer-B
1825 (setq file-B (ediff-make-temp-file))) 2084 (setq file-B (ediff-make-temp-file)))
1826 (ediff-setup (get-buffer buffer-A) file-A 2085 (ediff-setup (get-buffer buffer-A) file-A
@@ -1861,7 +2120,8 @@ If `F.~REV~' already exists, it is used instead of being re-created."
1861 (define-key vc-prefix-map "=" 'vc-ediff)) 2120 (define-key vc-prefix-map "=" 'vc-ediff))
1862 (error "The VC package is apparently not installed."))) 2121 (error "The VC package is apparently not installed.")))
1863 (let ((newvers (current-buffer)) 2122 (let ((newvers (current-buffer))
1864 (oldvers (vc-version-other-window rev))) 2123 )
2124 (vc-version-other-window rev)
1865 ;; current-buffer is supposed to contain the old version in another 2125 ;; current-buffer is supposed to contain the old version in another
1866 ;; window 2126 ;; window
1867 (ediff-buffers newvers (current-buffer)) 2127 (ediff-buffers newvers (current-buffer))
@@ -1894,7 +2154,7 @@ With prefix argument, prompts for a revision name."
1894(defun ediff-rcs-get-output-buffer (file name) 2154(defun ediff-rcs-get-output-buffer (file name)
1895 ;; Get a buffer for RCS output for FILE, make it writable and clean it up. 2155 ;; Get a buffer for RCS output for FILE, make it writable and clean it up.
1896 ;; Optional NAME is name to use instead of `*RCS-output*'. 2156 ;; Optional NAME is name to use instead of `*RCS-output*'.
1897 ;; This is a mofified version from rcs.el v1.1. I use it here to make 2157 ;; This is a modified version from rcs.el v1.1. I use it here to make
1898 ;; Ediff immune to changes in rcs.el 2158 ;; Ediff immune to changes in rcs.el
1899 (let* ((default-major-mode 'fundamental-mode);; no frills! 2159 (let* ((default-major-mode 'fundamental-mode);; no frills!
1900 (buf (get-buffer-create name))) 2160 (buf (get-buffer-create name)))
@@ -1923,20 +2183,6 @@ With prefix argument, prompts for revision name."
1923 )) 2183 ))
1924 2184
1925 2185
1926;;; Functions to start Ediff via remote request
1927
1928;;;###autoload
1929(defun ediff-files-remote (file-a file-b)
1930 "Run Ediff on remote files, FILE-A and FILE-B."
1931 (ediff-files-internal file-a file-b nil)
1932 (throw 'client-wait nil))
1933
1934
1935(defun ediff-remote-exit (exit-func)
1936 "Exit remote Ediff session."
1937 (ediff-really-quit)
1938 (funcall exit-func))
1939
1940 2186
1941 2187
1942;; Select the lowest window on the frame. 2188;; Select the lowest window on the frame.
@@ -1982,7 +2228,7 @@ With prefix argument, prompts for revision name."
1982 (ediff-setup-control-window) 2228 (ediff-setup-control-window)
1983 2229
1984 ;; If diff reports errors, show them then quit. 2230 ;; If diff reports errors, show them then quit.
1985 (if (/= 0 (emerge-eval-in-buffer ediff-error-buffer (buffer-size))) 2231 (if (/= 0 (ediff-eval-in-buffer ediff-error-buffer (buffer-size)))
1986 (let ((diff-output-buf ediff-diff-buffer)) 2232 (let ((diff-output-buf ediff-diff-buffer))
1987 (switch-to-buffer ediff-error-buffer) 2233 (switch-to-buffer ediff-error-buffer)
1988 (ediff-kill-buffer-carefully control-buffer) 2234 (ediff-kill-buffer-carefully control-buffer)
@@ -2059,7 +2305,7 @@ With prefix argument, prompts for revision name."
2059(defun ediff-leave-window-config (control-buf) 2305(defun ediff-leave-window-config (control-buf)
2060 (and (eq control-buf (current-buffer)) 2306 (and (eq control-buf (current-buffer))
2061 (/= (buffer-size) 0) 2307 (/= (buffer-size) 0)
2062 (emerge-eval-in-buffer 2308 (ediff-eval-in-buffer
2063 control-buf 2309 control-buf
2064 (string= ediff-window-config-saved 2310 (string= ediff-window-config-saved
2065 (format "%S%S%S%S" 2311 (format "%S%S%S%S"
@@ -2091,17 +2337,16 @@ because this is required by `before-change-function'."
2091 (mapcar 2337 (mapcar
2092 (function 2338 (function
2093 (lambda (buf) 2339 (lambda (buf)
2094 (if (ediff-buffer-live-p buf) 2340 (ediff-eval-in-buffer
2095 (emerge-eval-in-buffer 2341 buf
2096 buf 2342 (if (eq ediff-highlighting-style 'ascii)
2097 (if (eq ediff-highlighting-style 'ascii) 2343 (progn
2098 (progn 2344 (ediff-unselect-and-select-difference
2099 (ediff-unselect-and-select-difference 2345 ediff-current-difference
2100 ediff-current-difference 2346 'unselect-only 'no-recenter)
2101 'unselect-only 'no-recenter) 2347 (setq rehighlight-key
2102 (setq rehighlight-key 2348 (substitute-command-keys "\\[ediff-recenter]"))
2103 (substitute-command-keys "\\[ediff-recenter]")) 2349 )))))
2104 ))))))
2105 ediff-this-buffer-control-sessions) 2350 ediff-this-buffer-control-sessions)
2106 (if rehighlight-key 2351 (if rehighlight-key
2107 (error 2352 (error
@@ -2112,15 +2357,14 @@ because this is required by `before-change-function'."
2112(defun ediff-recompute-diffs () 2357(defun ediff-recompute-diffs ()
2113 "Recompute difference regions in buffers A and B." 2358 "Recompute difference regions in buffers A and B."
2114 (interactive) 2359 (interactive)
2115 (let ((curr-diff ediff-current-difference) 2360 (let ((point-A (ediff-eval-in-buffer ediff-A-buffer (point)))
2116 (point-A (emerge-eval-in-buffer ediff-A-buffer (point))) 2361 (point-B (ediff-eval-in-buffer ediff-B-buffer (point)))
2117 (point-B (emerge-eval-in-buffer ediff-B-buffer (point)))
2118 file-A file-B) 2362 file-A file-B)
2119 (ediff-unselect-and-select-difference -1) 2363 (ediff-unselect-and-select-difference -1)
2120 (emerge-eval-in-buffer 2364 (ediff-eval-in-buffer
2121 ediff-A-buffer 2365 ediff-A-buffer
2122 (setq file-A (ediff-make-temp-file))) 2366 (setq file-A (ediff-make-temp-file)))
2123 (emerge-eval-in-buffer 2367 (ediff-eval-in-buffer
2124 ediff-B-buffer 2368 ediff-B-buffer
2125 (setq file-B (ediff-make-temp-file))) 2369 (setq file-B (ediff-make-temp-file)))
2126 (ediff-clear-diff-vector ediff-difference-vector 'fine-diffs-also) 2370 (ediff-clear-diff-vector ediff-difference-vector 'fine-diffs-also)
@@ -2131,13 +2375,13 @@ because this is required by `before-change-function'."
2131 (setq ediff-number-of-differences (length ediff-difference-vector)) 2375 (setq ediff-number-of-differences (length ediff-difference-vector))
2132 (delete-file file-A) 2376 (delete-file file-A)
2133 (delete-file file-B) 2377 (delete-file file-B)
2134 (emerge-eval-in-buffer ediff-A-buffer (goto-char point-A)) 2378 (ediff-eval-in-buffer ediff-A-buffer (goto-char point-A))
2135 (ediff-jump-to-difference (ediff-diff-at-point 'A)) 2379 (ediff-jump-to-difference (ediff-diff-at-point 'A))
2136 (beep 1) 2380 (beep 1)
2137 (if (y-or-n-p 2381 (if (y-or-n-p
2138 "Ediff is around last posn in buff A. Stay (or goto last posn in B)? ") 2382 "Ediff is at last posn in buff A. Stay (or goto last posn in B)? ")
2139 () 2383 ()
2140 (emerge-eval-in-buffer ediff-B-buffer (goto-char point-B)) 2384 (ediff-eval-in-buffer ediff-B-buffer (goto-char point-B))
2141 (ediff-jump-to-difference (ediff-diff-at-point 'B))) 2385 (ediff-jump-to-difference (ediff-diff-at-point 'B)))
2142 (message "") 2386 (message "")
2143 )) 2387 ))
@@ -2151,14 +2395,14 @@ and `auto-save' properties in buffer local variables. Turns off
2151 2395
2152 ;; remember and alter buffer characteristics 2396 ;; remember and alter buffer characteristics
2153 (set (if arg 'ediff-A-buffer-values-setup 'ediff-A-buffer-values) 2397 (set (if arg 'ediff-A-buffer-values-setup 'ediff-A-buffer-values)
2154 (emerge-eval-in-buffer 2398 (ediff-eval-in-buffer
2155 ediff-A-buffer 2399 ediff-A-buffer
2156 (prog1 2400 (prog1
2157 (emerge-save-variables ediff-saved-variables) 2401 (emerge-save-variables ediff-saved-variables)
2158 (emerge-restore-variables ediff-saved-variables 2402 (emerge-restore-variables ediff-saved-variables
2159 ediff-working-values)))) 2403 ediff-working-values))))
2160 (set (if arg 'ediff-B-buffer-values-setup 'ediff-B-buffer-values) 2404 (set (if arg 'ediff-B-buffer-values-setup 'ediff-B-buffer-values)
2161 (emerge-eval-in-buffer 2405 (ediff-eval-in-buffer
2162 ediff-B-buffer 2406 ediff-B-buffer
2163 (prog1 2407 (prog1
2164 (emerge-save-variables ediff-saved-variables) 2408 (emerge-save-variables ediff-saved-variables)
@@ -2169,15 +2413,16 @@ and `auto-save' properties in buffer local variables. Turns off
2169 "Restores properties saved by `ediff-remember-buffer-characteristics'." 2413 "Restores properties saved by `ediff-remember-buffer-characteristics'."
2170 (let ((A-values (if arg ediff-A-buffer-values-setup ediff-A-buffer-values)) 2414 (let ((A-values (if arg ediff-A-buffer-values-setup ediff-A-buffer-values))
2171 (B-values (if arg ediff-B-buffer-values-setup ediff-B-buffer-values))) 2415 (B-values (if arg ediff-B-buffer-values-setup ediff-B-buffer-values)))
2172 (emerge-eval-in-buffer ediff-A-buffer 2416
2173 (emerge-restore-variables ediff-saved-variables 2417 (ediff-eval-in-buffer ediff-A-buffer
2174 A-values)) 2418 (emerge-restore-variables ediff-saved-variables
2175 (emerge-eval-in-buffer ediff-B-buffer 2419 A-values))
2176 (emerge-restore-variables ediff-saved-variables 2420 (ediff-eval-in-buffer ediff-B-buffer
2177 B-values)))) 2421 (emerge-restore-variables ediff-saved-variables
2422 B-values))))
2178 2423
2179 2424
2180;; if optional A-buffer and B-buffer are given, then construct a vector of 2425;; If optional A-buffer and B-buffer are given, then construct a vector of
2181;; diff using point values. Otherwise, use line offsets. 2426;; diff using point values. Otherwise, use line offsets.
2182(defun ediff-extract-diffs (diff-buffer &optional A-buffer B-buffer) 2427(defun ediff-extract-diffs (diff-buffer &optional A-buffer B-buffer)
2183 (let (diff-list 2428 (let (diff-list
@@ -2186,14 +2431,14 @@ and `auto-save' properties in buffer local variables. Turns off
2186 2431
2187 (if (and A-buffer B-buffer) 2432 (if (and A-buffer B-buffer)
2188 (progn ;; reset point in buffers A and B 2433 (progn ;; reset point in buffers A and B
2189 (emerge-eval-in-buffer 2434 (ediff-eval-in-buffer
2190 A-buffer 2435 A-buffer
2191 (goto-char (point-min))) 2436 (goto-char (point-min)))
2192 (emerge-eval-in-buffer 2437 (ediff-eval-in-buffer
2193 B-buffer 2438 B-buffer
2194 (goto-char (point-min))))) 2439 (goto-char (point-min)))))
2195 2440
2196 (emerge-eval-in-buffer 2441 (ediff-eval-in-buffer
2197 diff-buffer 2442 diff-buffer
2198 (goto-char (point-min)) 2443 (goto-char (point-min))
2199 (while (re-search-forward ediff-match-diff-line nil t) 2444 (while (re-search-forward ediff-match-diff-line nil t)
@@ -2229,14 +2474,14 @@ and `auto-save' properties in buffer local variables. Turns off
2229 (if (and A-buffer B-buffer) 2474 (if (and A-buffer B-buffer)
2230 (progn ;; computing main diff vector 2475 (progn ;; computing main diff vector
2231 ;; convert to relative line numbers 2476 ;; convert to relative line numbers
2232 (emerge-eval-in-buffer 2477 (ediff-eval-in-buffer
2233 A-buffer 2478 A-buffer
2234 (forward-line (- a-begin a-prev)) 2479 (forward-line (- a-begin a-prev))
2235 (setq a-begin-pt (point)) 2480 (setq a-begin-pt (point))
2236 (forward-line (- a-end a-begin)) 2481 (forward-line (- a-end a-begin))
2237 (setq a-end-pt (point) 2482 (setq a-end-pt (point)
2238 a-prev a-end)) 2483 a-prev a-end))
2239 (emerge-eval-in-buffer 2484 (ediff-eval-in-buffer
2240 B-buffer 2485 B-buffer
2241 (forward-line (- b-begin b-prev)) 2486 (forward-line (- b-begin b-prev))
2242 (setq b-begin-pt (point)) 2487 (setq b-begin-pt (point))
@@ -2255,7 +2500,7 @@ and `auto-save' properties in buffer local variables. Turns off
2255 a-prev a-end 2500 a-prev a-end
2256 b-prev b-end)) 2501 b-prev b-end))
2257 2502
2258 ))) ;; end emerge-eval-in-buffer 2503 ))) ;; end ediff-eval-in-buffer
2259 diff-list 2504 diff-list
2260 )) 2505 ))
2261 2506
@@ -2275,10 +2520,10 @@ and `auto-save' properties in buffer local variables. Turns off
2275 b-begin (aref list-element 2) 2520 b-begin (aref list-element 2)
2276 b-end (aref list-element 3)) 2521 b-end (aref list-element 3))
2277 2522
2278 ;; place overlays at the appropriate places in the buffers 2523 ;; Put overlays at the appropriate places in the buffers
2279 (setq a-overlay (ediff-make-overlay a-begin a-end A-buffer)) 2524 (setq a-overlay (ediff-make-overlay a-begin a-end A-buffer))
2280 ;; priorities of overlays should be equal in all ediff-control 2525 ;; Priorities of overlays should be equal in all ediff control
2281 ;; buffers. otherwise it won't work due to Emacs 2526 ;; panels buffers. Otherwise it won't work due to Emacs
2282 ;; bug---insert-in-front-hooks will be called 2527 ;; bug---insert-in-front-hooks will be called
2283 ;; only on behalf of the buffer with higher priority. 2528 ;; only on behalf of the buffer with higher priority.
2284 (ediff-overlay-put a-overlay 'priority ediff-shaded-overlay-priority) 2529 (ediff-overlay-put a-overlay 'priority ediff-shaded-overlay-priority)
@@ -2339,9 +2584,14 @@ Reestablish the default three-window display."
2339 (interactive) 2584 (interactive)
2340 (setq ediff-disturbed-overlays nil) ;; clear after use 2585 (setq ediff-disturbed-overlays nil) ;; clear after use
2341 (let (buffer-read-only) 2586 (let (buffer-read-only)
2342 (ediff-setup-windows ediff-A-buffer ediff-B-buffer ediff-control-buffer)) 2587 (if (and (ediff-buffer-live-p ediff-A-buffer)
2588 (ediff-buffer-live-p ediff-B-buffer))
2589 (ediff-setup-windows
2590 ediff-A-buffer ediff-B-buffer ediff-control-buffer)))
2343 ;; Redisplay whatever buffers are showing, if there is a selected difference 2591 ;; Redisplay whatever buffers are showing, if there is a selected difference
2344 (if (and (>= ediff-current-difference 0) 2592 (if (and (ediff-buffer-live-p ediff-A-buffer)
2593 (ediff-buffer-live-p ediff-B-buffer)
2594 (>= ediff-current-difference 0)
2345 (< ediff-current-difference ediff-number-of-differences)) 2595 (< ediff-current-difference ediff-number-of-differences))
2346 (let* ( ;; context must be saved before switching to windows A/B 2596 (let* ( ;; context must be saved before switching to windows A/B
2347 (buffer-A ediff-A-buffer) 2597 (buffer-A ediff-A-buffer)
@@ -2481,7 +2731,7 @@ On a dumb terminal, switches between ASCII highlighting and no highlighting."
2481(defun ediff-toggle-read-only () 2731(defun ediff-toggle-read-only ()
2482 "Toggles buffer-read-only for buffer buffers A and B." 2732 "Toggles buffer-read-only for buffer buffers A and B."
2483 (interactive) 2733 (interactive)
2484 (emerge-eval-in-buffer 2734 (ediff-eval-in-buffer
2485 (if (eq last-command-char ?A) ediff-A-buffer ediff-B-buffer) 2735 (if (eq last-command-char ?A) ediff-A-buffer ediff-B-buffer)
2486 (setq buffer-read-only (null buffer-read-only)))) 2736 (setq buffer-read-only (null buffer-read-only))))
2487 2737
@@ -2651,6 +2901,8 @@ With a prefix argument, go back that many differences."
2651 (let ((n (min ediff-number-of-differences 2901 (let ((n (min ediff-number-of-differences
2652 (+ ediff-current-difference (if arg arg 1)))) 2902 (+ ediff-current-difference (if arg arg 1))))
2653 (buffer-read-only nil)) 2903 (buffer-read-only nil))
2904 (while (funcall ediff-skip-diff-region-function n)
2905 (setq n (1+ n)))
2654 (ediff-unselect-and-select-difference n)) 2906 (ediff-unselect-and-select-difference n))
2655 (error "At end of the difference list."))) 2907 (error "At end of the difference list.")))
2656 2908
@@ -2661,7 +2913,9 @@ With a prefix argument, go back that many differences."
2661 (if (> ediff-current-difference -1) 2913 (if (> ediff-current-difference -1)
2662 (let ((n (max -1 (- ediff-current-difference (if arg arg 1)))) 2914 (let ((n (max -1 (- ediff-current-difference (if arg arg 1))))
2663 (buffer-read-only nil)) 2915 (buffer-read-only nil))
2664 (ediff-unselect-and-select-difference n)) 2916 (while (funcall ediff-skip-diff-region-function n)
2917 (setq n (1- n)))
2918 (ediff-unselect-and-select-difference n))
2665 (error "At beginning of the difference list."))) 2919 (error "At beginning of the difference list.")))
2666 2920
2667(defun ediff-jump-to-difference (difference-number) 2921(defun ediff-jump-to-difference (difference-number)
@@ -2676,8 +2930,9 @@ With a prefix argument, go back that many differences."
2676 2930
2677(defun ediff-jump-to-difference-at-point () 2931(defun ediff-jump-to-difference-at-point ()
2678 "Go to the difference closest to the point in buffer A or B. 2932 "Go to the difference closest to the point in buffer A or B.
2679If this command is invoked via `ja' or `ga' then the point in buffer A is 2933If this command is invoked via `\\[ediff-jump-to-difference-at-point]'
2680used. Otherwise, buffer B is used." 2934then the point in buffer B is used.
2935Otherwise, buffer A's point is used."
2681 (interactive) 2936 (interactive)
2682 (let ((buffer-read-only nil) 2937 (let ((buffer-read-only nil)
2683 (buf-type (ediff-char-to-buftype last-command-char))) 2938 (buf-type (ediff-char-to-buftype last-command-char)))
@@ -2689,15 +2944,17 @@ used. Otherwise, buffer B is used."
2689(defun ediff-diff-at-point (buf-type) 2944(defun ediff-diff-at-point (buf-type)
2690 (let ((buffer (ediff-get-buffer buf-type)) 2945 (let ((buffer (ediff-get-buffer buf-type))
2691 (ctl-buffer ediff-control-buffer) 2946 (ctl-buffer ediff-control-buffer)
2947 (max-dif-num (1- ediff-number-of-differences))
2692 (diff-no -1) 2948 (diff-no -1)
2693 (prev-beg 0) 2949 (prev-beg 0)
2694 (prev-end 0) 2950 (prev-end 0)
2695 (beg 0) 2951 (beg 0)
2696 (end 0)) 2952 (end 0))
2697 2953
2698 (emerge-eval-in-buffer 2954 (ediff-eval-in-buffer
2699 buffer 2955 buffer
2700 (while (or (< (point) prev-beg) (> (point) beg)) 2956 (while (and (or (< (point) prev-beg) (> (point) beg))
2957 (< diff-no max-dif-num))
2701 (setq diff-no (1+ diff-no)) 2958 (setq diff-no (1+ diff-no))
2702 (setq prev-beg beg 2959 (setq prev-beg beg
2703 prev-end end) 2960 prev-end end)
@@ -2720,10 +2977,14 @@ Otherwise, copy the difference given by `ediff-current-difference'."
2720 (interactive "P") 2977 (interactive "P")
2721 (if arg 2978 (if arg
2722 (ediff-jump-to-difference arg)) 2979 (ediff-jump-to-difference arg))
2723 (ediff-copy-diff ediff-current-difference 2980 (let* ((key1 (aref (this-command-keys) 0))
2724 (ediff-char-to-buftype (aref (this-command-keys) 0)) 2981 (key2 (aref (this-command-keys) 1))
2725 (ediff-char-to-buftype (aref (this-command-keys) 1))) 2982 (char1 (if (ediff-if-lucid) (event-key key1) key1))
2726 (ediff-recenter 'no-rehighlight)) 2983 (char2 (if (ediff-if-lucid) (event-key key2) key2)))
2984 (ediff-copy-diff ediff-current-difference
2985 (ediff-char-to-buftype char1)
2986 (ediff-char-to-buftype char2))
2987 (ediff-recenter 'no-rehighlight)))
2727 2988
2728 2989
2729(defun ediff-copy-diff (n from-buf-type to-buf-type) 2990(defun ediff-copy-diff (n from-buf-type to-buf-type)
@@ -2739,13 +3000,13 @@ Otherwise, copy the difference given by `ediff-current-difference'."
2739 (ediff-get-diff-posn to-buf-type 'beg n ctrl-buf)) 3000 (ediff-get-diff-posn to-buf-type 'beg n ctrl-buf))
2740 (setq reg-to-delete-end 3001 (setq reg-to-delete-end
2741 (ediff-get-diff-posn to-buf-type 'end n ctrl-buf)) 3002 (ediff-get-diff-posn to-buf-type 'end n ctrl-buf))
2742 (setq reg-to-copy (emerge-eval-in-buffer 3003 (setq reg-to-copy (ediff-eval-in-buffer
2743 from-buf 3004 from-buf
2744 (buffer-substring (ediff-get-diff-posn 3005 (buffer-substring (ediff-get-diff-posn
2745 from-buf-type 'beg n ctrl-buf) 3006 from-buf-type 'beg n ctrl-buf)
2746 (ediff-get-diff-posn 3007 (ediff-get-diff-posn
2747 from-buf-type 'end n ctrl-buf)))) 3008 from-buf-type 'end n ctrl-buf))))
2748 (setq reg-to-delete (emerge-eval-in-buffer 3009 (setq reg-to-delete (ediff-eval-in-buffer
2749 to-buf 3010 to-buf
2750 (buffer-substring reg-to-delete-beg 3011 (buffer-substring reg-to-delete-beg
2751 reg-to-delete-end))) 3012 reg-to-delete-end)))
@@ -2762,7 +3023,7 @@ Otherwise, copy the difference given by `ediff-current-difference'."
2762 (if (ediff-test-save-region n to-buf-type) 3023 (if (ediff-test-save-region n to-buf-type)
2763 (condition-case conds 3024 (condition-case conds
2764 (let (inhibit-read-only) 3025 (let (inhibit-read-only)
2765 (emerge-eval-in-buffer 3026 (ediff-eval-in-buffer
2766 to-buf 3027 to-buf
2767 ;; to prevent flags from interfering if buffer is writable 3028 ;; to prevent flags from interfering if buffer is writable
2768 (setq inhibit-read-only (null buffer-read-only)) 3029 (setq inhibit-read-only (null buffer-read-only))
@@ -2848,7 +3109,7 @@ convenience."
2848 (setq ediff-disturbed-overlays nil) ;; clear before use 3109 (setq ediff-disturbed-overlays nil) ;; clear before use
2849 3110
2850 (condition-case conds 3111 (condition-case conds
2851 (emerge-eval-in-buffer 3112 (ediff-eval-in-buffer
2852 buf 3113 buf
2853 (let ((inhibit-read-only (null buffer-read-only)) 3114 (let ((inhibit-read-only (null buffer-read-only))
2854 (before-change-function nil)) 3115 (before-change-function nil))
@@ -2890,6 +3151,101 @@ ARG is a prefix argument. If ARG is nil, restore current-difference."
2890 (ediff-pop-diff ediff-current-difference 3151 (ediff-pop-diff ediff-current-difference
2891 (ediff-char-to-buftype last-command-char)) 3152 (ediff-char-to-buftype last-command-char))
2892 (ediff-recenter 'no-rehighlight)) 3153 (ediff-recenter 'no-rehighlight))
3154
3155(defun ediff-toggle-regexp-match ()
3156 "Focus on difference regions that match a regexp or hide those diffs."
3157 (interactive)
3158 (let (regexp-A regexp-B)
3159 (cond
3160 ((or (and (eq ediff-skip-diff-region-function 'ediff-focus-on-regexp-matches)
3161 (eq last-command-char ?f))
3162 (and (eq ediff-skip-diff-region-function 'ediff-hide-regexp-matches)
3163 (eq last-command-char ?h)))
3164 (message "Show all difference regions.")
3165 (setq ediff-skip-diff-region-function 'ediff-show-all-diffs))
3166 ((eq last-command-char ?h)
3167 (setq ediff-skip-diff-region-function 'ediff-hide-regexp-matches
3168 regexp-A
3169 (read-string
3170 (format
3171 "Ignore A-regions matching this regexp (default \"%s\"): "
3172 (regexp-quote ediff-regexp-hide-A)))
3173 regexp-B
3174 (read-string
3175 (format
3176 "Ignore B-regions matching this regexp (default \"%s\"): "
3177 (regexp-quote ediff-regexp-hide-B))))
3178 (message "Hide difference regions matching regexp.")
3179 (or (string= regexp-A "") (setq ediff-regexp-hide-A regexp-A))
3180 (or (string= regexp-B "") (setq ediff-regexp-hide-B regexp-B)))
3181 ((eq last-command-char ?f)
3182 (setq ediff-skip-diff-region-function 'ediff-focus-on-regexp-matches
3183 regexp-A
3184 (read-string
3185 (format
3186 "Focus on A-regions matching this regexp (default \"%s\"): "
3187 (regexp-quote ediff-regexp-focus-A)))
3188 regexp-B
3189 (read-string
3190 (format
3191 "Focus on B-regions matching this regexp (default \"%s\"): "
3192 (regexp-quote ediff-regexp-focus-B))))
3193 (message "Focus on difference regions matching regexp.")
3194 (or (string= regexp-A "") (setq ediff-regexp-focus-A regexp-A))
3195 (or (string= regexp-B "") (setq ediff-regexp-focus-B regexp-B))))))
3196
3197(defun ediff-show-all-diffs (n)
3198 "Don't skip difference regions."
3199 nil)
3200
3201(defun ediff-focus-on-regexp-matches (n)
3202 "Focus on diffs that match regexp `ediff-regexp-focus-A/B'.
3203Regions to be ignored according to this function are those where
3204buf A region doesn't match `ediff-regexp-focus-A' and buf B region
3205doesn't match `ediff-regexp-focus-B'.
3206This function should return nil for regions not to be ignored and t for
3207regions to be ignored."
3208 (if (and (>= n 0) (< n ediff-number-of-differences))
3209 (let* ((ctl-buf ediff-control-buffer)
3210 (reg-A-match (ediff-eval-in-buffer
3211 ediff-A-buffer
3212 (goto-char (ediff-get-diff-posn 'A 'beg n ctl-buf))
3213 (re-search-forward
3214 ediff-regexp-focus-A
3215 (ediff-get-diff-posn 'A 'end n ctl-buf)
3216 t)))
3217 (reg-B-match (ediff-eval-in-buffer
3218 ediff-B-buffer
3219 (goto-char (ediff-get-diff-posn 'B 'beg n ctl-buf))
3220 (re-search-forward
3221 ediff-regexp-focus-B
3222 (ediff-get-diff-posn 'B 'end n ctl-buf)
3223 t))))
3224 (not (and reg-A-match reg-B-match)))))
3225
3226(defun ediff-hide-regexp-matches (n)
3227 "Hide diffs that match regexp `ediff-regexp-hide-A/B'.
3228Regions to be ignored are those where buf A region matches
3229`ediff-regexp-hide-A' and buf B region matches `ediff-regexp-hide-B'.
3230This function returns nil for regions not to be ignored and t for regions
3231to be ignored."
3232 (if (and (>= n 0) (< n ediff-number-of-differences))
3233 (let* ((ctl-buf ediff-control-buffer)
3234 (reg-A-match (ediff-eval-in-buffer
3235 ediff-A-buffer
3236 (goto-char (ediff-get-diff-posn 'A 'beg n ctl-buf))
3237 (re-search-forward
3238 ediff-regexp-hide-A
3239 (ediff-get-diff-posn 'A 'end n ctl-buf)
3240 t)))
3241 (reg-B-match (ediff-eval-in-buffer
3242 ediff-B-buffer
3243 (goto-char (ediff-get-diff-posn 'B 'beg n ctl-buf))
3244 (re-search-forward
3245 ediff-regexp-hide-B
3246 (ediff-get-diff-posn 'B 'end n ctl-buf)
3247 t))))
3248 (and reg-A-match reg-B-match))))
2893 3249
2894 3250
2895;;; Quitting, suspending, etc. 3251;;; Quitting, suspending, etc.
@@ -2916,24 +3272,29 @@ flags of the compared file buffers, kills Ediff buffers for this session
2916 3272
2917 ;; restore buffer mode line id's in buffer-A/B 3273 ;; restore buffer mode line id's in buffer-A/B
2918 (let ((control-buffer ediff-control-buffer)) 3274 (let ((control-buffer ediff-control-buffer))
2919 (emerge-eval-in-buffer 3275 (condition-case nil
2920 ediff-A-buffer 3276 (ediff-eval-in-buffer
2921 (setq before-change-function nil) 3277 ediff-A-buffer
2922 (setq ediff-this-buffer-control-sessions 3278 (setq before-change-function nil)
2923 (delq control-buffer ediff-this-buffer-control-sessions)) 3279 (setq ediff-this-buffer-control-sessions
2924 (if (null ediff-this-buffer-control-sessions) 3280 (delq control-buffer ediff-this-buffer-control-sessions))
2925 (setq local-write-file-hooks 3281 (if (null ediff-this-buffer-control-sessions)
2926 (delq 'ediff-block-write-file local-write-file-hooks))) 3282 (setq local-write-file-hooks
2927 (kill-local-variable 'mode-line-buffer-identification)) 3283 (delq 'ediff-block-write-file local-write-file-hooks)))
2928 (emerge-eval-in-buffer 3284 (kill-local-variable 'mode-line-buffer-identification))
2929 ediff-B-buffer 3285 (error))
2930 (setq ediff-this-buffer-control-sessions 3286
2931 (delq control-buffer ediff-this-buffer-control-sessions)) 3287 (condition-case nil
2932 (if (null ediff-this-buffer-control-sessions) 3288 (ediff-eval-in-buffer
2933 (setq local-write-file-hooks 3289 ediff-B-buffer
2934 (delq 'ediff-block-write-file local-write-file-hooks))) 3290 (setq ediff-this-buffer-control-sessions
2935 (setq before-change-function nil) 3291 (delq control-buffer ediff-this-buffer-control-sessions))
2936 (kill-local-variable 'mode-line-buffer-identification))) 3292 (if (null ediff-this-buffer-control-sessions)
3293 (setq local-write-file-hooks
3294 (delq 'ediff-block-write-file local-write-file-hooks)))
3295 (setq before-change-function nil)
3296 (kill-local-variable 'mode-line-buffer-identification))
3297 (error)))
2937 3298
2938 (run-hooks 'ediff-quit-hooks)) 3299 (run-hooks 'ediff-quit-hooks))
2939 3300
@@ -2954,9 +3315,21 @@ flags of the compared file buffers, kills Ediff buffers for this session
2954 (ediff-kill-buffer-carefully ediff-control-buffer) 3315 (ediff-kill-buffer-carefully ediff-control-buffer)
2955 (ediff-kill-buffer-carefully ediff-patch-diagnostics) 3316 (ediff-kill-buffer-carefully ediff-patch-diagnostics)
2956 (delete-other-windows) 3317 (delete-other-windows)
2957 (switch-to-buffer buff-B) 3318 ;; display only if not visible
2958 (split-window-vertically) 3319
2959 (switch-to-buffer buff-A))) 3320 (condition-case nil
3321 (or (get-buffer-window buff-B t)
3322 (switch-to-buffer buff-B))
3323 (error))
3324 (condition-case nil
3325 (or (get-buffer-window buff-A t)
3326 (progn
3327 (if (get-buffer-window buff-B)
3328 (split-window-vertically))
3329 (switch-to-buffer buff-A)))
3330 (error))
3331 (message "")
3332 ))
2960 3333
2961;; The default way of suspending Ediff. 3334;; The default way of suspending Ediff.
2962;; Buries Ediff buffers, kills all windows. 3335;; Buries Ediff buffers, kills all windows.
@@ -2979,46 +3352,65 @@ flags of the compared file buffers, kills Ediff buffers for this session
2979 3352
2980(defun ediff-suspend () 3353(defun ediff-suspend ()
2981 "Suspend Ediff. 3354 "Suspend Ediff.
2982To resume, switch to the appropriate `*ediff-control*' 3355To resume, switch to the appropriate `Ediff Control Panel'
2983buffer and then type \\[ediff-recenter]. Ediff will automatically set 3356buffer and then type \\[ediff-recenter]. Ediff will automatically set
2984up an appropriate window config." 3357up an appropriate window config."
2985 (interactive) 3358 (interactive)
2986 (let ((key (substitute-command-keys "\\[ediff-recenter]"))) 3359 (let ((key (substitute-command-keys "\\[ediff-recenter]")))
2987 (run-hooks 'ediff-suspend-hooks) 3360 (run-hooks 'ediff-suspend-hooks)
2988 (message 3361 (message
2989 "To resume Ediff, switch to *ediff-control* and hit '%S'" key))) 3362 "To resume Ediff, switch to Ediff Control Panel and hit '%S'" key)))
2990 3363
2991 3364
2992(defun ediff-file-names () 3365(defun ediff-status-info ()
2993 "Show the names of the buffers or files being operated on by Ediff. 3366 "Show the names of the buffers or files being operated on by Ediff.
2994Hit \\[ediff-recenter] to reset the windows afterward." 3367Hit \\[ediff-recenter] to reset the windows afterward."
2995 (interactive) 3368 (interactive)
2996 (with-output-to-temp-buffer "*Help*" 3369 (with-output-to-temp-buffer " *ediff-info*"
2997 (emerge-eval-in-buffer ediff-A-buffer 3370 (princ (format "Ediff version: %s of %s\n\n"
3371 ediff-version ediff-date))
3372 (ediff-eval-in-buffer ediff-A-buffer
2998 (if buffer-file-name 3373 (if buffer-file-name
2999 (princ 3374 (princ
3000 (format "File A is: %s\n" buffer-file-name)) 3375 (format "File A is: %s\n" buffer-file-name))
3001 (princ 3376 (princ
3002 (format "Buffer A is: %s\n" (buffer-name))))) 3377 (format "Buffer A is: %s\n" (buffer-name)))))
3003 (emerge-eval-in-buffer ediff-B-buffer 3378 (ediff-eval-in-buffer ediff-B-buffer
3004 (if buffer-file-name 3379 (if buffer-file-name
3005 (princ 3380 (princ
3006 (format "File B is: %s\n" buffer-file-name)) 3381 (format "File B is: %s\n" buffer-file-name))
3007 (princ 3382 (princ
3008 (format "Buffer B is: %s\n" (buffer-name))))) 3383 (format "Buffer B is: %s\n" (buffer-name)))))
3009 )) 3384
3010 3385 (let* ((A-line (ediff-eval-in-buffer ediff-A-buffer
3011
3012
3013(defun ediff-line-numbers ()
3014 "Display the current line numbers.
3015This function displays the line numbers of the points in the A, B."
3016 (interactive)
3017 (let* ((A-line (emerge-eval-in-buffer ediff-A-buffer
3018 (count-lines (point-min) (point)))) 3386 (count-lines (point-min) (point))))
3019 (B-line (emerge-eval-in-buffer ediff-B-buffer 3387 (B-line (ediff-eval-in-buffer ediff-B-buffer
3020 (count-lines (point-min) (point))))) 3388 (count-lines (point-min) (point)))))
3021 (message "At lines: A = %d, B = %d" A-line B-line))) 3389 (princ (format "\nPoint position in buffer A = %d\n" A-line))
3390 (princ (format "Point position in buffer B = %d\n" B-line)))
3391
3392 (princ (format "\nCurrent difference number = %d\n"
3393 (1+ ediff-current-difference)))
3394
3395 (cond ((eq ediff-skip-diff-region-function 'ediff-show-all-diffs)
3396 (princ "\nSelective browsing is not in effect.\n"))
3397 ((eq ediff-skip-diff-region-function 'ediff-hide-regexp-matches)
3398 (princ
3399 "\nSelective browsing is in effect. Ignoring diff regions that:")
3400 (princ
3401 (format "\n match `%s' in buffer A and `%s' in buffer B\n"
3402 ediff-regexp-hide-A ediff-regexp-hide-B)))
3403 ((eq ediff-skip-diff-region-function 'ediff-focus-on-regexp-matches)
3404 (princ
3405 "\nSelective browsing is in effect. Focus on diff regions that:")
3406 (princ
3407 (format "\n match `%s' in buffer A and `%s' in buffer B\n"
3408 ediff-regexp-focus-A ediff-regexp-focus-B))))
3409
3410 (princ "\nBug fixes to: Michael Kifer <kifer@cs.sunysb.edu>\n")
3411 (princ "Gripes to: /dev/null <dev@null.gov>\n")
3412 ))
3413
3022 3414
3023 3415
3024;;; Support routines 3416;;; Support routines
@@ -3026,7 +3418,9 @@ This function displays the line numbers of the points in the A, B."
3026;; Select a difference by placing the ASCII flags around the appropriate 3418;; Select a difference by placing the ASCII flags around the appropriate
3027;; group of lines in the A, B buffers 3419;; group of lines in the A, B buffers
3028(defun ediff-select-difference (n) 3420(defun ediff-select-difference (n)
3029 (if (and (>= n 0) (< n ediff-number-of-differences)) 3421 (if (and (ediff-buffer-live-p ediff-A-buffer)
3422 (ediff-buffer-live-p ediff-B-buffer)
3423 (>= n 0) (< n ediff-number-of-differences))
3030 (progn 3424 (progn
3031 (ediff-remember-buffer-characteristics) 3425 (ediff-remember-buffer-characteristics)
3032 (if (and window-system ediff-want-faces) 3426 (if (and window-system ediff-want-faces)
@@ -3097,7 +3491,7 @@ This function displays the line numbers of the points in the A, B."
3097;; don't recenter buffers after selecting/unselecting. 3491;; don't recenter buffers after selecting/unselecting.
3098;; 3492;;
3099;; Don't use `ediff-select-difference' and `ediff-unselect-difference' 3493;; Don't use `ediff-select-difference' and `ediff-unselect-difference'
3100;; directly,;; since this will screw up the undo info in the presence of 3494;; directly, since this will screw up the undo info in the presence of
3101;; ASCII flags. 3495;; ASCII flags.
3102;; Instead, use `ediff-unselect-and-select-difference' with appropriate 3496;; Instead, use `ediff-unselect-and-select-difference' with appropriate
3103;; flags. 3497;; flags.
@@ -3114,15 +3508,18 @@ This function displays the line numbers of the points in the A, B."
3114 (or no-recenter 3508 (or no-recenter
3115 (ediff-recenter 'no-rehighlight))) 3509 (ediff-recenter 'no-rehighlight)))
3116 3510
3117 (emerge-eval-in-buffer 3511 (if (and (ediff-buffer-live-p ediff-A-buffer)
3118 ediff-A-buffer 3512 (ediff-buffer-live-p ediff-B-buffer))
3119 (setq buf-A-undo buffer-undo-list)) 3513 (progn
3120 (emerge-eval-in-buffer 3514 (ediff-eval-in-buffer
3121 ediff-B-buffer 3515 ediff-A-buffer
3122 (setq buf-B-undo buffer-undo-list)) 3516 (setq buf-A-undo buffer-undo-list))
3517 (ediff-eval-in-buffer
3518 ediff-B-buffer
3519 (setq buf-B-undo buffer-undo-list))
3123 3520
3124 (buffer-disable-undo ediff-A-buffer) 3521 (buffer-disable-undo ediff-A-buffer)
3125 (buffer-disable-undo ediff-B-buffer) 3522 (buffer-disable-undo ediff-B-buffer)))
3126 3523
3127 (unwind-protect ;; we don't want to lose undo info due to error 3524 (unwind-protect ;; we don't want to lose undo info due to error
3128 (progn 3525 (progn
@@ -3130,11 +3527,11 @@ This function displays the line numbers of the points in the A, B."
3130 (ediff-unselect-difference ediff-current-difference)) 3527 (ediff-unselect-difference ediff-current-difference))
3131 3528
3132 ;; Auto-save buffers while Ediff flags are temporarily removed. 3529 ;; Auto-save buffers while Ediff flags are temporarily removed.
3133 (emerge-eval-in-buffer 3530 (ediff-eval-in-buffer
3134 ediff-A-buffer 3531 ediff-A-buffer
3135 (if buf-A-modified 3532 (if buf-A-modified
3136 (do-auto-save))) 3533 (do-auto-save)))
3137 (emerge-eval-in-buffer 3534 (ediff-eval-in-buffer
3138 ediff-B-buffer 3535 ediff-B-buffer
3139 (if buf-B-modified 3536 (if buf-B-modified
3140 (do-auto-save))) 3537 (do-auto-save)))
@@ -3144,36 +3541,35 @@ This function displays the line numbers of the points in the A, B."
3144 (setq ediff-current-difference n) 3541 (setq ediff-current-difference n)
3145 ) ;; end protected section 3542 ) ;; end protected section
3146 3543
3147 (emerge-eval-in-buffer 3544 (ediff-eval-in-buffer
3148 control-buf 3545 control-buf
3149 (ediff-refresh-mode-line) 3546 (ediff-refresh-mode-line)
3547 ;; restore undo and buffer-modified info
3548 (ediff-eval-in-buffer
3549 ediff-A-buffer
3550 (set-buffer-modified-p buf-A-modified)
3551 (setq buffer-undo-list buf-A-undo)))
3150 3552
3151 ;; restore undo and buffer-modified info 3553 (ediff-eval-in-buffer
3152 (emerge-eval-in-buffer
3153 ediff-A-buffer
3154 (set-buffer-modified-p buf-A-modified)
3155 (setq buffer-undo-list buf-A-undo)))
3156
3157 (emerge-eval-in-buffer
3158 control-buf 3554 control-buf
3159 (emerge-eval-in-buffer 3555 (ediff-eval-in-buffer
3160 ediff-B-buffer 3556 ediff-B-buffer
3161 (set-buffer-modified-p buf-B-modified) 3557 (set-buffer-modified-p buf-B-modified)
3162 (setq buffer-undo-list buf-B-undo)) 3558 (setq buffer-undo-list buf-B-undo)))
3163 )))) 3559 )))
3164 3560
3165;; Revise the mode line to display which difference we have selected 3561;; Revise the mode line to display which difference we have selected
3166 3562
3167(defun ediff-refresh-mode-line () 3563(defun ediff-refresh-mode-line ()
3168 (setq mode-line-buffer-identification 3564 (setq mode-line-buffer-identification
3169 (cond ((< ediff-current-difference 0) 3565 (cond ((< ediff-current-difference 0)
3170 (list (format "Ediff: %%b At start: %d diffs" 3566 (list (format "%%b: At start of %d diffs"
3171 ediff-number-of-differences))) 3567 ediff-number-of-differences)))
3172 ((>= ediff-current-difference ediff-number-of-differences) 3568 ((>= ediff-current-difference ediff-number-of-differences)
3173 (list (format "Ediff: %%b At end: %d diffs" 3569 (list (format "%%b: At end of %d diffs"
3174 ediff-number-of-differences))) 3570 ediff-number-of-differences)))
3175 (t 3571 (t
3176 (list (format "Ediff: %%b diff %d of %d" 3572 (list (format "%%b: diff %d of %d"
3177 (1+ ediff-current-difference) 3573 (1+ ediff-current-difference)
3178 ediff-number-of-differences))))) 3574 ediff-number-of-differences)))))
3179 ;; Force mode-line redisplay 3575 ;; Force mode-line redisplay
@@ -3187,56 +3583,50 @@ This function displays the line numbers of the points in the A, B."
3187 (< ediff-current-difference ediff-number-of-differences))) 3583 (< ediff-current-difference ediff-number-of-differences)))
3188 (error "No difference selected"))) 3584 (error "No difference selected")))
3189 3585
3190(defun ediff-read-file-name (prompt default-dir default-file A-file) 3586(defun ediff-read-file-name (prompt default-dir default-file)
3191; This is a modified version of a similar function in `emerge.el'. 3587; This is a modified version of a similar function in `emerge.el'.
3192; PROMPT should not have trailing ': ', so that it can be modified 3588; PROMPT should not have trailing ': ', so that it can be modified
3193; according to context. 3589; according to context.
3194; If both A-FILE and default-dir are set, the file constructed our of
3195; default-dir and the non-directory part of A-FILE is used as default and as
3196; initial input.
3197; If A-FILE is set (but default-dir is not), it is used as default and
3198; initial input.
3199; If default-file is set, it should be used as the default value. 3590; If default-file is set, it should be used as the default value.
3200; If default-dir is non-nil, use it as the default directory. 3591; If default-dir is non-nil, use it as the default directory.
3201; Otherwise, use the value in Emacs's var default-directory. 3592; Otherwise, use the value of Emacs' variable `default-directory.'
3593
3594 ;; hack default-dir if it is not set
3595 (setq default-dir
3596 (file-name-as-directory
3597 (abbreviate-file-name
3598 (expand-file-name (or default-dir
3599 (and default-file
3600 (file-name-directory default-file))
3601 default-directory)))))
3602
3603 ;; strip the directory from default-file
3604 (if default-file
3605 (setq default-file (file-name-nondirectory default-file)))
3606
3202 (let (f) 3607 (let (f)
3203 (setq f 3608 (setq f (expand-file-name
3204 (cond 3609 (read-file-name
3205 ((and A-file default-dir) 3610 (format "%s%s: "
3206 (read-file-name (format "%s (default %s%s): " 3611 prompt
3207 prompt 3612 (if default-file
3208 (abbreviate-file-name 3613 (concat " (default " default-file ")")
3209 (expand-file-name default-dir)) 3614 ""))
3210 (file-name-nondirectory A-file)) 3615 default-dir
3211 (expand-file-name default-dir) 3616 default-file
3212 (concat (expand-file-name default-dir) 3617 'confirm
3213 (file-name-nondirectory A-file)) 3618 default-file
3214 'confirm (file-name-nondirectory A-file))) 3619 )
3215 (A-file 3620 default-dir
3216 (read-file-name (format "%s (default %s): " 3621 ))
3217 prompt (file-name-nondirectory A-file))
3218 (expand-file-name (file-name-directory A-file))
3219 A-file
3220 'confirm (file-name-nondirectory A-file)))
3221 ;; If there is a default file, but no A-file, use it.
3222 (default-file
3223 (read-file-name (format "%s (default %s): " prompt default-file)
3224 default-dir;; if nil then default-directory.
3225 nil 'confirm))
3226 (t
3227 (read-file-name (concat prompt ": ")
3228 default-dir;; if nil then default-directory.
3229 nil 'confirm))))
3230 ;; If user enters a directory name, expand the default file in that 3622 ;; If user enters a directory name, expand the default file in that
3231 ;; directory. This allows the user to enter a directory name for the 3623 ;; directory. This allows the user to enter a directory name for the
3232 ;; B-file and diff against the A-file in that directory instead of a DIRED 3624 ;; B-file and diff against the default-file in that directory instead
3233 ;; listing! 3625 ;; of a DIRED listing!
3234 (if (and (file-directory-p f) 3626 (if (and (file-directory-p f) default-file)
3235 (or A-file default-file))
3236 (setq f (expand-file-name 3627 (setq f (expand-file-name
3237 (file-name-nondirectory (or A-file default-file)) f))) 3628 (file-name-nondirectory default-file) f)))
3238 f)) 3629 f))
3239
3240 3630
3241;; If `prefix' is given, then it is used as a prefix for the temp file 3631;; If `prefix' is given, then it is used as a prefix for the temp file
3242;; name. Otherwise, `.buffer-name' is used. If `file' is given, use this 3632;; name. Otherwise, `.buffer-name' is used. If `file' is given, use this
@@ -3248,8 +3638,7 @@ This function displays the line numbers of the points in the A, B."
3248 (or prefix 3638 (or prefix
3249 (format 3639 (format
3250 ".%s" 3640 ".%s"
3251 (file-name-nondirectory 3641 "buf")))))))
3252 (buffer-name)))))))))
3253 ;; create the file 3642 ;; create the file
3254 (write-region (point-min) (point-max) f nil 'no-message) 3643 (write-region (point-min) (point-max) f nil 'no-message)
3255 (set-file-modes f ediff-temp-file-mode) 3644 (set-file-modes f ediff-temp-file-mode)
@@ -3267,19 +3656,56 @@ This function displays the line numbers of the points in the A, B."
3267 (setq limit (1+ (match-end 0)))))) 3656 (setq limit (1+ (match-end 0))))))
3268 str) 3657 str)
3269 3658
3659;; Make sure the current buffer (for a file) has the same contents as the
3660;; file on disk, and attempt to remedy the situation if not.
3661;; Signal an error if we can't make them the same, or the user doesn't want
3662;; to do what is necessary to make them the same.
3663;; If file has file handlers (indicated by the optional arg), then we
3664;; offer to instead of saving. This is one difference with Emerge.
3665;; Another is that we always offer to revert obsolete files, whether they
3666;; are modified or not.
3667(defun ediff-verify-file-buffer (&optional file-magic)
3668 ;; First check if the file has been modified since the buffer visited it.
3669 (if (verify-visited-file-modtime (current-buffer))
3670 (if (buffer-modified-p)
3671 ;; If buffer is not obsolete and is modified, offer to save
3672 (if (yes-or-no-p
3673 (format "Buffer out of sync with visited file. %s file %s? "
3674 (if file-magic "Revert" "Save")
3675 buffer-file-name))
3676 (if (not file-magic)
3677 (save-buffer)
3678 ;; for some reason, file-name-handlers append instead of
3679 ;; replacing, so we have to erase first.
3680 (erase-buffer)
3681 (revert-buffer t t))
3682 (error "Buffer out of sync for file %s" buffer-file-name))
3683 ;; If buffer is not obsolete and is not modified, do nothing
3684 nil)
3685 ;; If buffer is obsolete, offer to revert
3686 (if (yes-or-no-p
3687 (format "Buffer out of sync with visited file. Revert file %s? "
3688 buffer-file-name))
3689 (progn
3690 (if file-magic
3691 (erase-buffer))
3692 (revert-buffer t t))
3693 (error "Buffer out of sync for file %s" buffer-file-name))))
3694
3270 3695
3271(defun ediff-block-write-file () 3696(defun ediff-block-write-file ()
3272 "Prevent writing files A and B directly." 3697 "Prevent writing files A and B directly."
3273 (if (ediff-check-for-ascii-flags) 3698 (if (ediff-check-for-ascii-flags)
3274 (error "Use 'wa' and 'wb' to save buffs A/B (first switch back to *ediff-control*."))) 3699 (error "Type 'wa' and 'wb' in Ediff Control Panel to save buffs A/B.")))
3275 3700
3276(defun ediff-check-for-ascii-flags () 3701(defun ediff-check-for-ascii-flags ()
3277 (eval 3702 (eval
3278 (cons 'or 3703 (cons 'or
3279 (mapcar (function (lambda (buf) 3704 (mapcar (function (lambda (buf)
3280 (emerge-eval-in-buffer 3705 (if (ediff-buffer-live-p buf)
3281 buf 3706 (ediff-eval-in-buffer
3282 (eq ediff-highlighting-style 'ascii)))) 3707 buf
3708 (eq ediff-highlighting-style 'ascii)))))
3283 ediff-this-buffer-control-sessions)))) 3709 ediff-this-buffer-control-sessions))))
3284 3710
3285(defun ediff-insert-in-front (overl beg end) 3711(defun ediff-insert-in-front (overl beg end)
@@ -3337,7 +3763,7 @@ them before they disappear."
3337 (ediff-unselect-and-select-difference ediff-current-difference 3763 (ediff-unselect-and-select-difference ediff-current-difference
3338 'unselect-only) 3764 'unselect-only)
3339 (unwind-protect 3765 (unwind-protect
3340 (emerge-eval-in-buffer 3766 (ediff-eval-in-buffer
3341 (if (eq last-command-char ?a) ediff-A-buffer ediff-B-buffer) 3767 (if (eq last-command-char ?a) ediff-A-buffer ediff-B-buffer)
3342 ;; temporarily remove writing block 3768 ;; temporarily remove writing block
3343 (setq hooks (delq 'ediff-block-write-file hooks)) 3769 (setq hooks (delq 'ediff-block-write-file hooks))
@@ -3353,7 +3779,7 @@ them before they disappear."
3353;; of read-only flags. 3779;; of read-only flags.
3354(defun ediff-remove-flags-from-buffer (buffer before-posn after-posn 3780(defun ediff-remove-flags-from-buffer (buffer before-posn after-posn
3355 before-flag after-flag) 3781 before-flag after-flag)
3356 (emerge-eval-in-buffer 3782 (ediff-eval-in-buffer
3357 buffer 3783 buffer
3358 (let ((buffer-read-only nil) 3784 (let ((buffer-read-only nil)
3359 (before-change-function nil) 3785 (before-change-function nil)
@@ -3374,7 +3800,7 @@ them before they disappear."
3374 (message "Trouble removing ASCII flag")) 3800 (message "Trouble removing ASCII flag"))
3375 (if (ediff-if-lucid) 3801 (if (ediff-if-lucid)
3376 (ediff-adjust-disturbed-extents-lucid (point))) 3802 (ediff-adjust-disturbed-extents-lucid (point)))
3377 3803
3378 (if (ediff-if-lucid) 3804 (if (ediff-if-lucid)
3379 (ediff-collect-extents-lucid (point))) 3805 (ediff-collect-extents-lucid (point)))
3380 (goto-char after-posn) 3806 (goto-char after-posn)
@@ -3391,7 +3817,7 @@ them before they disappear."
3391 3817
3392;; This is a modified `emerge-place-flags-in-buffer'. 3818;; This is a modified `emerge-place-flags-in-buffer'.
3393(defun ediff-place-flags-in-buffer (buf-type buffer ctl-buffer difference) 3819(defun ediff-place-flags-in-buffer (buf-type buffer ctl-buffer difference)
3394 (emerge-eval-in-buffer 3820 (ediff-eval-in-buffer
3395 buffer 3821 buffer
3396 (ediff-place-flags-in-buffer1 buf-type ctl-buffer difference))) 3822 (ediff-place-flags-in-buffer1 buf-type ctl-buffer difference)))
3397 3823
@@ -3413,7 +3839,7 @@ them before they disappear."
3413 (goto-char before) 3839 (goto-char before)
3414 (setq beg-of-line (bolp)) 3840 (setq beg-of-line (bolp))
3415 3841
3416 (setq flag (emerge-eval-in-buffer 3842 (setq flag (ediff-eval-in-buffer
3417 ctl-buffer 3843 ctl-buffer
3418 (if beg-of-line 3844 (if beg-of-line
3419 (set before-flag-name ediff-before-flag-bol) 3845 (set before-flag-name ediff-before-flag-bol)
@@ -3433,7 +3859,7 @@ them before they disappear."
3433 (goto-char after) 3859 (goto-char after)
3434 (setq beg-of-line (bolp)) 3860 (setq beg-of-line (bolp))
3435 3861
3436 (setq flag (emerge-eval-in-buffer 3862 (setq flag (ediff-eval-in-buffer
3437 ctl-buffer 3863 ctl-buffer
3438 (if beg-of-line 3864 (if beg-of-line
3439 (set after-flag-name ediff-after-flag-bol) 3865 (set after-flag-name ediff-after-flag-bol)
@@ -3462,7 +3888,7 @@ buffer."
3462 (or control-buf 3888 (or control-buf
3463 (setq control-buf (current-buffer))) 3889 (setq control-buf (current-buffer)))
3464 3890
3465 (emerge-eval-in-buffer 3891 (ediff-eval-in-buffer
3466 control-buf 3892 control-buf
3467 (or n (setq n ediff-current-difference)) 3893 (or n (setq n ediff-current-difference))
3468 (if (or (< n 0) (>= n ediff-number-of-differences)) 3894 (if (or (< n 0) (>= n ediff-number-of-differences))
@@ -3486,8 +3912,8 @@ buffer."
3486;; These would highlight differences under X 3912;; These would highlight differences under X
3487(defun ediff-highlight-diff (n) 3913(defun ediff-highlight-diff (n)
3488 "Put face on diff N. Invoked for X displays only." 3914 "Put face on diff N. Invoked for X displays only."
3489 (let* ((last-A (emerge-eval-in-buffer ediff-A-buffer (point-max))) 3915 (let* ((last-A (ediff-eval-in-buffer ediff-A-buffer (point-max)))
3490 (last-B (emerge-eval-in-buffer ediff-B-buffer (point-max))) 3916 (last-B (ediff-eval-in-buffer ediff-B-buffer (point-max)))
3491 (begin-A (ediff-get-diff-posn 'A 'beg n)) 3917 (begin-A (ediff-get-diff-posn 'A 'beg n))
3492 (end-A (ediff-get-diff-posn 'A 'end n)) 3918 (end-A (ediff-get-diff-posn 'A 'end n))
3493 (xtraA (if (equal begin-A end-A) 1 0)) 3919 (xtraA (if (equal begin-A end-A) 1 0))
@@ -3595,26 +4021,25 @@ buffer."
3595 "Re/unhighlights buffers A and B with all flags from all Ediff sessions. 4021 "Re/unhighlights buffers A and B with all flags from all Ediff sessions.
3596This is usually needed only when a 4022This is usually needed only when a
3597buffer is involved in multiple Ediff sessions." 4023buffer is involved in multiple Ediff sessions."
3598 (let* ((A-sessions (emerge-eval-in-buffer 4024 (let* ((A-sessions (ediff-eval-in-buffer
3599 ediff-A-buffer 4025 ediff-A-buffer
3600 ediff-this-buffer-control-sessions)) 4026 ediff-this-buffer-control-sessions))
3601 (B-sessions (emerge-eval-in-buffer 4027 (B-sessions (ediff-eval-in-buffer
3602 ediff-B-buffer 4028 ediff-B-buffer
3603 ediff-this-buffer-control-sessions)) 4029 ediff-this-buffer-control-sessions))
3604 (sessions (ediff-union A-sessions B-sessions)) 4030 (sessions (ediff-union A-sessions B-sessions))
3605 (flag (if (eq action 'remove) 'unselect-only 'select-only))) 4031 (flag (if (eq action 'remove) 'unselect-only 'select-only)))
3606 4032
3607 (mapcar (function (lambda (buf) 4033 (mapcar (function (lambda (buf)
3608 (if (ediff-buffer-live-p buf) 4034 (ediff-eval-in-buffer
3609 (emerge-eval-in-buffer 4035 buf
3610 buf 4036 (or (if (eq action 'insert)
3611 (or (if (eq action 'insert)
3612 (memq ediff-highlighting-style '(ascii off)) 4037 (memq ediff-highlighting-style '(ascii off))
3613 (not (eq ediff-highlighting-style 'ascii))) 4038 (not (eq ediff-highlighting-style 'ascii)))
3614 (ediff-unselect-and-select-difference 4039 (ediff-unselect-and-select-difference
3615 ediff-current-difference 4040 ediff-current-difference
3616 flag 'no-recenter)) 4041 flag 'no-recenter))
3617 )))) 4042 )))
3618 sessions))) 4043 sessions)))
3619 4044
3620 4045
@@ -3622,6 +4047,12 @@ buffer is involved in multiple Ediff sessions."
3622;;; Refinement of current diff 4047;;; Refinement of current diff
3623;; Split region along word boundaries. Each word will be on its own line. 4048;; Split region along word boundaries. Each word will be on its own line.
3624;; Output to buffer out-buffer. 4049;; Output to buffer out-buffer.
4050(defun ediff-forward-word ()
4051 "Move point one word forward. Used for splitting diff regions into words.
4052This is the default for `ediff-forward-word-function'."
4053 (or (> (skip-chars-forward ediff-word-1) 0)
4054 (> (skip-chars-forward ediff-word-2) 0)))
4055
3625(defun ediff-wordify (beg end in-buffer out-buffer) 4056(defun ediff-wordify (beg end in-buffer out-buffer)
3626 (let (sv-point string) 4057 (let (sv-point string)
3627 (save-excursion 4058 (save-excursion
@@ -3635,14 +4066,12 @@ buffer is involved in multiple Ediff sessions."
3635 (skip-chars-forward ediff-whitespace) 4066 (skip-chars-forward ediff-whitespace)
3636 (delete-region (point-min) (point)) 4067 (delete-region (point-min) (point))
3637 4068
3638 (while (or (> (skip-chars-forward ediff-word-1) 0) 4069 (while (not (eobp))
3639 (> (skip-chars-forward ediff-word-2) 0)) 4070 (funcall ediff-forward-word-function)
3640
3641 (setq sv-point (point)) 4071 (setq sv-point (point))
3642 (skip-chars-forward ediff-whitespace) 4072 (skip-chars-forward ediff-whitespace)
3643 (delete-region sv-point (point)) 4073 (delete-region sv-point (point))
3644 (insert "\n"))))) 4074 (insert "\n")))))
3645
3646 4075
3647;; `n' is the diff region to work on. 4076;; `n' is the diff region to work on.
3648;; if `flag' is 'noforce then make fine-diffs only if this region's fine 4077;; if `flag' is 'noforce then make fine-diffs only if this region's fine
@@ -3675,21 +4104,21 @@ buffer is involved in multiple Ediff sessions."
3675 ;; recompute fine diffs 4104 ;; recompute fine diffs
3676 (setq ediff-tmp-buffer (get-buffer-create "*ediff-tmp*")) 4105 (setq ediff-tmp-buffer (get-buffer-create "*ediff-tmp*"))
3677 4106
3678 (funcall ediff-wordify-function 4107 (ediff-wordify
3679 (ediff-get-diff-posn 'A 'beg n) 4108 (ediff-get-diff-posn 'A 'beg n)
3680 (ediff-get-diff-posn 'A 'end n) 4109 (ediff-get-diff-posn 'A 'end n)
3681 ediff-A-buffer 4110 ediff-A-buffer
3682 ediff-tmp-buffer) 4111 ediff-tmp-buffer)
3683 (emerge-eval-in-buffer 4112 (ediff-eval-in-buffer
3684 ediff-tmp-buffer 4113 ediff-tmp-buffer
3685 (setq file-A (ediff-make-temp-file ".fine-diffs-A" file-A))) 4114 (setq file-A (ediff-make-temp-file ".fine-diffs-A" file-A)))
3686 4115
3687 (funcall ediff-wordify-function 4116 (ediff-wordify
3688 (ediff-get-diff-posn 'B 'beg n) 4117 (ediff-get-diff-posn 'B 'beg n)
3689 (ediff-get-diff-posn 'B 'end n) 4118 (ediff-get-diff-posn 'B 'end n)
3690 ediff-B-buffer 4119 ediff-B-buffer
3691 ediff-tmp-buffer) 4120 ediff-tmp-buffer)
3692 (emerge-eval-in-buffer 4121 (ediff-eval-in-buffer
3693 ediff-tmp-buffer 4122 ediff-tmp-buffer
3694 (setq file-B (ediff-make-temp-file ".fine-diffs-B" file-B))) 4123 (setq file-B (ediff-make-temp-file ".fine-diffs-B" file-B)))
3695 4124
@@ -3752,8 +4181,8 @@ buffer is involved in multiple Ediff sessions."
3752 a-begin a-end b-begin b-end 4181 a-begin a-end b-begin b-end
3753 a-overlay b-overlay) 4182 a-overlay b-overlay)
3754 4183
3755 (emerge-eval-in-buffer A-buffer (goto-char reg-A-start)) 4184 (ediff-eval-in-buffer A-buffer (goto-char reg-A-start))
3756 (emerge-eval-in-buffer B-buffer (goto-char reg-B-start)) 4185 (ediff-eval-in-buffer B-buffer (goto-char reg-B-start))
3757 4186
3758 (while diff-list 4187 (while diff-list
3759 (setq current-diff (1+ current-diff) 4188 (setq current-diff (1+ current-diff)
@@ -3785,21 +4214,19 @@ buffer is involved in multiple Ediff sessions."
3785 4214
3786;; goto word #n starting at current position in buffer `buf' 4215;; goto word #n starting at current position in buffer `buf'
3787;; For ediff, a word is either a string of a-z,A-Z, incl `-' and `_'; 4216;; For ediff, a word is either a string of a-z,A-Z, incl `-' and `_';
3788;; or a string of other non-blanks. A blank is a \n\t\j 4217;; or a string of other non-blanks. A blank is a \n\t\C-j
3789;; If `flag' is non-nil, goto the end of the n-th word. 4218;; If `flag' is non-nil, goto the end of the n-th word.
3790(defun ediff-goto-word (n buf &optional flag) 4219(defun ediff-goto-word (n buf &optional flag)
3791 (emerge-eval-in-buffer 4220 (ediff-eval-in-buffer
3792 buf 4221 buf
3793 (skip-chars-forward ediff-whitespace) 4222 (skip-chars-forward ediff-whitespace)
3794 (while (> n 1) 4223 (while (> n 1)
3795 (or (> (skip-chars-forward ediff-word-1) 0) 4224 (funcall ediff-forward-word-function)
3796 (> (skip-chars-forward ediff-word-2) 0))
3797 (skip-chars-forward ediff-whitespace) 4225 (skip-chars-forward ediff-whitespace)
3798 (setq n (1- n))) 4226 (setq n (1- n)))
3799 ;(if flag 4227 ;(if flag
3800 (if (and flag (> n 0)) 4228 (if (and flag (> n 0))
3801 (or (> (skip-chars-forward ediff-word-1) 0) 4229 (funcall ediff-forward-word-function))
3802 (> (skip-chars-forward ediff-word-2) 0)))
3803 (point))) 4230 (point)))
3804 4231
3805 4232
@@ -3825,7 +4252,6 @@ avoid loading cl-*."
3825 (setq list1 (cons (car list2) list1))) 4252 (setq list1 (cons (car list2) list1)))
3826 (setq list2 (cdr list2))) 4253 (setq list2 (cdr list2)))
3827 list1))) 4254 list1)))
3828
3829 4255
3830;(defun ediff-debug () 4256;(defun ediff-debug ()
3831; (interactive) 4257; (interactive)
@@ -3866,3 +4292,8 @@ avoid loading cl-*."
3866(provide 'ediff) 4292(provide 'ediff)
3867 4293
3868;;; ediff.el ends here 4294;;; ediff.el ends here
4295
4296
4297
4298
4299