unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* eval-after-load as a macro (and eval-next-after-load)
@ 2003-04-04 20:30 Stefan Monnier
  2003-04-05  8:13 ` Richard Stallman
  2003-04-05 15:57 ` Kai Großjohann
  0 siblings, 2 replies; 28+ messages in thread
From: Stefan Monnier @ 2003-04-04 20:30 UTC (permalink / raw)



eval-after-load is currently a function and is thus pretty much always
used as follows:

	(eval-after-load "foobar"
          '(some code))

Now, how about turning it into a macro so we can just write:

	(eval-after-load "foobar"
          (some code))

Of course, such a change would introduce an incompatibility,
but it turns out that I think it's rather minor.  We can detect
the case where the argument is of the form (quote ...) and
treat it as it was before.  That takes care of 98% of the
case.   Of the remaining 2% of the cases, the current Emacs
sources have two cases:

- the macro would break things.  This only happens once in Emacs,
  more specifically in

	(defun eval-next-after-load (file)
	  "Read the following input sexp, and run it whenever FILE is loaded.
	This makes or adds to an entry on `after-load-alist'.
	FILE should be the name of a library, with no directory name."
	  (eval-after-load file (read)))

  that's the only place I could find where the expression passed
  to eval-after-load is not a constant.  Note that eval-next-after-load
  is never used in Emacs and that a google search only turned up
  XEmacs code that adds compatibility support for Emacs'
  eval-after-load and eval-next-after-load: no uses.

- The macro would fix things because the author didn't realize
  what was going on and wrote (eval-after-load "foo" (some code))
  without the quote.  Such a bug was recently fixed in crisp.el
  but there's still a few occurrences in viper.el (luckily those
  occurences don't matter because they only contain defadvice
  which works either way anyway).

So I suggest we make eval-next-after-load obsolete and turn
eval-after-load into a macro that emulates the function behavior
in the special case that the second arg is a quoted expression.

See sample patch below,


	Stefan



--- subr.el	3 Apr 2003 23:13:38 -0000	1.347
+++ subr.el	4 Apr 2003 20:21:49 -0000
@@ -951,7 +977,7 @@
 \f
 ;;;; Specifying things to do after certain files are loaded.
 
-(defun eval-after-load (file form)
+(defun eval-after-load-internal (file form)
   "Arrange that, if FILE is ever loaded, FORM will be run at that time.
 This makes or adds to an entry on `after-load-alist'.
 If FILE is already loaded, evaluate FORM right now.
@@ -977,11 +1003,29 @@
 	  (eval form))))
   form)
 
