[Top][All Lists]

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

Re: Customize and autoloaded libraries

From: Stefan Monnier
Subject: Re: Customize and autoloaded libraries
Date: Wed, 05 Dec 2001 10:17:57 -0500

> I think this makes it more important that it gets its own name, its
> semantics is clearly distinct from defcustom/defvar (even with your
> change).  It is not defconst either, it is its own thing.

I have no opinion on that.

> > More specifically, if you do
> >
> >     (defhook foo-hook '(bar))
> >     (remove-hook 'foo-hook 'bar)
> >     (defhook foo-hook '(bar))
> >
> > foo-hook will contain bar even though you clearly wanted to remove it.
> The intent is not clear to me, maybe we evaluate the defhook again
> to put it back.

Well, except for the case where you're hacking elisp, the only time
`defcustom' is executed is when you load a file, so the above
scenario corresponds to the case where the user reloads a file.
I don't know how important it is, now that I think about it.

> In any case, consider the more simple scenario:
>       (remove-hook 'foo-hook 'bar)
>       (defhook foo-hook '(bar))

That scenario has never worked anyway, so it's not particularly
important to make it work, I think.

> We could get this to work by modifying remove-hook to add the value to
> a property (e.g. hook-removed), and let customize-initialize-hook skip
> functions listed in that property.  add-hook should remove the
> function from that list, if present.  add-hook and remove-hook should
> continue to manipulate the actual value as they do now.

That's beginning to sound like my need for negative hook-values
in hooks (so as to be able to buffer-locally remove a function that's
on the global part of a hook).
In remove-hook, I need something like:

    ;; If the function is on the global hook, we need to shadow it locally
    (when (and local (member function (default-value hook))
               (not (member (cons 'not function) hook-value)))
      (push (cons 'not function) hook-value))

and in run-hooks, I add something like the patch below.


Index: eval.c
RCS file: /cvs/emacs/src/eval.c,v
retrieving revision 1.177
diff -u -r1.177 eval.c
--- eval.c      2001/12/05 01:39:21     1.177
+++ eval.c      2001/12/05 15:14:54
@@ -91,7 +91,7 @@
 Lisp_Object Qinhibit_quit, Vinhibit_quit, Vquit_flag;
 Lisp_Object Qmocklisp_arguments, Vmocklisp_arguments, Qmocklisp;
 Lisp_Object Qand_rest, Qand_optional;
-Lisp_Object Qdebug_on_error;
+Lisp_Object Qdebug_on_error, Qnot;
 /* This holds either the symbol `run-hooks' or nil.
    It is nil at an early stage of startup, and when Emacs
@@ -1289,6 +1295,8 @@
   if (interrupt_input_blocked != 0)
     abort ();
+  if (handling_signal)
+    abort ();
   c.tag = Qnil;
   c.val = Qnil;
@@ -2330,7 +2338,8 @@
   Lisp_Object sym, val, ret;
   Lisp_Object globals;
-  struct gcpro gcpro1, gcpro2, gcpro3;
+  Lisp_Object negatives = Qnil;
+  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
   /* If we are dying or still initializing,
      don't do anything--it would probably crash if we tried.  */
@@ -2351,7 +2360,7 @@
       globals = Qnil;
-      GCPRO3 (sym, val, globals);
+      GCPRO4 (sym, val, globals, negatives);
       for (;
           CONSP (val) && ((cond == to_completion)
@@ -2373,10 +2382,15 @@
                  args[0] = XCAR (globals);
                  /* In a global value, t should not occur.  If it does, we
                     must ignore it to avoid an endless loop.  */
-                 if (!EQ (args[0], Qt))
+                 if (!(EQ (args[0], Qt))
+                     && NILP (Fmember (args[0], negatives)))
                    ret = Ffuncall (nargs, args);
+         else if (CONSP (XCAR (val)) && (EQ (XCAR (XCAR (val)), Qnot)))
+           /* (not . FUNCTION) indicates that any subsequent FUNCTION
+              should be ignored.  */
+           negatives = Fcons (XCDR (XCAR (val)), negatives);
              args[0] = XCAR (val);
@@ -3267,6 +3281,9 @@
   Qdebug_on_error = intern ("debug-on-error");
   staticpro (&Qdebug_on_error);
+  Qnot = intern ("not");
+  staticpro (&Qnot);
   Qmacro = intern ("macro");
   staticpro (&Qmacro);

reply via email to

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