emacs-devel
[Top][All Lists]
Advanced

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

Re: Recent attempts at standardizing major mode definitions.


From: Stefan Monnier
Subject: Re: Recent attempts at standardizing major mode definitions.
Date: Mon, 02 Sep 2002 12:51:40 -0400

> To avoid confusion: I am not at all opposed to "using such a macro
> systematically", but I am very much opposed to using define-derived-mode
> in its present form.  One reason is that the present use of this macro
> has caused bugs in several modes.  (See my previous message.)  It is
> not the only reason.

I haven't seen any actual bug in your previous message apart from
the bogus way mail-mode was made to use the text-mode-abbrev-table.
Thanks for that report, by the way.

> I believe that any macro that aims to standardize major mode definitions 
> should under no condition prevent the writer of a major mode to do
> anything that is not only not "forbidden" by the guidelines in the
> Elisp manual, but that is even explicitly allowed by these guidelines,
> and is very often in the best interest of the user.  Neither should
> the macro make this unnecessarily difficult for him or her.

That's obvious.

> The ELisp manual clearly says that a major mode does not need to have
> its own syntax-table or abbrev-table, but may share one with related
> modes.  Especially in the case of abbrev-tables, it is in the user's
> interest to share local abbrev-tables as much as possible between
> closely related modes.  Yet, define-derived-mode makes it
> unnecessarily tricky to share abbrev tables or syntax tables without
> introducing the second type of bug I described in my previous message.

Syntax-tables *are* shared via inheritance, so I don't see what you
mean by "unnecessarily tricky".
As for abbrev-tables, they are suboptimally shared (via poor man's
inheritance) which is not that bad either.  But we could change the
default indeed.
I think it's crucially important that

        (define-derived-mode foo-mode bar-mode "Foo"
          "Doc"
          (modify-syntax-entry ?; "<"))

doesn't change bar-mode-syntax-table, so I'd be opposed to changing
the default for syntax-tables.

> The Elisp manual also says that hooks of related modes may be run just
> before the mode's own hook OR that they may be ran earlier.  It seems
> to me that define-derived-mode tries to enforce the first type of behavior.

It doesn't try to enforce it, it just tries to make it possible
because that's what generally desired.  Do you have a counter-example ?

> define-derived-mode is currently used for two barely compatible, in
> many respects diametrically opposite purposes:

Could you expand a little ?  In what way are they diametrically opposed ?

> A way to make a very specialized, but common, task easy for people to
> do, namely defining a barely different derived mode from a parent
> mode.  I believe define-derived-mode serves this purpose well, except
> for the fact that, as I pointed out in my previous message, it should
> make the derived mode use the parent's abbrev table instead of
> introducing bugs and confusion by trying to copy the parent's
> abbrev-table.

I don't care much for this use, so I kept it "as it was".
Direct sharing of abbrev-table could be done and might indeed be better,
although it would be an imcompatible change.  I'll let others decide.

> The second, more recent purpose is as a "standard" way to define any
> major mode whatsoever.  This is a completely different task.

In what way is it completely different ?

> I believe that one should revert to the 21.2.90 behavior and no longer
> make the code expand into something different when the parent mode is
> fundamental-mode.

Any reason for it ?  I hope you realize that `fundamental-mode'
is an alias for `kill-all-local-variables'.  The special-treatment
of fundamental-mode is an *optimization* (i.e. should not make
*any* difference in terms of behavior).

> Some modes could truly differ so little from fundamental-mode that
> they are "truly" derived modes of fundamental mode.

Sure.  And the current macro will deal with it just fine.
Or do you have evidence to the contrary ?

> I believe the current value of "nil" for PARENT should be
> eliminated and replaced by a separate macro `define-major-mode', which
> would be a true analogue of `define-minor-mode'.  This would then
> take over as the "standard" way to define a major mode.

And what would be the benefit ?
I know Richard hates `define-derived-mode' and wants a `define-major-mode'
instead.  My point is just that the two can be merged and that we can
define `define-major-mode as an alias for `define-derived-mode'
or if you really dislike the "nil" argument, you can just do

  (defmacro define-major-mode (mode name &optional docstring &rest body)
    `(define-derived-mode ,mode nil ,name ,docstring ,@body)

> I propose to define a macro that would be called like this:
> 
> (define-major-mode mymode name syntax-table abbrev-table mode-class
> docstring body)

I believe it's good to follow the convention that the syntax-table for
mode foo is found in foo-mode-syntax-table, so I think it's a good idea
for define-major-mode to use foo-mode-syntax-table as the syntax-table
rather than to take it as an argument.

> The Elisp manual says:
> 
> Major modes usually should have their own keymap...
> 
> There is a "usually" in this sentence.  So maybe define-major-mode
> should also take a keymap argument.  This is a lot less clear than it
> is for syntax-tables and abbrev-tables however.

  (defvar foo-mode-map bar-mode-map)
  (define-derived-mode foo-mode bar-mode "Foo" "Doc")

will make foo-mode use bar-mode-map directly, so define-derived-mode
does not force you to use your own keymap.  Same thing holds for syntax-table
and abbrev-table of course.  And for keymap and syntax-tables this is
rarely (if ever) needed since inheritance provides pretty much the same
sharing advantages while at the same time still allowing mode-specific
changes.


        Stefan





reply via email to

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