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

From: Stefan Monnier <[email-masked]>
Date: Thu, 18 Jan 2024 16:24:46 -0500

> Still not sure how that would work.  I mean, we could have content-type
> like text/html or application/json, but neither splits into two
> languages, really.

Not sure what you mean by "split", but just as with major modes and
"languages", MIME content-types have inclusion properties, such as

    application/atom+xml ⊂ application/xml ⊂ text/plain

>>> OTOH, the major mode can only run the language hook, I think, if any major
>>> mode can correspond only to one language.
>> Not so.  A major mode can easily do
>>      (run-mode-hooks (compute-the-hook))
> I guess that would mean that the language hook is not run automatically,
> that each major mode would need explicit code to compute it and run.

Not necessarily, e.g. you could specify the language to
`define-derived-mode` with something like

    :language (compute-the-language)

and then have `define-derived-mode` compute the hook name from that.
This said, I suspect that generic major modes supporting many languages
will not be very numerous (after all, that's the point of being generic,
no?), so it should be OK if they have to do some things manually.

>>> Though I suppose if set-auto-mode-0 saves the currently "detected"
>>> language somewhere, the major mode definitions could pick it up and
>>> call the corresponding hook.
>> Major modes are not activated solely via `set-auto-mode-0`, so relying
>> on that is a crutch/hack, not something on which to base a design.
> The major mode could compute which language it is for. But the algorithm
> could be undecidable if the buffer is not visiting a file yet, doesn't have
> an interpreter comment, etc. That's where the command set-buffer-language
> was supposed to come in handy.

That still doesn't justify the major mode relying on `set-auto-mode-0`.

AFAICT you seem to want to standardize how the user controls the language of
language-generic major modes.  I'm not sure we need such a standard.
Do we even have such a generic major mode yet?

>>>> I'm not comfortable enshrining the "-ts-mode" convention here.
>>> We can still go the "strict" approach, where when no language is assigned,
>>> we don't try to guess it.
>> I think the `<LANG>-mode` heuristic is acceptable, because it's been
>> *the* convention used in Emacs.
> We are now getting a whole set of new modes for which this heuristic isn't
> going to work

Cue the patch I submitted when I open this bug report 🙂
Now `<LANG>-mode` is again included in `derived-mode-all-parents` for
those new modes.

Admittedly, it doesn't fully give a solution to the problem of computing
"the" language of a buffer.  But that gets us back to one of my recent
questions: beside Eglot, which other package needs that?  Is "the"
language always unique and always the same for all those packages?
Is it really the only thing those packages need?

In the case of Eglot, at least it doesn't seem to be the case: we don't
just need the language, but also the name of the language server to use.
And for some buffers there can be several applicable language servers,
and they don't necessarily all accept the same language.

So we need either the major mode to provide the name of the server, or
a central database that maps from language/type/mode to server name.
In both cases, adding the language info to the server name is
a non-issue.  And in neither case is it necessary to know "the" language
in order to find the server.  My patch makes the central database
work better.

> The major-mode could be fundamental-mode. If the language were to be
> specifiable through settings external to major modes, we could still do
> useful things while in fundamental-mode (e.g. do some useful editing with
> Eglot, provided it supports indentation and completion), or suggest which
> major modes to install from ELPA.

I don't see the interest of using specifically `fundamental-mode` for
that.  In any case, this seems too hypothetical at this stage to have
a good idea of what we'd need in such circumstances.

> Would we really care that an xml file inside an archive is applied both
> archive-subfile-mode and xml-mode dir-locals settings?

No, I wasn't thinking of XML files inside archives, but about files
which are both archives and something else (e.g. ODT).  The same applies
for most other "generic" data containers, like XML and JSON.

> Perhaps dir-locals.el could get a syntax for specifying variables when
> specific minor modes are enabled as well.

Or we could do something like

    (defun derived-mode-p (modes)
      (provided-mode-derived-p (or (funcall major-mode-function) major-mode)
                                modes)

or

    (defun derived-mode-current-all-parents ()
      (or (funcall major-mode-all-parents-function)
          (derived-mode-all-parents major-mode)))

So your XML major mode can indicate that the current buffer is actually
in `xml+atom-mode` (which is a child of `xml-mode`).

Anyway, as I mentioned elsewhere, I think this discussion of "languages"
is only tangentially related to my proposed patch.  There is some
overlap, but they serve different purposes, and they're not
mutually exclusive.

        Stefan