>>>>> Stefan Monnier <[email protected]> writes:
>> [Incompatibility]
>> 1. directory local variables
>> Currently, directory local variables are prepared in a entry like
>> (latex-mode (reftex-label-alist . (("equation" ?e "eq:%f-" "\\eqref{%s}")
>> ("align" ?e "eq:%f-" "\\eqref{%s}")
>> ("gather" ?e "eq:%f-" "\\eqref{%s}")))))
>> in .dir-locals.el. In this feature branch, mode name is `LaTeX-mode',
>> thus this entry is ignored.
>>
>> The facility of major-mode-remap-list still does not handle this
>> situation.
>>
>> We can announce this fact and ask users to rewrite their
>> .dir-locals.el, but that can't be done if the user doesn't have write
>> access for that particular .dir-locals.el. (Maybe we can ignore such
>> corner cases?)
> We should fix this for Emacs-30.
> [ And then add some backward compatibility hack (presumably using
> an advice for when AUCTeX is used on Emacs<30). ]
I attach my tentative proposal for Emacs<30, using an advice.
>From 5447814da30ffe9e9e06095fd567e8169df5fb64 Mon Sep 17 00:00:00 2001
From: Ikumi Keita <[email protected]>
Date: Sat, 21 Oct 2023 21:16:36 +0900
Subject: [PATCH] Add ugly hack to accept dir local vars with former mode names
* tex.el (TeX-hack-former-dir-local-variables): New customize option.
(TeX--hack-dir-locals-collect-variables): New function to advice
`dir-locals-collect-variables'. When `major-mode' is one of major
modes which have former name, pull in directory local variables
declared under former name. Take into account the parent mode of the
former mode as well.
---
tex.el | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+)
diff --git a/tex.el b/tex.el
index d4fded73..72b39e9b 100644
--- a/tex.el
+++ b/tex.el
@@ -3875,6 +3875,67 @@ Run after mode hooks and file local variables application."
;;;###autoload
(put 'TeX-mode 'auctex-function-definition (symbol-function 'TeX-mode))
+;; COMPATIBILITY for Emacs<30
+;; hack for directory local variables
+(defcustom TeX-hack-former-dir-local-variables nil
+ "If non-nil, apply dir local vars under former mode names.
+For example, directory local variables prepared for `latex-mode'
+will be available in `LaTeX-mode' buffers.
+It is highly discouraged to enable this option. Instead, please
+rewrite mode names in .dir-locals.el whenever possible."
+ :group 'TeX-misc
+ :type 'boolean)
+
+(advice-add 'dir-locals-collect-variables :around
+ #'TeX--hack-dir-locals-collect-variables)
+(defun TeX--hack-dir-locals-collect-variables (f &rest args)
+ ;; Call `dir-locals-collect-variables' once.
+ (let ((result (apply f args))
+ entry former former-parent orig-former orig-former-parent)
+ (when (and TeX-hack-former-dir-local-variables
+ (setq entry
+ (cdr
+ (assq major-mode
+ ;; MAJOR-MODE FORMER FORMER-PARENT
+ '((plain-TeX-mode plain-tex-mode nil)
+ (LaTeX-mode latex-mode nil)
+ (docTeX-mode doctex-mode latex-mode)
+ (Texinfo-mode texinfo-mode nil)
+ (ConTeXt-mode context-mode nil)
+ (AmSTeX-mode ams-tex-mode nil)
+ (japanese-plain-TeX-mode japanese-plain-tex-mode plain-tex-mode)
+ (japanese-LaTeX-mode japanese-latex-mode latex-mode))))))
+ (setq former (pop entry) ; former AUCTeX mode name, e.g. latex-mode
+ former-parent (pop entry)) ; former parent mode name
+ (setq orig-former-parent (get former 'derived-mode-parent))
+ (put former 'derived-mode-parent former-parent)
+ ;; Very ugly hack to deceive `derived-mode-p'. Suppose
+ ;; - aaa-mode is an alias of bbb-mode
+ ;; - major-mode value is aaa-mode
+ ;; Then (derived-mode-p 'aaa-mode) returns nil on Emacs 28 and
+ ;; later, which makes `dir-locals-collect-variables' ignore a
+ ;; directory local variable entry for aaa-mode and look for an
+ ;; entry for bbb-mode instead. Hence we temporally make
+ ;; aaa-mode an alias of aaa-mode itself. :-(
+ (setq orig-former (symbol-function former))
+ (fset former former)
+ (unwind-protect
+ (let ((major-mode former))
+ ;; Append dir local vars with former mode names to return value.
+ ;; We need the next `setq' because `result' can be nil.
+ (setq result (nconc result (apply f args))))
+ ;; Restore original state.
+ (put former 'derived-mode-parent orig-former-parent)
+ (fset former orig-former)))
+ result))
+;; The above treatment fails to pick the "correct" value when
+;; .dir-locals.el assigns different value for the same variable
+;; between latex-mode and japanese-latex-mode. In that case, the
+;; value for latex-mode is picked up even in japanese-latex-mode
+;; buffer, but I couldn't find a workaround. This is just a makeshift
+;; for users who don't rewrite .dir-locals.el after all, thus let us
+;; provide this as instrument with limitation.
+
;;; Hilighting
;; FIXME: It's likely that `hilit-patterns-alist' is much obsolete.
--
2.42.0
>> (a-2) Now `TeX-add-local-master' adds entry of new mode names such as
>> %%% Local Variables:
>> %%% mode: LaTeX <-- not `latex'
>> %%% End:
> I don't like this very much: IMO the `mode:` cookie should really not specify
> the "mode" to use but rather describe the file-type (Emacs could/should
> aim to support "mime types" kind of names), and then which mode to use
> for each file-type is decided based on the user's configuration.
I understand your preferance, but I think such discrimination can't be
much rigorous in practical situations. For example, ConTeXt mode doesn't
have overlapped mode, so it's most natural to have
%%% mode: ConTeXt
; In my opinion, having both
%%% mode: context
and additional entry in major-mode-remap-alist is spurious
implementation.
Then "%%% mode: ConTeXt" v.s. "%%% mode: latex" doesn't look nice to me.
I prefer "%%% mode: ConTeXt" and "%%% mode: LaTeX", which look coherent.
> Maybe in addition to that, we need to be able to say in `dir-locals.el`
> that a setting applies only for exactly this major mode, and not
> its derivatives, maybe with a syntax like:
> ((= latex-mode) (reftex-label-alist
> . (("equation" ?e "eq:%f-" "\\eqref{%s}")
> ("align" ?e "eq:%f-" "\\eqref{%s}")
> ("gather" ?e "eq:%f-" "\\eqref{%s}"))))
Looks reasonable.
Best regards,
Ikumi Keita
#StandWithUkraine #StopWarInUkraine