* lisp/files.el (major-mode-remap-alist): New custom var.
(set-auto-mode--last): New var.
(set-auto-mode-0): Obey `major-mode-remap-alist`.
* doc/emacs/modes.texi (Choosing Modes): Document `major-mode-remap-alist`.
* lisp/progmodes/cperl-mode.el: Recommend the use of
`major-mode-remap-alist` over the crude `defalias` solution.
* lisp/textmodes/tex-mode.el (tex--guess-mode): Simplify.
(tex--redirect-to-submode): Obey `major-mode-remap-alist`.
files, HTML/XML/SGML files, PostScript files, and Unix style Conf
files.
+@vindex major-mode-remap-alist
+ Once a major mode is found, Emacs does a final check to see if the
+mode has been remapped by @code{major-mode-remap-alist}, in which case
+it uses the remapped mode instead. This is used when several
+different major modes can be used for the same file type, so you can
+specify which mode you prefer.
+
@findex normal-mode
If you have changed the major mode of a buffer, you can return to
the major mode Emacs would have chosen automatically, by typing
\f
* Changes in Emacs 29.1
++++
+** New variable 'major-mode-remap-alist' to specify your favorite major modes.
+This variable lets you remap the default modes (e.g. 'perl-mode' or
+'latex-mode') to your favorite ones (e.g. 'cperl-mode' or
+'LaTeX-mode') without having to use 'defalias', which can have
+undesirable side effects.
+This applies to all modes specified via 'auto-mode-alist', file-local
+variables, etc...
+
---
** Emacs now supports Unicode Standard version 15.0.
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'.
If `enable-local-variables' is nil, or if the file name matches
`inhibit-local-variables-regexps', this function does not check
(unless done
(set-buffer-major-mode (current-buffer)))))
+(defvar-local set-auto-mode--last nil
+ "Remember the mode we have set via `set-auto-mode-0'.")
+
+(defcustom major-mode-remap-alist nil
+ "Alist mapping file-specified mode to actual mode.
+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."
+ :type '(alist (symbol) (function)))
+
;; 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
any aliases and compared to current major mode. If they are the
same, do nothing and return nil."
(unless (and keep-mode-if-same
- (eq (indirect-function mode)
- (indirect-function major-mode)))
+ (or (eq (indirect-function mode)
+ (indirect-function major-mode))
+ (and set-auto-mode--last
+ (eq mode (car set-auto-mode--last))
+ (eq major-mode (cdr set-auto-mode--last)))))
(when mode
- (funcall mode)
+ (funcall (alist-get mode major-mode-remap-alist mode))
+ (unless (eq mode major-mode)
+ (setq set-auto-mode--last (cons mode major-mode)))
mode)))
(defvar file-auto-mode-skip "^\\(#!\\|'\\\\\"\\)"
;; interpreter invocation. The same holds
;; for '\" in man pages (preprocessor
;; magic for the `man' program).
- (and (looking-at file-auto-mode-skip) 2)) t)
+ (and (looking-at file-auto-mode-skip) 2))
+ t)
(progn
(skip-chars-forward " \t")
(setq beg (point))
If your Emacs does not default to `cperl-mode' on Perl files, and you
want it to: put the following into your .emacs file:
- (defalias \\='perl-mode \\='cperl-mode)
+ (add-to-list \\='major-mode-remap-alist \\='(perl-mode . cperl-mode))
Get perl5-info from
$CPAN/doc/manual/info/perl5-old/perl5-info.tar.gz
(save-excursion
(beginning-of-line)
(search-forward "%" search-end t))))))
- (when (and slash (not comment))
- (setq mode
- (if (looking-at
- (concat
- (regexp-opt '("documentstyle" "documentclass"
- "begin" "subsection" "section"
- "part" "chapter" "newcommand"
- "renewcommand" "RequirePackage")
- 'words)
- "\\|NeedsTeXFormat{LaTeX"))
- (if (and (looking-at
- "document\\(style\\|class\\)\\(\\[.*\\]\\)?{slides}")
- ;; SliTeX is almost never used any more nowadays.
- (tex-executable-exists-p slitex-run-command))
- #'slitex-mode
- #'latex-mode)
- #'plain-tex-mode))))
- mode))
+ (if (not (and slash (not comment)))
+ mode
+ (if (looking-at
+ (concat
+ (regexp-opt '("documentstyle" "documentclass"
+ "begin" "subsection" "section"
+ "part" "chapter" "newcommand"
+ "renewcommand" "RequirePackage")
+ 'words)
+ "\\|NeedsTeXFormat{LaTeX"))
+ (if (and (looking-at
+ "document\\(style\\|class\\)\\(\\[.*\\]\\)?{slides}")
+ ;; SliTeX is almost never used any more nowadays.
+ (tex-executable-exists-p slitex-run-command))
+ #'slitex-mode
+ #'latex-mode)
+ #'plain-tex-mode)))))
;; `tex-mode' plays two roles: it's the parent of several sub-modes
;; but it's also the function that chooses between those submodes.
;; We're called from one of the children already.
orig-fun
(setq tex-mode--recursing t)
- (tex--guess-mode)))))
+ (let ((mode (tex--guess-mode)))
+ ;; `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.
+ (funcall (alist-get mode major-mode-remap-alist mode)))))))
;; The following three autoloaded aliases appear to conflict with
-;; AUCTeX. However, even though AUCTeX uses the mixed case variants
-;; for all mode relevant variables and hooks, the invocation function
-;; and setting of `major-mode' themselves need to be lowercase for
-;; AUCTeX to provide a fully functional user-level replacement. So
-;; these aliases should remain as they are, in particular since AUCTeX
-;; users are likely to use them.
-;; Note from Stef: I don't understand the above explanation, the only
-;; justification I can find to keep those confusing aliases is for those
-;; users who may have files annotated with -*- LaTeX -*- (e.g. because they
-;; received them from someone using AUCTeX).
-
+;; AUCTeX. We keep those confusing aliases for those users who may
+;; have 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 it's 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)