GNU bug report logs -
#68246
30.0.50; Add non-TS mode as extra parent of TS modes
Previous Next
Reported by: Stefan Monnier <monnier <at> iro.umontreal.ca>
Date: Thu, 4 Jan 2024 22:12:01 UTC
Severity: wishlist
Found in version 30.0.50
Done: Stefan Monnier <monnier <at> iro.umontreal.ca>
Bug is archived. No further changes may be made.
Full log
View this message in rfc822 format
On Mon, Jan 15, 2024 at 2:10 AM Dmitry Gutov <dmitry <at> gutov.dev> wrote:
>
> It's not like we don't have an existing solution for this: if there are
> two different modes to configure, change the settings for both modes, or
> alter two hooks. Less magical and more verbose, but being explicit can
> be good.
I don't think there's anything magical about a base mode. But I like your
solution too.
> Here's a draft patch of how a "language" could work. It doesn't alter
> every entry, but it is backward compatible.
I think something like this can work, yes.
- (funcall (alist-get mode major-mode-remap-alist mode))
+ ;; XXX: When there's no mapping for `:<language>', we could also
+ ;; look for a function called `<language>-mode'.
+ (funcall (alist-get mode major-mode-remap-alist (if (keywordp mode)
+ #'fundamental-mode
+ mode)))
+ (when (keywordp mode) ;Perhaps do that unconditionally.
+ (run-hooks (intern (format "%s-language-hook" (buffer-language)))))
(unless (eq mode major-mode)
Regarding the "XXX", this is basically the same questions in the
two headings, I think, which is whether to consider the <foo> in existing
<foo>-mode as language. I think we can do it yes. Eglot and other
packages [*] have been doing it for quite some time. It will fail very
rarely, only for major modes outside Emacs (like "tuareg-mode" for
Ocaml) and we can probably fix that in-tree.
The only thing that leaves me some doubts is the 'set-buffer-language'
entry point. It's a new thing not strictly required. Normally the
databases are edited (via whatever means) and then the buffer is
reverted for a mode change. So I don't think we need to introduce
this user convenience just yet (though, like the other user conveniences
you have imagined, I'm not necessarily opposed to it).
Also 'buffer-language' could be 'get-mode-language', so you don't
have to have an actual buffer handy to get this association. The
implementation would just be a reverse search in major-mode-remap-alist
Other than that, I think the solution is workable.
The other package [*] that does exactly the same thing as Eglot, and
invented it independently is markdown-mode:
(defun markdown-get-lang-mode (lang)
"Return major mode that should be used for LANG.
LANG is a string, and the returned major mode is a symbol."
(cl-find-if
#'markdown--lang-mode-predicate
(nconc (list (cdr (assoc lang markdown-code-lang-modes))
(cdr (assoc (downcase lang) markdown-code-lang-modes)))
(and (fboundp 'treesit-language-available-p)
(list (and (treesit-language-available-p (intern lang))
(intern (concat lang "-ts-mode")))
(and (treesit-language-available-p (intern
(downcase lang)))
(intern (concat (downcase lang) "-ts-mode")))))
(list
(intern (concat lang "-mode"))
(intern (concat (downcase lang) "-mode"))))))
It uses this to know what major-mode to use to fontify GitHub style
markdown code blocks (which have a little language cookie after the
three backticks). Like Eglot's similar code, I think it could be trivially
rewritten if something like your patch were in place.
Bug#68217 is also relevant here. Eglot calls into markdown-mode.el
to fontify LSP documentation snippets and sometimes the mode picked
by markdown-mode.el to do the fontification is not the same the user
is using for the buffer. It most clearly should be. So
get-language-for-mode and get-(preferred)-mode-for-language are two
evidently needed helpers.
João
This bug report was last modified 1 year and 104 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.