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:
parent
31ade731e6
commit
c3912d548f
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user