diff lisp/ediff/ediff-util.el @ 12:bcdc7deadc19 r19-15b7

Import from CVS: tag r19-15b7
author cvs
date Mon, 13 Aug 2007 08:48:16 +0200
parents ac2d302a0011
children 9ee227acff29
line wrap: on
line diff
--- a/lisp/ediff/ediff-util.el	Mon Aug 13 08:47:56 2007 +0200
+++ b/lisp/ediff/ediff-util.el	Mon Aug 13 08:48:16 2007 +0200
@@ -23,14 +23,27 @@
 
 ;;; Code:
 
-(require 'ediff-init)
-(require 'ediff-mult)
-
 ;; Pacify compiler and avoid the need in checking for boundp
 (defvar ediff-patch-diagnostics nil)
 (defvar ediff-patchbufer nil)
+(and noninteractive
+     (eval-when-compile
+       (let ((load-path (cons (expand-file-name ".") load-path)))
+	 (load-file "ediff-init.el")
+	 (load-file "ediff-help.el"))))
 ;; end pacifier
 
+(require 'ediff-init)
+(require 'ediff-help)
+(require 'ediff-mult)
+
+;;(if ediff-xemacs-p
+;;    (require 'ediff-tbar)
+;;  (defun ediff-use-toolbar-p () nil))
+;;
+;; for the time being
+(defun ediff-use-toolbar-p () nil)
+
 
 ;;; Functions
 
@@ -100,6 +113,10 @@
   (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)
@@ -183,6 +200,7 @@
   (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
@@ -210,10 +228,13 @@
 ;; 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)
-  (setq file-A (expand-file-name file-A))
-  (setq file-B (expand-file-name file-B))
+  ;; 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)))
   (if (stringp file-C)
-      (setq file-C (expand-file-name file-C)))
+      (setq file-C
+	    (ediff-convert-standard-filename (expand-file-name file-C))))
   (let* ((control-buffer-name 
 	  (ediff-unique-buffer-name "*Ediff Control Panel" "*"))
 	 (control-buffer (ediff-eval-in-buffer buffer-A
@@ -461,11 +482,13 @@
     (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
@@ -473,74 +496,11 @@
 		  ediff-split-window-function
 		  (ediff-multiframe-setup-p)
 		  ediff-wide-display-p))
+    (if (not (ediff-multiframe-setup-p))
+	(ediff-make-bottom-toolbar))    ; 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))
 
 
 
@@ -770,8 +730,9 @@
 		 control-frame
 		 (eq this-command 'ediff-quit))))
 	  ))
-    (ediff-eval-in-buffer control-buf
-      (ediff-refresh-mode-lines))
+
+    (ediff-restore-highlighting)
+    (ediff-eval-in-buffer control-buf (ediff-refresh-mode-lines))
     ))
   
 ;; this function returns to the window it was called from
@@ -881,12 +842,13 @@
 		 ediff-highlight-all-diffs t)))
 		 
     (if (and ediff-use-faces ediff-highlight-all-diffs)
-	(ediff-color-background-regions)
-      (ediff-color-background-regions 'unhighlight))
+	(ediff-paint-background-regions)
+      (ediff-paint-background-regions 'unhighlight))
     
     (ediff-unselect-and-select-difference
      ediff-current-difference 'select-only))
   )
+
   
 (defun ediff-toggle-autorefine ()
   "Toggle auto-refine mode."
@@ -1001,12 +963,13 @@
 		   (setq toggle-ro-cmd 'toggle-read-only)
 		   (beep 1) (beep 1)
 		   (message
-		    "Boy, this is risky! Better don't change this file...")
+		    "Boy, this is risky! Don't modify 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))
 	
@@ -1019,30 +982,51 @@
 	    (message "Warning: file %s is read-only"
 		     (ediff-abbreviate-file-name file) (beep 1)))
 	))))
-  
 
-;; This is a simple-minded check for whether a file is under version control
-;; and is checked out.
+;; 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.
 ;; 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-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-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 (ediff-file-under-version-control file)
