;;; ediff.el --- a comprehensive visual interface to diff & patch
-;; Copyright (C) 1994, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
+;; Copyright (C) 1994, 95, 96, 97, 98, 99, 2000, 01, 02 Free Software Foundation, Inc.
-;; Author: Michael Kifer <kifer@cs.sunysb.edu>
+;; Author: Michael Kifer <kifer@cs.stonybrook.edu>
;; Created: February 2, 1994
;; Keywords: comparing, merging, patching, tools, unix
-(defconst ediff-version "2.75" "The current version of Ediff")
-(defconst ediff-date "October 29, 2000" "Date of last update")
+(defconst ediff-version "2.77" "The current version of Ediff")
+(defconst ediff-date "March 5, 2002" "Date of last update")
;; This file is part of GNU Emacs.
;; Last directory used by an Ediff command for the ancestor file.
(defvar ediff-last-dir-ancestor nil)
;; Last directory used by an Ediff command as the output directory for merge.
-(defvar ediff-last-merge-autostore-dir)
+(defvar ediff-last-merge-autostore-dir nil)
;; Used as a startup hook to set `_orig' patch file read-only.
(let ((current (dired-get-filename nil 'no-error))
(marked (condition-case nil
(dired-get-marked-files 'no-dir)
- (error)))
+ (error nil)))
aux-list choices result)
(or (integerp fileno) (setq fileno 0))
(if (stringp default)
default-directory))
dir-B f)
(list (setq f (ediff-read-file-name
- "File A to compare" dir-A
- (ediff-get-default-file-name)))
+ "File A to compare"
+ dir-A
+ (ediff-get-default-file-name)
+ 'no-dirs))
(ediff-read-file-name "File B to compare"
(setq dir-B
(if ediff-use-last-dir
default-directory))
dir-B dir-C f ff)
(list (setq f (ediff-read-file-name
- "File A to compare" dir-A
- (ediff-get-default-file-name)))
+ "File A to compare"
+ dir-A
+ (ediff-get-default-file-name)
+ 'no-dirs))
(setq ff (ediff-read-file-name "File B to compare"
(setq dir-B
(if ediff-use-last-dir
(defun ediff-files-internal (file-A file-B file-C startup-hooks job-name
&optional merge-buffer-file)
(let (buf-A buf-B buf-C)
+ (if (string= file-A file-B)
+ (error "Files A and B are the same"))
+ (if (stringp file-C)
+ (or (and (string= file-A file-C) (error "Files A and C are the same"))
+ (and (string= file-B file-C) (error "Files B and C are the same"))))
(message "Reading file %s ... " file-A)
;;(sit-for 0)
(ediff-find-file 'file-A 'buf-A 'ediff-last-dir-A 'startup-hooks)
(or (stringp merge-autostore-dir)
(error "%s: Directory for storing merged files must be a string"
jobname)))
- (let (diffs ; var where ediff-intersect-directories returns the diff list
- file-list meta-buf)
+ (let (;; dir-diff-struct is of the form (common-list diff-list)
+ ;; It is a structure where ediff-intersect-directories returns
+ ;; commonalities and differences among directories
+ dir-diff-struct
+ meta-buf)
(if (and ediff-autostore-merges
(ediff-merge-metajob jobname)
(not merge-autostore-dir))
"Directory for saving merged files = Ancestor Directory. Sure? ")
(error "Directory merge aborted")))))
- (setq file-list (ediff-intersect-directories
- jobname 'diffs
- regexp dir1 dir2 dir3 merge-autostore-dir))
+ (setq dir-diff-struct (ediff-intersect-directories
+ jobname
+ regexp dir1 dir2 dir3 merge-autostore-dir))
(setq startup-hooks
;; this sets various vars in the meta buffer inside
;; ediff-prepare-meta-buffer
;; tell what to do if the user clicks on a session record
(setq ediff-session-action-function (quote ,action))
;; set ediff-dir-difference-list
- (setq ediff-dir-difference-list (quote ,diffs)))
+ (setq ediff-dir-difference-list
+ (cdr (quote ,dir-diff-struct))))
startup-hooks))
(setq meta-buf (ediff-prepare-meta-buffer
'ediff-filegroup-action
- file-list
+ (car dir-diff-struct)
"*Ediff Session Group Panel"
'ediff-redraw-directory-group-buffer
jobname
(select-window wind-B)
(setq beg-B (window-start)
end-B (window-end))))
+ (setq buffer-A
+ (ediff-clone-buffer-for-window-comparison
+ buffer-A wind-A "-Window.A-")
+ buffer-B
+ (ediff-clone-buffer-for-window-comparison
+ buffer-B wind-B "-Window.B-"))
(ediff-regions-internal
buffer-A beg-A end-A buffer-B beg-B end-B
startup-hooks job-name word-mode nil)))
+
;;;###autoload
(defun ediff-regions-wordwise (buffer-A buffer-B &optional startup-hooks)
- "Run Ediff on a pair of regions in two different buffers.
-Regions \(i.e., point and mark\) are assumed to be set in advance.
+ "Run Ediff on a pair of regions in specified buffers.
+Regions \(i.e., point and mark\) are assumed to be set in advance except
+for the second region in the case both regions are from the same buffer.
+In such a case the user is asked to interactively establish the second
+region.
This function is effective only for relatively small regions, up to 200
lines. For large regions, use `ediff-regions-linewise'."
(interactive
(error "Buffer %S doesn't exist" buffer-B))
- (let (reg-A-beg reg-A-end reg-B-beg reg-B-end)
+ (let ((buffer-A
+ (ediff-clone-buffer-for-region-comparison buffer-A "-Region.A-"))
+ (buffer-B
+ (ediff-clone-buffer-for-region-comparison buffer-B "-Region.B-"))
+ reg-A-beg reg-A-end reg-B-beg reg-B-end)
(save-excursion
(set-buffer buffer-A)
(setq reg-A-beg (region-beginning)
;;;###autoload
(defun ediff-regions-linewise (buffer-A buffer-B &optional startup-hooks)
- "Run Ediff on a pair of regions in two different buffers.
-Regions \(i.e., point and mark\) are assumed to be set in advance.
+ "Run Ediff on a pair of regions in specified buffers.
+Regions \(i.e., point and mark\) are assumed to be set in advance except
+for the second region in the case both regions are from the same buffer.
+In such a case the user is asked to interactively establish the second
+region.
Each region is enlarged to contain full lines.
This function is effective for large regions, over 100-200
lines. For small regions, use `ediff-regions-wordwise'."
(if (not (ediff-buffer-live-p buffer-B))
(error "Buffer %S doesn't exist" buffer-B))
- (let (reg-A-beg reg-A-end reg-B-beg reg-B-end)
+ (let ((buffer-A
+ (ediff-clone-buffer-for-region-comparison buffer-A "-Region.A-"))
+ (buffer-B
+ (ediff-clone-buffer-for-region-comparison buffer-B "-Region.B-"))
+ reg-A-beg reg-A-end reg-B-beg reg-B-end)
(save-excursion
(set-buffer buffer-A)
(setq reg-A-beg (region-beginning)
(setq beg-B (move-marker (make-marker) beg-B)
end-B (move-marker (make-marker) end-B)))
- (if (and (eq buffer-A buffer-B)
- (or (and (< beg-A end-B) (<= beg-B beg-A)) ; b-B b-A e-B
- (and (< beg-B end-A) (<= end-A end-B)))) ; b-B e-A e-B
- (progn
- (with-output-to-temp-buffer ediff-msg-buffer
- (ediff-with-current-buffer standard-output
- (fundamental-mode))
- (princ "
-You have requested to compare overlapping regions of the same buffer.
-
-In this case, Ediff's highlighting may be confusing---in the same window,
-you may see highlighted regions that belong to different regions.
-
-Continue anyway? (y/n) "))
-
- (if (y-or-n-p "Continue anyway? ")
- ()
- (error "%S aborted" job-name))))
-
;; make file-A
(if word-mode
(ediff-wordify beg-A end-A buffer-A tmp-buffer)
default-directory))
dir-B f)
(list (setq f (ediff-read-file-name
- "File A to merge" dir-A
- (ediff-get-default-file-name)))
+ "File A to merge"
+ dir-A
+ (ediff-get-default-file-name)
+ 'no-dirs))
(ediff-read-file-name "File B to merge"
(setq dir-B
(if ediff-use-last-dir
default-directory))
dir-B dir-ancestor f ff)
(list (setq f (ediff-read-file-name
- "File A to merge" dir-A
- (ediff-get-default-file-name)))
+ "File A to merge"
+ dir-A
+ (ediff-get-default-file-name)
+ 'no-dirs))
(setq ff (ediff-read-file-name "File B to merge"
(setq dir-B
(if ediff-use-last-dir
(setq rev1
(read-string
(format
- "Version 1 to merge (default: %s's latest version): "
+ "Version 1 to merge (default: %s's working version): "
(if (stringp file)
(file-name-nondirectory file) "current buffer")))
rev2
;; buffer
merge-buffer-file)
"Run Ediff by merging two revisions of a file with a common ancestor.
-The file is the the optional FILE argument or the file visited by the current
+The file is the optional FILE argument or the file visited by the current
buffer."
(interactive)
(if (stringp file) (find-file file))
(setq rev1
(read-string
(format
- "Version 1 to merge (default: %s's latest version): "
+ "Version 1 to merge (default: %s's working version): "
(if (stringp file)
(file-name-nondirectory file) "current buffer")))
rev2
(intern (format "ediff-%S-merge-internal" ediff-version-control-package))
rev1 rev2 ancestor-rev startup-hooks merge-buffer-file)))
+;; MK: Check. This function doesn't seem to be used any more by pcvs or pcl-cvs
;;;###autoload
(defun run-ediff-from-cvs-buffer (pos)
"Run Ediff-merge on appropriate revisions of the selected file.
(buffer-file-name patch-buf))))
(t default-directory)))
(setq source-file
- ;; the default is the directory, not the visited file name
(read-file-name
"File to patch (directory, if multifile patch): "
- source-dir (ediff-get-default-file-name)))
+ ;; use an explicit initial file
+ source-dir nil nil (ediff-get-default-file-name)))
(ediff-dispatch-file-patching-job patch-buf source-file)))
;;;###autoload
(if ediff-use-last-dir
ediff-last-dir-A
default-directory)
- (ediff-get-default-file-name))))
+ (ediff-get-default-file-name)
+ 'no-dirs)))
(find-file file)
(if (and (buffer-modified-p)
(y-or-n-p (message "Buffer %s is modified. Save buffer? "
(let (rev1 rev2)
(setq rev1
(read-string
- (format "Version 1 to compare (default: %s's latest version): "
+ (format "Version 1 to compare (default: %s's working version): "
(file-name-nondirectory file)))
rev2
(read-string