emacs-devel
[Top][All Lists]
Advanced

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

Re: table.el and GNU Emacs integration?


From: Tak Ota
Subject: Re: table.el and GNU Emacs integration?
Date: Sun, 27 Jan 2002 20:48:56 -0800 (PST)

Sat, 26 Jan 2002 18:28:21 -0700 (MST): Richard Stallman <address@hidden> wrote:

> The wrappers would have a major advantage compared with advice: it
> would be visible in the original function definition that it uses
> wrappers.
> 
> The policy of avoiding use of advice in standard Emacs packages is not
> a matter of esthetics.  It exists for important practical reasons.
> We should fix this not to use advice, before installing it.

Following is the final wrapper implementation we discussed sometime
ago.  After placing this in `subr.el' I started adding a wrapper to
each function that is currently advised in table.el.  There is one
problem.  I don't know how to implement the same wrapper effect in
"interactive compiled Lisp functions", for example `beginning-of-line'
defined in cmds.c in "C".  Would someone help me accomplishing this?

-Tak

(defmacro with-wrapper-hook (wrapper-form &rest body)
  "Invoke wrappers in WRAPPER-HOOK if present, otherwise execute forms in BODY.
WRAPPER-FORM looks like (WRAPPER-HOOK ARGS...), where ARGS is a list
of arguments passed to each wrapper in WRAPPER-HOOK.  Normal
convention is to place the original function which is being wrapped as
the first item in ARGS.  It is then called from the wrapper function.
While this macro is calling each wrapper, WRAPPER-HOOK is bound to the
cdr of the list, so that recursive invocations of `with-wrapper-hook'
on the same variable will result in each wrapper in the list being
called.  Use `add-hook' and `remove-hook' for manipuation of
WRAPPER-HOOK.

An example usage of this is:

  (defvar kill-region-wrapper-hook nil)

  (defun kill-region (beg end)
    (interactive \"r\")
    (with-wrapper-hook (kill-region-wrapper-hook 'kill-region beg end)
      ...ordinary kill-region stuff...))

  (defun my-wrapper (func beg end)
    (cond
     ((eq func 'kill-region)
      (let ((offset 5))
        (funcall func (+ beg offset) (+ end offset))))
     (t (funcall func beg end))))

  (add-hook 'kill-region-wrapper-hook 'my-wrapper)"

  (let ((wrapper-hook (car wrapper-form)))
    `(if ,wrapper-hook
         (let ((,wrapper-hook ,wrapper-hook))
           ;; Local/global special handling.
           (when (and (local-variable-p ',wrapper-hook)
                      (eq t (car ,wrapper-hook)))
             (setq ,wrapper-hook
                   (append (default-value ',wrapper-hook)
                           (cdr ,wrapper-hook))))
           ;; Call the first wrapper, with function and args.
           (if ,wrapper-hook
               (funcall (pop ,wrapper-hook) ,@(cdr wrapper-form))))
       ,@body)))



reply via email to

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