GNU bug report logs -
#75961
set-auto-mode--apply-alist
Previous Next
Reported by: nat chapman <nat.chapman <at> proton.me>
Date: Fri, 31 Jan 2025 07:59:02 UTC
Severity: normal
Done: Stefan Monnier <monnier <at> iro.umontreal.ca>
Bug is archived. No further changes may be made.
To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 75961 in the body.
You can then email your comments to 75961 AT debbugs.gnu.org in the normal way.
Toggle the display of automated, internal messages from the tracker.
Report forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#75961
; Package
emacs
.
(Fri, 31 Jan 2025 07:59:02 GMT)
Full text and
rfc822 format available.
Acknowledgement sent
to
nat chapman <nat.chapman <at> proton.me>
:
New bug report received and forwarded. Copy sent to
bug-gnu-emacs <at> gnu.org
.
(Fri, 31 Jan 2025 07:59:02 GMT)
Full text and
rfc822 format available.
Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
On https://www.gnu.org/software/emacs/manual/html_node/emacs/Choosing-Modes.html, the manual says: "If the element has the form (regexp mode-function flag) and flag is non-nil, then after calling mode-function (if it is non-nil), Emacs discards the suffix that matched regexp and searches the list again for another match. This “recursive extension stripping” is used for files which have multiple extensions, and the “outer” extension hides the “inner” one that actually specifies the right mode. For example, backup files and GPG-encrypted files with .gpg extension use this feature."
My understanding of this paragraph is that the outside mode-function should be called, and then subsequent mode-functions should be called after. Currently, only the inner-most matched suffix has its mode-function called.
I believe this was changed in this commit: https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=ad5faa424a5d2f0d67265906d21f7af98220df26
It looks like the (when mode (set-auto-mode-0 ...)) was moved from inside the (while name ...) to outside when the section was pulled into its own function. It's been four and a half years, so maybe it doesn't matter anymore, but if that's the case the manual should be updated; it would have saved me a couple hours of difficulty.
nat
[Message part 2 (text/html, inline)]
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#75961
; Package
emacs
.
(Fri, 31 Jan 2025 08:17:02 GMT)
Full text and
rfc822 format available.
Message #8 received at 75961 <at> debbugs.gnu.org (full text, mbox):
> Date: Fri, 31 Jan 2025 06:24:02 +0000
> From: nat chapman via "Bug reports for GNU Emacs,
> the Swiss army knife of text editors" <bug-gnu-emacs <at> gnu.org>
>
> On https://www.gnu.org/software/emacs/manual/html_node/emacs/Choosing-Modes.html, the manual says:
> "If the element has the form (regexp mode-function flag) and flag is non-nil, then after calling
> mode-function (if it is non-nil), Emacs discards the suffix that matched regexp and searches the list again
> for another match. This “recursive extension stripping” is used for files which have multiple extensions, and
> the “outer” extension hides the “inner” one that actually specifies the right mode. For example, backup files
> and GPG-encrypted files with .gpg extension use this feature."
>
> My understanding of this paragraph is that the outside mode-function should be called, and then
> subsequent mode-functions should be called after. Currently, only the inner-most matched suffix has its
> mode-function called.
>
> I believe this was changed in this commit:
> https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=ad5faa424a5d2f0d67265906d21f7af98220df26
>
> It looks like the (when mode (set-auto-mode-0 ...)) was moved from inside the (while name ...) to outside
> when the section was pulled into its own function. It's been four and a half years, so maybe it doesn't matter
> anymore, but if that's the case the manual should be updated; it would have saved me a couple hours of
> difficulty.
Thanks.
Do you have a recipe for showing some failure, preferably starting
from "emacs -Q", to behave according to the documentation, due to the
above change? If so, can you please show such a recipe?
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#75961
; Package
emacs
.
(Fri, 31 Jan 2025 17:25:04 GMT)
Full text and
rfc822 format available.
Message #11 received at 75961 <at> debbugs.gnu.org (full text, mbox):
On Friday, January 31st, 2025 at 02:16, Eli Zaretskii <eliz <at> gnu.org> wrote:
>
>
> > Date: Fri, 31 Jan 2025 06:24:02 +0000
>
> > From: nat chapman via "Bug reports for GNU Emacs,
> > the Swiss army knife of text editors" bug-gnu-emacs <at> gnu.org
> >
> > On https://www.gnu.org/software/emacs/manual/html_node/emacs/Choosing-Modes.html, the manual says:
> > "If the element has the form (regexp mode-function flag) and flag is non-nil, then after calling
> > mode-function (if it is non-nil), Emacs discards the suffix that matched regexp and searches the list again
> > for another match. This “recursive extension stripping” is used for files which have multiple extensions, and
> > the “outer” extension hides the “inner” one that actually specifies the right mode. For example, backup files
> > and GPG-encrypted files with .gpg extension use this feature."
> >
> > My understanding of this paragraph is that the outside mode-function should be called, and then
> > subsequent mode-functions should be called after. Currently, only the inner-most matched suffix has its
> > mode-function called.
> >
> > I believe this was changed in this commit:
> > https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=ad5faa424a5d2f0d67265906d21f7af98220df26
> >
> > It looks like the (when mode (set-auto-mode-0 ...)) was moved from inside the (while name ...) to outside
> > when the section was pulled into its own function. It's been four and a half years, so maybe it doesn't matter
> > anymore, but if that's the case the manual should be updated; it would have saved me a couple hours of
> > difficulty.
>
>
> Thanks.
>
> Do you have a recipe for showing some failure, preferably starting
> from "emacs -Q", to behave according to the documentation, due to the
> above change? If so, can you please show such a recipe?
emacs -Q --eval '(progn (define-derived-mode test-mode fundamental-mode "TEST" (message "Test mode called")) (add-to-list (quote auto-mode-alist) (quote ("\\.test$" test-mode t))))' file.html.test file.test
Buffer visiting file.html.test is in mhtml-mode, buffer visiting file.test is in fundamental mode, no message is emitted.
Using edebug to step through set-auto-mode--apply alist, (regexp mode-function t) matches correctly but the mode-function is never called.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#75961
; Package
emacs
.
(Sat, 15 Feb 2025 10:26:02 GMT)
Full text and
rfc822 format available.
Message #14 received at 75961 <at> debbugs.gnu.org (full text, mbox):
Ping! Stefan, any comments?
> Date: Fri, 31 Jan 2025 15:42:32 +0000
> From: nat chapman <nat.chapman <at> proton.me>
> Cc: Stefan Monnier <monnier <at> iro.umontreal.ca>, Tom Tromey <tom <at> tromey.com>, 75961 <at> debbugs.gnu.org
>
> On Friday, January 31st, 2025 at 02:16, Eli Zaretskii <eliz <at> gnu.org> wrote:
>
> >
> >
> > > Date: Fri, 31 Jan 2025 06:24:02 +0000
> >
> > > From: nat chapman via "Bug reports for GNU Emacs,
> > > the Swiss army knife of text editors" bug-gnu-emacs <at> gnu.org
> > >
> > > On https://www.gnu.org/software/emacs/manual/html_node/emacs/Choosing-Modes.html, the manual says:
> > > "If the element has the form (regexp mode-function flag) and flag is non-nil, then after calling
> > > mode-function (if it is non-nil), Emacs discards the suffix that matched regexp and searches the list again
> > > for another match. This “recursive extension stripping” is used for files which have multiple extensions, and
> > > the “outer” extension hides the “inner” one that actually specifies the right mode. For example, backup files
> > > and GPG-encrypted files with .gpg extension use this feature."
> > >
> > > My understanding of this paragraph is that the outside mode-function should be called, and then
> > > subsequent mode-functions should be called after. Currently, only the inner-most matched suffix has its
> > > mode-function called.
> > >
> > > I believe this was changed in this commit:
> > > https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=ad5faa424a5d2f0d67265906d21f7af98220df26
> > >
> > > It looks like the (when mode (set-auto-mode-0 ...)) was moved from inside the (while name ...) to outside
> > > when the section was pulled into its own function. It's been four and a half years, so maybe it doesn't matter
> > > anymore, but if that's the case the manual should be updated; it would have saved me a couple hours of
> > > difficulty.
> >
> >
> > Thanks.
> >
> > Do you have a recipe for showing some failure, preferably starting
> > from "emacs -Q", to behave according to the documentation, due to the
> > above change? If so, can you please show such a recipe?
>
> emacs -Q --eval '(progn (define-derived-mode test-mode fundamental-mode "TEST" (message "Test mode called")) (add-to-list (quote auto-mode-alist) (quote ("\\.test$" test-mode t))))' file.html.test file.test
>
> Buffer visiting file.html.test is in mhtml-mode, buffer visiting file.test is in fundamental mode, no message is emitted.
>
> Using edebug to step through set-auto-mode--apply alist, (regexp mode-function t) matches correctly but the mode-function is never called.
>
>
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#75961
; Package
emacs
.
(Sat, 15 Feb 2025 23:54:02 GMT)
Full text and
rfc822 format available.
Message #17 received at 75961 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
>> emacs -Q --eval '(progn (define-derived-mode test-mode fundamental-mode
>> "TEST" (message "Test mode called")) (add-to-list (quote auto-mode-alist)
>> (quote ("\\.test$" test-mode t))))' file.html.test file.test
>>
>> Buffer visiting file.html.test is in mhtml-mode, buffer visiting file.test
>> is in fundamental mode, no message is emitted.
Yup.
The patch below seems to do the trick. Any comment/objection?
Stefan
[auto-mode-alist.patch (text/x-diff, inline)]
diff --git a/lisp/files.el b/lisp/files.el
index a71d0c5c9d0..bf05939ebeb 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -3469,7 +3469,7 @@
If CASE-INSENSITIVE, the file system of file NAME is case-insensitive."
(let (mode)
(while name
- (setq mode
+ (let ((newmode
(if case-insensitive
;; Filesystem is case-insensitive.
(let ((case-fold-search t))
@@ -3482,14 +3482,24 @@
;; Fallback to case-insensitive match.
(and auto-mode-case-fold
(let ((case-fold-search t))
- (assoc-default name alist 'string-match))))))
- (if (and mode
- (not (functionp mode))
- (consp mode)
- (cadr mode))
- (setq mode (car mode)
+ (assoc-default name alist 'string-match)))))))
+ (when newmode
+ (when mode
+ ;; We had already found a mode but in a (REGEXP MODE t)
+ ;; entry, so we still have to run MODE. Let's do it now.
+ ;; FIXME: It's kind of ugly to run the function here.
+ ;; An alternative could be to return a list of functions and
+ ;; callers.
+ (set-auto-mode-0 mode t))
+ (setq mode newmode))
+ (if (and newmode
+ (not (functionp newmode))
+ (consp newmode)
+ (cadr newmode))
+ ;; It's a (REGEXP MODE t): Keep looking but remember the MODE.
+ (setq mode (car newmode)
name (substring name 0 (match-beginning 0)))
- (setq name nil)))
+ (setq name nil))))
mode))
(defun set-auto-mode--apply-alist (alist keep-mode-if-same dir-local)
diff --git a/test/lisp/files-tests.el b/test/lisp/files-tests.el
index 5e2c4eb2669..1e7e00ce1c0 100644
--- a/test/lisp/files-tests.el
+++ b/test/lisp/files-tests.el
@@ -1680,6 +1680,16 @@ files-tests-auto-mode-alist
(should-not (eq (files-tests--check-mode "gdbinit.5") #'gdb-script-mode))
(should-not (eq (files-tests--check-mode ".gdbinit.py.in") #'gdb-script-mode)))
+(ert-deftest files-tests--bug75961 ()
+ (let ((auto-mode-alist (cons '("\\.text\\'" text-mode t) auto-mode-alist)))
+ (with-temp-buffer
+ (setq buffer-file-name "foo.text")
+ (normal-mode)
+ (should (derived-mode-p 'text-mode))
+ (setq buffer-file-name "foo.html.text")
+ (normal-mode)
+ (should (derived-mode-p 'html-mode)))))
+
(defvar sh-shell)
(defun files-tests--check-shebang (shebang expected-mode &optional expected-dialect)
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#75961
; Package
emacs
.
(Sun, 16 Feb 2025 06:20:02 GMT)
Full text and
rfc822 format available.
Message #20 received at 75961 <at> debbugs.gnu.org (full text, mbox):
> From: Stefan Monnier <monnier <at> iro.umontreal.ca>
> Cc: nat chapman <nat.chapman <at> proton.me>, 75961 <at> debbugs.gnu.org,
> tom <at> tromey.com
> Date: Sat, 15 Feb 2025 18:53:16 -0500
>
> >> emacs -Q --eval '(progn (define-derived-mode test-mode fundamental-mode
> >> "TEST" (message "Test mode called")) (add-to-list (quote auto-mode-alist)
> >> (quote ("\\.test$" test-mode t))))' file.html.test file.test
> >>
> >> Buffer visiting file.html.test is in mhtml-mode, buffer visiting file.test
> >> is in fundamental mode, no message is emitted.
>
> Yup.
>
> The patch below seems to do the trick. Any comment/objection?
Not from me.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#75961
; Package
emacs
.
(Sun, 16 Feb 2025 14:52:01 GMT)
Full text and
rfc822 format available.
Message #23 received at 75961 <at> debbugs.gnu.org (full text, mbox):
On Sunday, February 16th, 2025 at 00:19, Eli Zaretskii <eliz <at> gnu.org> wrote:
>
>
> > From: Stefan Monnier monnier <at> iro.umontreal.ca
>
> > Cc: nat chapman nat.chapman <at> proton.me, 75961 <at> debbugs.gnu.org,
> > tom <at> tromey.com
> > Date: Sat, 15 Feb 2025 18:53:16 -0500
> >
> > > > emacs -Q --eval '(progn (define-derived-mode test-mode fundamental-mode
> > > > "TEST" (message "Test mode called")) (add-to-list (quote auto-mode-alist)
> > > > (quote ("\\.test$" test-mode t))))' file.html.test file.test
> > > >
> > > > Buffer visiting file.html.test is in mhtml-mode, buffer visiting file.test
> > > > is in fundamental mode, no message is emitted.
> >
> > Yup.
> >
> > The patch below seems to do the trick. Any comment/objection?
>
>
> Not from me.
I'm not an expert, but the supplied test doesn't appear to check that text-mode is actually called when the mode falls through. I suspect that test would succeed even if you didn't make any change to set-auto-mode--apply alist, so I'm not sure it's useful (or at least not sufficient; maybe there wasn't a test of the (regexp mode t) behavior at all before).
Reply sent
to
Stefan Monnier <monnier <at> iro.umontreal.ca>
:
You have taken responsibility.
(Sun, 16 Feb 2025 16:55:01 GMT)
Full text and
rfc822 format available.
Notification sent
to
nat chapman <nat.chapman <at> proton.me>
:
bug acknowledged by developer.
(Sun, 16 Feb 2025 16:55:01 GMT)
Full text and
rfc822 format available.
Message #28 received at 75961-done <at> debbugs.gnu.org (full text, mbox):
> I'm not an expert, but the supplied test doesn't appear to check that
> text-mode is actually called when the mode falls through. I suspect
> that test would succeed even if you didn't make any change to
> set-auto-mode--apply alist,
The test does fail in Emacs-30 because `foo.text` is left in
`fundamental-mode` there, so it is useful.
But you're right that in the case of `foo.html.text` I did not bother to
check if `text-mode` was called before calling the html mode.
I pushed the patch with an improved test which fixes that weakness, thanks.
BTW, I pushed this to `master`, but as mentioned the bug is present in
Emacs-30 as well. Not sure it's worth taking the risk in `emacs-30`.
Stefan
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#75961
; Package
emacs
.
(Sun, 16 Feb 2025 19:19:02 GMT)
Full text and
rfc822 format available.
Message #31 received at 75961-done <at> debbugs.gnu.org (full text, mbox):
> From: Stefan Monnier <monnier <at> iro.umontreal.ca>
> Cc: Eli Zaretskii <eliz <at> gnu.org>, 75961-done <at> debbugs.gnu.org, tom <at> tromey.com
> Date: Sun, 16 Feb 2025 11:54:36 -0500
>
> BTW, I pushed this to `master`, but as mentioned the bug is present in
> Emacs-30 as well. Not sure it's worth taking the risk in `emacs-30`.
I don't think it's worth risking that.
bug archived.
Request was from
Debbugs Internal Request <help-debbugs <at> gnu.org>
to
internal_control <at> debbugs.gnu.org
.
(Mon, 17 Mar 2025 11:24:27 GMT)
Full text and
rfc822 format available.
This bug report was last modified 96 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.