1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-12-17 10:06:13 +00:00

* ediff-init.el: comments.

* ediff-hook.el: Got rid of autoloads. Not needed, since the hook
is loaded.

* ediff-mult.el (ediff-intersect-directories,
ediff-prepare-meta-buffer,ediff-get-directory-files-under-revision):
cleanup.
(ediff-draw-dir-diffs): now supports the "C" command in directory
difference buffer.
(ediff-dir-diff-copy-file): new function that implements copying
of files from one Ediff dir to another
(ediff-bury-dir-diffs-buffer): kills the buffer instead.
(ediff-append-custom-diff): better error msgs.

* ediff-util.el (ediff-compute-custom-diffs-maybe): buglet fix.
(ediff-inferior-compare-regions): Use
ediff-clone-buffer-for-region-comparison. Better and simpler interface.

* ediff.el (ediff-directories-internal): Cleanup.
(ediff-clone-buffer-for-region-comparison): Better interface.
This commit is contained in:
Michael Kifer 2002-03-05 05:34:19 +00:00
parent 31ade731e6
commit c3912d548f
5 changed files with 325 additions and 196 deletions

View File

@ -1,3 +1,27 @@
2002-03-05 Michael Kifer <kifer@cs.stonybrook.edu>
* ediff-init.el: comments.
* ediff-hook.el: Got rid of autoloads. Not needed, since the hook
is loaded.
* ediff-mult.el (ediff-intersect-directories,
ediff-prepare-meta-buffer,ediff-get-directory-files-under-revision):
cleanup.
(ediff-draw-dir-diffs): now supports the "C" command in directory
difference buffer.
(ediff-dir-diff-copy-file): new function that implements copying
of files from one Ediff dir to another
(ediff-bury-dir-diffs-buffer): kills the buffer instead.
(ediff-append-custom-diff): better error msgs.
* ediff-util.el (ediff-compute-custom-diffs-maybe): buglet fix.
(ediff-inferior-compare-regions): Use
ediff-clone-buffer-for-region-comparison. Better and simpler interface.
* ediff.el (ediff-directories-internal): Cleanup.
(ediff-clone-buffer-for-region-comparison): Better interface.
2002-03-04 Richard M. Stallman <rms@gnu.org>
* emacs-lisp/easy-mmode.el (define-minor-mode):

View File