+       (file-writable-p file)))
 (defun ediff-file-checked-in-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")))
-       ))
+  (and (ediff-file-under-version-control file)
+       (not (file-writable-p file))))
       
 (defun ediff-swap-buffers ()
   "Rotate the display of buffers A, B, and C."
@@ -1175,22 +1159,57 @@
       (ediff-eval-in-buffer ctl-buf
 	(setq ediff-window-B nil) ; force update of window config
 	(ediff-recenter 'no-rehighlight)))))
-	
+
+;;;###autoload
 (defun ediff-toggle-multiframe ()
   "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)
-  (ediff-barf-if-not-control-buffer)
+  (let (set-func)
   (or (ediff-window-display-p)
       (error "%sEmacs is not running as a window application"
 	     (if ediff-emacs-p "" "X")))
+
+  (setq set-func (if (ediff-in-control-buffer-p) 'setq 'setq-default))
+
   (cond ((eq ediff-window-setup-function 'ediff-setup-windows-multiframe)
-	 (setq ediff-window-setup-function 'ediff-setup-windows-plain))
+	 (eval
+	  (list
+	   set-func
+	   'ediff-window-setup-function ''ediff-setup-windows-plain)))
 	((eq ediff-window-setup-function 'ediff-setup-windows-plain)
-	 (setq ediff-window-setup-function 'ediff-setup-windows-multiframe)))
-  (setq ediff-window-B nil)
-  (ediff-recenter 'no-rehighlight))
+	 (if (ediff-in-control-buffer-p)
+	     (ediff-kill-bottom-toolbar))
+	 (eval
+	  (list
+	   set-func
+	   'ediff-window-setup-function ''ediff-setup-windows-multiframe))))
+  (if (ediff-in-control-buffer-p)
+      (progn
+	(setq ediff-window-B nil)
+	(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
+(defun ediff-make-bottom-toolbar ()
+  (if (ediff-use-toolbar-p)
+      (progn
+	(set-specifier bottom-toolbar (list (selected-frame) ediff-toolbar))
+	(set-specifier bottom-toolbar-visible-p (list (selected-frame) t)) 
+	(set-specifier bottom-toolbar-height (list (selected-frame) 34)))))
 	       
 ;; Merging
 
@@ -2188,10 +2207,17 @@
 		      (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))
+	(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))))))
     (condition-case nil
 	(ediff-eval-in-buffer ediff-buffer-A
 	  (setq ediff-this-buffer-ediff-sessions 
@@ -2233,6 +2259,14 @@
   (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))
@@ -2242,6 +2276,20 @@
 
   (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))
   ))
@@ -2277,6 +2325,10 @@
 
     (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)
@@ -2290,7 +2342,7 @@
 	(or (ediff-get-visible-buffer-window buff-A)
 	    (progn
 	      (if (ediff-get-visible-buffer-window buff-B)
-		  (split-window-vertically))
+		  (funcall ediff-split-window-function))
 	      (switch-to-buffer buff-A)))
       (error))
     (if three-way-job
@@ -2299,7 +2351,7 @@
 		(progn
 		  (if (or (ediff-get-visible-buffer-window buff-A)
 			  (ediff-get-visible-buffer-window buff-B))
-		      (split-window-vertically))
+		      (funcall ediff-split-window-function))
 		  (switch-to-buffer buff-C)
 		  (balance-windows)))
 	  (error)))
@@ -2337,6 +2389,53 @@
 					(buffer-name ediff-buffer-C)))))
 	(ediff-kill-buffer-carefully ediff-buffer-C))))
 
+(defun ediff-maybe-save-and-delete-merge ()
+  "Default hook to run on quitting a merge job.
+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 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))
+    (if ediff-autostore-merges
+	(cond ((stringp ediff-merge-store-file)
+	       ;; store, ask to delete
+	       (ediff-write-merge-buffer-then-kill
+		ediff-buffer-C merge-store-file 'show-file))
+	      ((eq ediff-autostore-merges t)
+	       ;; ask for file name
+	       (setq merge-store-file
+		     (read-file-name "Save the result of the merge in: "))
+	       (ediff-write-merge-buffer-then-kill
+		ediff-buffer-C merge-store-file))
+	      ((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 "The result of the merge goes into: "))
+	       (ediff-write-merge-buffer-then-kill
+		ediff-buffer-C merge-store-file))))
+    ))
+
+(defun ediff-write-merge-buffer-then-kill (buf file &optional show-file)
+  (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 (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 ()
@@ -2583,8 +2682,7 @@
 	  (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))
       )))
 
 
@@ -2618,7 +2716,6 @@
 		      prompt
 		      (cond (default-file
 			      (concat " (default " default-file "):"))
-			    ;;((string-match "[?:!,;][ \t]*$" prompt) "")
 			    (t (concat " (default " default-dir "):"))))
 	      default-dir
 	      (or default-file default-dir)
@@ -2673,7 +2770,7 @@
 		    nil          ; don't append---erase
 		    'no-message) 
       (set-file-modes f ediff-temp-file-mode)
-      f)))
+      (ediff-convert-standard-filename (expand-file-name f)))))
 
 ;; Quote metacharacters (using \) when executing diff in Unix, but not in
 ;; EMX OS/2
@@ -2796,29 +2893,156 @@
       (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)
+	quit-now
+	begA begB endA endB bufA bufB)
+
+    (cond ((ediff-merge-job)
+	   (setq bufB ediff-buffer-C)
+	   (while (cond ((memq answer '(?A ?a))
+			 (setq bufA ediff-buffer-A)
+			 nil)
+			((memq answer '(?B ?b))
+			 (setq bufA ediff-buffer-B)
+			 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 (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)))
+
+    (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)
     
+    (or (y-or-n-p 
+	 "Please check the selected regions. Continue? ")
+	(setq quit-now t))
+    
+    (ediff-eval-in-buffer bufA
+      (widen))
+    (ediff-eval-in-buffer bufB
+      (widen))
+    (if quit-now
+	(error "Thank you. Come back another day..."))
 
-;; will simplify it in due time, when emacs acquires before/after strings
+    (ediff-regions-internal
+     bufA begA endA bufB begB endB
+     nil  			; startup hook
+     'ediff-regions-linewise	; job name
+     nil)			; no word mode
+    ))
+
+
 (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)))
@@ -2893,68 +3117,16 @@
     ))
 
 
-
-(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)
-	)))
-
+;; 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-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
@@ -2973,58 +3145,10 @@
   ;; 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.
@@ -3235,6 +3359,10 @@
   (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
@@ -3462,6 +3590,7 @@
 ;;; 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)