From: Stefan Monnier via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
To: 69191@debbugs.gnu.org
Cc: monnier@iro.umontreal.ca
Subject: bug#69191: 30.0.50; New var `major-mode-remap-defaults`, for packages
Date: Fri, 16 Feb 2024 10:45:13 -0500 [thread overview]
Message-ID: <jwvttm85sln.fsf-monnier+@gnu.org> (raw)
[-- Attachment #1: Type: text/plain, Size: 764 bytes --]
Package: Emacs
Version: 30.0.50
While `major-mode-remap-alist` provides a way for users to indicate the
major mode of their choice, I think we need a similar variable for the
use of packages.
The package below accordingly adds a new `major-mode-remap-defaults`
and changes various packages to obey it or make use of it.
I think it nicely cleans the regexp duplication between CC-mode and
`c-ts-mode.el` and also makes it easier/cleaner for users to override
the changes made by `*-ts-mode.el`.
There are some FIXMEs that one might want to address, most importantly
whether we should use an indirection through `major-mode-remap-defaults`
for all TS modes or only for those for which we provide a non-TS mode.
And there's no doc update yet.
Stefan
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: major-mode-remap.patch --]
[-- Type: text/x-diff, Size: 8809 bytes --]
diff --git a/lisp/files.el b/lisp/files.el
index f67b650cb92..6b80175b157 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -3404,7 +3404,7 @@ set-auto-mode
matches the buffer beginning against `magic-mode-alist',
compares the file name against the entries in `auto-mode-alist',
then matches the buffer beginning against `magic-fallback-mode-alist'.
-It also obeys `major-mode-remap-alist'.
+It also obeys `major-mode-remap-alist' and `major-mode-remap-defaults'.
If `enable-local-variables' is nil, or if the file name matches
`inhibit-local-variables-regexps', this function does not check
@@ -3550,9 +3550,22 @@ major-mode-remap-alist
Every entry is of the form (MODE . FUNCTION) which means that in order
to activate the major mode MODE (specified via something like
`auto-mode-alist', file-local variables, ...) we should actually call
-FUNCTION instead."
+FUNCTION instead.
+FUNCTION can be nil to hide other entries (either in this var or in
+`major-mode-remap-defaults') and means that we should call MODE."
:type '(alist (symbol) (function)))
+(defvar major-mode-remap-defaults nil
+ "Alist mapping file-specified mode to actual mode.
+This works like `major-mode-remap-alist' except it has lower priority
+and it is meant to be modified by packages rather than users.")
+
+(defun major-mode-remap (mode)
+ "Return the function to use to enable MODE."
+ (or (cdr (or (assq mode major-mode-remap-alist)
+ (assq mode major-mode-remap-defaults)))
+ mode))
+
;; When `keep-mode-if-same' is set, we are working on behalf of
;; set-visited-file-name. In that case, if the major mode specified is the
;; same one we already have, don't actually reset it. We don't want to lose
@@ -3569,7 +3582,7 @@ set-auto-mode-0
(eq mode (car set-auto-mode--last))
(eq major-mode (cdr set-auto-mode--last)))))
(when mode
- (funcall (alist-get mode major-mode-remap-alist mode))
+ (funcall (major-mode-remap mode))
(unless (eq mode major-mode)
(setq set-auto-mode--last (cons mode major-mode)))
mode)))
diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el
index 4ef17daf876..b9064d689cf 100644
--- a/lisp/progmodes/c-ts-mode.el
+++ b/lisp/progmodes/c-ts-mode.el
@@ -1439,36 +1439,33 @@ c-or-c++-ts-mode
This function attempts to use file contents to determine whether
the code is C or C++ and based on that chooses whether to enable
`c-ts-mode' or `c++-ts-mode'."
+ ;; FIXME: (declare (obsolete c-or-c++-mode "30.1"))?
(interactive)
- (if (save-excursion
- (save-restriction
- (save-match-data ; Why `save-match-data'?
- (widen)
- (goto-char (point-min))
- (re-search-forward c-ts-mode--c-or-c++-regexp nil t))))
- (c++-ts-mode)
- (c-ts-mode)))
+ (let ((mode
+ (if (save-excursion
+ (save-restriction
+ (save-match-data ; Why `save-match-data'?
+ (widen)
+ (goto-char (point-min))
+ (re-search-forward c-ts-mode--c-or-c++-regexp nil t))))
+ 'c++-ts-mode)
+ 'c-ts-mode))
+ (funcall (major-mode-remap mode))))
+
;; The entries for C++ must come first to prevent *.c files be taken
;; as C++ on case-insensitive filesystems, since *.C files are C++,
;; not C.
(if (treesit-ready-p 'cpp)
- (add-to-list 'auto-mode-alist
- '("\\(\\.ii\\|\\.\\(CC?\\|HH?\\)\\|\\.[ch]\\(pp\\|xx\\|\\+\\+\\)\\|\\.\\(cc\\|hh\\)\\)\\'"
- . c++-ts-mode)))
+ (add-to-list 'major-mode-remap-defaults
+ '(c++-mode . c++-ts-mode)))
(when (treesit-ready-p 'c)
- (add-to-list 'auto-mode-alist
- '("\\(\\.[chi]\\|\\.lex\\|\\.y\\(acc\\)?\\)\\'" . c-ts-mode))
- (add-to-list 'auto-mode-alist '("\\.x[pb]m\\'" . c-ts-mode))
- ;; image-mode's association must be before the C mode, otherwise XPM
- ;; images will be initially visited as C files. Also note that the
- ;; regexp must be different from what files.el does, or else
- ;; add-to-list will not add the association where we want it.
- (add-to-list 'auto-mode-alist '("\\.x[pb]m\\'" . image-mode)))
-
-(if (and (treesit-ready-p 'cpp)
- (treesit-ready-p 'c))
- (add-to-list 'auto-mode-alist '("\\.h\\'" . c-or-c++-ts-mode)))
+ (add-to-list 'major-mode-remap-defaults '(c++-mode . c++-ts-mode))
+ (add-to-list 'major-mode-remap-defaults '(c-mode . c-ts-mode)))
+
+(when (and (treesit-ready-p 'cpp)
+ (treesit-ready-p 'c))
+ (add-to-list 'major-mode-remap-defaults '(c-or-c++-mode . c-or-c++-ts-mode)))
(provide 'c-ts-mode)
(provide 'c++-ts-mode)
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 64a679eacc7..6e98ce047c3 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -2902,15 +2902,19 @@ c-or-c++-mode
the code is C or C++ and based on that chooses whether to enable
`c-mode' or `c++-mode'."
(interactive)
- (if (save-excursion
- (save-restriction
- (save-match-data
- (widen)
- (goto-char (point-min))
- (re-search-forward c-or-c++-mode--regexp
- (+ (point) c-guess-region-max) t))))
- (c++-mode)
- (c-mode)))
+ (let ((mode
+ (if (save-excursion
+ (save-restriction
+ (save-match-data
+ (widen)
+ (goto-char (point-min))
+ (re-search-forward c-or-c++-mode--regexp
+ (+ (point) c-guess-region-max) t))))
+ 'c++-mode)
+ 'c-mode))
+ (funcall (if (fboundp 'major-mode-remap)
+ (major-mode-remap mode)
+ mode))))
\f
;; Support for C++
diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el
index 65adc1c55ea..296e4d0037d 100644
--- a/lisp/progmodes/go-ts-mode.el
+++ b/lisp/progmodes/go-ts-mode.el
@@ -262,6 +262,8 @@ go-ts-mode
(treesit-major-mode-setup)))
(if (treesit-ready-p 'go)
+ ;; FIXME: Should we instead put `go-mode' in `auto-mode-alist'
+ ;; and then use `major-mode-remap-defaults' to map it to `go-ts-mode'?
(add-to-list 'auto-mode-alist '("\\.go\\'" . go-ts-mode)))
(defun go-ts-mode--defun-name (node &optional skip-prefix)
diff --git a/lisp/progmodes/ruby-ts-mode.el b/lisp/progmodes/ruby-ts-mode.el
index 426ae248cac..cdfa3dca498 100644
--- a/lisp/progmodes/ruby-ts-mode.el
+++ b/lisp/progmodes/ruby-ts-mode.el
@@ -1211,18 +1211,8 @@ ruby-ts-mode
(setq-local syntax-propertize-function #'ruby-ts--syntax-propertize))
(if (treesit-ready-p 'ruby)
- ;; Copied from ruby-mode.el.
- (add-to-list 'auto-mode-alist
- (cons (concat "\\(?:\\.\\(?:"
- "rbw?\\|ru\\|rake\\|thor"
- "\\|jbuilder\\|rabl\\|gemspec\\|podspec"
- "\\)"
- "\\|/"
- "\\(?:Gem\\|Rake\\|Cap\\|Thor"
- "\\|Puppet\\|Berks\\|Brew"
- "\\|Vagrant\\|Guard\\|Pod\\)file"
- "\\)\\'")
- 'ruby-ts-mode)))
+ (add-to-list 'major-mode-remap-defaults
+ '(ruby-mode . ruby-ts-mode)))
(provide 'ruby-ts-mode)
diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el
index 5c5ca573f38..d14953ef1c7 100644
--- a/lisp/textmodes/tex-mode.el
+++ b/lisp/textmodes/tex-mode.el
@@ -1032,17 +1032,13 @@ tex--redirect-to-submode
;; `tex--guess-mode' really tries to guess the *type* of file,
;; so we still need to consult `major-mode-remap-alist'
;; to see which mode to use for that type.
- (alist-get mode major-mode-remap-alist mode))))))
+ (major-mode-remap mode))))))
-;; The following three autoloaded aliases appear to conflict with
-;; AUCTeX. We keep those confusing aliases for those users who may
-;; have files annotated with -*- LaTeX -*- (e.g. because they received
+;; Support files annotated with -*- LaTeX -*- (e.g. because they received
;; them from someone using AUCTeX).
-;; FIXME: Turn them into autoloads so that AUCTeX can override them
-;; with its own autoloads? Or maybe rely on `major-mode-remap-alist'?
-;;;###autoload (defalias 'TeX-mode #'tex-mode)
-;;;###autoload (defalias 'plain-TeX-mode #'plain-tex-mode)
-;;;###autoload (defalias 'LaTeX-mode #'latex-mode)
+;;;###autoload (add-to-list 'major-mode-remap-defaults '(TeX-mode . tex-mode))
+;;;###autoload (add-to-list 'major-mode-remap-defaults '(plain-TeX-mode . plain-tex-mode))
+;;;###autoload (add-to-list 'major-mode-remap-defaults '(LaTeX-mode . latex-mode))
;;;###autoload
(define-derived-mode plain-tex-mode tex-mode "TeX"
next reply other threads:[~2024-02-16 15:45 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-16 15:45 Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors [this message]
2024-02-21 13:44 ` bug#69191: 30.0.50; New var `major-mode-remap-defaults`, for packages Basil L. Contovounesios
2024-03-04 4:25 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-04 4:59 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-06 0:03 ` Dmitry Gutov
2024-03-06 2:54 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-06 23:15 ` Dmitry Gutov
2024-03-07 3:39 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=jwvttm85sln.fsf-monnier+@gnu.org \
--to=bug-gnu-emacs@gnu.org \
--cc=69191@debbugs.gnu.org \
--cc=monnier@iro.umontreal.ca \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).