Subject: Re: bug#68246: 30.0.50; Add non-TS mode as extra parent of TS modes

From: João Távora <[email-masked]>
Date: Sat, 6 Jan 2024 00:16:02 +0000

On Fri, Jan 5, 2024 at 11:51 PM Stefan Monnier <[email-masked]> wrote:
>
> [ IMO, it would indeed be a good idea to try and write some abstraction
>   layer so we can share more code between modes parsing with
>   syntax-tables/tree-sitter/wisi/SMIE/younameit.  It will also be very
>   useful when tree-sitter goes the way of the dodo.

Very relevant.

>   But that's a difficult job, and with limited immediately-visible
>   benefits to the end users.  In the mean time, we're stuck with major
>   modes that don't share much code.  ]
>
> Whether it's worthwhile to have a `FOO-base-mode` or not depends on
> the specifics, but it's largely an implementation detail.  More
> importantly it's not directly relevant to this here bug, because
> I want to say "FOO-ts-mode is a kind of mode for FOO, so it's
> a kind of FOO-mode".

OK, so "kind".  So you seem to want to FOO-mode designates a family
of modes for FOO.  That's reasonable but it  has the confusing property
that the name of the family coincides with  the name of one of the
members of the family.  Using inheritance for  that just seems a bit off,
like a hack.  Really what we wanted is a  new variable called 'mode-family'
and test against that.

> There are very few YASnippets for FOO-base-mode,
> instead they're all for FOO-mode.  Similarly, Eglot doesn't have rules
> for FOO-base-mode, only for FOO-mode.

Right.  But we can change Eglot and Yasnippet, can't we?  I know what
to do in Eglot, which is something like this:

 (defvar eglot-server-programs `(((rust-ts-mode rust-mode) . ("rust-analyzer"))
                                 ((cmake-mode cmake-ts-mode) .
("cmake-language-server"))
                                 (vimrc-mode . ("vim-language-server"
"--stdio"))
-                                ((python-mode python-ts-mode)
+                                (python-base-mode
                                  . ,(eglot-alternatives

In Yasnippet, if I remember correctly (it was a long time ago), the
snippet directory could either be renamed foo-base-mode or something
in a .yas-parents inside that directory can be added containing
"foo-base-mode".

As to the problem that this doesn't work in Emacs < 30, we must
either:

* also keep the old definitions, or better

* use compat.el like Eli suggested to bring in those new base modes
(whereby compat.el could use derive-mode-add-parent itself, but for
but adding foo-base-mode as a parent of foo-mode and foo-ts-mode
instead).

> That's why in my patch I add `python-mode` as an extra parent of
> `python-ts-mode` even though they both share `python-base-mode` as
> their parent.

Right, that's what sounds hacky to me.  They're siblings, but now
one also is the parent of the other. Maybe it works, but is
definitely  odd.

That said, if it works, I'm not really opposed to it.  What
other packages do you know like Eglot and Yasnippet which use
major-mode in this way.

> IOW, in my patch, I'm using `FOO-mode` not really as the name of a major
> mode, but rather as the name of a *file type*.
> I already mentioned this distinction in the bug-report where
> I introduced `major-mode-remap-alist`: Emacs usually conflates
> file-type and major-mode, which works great where there's only one major
> mode for a given file type, but less great where there are
> several alternatives.

Agree, so your "file-type" seems to match my idea of "mode family".
So a new variable called file-type would be the correct abstraction.

And I don't see how "foo-base-mode" is much worse, modulo slightly
more akward naming and backward compatibility problems that you would
have anyway.

João