;;; ediff-mult.el --- support for multi-file/multi-buffer processing in Ediff
-;; Copyright (C) 1995, 96, 97, 98, 99, 2000, 01, 02 Free Software Foundation, Inc.
+;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+;; 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
;; Author: Michael Kifer <kifer@cs.stonybrook.edu>
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
;;; Commentary:
;; The present file contains all the infrastructure needed for that.
;;
;; Generally, to implement a new multisession capability within Ediff,
-;; you need to tell it
+;; you need to tell it
;;
;; 1. How to display the session group buffer.
;; This function must indicate which Ediff sessions are active (+) and
;; 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-header (nil nil (obj1 nil) (obj2 nil) (obj3 nil))
+;; (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-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.
+;; 2nd and subsequent elements of that list (i.e., after the
+;; description header). See ediff-make-new-meta-list-element for the
+;; explanation of the two nil placeholders in such elements.
+;;
+;; There is API for extracting the components of the members of the
+;; above list. Search for `API for ediff-meta-list' for details.
+;;
+;; HEADER must be a list of SIX elements (nil or string):
+;; (regexp metaobj1 metaobj2 metaobj3 merge-save-buffer
+;; comparison-function)
+;; The function ediff-redraw-registry-buffer displays the
+;; 1st - 4th of these in the registry buffer.
+;; For some jobs some of the members of the header might be nil.
+;; The meaning of metaobj1, metaobj2, and metaobj3 depend on the job.
+;; Typically these are directories where the files to be compared are
+;; found.
;; Also, keep in mind that the function ediff-prepare-meta-buffer
;; (which see) prepends the session group buffer to the descriptor, so
;; the descriptor becomes 7-long.
;; to any of Ediff major entries (such as ediff-files, epatch, etc.).
;; See how this is done in ediff-filegroup-action.
;;
-;; Session descriptions are of the form (obj1 obj2 obj3), which
-;; describe objects relevant to the session. Usually they are names of
-;; files, but sometimes they may be other things. For instance, obj3
-;; is nil for jobs that involve only two files. For patch jobs, obj2
-;; and obj3 are markers that specify the patch corresponding to the
-;; file (whose name is obj1).
+;; Session descriptions are of the form
+;; (nil nil (obj1 . nil) (obj2 . nil) (obj3 . nil))
+;; which describe the objects relevant to the session.
+;; Use ediff-make-new-meta-list-element to create these things.
+;; Usually obj1/2/3 are names of files, but they may also be other
+;; things for some jobs. For instance, obj3 is nil for jobs that
+;; involve only two files. For patch jobs, obj2 and obj3 are markers
+;; that specify the patch corresponding to the file
+;; (whose name is obj1).
+;; The nil's are placeholders, which are used internally by ediff.
;; 4. Write a function that makes a call to ediff-prepare-meta-buffer
-;; passing all this info.
+;; passing all this info.
;; You may be able to use ediff-directories-internal as a template.
;; 5. If you intend to add several related pieces of functionality,
;; you may want to keep the function in 4 as an internal version
;; with different parameters.
;; See how ediff-directories, ediff-merge-directories, and
;; ediff-merge-directories-with-ancestor all use
-;; ediff-directories-internal.
+;; ediff-directories-internal.
;;
;; A useful addition here could be session groups selected by patterns
;; (which are different in each directory). For instance, one may want to
;; which may be in the same or different directories. Or, one may want to
;; compare all files of the form {something} to files of the form {something}~.
;;
-;; Implementing this requires writing an collating function, which should pair
+;; Implementing this requires writing a collating function, which should pair
;; up appropriate files. It will also require a generalization of the
;; functions that do the layout of the meta- and differences buffers and of
;; ediff-filegroup-action.
;;; Code:
-(provide 'ediff-mult)
(defgroup ediff-mult nil
- "Multi-file and multi-buffer processing in Ediff"
+ "Multi-file and multi-buffer processing in Ediff."
:prefix "ediff-"
:group 'ediff)
;; end pacifier
(require 'ediff-init)
-(require 'ediff-util)
;; meta-buffer
(ediff-defvar-local ediff-meta-buffer nil "")
;; buffer used to collect custom diffs from individual sessions in the group
(ediff-defvar-local ediff-meta-diff-buffer nil "")
-;; history var to use for filtering groups
+;; t means recurse into subdirs when deciding which files have same contents
+(ediff-defvar-local ediff-recurse-to-subdirectories nil "")
+
+;; history var to use for filtering groups of files
(defvar ediff-filtering-regexp-history nil "")
+(defcustom ediff-default-filtering-regexp nil
+ "The default regular expression used as a filename filter in multifile comparisons.
+Should be a sexp. For instance (car ediff-filtering-regexp-history) or nil."
+ :type 'sexp
+ :group 'ediff-mult)
+
;; This has the form ((meta-buf regexp dir1 dir2 dir3 merge-auto-store-dir)
;; (ctl-buf session-status (file1 . eq-status) (file2 . eq-status) (file3
;; . eq-status)) (ctl-buf session-status (file1 . eq-status) (file2
(defcustom ediff-meta-truncate-filenames t
"*If non-nil, truncate long file names in the session group buffers.
This can be toggled with `ediff-toggle-filename-truncation'."
+ :type 'boolean
+ :group 'ediff-mult)
+
+(defcustom ediff-meta-mode-hook nil
+ "*Hooks run just after setting up meta mode."
:type 'hook
:group 'ediff-mult)
+
(defcustom ediff-registry-setup-hook nil
"*Hooks run just after the registry control panel is set up."
:type 'hook
(defcustom ediff-before-session-group-setup-hooks nil
"*Hooks to run before Ediff arranges the window for group-level operations.
-It is used by commands such as ediff-directories.
+It is used by commands such as `ediff-directories'.
This hook can be used to save the previous window config, which can be restored
-on ediff-quit, ediff-suspend, or ediff-quit-session-group-hook."
+on `ediff-quit', `ediff-suspend', or `ediff-quit-session-group-hook'."
:type 'hook
- :group 'ediff-hook)
+ :group 'ediff-hook)
(defcustom ediff-after-session-group-setup-hook nil
"*Hooks run just after a meta-buffer controlling a session group, such as
ediff-directories, is run."
:type 'hook
:group 'ediff-mult)
(defcustom ediff-meta-buffer-keymap-setup-hook nil
- "*Hooks run just after setting up the ediff-meta-buffer-map.
+ "*Hooks run just after setting up the `ediff-meta-buffer-map'.
This keymap controls key bindings in the meta buffer and is a local variable.
This means that you can set different bindings for different kinds of meta
buffers."
(nth 3 elt))
(defsubst ediff-get-session-objC (elt)
(nth 4 elt))
+;; Take the "name" component of the object into acount. ObjA/C/B is of the form
+;; (name . equality-indicator)
(defsubst ediff-get-session-objA-name (elt)
(car (nth 2 elt)))
(defsubst ediff-get-session-objB-name (elt)
;; 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.
+;; The first nil in such an element 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 =.
+;; This nil 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)))
+;; Constructs a meta list header.
+;; OBJA, OBJB, OBJC are usually directories involved, but can be different for
+;; different jobs. For instance, multifile patch has only OBJA, which is the
+;; patch buffer.
+(defun ediff-make-new-meta-list-header (regexp
+ objA objB objC
+ merge-auto-store-dir
+ comparison-func)
+ (list regexp objA objB objC merge-auto-store-dir comparison-func))
+
;; 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
;; checks if the session is a meta session
(defun ediff-meta-session-p (session-info)
(and (stringp (ediff-get-session-objA-name session-info))
- (file-directory-p (ediff-get-session-objA-name session-info))
+ (file-directory-p (ediff-get-session-objA-name session-info))
(stringp (ediff-get-session-objB-name session-info))
(file-directory-p (ediff-get-session-objB-name session-info))
(if (stringp (ediff-get-session-objC-name session-info))
(file-directory-p (ediff-get-session-objC-name session-info)) t)))
;; set up the keymap in the meta buffer
-(defun ediff-setup-meta-map()
+(defun ediff-setup-meta-map ()
(setq ediff-meta-buffer-map (make-sparse-keymap))
(suppress-keymap ediff-meta-buffer-map)
(define-key ediff-meta-buffer-map "q" 'ediff-quit-meta-buffer)
\\{ediff-meta-buffer-map}"
(kill-all-local-variables)
(setq major-mode 'ediff-meta-mode)
- (setq mode-name "MetaEdiff"))
+ (setq mode-name "MetaEdiff")
+ ;; don't use run-mode-hooks here!
+ (run-hooks 'ediff-meta-mode-hook))
;; the keymap for the buffer showing directory differences
;;; (while (ediff-get-session-status
;;; (ediff-get-meta-info (current-buffer) pos 'noerror))
;;; (setq pos (ediff-previous-meta-overlay-start pos)))
-
+
(if pos (goto-char pos))
(if (eq ediff-metajob-name 'ediff-registry)
(if (and (ediff-get-meta-info (current-buffer) pos 'noerror)
;; DIR1, DIR2, DIR3 are directories. DIR3 can be nil.
;; OUTPUT-DIR is a directory for auto-storing the results of merge jobs.
;; Can be nil.
-;; REGEXP is a regexp used to filter out files in the directories.
+;; REGEXP is nil or a filter regexp; only file names that match the regexp
+;; are considered.
;; If a file is a directory in dir1 but not dir2 (or vice versa), it is not
;; included in the intersection. However, a regular file that is a dir in dir3
;; is included, since dir3 files are supposed to be ancestors for merging.
-;; Returns a list of the form:
-;; (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=
+;;
+;; Returns a list of the form:
+;; (COMMON-PART DIFF-LIST)
+;; COMMON-PART is car and DIFF-LIST is cdr.
+;;
+;; COMMON-PART is of the form:
+;; (META-HEADER (f1 f2 f3) (f1 f2 f3) ...)
+;; f3 can be nil if intersecting only 2 directories.
+;; Each triple (f1 f2 f3) represents the files to be compared in the
+;; corresponding ediff subsession.
+;;
;; 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
+;; META-HEADER:
+;; 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.
+;;
+;; Some operations might use a different meta header. For instance,
+;; ediff-multifile-patch doesn't have dir2 and dir3, and regexp,
+;; comparison-func don't apply.
+;;
(defun ediff-intersect-directories (jobname
regexp dir1 dir2
&optional
lis1 (directory-files auxdir1 nil regexp)
lis1 (delete "." lis1)
lis1 (delete ".." lis1)
- lis1 (mapcar
+ lis1 (mapcar
(lambda (elt)
(ediff-add-slash-if-directory auxdir1 elt))
lis1)
auxdir2 (file-name-as-directory dir2)
- lis2 (mapcar
+ lis2 (directory-files auxdir2 nil regexp)
+ lis2 (delete "." lis2)
+ lis2 (delete ".." lis2)
+ lis2 (mapcar
(lambda (elt)
(ediff-add-slash-if-directory auxdir2 elt))
- (directory-files auxdir2 nil regexp)))
+ lis2))
(if (stringp dir3)
(setq auxdir3 (file-name-as-directory dir3)
- lis3 (mapcar
+ lis3 (directory-files auxdir3 nil regexp)
+ lis3 (delete "." lis3)
+ lis3 (delete ".." lis3)
+ lis3 (mapcar
(lambda (elt)
(ediff-add-slash-if-directory auxdir3 elt))
- (directory-files auxdir3 nil regexp))))
+ lis3)))
(if (ediff-nonempty-string-p merge-autostore-dir)
(setq merge-autostore-dir
difflist)
(setq difflist (cons
;; diff metalist header
- (list regexp
- auxdir1 auxdir2 auxdir3
- merge-autostore-dir
- comparison-func)
+ (ediff-make-new-meta-list-header regexp
+ auxdir1 auxdir2 auxdir3
+ merge-autostore-dir
+ comparison-func)
difflist))
-
+
(setq common-part
- (cons
+ (cons
;; metalist header
- (list regexp
- auxdir1 auxdir2 auxdir3
- merge-autostore-dir
- comparison-func)
+ (ediff-make-new-meta-list-header regexp
+ auxdir1 auxdir2 auxdir3
+ merge-autostore-dir
+ comparison-func)
(mapcar
- (lambda (elt)
+ (lambda (elt)
(ediff-make-new-meta-list-element
(concat auxdir1 elt)
(concat auxdir2 elt)
(setq common (sort (ediff-copy-list common) 'string-lessp))
;; return result
- (cons
+ (cons
;; header -- has 6 elements. Meta buffer is prepended later by
- ;; ediff-prepare-meta-buffer
- (list regexp auxdir1 nil nil merge-autostore-dir nil)
+ ;; ediff-prepare-meta-buffer
+ (ediff-make-new-meta-list-header regexp
+ auxdir1 nil nil
+ merge-autostore-dir nil)
(mapcar (lambda (elt) (ediff-make-new-meta-list-element
(concat auxdir1 elt) nil nil))
common))
))
-
+
;; If file groups selected by patterns will ever be implemented, this
;; comparison function might become useful.
(defun ediff-prepare-meta-buffer (action-func meta-list
meta-buffer-name redraw-function
jobname &optional startup-hooks)
- (let* ((meta-buffer-name
+ (let* ((meta-buffer-name
(ediff-unique-buffer-name meta-buffer-name "*"))
(meta-buffer (get-buffer-create meta-buffer-name)))
(ediff-with-current-buffer meta-buffer
;; comes after ediff-meta-action-function is set
(ediff-setup-meta-map)
-
+
(if (eq ediff-metajob-name 'ediff-registry)
(progn
(setq ediff-registry-buffer meta-buffer
;; add meta-buffer to the list header
(cons (cons meta-buffer (car meta-list))
(cdr meta-list))))
-
+
(or (eq meta-buffer ediff-registry-buffer)
(setq ediff-session-registry
(cons meta-buffer ediff-session-registry)))
-
+
;; redraw-function uses ediff-meta-list
(funcall redraw-function ediff-meta-list)
-
+
;; set read-only/non-modified
(setq buffer-read-only t)
(set-buffer-modified-p nil)
(or (ediff-one-filegroup-metajob jobname)
(ediff-draw-dir-diffs ediff-dir-difference-list))
- (define-key
+ (define-key
ediff-meta-buffer-map "h" 'ediff-mark-for-hiding-at-pos)
(define-key ediff-meta-buffer-map "x" 'ediff-hide-marked-sessions)
- (define-key
+ (define-key
ediff-meta-buffer-map "m" 'ediff-mark-for-operation-at-pos)
(define-key ediff-meta-buffer-map "u" nil)
(define-key
ediff-meta-buffer-map "um" 'ediff-unmark-all-for-operation)
- (define-key
+ (define-key
ediff-meta-buffer-map "uh" 'ediff-unmark-all-for-hiding)
(cond ((ediff-collect-diffs-metajob jobname)
(define-key
;; Insert session status at point. Status is either ?H (marked for hiding), or
;; ?I (hidden or invalid), or ?* (meaning marked for an operation; currently,
;; such op can only be checking for equality)), or SPC (meaning neither marked
-;; nor invalid)
+;; nor invalid)
(defun ediff-insert-session-status-in-meta-buffer (session)
(insert
(cond ((ediff-get-session-status session)) ; session has status: ?H, ?I, ?*
(session-info (ediff-overlay-get overl 'ediff-meta-info))
(activity-marker (ediff-get-session-activity-marker session-info))
buffer-read-only)
- (or new-marker activity-marker (setq new-marker ?\ ))
+ (or new-marker activity-marker (setq new-marker ?\s))
(goto-char (ediff-overlay-start overl))
(if (eq (char-after (point)) new-marker)
() ; if marker shown in buffer is the same as new-marker, do nothing
(session-info (ediff-overlay-get overl 'ediff-meta-info))
(status (ediff-get-session-status session-info))
buffer-read-only)
- (setq new-status (or new-status status ?\ ))
+ (setq new-status (or new-status status ?\s))
(goto-char (ediff-overlay-start overl))
(forward-char 1) ; status is the second char in session record
(if (eq (char-after (point)) new-status)
(map-extents 'delete-extent) ; xemacs
(mapcar 'delete-overlay (overlays-in 1 1)) ; emacs
)
-
+
(insert (format ediff-meta-buffer-message
(ediff-abbrev-jobname ediff-metajob-name)))
(setq regexp (ediff-get-group-regexp meta-list)
merge-autostore-dir
(ediff-get-group-merge-autostore-dir meta-list))
-
+
(cond ((ediff-collect-diffs-metajob)
(insert
" P:\tcollect custom diffs of all marked sessions\n"))
----------------------------------------------
")
-
+
;; discard info on directories and regexp
(setq meta-list (cdr meta-list)
tmp-list meta-list)
(if empty
(insert
" ****** ****** This session group has no members\n"))
-
+
;; now organize file names like this:
;; use-mark sizeA dateA sizeB dateB filename
;; make sure directories are displayed with a trailing slash.
(if (stringp dir3)
(if (= (mod membership-code ediff-membership-code3) 0) ; dir3
(let ((beg (point)))
- (insert (format " %-25s"
+ (insert (format " %-25s"
(ediff-truncate-string-left
(ediff-abbreviate-file-name
(if (file-directory-p (concat dir3 file))
(if otherfile
(or (file-exists-p otherfile)
(if (y-or-n-p
- (format "Copy %s to %s ? " file-abs otherfile))
+ (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)))
(ediff-show-meta-buffer
ediff-parent-meta-buffer ediff-meta-session-number)
(error "This session group has no parent")))
-
+
;; argument is ignored
(defun ediff-redraw-registry-buffer (&optional ignore)
(while registry-list
(setq elt (car registry-list)
registry-list (cdr registry-list))
-
+
(if (ediff-buffer-live-p elt)
(if (ediff-with-current-buffer elt
(setq job-name ediff-metajob-name
(ediff-overlay-put overl 'highlight t))
(ediff-overlay-put overl 'ediff-meta-info prop)
(ediff-overlay-put overl 'invisible hidden)
+ (ediff-overlay-put overl 'follow-link t)
(if (numberp session-number)
(ediff-overlay-put overl 'ediff-meta-session-number session-number))))
;;; (error "Can't hide active session, %s" (buffer-name session-buf)))
(t (ediff-set-session-status info ?H))))
unmark)
-
+
(defun ediff-mark-for-operation-at-pos (unmark)
"Mark session for a group operation. With prefix arg, unmark."
(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
+ ((and (ediff-meta-session-p elt)
+ (ediff-buffer-live-p
(setq session-buf (ediff-get-session-buffer elt))))
(setq numMarked
- (+ numMarked
+ (+ numMarked
(ediff-with-current-buffer session-buf
;; pass meta-diff along
(setq ediff-meta-diff-buffer diff-buffer)
(save-excursion
(set-buffer meta-diff-buff)
(goto-char (point-max))
- (insert-buffer custom-diff-buf)
+ (insert-buffer-substring custom-diff-buf)
(insert "\n")))
;; if ediff session is not live, run diff directly on the files
- ((memq metajob '(ediff-directories
+ ((memq metajob '(ediff-directories
ediff-merge-directories
ediff-merge-directories-with-ancestor))
;; get diffs by calling shell command on ediff-custom-diff-program
(save-excursion
(set-buffer meta-diff-buff)
(goto-char (point-max))
- (insert-buffer tmp-buf)
+ (insert-buffer-substring tmp-buf)
(insert "\n")))
(t
(ediff-kill-buffer-carefully meta-diff-buff)
(ediff-get-session-objC-name info)))
(set-buffer (get-buffer-create ediff-tmp-buffer))
(erase-buffer)
- (insert-buffer patchbuffer)
+ (insert-buffer-substring patchbuffer)
+ (goto-char (point-min))
(display-buffer ediff-tmp-buffer 'not-this-window)
))
(error "The patch buffer wasn't found"))))
-
+
;; This function executes in meta buffer. It knows where event happened.
(defun ediff-filegroup-action ()
"Execute appropriate action for a selected session."
(info (ediff-get-meta-info meta-buf pos))
(session-buf (ediff-get-session-buffer info))
(session-number (ediff-get-session-number-at-pos pos meta-buf))
+ (default-regexp (eval ediff-default-filtering-regexp))
merge-autostore-dir file1 file2 file3 regexp)
(setq file1 (ediff-get-session-objA-name info)
;; do ediff/ediff-merge on subdirectories
(if (ediff-buffer-live-p session-buf)
(ediff-show-meta-buffer session-buf)
- (setq regexp (read-string "Filter through regular expression: "
- nil 'ediff-filtering-regexp-history))
+ (setq regexp
+ (read-string
+ (if (stringp default-regexp)
+ (format
+ "Filter through regular expression (default %s): "
+ default-regexp)
+ "Filter through regular expression: ")
+ nil
+ 'ediff-filtering-regexp-history
+ (eval ediff-default-filtering-regexp)))
(ediff-directories-internal
file1 file2 file3 regexp
ediff-session-action-function
- ediff-metajob-name
+ ediff-metajob-name
;; make it update (car info) after startup
- `(list (lambda ()
+ `(list (lambda ()
;; child session group should know its parent
(setq ediff-parent-meta-buffer
(quote ,ediff-meta-buffer)
(file-directory-p file1))
(if (ediff-buffer-live-p session-buf)
(ediff-show-meta-buffer session-buf)
- (setq regexp (read-string "Filter through regular expression: "
+ (setq regexp (read-string "Filter through regular expression: "
nil 'ediff-filtering-regexp-history))
(ediff-directory-revisions-internal
file1 regexp
ediff-session-action-function ediff-metajob-name
;; make it update (car info) after startup
- `(list (lambda ()
+ `(list (lambda ()
;; child session group should know its parent and
;; its number
(setq ediff-parent-meta-buffer
"This session has no ancestor. Merge without the ancestor? ")
(ediff-merge-files
file1 file2
- ;; provide startup hooks
- `(list (lambda ()
+ ;; provide startup hooks
+ `(list (lambda ()
(add-hook
'ediff-after-quit-hook-internal
(lambda ()
((ediff-one-filegroup-metajob) ; needs 1 file arg
(funcall ediff-session-action-function
file1
- ;; provide startup hooks
- `(list (lambda ()
+ ;; provide startup hooks
+ `(list (lambda ()
(add-hook
'ediff-after-quit-hook-internal
(lambda ()
((not (ediff-metajob3)) ; need 2 file args
(funcall ediff-session-action-function
file1 file2
- ;; provide startup hooks
- `(list (lambda ()
+ ;; provide startup hooks
+ `(list (lambda ()
(add-hook
'ediff-after-quit-hook-internal
(lambda ()
((ediff-metajob3) ; need 3 file args
(funcall ediff-session-action-function
file1 file2 file3
- ;; arrange startup hooks
- `(list (lambda ()
+ ;; arrange startup hooks
+ `(list (lambda ()
(add-hook
'ediff-after-quit-hook-internal
(lambda ()
(set-window-buffer (selected-window) meta-buf)))
))
(if (and (ediff-window-display-p)
- (window-live-p
+ (window-live-p
(setq wind (ediff-get-visible-buffer-window meta-buf))))
(progn
(setq frame (window-frame wind))
))
(if (ediff-window-display-p)
(progn
- (setq frame
+ (setq frame
(window-frame
(ediff-get-visible-buffer-window ediff-registry-buffer)))
(raise-frame frame)
(ediff-with-current-buffer (current-buffer)
(if (ediff-buffer-live-p ediff-registry-buffer)
(ediff-redraw-registry-buffer)
- (ediff-prepare-meta-buffer
+ (ediff-prepare-meta-buffer
'ediff-registry-action
ediff-session-registry
"*Ediff Registry"
'ediff-registry))
))
-;; If meta-buf exists, it is redrawn along with parent.
+;; If meta-buf exists, it is redrawn along with parent.
;; Otherwise, nothing happens.
(defun ediff-cleanup-meta-buffer (meta-buffer)
(if (ediff-buffer-live-p meta-buffer)
(if (ediff-buffer-live-p ediff-dir-diffs-buffer)
(kill-buffer ediff-dir-diffs-buffer)))
(kill-buffer buf))
-
+
;; Obtain information on a meta record where the user clicked or typed
;; BUF is the buffer where this happened and POINT is the position
(or (ediff-buffer-live-p session-buf) ; either an active patch session
(null session-buf) ; or it is a virgin session
(error
- "Patch has been already applied to this file--cannot be repeated!"))
+ "Patch has already been applied to this file -- can't repeat!"))
(ediff-with-current-buffer meta-patchbuf
(save-restriction
"Run through the session list and mark identical files.
This is used only for sessions that involve 2 or 3 files at the same time.
ACTION is an optional argument that can be ?h, ?m, ?=, to mark for hiding, mark
-for operation, or simply indicate which are equal files. If it is nil, then
-last-command-char is used to decide which action to take."
+for operation, or simply indicate which are equal files. If it is nil, then
+`last-command-char' is used to decide which action to take."
(interactive)
(if (null action)
(setq action last-command-char))
))
(setq list (cdr list)))
(message "Comparing files ... Done"))
+ (setq ediff-recurse-to-subdirectories nil)
(ediff-update-meta-buffer (current-buffer) 'must-redraw))
;; mark files 1 and 2 as equal, if they are.
(defun ediff-mark-if-equal (fileinfo1 fileinfo2)
(let ((f1 (car fileinfo1))
(f2 (car fileinfo2)))
- (cond ((file-directory-p f1) nil)
- ((file-directory-p f2) nil)
- ((ediff-same-file-contents f1 f2)
- (ediff-set-file-eqstatus fileinfo1 t)
- (ediff-set-file-eqstatus fileinfo2 t)
- t))
+ (if (and (stringp f1) (stringp f2) (ediff-same-contents f1 f2))
+ (progn
+ (ediff-set-file-eqstatus fileinfo1 t)
+ (ediff-set-file-eqstatus fileinfo2 t)
+ ))
))
+(provide 'ediff-mult)
+
;;; Local Variables:
;;; eval: (put 'ediff-defvar-local 'lisp-indent-hook 'defun)
;;; eval: (put 'ediff-with-current-buffer 'edebug-form-spec '(form body))
;;; End:
+;;; arch-tag: c8a76898-f96f-4d9c-be9d-129134017188
;;; ediff-mult.el ends here