summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/emacs/modes.texi7
-rw-r--r--etc/NEWS9
-rw-r--r--lisp/files.el26
-rw-r--r--lisp/progmodes/cperl-mode.el2
-rw-r--r--lisp/textmodes/tex-mode.el57
5 files changed, 66 insertions, 35 deletions
diff --git a/doc/emacs/modes.texi b/doc/emacs/modes.texi
index c348130807c..56b779f8de6 100644
--- a/doc/emacs/modes.texi
+++ b/doc/emacs/modes.texi
@@ -454,6 +454,13 @@ only @emph{after} @code{auto-mode-alist}. By default,
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
diff --git a/etc/NEWS b/etc/NEWS
index 6e7836e3c09..9e9f9b65030 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -477,6 +477,15 @@ option) and can be set to nil to disable Just-in-time Lock mode.
* 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.
diff --git a/lisp/files.el b/lisp/files.el
index 40ad11ecfc4..667e3325bb7 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -3333,6 +3333,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'.
If `enable-local-variables' is nil, or if the file name matches
`inhibit-local-variables-regexps', this function does not check
@@ -3470,6 +3471,17 @@ we don't actually set it to the same mode the buffer already has."
(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
@@ -3480,10 +3492,15 @@ If optional arg KEEP-MODE-IF-SAME is non-nil, MODE is chased of
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 "^\\(#!\\|'\\\\\"\\)"
@@ -3513,7 +3530,8 @@ have no effect."
;; 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))
diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el
index fa428642fa4..20a73e238e9 100644
--- a/lisp/progmodes/cperl-mode.el
+++ b/lisp/progmodes/cperl-mode.el
@@ -632,7 +632,7 @@ mode-compile.el.
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
diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el
index b43537265f5..5c2dbdfe5cd 100644
--- a/lisp/textmodes/tex-mode.el
+++ b/lisp/textmodes/tex-mode.el
@@ -980,24 +980,23 @@ Inherits `shell-mode-map' with a few additions.")
(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.
@@ -1029,20 +1028,18 @@ says which mode to use."
;; 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)