]> git.eshelyaron.com Git - emacs.git/commitdiff
files.el (major-mode-remap-alist): New custom var (bug#58075)
authorStefan Monnier <monnier@iro.umontreal.ca>
Mon, 3 Oct 2022 15:17:51 +0000 (11:17 -0400)
committerStefan Monnier <monnier@iro.umontreal.ca>
Mon, 3 Oct 2022 15:17:51 +0000 (11:17 -0400)
* 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`.

doc/emacs/modes.texi
etc/NEWS
lisp/files.el
lisp/progmodes/cperl-mode.el
lisp/textmodes/tex-mode.el

index c348130807c383531406d01340bd668f3c41bf71..56b779f8de6a5d4ae494ce78a5f3baeefc9e536a 100644 (file)
@@ -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
index 6e7836e3c097c703b697a8bf401d9b174d427b3b..9e9f9b650305d39e4552fbfcd3894bf073087b6a 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -477,6 +477,15 @@ option) and can be set to nil to disable Just-in-time Lock mode.
 \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.
 
index 40ad11ecfc498f724d1d1a51744b381499a28f5b..667e3325bb78a17202745147695a8f2146b32887 100644 (file)
@@ -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))
index fa428642fa44c3a7603eea31417519b19fae82e0..20a73e238e963e3bbc0cac7b49b28a23a6f49bd0 100644 (file)
@@ -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
index b43537265f5b440fd61fb69173d469c0bf26c34c..5c2dbdfe5cd27143b2a4f158c4d3b9c2636f0622 100644 (file)
@@ -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)