@ -344,12 +344,13 @@ It needs to be killed when we quit the session.")
(ediff-patch-metajob metajob)
;; add more here
))
;; jobs suitable for the operation of collecting diffs into a multifile patch
(defsubst ediff-collect-diffs-metajob (&optional metajob)
(memq (or metajob ediff-metajob-name)
'(ediff-directories
ediff-directory-revisions
ediff-merge-directories
ediff-merge-directories-with-ancestor
ediff-directory-revisions
ediff-merge-directory-revisions
ediff-merge-directory-revisions-with-ancestor
;; add more here

View File

@ -40,19 +40,20 @@
;; 3. Provide a list of pairs or triples of file names (or buffers,
;; depending on the particular Ediff operation you want to invoke)
;; in the following format:
;; (descriptor (obj1 obj2 obj3) (...) ...)
;; (descriptor-header (nil nil (obj1 nil) (obj2 nil) (obj3 nil))
;; (...) ...)
;; The function ediff-make-new-meta-list-element can be used to create
;; 2nd and subsequent elements of that list.
;; 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,
;; 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
;; second through last of these in the registry buffer.
;; This descriptor-header must be a list of SIX elements (nil or
;; string). The function ediff-redraw-registry-buffer displays the
;; 1st - 4th 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
;; nil in front of each subsequent list (i.e., the above list
;; will become
;; ((meta-buf descriptor) (nil obj1 obj2 obj3) (nil ...) ...)
;; (which see) prepends the session group buffer to the descriptor, so
;; the descriptor becomes 7-long.
;; Ediff expects that your function (in 2 above) will arrange to
;; replace this prepended nil (via setcar) with the actual ediff
;; control buffer associated with an appropriate Ediff session.
@ -225,9 +226,14 @@ buffers."
;;; API for ediff-meta-list
;; A meta-list is either ediff-meta-list, which contains a header and the list
;; of ediff sessions or ediff-dir-difference-list, which is a header followed
;; by the list of differences among the directories (i.e., files that are not
;; in all directories). The header is the same in all meta lists, but the rest
;; is different.
;; Structure of the meta-list:
;; (HEADER SESSION1 SESSION2 ...)
;; HEADER: (GROUP-BUF REGEXP OBJA OBJB OBJC SAVE-DIR)
;; HEADER: (GROUP-BUF REGEXP OBJA OBJB OBJC SAVE-DIR COMPARISON-FUNC)
;; OBJA - first directory
;; OBJB - second directory
;; OBJC - third directory
@ -247,11 +253,14 @@ buffers."
(nth 4 (car meta-list)))
(defsubst ediff-get-group-merge-autostore-dir (meta-list)
(nth 5 (car meta-list)))
(defsubst ediff-get-group-comparison-func (meta-list)
(nth 6 (car meta-list)))
;; ELT is a session meta descriptor (what is being preserved as
;; 'ediff-meta-info)
;; The structure is: (SESSION-CTL-BUFFER STATUS OBJA OBJB OBJC)
;; STATUS is ?I, ?*, ?H
;; STATUS is ?I (hidden or invalid), ?* (marked for operation), ?H (hidden)
;; nil (nothing)
;; OBJA/B/C is (FILENAME EQSTATUS)
;; EQSTATUS is ?= or nil (?= means that this file is equal to some other
;; file in this session)
@ -281,6 +290,20 @@ buffers."
(defsubst ediff-set-file-eqstatus (elt value)
(setcar (cdr elt) value))
;; Create a new element for the meta list out of obj1/2/3, which usually are
;; files
;;
;; The first nil in such an is later replaced with the session buffer. The
;; second nil is reserved for session status.
;;
;; Also, session objects A/B/C are turned into lists of the form (obj nil).
;; This nill is a placeholder for eq-indicator. It is either nil or =.
;; If it is discovered that this file is = to some other
;; file in the same session, eq-indicator is changed to `='.
;; Curently, the eq-indicator is used only for 2 and 3-file jobs.
(defun ediff-make-new-meta-list-element (obj1 obj2 obj3)
(list nil nil (list obj1 nil) (list obj2 nil) (list obj3 nil)))
;; 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
@ -331,6 +354,7 @@ buffers."
;; modify ediff-meta-buffer-map here
(run-hooks 'ediff-meta-buffer-keymap-setup-hook))
(defun ediff-meta-mode ()
"This mode controls all operations on Ediff session groups.
It is entered through one of the following commands:
@ -363,6 +387,10 @@ Commands:
(define-key ediff-dir-diffs-buffer-map "n" 'next-line)
(define-key ediff-dir-diffs-buffer-map "\C-?" 'previous-line)
(define-key ediff-dir-diffs-buffer-map "p" 'previous-line)
(define-key ediff-dir-diffs-buffer-map "C" 'ediff-dir-diff-copy-file)
(if ediff-emacs-p
(define-key ediff-dir-diffs-buffer-map [mouse-2] 'ediff-dir-diff-copy-file)
(define-key ediff-dir-diffs-buffer-map [button2] 'ediff-dir-diff-copy-file))
(define-key ediff-dir-diffs-buffer-map [delete] 'previous-line)
(define-key ediff-dir-diffs-buffer-map [backspace] 'previous-line)
@ -440,6 +468,16 @@ behavior."
(ediff-update-meta-buffer (current-buffer) 'must-redraw))
;; These are used to encode membership of files in directory1/2/3
;; Membership code of a file is a product of codes for the directories where
;; this file is in
(defvar ediff-membership-code1 2)
(defvar ediff-membership-code2 3)
(defvar ediff-membership-code3 5)
(defvar ediff-product-of-memcodes (* ediff-membership-code1
ediff-membership-code2
ediff-membership-code3))
;; 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.
@ -448,21 +486,23 @@ behavior."
;; 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) ...)
;; (DIFF-LIST META-HEADER (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=
;; 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:
;; ((dir1 dir2 dir3) (file . num) (file . num)...)
;; DIFF-LIST is of the form:
;; (META-HEADER (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.
;; META-HEADER is of the form
;; It contains the meta info about this ediff operation
;; (regexp dir1 dir2 dir3 merge-auto-store-dir comparison-func)
;; Later the meta-buffer is prepended to this list.
(defun ediff-intersect-directories (jobname
diff-var regexp dir1 dir2
regexp dir1 dir2
&optional
dir3 merge-autostore-dir comparison-func)
(setq comparison-func (or comparison-func 'string=))
(let (lis1 lis2 lis3 common auxdir1 auxdir2 auxdir3 difflist)
(let (lis1 lis2 lis3 common auxdir1 auxdir2 auxdir3 common-part difflist)
(setq auxdir1 (file-name-as-directory dir1)
lis1 (directory-files auxdir1 nil regexp)
@ -514,39 +554,56 @@ behavior."
(setq difflist (mapcar (lambda (elt) (cons elt 1)) difflist))
;; check for files belonging to lis1/2/3
;; Each elt is of the norm (file . number)
;; Number encodes the directories to which file belongs.
;; It is a product of a subset of ediff-membership-code1=2,
;; ediff-membership-code2=3, and ediff-membership-code3=5.
;; If file belongs to dir 1 only, the membership code is 2.
;; If it is in dir1 and dir3, then the membership code is 2*5=10;
;; if it is in dir1 and dir2, then the membership code is 2*3=6, etc.
(mapcar (lambda (elt)
(if (member (car elt) lis1)
(setcdr elt (* (cdr elt) 2)))
(setcdr elt (* (cdr elt) ediff-membership-code1)))
(if (member (car elt) lis2)
(setcdr elt (* (cdr elt) 3)))
(setcdr elt (* (cdr elt) ediff-membership-code2)))
(if (member (car elt) lis3)
(setcdr elt (* (cdr elt) 5)))
(setcdr elt (* (cdr elt) ediff-membership-code3)))
)
difflist)
(setq difflist (cons (list regexp auxdir1 auxdir2 auxdir3) difflist))
(setq difflist (cons
;; diff metalist header
(list regexp
auxdir1 auxdir2 auxdir3
merge-autostore-dir
comparison-func)
difflist))
;; return the difference list back to the calling function
(set diff-var difflist)
(setq common-part
(cons
;; metalist header
(list regexp
auxdir1 auxdir2 auxdir3
merge-autostore-dir
comparison-func)
(mapcar
(lambda (elt)
(ediff-make-new-meta-list-element
(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)))
;; return result
(cons (list regexp auxdir1 auxdir2 auxdir3 merge-autostore-dir)
(mapcar
(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))
(cons common-part difflist)
))
;; find directory files that are under revision. Include subdirectories, since
@ -592,9 +649,13 @@ behavior."
(setq common (sort (ediff-copy-list common) 'string-lessp))
;; return result
(cons (list regexp auxdir1 nil nil merge-autostore-dir)
(mapcar (lambda (elt) (list (concat auxdir1 elt) nil nil))
common))
(cons
;; header -- has 6 elements. Meta buffer is prepended later by
;; ediff-prepare-meta-buffer
(list regexp auxdir1 nil nil merge-autostore-dir nil)
(mapcar (lambda (elt) (ediff-make-new-meta-list-element
(concat auxdir1 elt) nil nil))
common))
))
@ -657,30 +718,11 @@ behavior."
;; meta-buffs.
(define-key
ediff-meta-buffer-map "M" 'ediff-show-meta-buff-from-registry))
;; 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
;; 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
;; file in the same session, eq-indicator is changed to `='.
;; For now, the eq-indicator is used only for 2 and 3-file jobs.
;; Initialize the meta list -- we don't do this for registry.
(setq ediff-meta-list
;; add meta-buffer to the list header
(cons (cons meta-buffer (car meta-list))
(mapcar
(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)))))
(cdr meta-list))))
(or (eq meta-buffer ediff-registry-buffer)
(setq ediff-session-registry
@ -1048,52 +1090,46 @@ behavior."
(if dir3 (insert "*** Directory C: " dir3 "\n"))
(insert "\n")))
(defun ediff-draw-dir-diffs (diff-list)
(defun ediff-draw-dir-diffs (diff-list &optional buf-name)
(if (null diff-list) (error "Lost difference info on these directories"))
(let* ((buf-name (ediff-unique-buffer-name
"*Ediff File Group Differences" "*"))
(regexp (ediff-get-group-regexp diff-list))
(setq buf-name
(or buf-name
(ediff-unique-buffer-name "*Ediff File Group Differences" "*")))
(let* ((regexp (ediff-get-group-regexp diff-list))
(dir1 (ediff-abbreviate-file-name (ediff-get-group-objA diff-list)))
(dir2 (ediff-abbreviate-file-name (ediff-get-group-objB diff-list)))
(dir3 (ediff-get-group-objC diff-list))
(dir3 (if (stringp dir3) (ediff-abbreviate-file-name dir3)))
(meta-buf (ediff-get-group-buffer diff-list))
(underline (make-string 26 ?-))
file code
file membership-code saved-point
buffer-read-only)
;; skip the directory part
(setq diff-list (cdr diff-list))
(setq ediff-dir-diffs-buffer (get-buffer-create buf-name))
(ediff-with-current-buffer ediff-dir-diffs-buffer
(setq saved-point (point))
(use-local-map ediff-dir-diffs-buffer-map)
(erase-buffer)
(setq ediff-meta-buffer meta-buf)
(insert "\t\t*** Directory Differences ***\n")
(insert "
Useful commands:
`q': hide this buffer
n,SPC: next line
p,DEL: previous line\n\n")
C,button2: over file name -- copy this file to directory that doesn't have it
q: hide this buffer
n,SPC: next line
p,DEL: previous line\n\n")
(insert (format "\n*** Directory A: %s\n" dir1))
(if dir2 (insert (format "*** Directory B: %s\n" dir2)))
(if dir3 (insert (format "*** Directory C: %s\n" dir3)))
(if (and (stringp regexp) (> (length regexp) 0))
(insert
(format "\n*** Filter-through regular expression: %s\n" regexp)))
(format "*** Filter-through regular expression: %s\n" regexp)))
(insert "\n")
(insert (format "\n%-27s%-26s"
(ediff-truncate-string-left
(ediff-abbreviate-file-name
(file-name-as-directory dir1))
25)
(ediff-truncate-string-left
(ediff-abbreviate-file-name
(file-name-as-directory dir2))
25)))
(insert (format "\n%-27s%-26s" "Directory A" "Directory B"))
(if dir3
(insert (format " %-25s\n"
(ediff-truncate-string-left
(ediff-abbreviate-file-name
(file-name-as-directory dir3))
25)))
(insert (format " %-25s\n" "Directory C"))
(insert "\n"))
(insert (format "%s%s" underline underline))
(if (stringp dir3)
@ -1105,47 +1141,64 @@ Useful commands:
(while diff-list
(setq file (car (car diff-list))
code (cdr (car diff-list))
membership-code (cdr (car diff-list))
diff-list (cdr diff-list))
(if (= (mod code 2) 0) ; dir1
(insert (format "%-27s"
(ediff-truncate-string-left
(ediff-abbreviate-file-name
(if (file-directory-p (concat dir1 file))
(file-name-as-directory file)
file))
24)))
(if (= (mod membership-code ediff-membership-code1) 0) ; dir1
(let ((beg (point)))
(insert (format "%-27s"
(ediff-truncate-string-left
(ediff-abbreviate-file-name
(if (file-directory-p (concat dir1 file))
(file-name-as-directory file)
file))
24)))
;; format of meta info in the dir-diff-buffer:
;; (filename-tail filename-full otherdir1 otherdir2 otherdir3)
(ediff-set-meta-overlay
beg (point)
(list meta-buf file (concat dir1 file) dir1 dir2 dir3)))
(insert (format "%-27s" "---")))
(if (= (mod code 3) 0) ; dir2
(insert (format "%-26s"
(ediff-truncate-string-left
(ediff-abbreviate-file-name
(if (file-directory-p (concat dir2 file))
(file-name-as-directory file)
file))
24)))
(if (= (mod membership-code ediff-membership-code2) 0) ; dir2
(let ((beg (point)))
(insert (format "%-26s"
(ediff-truncate-string-left
(ediff-abbreviate-file-name
(if (file-directory-p (concat dir2 file))
(file-name-as-directory file)
file))
24)))
(ediff-set-meta-overlay
beg (point)
(list meta-buf file (concat dir2 file) dir1 dir2 dir3)))
(insert (format "%-26s" "---")))
(if (stringp dir3)
(if (= (mod code 5) 0) ; dir3
(insert (format " %-25s"
(ediff-truncate-string-left
(ediff-abbreviate-file-name
(if (file-directory-p (concat dir3 file))
(file-name-as-directory file)
file))
24)))
(if (= (mod membership-code ediff-membership-code3) 0) ; dir3
(let ((beg (point)))
(insert (format " %-25s"
(ediff-truncate-string-left
(ediff-abbreviate-file-name
(if (file-directory-p (concat dir3 file))
(file-name-as-directory file)
file))
24)))
(ediff-set-meta-overlay
beg (point)
(list meta-buf file (concat dir3 file) dir1 dir2 dir3)))
(insert (format " %-25s" "---"))))
(insert "\n"))
(setq buffer-read-only t)
(set-buffer-modified-p nil)) ; eval in diff buffer
(set-buffer-modified-p nil)
(goto-char saved-point)) ; end eval in diff buffer
))
(defun ediff-bury-dir-diffs-buffer ()
"Bury the directory difference buffer. Display the meta buffer instead."
(interactive)
;; ediff-meta-buffer is set in ediff-draw-dir-diffs so the directory
;; difference buffer remembers the meta buffer
(let ((buf ediff-meta-buffer)
wind)
(bury-buffer)
(ediff-kill-buffer-carefully ediff-dir-diffs-buffer)
(if (setq wind (ediff-get-visible-buffer-window buf))
(select-window wind)
(set-window-buffer (selected-window) buf))))
@ -1164,6 +1217,70 @@ Useful commands:
(set-window-buffer (selected-window) buf)
(goto-char (point-min))))
;; Format of meta info in dir-diff-buffer:
;; (filename-tail filename-full otherdir1 otherdir2)
(defun ediff-dir-diff-copy-file ()
"Copy file described at point to directories where this file is missing."
(interactive)
(let* ((pos (ediff-event-point last-command-event))
(info (ediff-get-meta-info (current-buffer) pos 'noerror))
(meta-buf (car info))
(file-tail (nth 1 info))
(file-abs (nth 2 info))
(otherdir1 (nth 3 info))
(otherfile1 (if otherdir1 (concat otherdir1 file-tail)))
(otherdir2 (nth 4 info))
(otherfile2 (if otherdir2 (concat otherdir2 file-tail)))
(otherdir3 (nth 5 info))
(otherfile3 (if otherdir3 (concat otherdir3 file-tail)))
meta-list dir-diff-list
)
(if (null info)
(error "No file suitable for copying described at this location"))
(ediff-with-current-buffer meta-buf
(setq meta-list ediff-meta-list
dir-diff-list ediff-dir-difference-list))
;; copy file to directories where it doesn't exist, update
;; ediff-dir-difference-list and redisplay
(mapcar
(lambda (otherfile-struct)
(let ((otherfile (car otherfile-struct))
(file-mem-code (cdr otherfile-struct)))
(if otherfile
(or (file-exists-p otherfile)
(if (y-or-n-p
(format "Copy %s to %s ? " file-abs otherfile))
(let* ((file-diff-record (assoc file-tail dir-diff-list))
(new-mem-code
(* (cdr file-diff-record) file-mem-code)))
(copy-file file-abs otherfile)
(setcdr file-diff-record new-mem-code)
(ediff-draw-dir-diffs dir-diff-list (buffer-name))
(sit-for 0)
;; if file is in all three dirs or in two dirs and only
;; two dirs are involved, delete this file's record
(if (or (= new-mem-code ediff-product-of-memcodes)
(and (> new-mem-code ediff-membership-code3)
(null otherfile3)))
(delq file-diff-record dir-diff-list))
))))
))
;; 2,3,5 are numbers used to encode membership of a file in
;; dir1/2/3. See ediff-intersect-directories.
(list (cons otherfile1 2) (cons otherfile2 3) (cons otherfile3 5)))
(if (and (file-exists-p otherfile1)
(file-exists-p otherfile2)
(or (not otherfile3) (file-exists-p otherfile3)))
;; update ediff-meta-list by direct modification
(nconc meta-list
(list (ediff-make-new-meta-list-element
otherfile1 otherfile2 otherfile3)))
)
(ediff-update-meta-buffer meta-buf 'must-redraw)
))
(defun ediff-up-meta-hierarchy ()
"Go to the parent session group buffer."
(interactive)
@ -1404,6 +1521,8 @@ Useful commands:
(save-excursion
(setq numMarked (1+ numMarked))
(funcall operation elt sessionNum)))
;; The following goes into a session represented by a subdirectory
;; and applies operation to marked sessions there
((and (ediff-meta-session-p elt)
(ediff-buffer-live-p
(setq session-buf (ediff-get-session-buffer elt))))
@ -1420,7 +1539,7 @@ Useful commands:
(defun ediff-append-custom-diff (session sessionNum)
(or (ediff-collect-diffs-metajob)
(error "Hmm, I'd hate to do it to you ..."))
(error "Can't compute multifile patch in this context"))
(let ((session-buf (ediff-get-session-buffer session))
(meta-diff-buff ediff-meta-diff-buffer)
(metajob ediff-metajob-name)
@ -1433,14 +1552,17 @@ Useful commands:
(setq custom-diff-buf ediff-custom-diff-buffer)))))
(or (ediff-buffer-live-p meta-diff-buff)
(error "Ediff: something wrong--no multiple diffs buffer"))
(error "Ediff: something wrong--killed multiple diff's buffer"))
(cond ((ediff-buffer-live-p custom-diff-buf)
;; for live session buffers we do them first because the user may
;; have changed them with respect to the underlying files
(save-excursion
(set-buffer meta-diff-buff)
(goto-char (point-max))
(insert-buffer custom-diff-buf)
(insert "\n")))
;; if ediff session is not live, run diff directly on the files
((memq metajob '(ediff-directories
ediff-merge-directories
ediff-merge-directories-with-ancestor))
@ -1460,7 +1582,8 @@ Useful commands:
(insert-buffer tmp-buf)
(insert "\n")))
(t
(error "Can't make context diff for Session %d" sessionNum )))
(ediff-kill-buffer-carefully meta-diff-buff)
(error "Session %d compares versions of file. Such session must be active to enable multifile patch collection" sessionNum )))
))
(defun ediff-collect-custom-diffs ()
@ -1475,6 +1598,7 @@ all marked sessions must be active."
(get-buffer-create
(ediff-unique-buffer-name "*Ediff Multifile Diffs" "*"))))
(ediff-with-current-buffer ediff-meta-diff-buffer
(setq buffer-read-only nil)
(erase-buffer))
(if (> (ediff-operate-on-marked-sessions 'ediff-append-custom-diff) 0)
;; did something

View File

@ -3302,6 +3302,7 @@ Without an argument, it saves customized diff argument, if available
)
(save-buffer)))
;; This function operates only from an ediff control buffer
(defun ediff-compute-custom-diffs-maybe ()
(let ((buf-A-file-name (buffer-file-name ediff-buffer-A))
(buf-B-file-name (buffer-file-name ediff-buffer-B))
@ -3317,6 +3318,9 @@ Without an argument, it saves customized diff argument, if available
(setq ediff-custom-diff-buffer
(get-buffer-create
(ediff-unique-buffer-name "*ediff-custom-diff" "*"))))
(ediff-with-current-buffer ediff-custom-diff-buffer
(setq buffer-read-only nil)
(erase-buffer))
(ediff-exec-process
ediff-custom-diff-program ediff-custom-diff-buffer 'synchronize
ediff-custom-diff-options file-A file-B)
@ -3373,6 +3377,7 @@ Ediff Control Panel to restore highlighting."
(cond ((ediff-merge-job)
(setq bufB ediff-buffer-C)
;; ask which buffer to compare to the merge buffer
(while (cond ((eq answer ?A)
(setq bufA ediff-buffer-A
possibilities '(?B))
@ -3387,10 +3392,12 @@ Ediff Control Panel to restore highlighting."
(sit-for 2)
t))
(let ((cursor-in-echo-area t))
(message "Which buffer to compare to the merge buffer (A/B)? ")
(message
"Which buffer to compare to the merge buffer (A or B)? ")
(setq answer (capitalize (read-char-exclusive))))))
((ediff-3way-comparison-job)
;; ask which two buffers to compare
(while (cond ((memq answer possibilities)
(setq possibilities (delq answer possibilities))
(setq bufA
@ -3407,7 +3414,7 @@ Ediff Control Panel to restore highlighting."
t))
(let ((cursor-in-echo-area t))
(message "Enter the 1st buffer you want to compare (%s): "
(mapconcat 'char-to-string possibilities "/"))
(mapconcat 'char-to-string possibilities " or "))
(setq answer (capitalize (read-char-exclusive)))))
(setq answer "") ; silence error msg
(while (cond ((memq answer possibilities)
@ -3433,9 +3440,9 @@ Ediff Control Panel to restore highlighting."
bufB ediff-buffer-B
possibilities nil)))
(setq bufA (ediff-clone-buffer-for-region-comparison
(buffer-name bufA) "-Region.A-"))
(ediff-with-current-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)
@ -3445,9 +3452,10 @@ Ediff Control Panel to restore highlighting."
(end-of-line)
(or (eobp) (forward-char)) ; include the newline char
(setq endA (point)))
(setq bufB (ediff-clone-buffer-for-region-comparison
(buffer-name bufB) "-Region.B-"))
(ediff-with-current-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)
@ -3458,52 +3466,6 @@ Ediff Control Panel to restore highlighting."
(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-with-current-buffer bufA
(goto-char begA)
(set-mark endA)
(narrow-to-region begA endA)
;; (ediff-activate-mark)
)
;; (sit-for 0)
(ediff-with-current-buffer bufB
(goto-char begB)
(set-mark endB)
(narrow-to-region begB endB)
;; (ediff-activate-mark)
)
;; (sit-for 0)
;; At this point, possibilities contains either the window char A/B/C
;; that was not selected, or it is nil. We delete the window that is not
;; selected.
(if possibilities
(ediff-with-current-buffer ctl-buf
(let* ((wind-to-delete (eval
(ediff-get-symbol-from-alist
(car possibilities)
ediff-window-alist)))
(frame (window-frame wind-to-delete)))
(delete-window wind-to-delete)
(select-frame frame)
(balance-windows))))
(or (y-or-n-p
"Please check regions selected for comparison. Continue? ")
(setq quit-now t))
(ediff-with-current-buffer bufA
(widen))
(ediff-with-current-buffer bufB
(widen))
(if quit-now
(ediff-with-current-buffer ctl-buf
(ediff-recenter)
(sit-for 0)
(error "All right. Make up your mind and come back...")))
(ediff-regions-internal
bufA begA endA bufB begB endB
nil ; setup-hook

View File

@ -6,8 +6,8 @@
;; Created: February 2, 1994
;; Keywords: comparing, merging, patching, tools, unix
(defconst ediff-version "2.76.1" "The current version of Ediff")
(defconst ediff-date "January 4, 2002" "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.
@ -154,7 +154,7 @@
;; 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.
@ -688,8 +688,11 @@ names. Only the files that are under revision control are taken into account."
(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))
@ -715,9 +718,9 @@ names. Only the files that are under revision control are taken into account."
"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
@ -725,11 +728,12 @@ names. Only the files that are under revision control are taken into account."
;; 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
@ -839,10 +843,10 @@ If WIND-B is nil, use window next to WIND-A."
end-B (window-end))))
(setq buffer-A
(ediff-clone-buffer-for-window-comparison
buffer-A wind-A "-Window1-")
buffer-A wind-A "-Window.A-")
buffer-B
(ediff-clone-buffer-for-window-comparison
buffer-B wind-B "-Window2-"))
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)))
@ -853,18 +857,32 @@ If WIND-B is nil, use window next to WIND-A."
buff-name
(concat buff-name region-name
(symbol-name (gensym)))))
(wind (ediff-get-visible-buffer-window buff-name)))
(wind (ediff-get-visible-buffer-window buff-name))
(pop-up-windows t)
other-wind
msg-buf)
(ediff-with-current-buffer cloned-buff
(setq ediff-temp-indirect-buffer t))
(if (window-live-p wind)
(set-window-buffer wind cloned-buff))
(pop-to-buffer cloned-buff)
(message
"Mark a region in buffer %s; then type %s. Use %s to abort."
(buffer-name cloned-buff)
(ediff-format-bindings-of 'exit-recursive-edit)
(ediff-format-bindings-of 'abort-recursive-edit))
(recursive-edit)
(with-temp-buffer
(erase-buffer)
(insert
(format "\n ******* Mark a region in buffer %s *******\n"
(buffer-name cloned-buff)))
(insert
(format "\n\t When done, type %s Use %s to abort\n "
(ediff-format-bindings-of 'exit-recursive-edit)
(ediff-format-bindings-of 'abort-recursive-edit)))
(goto-char (point-min))
(setq msg-buf (current-buffer))
(other-window 1)
(set-window-buffer (selected-window) msg-buf)
(shrink-window-if-larger-than-buffer)
(select-window wind)
(recursive-edit)
)
cloned-buff))
(defun ediff-clone-buffer-for-window-comparison (buff wind region-name)
@ -910,9 +928,9 @@ lines. For large regions, use `ediff-regions-linewise'."
(let ((buffer-A
(ediff-clone-buffer-for-region-comparison buffer-A "-Region1-"))
(ediff-clone-buffer-for-region-comparison buffer-A "-Region.A-"))
(buffer-B
(ediff-clone-buffer-for-region-comparison buffer-B "-Region2-"))
(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)
@ -954,9 +972,9 @@ lines. For small regions, use `ediff-regions-wordwise'."
(error "Buffer %S doesn't exist" buffer-B))
(let ((buffer-A
(ediff-clone-buffer-for-region-comparison buffer-A "-Region1-"))
(ediff-clone-buffer-for-region-comparison buffer-A "-Region.A-"))
(buffer-B
(ediff-clone-buffer-for-region-comparison buffer-B "-Region2-"))
(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)