Commits

Anonymous committed 525d217

Wed Oct 14 01:49:52 1998 Michael Kifer <kifer@cs.sunysb.edu>

* ediff-util.el (ediff-cleanup-mess): fixed the case of dead windows.
make sure you are in a good frame before deleting other
windows.

* ediff-mult.el (ediff-show-session-group-hook): new default.

* ediff-vers.el (ediff-pcl-cvs-view-revision):
first cd to the file directory. reportedly works
better with remote files.

* ediff-vers.el (ediff-pcl-cvs-internal, ediff-pcl-cvs-merge-internal):
use file-name-nondirectory when passing files to CVS.

* ediff-help.el (ediff-long-help-message-merge): default changed.

* ediff-util.el (ediff-status-info): updated.
(ediff-toggle-skip-changed-regions): new function.
(ediff-next-difference, ediff-previous-difference):
now skips white space correctly in the merge mode.
(ediff-write-merge-buffer-and-maybe-kill,
ediff-maybe-save-and-delete-merge): changed to give more options to
the user.
(ediff-other-buffer): no longer skips mail buffers.

* ediff-merg.el (ediff-skip-merge-regions-that-differ-from-default):
new variable.
(ediff-skip-merge-region-if-changed-from-default-p,
ediff-merge-changed-from-default-p): new functions.

* ediff-wind.el (ediff-control-frame-parameters):
improved, to reduce distraction.
(ediff-skip-unsuitable-frames): make it skip small windows.

* ediff-diff.el, ediff-init.el: Improved comments.

* ediff-mult.el (ediff-hide-marked-sessions):
make it redraw the meta buffer.
(ediff-collect-custom-diffs): make the diff buffer read-only, not
modified.
(ediff-mark-for-hiding, ediff-mark-for-operation): renamed to *-at-pos.
(ediff-mark-session-for-hiding, ediff-mark-session-for-operation,
ediff-unmark-all-for-operation, ediff-unmark-all-for-hiding): new
functions.
(ediff-setup-meta-map): changed bindings.

* ediff.el, ediff-init.el, ediff-ptch.el, ediff-help.el,
ediff-diff.el, ediff-tbar.el, ediff-wind.el, ediff-mult.el: Removed
function quotes around lambdas.

* ediff.texi: add section about $*.

Comments (0)

Files changed (16)

+Thu Oct  8 04:22:52 1998  Michael Kifer  <kifer@cs.sunysb.edu> 
+ 
+        * ediff-util.el (ediff-cleanup-mess): fixed the case of dead windows. 
+        make sure you are in a good frame before deleting other 
+        windows. 
+ 
+        * ediff-mult.el (ediff-show-session-group-hook): new default. 
+ 
+        * ediff-vers.el (ediff-pcl-cvs-view-revision): 
+        first cd to the file directory. reportedly works 
+        better with remote files. 
+ 
+        * ediff-vers.el (ediff-pcl-cvs-internal, ediff-pcl-cvs-merge-internal):
+        use file-name-nondirectory when passing files to CVS. 
+	
+1998-07-20  Michael Kifer  <kifer@cs.sunysb.edu>
+
+	* ediff-help.el (ediff-long-help-message-merge): default changed.
+
+	* ediff-util.el (ediff-status-info): updated.
+	(ediff-toggle-skip-changed-regions): new function.
+	(ediff-next-difference, ediff-previous-difference):
+	now skips white space correctly in the merge mode.
+	(ediff-write-merge-buffer-and-maybe-kill,
+	ediff-maybe-save-and-delete-merge): changed to give more options to
+	the user. 
+	(ediff-other-buffer): no longer skips mail buffers.
+
+	* ediff-merg.el (ediff-skip-merge-regions-that-differ-from-default):
+	new variable.
+	(ediff-skip-merge-region-if-changed-from-default-p,
+	ediff-merge-changed-from-default-p): new functions.
+
+	* ediff-wind.el (ediff-control-frame-parameters):
+	improved, to reduce distraction.
+	(ediff-skip-unsuitable-frames): make it skip small windows. 
+
+	* ediff-diff.el, ediff-init.el: Improved comments.
+
+	* ediff-mult.el (ediff-hide-marked-sessions):
+	make it redraw the meta buffer.
+	(ediff-collect-custom-diffs): make the diff buffer read-only, not
+	modified. 
+	(ediff-mark-for-hiding, ediff-mark-for-operation): renamed to *-at-pos.
+	(ediff-mark-session-for-hiding, ediff-mark-session-for-operation,
+	ediff-unmark-all-for-operation, ediff-unmark-all-for-hiding): new
+	functions. 
+	(ediff-setup-meta-map): changed bindings.
+
+	* ediff.el, ediff-init.el, ediff-ptch.el, ediff-help.el,
+	ediff-diff.el, ediff-tbar.el, ediff-wind.el, ediff-mult.el: Removed
+	function quotes around lambdas. 
+	
+	* ediff.texi: add section about $*.
+
+	
 1998-04-27  SL Baur  <steve@altair.xemacs.org>
 
 	* dumped-lisp.el: removed.
 # Boston, MA 02111-1307, USA.
 
 VERSION = 1.12
-AUTHOR_VERSION = 2.70.2
+AUTHOR_VERSION = 2.71
 MAINTAINER = XEmacs Development Team <xemacs-beta@xemacs.org>
 PACKAGE = ediff
 PKG_TYPE = regular
-REQUIRES = elib dired xemacs-base
+REQUIRES = pcl-cvs elib dired xemacs-base
 CATEGORY = prog
 
 ELCS = ediff-diff.elc ediff-help.elc ediff-hook.elc ediff-init.elc \
-**** EDIFF -- a comprehensive interface to diff for Emacs 19 and XEmacs 19
-
-**** This version of Ediff requires *at least* Emacs 19.34 or XEmacs 19.14
+**** EDIFF -- a comprehensive interface to diff for Emacs and XEmacs
 
 This directory:
 
    You also need to have a write permission for all directories
    mentioned in LISPDIR, INFODIR, and ETCDIR.
    
-3. XEmacs users must invoke `make' with the parameter EMACS=xemacs
-   or whatever name is used to invoke XEmacs (some sites still use xemacs
-   for Emacs 18). An even better thing would be to edit Makefile directly
-   as indicated in the comments there.
+3. XEmacs users must invoke `make' with the parameter EMACS=xemacs.
+   Even better: edit Makefile directly.
 
 4. Under XEmacs, copy the icons in the `toolbar' directory into
    the-directory-where-xemacs-installed/etc/toolbar/
     ;; fixup diff-list
     (if diff3-job
 	(cond ((not file-A)
-	       (mapcar (function (lambda (elt)
-				   (aset elt 0 nil)
-				   (aset elt 1 nil)))
+	       (mapcar (lambda (elt)
+			 (aset elt 0 nil)
+			 (aset elt 1 nil))
 		       (cdr diff-list)))
 	      ((not file-B)
-	       (mapcar (function (lambda (elt)
-				   (aset elt 2 nil)
-				   (aset elt 3 nil)))
+	       (mapcar (lambda (elt)
+			 (aset elt 2 nil)
+			 (aset elt 3 nil))
 		       (cdr diff-list)))
 	      ((not file-C)
-	       (mapcar (function (lambda (elt)
-				   (aset elt 4 nil)
-				   (aset elt 5 nil)))
+	       (mapcar (lambda (elt)
+			 (aset elt 4 nil)
+			 (aset elt 5 nil))
 		       (cdr diff-list)))
 	  ))
     
   (if ediff-merge-job
       (setq ediff-state-of-merge
 	    (vconcat
-	     (mapcar (function
-		      (lambda (elt)
-			(let ((state-of-merge (aref elt 9))
-			      (state-of-ancestor (aref elt 10)))
-			  (vector
-			   (if state-of-merge (format "%S" state-of-merge))
-			   state-of-ancestor))))
+	     (mapcar (lambda (elt)
+		       (let ((state-of-merge (aref elt 9))
+			     (state-of-ancestor (aref elt 10)))
+			 (vector
+			  ;; state of merge: prefers/default-A/B or combined
+			  (if state-of-merge (format "%S" state-of-merge))
+			  ;; whether the ancestor region is empty
+			  state-of-ancestor)))
 		     ;; the first elt designates type of list
 		     (cdr diff-list))
 	     )))
       (if (= 0 (mod current-diff 10))
 	  (message "Buffer %S: Processing difference region %d of %d"
 		   buf-type current-diff total-diffs))
-      ;; record all overlays for this difference
-      ;; the second elt, nil, is a place holder for the fine diff vector.
-      ;; the third elt, nil, is a place holder for no-fine-diffs flag.
+      ;; Record all overlays for this difference.
+      ;; The 2-d elt, nil, is a place holder for the fine diff vector.
+      ;; The 3-d elt, nil, is a place holder for no-fine-diffs flag.
+      ;; The 4-th elt says which diff region is different from the other two
+      ;; (3-way jobs only).
       (setq diff-overlay-list
 	    (nconc
 	     diff-overlay-list
 	       (or (ediff-get-fine-diff-vector n 'A)
 		   (memq ediff-auto-refine '(off nix))
 		   (ediff-message-if-verbose
-		    "Region %d exceeds auto-refine limit. Type `%s' to refine"
+		    "Region %d exceeds the auto-refinement limit. Type `%s' to refine"
 		    (1+ n)
 		    (substitute-command-keys
 		     "\\[ediff-make-or-kill-fine-diffs]")
 			       ediff-current-diff-overlay-alist))
 			     'priority)
 			    0)))))
