1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-22 07:09:54 +00:00

(major-mode-remap(-defaults)): New var and function (bug#69191)

While `major-mode-remap-alist` provides a way for users to indicate the
major mode of their choice, we need a similar variable for the
use of packages.

This patch 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`.

* lisp/files.el (major-mode-remap-defaults): New variable.
(major-mode-remap): New function.
(set-auto-mode-0): Use it.
* doc/lispref/modes.texi (Auto Major Mode): Document them.

* lisp/textmodes/tex-mode.el (tex--redirect-to-submode):
Use `major-mode-remap`.
(major-mode-remap-defaults): Set it to remap AUCTeX modes by default.
* lisp/progmodes/ruby-ts-mode.el (auto-mode-alist): Leave it alone.
(major-mode-remap-defaults): Set this one instead.
* lisp/progmodes/c-ts-mode.el (c-or-c++-ts-mode): Use `major-mode-remap`.
(auto-mode-alist): Leave it alone.
(major-mode-remap-defaults): Set this one instead.
* lisp/org/ox.el (org-export-to-buffer): Modernize docstring accordingly.
* lisp/progmodes/cc-mode.el (c-or-c++-mode):
* lisp/org/ox-latex.el (org-latex-export-as-latex):
* lisp/org/ox-koma-letter.el (org-koma-letter-export-as-latex):
* lisp/org/ox-beamer.el (org-beamer-export-as-latex):
Use `major-mode-remap` when available.
This commit is contained in:
Stefan Monnier 2024-03-03 23:08:16 -05:00
parent f5c65dae09
commit 2b5d43081a
12 changed files with 113 additions and 57 deletions

View File

@ -791,6 +791,39 @@ init file.)
@end smallexample
@end defvar
@defvar major-mode-remap-defaults
This variable contains an association list indicating which function
to call to activate a given major mode. This is used for file formats
that can be supported by various major modes, where this variable can be
used to indicate which alternative should be used by default.
For example, a third-party package providing a much improved Pascal
major mode, can use the following to tell @code{normal-mode} to use
@code{spiffy-pascal-mode} for all the files that would normally use @code{pascal-mode}:
@smallexample
@group
(add-to-list 'major-mode-remap-defaults '(pascal-mode . spiffy-pascal-mode))
@end group
@end smallexample
This variable has the same format as @code{major-mode-remap-alist}.
If both lists match a major mode, the entry in
@code{major-mode-remap-alist} takes precedence.
@end defvar
@defun major-mode-remap mode
This function returns the major mode to use instead of @var{mode}
according to @code{major-mode-remap-alist} and
@code{major-mode-remap-defaults}. It returns @var{mode} if the mode
is not remapped by those variables.
When a package wants to activate a major mode for a particular file
format, it should use this function, passing as @code{mode} argument the
canonical major mode for that file format, to find which specific major
mode to activate, so as to take into account the user's preferences.
@end defun
@node Mode Help
@subsection Getting Help about a Major Mode
@cindex mode help

View File

@ -1595,6 +1595,10 @@ values.
* Lisp Changes in Emacs 30.1
** New var 'major-mode-remap-defaults' and function 'major-mode-remap'.
The first is like Emacs-29's 'major-mode-remap-alist' but to be set by
packages (instead of users). The second looks up those two variables.
+++
** Pcase's functions (in 'pred' and 'app') can specify the argument position.
For example, instead of '(pred (< 5))' you can write '(pred (> _ 5))'.

View File

@ -3413,7 +3413,7 @@ checks if it uses an interpreter listed in `interpreter-mode-alist',
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
@ -3559,9 +3559,22 @@ we don't actually set it to the same mode the buffer already has."
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
@ -3578,7 +3591,7 @@ same, do nothing and return nil."
(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)))

View File

@ -1008,7 +1008,10 @@ will be displayed when `org-export-show-temporary-export-buffer'
is non-nil."
(interactive)
(org-export-to-buffer 'beamer "*Org BEAMER Export*"
async subtreep visible-only body-only ext-plist (lambda () (LaTeX-mode))))
async subtreep visible-only body-only ext-plist
(if (fboundp 'major-mode-remap)
(major-mode-remap 'latex-mode)
#'LaTeX-mode)))
;;;###autoload
(defun org-beamer-export-to-latex

View File

@ -911,7 +911,9 @@ non-nil."
(let (org-koma-letter-special-contents)
(org-export-to-buffer 'koma-letter "*Org KOMA-LETTER Export*"
async subtreep visible-only body-only ext-plist
(lambda () (LaTeX-mode)))))
(if (fboundp 'major-mode-remap)
(major-mode-remap 'latex-mode)
#'LaTeX-mode))))
;;;###autoload
(defun org-koma-letter-export-to-latex

View File

@ -4160,7 +4160,10 @@ will be displayed when `org-export-show-temporary-export-buffer'
is non-nil."
(interactive)
(org-export-to-buffer 'latex "*Org LATEX Export*"
async subtreep visible-only body-only ext-plist (lambda () (LaTeX-mode))))
async subtreep visible-only body-only ext-plist
(if (fboundp 'major-mode-remap)
(major-mode-remap 'latex-mode)
#'LaTeX-mode)))
;;;###autoload
(defun org-latex-convert-region-to-latex ()

View File

@ -6608,7 +6608,7 @@ use it to set a major mode there, e.g.,
(interactive)
(org-export-to-buffer \\='latex \"*Org LATEX Export*\"
async subtreep visible-only body-only ext-plist
#\\='LaTeX-mode))
(major-mode-remap 'latex-mode)))
When expressed as an anonymous function, using `lambda',
POST-PROCESS needs to be quoted.

View File

@ -1190,7 +1190,6 @@ BEG and END are described in `treesit-range-rules'."
"C-c C-c" #'comment-region
"C-c C-k" #'c-ts-mode-toggle-comment-style)
;;;###autoload
(define-derived-mode c-ts-base-mode prog-mode "C"
"Major mode for editing C, powered by tree-sitter.
@ -1439,36 +1438,33 @@ should be used.
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'."
(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)))
(add-to-list 'major-mode-remap-defaults '(c++-mode . c++-ts-mode))
(add-to-list 'major-mode-remap-defaults '(c-mode . c-ts-mode)))
(if (and (treesit-ready-p 'cpp)
(treesit-ready-p 'c))
(add-to-list 'auto-mode-alist '("\\.h\\'" . c-or-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)

View File

@ -2902,15 +2902,19 @@ 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-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))))
;; Support for C++

View File

@ -262,6 +262,8 @@
(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)

View File

@ -1211,18 +1211,8 @@ leading double colon is not added."
(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)

View File

@ -1036,14 +1036,20 @@ says which mode to use."
;; `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 (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))
;; FIXME: These aliases conflict with AUCTeX, but we still need them
;; because of packages out there which call these functions directly.
;; They should be patched to use `major-mode-remap'.
;; It would be nice to mark them obsolete somehow to encourage using
;; something else, but the obsolete declaration would become invalid
;; and confusing when AUCTeX *is* installed.
;;;###autoload (defalias 'TeX-mode #'tex-mode)
;;;###autoload (defalias 'plain-TeX-mode #'plain-tex-mode)
;;;###autoload (defalias 'LaTeX-mode #'latex-mode)