diff 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
line wrap: on
line diff
--- a/lisp/ediff/ediff-util.el	Mon Aug 13 09:00:04 2007 +0200
+++ b/lisp/ediff/ediff-util.el	Mon Aug 13 09:02:59 2007 +0200
@@ -1,6 +1,6 @@
 ;;; ediff-util.el --- the core commands and utilities of ediff
 
-;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+;; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
 
 ;; Author: Michael Kifer <kifer@cs.sunysb.edu>
 
@@ -22,55 +22,14 @@
 ;; Boston, MA 02111-1307, USA.
 
 ;;; Code:
-	 
-(provide 'ediff-util)
-
-;; Compiler pacifier
-(defvar ediff-patch-diagnostics)
-(defvar ediff-patchbufer)
-(defvar ediff-toolbar)
-(defvar ediff-toolbar-3way)
-(defvar bottom-toolbar)
-(defvar bottom-toolbar-visible-p)
-(defvar bottom-toolbar-height)
-(defvar mark-active)
-
-(eval-when-compile
-  (let ((load-path (cons (expand-file-name ".") load-path)))
-    (or (featurep 'ediff-init)
-	(load "ediff-init.el" nil nil 'nosuffix))
-    (or (featurep 'ediff-help)
-	(load "ediff-help.el" nil nil 'nosuffix))
-    (or (featurep 'ediff-mult)
-	(load "ediff-mult.el" nil nil 'nosuffix))
-    (or (featurep 'ediff-wind)
-	(load "ediff-wind.el" nil nil 'nosuffix))
-    (or (featurep 'ediff-diff)
-	(load "ediff-diff.el" nil nil 'nosuffix))
-    (or (featurep 'ediff-merg)
-	(load "ediff-merg.el" nil nil 'nosuffix))
-    (or (featurep 'ediff)
-	(load "ediff.el" nil nil 'nosuffix))
-    (or (featurep 'ediff-tbar)
-	(load "ediff-tbar.el" 'noerror nil 'nosuffix))
-    ))
-;; end pacifier
 
 (require 'ediff-init)
-(require 'ediff-help)
 (require 'ediff-mult)
-(require 'ediff-wind)
-(require 'ediff-diff)
-(require 'ediff-merg)
-
 
-;; be careful with ediff-tbar
-(if ediff-xemacs-p
-    (condition-case nil
-	(require 'ediff-tbar)
-      (error
-       (defun ediff-use-toolbar-p () nil)))
-  (defun ediff-use-toolbar-p () nil))
+;; Pacify compiler and avoid the need in checking for boundp
+(defvar ediff-patch-diagnostics nil)
+(defvar ediff-patchbufer nil)
+;; end pacifier
 
 
 ;;; Functions
@@ -111,6 +70,9 @@
   (run-hooks 'ediff-mode-hook))
 
     
+(require 'ediff-diff)
+(require 'ediff-merg)
+  
 
 ;;; Build keymaps
 
@@ -138,10 +100,6 @@
   (setq ediff-mode-map (make-sparse-keymap))
   (suppress-keymap ediff-mode-map)
   
-  (define-key ediff-mode-map
-    (if ediff-emacs-p [mouse-2] [button2]) 'ediff-help-for-quick-help)
-  (define-key ediff-mode-map "\C-m"  'ediff-help-for-quick-help)
-
   (define-key ediff-mode-map "p" 'ediff-previous-difference)
   (define-key ediff-mode-map "\C-?" 'ediff-previous-difference)
   (define-key ediff-mode-map [backspace] 'ediff-previous-difference)
@@ -225,7 +183,6 @@
   (define-key ediff-mode-map "wa"  'ediff-save-buffer)
   (define-key ediff-mode-map "wb"  'ediff-save-buffer)
   (define-key ediff-mode-map "wd"  'ediff-save-buffer)
-  (define-key ediff-mode-map "="   'ediff-inferior-compare-regions)
   (if (fboundp 'ediff-show-patch-diagnostics)
       (define-key ediff-mode-map "P"  'ediff-show-patch-diagnostics))
   (if ediff-3way-job
@@ -243,6 +200,8 @@
 
 ;;; Setup functions
 
+(require 'ediff-wind)
+
 ;; No longer needed: XEmacs has surrogate minibuffers now.
 ;;(or (boundp 'synchronize-minibuffers)
 ;;    (defvar synchronize-minibuffers nil))
@@ -251,13 +210,10 @@
 ;; It now returns control buffer so other functions can do post-processing
 (defun ediff-setup (buffer-A file-A buffer-B file-B buffer-C file-C
 			     startup-hooks setup-parameters)
-  ;; ediff-convert-standard-filename puts file names in the form appropriate
-  ;; for the OS at hand.
-  (setq file-A (ediff-convert-standard-filename (expand-file-name file-A)))
-  (setq file-B (ediff-convert-standard-filename (expand-file-name file-B)))
+  (setq file-A (expand-file-name file-A))
+  (setq file-B (expand-file-name file-B))
   (if (stringp file-C)
-      (setq file-C
-	    (ediff-convert-standard-filename (expand-file-name file-C))))
+      (setq file-C (expand-file-name file-C)))
   (let* ((control-buffer-name 
 	  (ediff-unique-buffer-name "*Ediff Control Panel" "*"))
 	 (control-buffer (ediff-eval-in-buffer buffer-A
@@ -505,13 +461,11 @@
     (shrink-window-if-larger-than-buffer)
     (or (ediff-multiframe-setup-p)
 	(ediff-indent-help-message))
-    (ediff-set-help-overlays)
-
     (set-buffer-modified-p nil)
     (ediff-refresh-mode-lines)
     (setq ediff-control-window (selected-window))
     (setq ediff-window-config-saved
-	  (format "%S%S%S%S%S%S%S"
+	  (format "\%S\%S\%S\%S\%S\%S\%S"
 		  ediff-control-window
 		  ediff-window-A
 		  ediff-window-B
@@ -519,14 +473,75 @@
 		  ediff-split-window-function
 		  (ediff-multiframe-setup-p)
 		  ediff-wide-display-p))
-
-    ;; In multiframe, toolbar is set in ediff-setup-control-frame
-    (if (not (ediff-multiframe-setup-p))
-	(ediff-make-bottom-toolbar)) ; this checks if toolbar is requested
     (goto-char (point-min))
     (skip-chars-forward ediff-whitespace)))
     
+;; assuming we are in control window, calculate length of the first line in
+;; help message
+(defun ediff-help-message-line-length ()
+  (save-excursion
+    (goto-char (point-min))
+    (if ediff-use-long-help-message
+	(next-line 1))
+    (end-of-line)
+    (current-column)))
     
+    
+(defun ediff-indent-help-message ()
+  (let* ((shift (/ (max 0 (- (window-width (selected-window))
+			     (ediff-help-message-line-length)))
+		   2))
+	 (str (make-string shift ?\ )))
+    (save-excursion
+      (goto-char (point-min))
+      (while (< (point) (point-max))
+	(insert str)
+	(beginning-of-line)
+	(forward-line 1)))))
+      
+
+(defun ediff-set-help-message ()
+  (setq ediff-long-help-message
+	(cond ((and ediff-long-help-message-function
+		    (or (symbolp ediff-long-help-message-function)
+			(consp ediff-long-help-message-function)))
+	       (funcall ediff-long-help-message-function))
+	      (ediff-word-mode 
+	       (concat ediff-long-help-message-head
+		       ediff-long-help-message-word-mode
+		       ediff-long-help-message-tail))
+	      (ediff-narrow-job
+	       (concat ediff-long-help-message-head
+		       ediff-long-help-message-narrow2
+		       ediff-long-help-message-tail))
+	      (ediff-merge-job 
+	       (concat ediff-long-help-message-head
+		       ediff-long-help-message-merge
+		       ediff-long-help-message-tail))
+	      (ediff-diff3-job
+	       (concat ediff-long-help-message-head
+		       ediff-long-help-message-compare3
+		       ediff-long-help-message-tail))
+	      (t 
+	       (concat ediff-long-help-message-head
+		       ediff-long-help-message-compare2
+		       ediff-long-help-message-tail))))
+  (setq ediff-brief-help-message 
+	(cond ((and ediff-brief-help-message-function
+		    (or (symbolp ediff-brief-help-message-function)
+			(consp ediff-brief-help-message-function)))
+	       (funcall ediff-brief-help-message-function))
+	      ((stringp ediff-brief-help-message-function)
+	       ediff-brief-help-message-function)
+	      ((ediff-multiframe-setup-p) ediff-brief-message-string)
+	      (t ; long brief msg, not multiframe --- put in the middle
+	       ediff-brief-message-string)
+	      ))
+  (setq ediff-help-message (if ediff-use-long-help-message
+			       ediff-long-help-message
+			     ediff-brief-help-message))
+  (run-hooks 'ediff-display-help-hook))
+
 
 
 ;;; Commands for working with Ediff
@@ -755,9 +770,8 @@
 		 control-frame
 		 (eq this-command 'ediff-quit))))
 	  ))
-
-    (ediff-restore-highlighting)
-    (ediff-eval-in-buffer control-buf (ediff-refresh-mode-lines))
+    (ediff-eval-in-buffer control-buf
+      (ediff-refresh-mode-lines))
     ))
   
 ;; this function returns to the window it was called from
@@ -867,13 +881,12 @@
 		 ediff-highlight-all-diffs t)))
 		 
     (if (and ediff-use-faces ediff-highlight-all-diffs)
-	(ediff-paint-background-regions)
-      (ediff-paint-background-regions 'unhighlight))
+	(ediff-color-background-regions)
+      (ediff-color-background-regions 'unhighlight))
     
     (ediff-unselect-and-select-difference
      ediff-current-difference 'select-only))
   )
-
   
 (defun ediff-toggle-autorefine ()
   "Toggle auto-refine mode."
@@ -988,13 +1001,12 @@
 		   (setq toggle-ro-cmd 'toggle-read-only)
 		   (beep 1) (beep 1)
 		   (message
-		    "Boy, this is risky! Don't modify this file...")
+		    "Boy, this is risky! Better don't change this file...")
 		   (sit-for 3)))) ; let the user see the warning
 	(if (and toggle-ro-cmd 
 		 (string-match "toggle-read-only" (symbol-name toggle-ro-cmd)))
 	    (save-excursion
 	      (save-window-excursion
-		(select-window (ediff-get-visible-buffer-window buf))
 		(command-execute toggle-ro-cmd)))
 	  (error "Don't know how to toggle read-only in buffer %S" buf))
 	
@@ -1007,51 +1019,30 @@
 	    (message "Warning: file %s is read-only"
 		     (ediff-abbreviate-file-name file) (beep 1)))
 	))))
+  
 
-;; checkout if visited file is checked in
-(defun ediff-maybe-checkout (buf)
-  (let ((file (buffer-file-name buf))
-	(checkout-function (key-binding "\C-x\C-q")))
-    (if (and (ediff-file-checked-in-p file)
-	     (or (beep 1) t)
-	     (y-or-n-p
-	      (format
-	       "File %s is under version control. Check it out? "
-	       (ediff-abbreviate-file-name file))))
-	(ediff-eval-in-buffer buf
-	  (command-execute checkout-function)))))
-	   
-
-;; This is a simple-minded check for whether a file is under version control.
+;; This is a simple-minded check for whether a file is under version control
+;; and is checked out.
 ;; If file,v exists but file doesn't, this file is considered to be not checked
 ;; in and not checked out for the purpose of patching (since patch won't be
 ;; able to read such a file anyway).
 ;; FILE is a string representing file name
-(defun ediff-file-under-version-control (file)
-  (let* ((filedir (file-name-directory file))
-	 (file-nondir (file-name-nondirectory file))
-	 (trial (concat file-nondir ",v"))
-	 (full-trial (concat filedir trial))
-	 (full-rcs-trial (concat filedir "RCS/" trial)))
-    (and (stringp file)
-	 (file-exists-p file)
-	 (or
-	  (and
-	   (file-exists-p full-trial)
-	   ;; in FAT FS, `file,v' and `file' may turn out to be the same!
-	   ;; don't be fooled by this!
-	   (not (equal (file-attributes file)
-		       (file-attributes full-trial))))
-	  ;; check if a version is in RCS/ directory
-	  (file-exists-p full-rcs-trial)))
+(defun ediff-file-checked-out-p (file)
+  (and (stringp file)
+       (file-exists-p file)
+       (file-writable-p file)
+       (or
+	(file-exists-p (concat file ",v"))
+	(file-exists-p (concat "RCS/" file ",v")))
        ))
-
-(defun ediff-file-checked-out-p (file)
-  (and (ediff-file-under-version-control file)
-       (file-writable-p file)))
 (defun ediff-file-checked-in-p (file)
-  (and (ediff-file-under-version-control file)
-       (not (file-writable-p file))))
+  (and (stringp file)
+       (file-exists-p file)
+       (not (file-writable-p file))
+       (or
+	(file-exists-p (concat file ",v"))
+	(file-exists-p (concat "RCS/" file ",v")))
+       ))
       
 (defun ediff-swap-buffers ()
   "Rotate the display of buffers A, B, and C."
@@ -1185,94 +1176,21 @@
 	(setq ediff-window-B nil) ; force update of window config
 	(ediff-recenter 'no-rehighlight)))))
 	
-;;;###autoload
 (defun ediff-toggle-multiframe ()
-  "Switch from multiframe display to single-frame display and back.
-To change the default, set the variable `ediff-window-setup-function',
+  "Switch from the multiframe display to single-frame display and back.
+For a permanent change, set the variable `ediff-window-setup-function',
 which see."
   (interactive)
-  (let (window-setup-func)
-    (or (ediff-window-display-p)
-	(error "%sEmacs is not running as a window application"
-	       (if ediff-emacs-p "" "X")))
-
+  (ediff-barf-if-not-control-buffer)
+  (or (ediff-window-display-p)
+      (error "%sEmacs is not running as a window application"
+	     (if ediff-emacs-p "" "X")))
   (cond ((eq ediff-window-setup-function 'ediff-setup-windows-multiframe)
-	 (setq window-setup-func 'ediff-setup-windows-plain))
+	 (setq ediff-window-setup-function 'ediff-setup-windows-plain))
 	((eq ediff-window-setup-function 'ediff-setup-windows-plain)
-	 (if (ediff-in-control-buffer-p)
-	     (ediff-kill-bottom-toolbar))
-	 (setq window-setup-func 'ediff-setup-windows-multiframe)))
-
-  ;; change default
-  (setq-default ediff-window-setup-function window-setup-func)
-  ;; change in all active ediff sessions
-  (mapcar (function (lambda(buf)
-		      (ediff-eval-in-buffer buf
-			(setq ediff-window-setup-function window-setup-func
-			      ediff-window-B nil))))
-	  ediff-session-registry)
-  (if (ediff-in-control-buffer-p)
-      (ediff-recenter 'no-rehighlight))))
-
-
-;;;###autoload
-(defun ediff-toggle-use-toolbar ()
-  "Enable or disable Ediff toolbar.
-Works only in versions of Emacs that support toolbars.
-To change the default, set the variable `ediff-use-toolbar-p', which see."
-  (interactive)
-  (if (featurep 'ediff-tbar)
-      (progn
-	(or (ediff-window-display-p)
-	    (error "%sEmacs is not running as a window application"
-		   (if ediff-emacs-p "" "X")))
-	(if (ediff-use-toolbar-p)
-	    (ediff-kill-bottom-toolbar))
-	;; do this only after killing the toolbar
-	(setq ediff-use-toolbar-p (not ediff-use-toolbar-p))
-	
-	(mapcar (function (lambda(buf)
-			    (ediff-eval-in-buffer buf
-			      ;; force redisplay
-			      (setq ediff-window-config-saved "")
-			      )))
-		ediff-session-registry)
-	(if (ediff-in-control-buffer-p)
-	    (ediff-recenter 'no-rehighlight)))))
-
-
-;; if was using toolbar, kill it
-(defun ediff-kill-bottom-toolbar ()
-  ;; Using ctl-buffer or ediff-control-window for LOCALE does not
-  ;; work properly in XEmacs 19.14: we have to use
-  ;;(selected-frame).
-  ;; The problem with this is that any previous bottom-toolbar
-  ;; will not re-appear after our cleanup here.  Is there a way
-  ;; to do "push" and "pop" toolbars ?  --marcpa  
-  (if (ediff-use-toolbar-p)
-      (progn
-	(set-specifier bottom-toolbar (list (selected-frame) nil))
-	(set-specifier bottom-toolbar-visible-p (list (selected-frame) nil)))))
-
-;; If wants to use toolbar, make it.
-;; If not, zero the toolbar for XEmacs.
-;; Do nothing for Emacs.
-(defun ediff-make-bottom-toolbar (&optional frame)
-  (if (ediff-window-display-p)
-      (progn
-	(setq frame (or frame (selected-frame)))
-	(cond ((ediff-use-toolbar-p) ; this checks for XEmacs
-	       (set-specifier
-		bottom-toolbar
-		(list frame (if (ediff-3way-comparison-job)
-				ediff-toolbar-3way ediff-toolbar)))
-	       (set-specifier bottom-toolbar-visible-p (list frame t)) 
-	       (set-specifier bottom-toolbar-height
-			      (list frame ediff-toolbar-height)))
-	      (ediff-xemacs-p
-	       (set-specifier bottom-toolbar-height (list frame 0)))
-	      ))
-    ))
+	 (setq ediff-window-setup-function 'ediff-setup-windows-multiframe)))
+  (setq ediff-window-B nil)
+  (ediff-recenter 'no-rehighlight))
 	       
 ;; Merging
 
@@ -1329,7 +1247,7 @@
 	(narrow-to-region
 	 (ediff-overlay-start overl-B) (ediff-overlay-end overl-B)))
       
-      (if ediff-3way-job
+      (if ediff-3way-comparison-job
 	  (ediff-eval-in-buffer ediff-buffer-C
 	    (narrow-to-region
 	     (ediff-overlay-start overl-C) (ediff-overlay-end overl-C))))
@@ -1579,7 +1497,6 @@
 		    (+ ediff-current-difference arg)))
 	    regexp-skip)
 	    
-	(ediff-visible-region)
 	(or (>= n ediff-number-of-differences)
 	    (setq regexp-skip (funcall ediff-skip-diff-region-function n))
 	    (ediff-install-fine-diff-if-necessary n))
@@ -1616,7 +1533,6 @@
       (let ((n (max -1 (- ediff-current-difference arg)))
 	    regexp-skip)
 	    
-	(ediff-visible-region)
 	(or (< n 0)
 	    (setq regexp-skip (funcall ediff-skip-diff-region-function n))
 	    (ediff-install-fine-diff-if-necessary n))
@@ -2235,15 +2151,13 @@
 temporarily reverses the meaning of this variable."
   (interactive "P")
   (ediff-barf-if-not-control-buffer)
-  (let ((ctl-buf (current-buffer)))
-    (if (y-or-n-p (format "Quit this Ediff session%s? "
-			  (if (ediff-buffer-live-p ediff-meta-buffer)
-			      " & show containing session group" "")))
-	(progn
-	  (message "")
-	  (set-buffer ctl-buf)
-	  (ediff-really-quit reverse-default-keep-variants))
-      (message ""))))
+  (if (y-or-n-p (format "Quit this Ediff session%s? "
+			(if (ediff-buffer-live-p ediff-meta-buffer)
+			    " & show containing session group" "")))
+      (progn
+	(message "")
+	(ediff-really-quit reverse-default-keep-variants))
+    (message "")))
 
 
 ;; Perform the quit operations.
@@ -2274,17 +2188,10 @@
 		      (if (ediff-overlayp overl)
 			  (ediff-delete-overlay overl))))
 	  ediff-narrow-bounds)
-
+  
   ;; restore buffer mode line id's in buffer-A/B/C
   (let ((control-buffer ediff-control-buffer)
-	(meta-buffer ediff-meta-buffer)
-	;; suitable working frame
-	(warp-frame (if (and (ediff-window-display-p) (eq ediff-grab-mouse t))
-			(cond ((window-live-p ediff-window-A) 
-			       (window-frame ediff-window-A))
-			      ((window-live-p ediff-window-B) 
-			       (window-frame ediff-window-B))
-			      (t (next-frame))))))
+	(meta-buffer ediff-meta-buffer))
     (condition-case nil
 	(ediff-eval-in-buffer ediff-buffer-A
 	  (setq ediff-this-buffer-ediff-sessions 
@@ -2326,14 +2233,6 @@
   (ediff-update-registry)
   ;; restore state of buffers to what it was before ediff
   (ediff-restore-protected-variables)
-
-  ;; If the user interrupts (canceling saving the merge buffer), continue
-  ;; normally.
-  (condition-case nil
-      (if (ediff-merge-job)
-	  (run-hooks 'ediff-quit-merge-hook))
-    (quit))
-
   ;; good place to kill buffers A/B/C
   (run-hooks 'ediff-cleanup-hook)
   (let ((ediff-keep-variants ediff-keep-variants))
@@ -2343,20 +2242,6 @@
 
   (run-hooks 'ediff-quit-hook)
   (ediff-cleanup-meta-buffer meta-buffer)
-
-  ;; warp mouse into a working window
-  (setq warp-frame  ; if mouse is over a reasonable frame, use it
-	(cond ((and ediff-xemacs-p (window-live-p (car (mouse-position))))
-	       (window-frame (car (mouse-position))))
-	      ((frame-live-p (car (mouse-position)))
-	       (car (mouse-position)))
-	      (t warp-frame)))
-  (if (frame-live-p warp-frame)
-      (set-mouse-position (if ediff-emacs-p
-			      warp-frame
-			    (frame-selected-window warp-frame))
-			  2 1))
-
   (if (ediff-buffer-live-p meta-buffer)
       (ediff-show-meta-buffer meta-buffer))
   ))
@@ -2386,17 +2271,12 @@
     (ediff-kill-buffer-carefully ediff-fine-diff-buffer)
     (ediff-kill-buffer-carefully ediff-tmp-buffer)
     (ediff-kill-buffer-carefully ediff-error-buffer)
+    (ediff-kill-buffer-carefully ediff-patch-diagnostics)
     (ediff-kill-buffer-carefully ediff-msg-buffer)
     (ediff-kill-buffer-carefully ediff-debug-buffer)
-    (if (boundp 'ediff-patch-diagnostics)
-	(ediff-kill-buffer-carefully ediff-patch-diagnostics))
 
     (if (and (ediff-window-display-p) (frame-live-p ctl-frame))
 	(delete-frame ctl-frame))
-    ;; Hide bottom toolbar.  --marcpa
-    (if (not (ediff-multiframe-setup-p))
-	(ediff-kill-bottom-toolbar))
-
     (ediff-kill-buffer-carefully ctl-buf)
       
     (delete-other-windows)
@@ -2410,7 +2290,7 @@
 	(or (ediff-get-visible-buffer-window buff-A)
 	    (progn
 	      (if (ediff-get-visible-buffer-window buff-B)
-		  (funcall ediff-split-window-function))
+		  (split-window-vertically))
 	      (switch-to-buffer buff-A)))
       (error))
     (if three-way-job
@@ -2419,7 +2299,7 @@
 		(progn
 		  (if (or (ediff-get-visible-buffer-window buff-A)
 			  (ediff-get-visible-buffer-window buff-B))
-		      (funcall ediff-split-window-function))
+		      (split-window-vertically))
 		  (switch-to-buffer buff-C)
 		  (balance-windows)))
 	  (error)))
@@ -2457,65 +2337,6 @@
 					(buffer-name ediff-buffer-C)))))
 	(ediff-kill-buffer-carefully ediff-buffer-C))))
 
-(defun ediff-maybe-save-and-delete-merge (&optional save-and-continue)
-  "Default hook to run on quitting a merge job.
-This can also be used to save merge buffer in the middle of an Ediff session.
-
-If the optional SAVE-AND-CONTINUE argument is non-nil, save merge buffer and
-continue. Otherwise:
-If `ediff-autostore-merges' is nil, this does nothing.
-If it is t, it saves the merge buffer in the file `ediff-merge-store-file'
-or asks the user, if the latter is nil. It then asks the user whether to
-delete the merge buffer.
-If `ediff-autostore-merges' is neither nil nor t, the merge buffer is saved
-only if this merge job is part of a group, i.e., was invoked from within
-`ediff-merge-directories', `ediff-merge-directory-revisions', and such."
-  (let ((merge-store-file ediff-merge-store-file)
-	(ediff-autostore-merges ; fake ediff-autostore-merges, if necessary
-	 (if save-and-continue t ediff-autostore-merges)))
-    (if ediff-autostore-merges
-	(cond ((stringp ediff-merge-store-file)
-	       ;; store, ask to delete
-	       (ediff-write-merge-buffer-and-maybe-kill
-		ediff-buffer-C merge-store-file 'show-file save-and-continue))
-	      ((eq ediff-autostore-merges t)
-	       ;; ask for file name
-	       (setq merge-store-file
-		     (read-file-name "Save the merge buffer in file: "))
-	       (ediff-write-merge-buffer-and-maybe-kill
-		ediff-buffer-C merge-store-file nil save-and-continue))
-	      ((and (ediff-buffer-live-p ediff-meta-buffer)
-		    (ediff-eval-in-buffer ediff-meta-buffer
-		      (ediff-merge-metajob)))
-	       ;; This case shouldn't occur, as the parent metajob must pass on
-	       ;; a file name, ediff-merge-store-file, where to save the result
-	       ;; of the merge.
-	       ;; Ask where to save anyway--will decide what to do here later.
-	       (setq merge-store-file
-		     (read-file-name "Save the merge buffer in file: "))
-	       (ediff-write-merge-buffer-and-maybe-kill
-		ediff-buffer-C merge-store-file nil save-and-continue))))
-    ))
-
-;; write merge buffer. If the optional argument save-and-continue is non-nil,
-;; then don't kill the merge buffer
-(defun ediff-write-merge-buffer-and-maybe-kill (buf file
-					       &optional
-					       show-file save-and-continue)
-  (ediff-eval-in-buffer buf
-    (if (or (not (file-exists-p file))
-	    (y-or-n-p (format "File %s exists, overwrite? " file)))
-	(progn
-	  (write-region (point-min) (point-max) file)
-	  (if show-file
-	      (progn
-		(message "Merge buffer saved in: %s" file)
-		(sit-for 2)))
-	  (if (and
-	       (not save-and-continue)
-	       (y-or-n-p "Merge buffer saved in file. Now kill the buffer? "))
-	      (ediff-kill-buffer-carefully buf))))))
-
 ;; The default way of suspending Ediff.
 ;; Buries Ediff buffers, kills all windows.
 (defun ediff-default-suspend-function ()
@@ -2525,9 +2346,8 @@
 	 (buf-A-wind (ediff-get-visible-buffer-window buf-A))
 	 (buf-B-wind (ediff-get-visible-buffer-window buf-B))
 	 (buf-C-wind (ediff-get-visible-buffer-window buf-C))
-	 (buf-patch  (if (boundp 'ediff-patchbufer) ediff-patchbufer nil))
-	 (buf-patch-diag (if (boundp 'ediff-patch-diagnostics)
-			     ediff-patch-diagnostics nil))
+	 (buf-patch  ediff-patchbufer)
+	 (buf-patch-diag ediff-patch-diagnostics)
 	 (buf-err  ediff-error-buffer)
 	 (buf-diff ediff-diff-buffer)
 	 (buf-custom-diff ediff-custom-diff-buffer)
@@ -2548,28 +2368,20 @@
 	  (select-window buf-A-wind)
 	  (delete-other-windows)
 	  (bury-buffer))
-      (if (ediff-buffer-live-p buf-A)
-	  (progn
-	    (set-buffer buf-A)
-	    (bury-buffer))))
+      (if (ediff-buffer-live-p buf-A) (bury-buffer buf-A)))
     (if (window-live-p buf-B-wind)
 	(progn
 	  (select-window buf-B-wind)
 	  (delete-other-windows)
 	  (bury-buffer))
-      (if (ediff-buffer-live-p buf-B)
-	  (progn
-	    (set-buffer buf-B)
-	    (bury-buffer))))
+      (if (ediff-buffer-live-p buf-B) (bury-buffer buf-B)))
     (if (window-live-p buf-C-wind)
 	(progn
 	  (select-window buf-C-wind)
 	  (delete-other-windows)
 	  (bury-buffer))
-      (if (ediff-buffer-live-p buf-C)
-	  (progn
-	    (set-buffer buf-C)
-	    (bury-buffer))))
+      (if (ediff-buffer-live-p buf-C) (bury-buffer buf-C)))
+
     ))
 
      
@@ -2771,7 +2583,8 @@
 	  (setq ediff-current-difference n)
 	  ) ; end protected section
       
-      (ediff-eval-in-buffer control-buf (ediff-refresh-mode-lines))
+      (ediff-eval-in-buffer control-buf
+	(ediff-refresh-mode-lines))
       )))
 
 
@@ -2805,6 +2618,7 @@
 		      prompt
 		      (cond (default-file
 			      (concat " (default " default-file "):"))
+			    ;;((string-match "[?:!,;][ \t]*$" prompt) "")
 			    (t (concat " (default " default-dir "):"))))
 	      default-dir
 	      (or default-file default-dir)
@@ -2859,7 +2673,7 @@
 		    nil          ; don't append---erase
 		    'no-message) 
       (set-file-modes f ediff-temp-file-mode)
-      (ediff-convert-standard-filename (expand-file-name f)))))
+      f)))
 
 ;; Quote metacharacters (using \) when executing diff in Unix, but not in
 ;; EMX OS/2
@@ -2982,177 +2796,29 @@
       (ediff-reset-mouse ediff-control-frame))
   (if (window-live-p ediff-control-window)
       (select-window ediff-control-window)))
-
-
-(defun ediff-inferior-compare-regions ()
-  "Compare regions in an active Ediff session.
-Like ediff-regions-linewise but is called from under an active Ediff session on
-the files that belong to that session.
-
-After quitting the session invoked via this function, type C-l to the parent
-Ediff Control Panel to restore highlighting."
-  (interactive)
-  (let ((answer "")
-	(possibilities (list ?A ?B ?C))
-	(zmacs-regions t)
-	(ctl-buf (current-buffer))
-	quit-now
-	begA begB endA endB bufA bufB)
-
-    (cond ((ediff-merge-job)
-	   (setq bufB ediff-buffer-C)
-	   (while (cond ((eq answer ?A)
-			 (setq bufA ediff-buffer-A
-			       possibilities '(?B))
-			 nil)
-			((eq answer ?B)
-			 (setq bufA ediff-buffer-B
-			       possibilities '(?A))
-			 nil)
-			((equal answer ""))
-			(t (beep 1)
-			   (message "Valid values are A or B")
-			   (sit-for 2)
-			   t))
-	     (let ((cursor-in-echo-area t))
-	       (message "Which buffer to compare to the merge buffer (A/B)? ")
-	       (setq answer (capitalize (read-char-exclusive))))))
-
-	  ((ediff-3way-comparison-job)
-	   (while (cond ((memq answer possibilities)
-			 (setq possibilities (delq answer possibilities))
-			 (setq bufA
-			       (eval
-				(intern (format "ediff-buffer-%c" answer))))
-			 nil)
-			((equal answer ""))
-			(t (beep 1)
-			   (message 
-			    "Valid values are %s"
-			    (mapconcat 'char-to-string possibilities " or "))
-			   (sit-for 2)
-			   t))
-	     (let ((cursor-in-echo-area t))
-	       (message "Enter the 1st buffer you want to compare (%s): "
-			(mapconcat 'char-to-string possibilities "/"))
-	       (setq answer (capitalize (read-char-exclusive)))))
-	   (setq answer "") ; silence error msg
-	   (while (cond ((memq answer possibilities)
-			 (setq possibilities (delq answer possibilities))
-			 (setq bufB
-			       (eval
-				(intern (format "ediff-buffer-%c" answer))))
-			 nil)
-			((equal answer ""))
-			(t (beep 1)
-			   (message 
-			    "Valid values are %s"
-			    (mapconcat 'char-to-string possibilities " or "))
-			   (sit-for 2)
-			   t))
-	     (let ((cursor-in-echo-area t))
-	       (message "Enter the 2nd buffer you want to compare (%s): "
-			(mapconcat 'char-to-string possibilities "/"))
-	       (setq answer (capitalize (read-char-exclusive))))))
-	  (t ; 2way comparison
-	   (setq bufA ediff-buffer-A
-		 bufB ediff-buffer-B
-		 possibilities nil)))
-
-    (ediff-eval-in-buffer bufA
-      (or (mark t)
-	  (error "You forgot to specify a region in buffer %s" (buffer-name)))
-      (setq begA (region-beginning)
-	    endA (region-end))
-      (goto-char begA)
-      (beginning-of-line)
-      (setq begA (point))
-      (goto-char endA)
-      (end-of-line)
-      (or (eobp) (forward-char)) ; include the newline char
-      (setq endA (point)))
-    (ediff-eval-in-buffer bufB
-      (or (mark t)
-	  (error "You forgot to specify a region in buffer %s" (buffer-name)))
-      (setq begB (region-beginning)
-	    endB (region-end))
-      (goto-char begB)
-      (beginning-of-line)
-      (setq begB (point))
-      (goto-char endB)
-      (end-of-line)
-      (or (eobp) (forward-char)) ; include the newline char
-      (setq endB (point)))
-
-    (ediff-unselect-and-select-difference
-     ediff-current-difference 'unselect-only)
-    (ediff-paint-background-regions 'unhighlight)
-
-    (ediff-eval-in-buffer bufA
-      (goto-char begA)
-      (set-mark endA)
-      (narrow-to-region begA endA)
-      ;; (ediff-activate-mark)
-      )
-    ;; (sit-for 0)
-    (ediff-eval-in-buffer bufB
-      (goto-char begB)
-      (set-mark endB)
-      (narrow-to-region begB endB)
-      ;; (ediff-activate-mark)
-      )
-    ;; (sit-for 0)
-    
-    ;; At this point, possibilities contains either the window char A/B/C
-    ;; that was not selected, or it is nil. We delete the window that is not
-    ;; selected.
-    (if possibilities
-	(ediff-eval-in-buffer ctl-buf
-	  (let* ((wind-to-delete (eval
-				  (intern
-				   (format
-				    "ediff-window-%c" (car possibilities)))))
-		 (frame (window-frame wind-to-delete)))
-	    (delete-window wind-to-delete)
-	    (select-frame frame)
-	    (balance-windows))))
-    (or (y-or-n-p 
-	 "Please check regions selected for comparison. Continue? ")
-	(setq quit-now t))
-    
-    (ediff-eval-in-buffer bufA
-      (widen))
-    (ediff-eval-in-buffer bufB
-      (widen))
-    (if quit-now
-	(ediff-eval-in-buffer ctl-buf
-	  (ediff-recenter)
-	  (sit-for 0)
-	  (error "All right. Make up your mind and come back...")))
-
-    (ediff-regions-internal
-     bufA begA endA bufB begB endB
-     nil  			; startup hook
-     'ediff-regions-linewise	; job name
-     nil)			; no word mode
-    ))
       
     
 
+;; will simplify it in due time, when emacs acquires before/after strings
 (defun ediff-remove-flags-from-buffer (buffer overlay)
   (ediff-eval-in-buffer buffer
     (let ((inhibit-read-only t))
       (if ediff-xemacs-p
 	  (ediff-overlay-put overlay 'begin-glyph nil)
+	;; before-string is not yet implemented in emacs.
+	;; when it will be, I will be able to delete much of the rest of
+	;; this function
 	(ediff-overlay-put overlay 'before-string nil))
       
       (if ediff-xemacs-p
 	  (ediff-overlay-put overlay 'end-glyph nil)
+	;; after-string is not yet implemented in emacs.
 	(ediff-overlay-put overlay 'after-string nil))
       )))
 
 
 
+;; will simplify it in due time, when emacs acquires before/after strings
 (defun ediff-place-flags-in-buffer (buf-type buffer ctl-buffer diff)
   (ediff-eval-in-buffer buffer
     (ediff-place-flags-in-buffer1 buf-type ctl-buffer diff)))
@@ -3227,16 +2893,68 @@
     ))
 
 
-;; Restore highlighting to what it should be according to ediff-use-faces,
-;; ediff-highlighting-style, and ediff-highlight-all-diffs variables.
-(defun ediff-restore-highlighting (&optional ctl-buf)
-  (ediff-eval-in-buffer (or ctl-buf (current-buffer))
-    (if (and (ediff-has-face-support-p) 
-	     ediff-use-faces
-	     ediff-highlight-all-diffs)
-	(ediff-paint-background-regions))
-    (ediff-select-difference ediff-current-difference)))
+
+(defun ediff-highlight-diff-in-one-buffer (n buf-type)
+  (if (ediff-buffer-live-p (ediff-get-buffer buf-type))
+      (let* ((buff (ediff-get-buffer buf-type))
+	     (last (ediff-eval-in-buffer buff (point-max)))
+	     (begin (ediff-get-diff-posn buf-type 'beg n))
+	     (end (ediff-get-diff-posn buf-type 'end n))
+	     (xtra (if (equal begin end) 1 0))
+	     (end-hilit (min last (+ end xtra)))
+	     (current-diff-overlay 
+	      (symbol-value
+	       (intern (format "ediff-current-diff-overlay-%S" buf-type))))
+	     )
+	
+	(if ediff-xemacs-p
+	    (ediff-move-overlay current-diff-overlay begin end-hilit)
+	  (ediff-move-overlay current-diff-overlay begin end-hilit buff))
+	;; giving priority of 0 and then changing it may look funny, but
+	;; this overcomes an obscure Emacs bug.
+	(ediff-overlay-put current-diff-overlay 'priority  0)
+	(ediff-overlay-put current-diff-overlay 'priority  
+			   (ediff-highest-priority begin end-hilit buff))
+	(ediff-overlay-put current-diff-overlay 'ediff-diff-num n)
+	
+	;; unhighlight the background overlay for diff n so it won't
+	;; interfere with the current diff overlay
+	(ediff-set-overlay-face (ediff-get-diff-overlay n buf-type) nil)
+	)))
+
 
+(defun ediff-unhighlight-diff-in-one-buffer (buf-type)
+  (if (ediff-buffer-live-p (ediff-get-buffer buf-type))
+      (let ((current-diff-overlay 
+	     (symbol-value
+	      (intern (format "ediff-current-diff-overlay-%S" buf-type))))
+	    (overlay
+	     (ediff-get-diff-overlay ediff-current-difference buf-type))
+	    )
+    
+	(ediff-move-overlay current-diff-overlay 1 1)
+	
+	;; rehighlight the overlay in the background of the
+	;; current difference region
+	(ediff-set-overlay-face
+	 overlay
+	 (if (and (ediff-has-face-support-p)
+		  ediff-use-faces ediff-highlight-all-diffs)
+	     (ediff-background-face buf-type ediff-current-difference)))
+	)))
+
+(defun ediff-unhighlight-diffs-totally-in-one-buffer (buf-type)
+  (ediff-unselect-and-select-difference -1)
+  (if (and (ediff-has-face-support-p) ediff-use-faces)
+      (let* ((inhibit-quit t)
+	     (current-diff-overlay-var
+	      (intern (format "ediff-current-diff-overlay-%S" buf-type)))
+	     (current-diff-overlay (symbol-value current-diff-overlay-var)))
+	(ediff-color-background-regions 'unhighlight)
+	(if (ediff-overlayp current-diff-overlay)
+	    (ediff-delete-overlay current-diff-overlay))
+	(set current-diff-overlay-var nil)
+	)))
 
     
 ;; null out difference overlays so they won't slow down future
@@ -3255,10 +2973,58 @@
   ;; allow them to be garbage collected
   (set vec-var nil))
 
+(defun ediff-color-background-regions (&optional unhighlight)
+  (ediff-color-background-regions-in-one-buffer
+   'A unhighlight)
+  (ediff-color-background-regions-in-one-buffer
+   'B unhighlight)
+  (ediff-color-background-regions-in-one-buffer
+   'C unhighlight)
+  (ediff-color-background-regions-in-one-buffer
+   'Ancestor unhighlight))
+
+(defun ediff-color-background-regions-in-one-buffer (buf-type unhighlight)
+  (let ((diff-vector 
+	 (eval (intern (format "ediff-difference-vector-%S" buf-type))))
+	overl diff-num)
+    (mapcar (function
+	     (lambda (rec)
+	       (setq overl (ediff-get-diff-overlay-from-diff-record rec)
+		     diff-num (ediff-overlay-get overl 'ediff-diff-num))
+	       (ediff-set-overlay-face
+		overl
+		(if (not unhighlight)
+		    (ediff-background-face buf-type diff-num))
+		)))
+	    diff-vector)))
        
 
 ;;; Misc
 
+;; These two functions are here to neutralize XEmacs unwillingless to
+;; handle overlays whose buffers were deleted.
+(defun ediff-move-overlay (overlay beg end &optional buffer)
+  "Calls `move-overlay' in Emacs and `set-extent-endpoints' in Lemacs.
+Checks if overlay's buffer exists before actually doing the move."
+  (let ((buf (and overlay (ediff-overlay-buffer overlay))))
+    (if (ediff-buffer-live-p buf)
+	(if ediff-xemacs-p
+	    (set-extent-endpoints overlay beg end)
+	  (move-overlay overlay beg end buffer))
+      ;; buffer's dead
+      (if overlay
+	  (ediff-delete-overlay overlay)))))
+	  
+(defun ediff-overlay-put (overlay prop value)
+  "Calls `overlay-put' or `set-extent-property' depending on Emacs version.
+Checks if overlay's buffer exists."
+  (if (ediff-buffer-live-p (ediff-overlay-buffer overlay))
+      (if ediff-xemacs-p
+	  (set-extent-property overlay prop value)
+	(overlay-put overlay prop value))
+    (ediff-delete-overlay overlay)))
+    
+
 ;; In Emacs, this just makes overlay. In the future, when Emacs will start
 ;; supporting sticky overlays, this function will make a sticky overlay.
 ;; BEG and END are expressions telling where overlay starts.
@@ -3293,6 +3059,18 @@
 	  (ediff-overlay-put overl 'ediff-diff-num 0)
 	  overl))))
 	  
+(defsubst ediff-overlay-start (overl)
+  (if (ediff-overlayp overl)
+      (if ediff-emacs-p
+	  (overlay-start overl)
+	(extent-start-position overl))))
+	
+(defsubst ediff-overlay-end  (overl)
+  (if (ediff-overlayp overl)
+      (if ediff-emacs-p
+	  (overlay-end overl)
+	(extent-end-position overl))))
+
   
 ;; Like other-buffer, but prefers visible buffers and ignores temporary or
 ;; other insignificant buffers (those beginning with "^[ *]").
@@ -3457,10 +3235,6 @@
   (if ediff-xemacs-p
 	  (zmacs-deactivate-region)
 	(deactivate-mark)))
-(defun ediff-activate-mark ()
-  (if ediff-emacs-p
-      (setq mark-active t)
-    (zmacs-activate-region)))
 
 (cond ((fboundp 'nuke-selective-display)
        ;; XEmacs 19.12 has nuke-selective-display
@@ -3688,7 +3462,8 @@
 ;;; Local Variables:
 ;;; eval: (put 'ediff-defvar-local 'lisp-indent-hook 'defun)
 ;;; eval: (put 'ediff-eval-in-buffer 'lisp-indent-hook 1)
-;;; eval: (put 'ediff-eval-in-buffer 'edebug-form-spec '(form body))
 ;;; End:
 
+(provide 'ediff-util)
+
 ;;; ediff-util.el ends here