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

From: Dmitry Gutov <[email-masked]>
Date: Tue, 16 Jan 2024 04:09:07 +0200

On 16/01/2024 01:11, João Távora wrote:
> On Mon, Jan 15, 2024 at 8:51 PM Dmitry Gutov <[email-masked]> wrote:
> 
>>> I don't think there's anything magical about a base mode.  But I like your
>>> solution too.
>>
>> As "magical", I meant the original patch for this report. I wouldn't
>> mind the "base mode" approach, but I guess its still suffers from not
>> being suitable for using with earlier Emacs versions.
>>
>> And every programming mode will have to come with -base-mode defined,
> 
> We could define them all in batch in a macro, that's not too bad.  And
> then let the existing fleshed out ones overwrite those definitions by
> making sure to load them later.

A keyword for define-derived-mode like (:base t)? That would work.

> The main advantages of the foo-base-mode approach is that:
> 
> * it is easily grokkable by everybody, as it is very simply based on
>    simple inheritance, which everybody knows already.
> 
> * there's already a fair number of such modes in the tree.

Agree.

I guess the part I don't quite like is adding a lot more new -base- 
modes (we'll have to add one for every prog mode, at least), most of 
which would stay unused, but unlike hook variables, clutter the function 
namespace.

> But I do like your patch better, it seems pretty useful to introduce the
> language concept, as it solves this and more problems more cleanly.  So
> let's see where that goes.

Great.

>> This choice is coupled with the corresponding logic in 'buffer-language'
>> (whether to keep the replace-regexp-in-string branch).
> 
> Yes.  I think we should err on the side on convenience.  What exactly are
> the defects can we get?  I can't see anything else but the tuareg-mode, and we
> can plug that on our side.  Maybe you can see more.

For example, it would sometimes return ugly non-existent languages like 
:help-fns--edit-value, :org-lint--report or :xref--xref-buffer.

In most cases that would be harmless, but OTOH the callers would miss 
out on the opportunity to see that the language is nil and apply their 
own fallbacks right away. I don't have a real problem scenario in mind, 
though.

Perhaps some commands that would act on the language of the current 
buffer might want to say "no language is associated", but could not with 
the "convenience" approach.

>> Are there specific uses for get-mode-for-language when there is no
>> existing buffer?
> 
> Yes, I'd say this markdown-mode use is exactly that.  Markdown inserts
> some text into a buffer and all it knows is the language it's supposed
> to fontify it with.  The major mode has that logic, so it must invoke
> the correct (and preferred) major-mode function.

Sorry, I meant get-language-for-mode (which is the one implemented as 
buffer-language currently).

> Another use is allowing the user to choose major modes for languages,
> say from a tutorial or wizard or at Emacs startup.  Say, I prefer
> ruby-ts-mode for Ruby, but c++-mode for C++.  It'd be helpful to summarize
> those preferences.

This would require capabilities like "get all modes for a language" (not 
one of the set of functions mentioned so far, and it'll need a full scan 
of major-mode-remap-alist) and "get current mode for a language" (this 
one matches markdown-mode's function you posted).

BTW, get-current-mode-for-language could be implemented in terms of 
set-buffer-language.

>> We could have both functions: buffer-language and get-language-for-mode
>> ('get-mode-language'?). Or define one initially and add the other as needed.
> 
> Yes.  buffer-language isn't bad, it's a useful helper.  But buffer-language
> should be just
> 
>     (with-current-buffer buffer (get-language-for-mode major-mode))
> 
> Right?  Modulo some caching if it turns out to be very inneficient
> (which I really doubt)

Again: this won't work for files where no suitable major mode is 
available (e.g. not installed yet).