GNU bug report logs - #74964
31.0.50 master; .dir-locals.el vars does not work with changing major mode

Previous Next

Package: emacs;

Reported by: Yikai Zhao <yikai <at> z1k.dev>

Date: Thu, 19 Dec 2024 07:55:02 UTC

Severity: normal

Found in version 31.0.50

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 74964 in the body.
You can then email your comments to 74964 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#74964; Package emacs. (Thu, 19 Dec 2024 07:55:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Yikai Zhao <yikai <at> z1k.dev>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Thu, 19 Dec 2024 07:55:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Yikai Zhao <yikai <at> z1k.dev>
To: bug-gnu-emacs <at> gnu.org
Subject: 31.0.50 master;
 .dir-locals.el vars does not work with changing major mode
Date: Thu, 19 Dec 2024 15:53:58 +0800
How to reproduce:

With following content in /tmp/test/.dir-locals.el:

((nil . ((my/test . "test")))
 (c-mode . ((eval . (when (eq major-mode 'c-mode)
                      (c++-mode))))))
;; I use this code because I want my projects' .h files always opened
in c++ mode

Then open a new file test.c in the folder.

Expected behavior: my/test variable is set.
Actual behavior: my/test variable is not set.

Emacs 29 and 30 does give me the expected result.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#74964; Package emacs. (Fri, 20 Dec 2024 16:22:02 GMT) Full text and rfc822 format available.

Message #8 received at 74964 <at> debbugs.gnu.org (full text, mbox):

From: Robert Pluim <rpluim <at> gmail.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: Yikai Zhao <yikai <at> z1k.dev>, 74964 <at> debbugs.gnu.org
Subject: Re: bug#74964: 31.0.50 master; .dir-locals.el vars does not work
 with changing major mode
Date: Fri, 20 Dec 2024 17:20:10 +0100
>>>>> On Thu, 19 Dec 2024 15:53:58 +0800, Yikai Zhao <yikai <at> z1k.dev> said:

    Yikai> How to reproduce:
    Yikai> With following content in /tmp/test/.dir-locals.el:

    Yikai> ((nil . ((my/test . "test")))
    Yikai>  (c-mode . ((eval . (when (eq major-mode 'c-mode)
    Yikai>                       (c++-mode))))))
    Yikai> ;; I use this code because I want my projects' .h files always opened
    Yikai> in c++ mode

    Yikai> Then open a new file test.c in the folder.

    Yikai> Expected behavior: my/test variable is set.
    Yikai> Actual behavior: my/test variable is not set.

    Yikai> Emacs 29 and 30 does give me the expected result.

Stefan, reverting f713258416f (Bug#74349) fixes this

Robert
-- 




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#74964; Package emacs. (Sun, 22 Dec 2024 03:37:01 GMT) Full text and rfc822 format available.

Message #11 received at 74964 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Robert Pluim <rpluim <at> gmail.com>
Cc: Yikai Zhao <yikai <at> z1k.dev>, 74964 <at> debbugs.gnu.org
Subject: Re: bug#74964: 31.0.50 master; .dir-locals.el vars does not work
 with changing major mode
Date: Sat, 21 Dec 2024 22:36:07 -0500
>>>>>> On Thu, 19 Dec 2024 15:53:58 +0800, Yikai Zhao <yikai <at> z1k.dev> said:
>
>     Yikai> How to reproduce:
>     Yikai> With following content in /tmp/test/.dir-locals.el:
>
>     Yikai> ((nil . ((my/test . "test")))
>     Yikai>  (c-mode . ((eval . (when (eq major-mode 'c-mode)
>     Yikai>                       (c++-mode))))))
>     Yikai> ;; I use this code because I want my projects' .h files always opened
>     Yikai> in c++ mode

We need to offer our users a better solution than such a hack.
E.g. a dir-local way to set `auto-mode-alist` and/or `major-mode-remap-alist`.

> Stefan, reverting f713258416f (Bug#74349) fixes this

How 'bout a patch like the one below?


        Stefan


diff --git a/lisp/files.el b/lisp/files.el
index c92fc0608dd..594ee83efbe 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -4488,11 +4485,15 @@ hack-one-local-variable--obsolete
                      (substitute-command-keys instead)
                    (format-message "use `%s' instead" instead)))))))
 
