aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1994-09-18 08:52:32 +0000
committerRichard M. Stallman1994-09-18 08:52:32 +0000
commiteaccd4d857910c2a459876be38c4d1d0ba1a1372 (patch)
treee43701ef723d21a3ade466111189eaedeef7d84a
parentbcd40520863a594cacce49e6a9bc682a86cb2032 (diff)
downloademacs-eaccd4d857910c2a459876be38c4d1d0ba1a1372.tar.gz
emacs-eaccd4d857910c2a459876be38c4d1d0ba1a1372.zip
(ediff-submit-report, ediff-revision)
(ediff-find-file-name-handler, vc-ediff-internal, rcs-ediff-internal): New functions. (ediff-version-control-package): New variable. (vc-ediff, rcs-ediff): Functions deleted. (ediff-submit-report): New function. (ediff-toggle-read-only, ediff-patch-file): Check out version controlled files before their buffers are modified. (ediff-local-checkout-flag, ediff-toggle-read-only-function): New variables. (ediff-find-file, ediff-patch-file): Were getting confused by symbolic links. Fixed.
-rw-r--r--lisp/ediff.el583
1 files changed, 389 insertions, 194 deletions
diff --git a/lisp/ediff.el b/lisp/ediff.el
index 88bc230e234..8c8720a0bc5 100644
--- a/lisp/ediff.el
+++ b/lisp/ediff.el
@@ -3,9 +3,12 @@
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.65c 6;; Version: 1.65e
7;; Keywords: comparing, merging, patching, version control. 7;; Keywords: comparing, merging, patching, version control.
8 8
9(defvar ediff-version "1.65e" "The current version of Ediff")
10(defvar ediff-date "September 1, 1994" "Date of last update")
11
9;; This file is part of GNU Emacs. 12;; This file is part of GNU Emacs.
10 13
11;; GNU Emacs is free software; you can redistribute it and/or modify 14;; GNU Emacs is free software; you can redistribute it and/or modify
@@ -69,6 +72,10 @@
69;; ftp.cs.buffalo.edu:pub/Emacs/rcs.tar.Z 72;; ftp.cs.buffalo.edu:pub/Emacs/rcs.tar.Z
70;; ftp.uni-koeln.de:/pub/gnu/emacs/rcs.tar.Z 73;; ftp.uni-koeln.de:/pub/gnu/emacs/rcs.tar.Z
71;; 74;;
75;; To specify which version control package you are using, set the variable
76;; ediff-version-control-package, e.g.,
77;; (setq ediff-version-control-package 'rcs)
78;; The default, is 'vc'.
72 79
73 80
74;; Window configuration: 81;; Window configuration:
@@ -125,25 +132,20 @@
125;;; Remote and Compressed Files 132;;; Remote and Compressed Files
126;; --------------------------- 133;; ---------------------------
127 134
128;; Ediff will work with remote files, compressed files, and, probably, 135;; Ediff will work with remote, compressed, and encrypted files. Ediff
129;; with encrypted files. (I have only tested it with ange-ftp.el, 136;; supports ange-ftp.el, jka-compr.el, uncompress.el and crypt++.el, but
130;; jka-compr.el, and uncompress.el.) This means that you can compare files 137;; it may work with other similar packages as well. This
131;; residing on another machine, or you can apply a patch to a file on 138;; means that you can compare files residing on another machine, or you
132;; another machine (even the patch itself can be a remote file!). This is 139;; can apply a patch to a file on another machine (even the patch itself
133;; provided that you access remote files via the usual find-file command 140;; can be a remote file!).
134;; using the syntax acceptable to ange-ftp (see Emacs Manual).
135;; 141;;
136;; The files to be compared or patched can be compressed or be both 142;; When patching compressed or remote files, Ediff doesn't rename the
137;; compressed and remote. To be able to handle compressed files, you 143;; source file into source-file-name.orig (unlike what `patch' would
138;; should use uncompress.el or jka-compr.el. Ediff is designed so that it 144;; usually do). Instead, the source file retains its name and the result
139;; will interface to these packages. When patching compressed or remote 145;; of applying the patch is placed in a temporary file that has the suffix
140;; files, Ediff doesn't rename the source file into source-file-name.orig 146;; `.patched'. Generally, this applies to files that are handled using
141;; (unlike what `patch' would usually do). Instead, the source file 147;; black magic, such as special file handlers (ange-ftp and some
142;; retains its name and the result of applying the patch is placed in a 148;; compression and encryption packages all use this method).
143;; temporary file that has the suffix `.patched'. Generally, this applies
144;; to files that are handled using black magic, such as special file
145;; handlers (ange-ftp and some compression and encryption packages all
146;; use this method).
147;; 149;;
148;; Regular files are treated by `patch' in the usual manner, i.e., the 150;; Regular files are treated by `patch' in the usual manner, i.e., the
149;; original is renamed into source-name.orig and the result of the patch 151;; original is renamed into source-name.orig and the result of the patch
@@ -156,8 +158,8 @@
156;; 1. Ediff is heavily dependent on the new features of Emacs 19. 158;; 1. Ediff is heavily dependent on the new features of Emacs 19.
157;; It won't run under Emacs 18 at all. 159;; It won't run under Emacs 18 at all.
158;; 2. If running Lucid Emacs, Ediff requires at least version 19.9. 160;; 2. If running Lucid Emacs, Ediff requires at least version 19.9.
159;; 3. The function vc-ediff requires the version of vc.el that comes with 161;; 3. The function ediff-revision requires the version of vc.el that comes
160;; Emacs 19.22 and later. 162;; with Emacs 19.22 and later, or rcs.el version 1.67 or later.
161 163
162 164
163;;; Installation and use: 165;;; Installation and use:
@@ -172,12 +174,7 @@
172;; epatch - alias for ediff-patch-file 174;; epatch - alias for ediff-patch-file
173;; ediff-patch-buffer - patch buffer then compare 175;; ediff-patch-buffer - patch buffer then compare
174;; epatch-buffer - alias for ediff-patch-buffer 176;; epatch-buffer - alias for ediff-patch-buffer
175;; vc-ediff - compare buffer & version 177;; ediff-revision - compare buffer & version
176;; using vc.el package
177;; (Emacs 19.22 and up).
178;; rcs-ediff - same using rcs.el; rcs.el
179;; is not part of the
180;; standard Emacs distribution.
181;; 178;;
182;; 179;;
183;; To use Ediff, put this in your .emacs file: 180;; To use Ediff, put this in your .emacs file:
@@ -189,10 +186,8 @@
189;; (autoload 'ediff-patch-file "ediff" "Visual interface to patch" t) 186;; (autoload 'ediff-patch-file "ediff" "Visual interface to patch" t)
190;; (autoload 'ediff-patch-buffer "ediff" "Visual interface to patch" t) 187;; (autoload 'ediff-patch-buffer "ediff" "Visual interface to patch" t)
191;; (autoload 'epatch-buffer "ediff" "Visual interface to patch" t) 188;; (autoload 'epatch-buffer "ediff" "Visual interface to patch" t)
192;; (autoload 'vc-ediff "ediff" 189;; (autoload 'ediff-revision "ediff"
193;; "Interface to diff & version control via vc.el" t) 190;; "Interface to diff & version control" t)
194;; (autoload 'rcs-ediff "ediff"
195;; "Interface to diff & version control via rcs.el" t)
196;; 191;;
197;; 192;;
198;; If you want Ediff to be loaded from the very beginning, you should have 193;; If you want Ediff to be loaded from the very beginning, you should have
@@ -503,6 +498,7 @@
503;; ediff-split-window-function 498;; ediff-split-window-function
504;; ediff-use-last-dir 499;; ediff-use-last-dir
505;; ediff-no-help-in-control-buffer 500;; ediff-no-help-in-control-buffer
501;; ediff-toggle-read-only-function
506;; 502;;
507;; ediff-split-window-function controls the way you want the window be 503;; ediff-split-window-function controls the way you want the window be
508;; split between file-A and file-B. It defaults to vertical split, but you 504;; split between file-A and file-B. It defaults to vertical split, but you
@@ -527,11 +523,16 @@
527;; prompts the user for file names. Otherwise, it will use the 523;; prompts the user for file names. Otherwise, it will use the
528;; directories it had previously used for file-A and file-B. 524;; directories it had previously used for file-A and file-B.
529;; 525;;
530;; The ediff-no-help-in-control-buffer, if set to t, makes C-h behave like 526;; The variable ediff-no-help-in-control-buffer, if set to t, makes C-h
531;; the DEL key, i.e., it will move you back to the previous difference 527;; behave like the DEL key, i.e., it will move you back to the previous
532;; rather than invoking help. This is useful when, in an xterm window or on 528;; difference rather than invoking help. This is useful when, in an xterm
533;; a dumb terminal, the Backspace key is bound to C-h and is positioned 529;; window or on a dumb terminal, the Backspace key is bound to C-h and is
534;; more conveniently than the DEL key. 530;; positioned more conveniently than the DEL key.
531;;
532;; The variable ediff-toggle-read-only-function can be used to change the
533;; way Ediff toggles the read-only property in its buffers.
534;; By default, Ediff uses toggle-read-only. For files under version
535;; control, Ediff first tries to check the files out.
535 536
536 537
537;;; Commands 538;;; Commands
@@ -939,6 +940,31 @@
939;; If ediff-save-buffer is invoked with `wf', it'll save the diff 940;; If ediff-save-buffer is invoked with `wf', it'll save the diff
940;; output in a file. 941;; output in a file.
941 942
943;; Wed August 24, 1994
944
945;; Fixed ediff-toggle-read-only and ediff-patch-file so that they will
946;; check out version-controled files before modifying them. This will
947;; permit checking the modified versions back in. In earlier
948;; versions, such modifications could be lost, unless the user takes
949;; special care of preserving them.
950
951;; Tue August 30, 1994
952
953;; Added ediff-submit-report.
954;; Introduced ediff-revision as a uniform way of calling vc.el and
955;; rcs.el. This is controled by ediff-version-control-package
956;; variable. Functions vc-ediff, rcs-ediff are replaced by their
957;; internal versions.
958;; Added ediff-find-file-name-handler function to smooth out the
959;; transition from Emacs 19.22/Lucid 19.9 to 19.23/19/10
960
961;; Thus September 1, 1994
962
963;; Made ediff-overlay-put and ediff-move-overlay into bona fide
964;; functions (rather than fset symbols). These now check if overlay's
965;; buffer is alive. If not, overlay is deleted. This overcomes some of
966;; the problems with Lemacs.
967
942 968
943;;; Acknowledgements: 969;;; Acknowledgements:
944 970
@@ -954,11 +980,11 @@
954;; <norbert@i3.informatik.rwth-aachen.de>, Heinz Knutzen 980;; <norbert@i3.informatik.rwth-aachen.de>, Heinz Knutzen
955;; <hk@informatik.uni-kiel.d400.de>, Martin Maechler 981;; <hk@informatik.uni-kiel.d400.de>, Martin Maechler
956;; <maechler@stat.math.ethz.ch>, Richard Mlynarik <mly@adoc.xerox.com>, 982;; <maechler@stat.math.ethz.ch>, Richard Mlynarik <mly@adoc.xerox.com>,
957;; Ray Nickson <nickson@cs.uq.oz.au>, Sandy Rutherford 983;; Eyvind Ness <Eyvind.Ness@hrp.no>, Ray Nickson <nickson@cs.uq.oz.au>,
958;; <sandy@ibm550.sissa.it>, Andy Scott <ascott@pcocd2.intel.com>, 984;; Sandy Rutherford <sandy@ibm550.sissa.it>, Andy Scott
959;; Richard Stallman <rms@gnu.ai.mit.edu>, Richard Stanton 985;; <ascott@pcocd2.intel.com>, Richard Stallman <rms@gnu.ai.mit.edu>,
960;; <stanton@haas.berkeley.edu>, Peter Stout <Peter_Stout@cs.cmu.edu> 986;; Richard Stanton, <stanton@haas.berkeley.edu>, Peter Stout
961;; for contributing ideas, patches, and bug reports. 987;; <Peter_Stout@cs.cmu.edu> for contributing ideas, patches, and bug reports.
962;; 988;;
963;; Thanks also to many others who felt obliged to drop a thanks note. 989;; Thanks also to many others who felt obliged to drop a thanks note.
964 990
@@ -1074,8 +1100,7 @@ It is entered only through one of the following commands:
1074 `ediff-patch-file' 1100 `ediff-patch-file'
1075 `ediff-patch-buffer' 1101 `ediff-patch-buffer'
1076 `epatch-buffer' 1102 `epatch-buffer'
1077 `vc-ediff' 1103 `ediff-revision'
1078 `rcs-ediff'
1079 1104
1080Commands: 1105Commands:
1081\\{ediff-mode-map}" 1106\\{ediff-mode-map}"
@@ -1084,6 +1109,14 @@ Commands:
1084 (setq major-mode 'ediff-mode) 1109 (setq major-mode 'ediff-mode)
1085 (setq mode-name "Ediff")) 1110 (setq mode-name "Ediff"))
1086 1111
1112(defun ediff-version ()
1113 "Return string describing the version of Ediff.
1114When called interactively, displays the version."
1115 (interactive)
1116 (if (interactive-p)
1117 (message (ediff-version))
1118 (format "Ediff %s of %s" ediff-version ediff-date)))
1119
1087 1120
1088;; Hook variables 1121;; Hook variables
1089 1122
@@ -1123,6 +1156,7 @@ ga/gb -to point in A/B |---------------------------| ! -recompute diffs
1123 v/V -scroll up/down | #f/#h -focus/hide regions | wa/wb -save buf A/B 1156 v/V -scroll up/down | #f/#h -focus/hide regions | wa/wb -save buf A/B
1124 </> -scroll lft/rght | A/B -read-only buf A/B | wf -save diff output 1157 </> -scroll lft/rght | A/B -read-only buf A/B | wf -save diff output
1125=======================|===========================|=========================== 1158=======================|===========================|===========================
1159 | bug -submit bug report |
1126 i -status info | ? -toggle help window | z/q -suspend/quit Ediff" 1160 i -status info | ? -toggle help window | z/q -suspend/quit Ediff"
1127 ) 1161 )
1128 1162
@@ -1160,7 +1194,7 @@ If diff\(1\) is used as `ediff-diff-program', then the most useful options are
1160 "*White space. Used to split strings into words.") 1194 "*White space. Used to split strings into words.")
1161 1195
1162(defvar ediff-word-1 "a-zA-Z---_`'.?!:" 1196(defvar ediff-word-1 "a-zA-Z---_`'.?!:"
1163 "*Characters constituting type 1 words. 1197 "*Characters matching this regexp constitute words of type 1.
1164 1198
1165Ediff is using a very simple schema for splitting text into words, which is 1199Ediff is using a very simple schema for splitting text into words, which is
1166used to determine fine differences between regions. There are two types of 1200used to determine fine differences between regions. There are two types of
@@ -1208,21 +1242,21 @@ to a shell that you are not using or, better, fix your shell's startup file.")
1208 1242
1209(defvar ediff-diff-ok-lines-regexp 1243(defvar ediff-diff-ok-lines-regexp
1210 "^\\([0-9,]+[acd][0-9,]+$\\|[<>] \\|---\\|Warning:\\)" 1244 "^\\([0-9,]+[acd][0-9,]+$\\|[<>] \\|---\\|Warning:\\)"
1211 "*Regexp that matches normal output lines from `ediff-diff-program'. 1245 "Regexp that matches normal output lines from `ediff-diff-program'.
1212This is mostly lifted from Emerge, except that Ediff also considers the 1246This is mostly lifted from Emerge, except that Ediff also considers the
1213'Missing newline' message to be 'normal output.' 1247'Missing newline' message to be 'normal output.'
1214Lines that do not match are assumed to be error messages.") 1248Lines that do not match are assumed to be error messages.")
1215 1249
1216(defvar ediff-fine-diff-ok-lines-regexp 1250(defvar ediff-fine-diff-ok-lines-regexp
1217 "^\\([0-9,]+[acd][0-9,]+$\\|[<>] \\|---\\|Warning:\\)" 1251 "^\\([0-9,]+[acd][0-9,]+$\\|[<>] \\|---\\|Warning:\\)"
1218 "*Regexp that matches normal output lines from `ediff-fine-diff-program'. 1252 "Regexp that matches normal output lines from `ediff-fine-diff-program'.
1219This is mostly lifted from Emerge, except that Ediff also considers the 1253This is mostly lifted from Emerge, except that Ediff also considers the
1220'Missing newline' message to be 'normal output.' 1254'Missing newline' message to be 'normal output.'
1221Lines that do not match are assumed to be error messages.") 1255Lines that do not match are assumed to be error messages.")
1222 1256
1223(defvar ediff-match-diff-line (let ((x "\\([0-9]+\\)\\(\\|,\\([0-9]+\\)\\)")) 1257(defvar ediff-match-diff-line (let ((x "\\([0-9]+\\)\\(\\|,\\([0-9]+\\)\\)"))
1224 (concat "^" x "\\([acd]\\)" x "$")) 1258 (concat "^" x "\\([acd]\\)" x "$"))
1225 "*Pattern to match lines produced by diff that describe differences.") 1259 "Pattern to match lines produced by diff that describe differences.")
1226 1260
1227(defvar ediff-patch-buf nil 1261(defvar ediff-patch-buf nil
1228 "The buffer of the patch file.") 1262 "The buffer of the patch file.")
@@ -1230,8 +1264,8 @@ Lines that do not match are assumed to be error messages.")
1230 "The buffer where patch would display its diagnostics.") 1264 "The buffer where patch would display its diagnostics.")
1231 1265
1232 1266
1233;; Copying diffs betw buffers.
1234 1267
1268;; Copying difference regions between buffers.
1235(ediff-defvar-local ediff-killed-diffs-alist nil 1269(ediff-defvar-local ediff-killed-diffs-alist nil
1236 "A list of killed diffs. 1270 "A list of killed diffs.
1237A diff is saved here if it is replaced by a diff 1271A diff is saved here if it is replaced by a diff
@@ -1389,16 +1423,18 @@ through files.")
1389 (fset 'ediff-overlayp (symbol-function 'extentp)) 1423 (fset 'ediff-overlayp (symbol-function 'extentp))
1390 (fset 'ediff-make-overlay (symbol-function 'make-extent)) 1424 (fset 'ediff-make-overlay (symbol-function 'make-extent))
1391 (fset 'ediff-delete-overlay (symbol-function 'delete-extent)) 1425 (fset 'ediff-delete-overlay (symbol-function 'delete-extent))
1392 (fset 'ediff-overlay-put (symbol-function 'set-extent-property)) 1426 ;;(fset 'ediff-overlay-put (symbol-function 'set-extent-property))
1393 (fset 'ediff-move-overlay (symbol-function 'set-extent-endpoints)) 1427 ;;(fset 'ediff-move-overlay (symbol-function 'set-extent-endpoints))
1428 (fset 'ediff-overlay-buffer (symbol-function 'extent-buffer))
1394 (fset 'ediff-overlay-start (symbol-function 'extent-start-position)) 1429 (fset 'ediff-overlay-start (symbol-function 'extent-start-position))
1395 (fset 'ediff-overlay-end (symbol-function 'extent-end-position)) 1430 (fset 'ediff-overlay-end (symbol-function 'extent-end-position))
1396 (fset 'ediff-overlay-get (symbol-function 'extent-property))) 1431 (fset 'ediff-overlay-get (symbol-function 'extent-property)))
1397 (fset 'ediff-overlayp (symbol-function 'overlayp)) 1432 (fset 'ediff-overlayp (symbol-function 'overlayp))
1398 (fset 'ediff-make-overlay (symbol-function 'make-overlay)) 1433 (fset 'ediff-make-overlay (symbol-function 'make-overlay))
1399 (fset 'ediff-delete-overlay (symbol-function 'delete-overlay)) 1434 (fset 'ediff-delete-overlay (symbol-function 'delete-overlay))
1400 (fset 'ediff-overlay-put (symbol-function 'overlay-put)) 1435 ;;(fset 'ediff-overlay-put (symbol-function 'overlay-put))
1401 (fset 'ediff-move-overlay (symbol-function 'move-overlay)) 1436 ;;(fset 'ediff-move-overlay (symbol-function 'move-overlay))
1437 (fset 'ediff-overlay-buffer (symbol-function 'overlay-buffer))
1402 (fset 'ediff-overlay-start (symbol-function 'overlay-start)) 1438 (fset 'ediff-overlay-start (symbol-function 'overlay-start))
1403 (fset 'ediff-overlay-end (symbol-function 'overlay-end)) 1439 (fset 'ediff-overlay-end (symbol-function 'overlay-end))
1404 (fset 'ediff-overlay-get (symbol-function 'overlay-get))) 1440 (fset 'ediff-overlay-get (symbol-function 'overlay-get)))
@@ -1647,8 +1683,19 @@ through files.")
1647 1683
1648) ; end of window-system-only code. 1684) ; end of window-system-only code.
1649 1685
1686
1687;; Ediff toggle read-only stuff
1688(defvar ediff-toggle-read-only-function nil
1689 "*Specifies the function to be used to toggle read-only.
1690If nil, Ediff tries to deduce the function from the binding of C-x C-q.
1691Normally, this is the `toggle-read-only' function, but, if version
1692control is used, it could be `vc-toggle-read-only' or `rcs-toggle-read-only'.")
1693
1694(ediff-defvar-local ediff-local-checkout-flag nil
1695 "If t, indicates that buffer has been already checked out.")
1650 1696
1651 1697
1698
1652;;; Misc 1699;;; Misc
1653 1700
1654(defvar ediff-split-window-function 'split-window-vertically 1701(defvar ediff-split-window-function 'split-window-vertically
@@ -1659,13 +1706,15 @@ default vertical split by setting this variable to
1659splits. This variable has no effect when buffer-A and buffer-B are shown in 1706splits. This variable has no effect when buffer-A and buffer-B are shown in
1660different frames. In this case, Ediff will use those frames to display 1707different frames. In this case, Ediff will use those frames to display
1661these buffers.") 1708these buffers.")
1709
1662 1710
1663(defconst ediff-saved-variables 1711(defconst ediff-saved-variables
1664 '(buffer-read-only 1712 '(;;buffer-read-only
1665 buffer-auto-save-file-name) 1713 buffer-auto-save-file-name)
1666 "Buffer-local variables saved and restored during an Ediff session.") 1714 "Buffer-local variables saved and restored during an Ediff session.")
1667 1715
1668(defconst ediff-working-values '(nil nil) 1716;;(defconst ediff-working-values '(nil nil)
1717(defconst ediff-working-values '(nil)
1669 "Values to be assigned to `ediff-saved-variables' during diff.") 1718 "Values to be assigned to `ediff-saved-variables' during diff.")
1670 1719
1671(defvar ediff-use-last-dir nil 1720(defvar ediff-use-last-dir nil
@@ -1674,6 +1723,10 @@ these buffers.")
1674(defvar ediff-no-help-in-control-buffer nil 1723(defvar ediff-no-help-in-control-buffer nil
1675 "*Non-nil means C-h should not invoke Emacs help in control buffer. 1724 "*Non-nil means C-h should not invoke Emacs help in control buffer.
1676Instead, C-h jumps to previous difference.") 1725Instead, C-h jumps to previous difference.")
1726
1727(defvar ediff-version-control-package 'vc
1728 "Version control package used.
1729Currently, Ediff supports vc.el and rcs.el.")
1677 1730
1678(defvar ediff-temp-file-prefix 1731(defvar ediff-temp-file-prefix
1679 (let ((env (or (getenv "TMPDIR") 1732 (let ((env (or (getenv "TMPDIR")
@@ -1724,20 +1777,18 @@ Do not start with `~/' or `~user-name/'.")
1724;;; They only do something in loaddefs.el. 1777;;; They only do something in loaddefs.el.
1725;;;###autoload 1778;;;###autoload
1726(if purify-flag 1779(if purify-flag
1727 (progn 1780 (progn
1728 (defvar menu-bar-epatch-menu (make-sparse-keymap "Epatch")) 1781 (defvar menu-bar-epatch-menu (make-sparse-keymap "Epatch"))
1729 (fset 'menu-bar-epatch-menu (symbol-value 'menu-bar-epatch-menu)) 1782 (fset 'menu-bar-epatch-menu (symbol-value 'menu-bar-epatch-menu))
1730 (defvar menu-bar-ediff-menu (make-sparse-keymap "Ediff")) 1783 (defvar menu-bar-ediff-menu (make-sparse-keymap "Ediff"))
1731 (fset 'menu-bar-ediff-menu (symbol-value 'menu-bar-ediff-menu)))) 1784 (fset 'menu-bar-ediff-menu (symbol-value 'menu-bar-ediff-menu))))
1732 1785
1733 1786
1734;;;###autoload 1787;;;###autoload
1735(if purify-flag 1788(if purify-flag
1736 (progn 1789 (progn
1737 (define-key menu-bar-ediff-menu [rcs-ediff] 1790 (define-key menu-bar-ediff-menu [ediff-revision]
1738 '("File with a version via RCS ..." . rcs-ediff)) 1791 '("File with a version ..." . ediff-revision))
1739 (define-key menu-bar-ediff-menu [vc-ediff]
1740 '("File with a version via VC ..." . vc-ediff))
1741 (define-key menu-bar-ediff-menu [ediff-buffers] 1792 (define-key menu-bar-ediff-menu [ediff-buffers]
1742 '("Buffers ..." . ediff-buffers)) 1793 '("Buffers ..." . ediff-buffers))
1743 (define-key menu-bar-ediff-menu [ediff-files] 1794 (define-key menu-bar-ediff-menu [ediff-files]
@@ -1751,32 +1802,31 @@ Do not start with `~/' or `~user-name/'.")
1751 (define-key menu-bar-epatch-menu [ediff-patch-file] 1802 (define-key menu-bar-epatch-menu [ediff-patch-file]
1752 '("To a File ..." . ediff-patch-file)))) 1803 '("To a File ..." . ediff-patch-file))))
1753 1804
1754(define-key menu-bar-file-menu [epatch] 1805
1755 '("Apply Patch" . menu-bar-epatch-menu)) 1806(if (and window-system ediff-want-default-menus (ediff-frame-has-menubar))
1756(define-key menu-bar-file-menu [ediff] 1807 (cond ((ediff-if-lucid)
1757 '("Compare" . menu-bar-ediff-menu)) 1808 (defvar ediff-menu
1758 1809 '(""
1759(if (and window-system ediff-want-default-menus (ediff-frame-has-menubar) 1810 ["Files ..." ediff-files t]
1760 (ediff-if-lucid)) 1811 ["Buffers ..." ediff-buffers t]
1761 (progn ;; Lucid menu bars 1812 ["File with a version ..." ediff-revision t]))
1762 (defvar ediff-menu 1813 (defvar epatch-menu
1763 '("" 1814 '(""
1764 ["Files ..." ediff-files t] 1815 ["To a file ..." ediff-patch-file t]
1765 ["Buffers ..." ediff-buffers t] 1816 ["To a buffer ..." ediff-patch-buffer t]))
1766 ["File with a version via VC ..." vc-ediff t] 1817 (add-menu '("File") "Compare"
1767 ["File with a version via RCS ..." rcs-ediff t])) 1818 ediff-menu
1768 (defvar epatch-menu 1819 "New Screen")
1769 '("" 1820 (add-menu '("File") "Apply Patch"
1770 ["To a file ..." ediff-patch-file t] 1821 epatch-menu
1771 ["To a buffer ..." ediff-patch-buffer t])) 1822 "New Screen")
1772 (add-menu '("File") "Compare" 1823 ;; Display a solid horizontal line
1773 ediff-menu 1824 (add-menu-item '("File") "---" nil nil "New Screen"))
1774 "New Screen") 1825 (t ;; FSF Emacs
1775 (add-menu '("File") "Apply Patch" 1826 (define-key menu-bar-file-menu [epatch]
1776 epatch-menu 1827 '("Apply Patch" . menu-bar-epatch-menu))
1777 "New Screen") 1828 (define-key menu-bar-file-menu [ediff]
1778 ;; Displays as a solid horizontal line 1829 '("Compare" . menu-bar-ediff-menu)))))
1779 (add-menu-item '("File") "---" nil nil "New Screen")))
1780 1830
1781 1831
1782 1832
@@ -1816,6 +1866,7 @@ Do not start with `~/' or `~user-name/'.")
1816 (define-key ediff-mode-map "ab" 'ediff-diff-to-diff) 1866 (define-key ediff-mode-map "ab" 'ediff-diff-to-diff)
1817 (define-key ediff-mode-map "b" nil) 1867 (define-key ediff-mode-map "b" nil)
1818 (define-key ediff-mode-map "ba" 'ediff-diff-to-diff) 1868 (define-key ediff-mode-map "ba" 'ediff-diff-to-diff)
1869 (define-key ediff-mode-map "bug" 'ediff-submit-report)
1819 (define-key ediff-mode-map "r" nil) 1870 (define-key ediff-mode-map "r" nil)
1820 (define-key ediff-mode-map "ra" 'ediff-restore-diff) 1871 (define-key ediff-mode-map "ra" 'ediff-restore-diff)
1821 (define-key ediff-mode-map "rb" 'ediff-restore-diff) 1872 (define-key ediff-mode-map "rb" 'ediff-restore-diff)
@@ -1849,7 +1900,7 @@ assigned the hook to be executed after `ediff-strartup' is finished.
1849deleted. 1900deleted.
1850Arguments: (file buffer &optional last-dir hooks)" 1901Arguments: (file buffer &optional last-dir hooks)"
1851 (let* ((file (eval file-var)) 1902 (let* ((file (eval file-var))
1852 (file-magic (find-file-name-handler file 'find-file-noselect))) 1903 (file-magic (ediff-find-file-name-handler file)))
1853 (if (not (file-readable-p file)) 1904 (if (not (file-readable-p file))
1854 (error "File `%s' does not exist or is not readable" file)) 1905 (error "File `%s' does not exist or is not readable" file))
1855 1906
@@ -1881,9 +1932,9 @@ Arguments: (file buffer &optional last-dir hooks)"
1881 1932
1882(defun ediff-files-internal (file-A file-B &optional startup-hooks) 1933(defun ediff-files-internal (file-A file-B &optional startup-hooks)
1883 (let (buffer-A buffer-B) 1934 (let (buffer-A buffer-B)
1884 (message "Reading file %s ... " file-A)(sit-for .5) 1935 (message "Reading file %s ... " file-A)(sit-for 0)
1885 (ediff-find-file 'file-A 'buffer-A 'ediff-last-dir-A 'startup-hooks) 1936 (ediff-find-file 'file-A 'buffer-A 'ediff-last-dir-A 'startup-hooks)
1886 (message "Reading file %s ... " file-B)(sit-for .5) 1937 (message "Reading file %s ... " file-B)(sit-for 0)
1887 (ediff-find-file 'file-B 'buffer-B 'ediff-last-dir-B 'startup-hooks) 1938 (ediff-find-file 'file-B 'buffer-B 'ediff-last-dir-B 'startup-hooks)
1888 (ediff-setup buffer-A file-A buffer-B file-B startup-hooks))) 1939 (ediff-setup buffer-A file-A buffer-B file-B startup-hooks)))
1889 1940
@@ -1895,9 +1946,12 @@ Else, read patch file into a new buffer."
1895 (get-buffer (read-buffer "Patch buffer name: " nil t))) ;must match 1946 (get-buffer (read-buffer "Patch buffer name: " nil t))) ;must match
1896 (setq ediff-patch-buf 1947 (setq ediff-patch-buf
1897 (find-file-noselect (read-file-name "Patch file name: " dir)))) 1948 (find-file-noselect (read-file-name "Patch file name: " dir))))
1949
1950 ;; secure the patch buffer against accidental changes
1898 (ediff-eval-in-buffer 1951 (ediff-eval-in-buffer
1899 ediff-patch-buf 1952 ediff-patch-buf
1900 (toggle-read-only 1)) 1953 (setq buffer-read-only t))
1954
1901 (setq ediff-patch-diagnostics 1955 (setq ediff-patch-diagnostics
1902 (get-buffer-create "*ediff patch diagnostics*")) 1956 (get-buffer-create "*ediff patch diagnostics*"))
1903 (ediff-eval-in-buffer 1957 (ediff-eval-in-buffer
@@ -1917,7 +1971,7 @@ Else, read patch file into a new buffer."
1917 (ediff-eval-in-buffer 1971 (ediff-eval-in-buffer
1918 control-buffer 1972 control-buffer
1919 (ediff-mode) ;; in control buffer only 1973 (ediff-mode) ;; in control buffer only
1920 (setq buffer-read-only nil) 1974 (setq buffer-read-only nil) ;; in control buffer only
1921 (setq ediff-A-buffer buffer-A) 1975 (setq ediff-A-buffer buffer-A)
1922 (setq ediff-B-buffer buffer-B) 1976 (setq ediff-B-buffer buffer-B)
1923 (setq ediff-control-buffer control-buffer) 1977 (setq ediff-control-buffer control-buffer)
@@ -2011,7 +2065,7 @@ Else, read patch file into a new buffer."
2011 (let ((shell-file-name ediff-shell)) 2065 (let ((shell-file-name ediff-shell))
2012 (if refine-region 2066 (if refine-region
2013 (message "Refining difference region %d ..." (1+ refine-region)) 2067 (message "Refining difference region %d ..." (1+ refine-region))
2014 (message "Computing differences ...")(sit-for .5)) 2068 (message "Computing differences ...")(sit-for 0))
2015 (shell-command 2069 (shell-command
2016 (format "%s %s %s %s" 2070 (format "%s %s %s %s"
2017 diff-program diff-options 2071 diff-program diff-options
@@ -2030,7 +2084,7 @@ Else, read patch file into a new buffer."
2030 (ediff-extract-diffs ediff-fine-diff-buffer) 2084 (ediff-extract-diffs ediff-fine-diff-buffer)
2031 refine-region)) 2085 refine-region))
2032 (ediff-prepare-error-list diff-ok-lines-regexp ediff-diff-buffer) 2086 (ediff-prepare-error-list diff-ok-lines-regexp ediff-diff-buffer)
2033 (message "Computing differences ... Done.")(sit-for .5) 2087 (message "Computing differences ... Done.")(sit-for 0)
2034 (ediff-convert-diffs-to-overlays 2088 (ediff-convert-diffs-to-overlays
2035 ediff-A-buffer ediff-B-buffer 2089 ediff-A-buffer ediff-B-buffer
2036 (ediff-extract-diffs ediff-diff-buffer 2090 (ediff-extract-diffs ediff-diff-buffer
@@ -2088,9 +2142,13 @@ Else, read patch file into a new buffer."
2088 (setq file-name-magic-p (not (equal (file-truename true-source-filename) 2142 (setq file-name-magic-p (not (equal (file-truename true-source-filename)
2089 (file-truename source-filename)))) 2143 (file-truename source-filename))))
2090 2144
2145 ;; Checkout orig file, if necessary so that the patched file could be
2146 ;; checked back in.
2147 (ediff-toggle-read-only buf-to-patch)
2148
2091 (ediff-eval-in-buffer 2149 (ediff-eval-in-buffer
2092 ediff-patch-diagnostics 2150 ediff-patch-diagnostics
2093 (message "Applying patch ... ")(sit-for .5) 2151 (message "Applying patch ... ")(sit-for 0)
2094 ;; always pass patch the -f option, so it won't ask any questions 2152 ;; always pass patch the -f option, so it won't ask any questions
2095 (shell-command-on-region 2153 (shell-command-on-region
2096 (point-min) (point-max) 2154 (point-min) (point-max)
@@ -2098,7 +2156,7 @@ Else, read patch file into a new buffer."
2098 ediff-patch-program ediff-patch-options 2156 ediff-patch-program ediff-patch-options
2099 (expand-file-name true-source-filename)) 2157 (expand-file-name true-source-filename))
2100 t)) 2158 t))
2101 (message "Applying patch ... Done.")(sit-for .5) 2159 (message "Applying patch ... Done.")(sit-for 0)
2102 (switch-to-buffer ediff-patch-diagnostics) 2160 (switch-to-buffer ediff-patch-diagnostics)
2103 (sit-for 0) ;; synchronize 2161 (sit-for 0) ;; synchronize
2104 2162
@@ -2126,9 +2184,14 @@ Else, read patch file into a new buffer."
2126 true-source-filename t)) 2184 true-source-filename t))
2127 2185
2128 ;; make orig buffer read-only 2186 ;; make orig buffer read-only
2129 (setq startup-hooks (cons 'ediff-toggle-read-only-A startup-hooks)) 2187 (setq startup-hooks
2188 (cons 'ediff-toggle-read-only-patch-orig startup-hooks))
2189
2130 ;; set up a buf for the patched file 2190 ;; set up a buf for the patched file
2131 (setq target-buf (find-file-noselect target-filename)) 2191 (ediff-eval-in-buffer
2192 (setq target-buf (find-file-noselect target-filename))
2193 ;; files to be patched are always checked out first
2194 (setq ediff-local-checkout-flag t))
2132 2195
2133 (ediff-buffers buf-to-patch target-buf startup-hooks) 2196 (ediff-buffers buf-to-patch target-buf startup-hooks)
2134 2197
@@ -2218,23 +2281,29 @@ Else, read patch file into a new buffer."
2218;;; Versions Control functions 2281;;; Versions Control functions
2219 2282
2220;;;###autoload 2283;;;###autoload
2221(defun vc-ediff (rev) 2284(defun ediff-revision (revision)
2285 "Call `vc.el' or `rcs.el' depending on `ediff-version-control-package'.
2286This function is introduced to provide a uniform interface to version
2287control packages from Ediff."
2288 (interactive "sVersion to Ediff with (default is the latest version): ")
2289 (funcall
2290 (intern (format "%S-ediff-internal" ediff-version-control-package))
2291 revision))
2292
2293(defun vc-ediff-internal (rev)
2222;; Note: this function will work only with Emacs 19.22 and higher. 2294;; Note: this function will work only with Emacs 19.22 and higher.
2223 "Run ediff on version REV of the current buffer in another window. 2295 "Run Ediff on version REV of the current buffer in another window.
2224If the current buffer is named `F', the version is named `F.~REV~'. 2296If the current buffer is named `F', the version is named `F.~REV~'.
2225If `F.~REV~' already exists, it is used instead of being re-created." 2297If `F.~REV~' already exists, it is used instead of being re-created."
2226 (interactive "sVersion to ediff with (default is the latest version): ")
2227 (or (featurep 'vc) 2298 (or (featurep 'vc)
2228 (if (locate-library "vc") ;; if vc.el is available 2299 (if (locate-library "vc") ;; if vc.el is available
2229 (progn 2300 (require 'vc-hooks)
2230 (require 'vc-hooks) 2301 (error "The vc.el package is apparently not installed")))
2231 (define-key vc-prefix-map "=" 'vc-ediff)) 2302 (define-key vc-prefix-map "=" 'ediff-revision)
2232 (error "The VC package is apparently not installed."))) 2303 (let ((newvers (current-buffer)))
2233 (let ((newvers (current-buffer))
2234 )
2235 (vc-version-other-window rev) 2304 (vc-version-other-window rev)
2236 ;; current-buffer is supposed to contain the old version in another 2305 ;; current-buffer is supposed to contain the old version
2237 ;; window 2306 ;; in another window
2238 (ediff-buffers newvers (current-buffer)) 2307 (ediff-buffers newvers (current-buffer))
2239 )) 2308 ))
2240 2309
@@ -2275,18 +2344,13 @@ With prefix argument, prompts for a revision name."
2275 (erase-buffer)) 2344 (erase-buffer))
2276 buf)) 2345 buf))
2277 2346
2278;;;###autoload 2347(defun rcs-ediff-internal (rev)
2279(defun rcs-ediff (&optional rev) 2348 "Run Ediff on the current buffer, comparing it with previous RCS revision."
2280 "Run Ediff on the current buffer, comparing it with previous RCS revision.
2281With prefix argument, prompts for revision name."
2282 (interactive (list (if current-prefix-arg
2283 (read-string "Revision: "))))
2284 (or (featurep 'rcs) 2349 (or (featurep 'rcs)
2285 (if (locate-library "rcs") 2350 (if (locate-library "rcs")
2286 (progn 2351 (require 'rcs)
2287 (require 'rcs) 2352 (error "The rcs.el package is apparently not installed")))
2288 (global-set-key "\C-cD" 'rcs-ediff)) 2353 (global-set-key "\C-cD" 'ediff-revision)
2289 (error "The RCS package is apparently not installed.")))
2290 (let ((newvers (current-buffer)) 2354 (let ((newvers (current-buffer))
2291 (oldvers (rcs-ediff-view-revision rev))) 2355 (oldvers (rcs-ediff-view-revision rev)))
2292 (ediff-buffers newvers oldvers) 2356 (ediff-buffers newvers oldvers)
@@ -2348,16 +2412,17 @@ With prefix argument, prompts for revision name."
2348 2412
2349;; Arranges goal-buf on the screen. 2413;; Arranges goal-buf on the screen.
2350(defun ediff-arrange-buffer (goal-buf other-buf ctl-buf &optional pos) 2414(defun ediff-arrange-buffer (goal-buf other-buf ctl-buf &optional pos)
2351 (let* ((ctl-wind (get-buffer-window ctl-buf t)) 2415 (let* ((ctl-wind (ediff-get-visible-buffer-window ctl-buf))
2352 (goal-wind (get-buffer-window goal-buf t)) 2416 (goal-wind (ediff-get-visible-buffer-window goal-buf))
2353 (other-wind (get-buffer-window other-buf t)) 2417 (other-wind (ediff-get-visible-buffer-window other-buf))
2354 (ctl-frame (ediff-window-frame ctl-wind)) 2418 (ctl-frame (ediff-window-frame ctl-wind))
2355 (goal-frame (if goal-wind (ediff-window-frame goal-wind))) 2419 (goal-frame (if goal-wind (ediff-window-frame goal-wind)))
2356 (other-frame (if other-wind (ediff-window-frame other-wind))) 2420 (other-frame (if other-wind (ediff-window-frame other-wind)))
2357 (ctl-frame-shared (or (eq ctl-frame goal-frame) 2421 (ctl-frame-shared (or (eq ctl-frame goal-frame)
2358 (eq ctl-frame other-frame)))) 2422 (eq ctl-frame other-frame))))
2359 2423
2360 (cond ((and goal-frame (not (eq goal-wind other-wind))) 2424 (cond ((and goal-frame
2425 (not (eq goal-wind other-wind)))
2361 ;; goal buffer is visible and we are not comparing file 2426 ;; goal buffer is visible and we are not comparing file
2362 ;; against itself (by mistake). 2427 ;; against itself (by mistake).
2363 ;; Note: goal-frame != ctl-frame, as we deleted other 2428 ;; Note: goal-frame != ctl-frame, as we deleted other
@@ -2399,18 +2464,19 @@ With prefix argument, prompts for revision name."
2399;; to reside. 2464;; to reside.
2400(defun ediff-setup-control-window () 2465(defun ediff-setup-control-window ()
2401 "Set up window for control buffer." 2466 "Set up window for control buffer."
2402 (erase-buffer) 2467 (let ((window-min-height 2))
2403 (insert ediff-help-message) 2468 (erase-buffer)
2404 (shrink-window-if-larger-than-buffer) 2469 (insert ediff-help-message)
2405 (setq ediff-control-window (selected-window)) 2470 (shrink-window-if-larger-than-buffer)
2406 (setq ediff-window-config-saved 2471 (setq ediff-control-window (selected-window))
2407 (format "%S%S%S%S" 2472 (setq ediff-window-config-saved
2408 ediff-control-window 2473 (format "%S%S%S%S"
2409 (get-buffer-window ediff-A-buffer t) 2474 ediff-control-window
2410 (get-buffer-window ediff-B-buffer t) 2475 (ediff-get-visible-buffer-window ediff-A-buffer)
2411 ediff-split-window-function)) 2476 (ediff-get-visible-buffer-window ediff-B-buffer)
2412 (goto-char (point-min)) 2477 ediff-split-window-function))
2413 (skip-chars-forward ediff-whitespace)) 2478 (goto-char (point-min))
2479 (skip-chars-forward ediff-whitespace)))
2414 2480
2415(defun ediff-leave-window-config (control-buf) 2481(defun ediff-leave-window-config (control-buf)
2416 (and (eq control-buf (current-buffer)) 2482 (and (eq control-buf (current-buffer))
@@ -2419,9 +2485,9 @@ With prefix argument, prompts for revision name."
2419 control-buf 2485 control-buf
2420 (string= ediff-window-config-saved 2486 (string= ediff-window-config-saved
2421 (format "%S%S%S%S" 2487 (format "%S%S%S%S"
2422 (get-buffer-window ediff-control-buffer t) 2488 (ediff-get-visible-buffer-window ediff-control-buffer)
2423 (get-buffer-window ediff-A-buffer t) 2489 (ediff-get-visible-buffer-window ediff-A-buffer)
2424 (get-buffer-window ediff-B-buffer t) 2490 (ediff-get-visible-buffer-window ediff-B-buffer)
2425 ediff-split-window-function))))) 2491 ediff-split-window-function)))))
2426 2492
2427 2493
@@ -2722,8 +2788,8 @@ Reestablish the default three-window display."
2722 (after-flag-shift-B (if (eq ediff-highlighting-style 'ascii) 2788 (after-flag-shift-B (if (eq ediff-highlighting-style 'ascii)
2723 (1- (length ediff-after-flag-B)) 2789 (1- (length ediff-after-flag-B))
2724 0)) 2790 0))
2725 (window-A (get-buffer-window buffer-A t)) 2791 (window-A (ediff-get-visible-buffer-window buffer-A))
2726 (window-B (get-buffer-window buffer-B t))) 2792 (window-B (ediff-get-visible-buffer-window buffer-B)))
2727 2793
2728 (or no-rehighlight 2794 (or no-rehighlight
2729 (ediff-operate-on-flags 'insert)) 2795 (ediff-operate-on-flags 'insert))
@@ -2750,8 +2816,8 @@ Reestablish the default three-window display."
2750 "Toggle vertical/horizontal window split. 2816 "Toggle vertical/horizontal window split.
2751Does nothing if file-A and file-B are in different frames." 2817Does nothing if file-A and file-B are in different frames."
2752 (interactive) 2818 (interactive)
2753 (let* ((wind-A (get-buffer-window ediff-A-buffer t)) 2819 (let* ((wind-A (ediff-get-visible-buffer-window ediff-A-buffer))
2754 (wind-B (get-buffer-window ediff-B-buffer t)) 2820 (wind-B (ediff-get-visible-buffer-window ediff-B-buffer))
2755 (frame-A (if wind-A (ediff-window-frame wind-A))) 2821 (frame-A (if wind-A (ediff-window-frame wind-A)))
2756 (frame-B (if wind-B (ediff-window-frame wind-B)))) 2822 (frame-B (if wind-B (ediff-window-frame wind-B))))
2757 (if (eq frame-A frame-B) 2823 (if (eq frame-A frame-B)
@@ -2834,21 +2900,45 @@ On a dumb terminal, switches between ASCII highlighting and no highlighting."
2834 (ediff-recenter 'no-rehighlight)) 2900 (ediff-recenter 'no-rehighlight))
2835 2901
2836 2902
2837(defun ediff-toggle-read-only-A () 2903(defun ediff-toggle-read-only-patch-orig ()
2838 "Used as a startup hook to set `.orig' patch file read-only." 2904 "Used as a startup hook to set `.orig' patch file read-only."
2839 (let ((last-command-char ?A)) 2905 (ediff-toggle-read-only ediff-A-buffer))
2840 (ediff-toggle-read-only)))
2841 2906
2842(defun ediff-toggle-read-only () 2907(defun ediff-toggle-read-only (&optional buff)
2843 "Toggles buffer-read-only for buffer buffers A and B." 2908 "Toggles read-only in buffers A and B.
2909If buffer is under version control and locked, check it out first."
2844 (interactive) 2910 (interactive)
2911 ;; Optional argument, BUF, is passed only in a startup hook.
2912 (or buff (ediff-recenter))
2913
2845 (ediff-eval-in-buffer 2914 (ediff-eval-in-buffer
2846 (if (eq last-command-char ?A) ediff-A-buffer ediff-B-buffer) 2915 (or buff (if (eq last-command-char ?A) ediff-A-buffer ediff-B-buffer))
2847 (setq buffer-read-only (null buffer-read-only)))) 2916 (let* ((file (buffer-file-name (current-buffer)))
2917 (file-writable (and file (file-writable-p file)))
2918 (toggle-ro-cmd (cond (ediff-toggle-read-only-function)
2919 (ediff-local-checkout-flag
2920 (if (and file (not file-writable))
2921 (progn
2922 (beep 1)
2923 (message "Warning: file %s is read-only."
2924 (abbreviate-file-name file))))
2925 'toggle-read-only)
2926 (file-writable 'toggle-read-only)
2927 (t (key-binding "\C-x\C-q")))))
2928 (if (and toggle-ro-cmd
2929 (string-match "toggle-read-only" (symbol-name toggle-ro-cmd)))
2930 (save-window-excursion
2931 (setq ediff-local-checkout-flag t)
2932 (or buff
2933 (select-window
2934 (ediff-get-visible-buffer-window (current-buffer))))
2935 (command-execute toggle-ro-cmd))
2936 (error "Don't know how to toggle read-only in buffer %S"
2937 (current-buffer))))))
2938
2939
2848 2940
2849;;; Window scrolling operations 2941;;; Window scrolling operations
2850;; These operations are designed to scroll all three windows the same amount,
2851;; so as to keep the text in them aligned.
2852 2942
2853;; Perform some operation on the two file windows (if they are showing). 2943;; Perform some operation on the two file windows (if they are showing).
2854;; Catches all errors on the operation in the A and B windows. 2944;; Catches all errors on the operation in the A and B windows.
@@ -2858,8 +2948,8 @@ On a dumb terminal, switches between ASCII highlighting and no highlighting."
2858 (let* ((buffer-A ediff-A-buffer) 2948 (let* ((buffer-A ediff-A-buffer)
2859 (buffer-B ediff-B-buffer) 2949 (buffer-B ediff-B-buffer)
2860 (wind (selected-window)) 2950 (wind (selected-window))
2861 (window-A (get-buffer-window buffer-A t)) 2951 (window-A (ediff-get-visible-buffer-window buffer-A))
2862 (window-B (get-buffer-window buffer-B t))) 2952 (window-B (ediff-get-visible-buffer-window buffer-B)))
2863 (if window-A (progn 2953 (if window-A (progn
2864 (select-window window-A) 2954 (select-window window-A)
2865 (condition-case nil 2955 (condition-case nil
@@ -2886,8 +2976,8 @@ the height of window-A."
2886 ;; use it 2976 ;; use it
2887 (prefix-numeric-value arg) 2977 (prefix-numeric-value arg)
2888 ;; if not, see if we can determine a default amount (the window height) 2978 ;; if not, see if we can determine a default amount (the window height)
2889 (let* ((window-A (get-buffer-window ediff-A-buffer t)) 2979 (let* ((window-A (ediff-get-visible-buffer-window ediff-A-buffer))
2890 (window-B (get-buffer-window ediff-B-buffer t)) 2980 (window-B (ediff-get-visible-buffer-window ediff-B-buffer))
2891 default-amount) 2981 default-amount)
2892 (if (or (null window-A) (null window-B)) 2982 (if (or (null window-A) (null window-B))
2893 (setq default-amount 0) 2983 (setq default-amount 0)
@@ -2914,8 +3004,8 @@ the height of window-A."
2914 ;; use it 3004 ;; use it
2915 (prefix-numeric-value arg) 3005 (prefix-numeric-value arg)
2916 ;; if not, see if we can determine a default amount (the window height) 3006 ;; if not, see if we can determine a default amount (the window height)
2917 (let* ((window-A (get-buffer-window ediff-A-buffer t)) 3007 (let* ((window-A (ediff-get-visible-buffer-window ediff-A-buffer))
2918 (window-B (get-buffer-window ediff-B-buffer t)) 3008 (window-B (ediff-get-visible-buffer-window ediff-B-buffer))
2919 default-amount) 3009 default-amount)
2920 (if (or (null window-A) (null window-B)) 3010 (if (or (null window-A) (null window-B))
2921 (setq default-amount 0) 3011 (setq default-amount 0)
@@ -3011,7 +3101,7 @@ With a prefix argument, go back that many differences."
3011 (if (< ediff-current-difference ediff-number-of-differences) 3101 (if (< ediff-current-difference ediff-number-of-differences)
3012 (let ((n (min ediff-number-of-differences 3102 (let ((n (min ediff-number-of-differences
3013 (+ ediff-current-difference (if arg arg 1)))) 3103 (+ ediff-current-difference (if arg arg 1))))
3014 (buffer-read-only nil)) 3104 buffer-read-only)
3015 3105
3016 (while (and (< n ediff-number-of-differences) 3106 (while (and (< n ediff-number-of-differences)
3017 (funcall ediff-skip-diff-region-function n)) 3107 (funcall ediff-skip-diff-region-function n))
@@ -3033,7 +3123,7 @@ With a prefix argument, go back that many differences."
3033 (interactive "P") 3123 (interactive "P")
3034 (if (> ediff-current-difference -1) 3124 (if (> ediff-current-difference -1)
3035 (let ((n (max -1 (- ediff-current-difference (if arg arg 1)))) 3125 (let ((n (max -1 (- ediff-current-difference (if arg arg 1))))
3036 (buffer-read-only nil)) 3126 buffer-read-only)
3037 3127
3038 (while (and (funcall ediff-skip-diff-region-function n) 3128 (while (and (funcall ediff-skip-diff-region-function n)
3039 (> n -1)) 3129 (> n -1))
@@ -3051,7 +3141,7 @@ With a prefix argument, go back that many differences."
3051(defun ediff-jump-to-difference (difference-number) 3141(defun ediff-jump-to-difference (difference-number)
3052 "Go to the difference specified as a prefix argument." 3142 "Go to the difference specified as a prefix argument."
3053 (interactive "p") 3143 (interactive "p")
3054 (let ((buffer-read-only nil)) 3144 (let (buffer-read-only)
3055 (setq difference-number (1- difference-number)) 3145 (setq difference-number (1- difference-number))
3056 (if (and (>= difference-number -1) 3146 (if (and (>= difference-number -1)
3057 (< difference-number (1+ ediff-number-of-differences))) 3147 (< difference-number (1+ ediff-number-of-differences)))
@@ -3064,8 +3154,8 @@ If this command is invoked via `\\[ediff-jump-to-difference-at-point]'
3064then the point in buffer B is used. 3154then the point in buffer B is used.
3065Otherwise, buffer A's point is used." 3155Otherwise, buffer A's point is used."
3066 (interactive) 3156 (interactive)
3067 (let ((buffer-read-only nil) 3157 (let ((buf-type (ediff-char-to-buftype last-command-char))
3068 (buf-type (ediff-char-to-buftype last-command-char))) 3158 buffer-read-only)
3069 (ediff-jump-to-difference (ediff-diff-at-point buf-type)))) 3159 (ediff-jump-to-difference (ediff-diff-at-point buf-type))))
3070 3160
3071 3161
@@ -3152,12 +3242,12 @@ Otherwise, copy the difference given by `ediff-current-difference'."
3152 ;; seems ok to copy 3242 ;; seems ok to copy
3153 (if (ediff-test-save-region n to-buf-type) 3243 (if (ediff-test-save-region n to-buf-type)
3154 (condition-case conds 3244 (condition-case conds
3155 (let (inhibit-read-only) 3245 (progn
3156 (ediff-eval-in-buffer 3246 (ediff-eval-in-buffer
3157 to-buf 3247 to-buf
3158 ;; to prevent flags from interfering if buffer is writable 3248 ;; to prevent flags from interfering if buffer is writable
3159 (setq inhibit-read-only (null buffer-read-only)) 3249 (let ((inhibit-read-only (null buffer-read-only))
3160 (let ((before-change-function nil)) 3250 before-change-function)
3161 (goto-char reg-to-delete-end) 3251 (goto-char reg-to-delete-end)
3162 (insert-before-markers reg-to-copy) 3252 (insert-before-markers reg-to-copy)
3163 (if (ediff-if-lucid) 3253 (if (ediff-if-lucid)
@@ -3428,6 +3518,7 @@ flags of the compared file buffers, kills Ediff buffers for this session
3428 (if (null ediff-this-buffer-control-sessions) 3518 (if (null ediff-this-buffer-control-sessions)
3429 (setq local-write-file-hooks 3519 (setq local-write-file-hooks
3430 (delq 'ediff-block-write-file local-write-file-hooks))) 3520 (delq 'ediff-block-write-file local-write-file-hooks)))
3521 (kill-local-variable 'ediff-local-checkout-flag)
3431 (kill-local-variable 'mode-line-buffer-identification)) 3522 (kill-local-variable 'mode-line-buffer-identification))
3432 (error)) 3523 (error))
3433 3524
@@ -3440,6 +3531,7 @@ flags of the compared file buffers, kills Ediff buffers for this session
3440 (setq local-write-file-hooks 3531 (setq local-write-file-hooks
3441 (delq 'ediff-block-write-file local-write-file-hooks))) 3532 (delq 'ediff-block-write-file local-write-file-hooks)))
3442 (setq before-change-function nil) 3533 (setq before-change-function nil)
3534 (kill-local-variable 'ediff-local-checkout-flag)
3443 (kill-local-variable 'mode-line-buffer-identification)) 3535 (kill-local-variable 'mode-line-buffer-identification))
3444 (error))) 3536 (error)))
3445 3537
@@ -3463,16 +3555,16 @@ flags of the compared file buffers, kills Ediff buffers for this session
3463 (ediff-kill-buffer-carefully ediff-control-buffer) 3555 (ediff-kill-buffer-carefully ediff-control-buffer)
3464 (ediff-kill-buffer-carefully ediff-patch-diagnostics) 3556 (ediff-kill-buffer-carefully ediff-patch-diagnostics)
3465 (delete-other-windows) 3557 (delete-other-windows)
3466 ;; display only if not visible
3467 3558
3559 ;; display only if not visible
3468 (condition-case nil 3560 (condition-case nil
3469 (or (get-buffer-window buff-B t) 3561 (or (ediff-get-visible-buffer-window buff-B)
3470 (switch-to-buffer buff-B)) 3562 (switch-to-buffer buff-B))
3471 (error)) 3563 (error))
3472 (condition-case nil 3564 (condition-case nil
3473 (or (get-buffer-window buff-A t) 3565 (or (ediff-get-visible-buffer-window buff-A)
3474 (progn 3566 (progn
3475 (if (get-buffer-window buff-B) 3567 (if (ediff-get-visible-buffer-window buff-B)
3476 (split-window-vertically)) 3568 (split-window-vertically))
3477 (switch-to-buffer buff-A))) 3569 (switch-to-buffer buff-A)))
3478 (error)) 3570 (error))
@@ -3517,6 +3609,8 @@ up an appropriate window config."
3517Hit \\[ediff-recenter] to reset the windows afterward." 3609Hit \\[ediff-recenter] to reset the windows afterward."
3518 (interactive) 3610 (interactive)
3519 (with-output-to-temp-buffer " *ediff-info*" 3611 (with-output-to-temp-buffer " *ediff-info*"
3612 (princ (ediff-version))
3613 (princ "\n\n")
3520 (ediff-eval-in-buffer ediff-A-buffer 3614 (ediff-eval-in-buffer ediff-A-buffer
3521 (if buffer-file-name 3615 (if buffer-file-name
3522 (princ 3616 (princ
@@ -3564,8 +3658,7 @@ Hit \\[ediff-recenter] to reset the windows afterward."
3564 ediff-regexp-focus-A ediff-regexp-focus-B))) 3658 ediff-regexp-focus-A ediff-regexp-focus-B)))
3565 (t (princ "\nSelective browsing via a user-defined method.\n"))) 3659 (t (princ "\nSelective browsing via a user-defined method.\n")))
3566 3660
3567 (princ "\nBug fixes to: Michael Kifer <kifer@cs.sunysb.edu>\n") 3661 (princ "\nBugs: M-x ediff-submit-report")
3568 (princ "Gripes to: /dev/null <dev@null.gov>\n")
3569 )) 3662 ))
3570 3663
3571 3664
@@ -3942,12 +4035,11 @@ them before they disappear."
3942 before-flag after-flag) 4035 before-flag after-flag)
3943 (ediff-eval-in-buffer 4036 (ediff-eval-in-buffer
3944 buffer 4037 buffer
3945 (let ((buffer-read-only nil) 4038 (let ((before-flag-length (length before-flag))
3946 (before-change-function nil)
3947 (inhibit-read-only t)
3948 (before-flag-length (length before-flag))
3949 (after-flag-length (length after-flag)) 4039 (after-flag-length (length after-flag))
3950 ) 4040 (inhibit-read-only t)
4041 buffer-read-only
4042 before-change-function)
3951 (goto-char after-posn) 4043 (goto-char after-posn)
3952 (setq after-posn (point-marker)) ;; after-posn is now a marker 4044 (setq after-posn (point-marker)) ;; after-posn is now a marker
3953 ;; remove the flags, if they're there 4045 ;; remove the flags, if they're there
@@ -3984,16 +4076,14 @@ them before they disappear."
3984 4076
3985;; Modified `emerge-place-flags-in-buffer1'. 4077;; Modified `emerge-place-flags-in-buffer1'.
3986(defun ediff-place-flags-in-buffer1 (buf-type ctl-buffer difference) 4078(defun ediff-place-flags-in-buffer1 (buf-type ctl-buffer difference)
3987 (let ((buffer-read-only nil) 4079 (let ((before-flag-name (if (eq buf-type 'A)
3988 (inhibit-read-only t)
3989 (before-change-function nil)
3990 (before-flag-name (if (eq buf-type 'A)
3991 'ediff-before-flag-A 4080 'ediff-before-flag-A
3992 'ediff-before-flag-B)) 4081 'ediff-before-flag-B))
3993 (after-flag-name (if (eq buf-type 'A) 4082 (after-flag-name (if (eq buf-type 'A)
3994 'ediff-after-flag-A 4083 'ediff-after-flag-A
3995 'ediff-after-flag-B)) 4084 'ediff-after-flag-B))
3996 beg-of-line flag) 4085 (inhibit-read-only t)
4086 buffer-read-only before-change-function beg-of-line flag)
3997 4087
3998 ;; insert the flag before the difference 4088 ;; insert the flag before the difference
3999 (let ((before (ediff-get-diff-posn buf-type 'beg difference ctl-buffer))) 4089 (let ((before (ediff-get-diff-posn buf-type 'beg difference ctl-buffer)))
@@ -4131,20 +4221,22 @@ buffer."
4131 4221
4132 ;; rehighlight the overlay in the background of the 4222 ;; rehighlight the overlay in the background of the
4133 ;; current difference region 4223 ;; current difference region
4134 (ediff-overlay-put (ediff-get-diff-overlay ediff-current-difference 'A) 4224 (let ((overlay-A (ediff-get-diff-overlay ediff-current-difference 'A))
4135 'face (if (ediff-odd-p ediff-current-difference) 4225 (overlay-B (ediff-get-diff-overlay ediff-current-difference 'B)))
4136 'ediff-odd-diff-face-A-var 4226 (ediff-overlay-put overlay-A
4137 'ediff-even-diff-face-A-var)) 4227 'face (if (ediff-odd-p ediff-current-difference)
4138 (ediff-overlay-put (ediff-get-diff-overlay ediff-current-difference 'B) 4228 'ediff-odd-diff-face-A-var
4139 'face (if (ediff-odd-p ediff-current-difference) 4229 'ediff-even-diff-face-A-var))
4140 'ediff-odd-diff-face-B-var 4230 (ediff-overlay-put overlay-B
4141 'ediff-even-diff-face-B-var)) 4231 'face (if (ediff-odd-p ediff-current-difference)
4142 ) 4232 'ediff-odd-diff-face-B-var
4233 'ediff-even-diff-face-B-var))
4234 ))
4143 4235
4144 4236
4145;; delete highlighting overlays, restore faces to their original form 4237;; delete highlighting overlays, restore faces to their original form
4146(defun ediff-unhighlight-diffs-totally () 4238(defun ediff-unhighlight-diffs-totally ()
4147 (setq buffer-read-only nil) 4239 (let (buffer-read-only)
4148 (ediff-unselect-and-select-difference -1) 4240 (ediff-unselect-and-select-difference -1)
4149 4241
4150 (if (and window-system ediff-want-faces) 4242 (if (and window-system ediff-want-faces)
@@ -4161,7 +4253,7 @@ buffer."
4161 (if (ediff-overlayp ediff-current-diff-overlay-B) 4253 (if (ediff-overlayp ediff-current-diff-overlay-B)
4162 (ediff-delete-overlay ediff-current-diff-overlay-B)) 4254 (ediff-delete-overlay ediff-current-diff-overlay-B))
4163 (setq ediff-current-diff-overlay-B nil))) 4255 (setq ediff-current-diff-overlay-B nil)))
4164 ) 4256 ))
4165 4257
4166(defun ediff-clear-diff-vector (vec &optional fin-diffs-also) 4258(defun ediff-clear-diff-vector (vec &optional fin-diffs-also)
4167 ;; null out the difference overlays so they won't slow down future 4259 ;; null out the difference overlays so they won't slow down future
@@ -4398,12 +4490,115 @@ This is the default for `ediff-forward-word-function'."
4398 (if (and flag (> n 0)) 4490 (if (and flag (> n 0))
4399 (funcall ediff-forward-word-function)) 4491 (funcall ediff-forward-word-function))
4400 (point))) 4492 (point)))
4493
4494(defun ediff-get-visible-buffer-window (wind)
4495 (if (ediff-if-lucid)
4496 (get-buffer-window wind t)
4497 (get-buffer-window wind 'visible)))
4401 4498
4402 4499
4403 4500
4404 4501
4405 4502
4406;;; Misc 4503;;; Misc
4504
4505;; These two functions are here to neutralize Lemacs' unwillingless to
4506;; handle overlays whose buffers have been deleted.
4507(defun ediff-move-overlay (overlay beg end &optional buffer)
4508 "Calls `move-overlay' in Emacs and `set-extent-endpoints' in Lemacs.
4509Checks if overlay's buffer exists before actually doing the move."
4510 (let ((buf (ediff-overlay-buffer overlay)))
4511 (if (ediff-buffer-live-p buf)
4512 (if (ediff-if-lucid)
4513 (set-extent-endpoints overlay beg end)
4514 (move-overlay overlay beg end buffer))
4515 (ediff-delete-overlay overlay))))
4516
4517(defun ediff-overlay-put (overlay prop value)
4518 "Calls `overlay-put' or `set-extent-property' depending on Emacs version.
4519Checks if overlay's buffer exists."
4520 (if (ediff-buffer-live-p (ediff-overlay-buffer overlay))
4521 (if (ediff-if-lucid)
4522 (set-extent-property overlay prop value)
4523 (overlay-put overlay prop value))
4524 (ediff-delete-overlay overlay)))
4525
4526
4527;; In Emacs 19.23 and Lucid 19.10, the number of variables to
4528;; file-name-handler has changed.
4529(defun ediff-find-file-name-handler (file)
4530 (let (newvers)
4531 (setq newvers
4532 (cond ((and (boundp 'emacs-major-version)
4533 (> emacs-major-version 19))
4534 t)
4535 ((boundp 'emacs-minor-version)
4536 (if (ediff-if-lucid)
4537 (> emacs-minor-version 9)
4538 (> emacs-minor-version 22)))
4539 (t nil)))
4540 (if newvers
4541 (find-file-name-handler file 'find-file-noselect)
4542 (find-file-name-handler file))))
4543
4544
4545
4546
4547(defun ediff-submit-report ()
4548 "Submit bug report on Ediff."
4549 (interactive)
4550 (let ((reporter-prompt-for-summary-p t)
4551 varlist salutation)
4552 (setq varlist '(ediff-diff-program ediff-diff-options
4553 ediff-fine-diff-program ediff-fine-diff-options
4554 ediff-patch-program ediff-patch-options
4555 ediff-shell
4556 ediff-want-faces ediff-want-default-menus
4557 ediff-auto-refine ediff-highlighting-style
4558 ediff-A-buffer ediff-B-buffer ediff-control-buffer
4559 ediff-forward-word-function))
4560 (setq salutation "
4561Congratulations! You are about to report a bug in Ediff!
4562
4563Please make a concise, accurate summary of what happened
4564and mail it to the address above.
4565
4566Some ``bugs'' may actually not be bugs at all. For instance, if you are
4567reporting that certain difference regions are not matched as you think they
4568should, this is most likely due to the way Unix diff program decides what
4569constitutes a difference region. Ediff is an Emacs interface to diff, and
4570it has nothing to do with those decisions---it only takes the output from
4571diff and presents it in a way that is better suited for human browsing and
4572manipulation.
4573
4574Another popular topic for reports are ``error messages'' arising from
4575byte-compilation. Because Ediff interfaces to several other packages and
4576runs under Emacs and Lucid Emacs, byte-compilation may produce output like
4577this:
4578 While compiling toplevel forms in file ediff.el:
4579 ** reference to free variable pm-color-alist
4580 ........................
4581 While compiling the end of the data:
4582 ** The following functions are not known to be defined:
4583 ediff-valid-color-p, ediff-display-color-p, ediff-set-face,
4584 ........................
4585
4586These are NOT errors, but inevitable warnings that should be ignored.
4587
4588So, please don't report those and similar things. However, if all you wanted
4589is to tell us how much you liked Ediff, go ahead and send this message anyway.
4590
4591------------------------------------------------------------------")
4592
4593 (require 'reporter)
4594
4595 (reporter-submit-bug-report "kifer@cs.sunysb.edu"
4596 (ediff-version)
4597 varlist
4598 nil nil
4599 salutation)
4600 ))
4601
4407 4602
4408(defun ediff-union (list1 list2) 4603(defun ediff-union (list1 list2)
4409 "Combine LIST1 and LIST2 using a set-union operation. 4604 "Combine LIST1 and LIST2 using a set-union operation.