-    (mapcar
-     (function (lambda (overl)
-		 (ediff-set-overlay-face overl face)
-		 (ediff-overlay-put overl 'priority priority)))
-     fine-diff-vector)))
+    (mapcar (lambda (overl)
+	      (ediff-set-overlay-face overl face)
+	      (ediff-overlay-put overl 'priority priority))
+	    fine-diff-vector)))
      
 ;; This assumes buffer C and that the region looks like a combination of
 ;; regions in buffer A and C.
     ~ -rotate buffers|     m -wide display       |
 "
   "Help message usually used for 3-way comparison.
-Normally, not a user option. See `ediff-help-message' for details.")
+Normally, not a user option.  See `ediff-help-message' for details.")
   
 (defconst ediff-long-help-message-compare2
   "
     ~ -swap variants |     m -wide display       |  
 "
   "Help message usually used for 2-way comparison.
-Normally, not a user option. See `ediff-help-message' for details.")
+Normally, not a user option.  See `ediff-help-message' for details.")
   
 (defconst ediff-long-help-message-narrow2
   "
     ~ -swap variants |     m -wide display       |  
 "
   "Help message when comparing windows or regions line-by-line.
-Normally, not a user option. See `ediff-help-message' for details.")
+Normally, not a user option.  See `ediff-help-message' for details.")
   
 (defconst ediff-long-help-message-word-mode
   "
     ~ -swap variants |     m -wide display       |  
 "
   "Help message when comparing windows or regions word-by-word.
-Normally, not a user option. See `ediff-help-message' for details.")
+Normally, not a user option.  See `ediff-help-message' for details.")
   
 (defconst ediff-long-help-message-merge
   "
   v/V -scroll up/dn  |     X -read-only in buf X | wx -save buf X              
   </> -scroll lt/rt  |     m -wide display       | wd -save diff output        
     ~ -swap variants |     s -shrink window C    |  / -show ancestor buff      
-                     |     $ -show clashes only  |  & -merge w/new default     
+                     |  $$ -show clashes only    |  & -merge w/new default     
+                     |  $* -skip changed regions |
 "
-  "Help message during merging.
-Normally, not a user option. See `ediff-help-message' for details.")
+  "Help message for merge sessions.
+Normally, not a user option.  See `ediff-help-message' for details.")
 
 ;; The actual long help message.
 (ediff-defvar-local ediff-long-help-message ""
-  "Normally, not a user option. See `ediff-help-message' for details.")
+  "Normally, not a user option.  See `ediff-help-message' for details.")
   
 (defconst ediff-brief-message-string
-  "? -quick help "
+  " ? -quick help "
   "Contents of the brief help message.")
 ;; The actual brief help message
 (ediff-defvar-local ediff-brief-help-message ""
-  "Normally, not a user option. See `ediff-help-message' for details.")
+  "Normally, not a user option.  See `ediff-help-message' for details.")
   
 (ediff-defvar-local ediff-brief-help-message-function nil
   "The brief help message that the user can customize.
 If the user sets this to a parameter-less function, Ediff will use it to
-produce the brief help message. This function must return a string.")
+produce the brief help message.  This function must return a string.")
 (ediff-defvar-local ediff-long-help-message-function nil
   "The long help message that the user can customize.
 See `ediff-brief-help-message-function' for more.")
 
 (defvar ediff-use-long-help-message nil
-  "*If t, Ediff displays a long help message. Short help message otherwise.")
+  "*If t, Ediff displays a long help message.  Short help message otherwise.")
 
 ;; The actual help message.
 (ediff-defvar-local ediff-help-message ""
   "The actual help message.
-Normally, the user shouldn't touch this. However, if you want Ediff to
+Normally, the user shouldn't touch this.  However, if you want Ediff to
 start up with different help messages for different jobs, you can change
 the value of this variable and the variables `ediff-help-message-*' in
 `ediff-startup-hook'.") 
     (if ediff-xemacs-p
 	(setq overl (extent-at pos (current-buffer) 'ediff-help-info)
 	      cmd   (ediff-overlay-get overl 'ediff-help-info))
-      (setq cmd (car (mapcar (function (lambda (elt)
-					 (overlay-get elt 'ediff-help-info)))
+      (setq cmd (car (mapcar (lambda (elt)
+			       (overlay-get elt 'ediff-help-info))
 			     (overlays-at pos)))))
     
     (if (not (stringp cmd))
-	(error "Hmm... I don't see an Ediff command around here..."))
+	(error "Hmm...  I don't see an Ediff command around here..."))
     
     (ediff-documentation "Quick Help Commands")
     
 	    ((string= cmd "z/q") (re-search-forward "^`z'"))
 	    ((string= cmd "%") (re-search-forward "^`%'"))
 	    ((string= cmd "C-l") (re-search-forward "^`C-l'"))
-	    ((string= cmd "$") (re-search-forward "^`\\$'"))
+	    ((string= cmd "$$") (re-search-forward "^`\\$\\$'"))
+	    ((string= cmd "$*") (re-search-forward "^`\\$\\*'"))
 	    ((string= cmd "/") (re-search-forward "^`/'"))
 	    ((string= cmd "&") (re-search-forward "^`&'"))
 	    ((string= cmd "s") (re-search-forward "^`s'"))
 ;; end pacifier
 
 ;; allow menus to be set up without ediff-wind.el being loaded
+;;;###autoload
 (defvar ediff-window-setup-function)
-
-
-(defun ediff-xemacs-init-menus ()
-  (if (featurep 'menubar)
-      (progn
-	(add-submenu
-	 '("Tools") ediff-menu "OO-Browser...")
-	(add-submenu
-	 '("Tools") ediff-merge-menu "OO-Browser...")
-	(add-submenu
-	 '("Tools") epatch-menu "OO-Browser...")
-	(add-submenu
-	 '("Tools") ediff-misc-menu "OO-Browser...")
-	(add-menu-button
-	 '("Tools")
-	 ["-------" nil nil] "OO-Browser...")
-	)))
+ 
+;; Note we wrap this in a progn so that we pick up the whole def
+;; for auto-autoload. That way we do not load ediff-hook.el when defining
+;; the menus.
+;;;###autoload
+(progn
+  (defun ediff-xemacs-init-menus ()
+    (if (featurep 'menubar)
+	(progn
+	  (add-submenu
+	   '("Tools") ediff-menu "OO-Browser...")
+	  (add-submenu
+	   '("Tools") ediff-merge-menu "OO-Browser...")
+	  (add-submenu
+	   '("Tools") epatch-menu "OO-Browser...")
+	  (add-submenu
+	   '("Tools") ediff-misc-menu "OO-Browser...")
+	  (add-menu-button
+	   '("Tools")
+	   ["-------" nil nil] "OO-Browser...")
+	  ))))
 
 
 ;; explicit string-match is needed: ediff-xemacs-p is not defined at build time
+;;;###autoload
 (cond ((string-match "XEmacs" emacs-version)
        (defvar ediff-menu
 	 '("Compare"
 	    :selected (if (featurep 'ediff-tbar)
 			  (ediff-use-toolbar-p))]
 	   ))
-
+       
        ;; put these menus before Object-Oriented-Browser in Tools menu
-;;       (add-hook 'before-init-hook 'ediff-xemacs-init-menus)
-;;       (if (not purify-flag)
-;;	   (ediff-xemacs-init-menus))
-;;       )
-       (ediff-xemacs-init-menus))
+;;;      (add-hook 'before-init-hook 'ediff-xemacs-init-menus)
+;;;      (if (not purify-flag)
+;;;	   (ediff-xemacs-init-menus))
+;;;      )       
+       (if (and (featurep 'menubar) (not (featurep 'infodock))
+		(not (featurep 'ediff-hook)))
+	   (ediff-xemacs-init-menus)))
       
       ;; Emacs--only if menu-bar is loaded
       ((featurep 'menu-bar)
 
 ;; A-list is supposed to be of the form (A . symb) (B . symb)...)
 ;; where the first part of any association is a buffer type and the second is
-;; an appropriate symbol. Given buffer-type, this function returns the
-;; symbol. This is used to avoid using `intern'
+;; an appropriate symbol.  Given buffer-type, this function returns the
+;; symbol.  This is used to avoid using `intern'
 (defsubst ediff-get-symbol-from-alist (buf-type alist)
   (cdr (assoc buf-type alist)))
   
 ;; Tell if it has been previously determined that the region has
 ;; no diffs other than the white space and newlines
 ;; The argument, N, is the diff region number used by Ediff to index the
-;; diff vector. It is 1 less than the number seen by the user.
+;; diff vector.  It is 1 less than the number seen by the user.
 ;; Returns:
 ;;		t  if the diffs are whitespace in all buffers
 ;;		'A (in 3-buf comparison only) if there are only whitespace
 ;;		'C (in 3-buf comparison only) if there are only whitespace
 ;;		   diffs in bufs A and B
 ;;
-;; A difference vector has the form:
+;; A Difference Vector has the form:
 ;; [diff diff diff ...]
 ;; where each diff has the form:
-;; [overlay fine-diff-vector no-fine-diffs-flag]
+;; [overlay fine-diff-vector no-fine-diffs-flag state-of-difference]
 ;; fine-diff-vector is a vector [fine-diff fine-diff fine-diff ...]
+;; no-fine-diffs-flag says if there are fine differences.
+;; state-of-difference is A, B, C, or nil, indicating which buffer is
+;; 	different from the other two (used only in 3-way jobs).
 (defmacro ediff-no-fine-diffs-p (n)
   (` (aref (ediff-get-difference (, n) 'A) 2)))
   
 	 (aref (ediff-get-difference (, n) (, buf-type)) 3))))
 (defmacro ediff-set-state-of-diff (n buf-type val)
   (` (aset (ediff-get-difference (, n) (, buf-type)) 3 (, val))))
+
 (defmacro ediff-get-state-of-merge (n)
   (` (if ediff-state-of-merge
 	 (aref (aref ediff-state-of-merge (, n)) 0))))
-(defmacro ediff-get-state-of-ancestor (n)
-  (` (if ediff-state-of-merge
-	 (aref (aref ediff-state-of-merge (, n)) 1))))
 (defmacro ediff-set-state-of-merge (n val)
   (` (if ediff-state-of-merge
 	 (aset (aref ediff-state-of-merge (, n)) 0 (, val)))))
 
+(defmacro ediff-get-state-of-ancestor (n)
+  (` (if ediff-state-of-merge
+	 (aref (aref ediff-state-of-merge (, n)) 1))))
+
 ;; if flag is t, puts a mark on diff region saying that 
-;; the differences are in white space only. If flag is nil,
+;; the differences are in white space only.  If flag is nil,
 ;; the region is marked as essential (i.e., differences are
 ;; not just in the white space and newlines.)
 (defmacro ediff-mark-diff-as-space-only (n flag)
   
 (defcustom ediff-mode-hook nil
   "*Hook run just after ediff-mode is set up in the control buffer. 
-This is done before any windows or frames are created. One can use it to
+This is done before any windows or frames are created.  One can use it to
 set local variables that determine how the display looks like."
   :type 'hook
   :group 'ediff-hook)
   :type 'hook
   :group 'ediff-hook) 
 (defcustom ediff-cleanup-hook nil
-  "*Hooks to run on exiting Ediff but before killing the control buffer.
-This is a place to do various cleanups, such as deleting the variant buffers.
-Ediff provides a function, `ediff-janitor', as one such possible hook."
+  "*Hooks to run on exiting Ediff but before killing the control and variant buffers."
   :type 'hook
   :group 'ediff-hook)
 
   "Sorry, comparison of identical variants is not what I am made for...")
 (defconst ediff-BAD-DIFF-NUMBER
   ;; %S stands for this-command, %d - diff number, %d - max diff
-  "%S: Bad diff region number, %d. Valid numbers are 1 to %d")
+  "%S: Bad diff region number, %d.  Valid numbers are 1 to %d")
 (defconst ediff-BAD-INFO (format "
 *** The Info file for Ediff, a part of the standard distribution
 *** of %sEmacs, does not seem to be properly installed.
 (ediff-defvar-local ediff-skip-diff-region-function 'ediff-show-all-diffs
   "Function that determines the next/previous diff region to show.
 Should return t for regions to be ignored and nil otherwise.
-This function gets a region number as an argument. The region number
-is the one used internally by Ediff. It is 1 less than the number seen
+This function gets a region number as an argument.  The region number
+is the one used internally by Ediff.  It is 1 less than the number seen
 by the user.")
 
 (ediff-defvar-local ediff-hide-regexp-matches-function
 (ediff-defvar-local ediff-wide-bounds nil "")
 
 ;; Current visibility boundaries in buffers A, B, and C.
-;; This is also a list of overlays. When the user toggles narrow/widen,
+;; This is also a list of overlays.  When the user toggles narrow/widen,
 ;; this list changes from ediff-wide-bounds to ediff-narrow-bounds.
 ;; and back.
 (ediff-defvar-local ediff-visible-bounds nil "")
 ;; represented by a vector of two overlays plus a vector of fine diffs,
 ;; plus a no-fine-diffs flag.  The first overlay spans the
 ;; difference region in the A buffer and the second overlays the diff in
-;; the B buffer. If a difference section is empty, the corresponding
+;; the B buffer.  If a difference section is empty, the corresponding
 ;; overlay's endpoints coincide.
 ;;
-;; The precise form of a difference vector for one buffer is:
+;; The precise form of a Difference Vector for one buffer is:
 ;; [diff diff diff ...]
 ;; where each diff has the form:
-;; [diff-overlay fine-diff-vector no-fine-diffs-flag state-of-difference]
+;; [diff-overlay fine-diff-vector no-fine-diffs-flag state-of-diff]
 ;; fine-diff-vector is a vector [fine-diff-overlay fine-diff-overlay ...]
 ;; no-fine-diffs-flag says if there are fine differences.
 ;; state-of-difference is A, B, C, or nil, indicating which buffer is
-;; different from the other two (used only in 3-way jobs.
+;;	different from the other two (used only in 3-way jobs.
 (ediff-defvar-local ediff-difference-vector-A nil "")
 (ediff-defvar-local ediff-difference-vector-B nil "")
 (ediff-defvar-local ediff-difference-vector-C nil "")
 
 ;; [ status status status ...]
 ;; Each status: [state-of-merge state-of-ancestor]
-;; state-of-merge is default-A, default-B, prefer-A, or prefer-B. It
+;; state-of-merge is default-A, default-B, prefer-A, or prefer-B.  It
 ;; indicates the way a diff region was created in buffer C.
 ;; state-of-ancestor says if the corresponding region in ancestor buffer is
 ;; empty.
 ;; Buffer containing the output of diff, which is used by Ediff to step
 ;; through files.
 (ediff-defvar-local ediff-diff-buffer nil "")
-;; Like ediff-diff-buffer, but contains context diff. It is not used by
+;; Like ediff-diff-buffer, but contains context diff.  It is not used by
 ;; Ediff, but it is saved in a file, if user requests so.
 (ediff-defvar-local ediff-custom-diff-buffer nil "")
 ;; Buffer used for diff-style fine differences between regions.
 
 (defcustom ediff-version-control-package 'vc
   "Version control package used.
-Currently, Ediff supports vc.el, rcs.el, pcl-cvs.el, and generic-sc.el. The
-standard Emacs interface to RCS, CVS, SCCS, etc., is vc.el. However, some
-people find the other two packages more convenient. Set this variable to the
+Currently, Ediff supports vc.el, rcs.el, pcl-cvs.el, and generic-sc.el.  The
+standard Emacs interface to RCS, CVS, SCCS, etc., is vc.el.  However, some
+people find the other two packages more convenient.  Set this variable to the
 appropriate symbol: `rcs', `pcl-cvs', or `generic-sc' if you so desire."
   :type 'symbol
   :group 'ediff)
 ;; emacs-minor-version are defined.  Otherwise, for Emacs/XEmacs 19, if the
 ;; current minor version is < 10 (xemacs) or < 23 (emacs) the return value
 ;; will be nil (when op is =, >, or >=) and t (when op is <, <=), which may be
-;; incorrect. However, this gives correct result in our cases, since we are
+;; incorrect.  However, this gives correct result in our cases, since we are
 ;; testing for sufficiently high Emacs versions.
 (defun ediff-check-version (op major minor &optional type-of-emacs)
   (if (and (boundp 'emacs-major-version) (boundp 'emacs-minor-version))
       ;; pm-win.el in PM-Emacs should be fixed.
       (if (eq (ediff-device-type) 'pm)
 	  (fset 'ediff-valid-color-p 
-		(function (lambda (color) (assoc color pm-color-alist))))
+		(lambda (color) (assoc color pm-color-alist)))
 	(fset 'ediff-valid-color-p (symbol-function 'x-color-defined-p)))
       (fset 'ediff-get-face (symbol-function 'internal-get-face))))
 
     (t (:inverse-video t)))
   "Face for highlighting the selected difference in buffer A."
   :group 'ediff-highlighting)
-;; An internal variable. Ediff takes the face from here. When unhighlighting,
+;; An internal variable.  Ediff takes the face from here.  When unhighlighting,
 ;; this variable is set to nil, then again to the appropriate face.
 (defvar ediff-current-diff-face-A 'ediff-current-diff-face-A
   "Face for highlighting the selected difference in buffer A.
-DO NOT CHANGE this variable. Instead, use the customization
+DO NOT CHANGE this variable.  Instead, use the customization
 widget to customize the actual face object `ediff-current-diff-face-A'
 this variable represents.")
 (ediff-hide-face 'ediff-current-diff-face-A)
     (t (:inverse-video t)))
   "Face for highlighting the selected difference in buffer B."
   :group 'ediff-highlighting)
-;; An internal variable. Ediff takes the face from here. When unhighlighting,
+;; An internal variable.  Ediff takes the face from here.  When unhighlighting,
 ;; this variable is set to nil, then again to the appropriate face.
 (defvar ediff-current-diff-face-B 'ediff-current-diff-face-B
   "Face for highlighting the selected difference in buffer B.
- this variable. Instead, use the customization
+ this variable.  Instead, use the customization
 widget to customize the actual face `ediff-current-diff-face-B'
 this variable represents.")
 (ediff-hide-face 'ediff-current-diff-face-B)
     (t (:inverse-video t)))
   "Face for highlighting the selected difference in buffer C."
   :group 'ediff-highlighting)
-;; An internal variable. Ediff takes the face from here. When unhighlighting,
+;; An internal variable.  Ediff takes the face from here.  When unhighlighting,
 ;; this variable is set to nil, then again to the appropriate face.
 (defvar ediff-current-diff-face-C 'ediff-current-diff-face-C
   "Face for highlighting the selected difference in buffer C.
-DO NOT CHANGE this variable. Instead, use the customization
+DO NOT CHANGE this variable.  Instead, use the customization
 widget to customize the actual face object `ediff-current-diff-face-C'
 this variable represents.")
 (ediff-hide-face 'ediff-current-diff-face-C)
     (t (:inverse-video t)))
   "Face for highlighting the selected difference in buffer Ancestor."
   :group 'ediff-highlighting)
-;; An internal variable. Ediff takes the face from here. When unhighlighting,
+;; An internal variable.  Ediff takes the face from here.  When unhighlighting,
 ;; this variable is set to nil, then again to the appropriate face.
 (defvar ediff-current-diff-face-Ancestor 'ediff-current-diff-face-Ancestor
   "Face for highlighting the selected difference in buffer Ancestor.
-DO NOT CHANGE this variable. Instead, use the customization
+DO NOT CHANGE this variable.  Instead, use the customization
 widget to customize the actual face object `ediff-current-diff-face-Ancestor'
 this variable represents.")
 (ediff-hide-face 'ediff-current-diff-face-Ancestor)
     (t (:underline t :stipple "gray3")))
   "Face for highlighting the refinement of the selected diff in buffer A."
   :group 'ediff-highlighting)
-;; An internal variable. Ediff takes the face from here. When unhighlighting,
+;; An internal variable.  Ediff takes the face from here.  When unhighlighting,
 ;; this variable is set to nil, then again to the appropriate face.
 (defvar ediff-fine-diff-face-A 'ediff-fine-diff-face-A
   "Face for highlighting the fine differences in buffer A.
-DO NOT CHANGE this variable. Instead, use the customization
+DO NOT CHANGE this variable.  Instead, use the customization
 widget to customize the actual face object `ediff-fine-diff-face-A'
 this variable represents.")
 (ediff-hide-face 'ediff-fine-diff-face-A)
     (t (:underline t :stipple "gray3")))
   "Face for highlighting the refinement of the selected diff in buffer B."
   :group 'ediff-highlighting)
-;; An internal variable. Ediff takes the face from here. When unhighlighting,
+;; An internal variable.  Ediff takes the face from here.  When unhighlighting,
 ;; this variable is set to nil, then again to the appropriate face.
 (defvar ediff-fine-diff-face-B 'ediff-fine-diff-face-B
   "Face for highlighting the fine differences in buffer B.
-DO NOT CHANGE this variable. Instead, use the customization
+DO NOT CHANGE this variable.  Instead, use the customization
 widget to customize the actual face object `ediff-fine-diff-face-B'
 this variable represents.")
 (ediff-hide-face 'ediff-fine-diff-face-B)
     (t (:underline t :stipple "gray3")))
   "Face for highlighting the refinement of the selected diff in buffer C."
   :group 'ediff-highlighting)
-;; An internal variable. Ediff takes the face from here. When unhighlighting,
+;; An internal variable.  Ediff takes the face from here.  When unhighlighting,
 ;; this variable is set to nil, then again to the appropriate face.
 (defvar ediff-fine-diff-face-C 'ediff-fine-diff-face-C
   "Face for highlighting the fine differences in buffer C.
-DO NOT CHANGE this variable. Instead, use the customization
+DO NOT CHANGE this variable.  Instead, use the customization
 widget to customize the actual face object `ediff-fine-diff-face-C'
 this variable represents.")
 (ediff-hide-face 'ediff-fine-diff-face-C)
 At present, this face is not used and no fine differences are computed for the
 ancestor buffer."
   :group 'ediff-highlighting)
-;; An internal variable. Ediff takes the face from here. When unhighlighting,
+;; An internal variable.  Ediff takes the face from here.  When unhighlighting,
 ;; this variable is set to nil, then again to the appropriate face.
 (defvar ediff-fine-diff-face-Ancestor 'ediff-fine-diff-face-Ancestor
   "Face for highlighting the fine differences in buffer Ancestor.
-DO NOT CHANGE this variable. Instead, use the customization
+DO NOT CHANGE this variable.  Instead, use the customization
 widget to customize the actual face object `ediff-fine-diff-face-Ancestor'
 this variable represents.")
 (ediff-hide-face 'ediff-fine-diff-face-Ancestor)
     (t (:italic t :stipple "Stipple")))
   "Face for highlighting even-numbered non-current differences in buffer A."
   :group 'ediff-highlighting)
-;; An internal variable. Ediff takes the face from here. When unhighlighting,
+;; An internal variable.  Ediff takes the face from here.  When unhighlighting,
 ;; this variable is set to nil, then again to the appropriate face.
 (defvar ediff-even-diff-face-A 'ediff-even-diff-face-A
   "Face for highlighting even-numbered non-current differences in buffer A.
-DO NOT CHANGE this variable. Instead, use the customization
+DO NOT CHANGE this variable.  Instead, use the customization
 widget to customize the actual face object `ediff-even-diff-face-A'
 this variable represents.")
 (ediff-hide-face 'ediff-even-diff-face-A)
     (t (:italic t :stipple "Stipple")))
   "Face for highlighting even-numbered non-current differences in buffer B."
   :group 'ediff-highlighting)
-;; An internal variable. Ediff takes the face from here. When unhighlighting,
+;; An internal variable.  Ediff takes the face from here.  When unhighlighting,
 ;; this variable is set to nil, then again to the appropriate face.
 (defvar ediff-even-diff-face-B 'ediff-even-diff-face-B
   "Face for highlighting even-numbered non-current differences in buffer B.
-DO NOT CHANGE this variable. Instead, use the customization
+DO NOT CHANGE this variable.  Instead, use the customization
 widget to customize the actual face object `ediff-even-diff-face-B'
 this variable represents.")
 (ediff-hide-face 'ediff-even-diff-face-B)
     (t (:italic t :stipple "Stipple")))
   "Face for highlighting even-numbered non-current differences in buffer C."
   :group 'ediff-highlighting)
-;; An internal variable. Ediff takes the face from here. When unhighlighting,
+;; An internal variable.  Ediff takes the face from here.  When unhighlighting,
 ;; this variable is set to nil, then again to the appropriate face.
 (defvar ediff-even-diff-face-C 'ediff-even-diff-face-C
   "Face for highlighting even-numbered non-current differences in buffer C.
-DO NOT CHANGE this variable. Instead, use the customization
+DO NOT CHANGE this variable.  Instead, use the customization
 widget to customize the actual face object `ediff-even-diff-face-C'
 this variable represents.")
 (ediff-hide-face 'ediff-even-diff-face-C)
     (t (:italic t :stipple "Stipple")))
   "Face for highlighting even-numbered non-current differences in the ancestor buffer."
   :group 'ediff-highlighting)
-;; An internal variable. Ediff takes the face from here. When unhighlighting,
+;; An internal variable.  Ediff takes the face from here.  When unhighlighting,
 ;; this variable is set to nil, then again to the appropriate face.
 (defvar ediff-even-diff-face-Ancestor 'ediff-even-diff-face-Ancestor
   "Face for highlighting even-numbered non-current differences in buffer Ancestor.
-DO NOT CHANGE this variable. Instead, use the customization
+DO NOT CHANGE this variable.  Instead, use the customization
 widget to customize the actual face object `ediff-even-diff-face-Ancestor'
 this variable represents.")
 (ediff-hide-face 'ediff-even-diff-face-Ancestor)
     (t (:italic t :stipple "gray1")))
   "Face for highlighting odd-numbered non-current differences in buffer A."
   :group 'ediff-highlighting)
-;; An internal variable. Ediff takes the face from here. When unhighlighting,
+;; An internal variable.  Ediff takes the face from here.  When unhighlighting,
 ;; this variable is set to nil, then again to the appropriate face.
 (defvar ediff-odd-diff-face-A 'ediff-odd-diff-face-A
   "Face for highlighting odd-numbered non-current differences in buffer A.
-DO NOT CHANGE this variable. Instead, use the customization
+DO NOT CHANGE this variable.  Instead, use the customization
 widget to customize the actual face object `ediff-odd-diff-face-A'
 this variable represents.")
 (ediff-hide-face 'ediff-odd-diff-face-A)
     (t (:italic t :stipple "gray1")))
   "Face for highlighting odd-numbered non-current differences in buffer B."
   :group 'ediff-highlighting)
-;; An internal variable. Ediff takes the face from here. When unhighlighting,
+;; An internal variable.  Ediff takes the face from here.  When unhighlighting,
 ;; this variable is set to nil, then again to the appropriate face.
 (defvar ediff-odd-diff-face-B 'ediff-odd-diff-face-B
   "Face for highlighting odd-numbered non-current differences in buffer B.
-DO NOT CHANGE this variable. Instead, use the customization
+DO NOT CHANGE this variable.  Instead, use the customization
 widget to customize the actual face object `ediff-odd-diff-face-B'
 this variable represents.")
 (ediff-hide-face 'ediff-odd-diff-face-B)
     (t (:italic t :stipple "gray1")))
   "Face for highlighting odd-numbered non-current differences in buffer C."
   :group 'ediff-highlighting)
-;; An internal variable. Ediff takes the face from here. When unhighlighting,
+;; An internal variable.  Ediff takes the face from here.  When unhighlighting,
 ;; this variable is set to nil, then again to the appropriate face.
 (defvar ediff-odd-diff-face-C 'ediff-odd-diff-face-C
   "Face for highlighting odd-numbered non-current differences in buffer C.
-DO NOT CHANGE this variable. Instead, use the customization
+DO NOT CHANGE this variable.  Instead, use the customization
 widget to customize the actual face object `ediff-odd-diff-face-C'
 this variable represents.")
 (ediff-hide-face 'ediff-odd-diff-face-C)
     (t (:italic t :stipple "gray1")))
   "Face for highlighting odd-numbered non-current differences in the ancestor buffer."
   :group 'ediff-highlighting)
-;; An internal variable. Ediff takes the face from here. When unhighlighting,
+;; An internal variable.  Ediff takes the face from here.  When unhighlighting,
 ;; this variable is set to nil, then again to the appropriate face.
 (defvar ediff-odd-diff-face-Ancestor 'ediff-odd-diff-face-Ancestor
   "Face for highlighting odd-numbered non-current differences in buffer Ancestor.
-DO NOT CHANGE this variable. Instead, use the customization
+DO NOT CHANGE this variable.  Instead, use the customization
 widget to customize the actual face object `ediff-odd-diff-face-Ancestor'
 this variable represents.")
 (ediff-hide-face 'ediff-odd-diff-face-Ancestor)
 	  (setq ovr-list (append (overlays-at pos) ovr-list))
 	  (setq pos (next-overlay-change pos)))
 	(1+ (apply '+
-		   (mapcar (function
-			    (lambda (ovr)
-			      (if ovr
-				  (or (ediff-overlay-get ovr 'priority) 0)
-				0)))
+		   (mapcar (lambda (ovr)
+			     (if ovr
+				 (or (ediff-overlay-get ovr 'priority) 0)
+			       0))
 			   ovr-list)
 		   ))
 	))))
 
 (defcustom ediff-autostore-merges  'group-jobs-only
   "*Save the results of merge jobs automatically.
-Nil means don't save automatically. t means always save. Anything but nil or t
+Nil means don't save automatically.  t means always save.  Anything but nil or t
 means save automatically only if the merge job is part of a group of jobs, such
 as `ediff-merge-directory' or `ediff-merge-directory-revisions'."
   :type '(choice (const nil) (const t) (const group-jobs-only))
   :group 'ediff-merge)
 (make-variable-buffer-local 'ediff-autostore-merges)
 
-;; file where the result of the merge is to be saved. used internally
+;; file where the result of the merge is to be saved.  used internally
 (ediff-defvar-local ediff-merge-store-file nil "")
   
 (defcustom ediff-no-emacs-help-in-control-buffer nil
   :type 'boolean
   :group 'ediff)
   
+;; This is the same as temporary-file-directory from Emacs 20.3.
+;; Copied over here because XEmacs doesn't have this variable.
 (defcustom ediff-temp-file-prefix
-  (let ((env (or (getenv "TMPDIR")
-		 (getenv "TMP")
-		 (getenv "TEMP")))
-	d)
-    (setq d (if (and env (> (length env) 0))
-		env
-	      (cond ((memq system-type '(vax-vms axp-vms)) "SYS$SCRATCH:")
- 		    ((eq system-type 'ms-dos) "c:/")
- 		    (t "/tmp"))))
-    ;; The following is to make sure we get something to which we can
-    ;; add directory levels under VMS.
-    (setq d (file-name-as-directory (directory-file-name d)))
-    )
+  (file-name-as-directory
+   (cond ((memq system-type '(ms-dos windows-nt))
+	  (or (getenv "TEMP") (getenv "TMPDIR") (getenv "TMP") "c:/temp"))
+	 ((memq system-type '(vax-vms axp-vms))
+	  (or (getenv "TMPDIR") (getenv "TMP") (getenv "TEMP") "SYS$SCRATCH:"))
+	 (t
+	  (or (getenv "TMPDIR") (getenv "TMP") (getenv "TEMP") "/tmp"))))
   "*Prefix to put on Ediff temporary file names.
 Do not start with `~/' or `~USERNAME/'."
   :type 'string
 	 (eval (ediff-get-symbol-from-alist
 		buf-type ediff-difference-vector-alist)))
 	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))
-	       (if (ediff-overlay-buffer overl)
-		   ;; only if overlay is alive
-		   (ediff-set-overlay-face
-		    overl
-		    (if (not unhighlight)
-			(ediff-background-face buf-type diff-num))))
-	       ))
+    (mapcar (lambda (rec)
+	      (setq overl (ediff-get-diff-overlay-from-diff-record rec)
+		    diff-num (ediff-overlay-get overl 'ediff-diff-num))
+	      (if (ediff-overlay-buffer overl)
+		  ;; only if overlay is alive
+		  (ediff-set-overlay-face
+		   overl
+		   (if (not unhighlight)
+		       (ediff-background-face buf-type diff-num))))
+	      )
 	    diff-vector)))
 
 
 	    ;; Don't grab on quit, if the user doesn't want to.
 	    ;; If ediff-grab-mouse = t, then mouse won't be grabbed for
 	    ;; sessions that are not part of a group (this is done in
-	    ;; ediff-recenter). The condition below affects only terminating
+	    ;; ediff-recenter).  The condition below affects only terminating
 	    ;; sessions in session groups (in which case mouse is warped into
 	    ;; a meta buffer).
 	    (and (eq ediff-grab-mouse 'maybe)
   (setq ediff-mouse-pixel-position (mouse-pixel-position)))
 
 ;; It is not easy to find out when the user grabs the mouse, since emacs and
-;; xemacs behave differently when mouse is not in any frame. Also, this is
+;; xemacs behave differently when mouse is not in any frame.  Also, this is
 ;; sensitive to when the user grabbed mouse.  Not used for now.
 (defun ediff-user-grabbed-mouse ()
   (if ediff-mouse-pixel-position
 (defsubst ediff-empty-overlay-p (overl)
   (= (ediff-overlay-start overl) (ediff-overlay-end overl)))
 
-;; like overlay-buffer in Emacs. In XEmacs, returns nil if the extent is
-;; dead. Otherwise, works like extent-buffer
+;; like overlay-buffer in Emacs.  In XEmacs, returns nil if the extent is
+;; dead.  Otherwise, works like extent-buffer
 (defun ediff-overlay-buffer (overl)
   (if ediff-emacs-p
       (overlay-buffer overl)
     (and (extent-live-p overl) (extent-object overl))))
 
-;; like overlay-get in Emacs. In XEmacs, returns nil if the extent is
-;; dead. Otherwise, like extent-property
+;; like overlay-get in Emacs.  In XEmacs, returns nil if the extent is
+;; dead.  Otherwise, like extent-property
 (defun ediff-overlay-get (overl property)
   (if ediff-emacs-p
       (overlay-get overl property)
 	 (abbreviate-file-name file t))))
 
 ;; Takes a directory and returns the parent directory.
-;; does nothing to `/'. If the ARG is a regular file,
+;; does nothing to `/'.  If the ARG is a regular file,
 ;; strip the file AND the last dir.
 (defun ediff-strip-last-dir (dir)
   (if (not (stringp dir)) (setq dir default-directory))
       (setq substr (substring str (max 0 (- len 1 newlen))))
       (concat "..." substr))))
 
+(defsubst ediff-nonempty-string-p (string)
+  (and (stringp string) (not (string= string ""))))
+
 (defun ediff-abbrev-jobname (jobname)
   (cond ((eq jobname 'ediff-directories)
 	 "Compare two directories")
 (defcustom ediff-combination-pattern 
   '("<<<<<<<<<<<<<< variant A" ">>>>>>>>>>>>>> variant B" "======= end of combination")
   "*Pattern to be used for combining difference regions in buffers A and B.
-The value is (STRING1 STRING2 STRING3). The combined text will look like this:
+The value is (STRING1 STRING2 STRING3).  The combined text will look like this:
 
 STRING1
 diff region from variant A
   :type '(list string string string)
   :group 'ediff-merge)
 
-(ediff-defvar-local ediff-show-clashes-only  nil
+(defcustom ediff-show-clashes-only nil
   "*If t, show only those diff regions where both buffers disagree with the ancestor.
 This means that regions that have status prefer-A or prefer-B will be
-skiped over. Nil means show all regions.")
+skiped over.  Nil means show all regions."
+  :type 'boolean
+  :group 'ediff-merge
+  )
+(make-variable-buffer-local 'ediff-show-clashes-only)
+
+(defcustom ediff-skip-merge-regions-that-differ-from-default nil
+  "*If t, show only the regions that have not been changed by the user.
+A region is considered to have been changed if it is different from the current
+default (`default-A', `default-B', `combined') and it hasn't been marked as
+`prefer-A' or `prefer-B'.
+A region is considered to have been changed also when it is marked as 
+as `prefer-A', but is different from the corresponding difference region in
+Buffer A or if it is marked as `prefer-B' and is different from the region in
+Buffer B."
+  :type 'boolean
+  :group 'ediff-merge
+  )
+(make-variable-buffer-local 'ediff-skip-merge-regions-that-differ-from-default)
 
 ;; If ediff-show-clashes-only, check if there is no clash between the ancestor
 ;; and one of the variants.
   (and ediff-show-clashes-only
        (string-match "prefer" (or (ediff-get-state-of-merge n) ""))))
 
+;; If ediff-skip-changed-regions, check if the merge region differs from
+;; the current default. If a region is different from the default, it means
+;; that the user has made determination as to how to merge for this particular
+;; region. 
+(defsubst ediff-skip-merge-region-if-changed-from-default-p (n)
+  (and ediff-skip-merge-regions-that-differ-from-default
+       (ediff-merge-changed-from-default-p n 'prefers-too)))
+
+
 	
 (defsubst ediff-get-combined-region (n)
   (concat (nth 0 ediff-combination-pattern) "\n"
 		(reg-C (ediff-get-region-contents n 'C ediff-control-buffer)))
 		
 	    ;; if region was edited since it was first set by default
-	    (if (or (and (string= state-of-merge "default-A")
-			 (not (string= reg-A reg-C)))
-		    ;; was edited since first set by default
-		    (and (string= state-of-merge "default-B")
-			 (not (string= reg-B reg-C)))
-		    ;; was edited since first set by default
-		    (and (string= state-of-merge "combined")
-			 (not (string=
-			       (ediff-make-combined-diff reg-A reg-B) reg-C)))
-		    ;; was preferred--ignore
+	    (if (or (ediff-merge-changed-from-default-p n)
+		    ;; was preferred
 		    (string-match "prefer" state-of-merge))
+		;; then ignore
 		(setq do-not-copy t))
 		
 	    ;; change state of merge for this diff, if necessary
     
 
 (defun ediff-re-merge ()
-  "Remerge unmodified diff regions using a new default. Start with the current region."
+  "Remerge unmodified diff regions using a new default.  Start with the current region."
   (interactive)
   (let* ((default-variant-alist
 	   (list '("default-A") '("default-B") '("combined")))
     (setq ediff-default-variant
 	  (intern
 	   (completing-read 
-	    (format "Current merge default is `%S'. New default: "
+	    (format "Current merge default is `%S'.  New default: "
 		    ediff-default-variant)
 	    actual-alist nil 'must-match)))
     (ediff-do-merge ediff-current-difference 'remerge)
 	 (ediff-recenter 'no-rehighlight))))
 
 
-;; N here is the user's region number. It is 1+ what Ediff uses internally.
+;; N here is the user's region number.  It is 1+ what Ediff uses internally.
 (defun ediff-combine-diffs (n &optional batch-invocation)
   "Combine Nth diff regions of buffers A and B and place the combination in C.
-N is a prefix argument. If nil, combine the current difference regions.
+N is a prefix argument.  If nil, combine the current difference regions.
 Combining is done according to the specifications in variable
 `ediff-combination-pattern'."
   (interactive "P")
     
 
 ;; Checks if the region in buff C looks like a combination of the regions
-;; in buffers A and B. Returns a list (reg-a-beg reg-a-end reg-b-beg reg-b-end)
+;; in buffers A and B.  Return a list (reg-a-beg reg-a-end reg-b-beg reg-b-end)
 ;; These refer to where the copies of region A and B start and end in buffer C
 (defun ediff-looks-like-combined-merge (region-num)
   (if ediff-merge-job
 	(if (and reg-a-beg reg-a-end reg-b-beg reg-b-end)
 	    (list reg-a-beg reg-a-end reg-b-beg reg-b-end reg-c-beg reg-c-end))
 	)))
+
+
+;; Check if the non-preferred merge has been modified since originally set.
+;; This affects only the regions that are marked as default-A/B or combined.
+;; If PREFERS-TOO is non-nil, then look at the regions marked as prefers-A/B as
+;; well.
+(defun ediff-merge-changed-from-default-p (diff-num &optional prefers-too)
+  (let ((reg-A (ediff-get-region-contents diff-num 'A ediff-control-buffer))
+	(reg-B (ediff-get-region-contents diff-num 'B ediff-control-buffer))
+	(reg-C (ediff-get-region-contents diff-num 'C ediff-control-buffer)))
+
+    (setq state-of-merge (ediff-get-state-of-merge diff-num))
+		
+    ;; if region was edited since it was first set by default
+    (or (and (string= state-of-merge "default-A")
+	     (not (string= reg-A reg-C)))
+	(and (string= state-of-merge "default-B")
+	     (not (string= reg-B reg-C)))
+	(and (string= state-of-merge "combined")
+	     (not (string= (ediff-make-combined-diff reg-A reg-B) reg-C)))
+	(and prefers-too
+	     (string= state-of-merge "prefer-A")
+	     (not (string= reg-A reg-C)))
+	(and prefers-too
+	     (string= state-of-merge "prefer-B")
+	     (not (string= reg-B reg-C)))
+	)))
   
 
 ;;; Local Variables:
 ;;	   in the following format:
 ;;	  	(descriptor (obj1 obj2 obj3) (...) ...)
 ;;	   Actually, the format of this list is pretty much up to the
-;;	   developer. The only thing is that it must be a list of lists,
+;;	   developer.  The only thing is that it must be a list of lists,
 ;;	   and the first list must describe the meta session, and subsequent
 ;;	   elements must describe individual sessions.
 ;;	   This descriptor must be a list of two, three, or four elements (nil
-;;	   or string). The function ediff-redraw-registry-buffer displays the
+;;	   or string).  The function ediff-redraw-registry-buffer displays the
 ;;	   second through last of these in the registry buffer. 
 ;;	   Also, keep in mind that the function ediff-prepare-meta-buffer
 ;;	   (which see) prepends the session group buffer to the descriptor and
 ;;	   See how this is done in ediff-filegroup-action.
 ;;
 ;;	   Session descriptions are of the form (obj1 obj2 obj3), which
-;;	   describe objects relevant to the session. Usually they are names of
-;;	   files, but sometimes they may be other things. For instance, obj3 is
-;;	   nil for jobs that involve only two files. For patch jobs, obj2 and
-;;	   obj3 are markers that specify the patch corresponding to the file
-;;	   (whose name is obj1).
+;;	   describe objects relevant to the session.  Usually they are names of
+;;	   files, but sometimes they may be other things.  For instance, obj3
+;;	   is nil for jobs that involve only two files.  For patch jobs, obj2
+;;	   and obj3 are markers that specify the patch corresponding to the
+;;	   file (whose name is obj1).
 ;;	4. Write a function that makes a call to ediff-prepare-meta-buffer
 ;;	   passing all this info. 
 ;;	   You may be able to use ediff-directories-internal as a template.
 ;;	   ediff-directories-internal. 
 ;;
 ;; A useful addition here could be session groups selected by patterns
-;; (which are different in each directory). For instance, one may want to
+;; (which are different in each directory).  For instance, one may want to
 ;; compare files of the form abc{something}.c to files old{something}.d
-;; which may be in the same or different directories. Or, one may want to
+;; which may be in the same or different directories.  Or, one may want to
 ;; compare all files of the form {something} to files of the form {something}~.
 ;;
 ;; Implementing this requires writing an collating function, which should pair
-;; up appropriate files. It will also require a generalization of the functions
-;; that do the layout of the meta- and differences buffers and of
+;; up appropriate files.  It will also require a generalization of the
+;; functions that do the layout of the meta- and differences buffers and of
 ;; ediff-filegroup-action.
 
 ;;; Code:
 directories.")
 
 ;; Variable specifying the action to take when the use invokes ediff in the
-;; meta buffer. This is usually ediff-registry-action or ediff-filegroup-action
+;; meta buffer.  This is usually ediff-registry-action or ediff-filegroup-action
 (ediff-defvar-local ediff-meta-action-function nil "")
 ;; Tells ediff-update-meta-buffer how to redraw it
 (ediff-defvar-local ediff-meta-redraw-function nil "")
 ;; (ctl-buf session-status (file1 . eq-status) (file2 . eq-status) (file3
 ;; . eq-status)) (ctl-buf session-status (file1 . eq-status) (file2
 ;; . eq-status)) ...)
-;; If ctl-buf is nil, the file-pair hasn't processed yet. If it is
-;; killed-buffer object, the file pair has been processed. If it is a live
+;; If ctl-buf is nil, the file-pair hasn't processed yet.  If it is
+;; killed-buffer object, the file pair has been processed.  If it is a live
 ;; buffer, this means ediff is still working on the pair.
 ;; Eq-status of a file is t if the file equals some other file in the same
 ;; group.
 (ediff-defvar-local ediff-dir-difference-list nil "")
 (ediff-defvar-local ediff-dir-diffs-buffer nil "")
 
-;; The registry of Ediff sessions. A list of control buffers.
+;; The registry of Ediff sessions.  A list of control buffers.
 (defvar ediff-session-registry nil)
 
 (defcustom ediff-meta-truncate-filenames t
   "*Hooks run just after the registry buffer is shown."
   :type 'hook
   :group 'ediff-mult)
-(defcustom ediff-show-session-group-hook nil
+(defcustom ediff-show-session-group-hook '(delete-other-windows)
   "*Hooks run just after a session group buffer is shown."
   :type 'hook
   :group 'ediff-mult)
   :type 'hook
   :group 'ediff-mult)
 
-;; buffer holding the multi-file patch. local to the meta buffer
+;; Buffer holding the multi-file patch.  Local to the meta buffer
 (ediff-defvar-local ediff-meta-patchbufer nil "")
 
 ;;; API for ediff-meta-list
 
 ;; The activity marker is either or + (active session, i.e., ediff is currently
 ;; run in it), or - (finished session, i.e., we've ran ediff in it and then
-;; exited). Return nil, if session is neither active nor finished
+;; exited).  Return nil, if session is neither active nor finished
 (defun ediff-get-session-activity-marker (session)
   (let ((session-buf (ediff-get-session-buffer session)))
     (cond ((null session-buf) nil) ; virgin session
 
 (defun ediff-next-meta-item (count)
   "Move to the next item in Ediff registry or session group buffer.
-Moves in circular fashion. With numeric prefix arg, skip this many items."
+Moves in circular fashion.  With numeric prefix arg, skip this many items."
   (interactive "p")
   (or count (setq count 1))
   (let (overl)
 
 (defun ediff-previous-meta-item (count)
   "Move to the previous item in Ediff registry or session group buffer.
-Moves in circular fashion. With numeric prefix arg, skip this many items."
+Moves in circular fashion.  With numeric prefix arg, skip this many items."
   (interactive "p")
   (or count (setq count 1))
   (let (overl)
   (ediff-update-meta-buffer (current-buffer) 'must-redraw))
 
 
-;; DIR1, DIR2, DIR3 are directories. DIR3 can be nil.
+;; DIR1, DIR2, DIR3 are directories.  DIR3 can be nil.
 ;; OUTPUT-DIR is a directory for auto-storing the results of merge jobs.
 ;;	      Can be nil.
 ;; REGEXP is a regexp used to filter out files in the directories.
 ;; If a file is a directory in dir1 but not dir2 (or vice versa), it is not
-;; included in the intersection. However, a regular file that is a dir in dir3
+;; included in the intersection.  However, a regular file that is a dir in dir3
 ;; is included, since dir3 files are supposed to be ancestors for merging.
 ;; Returns a list of the form:
 ;;	((dir1 dir2 dir3) (f1 f2 f3) (f1 f2 f3) ...)
 ;; dir3, f3 can be nil if intersecting only 2 directories.
-;; If COMPARISON-FUNC is given, use it. Otherwise, use string=
+;; If COMPARISON-FUNC is given, use it.  Otherwise, use string=
 ;; DIFF-VAR contains the name of the variable in which to return the
 ;; difference list (which represents the differences among the contents of
-;; directories). The diff list is of the form:
+;; directories).  The diff list is of the form:
 ;;	((dir1 dir2 dir3) (file . num) (file . num)...)
 ;; where num encodes the set of dirs where the file is found:
 ;; 2 - only dir1; 3 - only dir2; 5 - only dir3; 6 - dir1&2; 10 - dir1&3; etc.
 	  lis1 		(delete "."  lis1)
 	  lis1 		(delete ".." lis1)
 	  lis1 		(mapcar 
-			 (function 
-			  (lambda (elt)
-				  (ediff-add-slash-if-directory auxdir1 elt)))
+			 (lambda (elt)
+			   (ediff-add-slash-if-directory auxdir1 elt))
 			 lis1)
 	  auxdir2	(file-name-as-directory dir2)
 	  lis2		(mapcar 
-			 (function
-			  (lambda (elt)
-				  (ediff-add-slash-if-directory auxdir2 elt)))
+			 (lambda (elt)
+			   (ediff-add-slash-if-directory auxdir2 elt))
 			 (directory-files auxdir2 nil regexp)))
 
     (if (stringp dir3)
 	(setq auxdir3	(file-name-as-directory dir3)
 	      lis3	(mapcar 
-			 (function
-			  (lambda (elt)
-				  (ediff-add-slash-if-directory auxdir3 elt)))
+			 (lambda (elt)
+			   (ediff-add-slash-if-directory auxdir3 elt))
 			 (directory-files auxdir3 nil regexp))))
 
-    (if (stringp merge-autostore-dir)
+    (if (ediff-nonempty-string-p merge-autostore-dir)
 	(setq merge-autostore-dir
 	      (file-name-as-directory merge-autostore-dir)))
     (setq common (ediff-intersection lis1 lis2 comparison-func))
 	  difflist (sort (ediff-copy-list (delete ".." difflist))
 			 'string-lessp))
 
-    (setq difflist (mapcar (function (lambda (elt) (cons elt 1))) difflist))
+    (setq difflist (mapcar (lambda (elt) (cons elt 1)) difflist))
 
     ;; check for files belonging to lis1/2/3
-    (mapcar (function (lambda (elt) 
-			(if (member (car elt) lis1)
-			    (setcdr elt (* (cdr elt) 2)))
-			(if (member (car elt) lis2)
-			    (setcdr elt (* (cdr elt) 3)))
-			(if (member (car elt) lis3)
-			    (setcdr elt (* (cdr elt) 5)))
-			))
+    (mapcar (lambda (elt)
+	      (if (member (car elt) lis1)
+		  (setcdr elt (* (cdr elt) 2)))
+	      (if (member (car elt) lis2)
+		  (setcdr elt (* (cdr elt) 3)))
+	      (if (member (car elt) lis3)
+		  (setcdr elt (* (cdr elt) 5)))
+	      )
 	    difflist)
     (setq difflist (cons (list regexp auxdir1 auxdir2 auxdir3) difflist))
     
     ;; return result
     (cons (list regexp auxdir1 auxdir2 auxdir3 merge-autostore-dir)
 	  (mapcar
-	   (function
-	    (lambda (elt) 
-	      (list (concat auxdir1 elt)
-		    (concat auxdir2 elt)
-		    (if lis3
-			(progn
-			  ;; The following is done because:
-			  ;;   In merging with ancestor, we don't intersect
-			  ;;   with lis3. So, it is possible that elt is a
-			  ;;   file in auxdir1/2 but a directory in auxdir3
-			  ;;   Or elt may not exist in auxdir3 at all.
-			  ;;   In the first case, we add a slash at the end.
-			  ;;   In the second case, we insert nil.
-			  (setq elt (ediff-add-slash-if-directory auxdir3 elt))
-			  (if (file-exists-p (concat auxdir3 elt))
-			      (concat auxdir3 elt)))))))
+	   (lambda (elt) 
+	     (list (concat auxdir1 elt)
+		   (concat auxdir2 elt)
+		   (if lis3
+		       (progn
+			 ;; The following is done because:
+			 ;;   In merging with ancestor, we don't intersect
+			 ;;   with lis3.  So, it is possible that elt is a
+			 ;;   file in auxdir1/2 but a directory in auxdir3
+			 ;;   Or elt may not exist in auxdir3 at all.
+			 ;;   In the first case, we add a slash at the end.
+			 ;;   In the second case, we insert nil.
+			 (setq elt (ediff-add-slash-if-directory auxdir3 elt))
+			 (if (file-exists-p (concat auxdir3 elt))
+			     (concat auxdir3 elt))))))
 	   common))
     ))
 
 ;; find directory files that are under revision.  Include subdirectories, since
 ;; we may visit them recursively.  DIR1 is the directory to inspect.
 ;; MERGE-AUTOSTORE-DIR is the directory where to auto-store the results of
-;; merges. Can be nil.
+;; merges.  Can be nil.
 (defun ediff-get-directory-files-under-revision (jobname
 						 regexp dir1
 						 &optional merge-autostore-dir)
     (setq auxdir1 (file-name-as-directory dir1)
 	  lis1	  (directory-files auxdir1 nil regexp))
 
-    (if (stringp merge-autostore-dir)
+    (if (ediff-nonempty-string-p merge-autostore-dir)
 	(setq merge-autostore-dir
 	      (file-name-as-directory merge-autostore-dir)))
 
 
     ;; return result
     (cons (list regexp auxdir1 nil nil merge-autostore-dir)
-	  (mapcar (function (lambda (elt) 
-			      (list (concat auxdir1 elt)
-				    nil nil)))
+	  (mapcar (lambda (elt) (list (concat auxdir1 elt) nil nil))
 		  common))
     ))
       
 
 
 ;; Prepare meta-buffer in accordance with the argument-function and
-;; redraw-function. Must return the created  meta-buffer.
+;; redraw-function.  Must return the created  meta-buffer.
 (defun ediff-prepare-meta-buffer (action-func meta-list
 				  meta-buffer-name redraw-function
 				  jobname &optional startup-hooks)
 	;; Initialize the meta list -- don't do this for registry.
 	;;
 	;; We prepend '(nil nil) to all elts of meta-list, except the first.
-	;; The first nil will later be replaced by the session buffer. The
+	;; The first nil will later be replaced by the session buffer.  The
 	;; second is reserved for session status.
 	;;
 	;; (car ediff-meta-list) gets cons'ed with the session group buffer.
 	;; Also, session objects A/B/C are turned into lists of the form
-	;; (obj eq-indicator). Eq-indicator is either nil or =. Initialized to
-	;; nil. If later it is discovered that this file is = to some other
+	;; (obj eq-indicator).  Eq-indicator is either nil or =. Initialized to
+	;; nil.  If later it is discovered that this file is = to some other
 	;; file in the same session, eq-indicator is changed to `='.
 	;; For now, the eq-indicator is used only for 2 and 3-file jobs.
 	(setq ediff-meta-list
 	      (cons (cons meta-buffer (car meta-list))
 		    (mapcar
-		     (function
-		      (lambda (elt)
-			(cons nil
-			      (cons nil
-				    ;; convert each obj to (obj nil),
-				    ;; where nil is the initial value
-				    ;; for eq-indicator -- see above
-				    (mapcar
-				     (function (lambda (obj) (list obj nil)))
-				     elt)))))
+		     (lambda (elt)
+		       (cons nil
+			     (cons nil
+				   ;; convert each obj to (obj nil),
+				   ;; where nil is the initial value
+				   ;; for eq-indicator -- see above
+				   (mapcar (lambda (obj) (list obj nil))
+					   elt))))
 		     (cdr meta-list)))))
 	
       (or (eq meta-buffer ediff-registry-buffer)
 	 ;; virgin session
 	 (t " "))))
 
-;; Insert session status at point. Status is either ?H (marked for hiding), or
+;; Insert session status at point.  Status is either ?H (marked for hiding), or
 ;; ?I (hidden or invalid), or ?* (meaning marked for an operation; currently,
 ;; such op can only be checking for equality)), or SPC (meaning neither marked
 ;; nor invalid) 
 	 (t " "))))
 
 ;; If NEW-MARKER is non-nil, use it to substitute the current activity marker
-;; in the meta buffer. If nil, use SPC
+;; in the meta buffer.  If nil, use SPC
 (defun ediff-replace-session-activity-marker-in-meta-buffer (point new-marker)
   (let* ((overl (ediff-get-meta-overlay-at-pos point))
 	 (session-info (ediff-overlay-get overl 'ediff-meta-info))
       (set-buffer-modified-p nil))))
 
 ;; If NEW-STATUS is non-nil, use it to substitute the current status marker in
-;; the meta buffer. If nil, use SPC
+;; the meta buffer.  If nil, use SPC
 (defun ediff-replace-session-status-in-meta-buffer (point new-status)
   (let* ((overl (ediff-get-meta-overlay-at-pos point))
 	 (session-info (ediff-overlay-get overl 'ediff-meta-info))
 	   (format "*** Filter-through regular expression: %s\n" regexp)))
       (ediff-insert-dirs-in-meta-buffer meta-list)
       (if (and ediff-autostore-merges (ediff-merge-metajob)
-	       (stringp merge-autostore-dir))
+	       (ediff-nonempty-string-p merge-autostore-dir))
 	  (insert (format
 		   "\nMerge results are automatically stored in:\n\t%s\n"
 		   merge-autostore-dir)))
     (setq overl
 	  (if ediff-xemacs-p
 	      (map-extents
-	       (function
-		(lambda (ext maparg)
-		  (if (and
-		       (ediff-overlay-get ext 'ediff-meta-info)
-		       (eq (ediff-overlay-get ext 'ediff-meta-session-number)
-			   session-num))
-		      ext))))
+	       (lambda (ext maparg)
+		 (if (and
+		      (ediff-overlay-get ext 'ediff-meta-info)
+		      (eq (ediff-overlay-get ext 'ediff-meta-session-number)
+			  session-num))
+		     ext)))
 	    ;; Emacs doesn't have map-extents, so try harder
 	    ;; Splice overlay lists to get all buffer overlays
 	    (setq buffer-meta-overlays (overlay-lists)
 	    (car
 	     (delq nil
 		   (mapcar
-		    (function
-		     (lambda (overl)
-		       (if (and
-			    (ediff-overlay-get overl 'ediff-meta-info)
-			    (eq (ediff-overlay-get
-				 overl 'ediff-meta-session-number)
-				session-num))
-			   overl)))
+		    (lambda (overl)
+		      (if (and
+			   (ediff-overlay-get overl 'ediff-meta-info)
+			   (eq (ediff-overlay-get
+				overl 'ediff-meta-session-number)
+			       session-num))
+			  overl))
 		    buffer-meta-overlays)))))
     (or overl
 	(error
 
 
 ;; Check if this is a problematic session.
-;; Return nil if not. Otherwise, return symbol representing the problem
+;; Return nil if not.  Otherwise, return symbol representing the problem
 ;; At present, problematic sessions occur only in -with-ancestor comparisons
 ;; when the ancestor is a directory rather than a file, or when there is no
 ;; suitable ancestor file in the ancestor directory
   ))
 
 (defun ediff-bury-dir-diffs-buffer ()
-  "Bury the directory difference buffer. Display the meta buffer instead."
+  "Bury the directory difference buffer.  Display the meta buffer instead."
   (interactive)
   (let ((buf ediff-meta-buffer)
 	wind)
 
 ")
       ;; purge registry list from dead buffers
-      (mapcar (function (lambda (elt)
-			  (if (not (ediff-buffer-live-p elt))
-			      (setq ediff-session-registry
-				    (delq elt ediff-session-registry)))))
+      (mapcar (lambda (elt)
+		(if (not (ediff-buffer-live-p elt))
+		    (setq ediff-session-registry
+			  (delq elt ediff-session-registry))))
 	      ediff-session-registry)
 
       (if (null ediff-session-registry)
 	(ediff-overlay-put overl 'ediff-meta-session-number session-number))))
 
 (defun ediff-mark-for-hiding-at-pos (unmark)
-  "Mark session for hiding. With prefix arg, unmark."
+  "Mark session for hiding.  With prefix arg, unmark."
   (interactive "P")
   (let* ((pos (ediff-event-point last-command-event))
 	 (meta-buf (ediff-event-buffer last-command-event))
   
 
 (defun ediff-mark-for-operation-at-pos (unmark)
-  "Mark session for a group operation. With prefix arg, unmark."
+  "Mark session for a group operation.  With prefix arg, unmark."
   (interactive "P")
   (let* ((pos (ediff-event-point last-command-event))
 	 (meta-buf (ediff-event-buffer last-command-event))
 
 
 (defun ediff-hide-marked-sessions (unhide)
-  "Hide marked sessions. With prefix arg, unhide."
+  "Hide marked sessions.  With prefix arg, unhide."
   (interactive "P")
   (let ((grp-buf (ediff-get-group-buffer ediff-meta-list))
 	(meta-list (cdr ediff-meta-list))
 		(setq active-sessions-exist t)
 	      (ediff-set-session-status elt to)))))
     (if (> numMarked 0)
-	(ediff-update-meta-buffer grp-buf)
+	(ediff-update-meta-buffer grp-buf 'must-redraw)
       (beep)
       (if unhide
 	  (message "Nothing to reveal...")
 	(message "Note: Ediff didn't hide active sessions!"))
     ))
 
-;; Apply OPERATION to marked sessions. Operation expects one argument of type
+;; Apply OPERATION to marked sessions.  Operation expects one argument of type
 ;; meta-list member (not the first one), i.e., a regular session description.
 ;; Returns number of marked sessions on which operation was performed
 (defun ediff-operate-on-marked-sessions (operation)
   "Collect custom diffs of marked sessions in buffer `*Ediff Multifile Diffs*'.
 This operation is defined only for `ediff-directories' and
 `ediff-directory-revisions', since its intent is to produce
-multifile patches. For `ediff-directory-revisions', we insist that
+multifile patches.  For `ediff-directory-revisions', we insist that
 all marked sessions must be active."
   (interactive)
   (or (ediff-buffer-live-p ediff-meta-diff-buffer)
     (erase-buffer))
   (if (> (ediff-operate-on-marked-sessions 'ediff-append-custom-diff) 0)
       ;; did something
-      (display-buffer ediff-meta-diff-buffer 'not-this-window)
+      (progn
+	(display-buffer ediff-meta-diff-buffer 'not-this-window)
+	(ediff-with-current-buffer ediff-meta-diff-buffer
+	  (set-buffer-modified-p nil)
+	  (setq buffer-read-only t)))
     (beep)
     (message "No marked sessions found")))
 
       (error "The patch buffer wasn't found"))))
 
 	      
-;; This function executes in meta buffer. It knows where event happened.
+;; This function executes in meta buffer.  It knows where event happened.
 (defun ediff-filegroup-action ()
   "Execute appropriate action for the selected session."
   (interactive)
 	    ((ediff-problematic-session-p info)
 	     (beep)
 	     (if (y-or-n-p
-		  "This session has no ancestor. Merge without the ancestor? ")
+		  "This session has no ancestor.  Merge without the ancestor? ")
 		 (ediff-merge-files
 		  file1 file2
 		  ;; provide startup hooks 
 				   ediff-meta-session-number
 				   (, session-number))
 			     (setq ediff-merge-store-file
-				   (, (concat
-				       merge-autostore-dir
-				       "merge_"
-				       (file-name-nondirectory file1))))
+				   (, (if (ediff-nonempty-string-p
+					   merge-autostore-dir)
+					  (concat
+					   merge-autostore-dir
+					   "merge_"
+					   (file-name-nondirectory file1)))
+				      ))
 			     ;; make ediff-startup pass
 			     ;; ediff-control-buffer back to the meta
 			     ;; level; see below
 				       ediff-meta-session-number
 				       (, session-number))
 				 (setq ediff-merge-store-file
-				       (, (concat
-					   merge-autostore-dir
-					   "merge_"
-					   (file-name-nondirectory file1))))
+				       (, (if (ediff-nonempty-string-p
+					       merge-autostore-dir)
+					      (concat
+					       merge-autostore-dir
+					       "merge_"
+					       (file-name-nondirectory file1)))
+					  ))
 				 ;; make ediff-startup pass
 				 ;; ediff-control-buffer back to the meta
 				 ;; level; see below
 				       ediff-meta-session-number
 				       (, session-number))
 				 (setq ediff-merge-store-file
-				       (, (concat
-					   merge-autostore-dir
-					   "merge_"
-					   (file-name-nondirectory file1))))
+				       (, (if (ediff-nonempty-string-p
+					       merge-autostore-dir)
+					      (concat
+					       merge-autostore-dir
+					       "merge_"
+					       (file-name-nondirectory file1)))
+					  ))
 				 ;; make ediff-startup pass
 				 ;; ediff-control-buffer back to the meta
 				 ;; level; see below
 		      ;; arrange startup hooks 
 		      (` (list (lambda () 
 				 (setq ediff-merge-store-file
-				       (, (concat
-					   merge-autostore-dir
-					   "merge_"
-					   (file-name-nondirectory file1))))
+				       (, (if (ediff-nonempty-string-p
+					       merge-autostore-dir)
+					      (concat
+					       merge-autostore-dir
+					       "merge_"
+					       (file-name-nondirectory file1)))
+					  ))
 				 (setq ediff-meta-buffer (, (current-buffer))
 				       ediff-meta-session-number
 				       (, session-number))
 ;;;###autoload
 (defalias 'eregistry 'ediff-show-registry)
 
-;; If meta-buf doesn't exist, it is created. In that case, id doesn't have a
+;; If meta-buf doesn't exist, it is created.  In that case, id doesn't have a
 ;; parent meta-buf
 ;; Check if META-BUF exists before calling this function
 ;; Optional MUST-REDRAW, if non-nil, would force redrawal of the whole meta
-;; buffer. Otherwise, it will just go over the buffer and update activity marks
+;; buffer.  Otherwise, it will just go over the buffer and update activity marks
 ;; and session status.
 ;; SESSION-NUMBER, if specified, says which session caused the update.
 (defun ediff-update-meta-buffer (meta-buf &optional must-redraw session-number)
   (if (ediff-buffer-live-p meta-buf)
       (ediff-with-current-buffer meta-buf
-	(cond (must-redraw ; completely redraw the meta buffer
-	       (funcall ediff-meta-redraw-function ediff-meta-list))
-	      ((numberp session-number) ; redraw only for the given session
-	       (ediff-update-session-marker-in-dir-meta-buffer session-number))
-	      (t ; update only what's changed, but scan the entire meta buffer
-	       (ediff-update-markers-in-dir-meta-buffer ediff-meta-list)))
-	)))
+	(let (overl)
+	  (cond (must-redraw ; completely redraw the meta buffer
+		 (funcall ediff-meta-redraw-function ediff-meta-list))
+		((numberp session-number) ; redraw only for the given session
+		 (ediff-update-session-marker-in-dir-meta-buffer
+		  session-number))
+		(t ; update what changed only, but scan the entire meta buffer
+		 (ediff-update-markers-in-dir-meta-buffer ediff-meta-list)))
+	  (setq overl (ediff-get-meta-overlay-at-pos (point)))
+	  ;; skip the invisible sessions
+	  (while (and overl (ediff-overlay-get overl 'invisible))
+	    (ediff-next-meta-item1)
+	    (setq overl (ediff-get-meta-overlay-at-pos (point))))
+	  ))))
 
 (defun ediff-update-registry ()
   (ediff-with-current-buffer (current-buffer)
 			(ediff-overlay-get tmp 'ediff-meta-info)))
 	    (setq olist (overlays-at point))
 	    (setq olist
-		  (mapcar (function (lambda (elt)
-				      (overlay-get elt 'ediff-meta-info)))
+		  (mapcar (lambda (elt) (overlay-get elt 'ediff-meta-info))
 			  olist))
 	    (while (and olist (null (car olist))
 			(overlay-get (car olist) 'invisible))
 	    (setq point (1- point)))
 	(setq point (previous-overlay-change point))
 	;; If we are not over an overlay after subtracting 1, it means we are
-	;; in the description area preceding session records. In this case,
+	;; in the description area preceding session records.  In this case,
 	;; goto the top of the registry buffer.
 	(or (car (overlays-at point))
 	    (setq point (point-min)))
 (defun ediff-unmark-all-for-operation ()
   "Unmark all sessions marked for operation."
   (interactive)
-  (let ((list (cdr ediff-meta-list)))
+  (let ((list (cdr ediff-meta-list))
+	elt)
     (while (setq elt (car list))
       (ediff-mark-session-for-operation elt 'unmark)
       (setq list (cdr list))))
 (defun ediff-unmark-all-for-hiding ()
   "Unmark all sessions marked for hiding."
   (interactive)
-  (let ((list (cdr ediff-meta-list)))
+  (let ((list (cdr ediff-meta-list))
+	elt)
     (while (setq elt (car list))
       (ediff-mark-session-for-hiding elt 'unmark)
       (setq list (cdr list))))
   (let ((list (cdr ediff-meta-list))
 	marked1 marked2 marked3
 	fileinfo1 fileinfo2 fileinfo3 elt)
+    (message "Comparing files ...")
     (while (setq elt (car list))
       (setq fileinfo1 (ediff-get-session-objA elt)
 	    fileinfo2 (ediff-get-session-objB elt)
 		((eq last-command-char ?m)
 		 (ediff-mark-session-for-operation elt 'mark))
 		))
-      (setq list (cdr list))))
+      (setq list (cdr list)))
+    (message "Comparing files ... Done"))
   (ediff-update-meta-buffer (current-buffer) 'must-redraw))
 
 ;; mark files 1 and 2 as equal, if they are.
 Note: the `-b' option should be specified in `ediff-backup-specs'.
 
 It is recommended to pass the `-f' option to the patch program, so it won't ask
-questions. However, some implementations don't accept this option, in which
+questions.  However, some implementations don't accept this option, in which
 case the default value for this variable should be changed."
   :type 'string
   :group 'ediff-ptch)
 	   (format "-b %s" ediff-backup-extension))))
   "*Backup directives to pass to the patch program.
 Ediff requires that the old version of the file \(before applying the patch\)
-be saved in a file named `the-patch-file.extension'. Usually `extension' is
+be saved in a file named `the-patch-file.extension'.  Usually `extension' is
 `.orig', but this can be changed by the user and may depend on the system.
 Therefore, Ediff needs to know the backup extension used by the patch program.
 
 Some versions of the patch program let you specify `-b backup-extension'.
 Other versions only permit `-b', which assumes the extension `.orig'
-\(in which case ediff-backup-extension MUST be also `.orig'\). The latest
+\(in which case ediff-backup-extension MUST be also `.orig'\).  The latest
 versions of GNU patch require `-b -z backup-extension'.
 
 Note that both `ediff-backup-extension' and `ediff-backup-specs'
-must be set properly. If your patch program takes the option `-b',
+must be set properly.  If your patch program takes the option `-b',
 but not `-b extension', the variable `ediff-backup-extension' must
 still be set so Ediff will know which extension to use.
 
-Ediff tries to guess the appropriate value for this variables. It is believed
+Ediff tries to guess the appropriate value for this variables.  It is believed
 to be working for `traditional' patch, all versions of GNU patch, and for POSIX
-patch. So, don't change these variables, unless the default doesn't work."
+patch.  So, don't change these variables, unless the default doesn't work."
   :type 'string
   :group 'ediff-ptch)
 
   :type 'regexp
   :group 'ediff-ptch)
 
-;; The buffer of the patch file. Local to control buffer.
+;; The buffer of the patch file.  Local to control buffer.
 (ediff-defvar-local ediff-patchbufer nil "")
 
 ;; The buffer where patch displays its diagnostics.
 (ediff-defvar-local ediff-patch-diagnostics nil "")
 
-;; Map of patch buffer. Has the form:
+;; Map of patch buffer.  Has the form:
 ;;    ((filename1 marker1 marker2) (filename2 marker1 marker2) ...)
 ;; where filenames are files to which patch would have applied the patch;
 ;; marker1 delimits the beginning of the corresponding patch and marker2 does
 ;;    ((filename1 marker1 marker2) (filename2 marker1 marker2) ...)
 ;; where filenames are files to which patch would have applied the patch;
 ;; marker1 delimits the beginning of the corresponding patch and marker2 does
-;; it for the end. This list is then assigned to ediff-patch-map.
+;; it for the end.  This list is then assigned to ediff-patch-map.
 ;; Returns the number of elements in the list ediff-patch-map
 (defun ediff-map-patch-buffer (buf)
   (ediff-with-current-buffer buf
 
 ;; Fix up the file names in the list using the argument FILENAME
 ;; Algorithm: find the first file's directory and cut it out from each file
-;; name in the patch. Prepend the directory of FILENAME to each file in the
-;; patch. In addition, the first file in the patch is replaced by FILENAME.
+;; name in the patch.  Prepend the directory of FILENAME to each file in the
+;; patch.  In addition, the first file in the patch is replaced by FILENAME.
 ;; Each file is actually a file-pair of files found in the context diff header
 ;; In the end, for each pair, we select the shortest existing file.
 ;; Note: Ediff doesn't recognize multi-file patches that are separated
-;; with the `Index:' line. It treats them as a single-file patch.
+;; with the `Index:' line.  It treats them as a single-file patch.
 ;;
 ;; Executes inside the patch buffer
 (defun ediff-fixup-patch-map (filename)
 	)
 
     ;; chop off base-dirs
-    (mapcar (function (lambda (triple)
-			(or (string= (car (car triple)) "/dev/null")
-			    (setcar (car triple)
-				    (ediff-file-name-sans-prefix
-				     (car (car triple)) base-dir1)))
-			(or (string= (cdr (car triple)) "/dev/null")
-			    (setcdr (car triple)
-				    (ediff-file-name-sans-prefix
-				     (cdr (car triple)) base-dir2)))
-			))
+    (mapcar (lambda (triple)
+	      (or (string= (car (car triple)) "/dev/null")
+		  (setcar (car triple)
+			  (ediff-file-name-sans-prefix
+			   (car (car triple)) base-dir1)))
+	      (or (string= (cdr (car triple)) "/dev/null")
+		  (setcdr (car triple)
+			  (ediff-file-name-sans-prefix
+			   (cdr (car triple)) base-dir2)))
+	      )
 	    ediff-patch-map)
 
     ;; take the given file name into account
 			(file-name-nondirectory filename)))))
 
     ;; prepend actual-dir
-    (mapcar (function (lambda (triple)
-			 (if (and (string-match "^/null/" (car (car triple)))
-				  (string-match "^/null/" (cdr (car triple))))
-			     ;; couldn't strip base-dir1 and base-dir2
-			     ;; hence, something wrong
-			     (progn
-			       (with-output-to-temp-buffer ediff-msg-buffer
-				 (princ
-				  (format "
+    (mapcar (lambda (triple)
+	      (if (and (string-match "^/null/" (car (car triple)))
+		       (string-match "^/null/" (cdr (car triple))))
+		  ;; couldn't strip base-dir1 and base-dir2
+		  ;; hence, something wrong
+		  (progn
+		    (with-output-to-temp-buffer ediff-msg-buffer
+		      (princ
+		       (format "
 The patch file contains a context diff for
 	%s
 	%s
 However, Ediff cannot infer the name of the actual file
-to be patched on your system. If you know the correct file name,
+to be patched on your system.  If you know the correct file name,
 please enter it now.
 
 If you don't know and still would like to apply patches to
 other files, enter /dev/null
 "
-					  (substring (car (car triple)) 6)
-					  (substring (cdr (car triple)) 6))))
-			       (let ((directory t)
-				     user-file)
-				 (while directory
-				   (setq user-file
-					 (read-file-name
-					  "Please enter file name: "
-					  actual-dir actual-dir t))
-				   (if (not (file-directory-p user-file))
-				       (setq directory nil)
-				     (setq directory t)
-				     (beep)
-				     (message "%s is a directory" user-file)
-				     (sit-for 2)))
-				 (setcar triple (cons user-file user-file))))
-			   (setcar (car triple)
-				   (expand-file-name 
-				    (concat actual-dir (car (car triple)))))
-			   (setcdr (car triple)
-				   (expand-file-name 
-				    (concat actual-dir (cdr (car triple))))))
-			 ))
+			       (substring (car (car triple)) 6)
+			       (substring (cdr (car triple)) 6))))
+		    (let ((directory t)
+			  user-file)
+		      (while directory
+			(setq user-file
+			      (read-file-name
+			       "Please enter file name: "
+			       actual-dir actual-dir t))
+			(if (not (file-directory-p user-file))
+			    (setq directory nil)
+			  (setq directory t)
+			  (beep)
+			  (message "%s is a directory" user-file)
+			  (sit-for 2)))
+		      (setcar triple (cons user-file user-file))))
+		(setcar (car triple)
+			(expand-file-name 
+			 (concat actual-dir (car (car triple)))))
+		(setcdr (car triple)
+			(expand-file-name 
+			 (concat actual-dir (cdr (car triple))))))
+	      )
 	    ediff-patch-map)
     ;; check for the shorter existing file in each pair and discard the other
     ;; one
-    (mapcar (function (lambda (triple)
-			(let* ((file1 (car (car triple)))
-			       (file2 (cdr (car triple)))
-			       (f1-exists (file-exists-p file1))
-			       (f2-exists (file-exists-p file2)))
-			  (cond
-			   ((and (< (length file2) (length file1))
-				 f2-exists)
-			    (setcar triple file2))
-			   ((and (< (length file1) (length file2))
-				 f1-exists)
-			    (setcar triple file1))
-			   ((and f1-exists f2-exists
-				 (string= file1 file2))
-			    (setcar triple file1))
-			   ((and f1-exists f2-exists)
-			    (with-output-to-temp-buffer ediff-msg-buffer
-			      (princ (format "
+    (mapcar (lambda (triple)
+	      (let* ((file1 (car (car triple)))
+		     (file2 (cdr (car triple)))
+		     (f1-exists (file-exists-p file1))
+		     (f2-exists (file-exists-p file2)))
+		(cond
+		 ((and (< (length file2) (length file1))
+		       f2-exists)
+		  (setcar triple file2))
+		 ((and (< (length file1) (length file2))
+		       f1-exists)
+		  (setcar triple file1))
+		 ((and f1-exists f2-exists
+		       (string= file1 file2))
+		  (setcar triple file1))
+		 ((and f1-exists f2-exists)
+		  (with-output-to-temp-buffer ediff-msg-buffer
+		    (princ (format "
 Ediff has inferred that
 	%s
 	%s
     Type `y' to use %s as the target;
     Type `n' to use %s as the target.
 "
-					     file1 file2 file2 file1)))
-			    (setcar triple
-				    (if (y-or-n-p (format "Use %s ? " file2))
-					file2 file1)))
-			   (f2-exists (setcar triple file2))
-			   (f1-exists (setcar triple file1))
-			   (t
-			    (with-output-to-temp-buffer ediff-msg-buffer
-			      (princ "\nEdiff has inferred that")
-			      (if (string= file1 file2)
-				  (princ (format "
+				   file1 file2 file2 file1)))
+		  (setcar triple
+			  (if (y-or-n-p (format "Use %s ? " file2))
+			      file2 file1)))
+		 (f2-exists (setcar triple file2))
+		 (f1-exists (setcar triple file1))
+		 (t
+		  (with-output-to-temp-buffer ediff-msg-buffer
+		    (princ "\nEdiff has inferred that")
+		    (if (string= file1 file2)
+			(princ (format "
 	%s
-is the target for this patch. However, this file does not exist."
-						 file1))
-				(princ (format "
+is the target for this patch.  However, this file does not exist."
+				       file1))
+		      (princ (format "
 	%s
 	%s
-are two possible targets for this patch. However, these files do not exist."
-					       file1 file2)))
-			      (princ "
+are two possible targets for this patch.  However, these files do not exist."
+				     file1 file2)))
+		    (princ "
 \nPlease enter an alternative patch target ...\n"))
-			    (let ((directory t)
-				  target)
-			      (while directory
-				(setq target (read-file-name 
-					      "Please enter a patch target: "
-					      actual-dir actual-dir t))
-				(if (not (file-directory-p target))
-				    (setq directory nil)
-				  (beep)
-				  (message "%s is a directory" target)
-				  (sit-for 2)))
-			      (setcar triple target)))))))
+		  (let ((directory t)
+			target)
+		    (while directory
+		      (setq target (read-file-name 
+				    "Please enter a patch target: "
+				    actual-dir actual-dir t))
+		      (if (not (file-directory-p target))
+			  (setq directory nil)
+			(beep)
+			(message "%s is a directory" target)
+			(sit-for 2)))
+		    (setcar triple target))))))
 	    ediff-patch-map)
     ))
 
     ))
 
 
-;; When patching a buffer, never change the orig file. Instead, create a new
+;; When patching a buffer, never change the orig file.  Instead, create a new
 ;; buffer, ***_patched, even if the buff visits a file.
 ;; Users who want to actually patch the buffer should use
 ;; ediff-patch-file, not ediff-patch-buffer.
 	  (error "Patch appears to have failed")))
     
     ;; If black magic is involved, apply patch to a temp copy of the
-    ;; file. Otherwise, apply patch to the orig copy.  If patch is applied
+    ;; file.  Otherwise, apply patch to the orig copy.  If patch is applied
     ;; to temp copy, we name the result old-name_patched for local files
-    ;; and temp-copy_patched for remote files. The orig file name isn't
+    ;; and temp-copy_patched for remote files.  The orig file name isn't
     ;; changed, and the temp copy of the original is later deleted.
     ;; Without magic, the original file is renamed (usually into
     ;; old-name_orig) and the result of patching will have the same name as
   (if (ediff-merge-job)
       (ediff-maybe-save-and-delete-merge 'save-and-continue)
     ;; 2-way or 3-way compare: save modified buffers
-    (mapcar (function
-	     (lambda (type)
-	       (let ((ebuf (ediff-get-buffer type)))
-		 (and (ediff-buffer-live-p ebuf)
-		      (ediff-with-current-buffer ebuf
-			(and (buffer-modified-p)
-			     (save-buffer)))))))
+    (mapcar (lambda (type)
+	      (let ((ebuf (ediff-get-buffer type)))
+		(and (ediff-buffer-live-p ebuf)
+		     (ediff-with-current-buffer ebuf
+		       (and (buffer-modified-p)
+			    (save-buffer))))))
 	    '(A B C))))
 
 
 ;; Compiler pacifier
 (defvar ediff-patch-diagnostics)
 (defvar ediff-patchbufer)
+(defvar ediff-use-toolbar-p)
+(defvar ediff-toolbar-height)
 (defvar ediff-toolbar)
 (defvar ediff-toolbar-3way)
 (defvar bottom-toolbar)
 (defvar bottom-toolbar-visible-p)
 (defvar bottom-toolbar-height)
 (defvar mark-active)
+(defvar ediff-emacs-p)
 
 (eval-when-compile
   (let ((load-path (cons (expand-file-name ".") load-path)))
 	 (define-key ediff-mode-map "r" 'ediff-restore-diff-in-merge-buffer)
 	 (define-key ediff-mode-map "s" 'ediff-shrink-window-C)
 	 (define-key ediff-mode-map "+" 'ediff-combine-diffs)
-	 (define-key ediff-mode-map "$" 'ediff-toggle-show-clashes-only)
+	 (define-key ediff-mode-map "$"  nil)
+	 (define-key ediff-mode-map "$$" 'ediff-toggle-show-clashes-only)