Package: emacs;
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.
View this message in rfc822 format
From: Stefan Monnier <monnier <at> iro.umontreal.ca> To: Dmitry Gutov <dmitry <at> gutov.dev> Cc: 68246 <at> debbugs.gnu.org, Eli Zaretskii <eliz <at> gnu.org>, casouri <at> gmail.com, João Távora <joaotavora <at> gmail.com>, Stefan Kangas <stefankangas <at> gmail.com> Subject: bug#68246: 30.0.50; Add non-TS mode as extra parent of TS modes Date: Thu, 18 Jan 2024 09:17:15 -0500
> away). The language-specific version of major-mode-remap-alist looks > necessary after all. It doesn't have to be specifically about languages. It can just be a "default" set of "major mode" remappings. >>> @@ -3206,10 +3209,10 @@ interpreter-mode-alist >>> ("emacs" . emacs-lisp-mode))) >>> "Alist mapping interpreter names to major modes. >>> This is used for files whose first lines match `auto-mode-interpreter-regexp'. >>> -Each element looks like (REGEXP . MODE). >>> +Each element looks like (REGEXP . MODE-OR-LANGUAGE). >>> If REGEXP matches the entire name (minus any directory part) of >>> the interpreter specified in the first line of a script, enable >>> -major mode MODE. >>> +MODE-OR-LANGUAGE. >> There's a similar need for "content type" rather than "language". If we >> want to mention "language" we should also take the opportunity to >> mention other related categorizations like "content type". > Are "content type" and "language" going to be different things? > They seem the same to me. I think there's the same kind of difference between "language" and "content type" as between "language" and "major mode" :-) > 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)) > 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. >> 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. >> Also I think if we want a `buffer-language` function, it should not rely >> on how the mode was installed (e.g. `set-auto-mode--last`) but only on >> the major mode itself, i.e. something like >> (defun buffer-language () >> (or buffer-language > Where would the buffer-language variable be set, if not inside > set-auto-mode-*? In the major mode? >> (some heuristic based on major-mode and/or derived-modes))) > If we're sure we don't want several languages to be able to refer to the > same major mode... A major mode can (setq major-mode ...) If/when such "generic" major modes become a thing, and the `(setq major-mode ...)` hack becomes too inconvenient, we can devise a better solution (e.g. extending/tweaking the way `derived-mode-*` work). >> [ Of course, I already mentioned that I also suspect that there can/will >> be sometimes several languages (or none). ] > I'm not clear on this. You mentioned complex cases - like an xml inside an > archive? But depending on the usage, only one of the languages might be > "active" at a given time. But depending on what "the language/type/mode" is used for, we may not care really about which language/type/mode is "active" but about which languages/types/modes are applicable (e.g. for `.dir-locals.el`). >>> +(defun set-buffer-language (language) >>> + "Set the language of the current buffer. >>> +And switch the major mode appropriately." >>> + (interactive >>> + (list (let* ((ct (mapcan >>> + (lambda (pair) (and (keywordp (car pair)) >>> + (list (symbol-name (car pair))))) >>> + major-mode-remap-alist)) >>> + (lang (completing-read "Language: " ct))) >>> + (and lang (intern lang))))) >>> + (set-auto-mode-0 language)) >> I see several issues with this function (name and implementation), but >> I wonder when we'd ever need such a thing. > > It seemed like a missed opportunity not to provide a more high-level command > to switch to a specific language for the buffer. E.g. how we sometimes use > 'M-x foo-major-mode' when a file type's been misdetected, or the buffer is > non-file-visiting (perhaps very temporary). > > A command which does this with exhaustive completion across the configured > languages seems handy. At least that's my impression from briefly testing > it out. We can do the same with major modes, of course (just `mapatom` and filter out the non-major modes), so feel free to add such a command, but it doesn't seem like offering it for "languages" is particularly more useful than offering it for "major modes". > Also, get-current-mode-for-language can be implemented in terms of > set-buffer-language (see my earlier email to Joao). That seems to be a roundabout way to go about it. `get-current-mode-for-language/type/mode` should be used by `set-auto-mode` rather than other way around, no? > <LANG>-mode is lexically indistinguishable from <NONLANG>-mode. If we used > the names like <LANG>-lang, at least one could tell whether one of the > parents of a given <foo>-mode is a language. Other than for Eglot, where does this distinction matter? >> Another issue I see if we don't use something like >> `derived-mode-add-parents` is that all the various places where we use >> mode-indexing, such as `.dir-locals.el`, `ffap`, YASnippet, etc... will >> need to be extended with a way to use "languages" as well, and then we >> also need to define a sane precedence between settings that apply to >> a given mode and settings that apply to a given language (setting for >> `js-ts-mode` should presumably take precedence over settings for >> `:js` which should take precedence over settings for `prog-mode`). > That's a good point: if "languages" as a separate notion gets added, it > would make sense to use them in more places (not 100% necessary, but good > for consistency). With the associated complexity that you mention. And if it's not merged into the same hierarchy as major modes, how do you get `:js` (i.e. "language") to be sometimes higher-precedence and sometimes lower precedence than a mode? Stefan
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.