emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: table.el


From: Tak Ota
Subject: Re: table.el
Date: Sun, 02 Dec 2001 12:42:03 -0800 (PST)

Sun, 02 Dec 2001 01:11:36 -0500: "Stefan Monnier" <monnier+gnu/address@hidden> 
wrote:

> You might want to define this idiom as a macro `with-wrapper-hook'

I like the naming `with-wrapper-hook' since the manipulation of the
object is done through `add-hook' and `remove-hook'.

> and you might even want to extend it to handle the local/global
> behavior of normal hooks (i.e. if you encounter a `t' in a buffer-local
> hook, it stands for its global value).

Could you elaborate on this?  Probably I have not used this feature
before.

> But I'd still advocate for passing not just the arguments but the
> function itself so that the same wrapper-hook can be used for
> several functions.  This is obviously a bit more difficult to do
> since the macro doesn't know from where it's being called.

I think it is a good idea.  How about the following definition?  The
argument to backtrace-frame depends on run-time environment.  1 is
good when it is byte-compiled.

(defvar inhibit-wrapper-hook nil
  "Non-nil inhibits invoking wrappers")

(defmacro with-wrapper-hook (wrapper-form &rest body)
  "Invoke wrappers in WRAPPERS-VAR if present, otherwise execute forms in BODY.
WRAPPER-FORM looks like (WRAPPERS-VAR ARG...), where ARG... is the
list of arguments passed to each wrapper in list stored in
WRAPPERS-VAR.  Each wrapper receives a symbol of the original function
as the first argument followed by ARG...  All wrappers must call the
original function from within itself.  While this macro is calling
each wrapper, WRAPPERS-VAR is bound to the cdr of the list, so that
recursive invocations of `with-wrappers' on the same variable will
result in each wrapper in the list being called.  Use `add-hook' and
`remove-hook' for manipuation of WRAPPERS-VAR.  When
`inhibit-wrapper-hook' is non-nil wrapper invokation is inhibited.

An example usage of this is:

  (defvar kill-region-wrapper-hook nil)

  (defun kill-region (beg end)
    (with-wrapper-hook (kill-region-wrapper-hook beg end)
      ...ordinary kill-region stuff...))"

  (let ((wrapper-var (car wrapper-form))
        (wrapper (make-symbol "wrapper")))
    `(if (and (not inhibit-wrapper-hook) ,wrapper-var)
         (let ((,wrapper (car ,wrapper-var))
               (,wrapper-var (cdr ,wrapper-var)))
           (funcall ,wrapper (nth 1 (backtrace-frame 1)) ,@(cdr wrapper-form)))
       ,@body)))

-Tak



reply via email to

[Prev in Thread] Current Thread [Next in Thread]