+(defvar hack-local-variables--inhibit nil
+  "List of file/dir local variables to ignore.")
+
 (defun hack-one-local-variable (var val)
   "Set local variable VAR with value VAL.
 If VAR is `mode', call `VAL-mode' as a function unless it's
 already the major mode."
   (pcase var
+    ((guard (memq var hack-local-variables--inhibit)) nil)
     ('mode
      (let ((mode (intern (concat (downcase (symbol-name val))
                                  "-mode"))))
@@ -4500,7 +4501,8 @@ hack-one-local-variable
     ('eval
      (pcase val
        (`(add-hook ',hook . ,_) (hack-one-local-variable--obsolete hook)))
-     (let ((enable-local-variables nil)) ;FIXME: Should be buffer-local!
+     (let ((hack-local-variables--inhibit ;; FIXME: Should be buffer-local!
+            (cons 'eval hack-local-variables--inhibit)))
        (save-excursion (eval val t))))
     (_
      (hack-one-local-variable--obsolete var)





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#74964; Package emacs. (Sat, 04 Jan 2025 11:43:01 GMT) Full text and rfc822 format available.

Message #14 received at 74964 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>, yikai <at> z1k.dev
Cc: rpluim <at> gmail.com, 74964 <at> debbugs.gnu.org
Subject: Re: bug#74964: 31.0.50 master;
 .dir-locals.el vars does not work with changing major mode
Date: Sat, 04 Jan 2025 13:42:11 +0200
Ping!

> Cc: Yikai Zhao <yikai <at> z1k.dev>, 74964 <at> debbugs.gnu.org
> Date: Sat, 21 Dec 2024 22:36:07 -0500
> From:  Stefan Monnier via "Bug reports for GNU Emacs,
>  the Swiss army knife of text editors" <bug-gnu-emacs <at> gnu.org>
> 
> >>>>>> On Thu, 19 Dec 2024 15:53:58 +0800, Yikai Zhao <yikai <at> z1k.dev> said:
> >
> >     Yikai> How to reproduce:
> >     Yikai> With following content in /tmp/test/.dir-locals.el:
> >
> >     Yikai> ((nil . ((my/test . "test")))
> >     Yikai>  (c-mode . ((eval . (when (eq major-mode 'c-mode)
> >     Yikai>                       (c++-mode))))))
> >     Yikai> ;; I use this code because I want my projects' .h files always opened
> >     Yikai> in c++ mode
> 
> We need to offer our users a better solution than such a hack.
> E.g. a dir-local way to set `auto-mode-alist` and/or `major-mode-remap-alist`.
> 
> > Stefan, reverting f713258416f (Bug#74349) fixes this
> 
> How 'bout a patch like the one below?
> 
> 
>         Stefan
> 
> 
> diff --git a/lisp/files.el b/lisp/files.el
> index c92fc0608dd..594ee83efbe 100644
> --- a/lisp/files.el
> +++ b/lisp/files.el
> @@ -4488,11 +4485,15 @@ hack-one-local-variable--obsolete
>                       (substitute-command-keys instead)
>                     (format-message "use `%s' instead" instead)))))))
>  
> +(defvar hack-local-variables--inhibit nil
> +  "List of file/dir local variables to ignore.")
> +
>  (defun hack-one-local-variable (var val)
>    "Set local variable VAR with value VAL.
>  If VAR is `mode', call `VAL-mode' as a function unless it's
>  already the major mode."
>    (pcase var
> +    ((guard (memq var hack-local-variables--inhibit)) nil)
>      ('mode
>       (let ((mode (intern (concat (downcase (symbol-name val))
>                                   "-mode"))))
> @@ -4500,7 +4501,8 @@ hack-one-local-variable
>      ('eval
>       (pcase val
>         (`(add-hook ',hook . ,_) (hack-one-local-variable--obsolete hook)))
> -     (let ((enable-local-variables nil)) ;FIXME: Should be buffer-local!
> +     (let ((hack-local-variables--inhibit ;; FIXME: Should be buffer-local!
> +            (cons 'eval hack-local-variables--inhibit)))
>         (save-excursion (eval val t))))
>      (_
>       (hack-one-local-variable--obsolete var)
> 
> 
> 
> 
> 




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#74964; Package emacs. (Sun, 05 Jan 2025 08:03:02 GMT) Full text and rfc822 format available.

Message #17 received at 74964 <at> debbugs.gnu.org (full text, mbox):

From: Yikai Zhao <yikai <at> z1k.dev>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: rpluim <at> gmail.com, 74964 <at> debbugs.gnu.org,
 Stefan Monnier <monnier <at> iro.umontreal.ca>
Subject: Re: bug#74964: 31.0.50 master; .dir-locals.el vars does not work with
 changing major mode
Date: Sun, 5 Jan 2025 16:02:06 +0800
This patch does fix the issue for me. Thanks.

On Sat, Jan 4, 2025 at 7:42 PM Eli Zaretskii <eliz <at> gnu.org> wrote:
>
> Ping!
>
> > Cc: Yikai Zhao <yikai <at> z1k.dev>, 74964 <at> debbugs.gnu.org
> > Date: Sat, 21 Dec 2024 22:36:07 -0500
> > From:  Stefan Monnier via "Bug reports for GNU Emacs,
> >  the Swiss army knife of text editors" <bug-gnu-emacs <at> gnu.org>
> >
> > >>>>>> On Thu, 19 Dec 2024 15:53:58 +0800, Yikai Zhao <yikai <at> z1k.dev> said:
> > >
> > >     Yikai> How to reproduce:
> > >     Yikai> With following content in /tmp/test/.dir-locals.el:
> > >
> > >     Yikai> ((nil . ((my/test . "test")))
> > >     Yikai>  (c-mode . ((eval . (when (eq major-mode 'c-mode)
> > >     Yikai>                       (c++-mode))))))
> > >     Yikai> ;; I use this code because I want my projects' .h files always opened
> > >     Yikai> in c++ mode
> >
> > We need to offer our users a better solution than such a hack.
> > E.g. a dir-local way to set `auto-mode-alist` and/or `major-mode-remap-alist`.
> >
> > > Stefan, reverting f713258416f (Bug#74349) fixes this
> >
> > How 'bout a patch like the one below?
> >
> >
> >         Stefan
> >
> >
> > diff --git a/lisp/files.el b/lisp/files.el
> > index c92fc0608dd..594ee83efbe 100644
> > --- a/lisp/files.el
> > +++ b/lisp/files.el
> > @@ -4488,11 +4485,15 @@ hack-one-local-variable--obsolete
> >                       (substitute-command-keys instead)
> >                     (format-message "use `%s' instead" instead)))))))
> >
> > +(defvar hack-local-variables--inhibit nil
> > +  "List of file/dir local variables to ignore.")
> > +
> >  (defun hack-one-local-variable (var val)
> >    "Set local variable VAR with value VAL.
> >  If VAR is `mode', call `VAL-mode' as a function unless it's
> >  already the major mode."
> >    (pcase var
> > +    ((guard (memq var hack-local-variables--inhibit)) nil)
> >      ('mode
> >       (let ((mode (intern (concat (downcase (symbol-name val))
> >                                   "-mode"))))
> > @@ -4500,7 +4501,8 @@ hack-one-local-variable
> >      ('eval
> >       (pcase val
> >         (`(add-hook ',hook . ,_) (hack-one-local-variable--obsolete hook)))
> > -     (let ((enable-local-variables nil)) ;FIXME: Should be buffer-local!
> > +     (let ((hack-local-variables--inhibit ;; FIXME: Should be buffer-local!
> > +            (cons 'eval hack-local-variables--inhibit)))
> >         (save-excursion (eval val t))))
> >      (_
> >       (hack-one-local-variable--obsolete var)
> >
> >
> >
> >
> >




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#74964; Package emacs. (Sun, 05 Jan 2025 09:12:02 GMT) Full text and rfc822 format available.

Message #20 received at 74964 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Yikai Zhao <yikai <at> z1k.dev>
Cc: rpluim <at> gmail.com, 74964 <at> debbugs.gnu.org, monnier <at> iro.umontreal.ca
Subject: Re: bug#74964: 31.0.50 master; .dir-locals.el vars does not work with
 changing major mode
Date: Sun, 05 Jan 2025 11:11:45 +0200
> From: Yikai Zhao <yikai <at> z1k.dev>
> Date: Sun, 5 Jan 2025 16:02:06 +0800
> Cc: Stefan Monnier <monnier <at> iro.umontreal.ca>, rpluim <at> gmail.com, 74964 <at> debbugs.gnu.org
> 
> This patch does fix the issue for me. Thanks.

Thanks for testing.  Stefan, please install, and thanks.




Reply sent to Stefan Monnier <monnier <at> iro.umontreal.ca>:
You have taken responsibility. (Sun, 05 Jan 2025 15:06:02 GMT) Full text and rfc822 format available.

Notification sent to Yikai Zhao <yikai <at> z1k.dev>:
bug acknowledged by developer. (Sun, 05 Jan 2025 15:06:02 GMT) Full text and rfc822 format available.

Message #25 received at 74964-done <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: rpluim <at> gmail.com, Yikai Zhao <yikai <at> z1k.dev>, 74964-done <at> debbugs.gnu.org
Subject: Re: bug#74964: 31.0.50 master; .dir-locals.el vars does not work
 with changing major mode
Date: Sun, 05 Jan 2025 10:05:06 -0500
>> This patch does fix the issue for me. Thanks.

Thank you for confirming!

> Thanks for testing.  Stefan, please install, and thanks.

Closing,


        Stefan





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#74964; Package emacs. (Thu, 16 Jan 2025 08:31:01 GMT) Full text and rfc822 format available.

Message #28 received at 74964-done <at> debbugs.gnu.org (full text, mbox):

From: Yikai Zhao <yikai <at> z1k.dev>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: Eli Zaretskii <eliz <at> gnu.org>, rpluim <at> gmail.com, 74964-done <at> debbugs.gnu.org
Subject: Re: bug#74964: 31.0.50 master; .dir-locals.el vars does not work with
 changing major mode
Date: Thu, 16 Jan 2025 16:29:40 +0800
Hi Stefan,

Sorry to bring this back again.

The original issue is indeed fixed, however there's another related
issue remaining. With the following .dir-locals.el code:

((nil . ((my/test . "test")
         (eval . (setq-local my/test2 "test2"))))
 (c-mode . ((eval . (when (eq major-mode 'c-mode)
                      (c++-mode))))))

The `my/test` variable will be set after your fix. But the `my/test2`
variable is still not set.

On Sun, Jan 5, 2025 at 11:05 PM Stefan Monnier <monnier <at> iro.umontreal.ca> wrote:
>
> >> This patch does fix the issue for me. Thanks.
>
> Thank you for confirming!
>
> > Thanks for testing.  Stefan, please install, and thanks.
>
> Closing,
>
>
>         Stefan
>




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#74964; Package emacs. (Fri, 17 Jan 2025 04:35:02 GMT) Full text and rfc822 format available.

Message #31 received at 74964 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Yikai Zhao <yikai <at> z1k.dev>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 74964 <at> debbugs.gnu.org, rpluim <at> gmail.com,
 74964-done <at> debbugs.gnu.org
Subject: Re: bug#74964: 31.0.50 master; .dir-locals.el vars does not work
 with changing major mode
Date: Thu, 16 Jan 2025 23:34:34 -0500
[Message part 1 (text/plain, inline)]
> ((nil . ((my/test . "test")
>          (eval . (setq-local my/test2 "test2"))))
>  (c-mode . ((eval . (when (eq major-mode 'c-mode)
>                       (c++-mode))))))

[ Sigh!  This is starting to make me remember the ugly hacks I added to
  try and avoid inf-loops in my type checker.  ]

How 'bout the patch below?


        Stefan
[files.patch (text/x-diff, inline)]
diff --git a/lisp/files.el b/lisp/files.el
index e9f69fcd33c..9981e7083c3 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -4490,15 +4490,15 @@ hack-one-local-variable--obsolete
                      (substitute-command-keys instead)
                    (format-message "use `%s' instead" instead)))))))
 
-(defvar hack-local-variables--inhibit nil
-  "List of file/dir local variables to ignore.")
+(defvar hack-local-variables--inhibit-eval nil
+  "List of `eval' forms to ignore in file/dir local variables.")
 
 (defun hack-one-local-variable (var val)
   "Set local variable VAR with value VAL.
 If VAR is `mode', call `VAL-mode' as a function unless it's
 already the major mode."
   (pcase var
-    ((guard (memq var hack-local-variables--inhibit)) nil)
+    ((and 'eval (guard (memq val hack-local-variables--inhibit-eval))) nil)
     ('mode
      (let ((mode (intern (concat (downcase (symbol-name val))
                                  "-mode"))))
@@ -4506,8 +4506,8 @@ hack-one-local-variable
     ('eval
      (pcase val
        (`(add-hook ',hook . ,_) (hack-one-local-variable--obsolete hook)))
-     (let ((hack-local-variables--inhibit ;; FIXME: Should be buffer-local!
-            (cons 'eval hack-local-variables--inhibit)))
+     (let ((hack-local-variables--inhibit-eval ;; FIXME: Should be buffer-local!
+            (cons val hack-local-variables--inhibit-eval)))
        (save-excursion (eval val t))))
     (_
      (hack-one-local-variable--obsolete var)

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#74964; Package emacs. (Fri, 17 Jan 2025 04:35:03 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#74964; Package emacs. (Fri, 17 Jan 2025 05:56:01 GMT) Full text and rfc822 format available.

Message #37 received at 74964 <at> debbugs.gnu.org (full text, mbox):

From: Yikai Zhao <yikai <at> z1k.dev>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 74964 <at> debbugs.gnu.org, rpluim <at> gmail.com,
 74964-done <at> debbugs.gnu.org
Subject: Re: bug#74964: 31.0.50 master; .dir-locals.el vars does not work with
 changing major mode
Date: Fri, 17 Jan 2025 13:55:15 +0800
Thanks! It fixes the issue for me.

On Fri, Jan 17, 2025 at 12:34 PM Stefan Monnier
<monnier <at> iro.umontreal.ca> wrote:
>
> > ((nil . ((my/test . "test")
> >          (eval . (setq-local my/test2 "test2"))))
> >  (c-mode . ((eval . (when (eq major-mode 'c-mode)
> >                       (c++-mode))))))
>
> [ Sigh!  This is starting to make me remember the ugly hacks I added to
>   try and avoid inf-loops in my type checker.  ]
>
> How 'bout the patch below?
>
>
>         Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#74964; Package emacs. (Fri, 17 Jan 2025 05:56:02 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#74964; Package emacs. (Fri, 17 Jan 2025 13:45:01 GMT) Full text and rfc822 format available.

Message #43 received at 74964-done <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Yikai Zhao <yikai <at> z1k.dev>
Cc: Eli Zaretskii <eliz <at> gnu.org>, rpluim <at> gmail.com, 74964-done <at> debbugs.gnu.org
Subject: Re: bug#74964: 31.0.50 master; .dir-locals.el vars does not work
 with changing major mode
Date: Fri, 17 Jan 2025 08:44:31 -0500
> Thanks! It fixes the issue for me.

Great, pushed to `master`.


        Stefan





bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Sat, 15 Feb 2025 12:24:08 GMT) Full text and rfc822 format available.

This bug report was last modified 122 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.