all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Extending define-derived-mode
@ 2023-05-30  5:16 Yuan Fu
  2023-05-30  5:51 ` Theodor Thornhill
                   ` (3 more replies)
  0 siblings, 4 replies; 24+ messages in thread
From: Yuan Fu @ 2023-05-30  5:16 UTC (permalink / raw)
  To: emacs-devel; +Cc: Mickey Petersen, Theodor Thornhill, Dmitry Gutov

When we were adding tree-sitter modes a couple of month ago, it was
clear that the current major mode model needs some upgrade, I’d like
to discuss the things we need and how can we address them.

Features we want:

1. Fallback modes: user enables xxx-ts-mode, but there’s no
   tree-sitter grammar for xxx, so Emacs falls back to xxx-mode
   instead. This feature is also desirable for some non-tree-sitter
   modes, like TeX modes. Ideally the dispatch should happen before
   major mode does anything.

2. Inheritance:

2.1 For xxx-mode and xxx-ts-mode, there should be shared hook. More
    generally, we want to be able to have a shared hook for similar
    modes (same language, similar language, etc).

2.2 For xxx-mode and xxx-ts-mode, they should be able to share some
    setup, and diverge on some other.

2.3 Right now we have a little inconsistency regarding hook
    inheritance. js-json-mode inherits from js-mode, json-ts-mode
    inherits from js-ts-mode. So there isn’t a shared hook that runs
    in both js-json-mode and json-ts-mode.

    More generally, if there is a language X and a derived language Y,
    and we have x-mode, x-ts-mode, y-mode, y-ts-mode, how should
    inheritance of code and hooks works among them? y-mode probably
    wants to inherit from x-mode, and y-ts-mode probably wants to
    inherit hook (but not necessarily code [1]) from x-ts-mode.

[1] If Y is different enough from X such that it has its own
tree-sitter grammar, y-ts-mode cannot inherit x-ts-mode’s code because
they target different grammar.

3. Unrelated to tree-sitter, here’s something I personally want:
   it would be nice if every major mode can
   have a hook that’s not run by its derived modes. Use case:
   sage-mode inherits python-mode. I have eglot-ensure in
   python-mode-hook but don’t want it when using sage-mode. Right now
   I have to wrap eglot-ensure with a lambda function so that it only
   runs when major-mode = python-mode.


Implementation wise, here are my thoughts regarding each feature:

1. Shouldn’t be hard to add some facility to define-derived-mode that
   runs before everything and dispatches to different major modes.
   Maybe define-derive-mode can have a :dispatch keyword which takes a
   arbitrary function; and if the function returns nil, rest of the
   major mode setup are skipped.

2. For those who don’t know, right now we define a xxx-base-mode,
   which is then inherited by xxx-mode and xxx-ts-mode. My
   understanding is that xxx-base-mode is considered a temporary
   solution and will be replaced. Personally I don’t mind
   xxx-base-mode, why can’t we keep it?

   From what I can see, major mode inheritance is used for three
   purposes: a) inheriting from a “virtual” mode (eg, prog-mode) for
   hooks and keymaps; b) y-mode deriving from x-mode, where Y is a
   derived language from X; c) y-2-mode deriving from y-mode as an
   extension, where y-2-mode can be a user’s personal customization,
   or distributed as packages (js2-mode).

   I think the current model serves a) and c) just fine. But for b),
   and for when there are multiple major modes for the same language,
   the single-inheritance model can be a bit lacking. I don’t have a
   clear vision right now, perhaps we want multiple inheritance for
   hooks, perhaps we can simply allow define-derived-mode to specify
   additional hooks to run, and create some language hooks that are
   shared by every mode serving that language. I’d like to hear your
   thoughts.

3. Like 1., shouldn’t be hard to modify define-derived-mode to add a
   hook that’s not run by its derived modes.

Yuan




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

end of thread, other threads:[~2023-06-08  7:25 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-30  5:16 Extending define-derived-mode Yuan Fu
2023-05-30  5:51 ` Theodor Thornhill
2023-05-31 20:35   ` Yuan Fu
2023-06-01  5:43     ` Theodor Thornhill
2023-05-30 10:48 ` Eli Zaretskii
2023-05-30 14:16   ` Stefan Monnier
2023-05-31 21:31     ` Yuan Fu
2023-06-01  4:06       ` Stefan Monnier
2023-06-01  6:39         ` Eli Zaretskii
2023-06-02  7:50           ` Yuan Fu
2023-06-02 11:54             ` Eli Zaretskii
2023-06-05  7:31               ` Yuan Fu
2023-06-05 11:33                 ` Eli Zaretskii
2023-06-08  7:25                   ` Yuan Fu
2023-06-02  7:44         ` Yuan Fu
2023-06-02 16:46           ` Stefan Monnier
2023-06-05  7:39             ` Yuan Fu
2023-06-05 15:17               ` Stefan Monnier
2023-05-31 20:48   ` Yuan Fu
2023-06-01  5:47     ` Eli Zaretskii
2023-06-02  7:45       ` Yuan Fu
2023-06-02 11:51         ` Eli Zaretskii
2023-05-30 17:24 ` Juri Linkov
2023-06-05  8:30 ` Philip Kaludercic

Code repositories for project(s) associated with this external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.