comparison lisp/ediff/ediff-util.el @ 70:131b0175ea99 r20-0b30

Import from CVS: tag r20-0b30
author cvs
date Mon, 13 Aug 2007 09:02:59 +0200
parents 0293115a14e9
children c7528f8e288d
comparison
equal deleted inserted replaced
69:804d1389bcd6 70:131b0175ea99
1 ;;; ediff-util.el --- the core commands and utilities of ediff 1 ;;; ediff-util.el --- the core commands and utilities of ediff
2 2
3 ;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc. 3 ;; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
4 4
5 ;; Author: Michael Kifer <kifer@cs.sunysb.edu> 5 ;; Author: Michael Kifer <kifer@cs.sunysb.edu>
6 6
7 ;; This file is part of GNU Emacs. 7 ;; This file is part of GNU Emacs.
8 8
20 ;; along with GNU Emacs; see the file COPYING. If not, write to the 20 ;; along with GNU Emacs; see the file COPYING. If not, write to the
21 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, 21 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA. 22 ;; Boston, MA 02111-1307, USA.
23 23
24 ;;; Code: 24 ;;; Code:
25 25
26 (provide 'ediff-util) 26 (require 'ediff-init)
27 27 (require 'ediff-mult)
28 ;; Compiler pacifier 28
29 (defvar ediff-patch-diagnostics) 29 ;; Pacify compiler and avoid the need in checking for boundp
30 (defvar ediff-patchbufer) 30 (defvar ediff-patch-diagnostics nil)
31 (defvar ediff-toolbar) 31 (defvar ediff-patchbufer nil)
32 (defvar ediff-toolbar-3way)
33 (defvar bottom-toolbar)
34 (defvar bottom-toolbar-visible-p)
35 (defvar bottom-toolbar-height)
36 (defvar mark-active)
37
38 (eval-when-compile
39 (let ((load-path (cons (expand-file-name ".") load-path)))
40 (or (featurep 'ediff-init)
41 (load "ediff-init.el" nil nil 'nosuffix))
42 (or (featurep 'ediff-help)
43 (load "ediff-help.el" nil nil 'nosuffix))
44 (or (featurep 'ediff-mult)
45 (load "ediff-mult.el" nil nil 'nosuffix))
46 (or (featurep 'ediff-wind)
47 (load "ediff-wind.el" nil nil 'nosuffix))
48 (or (featurep 'ediff-diff)
49 (load "ediff-diff.el" nil nil 'nosuffix))
50 (or (featurep 'ediff-merg)
51 (load "ediff-merg.el" nil nil 'nosuffix))
52 (or (featurep 'ediff)
53 (load "ediff.el" nil nil 'nosuffix))
54 (or (featurep 'ediff-tbar)
55 (load "ediff-tbar.el" 'noerror nil 'nosuffix))
56 ))
57 ;; end pacifier 32 ;; end pacifier
58
59 (require 'ediff-init)
60 (require 'ediff-help)
61 (require 'ediff-mult)
62 (require 'ediff-wind)
63 (require 'ediff-diff)
64 (require 'ediff-merg)
65
66
67 ;; be careful with ediff-tbar
68 (if ediff-xemacs-p
69 (condition-case nil
70 (require 'ediff-tbar)
71 (error
72 (defun ediff-use-toolbar-p () nil)))
73 (defun ediff-use-toolbar-p () nil))
74 33
75 34
76 ;;; Functions 35 ;;; Functions
77 36
78 (defun ediff-mode () 37 (defun ediff-mode ()
109 (setq major-mode 'ediff-mode) 68 (setq major-mode 'ediff-mode)
110 (setq mode-name "Ediff") 69 (setq mode-name "Ediff")
111 (run-hooks 'ediff-mode-hook)) 70 (run-hooks 'ediff-mode-hook))
112 71
113 72
73 (require 'ediff-diff)
74 (require 'ediff-merg)
75
114 76
115 ;;; Build keymaps 77 ;;; Build keymaps
116 78
117 (ediff-defvar-local ediff-mode-map nil 79 (ediff-defvar-local ediff-mode-map nil
118 "Local keymap used in Ediff mode. 80 "Local keymap used in Ediff mode.
136 (defun ediff-setup-keymap () 98 (defun ediff-setup-keymap ()
137 "Set up the keymap used in the control buffer of Ediff." 99 "Set up the keymap used in the control buffer of Ediff."
138 (setq ediff-mode-map (make-sparse-keymap)) 100 (setq ediff-mode-map (make-sparse-keymap))
139 (suppress-keymap ediff-mode-map) 101 (suppress-keymap ediff-mode-map)
140 102
141 (define-key ediff-mode-map
142 (if ediff-emacs-p [mouse-2] [button2]) 'ediff-help-for-quick-help)
143 (define-key ediff-mode-map "\C-m" 'ediff-help-for-quick-help)
144
145 (define-key ediff-mode-map "p" 'ediff-previous-difference) 103 (define-key ediff-mode-map "p" 'ediff-previous-difference)
146 (define-key ediff-mode-map "\C-?" 'ediff-previous-difference) 104 (define-key ediff-mode-map "\C-?" 'ediff-previous-difference)
147 (define-key ediff-mode-map [backspace] 'ediff-previous-difference) 105 (define-key ediff-mode-map [backspace] 'ediff-previous-difference)
148 (define-key ediff-mode-map [delete] 'ediff-previous-difference) 106 (define-key ediff-mode-map [delete] 'ediff-previous-difference)
149 (define-key ediff-mode-map "\C-h" (if ediff-no-emacs-help-in-control-buffer 107 (define-key ediff-mode-map "\C-h" (if ediff-no-emacs-help-in-control-buffer
223 (define-key ediff-mode-map "B" 'ediff-toggle-read-only) 181 (define-key ediff-mode-map "B" 'ediff-toggle-read-only)
224 (define-key ediff-mode-map "w" nil) 182 (define-key ediff-mode-map "w" nil)
225 (define-key ediff-mode-map "wa" 'ediff-save-buffer) 183 (define-key ediff-mode-map "wa" 'ediff-save-buffer)
226 (define-key ediff-mode-map "wb" 'ediff-save-buffer) 184 (define-key ediff-mode-map "wb" 'ediff-save-buffer)
227 (define-key ediff-mode-map "wd" 'ediff-save-buffer) 185 (define-key ediff-mode-map "wd" 'ediff-save-buffer)
228 (define-key ediff-mode-map "=" 'ediff-inferior-compare-regions)
229 (if (fboundp 'ediff-show-patch-diagnostics) 186 (if (fboundp 'ediff-show-patch-diagnostics)
230 (define-key ediff-mode-map "P" 'ediff-show-patch-diagnostics)) 187 (define-key ediff-mode-map "P" 'ediff-show-patch-diagnostics))
231 (if ediff-3way-job 188 (if ediff-3way-job
232 (progn 189 (progn
233 (define-key ediff-mode-map "wc" 'ediff-save-buffer) 190 (define-key ediff-mode-map "wc" 'ediff-save-buffer)
241 (run-hooks 'ediff-keymap-setup-hook)) 198 (run-hooks 'ediff-keymap-setup-hook))
242 199
243 200
244 ;;; Setup functions 201 ;;; Setup functions
245 202
203 (require 'ediff-wind)
204
246 ;; No longer needed: XEmacs has surrogate minibuffers now. 205 ;; No longer needed: XEmacs has surrogate minibuffers now.
247 ;;(or (boundp 'synchronize-minibuffers) 206 ;;(or (boundp 'synchronize-minibuffers)
248 ;; (defvar synchronize-minibuffers nil)) 207 ;; (defvar synchronize-minibuffers nil))
249 208
250 ;; Common startup entry for all Ediff functions 209 ;; Common startup entry for all Ediff functions
251 ;; It now returns control buffer so other functions can do post-processing 210 ;; It now returns control buffer so other functions can do post-processing
252 (defun ediff-setup (buffer-A file-A buffer-B file-B buffer-C file-C 211 (defun ediff-setup (buffer-A file-A buffer-B file-B buffer-C file-C
253 startup-hooks setup-parameters) 212 startup-hooks setup-parameters)
254 ;; ediff-convert-standard-filename puts file names in the form appropriate 213 (setq file-A (expand-file-name file-A))
255 ;; for the OS at hand. 214 (setq file-B (expand-file-name file-B))
256 (setq file-A (ediff-convert-standard-filename (expand-file-name file-A)))
257 (setq file-B (ediff-convert-standard-filename (expand-file-name file-B)))
258 (if (stringp file-C) 215 (if (stringp file-C)
259 (setq file-C 216 (setq file-C (expand-file-name file-C)))
260 (ediff-convert-standard-filename (expand-file-name file-C))))
261 (let* ((control-buffer-name 217 (let* ((control-buffer-name
262 (ediff-unique-buffer-name "*Ediff Control Panel" "*")) 218 (ediff-unique-buffer-name "*Ediff Control Panel" "*"))
263 (control-buffer (ediff-eval-in-buffer buffer-A 219 (control-buffer (ediff-eval-in-buffer buffer-A
264 (get-buffer-create control-buffer-name)))) 220 (get-buffer-create control-buffer-name))))
265 (ediff-eval-in-buffer control-buffer 221 (ediff-eval-in-buffer control-buffer
503 (ediff-set-help-message) 459 (ediff-set-help-message)
504 (insert ediff-help-message) 460 (insert ediff-help-message)
505 (shrink-window-if-larger-than-buffer) 461 (shrink-window-if-larger-than-buffer)
506 (or (ediff-multiframe-setup-p) 462 (or (ediff-multiframe-setup-p)
507 (ediff-indent-help-message)) 463 (ediff-indent-help-message))
508 (ediff-set-help-overlays)
509
510 (set-buffer-modified-p nil) 464 (set-buffer-modified-p nil)
511 (ediff-refresh-mode-lines) 465 (ediff-refresh-mode-lines)
512 (setq ediff-control-window (selected-window)) 466 (setq ediff-control-window (selected-window))
513 (setq ediff-window-config-saved 467 (setq ediff-window-config-saved
514 (format "%S%S%S%S%S%S%S" 468 (format "\%S\%S\%S\%S\%S\%S\%S"
515 ediff-control-window 469 ediff-control-window
516 ediff-window-A 470 ediff-window-A
517 ediff-window-B 471 ediff-window-B
518 ediff-window-C 472 ediff-window-C
519 ediff-split-window-function 473 ediff-split-window-function
520 (ediff-multiframe-setup-p) 474 (ediff-multiframe-setup-p)
521 ediff-wide-display-p)) 475 ediff-wide-display-p))
522
523 ;; In multiframe, toolbar is set in ediff-setup-control-frame
524 (if (not (ediff-multiframe-setup-p))
525 (ediff-make-bottom-toolbar)) ; this checks if toolbar is requested
526 (goto-char (point-min)) 476 (goto-char (point-min))
527 (skip-chars-forward ediff-whitespace))) 477 (skip-chars-forward ediff-whitespace)))
528 478
529 479 ;; assuming we are in control window, calculate length of the first line in
480 ;; help message
481 (defun ediff-help-message-line-length ()
482 (save-excursion
483 (goto-char (point-min))
484 (if ediff-use-long-help-message
485 (next-line 1))
486 (end-of-line)
487 (current-column)))
488
489
490 (defun ediff-indent-help-message ()
491 (let* ((shift (/ (max 0 (- (window-width (selected-window))
492 (ediff-help-message-line-length)))
493 2))
494 (str (make-string shift ?\ )))
495 (save-excursion
496 (goto-char (point-min))
497 (while (< (point) (point-max))
498 (insert str)
499 (beginning-of-line)
500 (forward-line 1)))))
501
502
503 (defun ediff-set-help-message ()
504 (setq ediff-long-help-message
505 (cond ((and ediff-long-help-message-function
506 (or (symbolp ediff-long-help-message-function)
507 (consp ediff-long-help-message-function)))
508 (funcall ediff-long-help-message-function))
509 (ediff-word-mode
510 (concat ediff-long-help-message-head
511 ediff-long-help-message-word-mode
512 ediff-long-help-message-tail))
513 (ediff-narrow-job
514 (concat ediff-long-help-message-head
515 ediff-long-help-message-narrow2
516 ediff-long-help-message-tail))
517 (ediff-merge-job
518 (concat ediff-long-help-message-head
519 ediff-long-help-message-merge
520 ediff-long-help-message-tail))
521 (ediff-diff3-job
522 (concat ediff-long-help-message-head
523 ediff-long-help-message-compare3
524 ediff-long-help-message-tail))
525 (t
526 (concat ediff-long-help-message-head
527 ediff-long-help-message-compare2
528 ediff-long-help-message-tail))))
529 (setq ediff-brief-help-message
530 (cond ((and ediff-brief-help-message-function
531 (or (symbolp ediff-brief-help-message-function)
532 (consp ediff-brief-help-message-function)))
533 (funcall ediff-brief-help-message-function))
534 ((stringp ediff-brief-help-message-function)
535 ediff-brief-help-message-function)
536 ((ediff-multiframe-setup-p) ediff-brief-message-string)
537 (t ; long brief msg, not multiframe --- put in the middle
538 ediff-brief-message-string)
539 ))
540 (setq ediff-help-message (if ediff-use-long-help-message
541 ediff-long-help-message
542 ediff-brief-help-message))
543 (run-hooks 'ediff-display-help-hook))
544
530 545
531 546
532 ;;; Commands for working with Ediff 547 ;;; Commands for working with Ediff
533 548
534 (defun ediff-update-diffs () 549 (defun ediff-update-diffs ()
753 ;; never grab mouse on quit in this place 768 ;; never grab mouse on quit in this place
754 (ediff-reset-mouse 769 (ediff-reset-mouse
755 control-frame 770 control-frame
756 (eq this-command 'ediff-quit)))) 771 (eq this-command 'ediff-quit))))
757 )) 772 ))
758 773 (ediff-eval-in-buffer control-buf
759 (ediff-restore-highlighting) 774 (ediff-refresh-mode-lines))
760 (ediff-eval-in-buffer control-buf (ediff-refresh-mode-lines))
761 )) 775 ))
762 776
763 ;; this function returns to the window it was called from 777 ;; this function returns to the window it was called from
764 ;; (which was the control window) 778 ;; (which was the control window)
765 (defun ediff-recenter-one-window (buf-type) 779 (defun ediff-recenter-one-window (buf-type)
865 (message "Re-highlighting all difference regions") 879 (message "Re-highlighting all difference regions")
866 (setq ediff-use-faces t 880 (setq ediff-use-faces t
867 ediff-highlight-all-diffs t))) 881 ediff-highlight-all-diffs t)))
868 882
869 (if (and ediff-use-faces ediff-highlight-all-diffs) 883 (if (and ediff-use-faces ediff-highlight-all-diffs)
870 (ediff-paint-background-regions) 884 (ediff-color-background-regions)
871 (ediff-paint-background-regions 'unhighlight)) 885 (ediff-color-background-regions 'unhighlight))
872 886
873 (ediff-unselect-and-select-difference 887 (ediff-unselect-and-select-difference
874 ediff-current-difference 'select-only)) 888 ediff-current-difference 'select-only))
875 ) 889 )
876
877 890
878 (defun ediff-toggle-autorefine () 891 (defun ediff-toggle-autorefine ()
879 "Toggle auto-refine mode." 892 "Toggle auto-refine mode."
880 (interactive) 893 (interactive)
881 (ediff-barf-if-not-control-buffer) 894 (ediff-barf-if-not-control-buffer)
986 'buffer-read-only nil buf-type))) 999 'buffer-read-only nil buf-type)))
987 (t 1000 (t
988 (setq toggle-ro-cmd 'toggle-read-only) 1001 (setq toggle-ro-cmd 'toggle-read-only)
989 (beep 1) (beep 1) 1002 (beep 1) (beep 1)
990 (message 1003 (message
991 "Boy, this is risky! Don't modify this file...") 1004 "Boy, this is risky! Better don't change this file...")
992 (sit-for 3)))) ; let the user see the warning 1005 (sit-for 3)))) ; let the user see the warning
993 (if (and toggle-ro-cmd 1006 (if (and toggle-ro-cmd
994 (string-match "toggle-read-only" (symbol-name toggle-ro-cmd))) 1007 (string-match "toggle-read-only" (symbol-name toggle-ro-cmd)))
995 (save-excursion 1008 (save-excursion
996 (save-window-excursion 1009 (save-window-excursion
997 (select-window (ediff-get-visible-buffer-window buf))
998 (command-execute toggle-ro-cmd))) 1010 (command-execute toggle-ro-cmd)))
999 (error "Don't know how to toggle read-only in buffer %S" buf)) 1011 (error "Don't know how to toggle read-only in buffer %S" buf))
1000 1012
1001 ;; Check if we made the current buffer updatable, but its file is RO. 1013 ;; Check if we made the current buffer updatable, but its file is RO.
1002 ;; Signal a warning in this case. 1014 ;; Signal a warning in this case.
1005 (file-exists-p file) 1017 (file-exists-p file)
1006 (not (file-writable-p file))) 1018 (not (file-writable-p file)))
1007 (message "Warning: file %s is read-only" 1019 (message "Warning: file %s is read-only"
1008 (ediff-abbreviate-file-name file) (beep 1))) 1020 (ediff-abbreviate-file-name file) (beep 1)))
1009 )))) 1021 ))))
1010 1022
1011 ;; checkout if visited file is checked in 1023
1012 (defun ediff-maybe-checkout (buf) 1024 ;; This is a simple-minded check for whether a file is under version control
1013 (let ((file (buffer-file-name buf)) 1025 ;; and is checked out.
1014 (checkout-function (key-binding "\C-x\C-q")))
1015 (if (and (ediff-file-checked-in-p file)
1016 (or (beep 1) t)
1017 (y-or-n-p
1018 (format
1019 "File %s is under version control. Check it out? "
1020 (ediff-abbreviate-file-name file))))
1021 (ediff-eval-in-buffer buf
1022 (command-execute checkout-function)))))
1023
1024
1025 ;; This is a simple-minded check for whether a file is under version control.
1026 ;; If file,v exists but file doesn't, this file is considered to be not checked 1026 ;; If file,v exists but file doesn't, this file is considered to be not checked
1027 ;; in and not checked out for the purpose of patching (since patch won't be 1027 ;; in and not checked out for the purpose of patching (since patch won't be
1028 ;; able to read such a file anyway). 1028 ;; able to read such a file anyway).
1029 ;; FILE is a string representing file name 1029 ;; FILE is a string representing file name
1030 (defun ediff-file-under-version-control (file) 1030 (defun ediff-file-checked-out-p (file)
1031 (let* ((filedir (file-name-directory file)) 1031 (and (stringp file)
1032 (file-nondir (file-name-nondirectory file)) 1032 (file-exists-p file)
1033 (trial (concat file-nondir ",v")) 1033 (file-writable-p file)
1034 (full-trial (concat filedir trial)) 1034 (or
1035 (full-rcs-trial (concat filedir "RCS/" trial))) 1035 (file-exists-p (concat file ",v"))
1036 (and (stringp file) 1036 (file-exists-p (concat "RCS/" file ",v")))
1037 (file-exists-p file)
1038 (or
1039 (and
1040 (file-exists-p full-trial)
1041 ;; in FAT FS, `file,v' and `file' may turn out to be the same!
1042 ;; don't be fooled by this!
1043 (not (equal (file-attributes file)
1044 (file-attributes full-trial))))
1045 ;; check if a version is in RCS/ directory
1046 (file-exists-p full-rcs-trial)))
1047 )) 1037 ))
1048
1049 (defun ediff-file-checked-out-p (file)
1050 (and (ediff-file-under-version-control file)
1051 (file-writable-p file)))
1052 (defun ediff-file-checked-in-p (file) 1038 (defun ediff-file-checked-in-p (file)
1053 (and (ediff-file-under-version-control file) 1039 (and (stringp file)
1054 (not (file-writable-p file)))) 1040 (file-exists-p file)
1041 (not (file-writable-p file))
1042 (or
1043 (file-exists-p (concat file ",v"))
1044 (file-exists-p (concat "RCS/" file ",v")))
1045 ))
1055 1046
1056 (defun ediff-swap-buffers () 1047 (defun ediff-swap-buffers ()
1057 "Rotate the display of buffers A, B, and C." 1048 "Rotate the display of buffers A, B, and C."
1058 (interactive) 1049 (interactive)
1059 (ediff-barf-if-not-control-buffer) 1050 (ediff-barf-if-not-control-buffer)
1183 ;;(sit-for (if ediff-xemacs-p 0.4 0)) 1174 ;;(sit-for (if ediff-xemacs-p 0.4 0))
1184 (ediff-eval-in-buffer ctl-buf 1175 (ediff-eval-in-buffer ctl-buf
1185 (setq ediff-window-B nil) ; force update of window config 1176 (setq ediff-window-B nil) ; force update of window config
1186 (ediff-recenter 'no-rehighlight))))) 1177 (ediff-recenter 'no-rehighlight)))))
1187 1178
1188 ;;;###autoload
1189 (defun ediff-toggle-multiframe () 1179 (defun ediff-toggle-multiframe ()
1190 "Switch from multiframe display to single-frame display and back. 1180 "Switch from the multiframe display to single-frame display and back.
1191 To change the default, set the variable `ediff-window-setup-function', 1181 For a permanent change, set the variable `ediff-window-setup-function',
1192 which see." 1182 which see."
1193 (interactive) 1183 (interactive)
1194 (let (window-setup-func) 1184 (ediff-barf-if-not-control-buffer)
1195 (or (ediff-window-display-p) 1185 (or (ediff-window-display-p)
1196 (error "%sEmacs is not running as a window application" 1186 (error "%sEmacs is not running as a window application"
1197 (if ediff-emacs-p "" "X"))) 1187 (if ediff-emacs-p "" "X")))
1198
1199 (cond ((eq ediff-window-setup-function 'ediff-setup-windows-multiframe) 1188 (cond ((eq ediff-window-setup-function 'ediff-setup-windows-multiframe)
1200 (setq window-setup-func 'ediff-setup-windows-plain)) 1189 (setq ediff-window-setup-function 'ediff-setup-windows-plain))
1201 ((eq ediff-window-setup-function 'ediff-setup-windows-plain) 1190 ((eq ediff-window-setup-function 'ediff-setup-windows-plain)
1202 (if (ediff-in-control-buffer-p) 1191 (setq ediff-window-setup-function 'ediff-setup-windows-multiframe)))
1203 (ediff-kill-bottom-toolbar)) 1192 (setq ediff-window-B nil)
1204 (setq window-setup-func 'ediff-setup-windows-multiframe))) 1193 (ediff-recenter 'no-rehighlight))
1205
1206 ;; change default
1207 (setq-default ediff-window-setup-function window-setup-func)
1208 ;; change in all active ediff sessions
1209 (mapcar (function (lambda(buf)
1210 (ediff-eval-in-buffer buf
1211 (setq ediff-window-setup-function window-setup-func
1212 ediff-window-B nil))))
1213 ediff-session-registry)
1214 (if (ediff-in-control-buffer-p)
1215 (ediff-recenter 'no-rehighlight))))
1216
1217
1218 ;;;###autoload
1219 (defun ediff-toggle-use-toolbar ()
1220 "Enable or disable Ediff toolbar.
1221 Works only in versions of Emacs that support toolbars.
1222 To change the default, set the variable `ediff-use-toolbar-p', which see."
1223 (interactive)
1224 (if (featurep 'ediff-tbar)
1225 (progn
1226 (or (ediff-window-display-p)
1227 (error "%sEmacs is not running as a window application"
1228 (if ediff-emacs-p "" "X")))
1229 (if (ediff-use-toolbar-p)
1230 (ediff-kill-bottom-toolbar))
1231 ;; do this only after killing the toolbar
1232 (setq ediff-use-toolbar-p (not ediff-use-toolbar-p))
1233
1234 (mapcar (function (lambda(buf)
1235 (ediff-eval-in-buffer buf
1236 ;; force redisplay
1237 (setq ediff-window-config-saved "")
1238 )))
1239 ediff-session-registry)
1240 (if (ediff-in-control-buffer-p)
1241 (ediff-recenter 'no-rehighlight)))))
1242
1243
1244 ;; if was using toolbar, kill it
1245 (defun ediff-kill-bottom-toolbar ()
1246 ;; Using ctl-buffer or ediff-control-window for LOCALE does not
1247 ;; work properly in XEmacs 19.14: we have to use
1248 ;;(selected-frame).
1249 ;; The problem with this is that any previous bottom-toolbar
1250 ;; will not re-appear after our cleanup here. Is there a way
1251 ;; to do "push" and "pop" toolbars ? --marcpa
1252 (if (ediff-use-toolbar-p)
1253 (progn
1254 (set-specifier bottom-toolbar (list (selected-frame) nil))
1255 (set-specifier bottom-toolbar-visible-p (list (selected-frame) nil)))))
1256
1257 ;; If wants to use toolbar, make it.
1258 ;; If not, zero the toolbar for XEmacs.
1259 ;; Do nothing for Emacs.
1260 (defun ediff-make-bottom-toolbar (&optional frame)
1261 (if (ediff-window-display-p)
1262 (progn
1263 (setq frame (or frame (selected-frame)))
1264 (cond ((ediff-use-toolbar-p) ; this checks for XEmacs
1265 (set-specifier
1266 bottom-toolbar
1267 (list frame (if (ediff-3way-comparison-job)
1268 ediff-toolbar-3way ediff-toolbar)))
1269 (set-specifier bottom-toolbar-visible-p (list frame t))
1270 (set-specifier bottom-toolbar-height
1271 (list frame ediff-toolbar-height)))
1272 (ediff-xemacs-p
1273 (set-specifier bottom-toolbar-height (list frame 0)))
1274 ))
1275 ))
1276 1194
1277 ;; Merging 1195 ;; Merging
1278 1196
1279 (defun ediff-toggle-show-clashes-only () 1197 (defun ediff-toggle-show-clashes-only ()
1280 "Toggle the mode where only the regions where both buffers differ with the ancestor are shown." 1198 "Toggle the mode where only the regions where both buffers differ with the ancestor are shown."
1327 (ediff-overlay-start overl-A) (ediff-overlay-end overl-A))) 1245 (ediff-overlay-start overl-A) (ediff-overlay-end overl-A)))
1328 (ediff-eval-in-buffer ediff-buffer-B 1246 (ediff-eval-in-buffer ediff-buffer-B
1329 (narrow-to-region 1247 (narrow-to-region
1330 (ediff-overlay-start overl-B) (ediff-overlay-end overl-B))) 1248 (ediff-overlay-start overl-B) (ediff-overlay-end overl-B)))
1331 1249
1332 (if ediff-3way-job 1250 (if ediff-3way-comparison-job
1333 (ediff-eval-in-buffer ediff-buffer-C 1251 (ediff-eval-in-buffer ediff-buffer-C
1334 (narrow-to-region 1252 (narrow-to-region
1335 (ediff-overlay-start overl-C) (ediff-overlay-end overl-C)))) 1253 (ediff-overlay-start overl-C) (ediff-overlay-end overl-C))))
1336 ))) 1254 )))
1337 1255
1577 (if (< ediff-current-difference ediff-number-of-differences) 1495 (if (< ediff-current-difference ediff-number-of-differences)
1578 (let ((n (min ediff-number-of-differences 1496 (let ((n (min ediff-number-of-differences
1579 (+ ediff-current-difference arg))) 1497 (+ ediff-current-difference arg)))
1580 regexp-skip) 1498 regexp-skip)
1581 1499
1582 (ediff-visible-region)
1583 (or (>= n ediff-number-of-differences) 1500 (or (>= n ediff-number-of-differences)
1584 (setq regexp-skip (funcall ediff-skip-diff-region-function n)) 1501 (setq regexp-skip (funcall ediff-skip-diff-region-function n))
1585 (ediff-install-fine-diff-if-necessary n)) 1502 (ediff-install-fine-diff-if-necessary n))
1586 (while (and (< n ediff-number-of-differences) 1503 (while (and (< n ediff-number-of-differences)
1587 (or 1504 (or
1614 (ediff-barf-if-not-control-buffer) 1531 (ediff-barf-if-not-control-buffer)
1615 (if (> ediff-current-difference -1) 1532 (if (> ediff-current-difference -1)
1616 (let ((n (max -1 (- ediff-current-difference arg))) 1533 (let ((n (max -1 (- ediff-current-difference arg)))
1617 regexp-skip) 1534 regexp-skip)
1618 1535
1619 (ediff-visible-region)
1620 (or (< n 0) 1536 (or (< n 0)
1621 (setq regexp-skip (funcall ediff-skip-diff-region-function n)) 1537 (setq regexp-skip (funcall ediff-skip-diff-region-function n))
1622 (ediff-install-fine-diff-if-necessary n)) 1538 (ediff-install-fine-diff-if-necessary n))
1623 (while (and (> n -1) 1539 (while (and (> n -1)
1624 (or 1540 (or
2233 containing the variants should be removed \(if they haven't been modified\). 2149 containing the variants should be removed \(if they haven't been modified\).
2234 If it is t, they will be preserved unconditionally. A prefix argument, 2150 If it is t, they will be preserved unconditionally. A prefix argument,
2235 temporarily reverses the meaning of this variable." 2151 temporarily reverses the meaning of this variable."
2236 (interactive "P") 2152 (interactive "P")
2237 (ediff-barf-if-not-control-buffer) 2153 (ediff-barf-if-not-control-buffer)
2238 (let ((ctl-buf (current-buffer))) 2154 (if (y-or-n-p (format "Quit this Ediff session%s? "
2239 (if (y-or-n-p (format "Quit this Ediff session%s? " 2155 (if (ediff-buffer-live-p ediff-meta-buffer)
2240 (if (ediff-buffer-live-p ediff-meta-buffer) 2156 " & show containing session group" "")))
2241 " & show containing session group" ""))) 2157 (progn
2242 (progn 2158 (message "")
2243 (message "") 2159 (ediff-really-quit reverse-default-keep-variants))
2244 (set-buffer ctl-buf) 2160 (message "")))
2245 (ediff-really-quit reverse-default-keep-variants))
2246 (message ""))))
2247 2161
2248 2162
2249 ;; Perform the quit operations. 2163 ;; Perform the quit operations.
2250 (defun ediff-really-quit (reverse-default-keep-variants) 2164 (defun ediff-really-quit (reverse-default-keep-variants)
2251 (ediff-unhighlight-diffs-totally) 2165 (ediff-unhighlight-diffs-totally)
2272 ediff-wide-bounds) 2186 ediff-wide-bounds)
2273 (mapcar (function (lambda (overl) 2187 (mapcar (function (lambda (overl)
2274 (if (ediff-overlayp overl) 2188 (if (ediff-overlayp overl)
2275 (ediff-delete-overlay overl)))) 2189 (ediff-delete-overlay overl))))
2276 ediff-narrow-bounds) 2190 ediff-narrow-bounds)
2277 2191
2278 ;; restore buffer mode line id's in buffer-A/B/C 2192 ;; restore buffer mode line id's in buffer-A/B/C
2279 (let ((control-buffer ediff-control-buffer) 2193 (let ((control-buffer ediff-control-buffer)
2280 (meta-buffer ediff-meta-buffer) 2194 (meta-buffer ediff-meta-buffer))
2281 ;; suitable working frame
2282 (warp-frame (if (and (ediff-window-display-p) (eq ediff-grab-mouse t))
2283 (cond ((window-live-p ediff-window-A)
2284 (window-frame ediff-window-A))
2285 ((window-live-p ediff-window-B)
2286 (window-frame ediff-window-B))
2287 (t (next-frame))))))
2288 (condition-case nil 2195 (condition-case nil
2289 (ediff-eval-in-buffer ediff-buffer-A 2196 (ediff-eval-in-buffer ediff-buffer-A
2290 (setq ediff-this-buffer-ediff-sessions 2197 (setq ediff-this-buffer-ediff-sessions
2291 (delq control-buffer ediff-this-buffer-ediff-sessions)) 2198 (delq control-buffer ediff-this-buffer-ediff-sessions))
2292 (kill-local-variable 'mode-line-buffer-identification) 2199 (kill-local-variable 'mode-line-buffer-identification)
2324 (setq ediff-session-registry 2231 (setq ediff-session-registry
2325 (delq ediff-control-buffer ediff-session-registry)) 2232 (delq ediff-control-buffer ediff-session-registry))
2326 (ediff-update-registry) 2233 (ediff-update-registry)
2327 ;; restore state of buffers to what it was before ediff 2234 ;; restore state of buffers to what it was before ediff
2328 (ediff-restore-protected-variables) 2235 (ediff-restore-protected-variables)
2329
2330 ;; If the user interrupts (canceling saving the merge buffer), continue
2331 ;; normally.
2332 (condition-case nil
2333 (if (ediff-merge-job)
2334 (run-hooks 'ediff-quit-merge-hook))
2335 (quit))
2336
2337 ;; good place to kill buffers A/B/C 2236 ;; good place to kill buffers A/B/C
2338 (run-hooks 'ediff-cleanup-hook) 2237 (run-hooks 'ediff-cleanup-hook)
2339 (let ((ediff-keep-variants ediff-keep-variants)) 2238 (let ((ediff-keep-variants ediff-keep-variants))
2340 (if reverse-default-keep-variants 2239 (if reverse-default-keep-variants
2341 (setq ediff-keep-variants (not ediff-keep-variants))) 2240 (setq ediff-keep-variants (not ediff-keep-variants)))
2342 (or ediff-keep-variants (ediff-janitor 'ask))) 2241 (or ediff-keep-variants (ediff-janitor 'ask)))
2343 2242
2344 (run-hooks 'ediff-quit-hook) 2243 (run-hooks 'ediff-quit-hook)
2345 (ediff-cleanup-meta-buffer meta-buffer) 2244 (ediff-cleanup-meta-buffer meta-buffer)
2346
2347 ;; warp mouse into a working window
2348 (setq warp-frame ; if mouse is over a reasonable frame, use it
2349 (cond ((and ediff-xemacs-p (window-live-p (car (mouse-position))))
2350 (window-frame (car (mouse-position))))
2351 ((frame-live-p (car (mouse-position)))
2352 (car (mouse-position)))
2353 (t warp-frame)))
2354 (if (frame-live-p warp-frame)
2355 (set-mouse-position (if ediff-emacs-p
2356 warp-frame
2357 (frame-selected-window warp-frame))
2358 2 1))
2359
2360 (if (ediff-buffer-live-p meta-buffer) 2245 (if (ediff-buffer-live-p meta-buffer)
2361 (ediff-show-meta-buffer meta-buffer)) 2246 (ediff-show-meta-buffer meta-buffer))
2362 )) 2247 ))
2363 2248
2364 2249
2384 (ediff-kill-buffer-carefully ediff-diff-buffer) 2269 (ediff-kill-buffer-carefully ediff-diff-buffer)
2385 (ediff-kill-buffer-carefully ediff-custom-diff-buffer) 2270 (ediff-kill-buffer-carefully ediff-custom-diff-buffer)
2386 (ediff-kill-buffer-carefully ediff-fine-diff-buffer) 2271 (ediff-kill-buffer-carefully ediff-fine-diff-buffer)
2387 (ediff-kill-buffer-carefully ediff-tmp-buffer) 2272 (ediff-kill-buffer-carefully ediff-tmp-buffer)
2388 (ediff-kill-buffer-carefully ediff-error-buffer) 2273 (ediff-kill-buffer-carefully ediff-error-buffer)
2274 (ediff-kill-buffer-carefully ediff-patch-diagnostics)
2389 (ediff-kill-buffer-carefully ediff-msg-buffer) 2275 (ediff-kill-buffer-carefully ediff-msg-buffer)
2390 (ediff-kill-buffer-carefully ediff-debug-buffer) 2276 (ediff-kill-buffer-carefully ediff-debug-buffer)
2391 (if (boundp 'ediff-patch-diagnostics)
2392 (ediff-kill-buffer-carefully ediff-patch-diagnostics))
2393 2277
2394 (if (and (ediff-window-display-p) (frame-live-p ctl-frame)) 2278 (if (and (ediff-window-display-p) (frame-live-p ctl-frame))
2395 (delete-frame ctl-frame)) 2279 (delete-frame ctl-frame))
2396 ;; Hide bottom toolbar. --marcpa
2397 (if (not (ediff-multiframe-setup-p))
2398 (ediff-kill-bottom-toolbar))
2399
2400 (ediff-kill-buffer-carefully ctl-buf) 2280 (ediff-kill-buffer-carefully ctl-buf)
2401 2281
2402 (delete-other-windows) 2282 (delete-other-windows)
2403 2283
2404 ;; display only if not visible 2284 ;; display only if not visible
2408 (error)) 2288 (error))
2409 (condition-case nil 2289 (condition-case nil
2410 (or (ediff-get-visible-buffer-window buff-A) 2290 (or (ediff-get-visible-buffer-window buff-A)
2411 (progn 2291 (progn
2412 (if (ediff-get-visible-buffer-window buff-B) 2292 (if (ediff-get-visible-buffer-window buff-B)
2413 (funcall ediff-split-window-function)) 2293 (split-window-vertically))
2414 (switch-to-buffer buff-A))) 2294 (switch-to-buffer buff-A)))
2415 (error)) 2295 (error))
2416 (if three-way-job 2296 (if three-way-job
2417 (condition-case nil 2297 (condition-case nil
2418 (or (ediff-get-visible-buffer-window buff-C) 2298 (or (ediff-get-visible-buffer-window buff-C)
2419 (progn 2299 (progn
2420 (if (or (ediff-get-visible-buffer-window buff-A) 2300 (if (or (ediff-get-visible-buffer-window buff-A)
2421 (ediff-get-visible-buffer-window buff-B)) 2301 (ediff-get-visible-buffer-window buff-B))
2422 (funcall ediff-split-window-function)) 2302 (split-window-vertically))
2423 (switch-to-buffer buff-C) 2303 (switch-to-buffer buff-C)
2424 (balance-windows))) 2304 (balance-windows)))
2425 (error))) 2305 (error)))
2426 (message "") 2306 (message "")
2427 )) 2307 ))
2455 (buffer-modified-p ediff-buffer-C) 2335 (buffer-modified-p ediff-buffer-C)
2456 (and ask (not (y-or-n-p (format "Kill buffer C [%s]? " 2336 (and ask (not (y-or-n-p (format "Kill buffer C [%s]? "
2457 (buffer-name ediff-buffer-C))))) 2337 (buffer-name ediff-buffer-C)))))
2458 (ediff-kill-buffer-carefully ediff-buffer-C)))) 2338 (ediff-kill-buffer-carefully ediff-buffer-C))))
2459 2339
2460 (defun ediff-maybe-save-and-delete-merge (&optional save-and-continue)
2461 "Default hook to run on quitting a merge job.
2462 This can also be used to save merge buffer in the middle of an Ediff session.
2463
2464 If the optional SAVE-AND-CONTINUE argument is non-nil, save merge buffer and
2465 continue. Otherwise:
2466 If `ediff-autostore-merges' is nil, this does nothing.
2467 If it is t, it saves the merge buffer in the file `ediff-merge-store-file'
2468 or asks the user, if the latter is nil. It then asks the user whether to
2469 delete the merge buffer.
2470 If `ediff-autostore-merges' is neither nil nor t, the merge buffer is saved
2471 only if this merge job is part of a group, i.e., was invoked from within
2472 `ediff-merge-directories', `ediff-merge-directory-revisions', and such."
2473 (let ((merge-store-file ediff-merge-store-file)
2474 (ediff-autostore-merges ; fake ediff-autostore-merges, if necessary
2475 (if save-and-continue t ediff-autostore-merges)))
2476 (if ediff-autostore-merges
2477 (cond ((stringp ediff-merge-store-file)
2478 ;; store, ask to delete
2479 (ediff-write-merge-buffer-and-maybe-kill
2480 ediff-buffer-C merge-store-file 'show-file save-and-continue))
2481 ((eq ediff-autostore-merges t)
2482 ;; ask for file name
2483 (setq merge-store-file
2484 (read-file-name "Save the merge buffer in file: "))
2485 (ediff-write-merge-buffer-and-maybe-kill
2486 ediff-buffer-C merge-store-file nil save-and-continue))
2487 ((and (ediff-buffer-live-p ediff-meta-buffer)
2488 (ediff-eval-in-buffer ediff-meta-buffer
2489 (ediff-merge-metajob)))
2490 ;; This case shouldn't occur, as the parent metajob must pass on
2491 ;; a file name, ediff-merge-store-file, where to save the result
2492 ;; of the merge.
2493 ;; Ask where to save anyway--will decide what to do here later.
2494 (setq merge-store-file
2495 (read-file-name "Save the merge buffer in file: "))
2496 (ediff-write-merge-buffer-and-maybe-kill
2497 ediff-buffer-C merge-store-file nil save-and-continue))))
2498 ))
2499
2500 ;; write merge buffer. If the optional argument save-and-continue is non-nil,
2501 ;; then don't kill the merge buffer
2502 (defun ediff-write-merge-buffer-and-maybe-kill (buf file
2503 &optional
2504 show-file save-and-continue)
2505 (ediff-eval-in-buffer buf
2506 (if (or (not (file-exists-p file))
2507 (y-or-n-p (format "File %s exists, overwrite? " file)))
2508 (progn
2509 (write-region (point-min) (point-max) file)
2510 (if show-file
2511 (progn
2512 (message "Merge buffer saved in: %s" file)
2513 (sit-for 2)))
2514 (if (and
2515 (not save-and-continue)
2516 (y-or-n-p "Merge buffer saved in file. Now kill the buffer? "))
2517 (ediff-kill-buffer-carefully buf))))))
2518
2519 ;; The default way of suspending Ediff. 2340 ;; The default way of suspending Ediff.
2520 ;; Buries Ediff buffers, kills all windows. 2341 ;; Buries Ediff buffers, kills all windows.
2521 (defun ediff-default-suspend-function () 2342 (defun ediff-default-suspend-function ()
2522 (let* ((buf-A ediff-buffer-A) 2343 (let* ((buf-A ediff-buffer-A)
2523 (buf-B ediff-buffer-B) 2344 (buf-B ediff-buffer-B)
2524 (buf-C ediff-buffer-C) 2345 (buf-C ediff-buffer-C)
2525 (buf-A-wind (ediff-get-visible-buffer-window buf-A)) 2346 (buf-A-wind (ediff-get-visible-buffer-window buf-A))
2526 (buf-B-wind (ediff-get-visible-buffer-window buf-B)) 2347 (buf-B-wind (ediff-get-visible-buffer-window buf-B))
2527 (buf-C-wind (ediff-get-visible-buffer-window buf-C)) 2348 (buf-C-wind (ediff-get-visible-buffer-window buf-C))
2528 (buf-patch (if (boundp 'ediff-patchbufer) ediff-patchbufer nil)) 2349 (buf-patch ediff-patchbufer)
2529 (buf-patch-diag (if (boundp 'ediff-patch-diagnostics) 2350 (buf-patch-diag ediff-patch-diagnostics)
2530 ediff-patch-diagnostics nil))
2531 (buf-err ediff-error-buffer) 2351 (buf-err ediff-error-buffer)
2532 (buf-diff ediff-diff-buffer) 2352 (buf-diff ediff-diff-buffer)
2533 (buf-custom-diff ediff-custom-diff-buffer) 2353 (buf-custom-diff ediff-custom-diff-buffer)
2534 (buf-fine-diff ediff-fine-diff-buffer)) 2354 (buf-fine-diff ediff-fine-diff-buffer))
2535 2355
2546 (if (window-live-p buf-A-wind) 2366 (if (window-live-p buf-A-wind)
2547 (progn 2367 (progn
2548 (select-window buf-A-wind) 2368 (select-window buf-A-wind)
2549 (delete-other-windows) 2369 (delete-other-windows)
2550 (bury-buffer)) 2370 (bury-buffer))
2551 (if (ediff-buffer-live-p buf-A) 2371 (if (ediff-buffer-live-p buf-A) (bury-buffer buf-A)))
2552 (progn
2553 (set-buffer buf-A)
2554 (bury-buffer))))
2555 (if (window-live-p buf-B-wind) 2372 (if (window-live-p buf-B-wind)
2556 (progn 2373 (progn
2557 (select-window buf-B-wind) 2374 (select-window buf-B-wind)
2558 (delete-other-windows) 2375 (delete-other-windows)
2559 (bury-buffer)) 2376 (bury-buffer))
2560 (if (ediff-buffer-live-p buf-B) 2377 (if (ediff-buffer-live-p buf-B) (bury-buffer buf-B)))
2561 (progn
2562 (set-buffer buf-B)
2563 (bury-buffer))))
2564 (if (window-live-p buf-C-wind) 2378 (if (window-live-p buf-C-wind)
2565 (progn 2379 (progn
2566 (select-window buf-C-wind) 2380 (select-window buf-C-wind)
2567 (delete-other-windows) 2381 (delete-other-windows)
2568 (bury-buffer)) 2382 (bury-buffer))
2569 (if (ediff-buffer-live-p buf-C) 2383 (if (ediff-buffer-live-p buf-C) (bury-buffer buf-C)))
2570 (progn 2384
2571 (set-buffer buf-C)
2572 (bury-buffer))))
2573 )) 2385 ))
2574 2386
2575 2387
2576 (defun ediff-suspend () 2388 (defun ediff-suspend ()
2577 "Suspend Ediff. 2389 "Suspend Ediff.
2769 (or (eq flag 'unselect-only) 2581 (or (eq flag 'unselect-only)
2770 (ediff-select-difference n)) 2582 (ediff-select-difference n))
2771 (setq ediff-current-difference n) 2583 (setq ediff-current-difference n)
2772 ) ; end protected section 2584 ) ; end protected section
2773 2585
2774 (ediff-eval-in-buffer control-buf (ediff-refresh-mode-lines)) 2586 (ediff-eval-in-buffer control-buf
2587 (ediff-refresh-mode-lines))
2775 ))) 2588 )))
2776 2589
2777 2590
2778 (defun ediff-read-file-name (prompt default-dir default-file) 2591 (defun ediff-read-file-name (prompt default-dir default-file)
2779 ; This is a modified version of a similar function in `emerge.el'. 2592 ; This is a modified version of a similar function in `emerge.el'.
2803 (read-file-name 2616 (read-file-name
2804 (format "%s%s " 2617 (format "%s%s "
2805 prompt 2618 prompt
2806 (cond (default-file 2619 (cond (default-file
2807 (concat " (default " default-file "):")) 2620 (concat " (default " default-file "):"))
2621 ;;((string-match "[?:!,;][ \t]*$" prompt) "")
2808 (t (concat " (default " default-dir "):")))) 2622 (t (concat " (default " default-dir "):"))))
2809 default-dir 2623 default-dir
2810 (or default-file default-dir) 2624 (or default-file default-dir)
2811 t ; must match, no-confirm 2625 t ; must match, no-confirm
2812 (if default-file (file-name-directory default-file)) 2626 (if default-file (file-name-directory default-file))
2857 (if end end (point-max)) 2671 (if end end (point-max))
2858 f 2672 f
2859 nil ; don't append---erase 2673 nil ; don't append---erase
2860 'no-message) 2674 'no-message)
2861 (set-file-modes f ediff-temp-file-mode) 2675 (set-file-modes f ediff-temp-file-mode)
2862 (ediff-convert-standard-filename (expand-file-name f))))) 2676 f)))
2863 2677
2864 ;; Quote metacharacters (using \) when executing diff in Unix, but not in 2678 ;; Quote metacharacters (using \) when executing diff in Unix, but not in
2865 ;; EMX OS/2 2679 ;; EMX OS/2
2866 ;;(defun ediff-protect-metachars (str) 2680 ;;(defun ediff-protect-metachars (str)
2867 ;; (or (memq system-type '(emx vax-vms axp-vms)) 2681 ;; (or (memq system-type '(emx vax-vms axp-vms))
2980 (raise-frame (selected-frame))))) 2794 (raise-frame (selected-frame)))))
2981 (if (frame-live-p ediff-control-frame) 2795 (if (frame-live-p ediff-control-frame)
2982 (ediff-reset-mouse ediff-control-frame)) 2796 (ediff-reset-mouse ediff-control-frame))
2983 (if (window-live-p ediff-control-window) 2797 (if (window-live-p ediff-control-window)
2984 (select-window ediff-control-window))) 2798 (select-window ediff-control-window)))
2985 2799
2986 2800
2987 (defun ediff-inferior-compare-regions () 2801
2988 "Compare regions in an active Ediff session. 2802 ;; will simplify it in due time, when emacs acquires before/after strings
2989 Like ediff-regions-linewise but is called from under an active Ediff session on
2990 the files that belong to that session.
2991
2992 After quitting the session invoked via this function, type C-l to the parent
2993 Ediff Control Panel to restore highlighting."
2994 (interactive)
2995 (let ((answer "")
2996 (possibilities (list ?A ?B ?C))
2997 (zmacs-regions t)
2998 (ctl-buf (current-buffer))
2999 quit-now
3000 begA begB endA endB bufA bufB)
3001
3002 (cond ((ediff-merge-job)
3003 (setq bufB ediff-buffer-C)
3004 (while (cond ((eq answer ?A)
3005 (setq bufA ediff-buffer-A
3006 possibilities '(?B))
3007 nil)
3008 ((eq answer ?B)
3009 (setq bufA ediff-buffer-B
3010 possibilities '(?A))
3011 nil)
3012 ((equal answer ""))
3013 (t (beep 1)
3014 (message "Valid values are A or B")
3015 (sit-for 2)
3016 t))
3017 (let ((cursor-in-echo-area t))
3018 (message "Which buffer to compare to the merge buffer (A/B)? ")
3019 (setq answer (capitalize (read-char-exclusive))))))
3020
3021 ((ediff-3way-comparison-job)
3022 (while (cond ((memq answer possibilities)
3023 (setq possibilities (delq answer possibilities))
3024 (setq bufA
3025 (eval
3026 (intern (format "ediff-buffer-%c" answer))))
3027 nil)
3028 ((equal answer ""))
3029 (t (beep 1)
3030 (message
3031 "Valid values are %s"
3032 (mapconcat 'char-to-string possibilities " or "))
3033 (sit-for 2)
3034 t))
3035 (let ((cursor-in-echo-area t))
3036 (message "Enter the 1st buffer you want to compare (%s): "
3037 (mapconcat 'char-to-string possibilities "/"))
3038 (setq answer (capitalize (read-char-exclusive)))))
3039 (setq answer "") ; silence error msg
3040 (while (cond ((memq answer possibilities)
3041 (setq possibilities (delq answer possibilities))
3042 (setq bufB
3043 (eval
3044 (intern (format "ediff-buffer-%c" answer))))
3045 nil)
3046 ((equal answer ""))
3047 (t (beep 1)
3048 (message
3049 "Valid values are %s"
3050 (mapconcat 'char-to-string possibilities " or "))
3051 (sit-for 2)
3052 t))
3053 (let ((cursor-in-echo-area t))
3054 (message "Enter the 2nd buffer you want to compare (%s): "
3055 (mapconcat 'char-to-string possibilities "/"))
3056 (setq answer (capitalize (read-char-exclusive))))))
3057 (t ; 2way comparison
3058 (setq bufA ediff-buffer-A
3059 bufB ediff-buffer-B
3060 possibilities nil)))
3061
3062 (ediff-eval-in-buffer bufA
3063 (or (mark t)
3064 (error "You forgot to specify a region in buffer %s" (buffer-name)))
3065 (setq begA (region-beginning)
3066 endA (region-end))
3067 (goto-char begA)
3068 (beginning-of-line)
3069 (setq begA (point))
3070 (goto-char endA)
3071 (end-of-line)
3072 (or (eobp) (forward-char)) ; include the newline char
3073 (setq endA (point)))
3074 (ediff-eval-in-buffer bufB
3075 (or (mark t)
3076 (error "You forgot to specify a region in buffer %s" (buffer-name)))
3077 (setq begB (region-beginning)
3078 endB (region-end))
3079 (goto-char begB)
3080 (beginning-of-line)
3081 (setq begB (point))
3082 (goto-char endB)
3083 (end-of-line)
3084 (or (eobp) (forward-char)) ; include the newline char
3085 (setq endB (point)))
3086
3087 (ediff-unselect-and-select-difference
3088 ediff-current-difference 'unselect-only)
3089 (ediff-paint-background-regions 'unhighlight)
3090
3091 (ediff-eval-in-buffer bufA
3092 (goto-char begA)
3093 (set-mark endA)
3094 (narrow-to-region begA endA)
3095 ;; (ediff-activate-mark)
3096 )
3097 ;; (sit-for 0)
3098 (ediff-eval-in-buffer bufB
3099 (goto-char begB)
3100 (set-mark endB)
3101 (narrow-to-region begB endB)
3102 ;; (ediff-activate-mark)
3103 )
3104 ;; (sit-for 0)
3105
3106 ;; At this point, possibilities contains either the window char A/B/C
3107 ;; that was not selected, or it is nil. We delete the window that is not
3108 ;; selected.
3109 (if possibilities
3110 (ediff-eval-in-buffer ctl-buf
3111 (let* ((wind-to-delete (eval
3112 (intern
3113 (format
3114 "ediff-window-%c" (car possibilities)))))
3115 (frame (window-frame wind-to-delete)))
3116 (delete-window wind-to-delete)
3117 (select-frame frame)
3118 (balance-windows))))
3119 (or (y-or-n-p
3120 "Please check regions selected for comparison. Continue? ")
3121 (setq quit-now t))
3122
3123 (ediff-eval-in-buffer bufA
3124 (widen))
3125 (ediff-eval-in-buffer bufB
3126 (widen))
3127 (if quit-now
3128 (ediff-eval-in-buffer ctl-buf
3129 (ediff-recenter)
3130 (sit-for 0)
3131 (error "All right. Make up your mind and come back...")))
3132
3133 (ediff-regions-internal
3134 bufA begA endA bufB begB endB
3135 nil ; startup hook
3136 'ediff-regions-linewise ; job name
3137 nil) ; no word mode
3138 ))
3139
3140
3141
3142 (defun ediff-remove-flags-from-buffer (buffer overlay) 2803 (defun ediff-remove-flags-from-buffer (buffer overlay)
3143 (ediff-eval-in-buffer buffer 2804 (ediff-eval-in-buffer buffer
3144 (let ((inhibit-read-only t)) 2805 (let ((inhibit-read-only t))
3145 (if ediff-xemacs-p 2806 (if ediff-xemacs-p
3146 (ediff-overlay-put overlay 'begin-glyph nil) 2807 (ediff-overlay-put overlay 'begin-glyph nil)
2808 ;; before-string is not yet implemented in emacs.
2809 ;; when it will be, I will be able to delete much of the rest of
2810 ;; this function
3147 (ediff-overlay-put overlay 'before-string nil)) 2811 (ediff-overlay-put overlay 'before-string nil))
3148 2812
3149 (if ediff-xemacs-p 2813 (if ediff-xemacs-p
3150 (ediff-overlay-put overlay 'end-glyph nil) 2814 (ediff-overlay-put overlay 'end-glyph nil)
2815 ;; after-string is not yet implemented in emacs.
3151 (ediff-overlay-put overlay 'after-string nil)) 2816 (ediff-overlay-put overlay 'after-string nil))
3152 ))) 2817 )))
3153 2818
3154 2819
3155 2820
2821 ;; will simplify it in due time, when emacs acquires before/after strings
3156 (defun ediff-place-flags-in-buffer (buf-type buffer ctl-buffer diff) 2822 (defun ediff-place-flags-in-buffer (buf-type buffer ctl-buffer diff)
3157 (ediff-eval-in-buffer buffer 2823 (ediff-eval-in-buffer buffer
3158 (ediff-place-flags-in-buffer1 buf-type ctl-buffer diff))) 2824 (ediff-place-flags-in-buffer1 buf-type ctl-buffer diff)))
3159 2825
3160 2826
3225 (ediff-overlay-start diff-overlay) 2891 (ediff-overlay-start diff-overlay)
3226 (ediff-overlay-end diff-overlay)) 2892 (ediff-overlay-end diff-overlay))
3227 )) 2893 ))
3228 2894
3229 2895
3230 ;; Restore highlighting to what it should be according to ediff-use-faces, 2896
3231 ;; ediff-highlighting-style, and ediff-highlight-all-diffs variables. 2897 (defun ediff-highlight-diff-in-one-buffer (n buf-type)
3232 (defun ediff-restore-highlighting (&optional ctl-buf) 2898 (if (ediff-buffer-live-p (ediff-get-buffer buf-type))
3233 (ediff-eval-in-buffer (or ctl-buf (current-buffer)) 2899 (let* ((buff (ediff-get-buffer buf-type))
3234 (if (and (ediff-has-face-support-p) 2900 (last (ediff-eval-in-buffer buff (point-max)))
3235 ediff-use-faces 2901 (begin (ediff-get-diff-posn buf-type 'beg n))
3236 ediff-highlight-all-diffs) 2902 (end (ediff-get-diff-posn buf-type 'end n))
3237 (ediff-paint-background-regions)) 2903 (xtra (if (equal begin end) 1 0))
3238 (ediff-select-difference ediff-current-difference))) 2904 (end-hilit (min last (+ end xtra)))
3239 2905 (current-diff-overlay
2906 (symbol-value
2907 (intern (format "ediff-current-diff-overlay-%S" buf-type))))
2908 )
2909
2910 (if ediff-xemacs-p
2911 (ediff-move-overlay current-diff-overlay begin end-hilit)
2912 (ediff-move-overlay current-diff-overlay begin end-hilit buff))
2913 ;; giving priority of 0 and then changing it may look funny, but
2914 ;; this overcomes an obscure Emacs bug.
2915 (ediff-overlay-put current-diff-overlay 'priority 0)
2916 (ediff-overlay-put current-diff-overlay 'priority
2917 (ediff-highest-priority begin end-hilit buff))
2918 (ediff-overlay-put current-diff-overlay 'ediff-diff-num n)
2919
2920 ;; unhighlight the background overlay for diff n so it won't
2921 ;; interfere with the current diff overlay
2922 (ediff-set-overlay-face (ediff-get-diff-overlay n buf-type) nil)
2923 )))
2924
2925
2926 (defun ediff-unhighlight-diff-in-one-buffer (buf-type)
2927 (if (ediff-buffer-live-p (ediff-get-buffer buf-type))
2928 (let ((current-diff-overlay
2929 (symbol-value
2930 (intern (format "ediff-current-diff-overlay-%S" buf-type))))
2931 (overlay
2932 (ediff-get-diff-overlay ediff-current-difference buf-type))
2933 )
2934
2935 (ediff-move-overlay current-diff-overlay 1 1)
2936
2937 ;; rehighlight the overlay in the background of the
2938 ;; current difference region
2939 (ediff-set-overlay-face
2940 overlay
2941 (if (and (ediff-has-face-support-p)
2942 ediff-use-faces ediff-highlight-all-diffs)
2943 (ediff-background-face buf-type ediff-current-difference)))
2944 )))
2945
2946 (defun ediff-unhighlight-diffs-totally-in-one-buffer (buf-type)
2947 (ediff-unselect-and-select-difference -1)
2948 (if (and (ediff-has-face-support-p) ediff-use-faces)
2949 (let* ((inhibit-quit t)
2950 (current-diff-overlay-var
2951 (intern (format "ediff-current-diff-overlay-%S" buf-type)))
2952 (current-diff-overlay (symbol-value current-diff-overlay-var)))
2953 (ediff-color-background-regions 'unhighlight)
2954 (if (ediff-overlayp current-diff-overlay)
2955 (ediff-delete-overlay current-diff-overlay))
2956 (set current-diff-overlay-var nil)
2957 )))
3240 2958
3241 2959
3242 ;; null out difference overlays so they won't slow down future 2960 ;; null out difference overlays so they won't slow down future
3243 ;; editing operations 2961 ;; editing operations
3244 ;; VEC is either a difference vector or a fine-diff vector 2962 ;; VEC is either a difference vector or a fine-diff vector
3253 )) 2971 ))
3254 (symbol-value vec-var))) 2972 (symbol-value vec-var)))
3255 ;; allow them to be garbage collected 2973 ;; allow them to be garbage collected
3256 (set vec-var nil)) 2974 (set vec-var nil))
3257 2975
2976 (defun ediff-color-background-regions (&optional unhighlight)
2977 (ediff-color-background-regions-in-one-buffer
2978 'A unhighlight)
2979 (ediff-color-background-regions-in-one-buffer
2980 'B unhighlight)
2981 (ediff-color-background-regions-in-one-buffer
2982 'C unhighlight)
2983 (ediff-color-background-regions-in-one-buffer
2984 'Ancestor unhighlight))
2985
2986 (defun ediff-color-background-regions-in-one-buffer (buf-type unhighlight)
2987 (let ((diff-vector
2988 (eval (intern (format "ediff-difference-vector-%S" buf-type))))
2989 overl diff-num)
2990 (mapcar (function
2991 (lambda (rec)
2992 (setq overl (ediff-get-diff-overlay-from-diff-record rec)
2993 diff-num (ediff-overlay-get overl 'ediff-diff-num))
2994 (ediff-set-overlay-face
2995 overl
2996 (if (not unhighlight)
2997 (ediff-background-face buf-type diff-num))
2998 )))
2999 diff-vector)))
3258 3000
3259 3001
3260 ;;; Misc 3002 ;;; Misc
3003
3004 ;; These two functions are here to neutralize XEmacs unwillingless to
3005 ;; handle overlays whose buffers were deleted.
3006 (defun ediff-move-overlay (overlay beg end &optional buffer)
3007 "Calls `move-overlay' in Emacs and `set-extent-endpoints' in Lemacs.
3008 Checks if overlay's buffer exists before actually doing the move."
3009 (let ((buf (and overlay (ediff-overlay-buffer overlay))))
3010 (if (ediff-buffer-live-p buf)
3011 (if ediff-xemacs-p
3012 (set-extent-endpoints overlay beg end)
3013 (move-overlay overlay beg end buffer))
3014 ;; buffer's dead
3015 (if overlay
3016 (ediff-delete-overlay overlay)))))
3017
3018 (defun ediff-overlay-put (overlay prop value)
3019 "Calls `overlay-put' or `set-extent-property' depending on Emacs version.
3020 Checks if overlay's buffer exists."
3021 (if (ediff-buffer-live-p (ediff-overlay-buffer overlay))
3022 (if ediff-xemacs-p
3023 (set-extent-property overlay prop value)
3024 (overlay-put overlay prop value))
3025 (ediff-delete-overlay overlay)))
3026
3261 3027
3262 ;; In Emacs, this just makes overlay. In the future, when Emacs will start 3028 ;; In Emacs, this just makes overlay. In the future, when Emacs will start
3263 ;; supporting sticky overlays, this function will make a sticky overlay. 3029 ;; supporting sticky overlays, this function will make a sticky overlay.
3264 ;; BEG and END are expressions telling where overlay starts. 3030 ;; BEG and END are expressions telling where overlay starts.
3265 ;; If they are numbers or buffers, then all is well. Otherwise, they must 3031 ;; If they are numbers or buffers, then all is well. Otherwise, they must
3291 (ediff-overlay-put overl 'start-open nil) 3057 (ediff-overlay-put overl 'start-open nil)
3292 (ediff-overlay-put overl 'end-open nil))) 3058 (ediff-overlay-put overl 'end-open nil)))
3293 (ediff-overlay-put overl 'ediff-diff-num 0) 3059 (ediff-overlay-put overl 'ediff-diff-num 0)
3294 overl)))) 3060 overl))))
3295 3061
3062 (defsubst ediff-overlay-start (overl)
3063 (if (ediff-overlayp overl)
3064 (if ediff-emacs-p
3065 (overlay-start overl)
3066 (extent-start-position overl))))
3067
3068 (defsubst ediff-overlay-end (overl)
3069 (if (ediff-overlayp overl)
3070 (if ediff-emacs-p
3071 (overlay-end overl)
3072 (extent-end-position overl))))
3073
3296 3074
3297 ;; Like other-buffer, but prefers visible buffers and ignores temporary or 3075 ;; Like other-buffer, but prefers visible buffers and ignores temporary or
3298 ;; other insignificant buffers (those beginning with "^[ *]"). 3076 ;; other insignificant buffers (those beginning with "^[ *]").
3299 ;; Gets one arg--buffer name or a list of buffer names (it won't return 3077 ;; Gets one arg--buffer name or a list of buffer names (it won't return
3300 ;; these buffers). 3078 ;; these buffers).
3455 3233
3456 (defun ediff-deactivate-mark () 3234 (defun ediff-deactivate-mark ()
3457 (if ediff-xemacs-p 3235 (if ediff-xemacs-p
3458 (zmacs-deactivate-region) 3236 (zmacs-deactivate-region)
3459 (deactivate-mark))) 3237 (deactivate-mark)))
3460 (defun ediff-activate-mark ()
3461 (if ediff-emacs-p
3462 (setq mark-active t)
3463 (zmacs-activate-region)))
3464 3238
3465 (cond ((fboundp 'nuke-selective-display) 3239 (cond ((fboundp 'nuke-selective-display)
3466 ;; XEmacs 19.12 has nuke-selective-display 3240 ;; XEmacs 19.12 has nuke-selective-display
3467 (fset 'ediff-nuke-selective-display 'nuke-selective-display)) 3241 (fset 'ediff-nuke-selective-display 'nuke-selective-display))
3468 (t 3242 (t
3686 3460
3687 3461
3688 ;;; Local Variables: 3462 ;;; Local Variables:
3689 ;;; eval: (put 'ediff-defvar-local 'lisp-indent-hook 'defun) 3463 ;;; eval: (put 'ediff-defvar-local 'lisp-indent-hook 'defun)
3690 ;;; eval: (put 'ediff-eval-in-buffer 'lisp-indent-hook 1) 3464 ;;; eval: (put 'ediff-eval-in-buffer 'lisp-indent-hook 1)
3691 ;;; eval: (put 'ediff-eval-in-buffer 'edebug-form-spec '(form body))
3692 ;;; End: 3465 ;;; End:
3693 3466
3467 (provide 'ediff-util)
3468
3694 ;;; ediff-util.el ends here 3469 ;;; ediff-util.el ends here