+;; this is the action invoked when the user selects a patch from the meta
+;; buffer.
+(defun ediff-patch-file-form-meta (file &optional startup-hooks)
+ (let* ((pos (ediff-event-point last-command-event))
+ (meta-buf (ediff-event-buffer last-command-event))
+ ;; ediff-get-meta-info gives error if meta-buf or pos are invalid
+ (info (ediff-get-meta-info meta-buf pos))
+ (meta-patchbuf ediff-meta-patchbufer)
+ session-buf beg-marker end-marker)
+
+ (if (or (file-directory-p file) (string-match "/dev/null" file))
+ (error "`%s' is not an ordinary file" (file-name-as-directory file)))
+ (setq session-buf (ediff-get-session-buffer info)
+ beg-marker (ediff-get-session-objB-name info)
+ end-marker (ediff-get-session-objC-name info))
+
+ (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!"))
+
+ (ediff-with-current-buffer meta-patchbuf
+ (save-restriction
+ (widen)
+ (narrow-to-region beg-marker end-marker)
+ (ediff-patch-file-internal meta-patchbuf file startup-hooks)))))
+
+
+(defun ediff-unmark-all-for-operation ()
+ "Unmark all sessions marked for operation."
+ (interactive)
+ (let ((list (cdr ediff-meta-list))
+ elt)
+ (while (setq elt (car list))
+ (ediff-mark-session-for-operation elt 'unmark)
+ (setq list (cdr list))))
+ (ediff-update-meta-buffer (current-buffer) 'must-redraw))
+
+(defun ediff-unmark-all-for-hiding ()
+ "Unmark all sessions marked for hiding."
+ (interactive)
+ (let ((list (cdr ediff-meta-list))
+ elt)
+ (while (setq elt (car list))
+ (ediff-mark-session-for-hiding elt 'unmark)
+ (setq list (cdr list))))
+ (ediff-update-meta-buffer (current-buffer) 'must-redraw))
+
+
+;; ACTION is ?h, ?m, ?=: to mark for hiding, mark for operation, or simply
+;; indicate which are equal files
+(defun ediff-meta-mark-equal-files (&optional action)
+ "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."
+ (interactive)
+ (if (null action)
+ (setq action last-command-char))
+ (let ((list (cdr ediff-meta-list))
+ marked1 marked2 marked3
+ fileinfo1 fileinfo2 fileinfo3 elt)
+ (message "Comparing files ...")
+ (while (setq elt (car list))
+ (setq fileinfo1 (ediff-get-session-objA elt)
+ fileinfo2 (ediff-get-session-objB elt)
+ fileinfo3 (ediff-get-session-objC elt))
+ (ediff-set-file-eqstatus fileinfo1 nil)
+ (ediff-set-file-eqstatus fileinfo2 nil)
+ (ediff-set-file-eqstatus fileinfo3 nil)
+
+ (setq marked1 t
+ marked2 t
+ marked3 t)
+ (or (ediff-mark-if-equal fileinfo1 fileinfo2)
+ (setq marked1 nil))
+ (if (ediff-metajob3)
+ (progn
+ (or (ediff-mark-if-equal fileinfo1 fileinfo3)
+ (setq marked2 nil))
+ (or (ediff-mark-if-equal fileinfo2 fileinfo3)
+ (setq marked3 nil))))
+ (if (and marked1 marked2 marked3)
+ (cond ((eq action ?h)
+ (ediff-mark-session-for-hiding elt 'mark))
+ ((eq action ?m)
+ (ediff-mark-session-for-operation elt 'mark))
+ ))
+ (setq list (cdr list)))
+ (message "Comparing files ... Done"))
+ (ediff-update-meta-buffer (current-buffer) 'must-redraw))
+
+;; mark files 1 and 2 as equal, if they are.
+;; returns t, if something was marked
+(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))
+ ))
+
+