ciaran@hrc63.co.uk (Ciaran Byrne) (09/15/87)
Here is something to help you go on living when you discover that the author of your favorite function arrogantly thought that his code did everything anyone could possible want, so didn't provide a user hook for you to prove him/her wrong. The first command, add-hook, sticks any s-exp onto the end of the target function definition, the second, make-hook-var, uses add-hook to invoke run-hooks on a variable of your choice. I personally prefer using just the former for simple extras, since you don't need to mess round with function or lambda definitions to provide arguments. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; module: hook.el ;;;; version: 1.3 ;;;; author: Ciaran A Byrne ;;;; date: 20:Aug:87 ;;;; ;;;;;;;;;;;;;;;;;;;; hook insertion fns;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; macros: ;;;; some c[ad]+r fns ;;;; ;;;; commands: ;;;; add-hook - appends s-exp to function ;;;; make-hook-var - adds hook variable to a function ;;;; (defmacro caar (x) (list 'car (list 'car x))) (defmacro cadr (x) (list 'car (list 'cdr x))) (defmacro caadr (x) (list 'car (list 'car (list 'cdr x)))) (defmacro caddr (x) (list 'car (list 'cdr (list 'cdr x)))) (defmacro cadar (x) (list 'car (list 'cdr (list 'car x)))) (defmacro cdar (x) (list 'cdr (list 'car x))) (defmacro cddr (l) "" (list 'cdr (list 'cdr l))) (defmacro cdadr (x) (list 'cdr (list 'car (list 'cdr x)))) (defun add-hook (target-function extrafn) "Redefines FUNCTION so that SEXP is evaluated (apparently!) after the function has completed. e.g. (add-hook 'next-line '(what-line)) The original return value is preserved. Does not work with subr's. " ;Even if it did attempt to put a wrapper around a subr, ;it would be only partially effective, ;since subrs get called from other 'C'-coded fns. (interactive "aTarget function: xs-exp: ") ; OLD FORM ==> NEW FORM ; ; (defun foo (args) "bar" (defun foo (args) "bar" ; (interactive "s") (interactive "s") ; (s1) (prog1 ; (s2)) (progn ; (s1) ; (s2)) ; old result ; extrafn) ; new action ; (if (subrp (symbol-function target-function)) (message "No can do; %s is a subr" target-function) (let* ( (fval (symbol-function target-function)) (args (cadr fval)) (body (cddr fval)) (doc (car body)) (newfn (list 'lambda args)) ) (if (or (numberp doc) (stringp doc)) ; move body past doc (setq newfn (append newfn (list doc)) body (cdr body))) (if (eq 'interactive (caar body)) ; move body past (interactive ..) (setq newfn (append newfn (list (car body))) body (cdr body))) (fset target-function (append newfn (list (list 'prog1 (append '(progn) body) extrafn)) ) ) ) ; let ) ) (defun make-hook-var (hook-name target-function) "Causes the functions (if any) in VARIABLE to be run at the completion of FUNCTION. e.g. (make-hook-var compilation-sentinel-hook-var compilation-sentinel) ; adds hook var to compilation-sentinel ; eg: (setq compilation-sentinel-hook-var '(next-error)) use this instead of add-hook (qv) when you need to be able to change the hook functions without reloading. " (interactive "SNew hook var name : aFunction : ") (add-hook target-function (list 'run-hooks (list 'quote hook-name)))) (provide 'hook) ; ; ; comments/suggestions to ...!seismo!mcvax!ukc!gec-rl-hrc!ciaran ; ; When you said ``HEAVILY FORESTED'' it reminded me of an overdue ; CLEANING BILL.. Don't you SEE? O'Grogan SWALLOWED a VALUABLE ; COIN COLLECTION and HAD to murder the ONLY MAN who KNEW!!
quiroz@cs.rochester.edu (Cesar Quiroz) (09/19/87)
Expires: Sender: Followup-To: In a recent article, <280@hrc63.co.uk>, Ciaran Byrne contributes some functions to add hooks to code that originally didn't have them. That posting contained some definitions of the classic c[ad]+r functions, only as macros. I want to make a plea so other Emacs contributors consider for a moment that those macros make it hard to implement the standardly accepted meanings of those functions. (Byrne's code is by no means unique in this respect, by the way, just the most recent one to provide c[ad]+r as macros.) As to why it could be good to approximate standardly accepted Lisp behavior, you could see the notes that accompany cl.el in recent releases of GNU Emacs (I understand it was in 18.47, cannot confirm right now). As to why redefining them as macros causes trouble, imagine an implementation of defstruct that uses list structure to represent a struct and apply-ies c[ad]+r to instances in order to retrieve the slot values. (The one in cl.el uses vectors, so it doesn't have this problem, but others might easily occur.) It can be argued that the language should have included these functions as primitives. However, it is so easy to define them "correctly", that it should be done the right way. (Notice that in 18.47 and later, if cl.el is available, just (require 'cl) should be enough.) By the way, if someone wants to discuss language extensions for Emacs Lisp or implementation/design questions, that could be a nice thing to do in this group. Ideas anyone? -- Cesar Augusto Quiroz Gonzalez Department of Computer Science {allegra|seismo}!rochester!quiroz University of Rochester or Rochester, NY 14627 quiroz@cs.rochester.edu
quiroz@CS.ROCHESTER.EDU (09/19/87)
In a recent article, <280@hrc63.co.uk>, Ciaran Byrne contributes some functions to add hooks to code that originally didn't have them. That posting contained some definitions of the classic c[ad]+r functions, only as macros. I want to make a plea so other Emacs contributors consider for a moment that those macros make it hard to implement the standardly accepted meanings of those functions. (Byrne's code is by no means unique in this respect, by the way, just the most recent one to provide c[ad]+r as macros.) As to why it could be good to approximate standardly accepted Lisp behavior, you could see the notes that accompany cl.el in recent releases of GNU Emacs (I understand it was in 18.47, cannot confirm right now). As to why redefining them as macros causes trouble, imagine an implementation of defstruct that uses list structure to represent a struct and apply-ies c[ad]+r to instances in order to retrieve the slot values. (The one in cl.el uses vectors, so it doesn't have this problem, but others might easily occur.) It can be argued that the language should have included these functions as primitives. However, it is so easy to define them "correctly", that it should be done the right way. (Notice that in 18.47 and later, if cl.el is available, just (require 'cl) should be enough.) By the way, if someone wants to discuss language extensions for Emacs Lisp or implementation/design questions, that could be a nice thing to do in this group. Ideas anyone?
aglew@ccvaxa.UUCP (09/20/87)
I haven't used the hooks package for GNU EMACS yet, but may I comment that this is probably the way most hooks should be done? Ie. instead of every package using a slightly different name for its pre and post hooks, have no hooks at all, but let the user be able to add them dynamically, in a standard way.
quiroz@cs.rochester.edu (Cesar Quiroz) (09/21/87)
Expires: Sender: Followup-To: From article <28500017@ccvaxa> (aglew@ccvaxa.UUCP): : ... instead of every package using a slightly different name for :its pre and post hooks, have no hooks at all, but let the user be :able to add them dynamically, in a standard way. Looks like a useful idea. Other Lisps (Interlisp, for one) have well evolved `advising' facilities, that permit not only pre- and post- customized activity, but also around- activity. The user retains ultimate control and can do useful things not thought of by the original writer. For instance, take the old newline-and-reindent (or whatever it was called). It could have been just an around-advice of indent-line, that called the internal function twice. (Details might be a little out of synch with reality, please just get the big picture.) Byrne's code could be used as a starting point. (Getting the advice to the right place is a simple macro, controlling how different pieces of advice interact takes a bit more effort, storing and retrieving the advice might be harder... Hmm, going beyond the simple seems to require something like flavor composition.) -- Cesar Augusto Quiroz Gonzalez Department of Computer Science {allegra|seismo}!rochester!quiroz University of Rochester or Rochester, NY 14627 quiroz@cs.rochester.edu