+(defmacro eval-after-load (file &rest code)
+  "Arrange that, if FILE is ever loaded, CODE will be run at that time.
+This makes or adds to an entry on `after-load-alist'.
+If FILE is already loaded, evaluate FORM right now.
+It does nothing if CODE is already on the list for FILE.
+FILE must match exactly.  Normally FILE is the name of a library,
+with no directory or extension specified, since that is how `load'
+is normally called.
+FILE can also be a feature (i.e. a symbol), in which case FORM is
+evaluated whenever that feature is `provide'd."
+  (declare (indent 1) (debug t))
+  (when (consp code)
+    (if (and (null (cdr code))
+	     (memq (car-safe (car code)) '(quote \`)))
+	`(eval-after-load-internal ,file ,(car code))
+      `(eval-after-load-internal ,file '(progn ,@code)))))
+
 (defun eval-next-after-load (file)
   "Read the following input sexp, and run it whenever FILE is loaded.
 This makes or adds to an entry on `after-load-alist'.
 FILE should be the name of a library, with no directory name."
-  (eval-after-load file (read)))
+  (eval `(eval-after-load file ,(read))))
+(make-obsolete 'eval-next-after-load 'eval-after-load "21.4")
 \f
 ;;; make-network-process wrappers

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-04 20:30 eval-after-load as a macro (and eval-next-after-load) Stefan Monnier
@ 2003-04-05  8:13 ` Richard Stallman
  2003-04-06 21:05   ` Stefan Monnier
  2003-04-05 15:57 ` Kai Großjohann
  1 sibling, 1 reply; 28+ messages in thread
From: Richard Stallman @ 2003-04-05  8:13 UTC (permalink / raw)
  Cc: emacs-devel

It seems ok to me.

This is an issue on which coordinating with XEmacs developers qwould
be useful.  Would you like to do that?

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-04 20:30 eval-after-load as a macro (and eval-next-after-load) Stefan Monnier
  2003-04-05  8:13 ` Richard Stallman
@ 2003-04-05 15:57 ` Kai Großjohann
  1 sibling, 0 replies; 28+ messages in thread
From: Kai Großjohann @ 2003-04-05 15:57 UTC (permalink / raw)


"Stefan Monnier" <monnier+gnu/emacs@rum.cs.yale.edu> writes:

> Of course, such a change would introduce an incompatibility,
> but it turns out that I think it's rather minor.  We can detect
> the case where the argument is of the form (quote ...) and
> treat it as it was before.  That takes care of 98% of the
> case.

Maybe the backward compatibility behavior should be documented;
otherwise people reading the `wrong' usage might get confused.
-- 
A preposition is not a good thing to end a sentence with.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-05  8:13 ` Richard Stallman
@ 2003-04-06 21:05   ` Stefan Monnier
  2003-04-07  9:25     ` Kai Großjohann
  2003-04-07 17:04     ` Juanma Barranquero
  0 siblings, 2 replies; 28+ messages in thread
From: Stefan Monnier @ 2003-04-06 21:05 UTC (permalink / raw)
  Cc: Stefan Monnier

> It seems ok to me.

Actually, my proposal is completely unworkable because it breaks execution
of old .elc files where the byte-code needs eval-after-load to be
a function :-(


	Stefan

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-06 21:05   ` Stefan Monnier
@ 2003-04-07  9:25     ` Kai Großjohann
  2003-04-07  9:33       ` Miles Bader
  2003-04-07 12:50       ` Luc Teirlinck
  2003-04-07 17:04     ` Juanma Barranquero
  1 sibling, 2 replies; 28+ messages in thread
From: Kai Großjohann @ 2003-04-07  9:25 UTC (permalink / raw)


"Stefan Monnier" <monnier+gnu/emacs@rum.cs.yale.edu> writes:

>> It seems ok to me.
>
> Actually, my proposal is completely unworkable because it breaks execution
> of old .elc files where the byte-code needs eval-after-load to be
> a function :-(

So what's left is a good name for the new macro.  Then the docstring
for eval-after-load could point to the new macro, and old code
wouldn't change behavior at all :-)
-- 
A preposition is not a good thing to end a sentence with.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-07  9:25     ` Kai Großjohann
@ 2003-04-07  9:33       ` Miles Bader
  2003-04-07 12:50       ` Luc Teirlinck
  1 sibling, 0 replies; 28+ messages in thread
From: Miles Bader @ 2003-04-07  9:33 UTC (permalink / raw)


kai.grossjohann@gmx.net (Kai Großjohann) writes:
> So what's left is a good name for the new macro.  Then the docstring
> for eval-after-load could point to the new macro, and old code
> wouldn't change behavior at all :-)

`do-after-load' seems consistent (in the spirit of dotimes and dolist).

-miles
-- 
We live, as we dream -- alone....

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-07  9:25     ` Kai Großjohann
  2003-04-07  9:33       ` Miles Bader
@ 2003-04-07 12:50       ` Luc Teirlinck
  2003-04-07 13:36         ` Kai Großjohann
  1 sibling, 1 reply; 28+ messages in thread
From: Luc Teirlinck @ 2003-04-07 12:50 UTC (permalink / raw)
  Cc: emacs-devel

Kai Grossjohann wrote:

   So what's left is a good name for the new macro.  Then the docstring
   for eval-after-load could point to the new macro, and old code
   wouldn't change behavior at all :-)

I believe that, in that case, the quote below from the Elisp manual
must be reworded too.  If that quote is accurate, we are trying very
hard to make writing badly designed code more convenient, which does
not seem to be a very meaningful activity.  Actually, if the quote
would be accurate, then it would be very bad that there is that much
old code that uses the function.  The quote below clearly says that it
is *not* OK to use this function outside of sloppy personal
customizations.  (Which might only mean that there is something wrong
with the quote itself.)

>From C-h i g (elisp)Hooks for Loading:
(talking about eval-after-load)

   In general, well-designed Lisp programs should not use this feature.
The clean and modular ways to interact with a Lisp library are (1)
examine and set the library's variables (those which are meant for
outside use), and (2) call the library's functions.  If you wish to do
(1), you can do it immediately--there is no need to wait for when the
library is loaded.  To do (2), you must load the library (preferably
with `require').

   But it is OK to use `eval-after-load' in your personal
customizations if you don't feel they must meet the design standards for
programs meant for wider use.

Sincerely,

Luc.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-07 12:50       ` Luc Teirlinck
@ 2003-04-07 13:36         ` Kai Großjohann
  2003-04-07 19:05           ` Luc Teirlinck
                             ` (2 more replies)
  0 siblings, 3 replies; 28+ messages in thread
From: Kai Großjohann @ 2003-04-07 13:36 UTC (permalink / raw)
  Cc: emacs-devel

Luc Teirlinck <teirllm@dms.auburn.edu> writes:

> I believe that, in that case, the quote below from the Elisp manual
> must be reworded too.

Maybe some wording could be added to talk about efficiency.  For
example, crisp.el adds two entries to cua-movement-commands.  It does
not make sense for crisp to require cua, as many crisp users probably
don't want to use cua.  It also doesn't work to just frob
cua-movement-commands, since adding to a list can only be done after
the defvar.
-- 
A preposition is not a good thing to end a sentence with.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-06 21:05   ` Stefan Monnier
  2003-04-07  9:25     ` Kai Großjohann
@ 2003-04-07 17:04     ` Juanma Barranquero
  2003-04-07 17:56       ` Stefan Monnier
  2003-04-08  2:31       ` Richard Stallman
  1 sibling, 2 replies; 28+ messages in thread
From: Juanma Barranquero @ 2003-04-07 17:04 UTC (permalink / raw)


On Sun, 06 Apr 2003 17:05:05 -0400, "Stefan Monnier" <monnier+gnu/emacs@rum.cs.yale.edu> wrote:

> Actually, my proposal is completely unworkable because it breaks execution
> of old .elc files where the byte-code needs eval-after-load to be
> a function :-(

Speaking of breaking execution and incompatibilities, the use of the new
`run-mode-hooks' in `define-derived-mode' has caused a small
backward-incompatibility: .elc files using `define-derived-mode' and
compiled with 21.3.50 cannot be loaded on 21.[123] releases. Source
modules can, of course.

                                                           /L/e/k/t/u

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-07 17:04     ` Juanma Barranquero
@ 2003-04-07 17:56       ` Stefan Monnier
  2003-04-07 19:50         ` Juanma Barranquero
  2003-04-08  2:31       ` Richard Stallman
  1 sibling, 1 reply; 28+ messages in thread
From: Stefan Monnier @ 2003-04-07 17:56 UTC (permalink / raw)
  Cc: emacs-devel

> Speaking of breaking execution and incompatibilities, the use of the new
> `run-mode-hooks' in `define-derived-mode' has caused a small
> backward-incompatibility: .elc files using `define-derived-mode' and
> compiled with 21.3.50 cannot be loaded on 21.[123] releases. Source
> modules can, of course.

That's forward-incompatibility.


	Stefan

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-07 13:36         ` Kai Großjohann
@ 2003-04-07 19:05           ` Luc Teirlinck
  2003-04-07 19:43             ` Kai Großjohann
  2003-04-07 19:35           ` Luc Teirlinck
  2003-04-08  2:31           ` Richard Stallman
  2 siblings, 1 reply; 28+ messages in thread
From: Luc Teirlinck @ 2003-04-07 19:05 UTC (permalink / raw)
  Cc: emacs-devel

Kai Grossjohann wrote:

   It also doesn't work to just frob cua-movement-commands, since
   adding to a list can only be done after the defvar.

So you defvar it to the same value cua would defvar it to and then add
the two entries.  What is the need for eval-after-load in this situaton?

Sincerely,

Luc.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-07 13:36         ` Kai Großjohann
  2003-04-07 19:05           ` Luc Teirlinck
@ 2003-04-07 19:35           ` Luc Teirlinck
  2003-04-08  2:31           ` Richard Stallman
  2 siblings, 0 replies; 28+ messages in thread
From: Luc Teirlinck @ 2003-04-07 19:35 UTC (permalink / raw)
  Cc: emacs-devel

>From my previous message:

    So you defvar it to the same value cua would defvar it to and then
    add the two entries.  What is the need for eval-after-load in this
    situaton?

I guess that could confuse C-h v and thus would be bad.  So you are
probably right.

Sincerely,

Luc.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-07 19:05           ` Luc Teirlinck
@ 2003-04-07 19:43             ` Kai Großjohann
  2003-04-07 20:04               ` Luc Teirlinck
  0 siblings, 1 reply; 28+ messages in thread
From: Kai Großjohann @ 2003-04-07 19:43 UTC (permalink / raw)
  Cc: emacs-devel

Luc Teirlinck <teirllm@dms.auburn.edu> writes:

> Kai Grossjohann wrote:
>
>    It also doesn't work to just frob cua-movement-commands, since
>    adding to a list can only be done after the defvar.
>
> So you defvar it to the same value cua would defvar it to and then add
> the two entries.  What is the need for eval-after-load in this situaton?

(1) The user might have modified the default value before loading
    crisp.

(2) With this strategy, the default value for many variables would be
    copied all around the place.  A nightmare if you ever want to
    change the default value.

Or am I misunderstanding something?
-- 
A preposition is not a good thing to end a sentence with.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-07 17:56       ` Stefan Monnier
@ 2003-04-07 19:50         ` Juanma Barranquero
  0 siblings, 0 replies; 28+ messages in thread
From: Juanma Barranquero @ 2003-04-07 19:50 UTC (permalink / raw)
  Cc: emacs-devel

On Mon, 07 Apr 2003 13:56:07 -0400, "Stefan Monnier" <monnier+gnu/emacs@rum.cs.yale.edu> wrote:

> That's forward-incompatibility.

Yeah, *that*! :-)


                                                           /L/e/k/t/u

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-07 19:43             ` Kai Großjohann
@ 2003-04-07 20:04               ` Luc Teirlinck
  2003-04-07 20:19                 ` Kai Großjohann
  0 siblings, 1 reply; 28+ messages in thread
From: Luc Teirlinck @ 2003-04-07 20:04 UTC (permalink / raw)
  Cc: emacs-devel

   (1) The user might have modified the default value before loading
       crisp.

You mean by making personal changes to cua?  Yes, that would be a
problem.

   (2) With this strategy, the default value for many variables would be
       copied all around the place.  A nightmare if you ever want to
       change the default value.

Yes that would be a problem too.

   Or am I misunderstanding something?

No, that was just a very bad idea of mine.  I just responded too
quickly, I guess.

Sincerely,

Luc.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-07 20:04               ` Luc Teirlinck
@ 2003-04-07 20:19                 ` Kai Großjohann
  0 siblings, 0 replies; 28+ messages in thread
From: Kai Großjohann @ 2003-04-07 20:19 UTC (permalink / raw)
  Cc: emacs-devel

Luc Teirlinck <teirllm@dms.auburn.edu> writes:

>    (1) The user might have modified the default value before loading
>        crisp.
>
> You mean by making personal changes to cua?  Yes, that would be a
> problem.

I meant that the user might have done this:

(setq cua-movement-commands ...)
(require 'crisp)

Hm.  Oh!  Your suggestion was to use defvar in crisp.  That wouldn't
overwrite the value.

D'oh.
-- 
A preposition is not a good thing to end a sentence with.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-07 17:04     ` Juanma Barranquero
  2003-04-07 17:56       ` Stefan Monnier
@ 2003-04-08  2:31       ` Richard Stallman
  2003-04-13 18:55         ` Juanma Barranquero
  1 sibling, 1 reply; 28+ messages in thread
From: Richard Stallman @ 2003-04-08  2:31 UTC (permalink / raw)
  Cc: emacs-devel

    Speaking of breaking execution and incompatibilities, the use of the new
    `run-mode-hooks' in `define-derived-mode' has caused a small
    backward-incompatibility: .elc files using `define-derived-mode' and
    compiled with 21.3.50 cannot be loaded on 21.[123] releases. 

Does this patch solve that problem?

*** derived.el.~1.36.~	Fri Sep 13 15:36:25 2002
--- derived.el	Mon Apr  7 17:41:13 2003
***************
*** 226,232 ****
  	  ,@body
  	  )
  					; Run the hooks, if any.
! 	 (run-mode-hooks ',hook)))))
  
  ;; PUBLIC: find the ultimate class of a derived mode.
  
--- 226,234 ----
  	  ,@body
  	  )
  					; Run the hooks, if any.
! 	 (if (fboundp 'run-mode-hooks)
! 	     (run-mode-hooks ',hook)
! 	   (run-hooks ',hook))))))
  
  ;; PUBLIC: find the ultimate class of a derived mode.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-07 13:36         ` Kai Großjohann
  2003-04-07 19:05           ` Luc Teirlinck
  2003-04-07 19:35           ` Luc Teirlinck
@ 2003-04-08  2:31           ` Richard Stallman
  2003-04-08 10:46             ` Kim F. Storm
  2 siblings, 1 reply; 28+ messages in thread
From: Richard Stallman @ 2003-04-08  2:31 UTC (permalink / raw)
  Cc: emacs-devel

    Maybe some wording could be added to talk about efficiency.  For
    example, crisp.el adds two entries to cua-movement-commands.  It does
    not make sense for crisp to require cua, as many crisp users probably
    don't want to use cua.  It also doesn't work to just frob
    cua-movement-commands, since adding to a list can only be done after
    the defvar.

The usual way to handle this is with hooks.  Does cua mode have
a cua-mode-hook?

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-08 10:46             ` Kim F. Storm
@ 2003-04-08 10:21               ` Kai Großjohann
  2003-04-08 18:17               ` Stefan Monnier
  2003-04-09  1:59               ` Richard Stallman
  2 siblings, 0 replies; 28+ messages in thread
From: Kai Großjohann @ 2003-04-08 10:21 UTC (permalink / raw)


storm@cua.dk (Kim F. Storm) writes:

> However, such hooks (e.g. cua-mode-hook) are normally for users to
> set, so if a package like crisp modifies it (too), Customize will
> report "this variable is set outside custom" -- and saving it will
> cause the crisp addition to be saved as well (potentially adding to
> the hook a reference to a function which isn't defined on next emacs
> startup).
>
> Doing this via a hook would require having two hooks -- one for emacs
> internal use and another for the user...  

That's right, but it's a general problem.  So I think it makes no
sense to try to solve it in this specific case only.

run-hooks could be extended to run two hooks, a "public" hook and a
"private" hook.  The arg would be the name of the public hook, and the
name of the corresponding private hook could be derived from the name
of the public hook.  (Running the private hook would be skipped if it
doesn't exist.)  What do people think?

Does one normally use defvar or defcustom to define the hook
variables?  If so, it might be useful to create a define-hook macro
that creates both variables.
-- 
A preposition is not a good thing to end a sentence with.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-08  2:31           ` Richard Stallman
@ 2003-04-08 10:46             ` Kim F. Storm
  2003-04-08 10:21               ` Kai Großjohann
                                 ` (2 more replies)
  0 siblings, 3 replies; 28+ messages in thread
From: Kim F. Storm @ 2003-04-08 10:46 UTC (permalink / raw)
  Cc: emacs-devel

Richard Stallman <rms@gnu.org> writes:

>     Maybe some wording could be added to talk about efficiency.  For
>     example, crisp.el adds two entries to cua-movement-commands.  It does
>     not make sense for crisp to require cua, as many crisp users probably
>     don't want to use cua.  It also doesn't work to just frob
>     cua-movement-commands, since adding to a list can only be done after
>     the defvar.
> 
> The usual way to handle this is with hooks.  Does cua mode have
> a cua-mode-hook?

It does not, but I can add one.

However, such hooks (e.g. cua-mode-hook) are normally for users to
set, so if a package like crisp modifies it (too), Customize will
report "this variable is set outside custom" -- and saving it will
cause the crisp addition to be saved as well (potentially adding to
the hook a reference to a function which isn't defined on next emacs
startup).

Doing this via a hook would require having two hooks -- one for emacs
internal use and another for the user...  

IMO, that is an unnecessary complication, when eval-after-load does
the job perfectly.  

In fact, using a hook is more complex, as we need to handle two cases,
depending on whether cua is enabled or not-enabled (which requires
testing cua internal variables), and then in the first case, the hook
action must be performed by crisp directly, and in the second case a
hook must be setup (and be written to de-install itself when it has
been run).


BTW, in the cua/crisp case, crisp actually add the entries to the
cua--standard-movement-commands list -- which is for emacs internal
use (there is a cua-movement-commands list for the user to modify).

The separation into cua--standard-movement-commands and
cua-movement-commands is precisely to avoid mixing emacs' internal
setup and the user's individual customizations.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-08 10:46             ` Kim F. Storm
  2003-04-08 10:21               ` Kai Großjohann
@ 2003-04-08 18:17               ` Stefan Monnier
  2003-04-09 23:41                 ` Kim F. Storm
  2003-04-09  1:59               ` Richard Stallman
  2 siblings, 1 reply; 28+ messages in thread
From: Stefan Monnier @ 2003-04-08 18:17 UTC (permalink / raw)
  Cc: emacs-devel

> > The usual way to handle this is with hooks.  Does cua mode have
> > a cua-mode-hook?
> 
> It does not, but I can add one.

How about defining it using define-minor-mode ?
Something like the untested patch below.


	Stefan


Index: cua-base.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/emulation/cua-base.el,v
retrieving revision 1.23
diff -u -u -b -r1.23 cua-base.el
--- cua-base.el	31 Mar 2003 21:48:39 -0000	1.23
+++ cua-base.el	8 Apr 2003 18:16:19 -0000
@@ -260,29 +260,6 @@
   :link '(emacs-commentary-link :tag "Commentary" "cua-base.el")
   :link '(emacs-library-link :tag "Lisp File" "cua-base.el"))
 
-;;;###autoload
-(defcustom cua-mode nil
-  "Non-nil means that CUA emulation mode is enabled.
-In CUA mode, shifted movement keys highlight and extend the region.
-When a region is highlighted, the binding of the C-x and C-c keys are
-temporarily changed to work as Motif, MAC or MS-Windows cut and paste.
-Also, insertion commands first delete the region and then insert.
-This mode enables Transient Mark mode and it provides a superset of the
-PC Selection Mode and Delete Selection Modes.
-
-Setting this variable directly does not take effect;
-use either \\[customize] or the function `cua-mode'."
-  :set (lambda (symbol value)
-	 (cua-mode (or value 0)))
-  :initialize 'custom-initialize-default
-  :set-after '(cua-enable-modeline-indications cua-use-hyper-key)
-  :require 'cua-base
-  :link '(emacs-commentary-link "cua-base.el")
-  :version "21.4"
-  :type 'boolean
-  :group 'cua)
-
-
 (defcustom cua-enable-cua-keys t
   "*Enable using C-z, C-x, C-c, and C-v for undo, cut, copy, and paste.
 If the value is t, these mappings are always enabled.  If the value is
@@ -1181,19 +1158,17 @@
 (defvar cua--saved-state nil)
 
 ;;;###autoload
-(defun cua-mode (&optional arg)
+(define-minor-mode cua-mode
   "Toggle CUA key-binding mode.
 When enabled, using shifted movement keys will activate the region (and
 highlight the region using `transient-mark-mode'), and typed text replaces
 the active selection.  C-z, C-x, C-c, and C-v will undo, cut, copy, and
 paste (in addition to the normal emacs bindings)."
-  (interactive "P")
-  (setq cua-mode
-	(cond
-	 ((null arg) (not cua-mode))
-	 ((symbolp arg) t)
-	 (t (> (prefix-numeric-value arg) 0))))
-
+  :global t
+  :set-after '(cua-enable-modeline-indications cua-use-hyper-key)
+  :require 'cua-base
+  :link '(emacs-commentary-link "cua-base.el")
+  :version "21.4"
   (setq mark-even-if-inactive t)
   (setq highlight-nonselected-windows nil)
   (make-variable-buffer-local 'cua--explicit-region-start)
@@ -1235,9 +1210,7 @@
     (setq transient-mark-mode (and cua-mode
 				   (if cua-highlight-region-shift-only
 				       (not cua--explicit-region-start)
-				     t)))
-    (if (interactive-p)
-	(message "CUA mode enabled")))
+				     t))))
    (cua--saved-state
     (setq transient-mark-mode (car cua--saved-state))
     (if (nth 1 cua--saved-state)
@@ -1250,11 +1223,7 @@
 		 (if (and (nth 1 cua--saved-state) (nth 2 cua--saved-state)) " and" "")
 		 (if (nth 2 cua--saved-state) " PC-Selection" "")
 		 (if (or (nth 1 cua--saved-state) (nth 2 cua--saved-state)) " enabled" "")))
-    (setq cua--saved-state nil))
-
-   (t
-    (if (interactive-p)
-	(message "CUA mode disabled")))))
+    (setq cua--saved-state nil))))
 
 (defun cua-debug ()
   "Toggle cua debugging."

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-08 10:46             ` Kim F. Storm
  2003-04-08 10:21               ` Kai Großjohann
  2003-04-08 18:17               ` Stefan Monnier
@ 2003-04-09  1:59               ` Richard Stallman
  2003-04-09  2:31                 ` Miles Bader
  2003-04-10  0:00                 ` Kim F. Storm
  2 siblings, 2 replies; 28+ messages in thread
From: Richard Stallman @ 2003-04-09  1:59 UTC (permalink / raw)
  Cc: emacs-devel

    However, such hooks (e.g. cua-mode-hook) are normally for users to
    set, so if a package like crisp modifies it (too), Customize will
    report "this variable is set outside custom"

It is normal for Lisp packages to modify hooks.  We mustn't base the
discussion on the assumption that this is somehow anomalous.

    IMO, that is an unnecessary complication, when eval-after-load does
    the job perfectly.  

It makes no sense to argue that people should avoid using hooks for
this sort of customization.  This is the reason for the hooks.


It could be useful to clean up the way Custom handles hooks.  For
instance, if Custom sees elements in the hook that it did not put
there, it could automatically divide the elements into two parts:
those specified thru Custom, and those specified outside Custom.
The user, in Custom, would edit only the former.  This way, one
hook variable would do both jobs, and we would not have to change
any packages.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-09  1:59               ` Richard Stallman
@ 2003-04-09  2:31                 ` Miles Bader
  2003-04-10  0:00                 ` Kim F. Storm
  1 sibling, 0 replies; 28+ messages in thread
From: Miles Bader @ 2003-04-09  2:31 UTC (permalink / raw)
  Cc: Kim F. Storm

Richard Stallman <rms@gnu.org> writes:
> It could be useful to clean up the way Custom handles hooks.  For
> instance, if Custom sees elements in the hook that it did not put
> there, it could automatically divide the elements into two parts:
> those specified thru Custom, and those specified outside Custom.
> The user, in Custom, would edit only the former.

This sounds good; but I think if it does this, it should also at least
display the `non-custom' hooks in some way, so that the user can see
the whole value.

-Miles
-- 
`To alcohol!  The cause of, and solution to,
 all of life's problems' --Homer J. Simpson

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-08 18:17               ` Stefan Monnier
@ 2003-04-09 23:41                 ` Kim F. Storm
  0 siblings, 0 replies; 28+ messages in thread
From: Kim F. Storm @ 2003-04-09 23:41 UTC (permalink / raw)
  Cc: emacs-devel

"Stefan Monnier" <monnier+gnu/emacs@rum.cs.yale.edu> writes:

> > > The usual way to handle this is with hooks.  Does cua mode have
> > > a cua-mode-hook?
> > 
> > It does not, but I can add one.
> 
> How about defining it using define-minor-mode ?
> Something like the untested patch below.

I have no principle objections doing that, but the message printed
when cua-mode is enabled or disabled is not a trivial Enabled/Disabled
message as normal minor modes have; the message explicitly mentions
interactions with delete-selection-mode and pc-selection-mode (when
applicable).  I don't know if define-minor-mode can handle that, but
your patch doesn't seem to address that specific issue...

-- 
Kim F. Storm <storm@cua.dk> http://www.cua.dk

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-09  1:59               ` Richard Stallman
  2003-04-09  2:31                 ` Miles Bader
@ 2003-04-10  0:00                 ` Kim F. Storm
  2003-04-10 22:47                   ` Richard Stallman
  1 sibling, 1 reply; 28+ messages in thread
From: Kim F. Storm @ 2003-04-10  0:00 UTC (permalink / raw)
  Cc: emacs-devel

Richard Stallman <rms@gnu.org> writes:

>     However, such hooks (e.g. cua-mode-hook) are normally for users to
>     set, so if a package like crisp modifies it (too), Customize will
>     report "this variable is set outside custom"
> 
> It is normal for Lisp packages to modify hooks.  We mustn't base the
> discussion on the assumption that this is somehow anomalous.

Perhaps not, but IMO there are two types of hooks -- those defined
with defcustom [supposing they are for users to change] and other
hooks [which are for Lisp code to change].  Mixing such hooks may lead
to undefined/undesireable behaviour.

> 
>     IMO, that is an unnecessary complication, when eval-after-load does
>     the job perfectly.  
> 
> It makes no sense to argue that people should avoid using hooks for
> this sort of customization.  This is the reason for the hooks.

So are you arguing that it is wrong to use defcustom to define hooks
(at least those which may be modified by Lisp packages)?

> It could be useful to clean up the way Custom handles hooks.  For
> instance, if Custom sees elements in the hook that it did not put
> there, it could automatically divide the elements into two parts:
> those specified thru Custom, and those specified outside Custom.
> The user, in Custom, would edit only the former.  This way, one
> hook variable would do both jobs, and we would not have to change
> any packages.

That's fine with me -- if someone can find a clean way to implement it.

How do you mark an element on a list as "set by Lisp" (or "set by
Custom")?  

What should happen if the user adds a hook that is already "set by
Lisp" via Custom?


BTW, does define-minor-mode create the xxx-mode-hook variable via
defvar (rather than defcustom)?

-- 
Kim F. Storm <storm@cua.dk> http://www.cua.dk

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-10  0:00                 ` Kim F. Storm
@ 2003-04-10 22:47                   ` Richard Stallman
  0 siblings, 0 replies; 28+ messages in thread
From: Richard Stallman @ 2003-04-10 22:47 UTC (permalink / raw)
  Cc: emacs-devel

    Perhaps not, but IMO there are two types of hooks -- those defined
    with defcustom [supposing they are for users to change] and other
    hooks [which are for Lisp code to change].

There is no such convention, and adopting it would be a big change.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-08  2:31       ` Richard Stallman
@ 2003-04-13 18:55         ` Juanma Barranquero
  2003-04-14  7:10           ` Juanma Barranquero
  0 siblings, 1 reply; 28+ messages in thread
From: Juanma Barranquero @ 2003-04-13 18:55 UTC (permalink / raw)


On Mon, 07 Apr 2003 22:31:03 -0400, Richard Stallman <rms@gnu.org> wrote:

> Does this patch solve that problem?

> ! 	 (run-mode-hooks ',hook)))))

> ! 	 (if (fboundp 'run-mode-hooks)
> ! 	     (run-mode-hooks ',hook)
> ! 	   (run-hooks ',hook))))))

With this patch, 21.3 does not fail when loading a HEAD-compiled mode
defined with `define-derived-mode'.

Still, it does not "work", so to speak.

As a simple example:

# .emacs contains:
(load "font-lock")
(global-font-lock-mode 1)
(autoload 'test-mode "test-mode")

# test-mode.el contains:
(define-derived-mode test-mode emacs-lisp-mode "Test Mode"
  "Test mode derived from emacs-lisp-mode.")

# test.el contains:
# -*- mode: test-mode -*-

Case 1:
 - compile test-mode.el with 21.3
 - start 21.3
 - load test.el

The comment in test.el is font-locked.

Case 2:
 - compile test-mode.el with HEAD
 - start 21.3
 - load test.el

The comment in test.el is not font-locked.

                                                           /L/e/k/t/u

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: eval-after-load as a macro (and eval-next-after-load)
  2003-04-13 18:55         ` Juanma Barranquero
@ 2003-04-14  7:10           ` Juanma Barranquero
  0 siblings, 0 replies; 28+ messages in thread
From: Juanma Barranquero @ 2003-04-14  7:10 UTC (permalink / raw)



On Sun, 13 Apr 2003 20:55:31 +0200
Juanma Barranquero <lektu@terra.es> wrote:

> # test.el contains:
> # -*- mode: test-mode -*-

Humm...

 # -*- mode: test -*-
 
I mean.


                                                                Juanma

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2003-04-14  7:10 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-04-04 20:30 eval-after-load as a macro (and eval-next-after-load) Stefan Monnier
2003-04-05  8:13 ` Richard Stallman
2003-04-06 21:05   ` Stefan Monnier
2003-04-07  9:25     ` Kai Großjohann
2003-04-07  9:33       ` Miles Bader
2003-04-07 12:50       ` Luc Teirlinck
2003-04-07 13:36         ` Kai Großjohann
2003-04-07 19:05           ` Luc Teirlinck
2003-04-07 19:43             ` Kai Großjohann
2003-04-07 20:04               ` Luc Teirlinck
2003-04-07 20:19                 ` Kai Großjohann
2003-04-07 19:35           ` Luc Teirlinck
2003-04-08  2:31           ` Richard Stallman
2003-04-08 10:46             ` Kim F. Storm
2003-04-08 10:21               ` Kai Großjohann
2003-04-08 18:17               ` Stefan Monnier
2003-04-09 23:41                 ` Kim F. Storm
2003-04-09  1:59               ` Richard Stallman
2003-04-09  2:31                 ` Miles Bader
2003-04-10  0:00                 ` Kim F. Storm
2003-04-10 22:47                   ` Richard Stallman
2003-04-07 17:04     ` Juanma Barranquero
2003-04-07 17:56       ` Stefan Monnier
2003-04-07 19:50         ` Juanma Barranquero
2003-04-08  2:31       ` Richard Stallman
2003-04-13 18:55         ` Juanma Barranquero
2003-04-14  7:10           ` Juanma Barranquero
2003-04-05 15:57 ` Kai Großjohann

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).