X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/3af0304a614da0c7f9b049623c1d814926930f95..1c1da4184c3870e9f207d8a35a519850b9f36d6a:/lisp/ediff-mult.el diff --git a/lisp/ediff-mult.el b/lisp/ediff-mult.el index bb6f815f87..ac77984935 100644 --- a/lisp/ediff-mult.el +++ b/lisp/ediff-mult.el @@ -1,6 +1,6 @@ ;;; ediff-mult.el --- support for multi-file/multi-buffer processing in Ediff -;; Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. +;; Copyright (C) 1995, 1996, 1997, 2001 Free Software Foundation, Inc. ;; Author: Michael Kifer @@ -26,7 +26,7 @@ ;; Users are encouraged to add functionality to this file. ;; The present file contains all the infrastructure needed for that. ;; -;; Generally, to to implement a new multisession capability within Ediff, +;; Generally, to implement a new multisession capability within Ediff, ;; you need to tell it ;; ;; 1. How to display the session group buffer. @@ -49,7 +49,7 @@ ;; or string). The function ediff-redraw-registry-buffer displays the ;; second through last 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 +;; (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 ...) ...) @@ -187,7 +187,15 @@ This can be toggled with `ediff-toggle-filename-truncation'." "*Hooks run just after the registry control panel is set up." :type 'hook :group 'ediff-mult) -(defcustom ediff-session-group-setup-hook nil + +(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. +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." + :type '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 @@ -217,6 +225,13 @@ buffers." ;;; API for ediff-meta-list +;; Structure of the meta-list: +;; (HEADER SESSION1 SESSION2 ...) +;; HEADER: (GROUP-BUF REGEXP OBJA OBJB OBJC SAVE-DIR) +;; OBJA - first directory +;; OBJB - second directory +;; OBJC - third directory +;; SESSION1/2/... are described below ;; group buffer/regexp (defsubst ediff-get-group-buffer (meta-list) (nth 0 (car meta-list))) @@ -233,6 +248,13 @@ buffers." (defsubst ediff-get-group-merge-autostore-dir (meta-list) (nth 5 (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 +;; OBJA/B/C is (FILENAME EQSTATUS) +;; EQSTATUS is ?= or nil (?= means that this file is equal to some other +;; file in this session) ;; session buffer (defsubst ediff-get-session-buffer (elt) (nth 0 elt)) @@ -706,7 +728,7 @@ behavior." (if (eq ediff-metajob-name 'ediff-registry) (run-hooks 'ediff-registry-setup-hook) - (run-hooks 'ediff-session-group-setup-hook)) + (run-hooks 'ediff-after-session-group-setup-hook)) ) ; eval in meta-buffer meta-buffer)) @@ -962,7 +984,7 @@ behavior." 500)) file-modtime file-size) (cond ((not (stringp fname)) (setq file-size -2)) ; file doesn't exits - ((not (ediff-file-remote-p fname)) + ((ediff-listable-file fname) (if (file-exists-p fname) ;; set real size and modtime (setq file-size (ediff-file-size fname) @@ -1255,6 +1277,9 @@ Useful commands: ;; Sets overlay around a meta record with 'ediff-meta-info property PROP ;; If optional SESSION-NUMBER, make it a property of the overlay, ;; ediff-meta-session-number +;; PROP is either the ctl or meta buffer (used when we work with the registry) +;; or a session meta descriptor of the form +;; (SESSION-CTL-BUFFER STATUS OBJA OBJB OBJC) (defun ediff-set-meta-overlay (b e prop &optional session-number hidden) (let (overl) (setq overl (ediff-make-overlay b e)) @@ -1525,14 +1550,14 @@ all marked sessions must be active." ediff-session-action-function ediff-metajob-name ;; make it update (car info) after startup - (` (list (lambda () - ;; child session group should know its parent - (setq ediff-parent-meta-buffer - (quote (, ediff-meta-buffer)) - ediff-meta-session-number - (, session-number)) - ;; and parent will know its child - (setcar (quote (, info)) ediff-meta-buffer))))))) + `(list (lambda () + ;; child session group should know its parent + (setq ediff-parent-meta-buffer + (quote ,ediff-meta-buffer) + ediff-meta-session-number + ,session-number) + ;; and parent will know its child + (setcar (quote ,info) ediff-meta-buffer)))))) ;; Do ediff-revision on a subdirectory ((and (ediff-one-filegroup-metajob) @@ -1546,15 +1571,15 @@ all marked sessions must be active." file1 regexp ediff-session-action-function ediff-metajob-name ;; make it update (car info) after startup - (` (list (lambda () - ;; child session group should know its parent and - ;; its number - (setq ediff-parent-meta-buffer - (quote (, ediff-meta-buffer)) - ediff-meta-session-number - (, session-number)) - ;; and parent will know its child - (setcar (quote (, info)) ediff-meta-buffer))))))) + `(list (lambda () + ;; child session group should know its parent and + ;; its number + (setq ediff-parent-meta-buffer + (quote ,ediff-meta-buffer) + ediff-meta-session-number + ,session-number) + ;; and parent will know its child + (setcar (quote ,info) ediff-meta-buffer)))))) ;; From here on---only individual session handlers @@ -1571,124 +1596,121 @@ all marked sessions must be active." (ediff-merge-files file1 file2 ;; provide startup hooks - (` (list (lambda () + `(list (lambda () (add-hook 'ediff-after-quit-hook-internal (lambda () - (if (ediff-buffer-live-p (, (current-buffer))) + (if (ediff-buffer-live-p ,(current-buffer)) (ediff-show-meta-buffer - (, (current-buffer)) (, session-number)))) + ,(current-buffer) ,session-number))) nil 'local) - (setq ediff-meta-buffer (, (current-buffer)) + (setq ediff-meta-buffer ,(current-buffer) ediff-meta-session-number - (, session-number)) + ,session-number) (setq ediff-merge-store-file - (, (if (ediff-nonempty-string-p - merge-autostore-dir) - (concat - merge-autostore-dir - "merge_" - (file-name-nondirectory file1))) + ,(if (ediff-nonempty-string-p + merge-autostore-dir) + (concat + merge-autostore-dir + ediff-merge-filename-prefix + (file-name-nondirectory file1)) )) ;; make ediff-startup pass ;; ediff-control-buffer back to the meta ;; level; see below (setcar - (quote (, info)) ediff-control-buffer))))) + (quote ,info) ediff-control-buffer)))) (error "Aborted"))) ((ediff-one-filegroup-metajob) ; needs 1 file arg (funcall ediff-session-action-function file1 ;; provide startup hooks - (` (list (lambda () - (add-hook - 'ediff-after-quit-hook-internal - (lambda () - (if (ediff-buffer-live-p - (, (current-buffer))) - (ediff-show-meta-buffer - (, (current-buffer)) - (, session-number)))) - nil 'local) - (setq ediff-meta-buffer (, (current-buffer)) - ediff-meta-session-number - (, session-number)) - (setq ediff-merge-store-file - (, (if (ediff-nonempty-string-p - merge-autostore-dir) - (concat - merge-autostore-dir - "merge_" - (file-name-nondirectory file1))) - )) - ;; make ediff-startup pass - ;; ediff-control-buffer back to the meta - ;; level; see below - (setcar - (quote (, info)) ediff-control-buffer)))))) + `(list (lambda () + (add-hook + 'ediff-after-quit-hook-internal + (lambda () + (if (ediff-buffer-live-p + ,(current-buffer)) + (ediff-show-meta-buffer + ,(current-buffer) + ,session-number))) + nil 'local) + (setq ediff-meta-buffer ,(current-buffer) + ediff-meta-session-number + ,session-number) + (setq ediff-merge-store-file + ,(if (ediff-nonempty-string-p + merge-autostore-dir) + (concat + merge-autostore-dir + ediff-merge-filename-prefix + (file-name-nondirectory file1))) ) + ;; make ediff-startup pass + ;; ediff-control-buffer back to the meta + ;; level; see below + (setcar + (quote ,info) ediff-control-buffer))))) ((not (ediff-metajob3)) ; need 2 file args (funcall ediff-session-action-function file1 file2 ;; provide startup hooks - (` (list (lambda () - (add-hook - 'ediff-after-quit-hook-internal - (lambda () - (if (ediff-buffer-live-p - (, (current-buffer))) - (ediff-show-meta-buffer - (, (current-buffer)) - (, session-number)))) - nil 'local) - (setq ediff-meta-buffer (, (current-buffer)) - ediff-meta-session-number - (, session-number)) - (setq ediff-merge-store-file - (, (if (ediff-nonempty-string-p - merge-autostore-dir) - (concat - merge-autostore-dir - "merge_" - (file-name-nondirectory file1))) - )) - ;; make ediff-startup pass - ;; ediff-control-buffer back to the meta - ;; level; see below - (setcar - (quote (, info)) ediff-control-buffer)))))) + `(list (lambda () + (add-hook + 'ediff-after-quit-hook-internal + (lambda () + (if (ediff-buffer-live-p + ,(current-buffer)) + (ediff-show-meta-buffer + ,(current-buffer) + ,session-number))) + nil 'local) + (setq ediff-meta-buffer ,(current-buffer) + ediff-meta-session-number + ,session-number) + (setq ediff-merge-store-file + ,(if (ediff-nonempty-string-p + merge-autostore-dir) + (concat + merge-autostore-dir + ediff-merge-filename-prefix + (file-name-nondirectory file1))) ) + ;; make ediff-startup pass + ;; ediff-control-buffer back to the meta + ;; level; see below + (setcar + (quote ,info) ediff-control-buffer))))) ((ediff-metajob3) ; need 3 file args (funcall ediff-session-action-function file1 file2 file3 ;; arrange startup hooks - (` (list (lambda () - (add-hook - 'ediff-after-quit-hook-internal - (lambda () - (if (ediff-buffer-live-p - (, (current-buffer))) - (ediff-show-meta-buffer - (, (current-buffer)) - (, session-number)))) - nil 'local) - (setq ediff-merge-store-file - (, (if (ediff-nonempty-string-p - merge-autostore-dir) - (concat - merge-autostore-dir - "merge_" - (file-name-nondirectory file1))) - )) - (setq ediff-meta-buffer (, (current-buffer)) - ediff-meta-session-number - (, session-number)) - ;; this arranges that ediff-startup will pass - ;; the value of ediff-control-buffer back to - ;; the meta level, to the record in the meta - ;; list containing the information about the - ;; session associated with that - ;; ediff-control-buffer - (setcar - (quote (, info)) ediff-control-buffer)))))) + `(list (lambda () + (add-hook + 'ediff-after-quit-hook-internal + (lambda () + (if (ediff-buffer-live-p + ,(current-buffer)) + (ediff-show-meta-buffer + ,(current-buffer) + ,session-number))) + nil 'local) + (setq ediff-merge-store-file + ,(if (ediff-nonempty-string-p + merge-autostore-dir) + (concat + merge-autostore-dir + ediff-merge-filename-prefix + (file-name-nondirectory file1))) ) + (setq ediff-meta-buffer , (current-buffer) + ediff-meta-session-number + ,session-number) + ;; this arranges that ediff-startup will pass + ;; the value of ediff-control-buffer back to + ;; the meta level, to the record in the meta + ;; list containing the information about the + ;; session associated with that + ;; ediff-control-buffer + (setcar + (quote ,info) ediff-control-buffer))))) ) ; cond ) ; eval in meta-buf )) @@ -1722,6 +1744,7 @@ all marked sessions must be active." (defun ediff-show-meta-buffer (&optional meta-buf session-number) "Show the session group buffer." (interactive) + (run-hooks 'ediff-before-directory-setup-hooks) (let (wind frame silent) (if meta-buf (setq silent t)) @@ -1958,10 +1981,11 @@ If this is a session registry buffer then just bury it." (ediff-overlay-get tmp 'ediff-meta-info))) (setq olist (overlays-at point)) (setq olist - (mapcar (lambda (elt) (overlay-get elt 'ediff-meta-info)) + (mapcar (lambda (elt) + (unless (overlay-get elt 'invisible) + (overlay-get elt 'ediff-meta-info))) olist)) - (while (and olist (null (car olist)) - (overlay-get (car olist) 'invisible)) + (while (and olist (null (car olist))) (setq olist (cdr olist))) (setq result (car olist))))) (if result @@ -2086,10 +2110,17 @@ If this is a session registry buffer then just bury it." (ediff-update-meta-buffer (current-buffer) 'must-redraw)) -(defun ediff-meta-mark-equal-files () - "Run though 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 ?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) @@ -2114,9 +2145,9 @@ This is used only for sessions that involve 2 or 3 files at the same time." (or (ediff-mark-if-equal fileinfo2 fileinfo3) (setq marked3 nil)))) (if (and marked1 marked2 marked3) - (cond ((eq last-command-char ?h) + (cond ((eq action ?h) (ediff-mark-session-for-hiding elt 'mark)) - ((eq last-command-char ?m) + ((eq action ?m) (ediff-mark-session-for-operation elt 'mark)) )) (setq list (cdr list)))