GNU bug report logs - #78608
31.0.50; Todo mode bug revealed by setq-default change

Previous Next

Package: emacs;

Reported by: Stephen Berman <stephen.berman <at> gmx.net>

Date: Tue, 27 May 2025 15:55:02 UTC

Severity: normal

Found in version 31.0.50

Done: Stephen Berman <stephen.berman <at> gmx.net>

To reply to this bug, email your comments to 78608 AT debbugs.gnu.org.
There is no need to reopen the bug first.

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#78608; Package emacs. (Tue, 27 May 2025 15:55:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Stephen Berman <stephen.berman <at> gmx.net>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Tue, 27 May 2025 15:55:02 GMT) Full text and rfc822 format available.

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

From: Stephen Berman <stephen.berman <at> gmx.net>
To: bug-gnu-emacs <at> gnu.org
Subject: 31.0.50; Todo mode bug revealed by setq-default change
Date: Tue, 27 May 2025 17:53:24 +0200
[Message part 1 (text/plain, inline)]
TL;DR: There is a bug in the command `todo-jump-to-category' from
todo-mode.el that manifests itself differently in master and in earlier
versions of Emacs due to the change to `setq-default' made in commit
f3e0bdf1b98.  A patch that fixes both manifestations is provided.

Background: As documented, `todo-jump-to-category' visits a
user-specified category of a given Todo file, and if the specified
category does not exist in the Todo file, the user is prompted whether
to add the category to the file, and if confirmed, then by default there
is a further prompt to add the first Todo item to the category.  The
command can also be invoked from outside of a todo-mode buffer, but
since it is not autoloaded, todo-mode must be loaded before it can be so
invoked.

Problem (master): Recently, I started observing aberrant behavior when
invoking `todo-jump-to-category' before visiting any Todo file in
todo-mode (I load todo-mode in my init file): upon jumping to an
existing category, I get prompted to add a Todo item, although the
category is not new.  To reproduce this:

0. HOME=/tmp/${USER} emacs -Q  (start Emacs in a clean environment)
1. Type `M-x todo-show' and at the prompt type "test RET test1 RET item1
   RET" to initialize the Todo file "test" with the category "test1"
   containing the item "item1".  The current buffer displays that
   category in todo-mode.
2. (Sanity check) Type `q' to save the newly created Todo file and bury
   the buffer, so that the current buffer is no longer a todo-mode
   buffer.  Then type `M-x todo-jump-to-category': this switches the
   buffer back to the todo-mode buffer displaying the category "test1"
   with the item "item1"; there is no prompt for a Todo item.
3. Kill the Emacs session and restart as in step 0.
4. Type `M-x load-library' and at the prompt enter `todo-mode RET'.
5. Type `M-x todo-jump-to-category' and at the prompt enter "test1" (or
   type TAB, which automatically inserts "test1" after the prompt, since
   it's the only category in the Todo file).
=> The category "test1" is displayed but now the minibuffer displays the
   prompt "Todo item: ".

Solution: The following patch fixes this, so that at step 5 the category
is displayed and there is no prompt to add an item.

[todo-jump-to-category.diff (text/x-patch, attachment)]
[Message part 3 (text/plain, inline)]
Analysis: The current code in `todo-jump-to-category' compares, via the
buffer-local variable `todo-categories', the length of the list of Todo
categories in the specified Todo file before and after specifying the
category to jump to.  When `todo-jump-to-category' is invoked outside of
todo-mode, `todo-categories' is always nil, so its length is zero, but
when the user specifies the category to jump to, `todo-categories' gets
(via `todo-read-category' and functions called from it) a non-nil list
value, so the post-specification length of `todo-categories' is greater
than the pre-specification length, and together with the non-nil default
value of `todo-add-item-if-new-category', this results in the prompt for
a Todo item.

The above patch eliminates the before and after comparison involving
`todo-categories' and replaces it by a check of whether there are any
items in the category, since an existing category should always have at
least one item (perhaps done or archived).

Trigger: After I debugged the problem on master and came up with the
above patch, I wondered why I had never encountered the problem until
recently, because most of the code involved hasn't changed since the
current version of Todo mode was added to the Emacs repo twelve years
ago.  So I executed the above recipe in the emacs-30 branch and was
surprised to find that the bug does not happen there: after step 5, the
category "test1" is displayed and there is no prompt for a Todo item.
Debugging showed that this is because the value of `todo-categories' is
nil in emacs-30, both before and after specifying a category to jump to.
This difference between emacs-30 and master manifests itself in the
function `todo-category-completions' (called from `todo-read-category')
around the following code:

(with-current-buffer (find-file-noselect f 'nowarn)
  [...]
  (todo-mode)
  [...])

In both master and emacs-30, before entering this sexp, the buffer-local
value of `todo-categories' is nil, but after invoking `todo-mode' its
value (for the buffer visiting the Todo file `f') becomes non-nil.
After leaving the `with-current-buffer' form, `todo-categories' retains
its non-nil value in master, but reverts to nil in emacs-30.  The mode
function `todo-mode' calls `todo-modes-set-3', which contains the form
`(setq-local todo-categories (todo-set-categories))'.  This led me to
commit f3e0bdf1b98, and indeed, when I undo that change in master, the
problematic prompt on calling `todo-jump-to-category' does not happen.

Problem (pre-master): Then I tested invoking `todo-jump-to-category'
from outside of a todo-mode buffer and specifying a non-existing
category, and saw the same pattern, which, however, now reverses the
problem status: the new (empty) category is displayed and there is the
now expected prompt for a Todo item in master but, now wrongly, not in
emacs-30; thus, in this case the behavior in emacs-30 (and earlier)
contradicts the documentation.  To reproduce, carry out the above recipe
(in master and in emacs-30), but in step 5 enter "test2" at the prompt
instead of "test1".  (When I implemented `todo-jump-to-category', I
apparently failed to test this case and haven't made use of it since.)

Applying the above patch to emacs-30 also fixes this problem, and with
the patch the other case (specifying an existing category) still works
correctly in emacs-30.  The fact that the latter case also works
correctly in emacs-30 without the patch is evidently due to the
problematic behavior of `setq-local' fixed by f3e0bdf1b98.  The patch
has a narrow scope, so I think it's safe enough to commit to emacs-30,
even though the bug there is not a regression; but if that's not
acceptable, I'll commit it to master.


In GNU Emacs 31.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version
 3.24.49, cairo version 1.18.4) of 2025-05-24 built on strobelfs2
Repository revision: 492adf20b91520e96fb198e6e936e3145359c43b
Repository branch: master
Windowing system distributor 'The X.Org Foundation', version 11.0.12101016
System Description: Linux From Scratch r12.3-20

Configured using:
 'configure -C 'CFLAGS=-Og -g3' PKG_CONFIG_PATH=/opt/qt6/lib/pkgconfig'

Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG
LCMS2 LIBSYSTEMD LIBXML2 MODULES NATIVE_COMP NOTIFY INOTIFY PDUMPER PNG
RSVG SECCOMP SOUND SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS TREE_SITTER
WEBP X11 XDBE XIM XINERAMA XINPUT2 XPM XRANDR GTK3 ZLIB

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78608; Package emacs. (Wed, 28 May 2025 10:47:01 GMT) Full text and rfc822 format available.

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: Stephen Berman <stephen.berman <at> gmx.net>,
 Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 78608 <at> debbugs.gnu.org
Subject: Re: bug#78608: 31.0.50; Todo mode bug revealed by setq-default change
Date: Wed, 28 May 2025 13:45:33 +0300
> Date: Tue, 27 May 2025 17:53:24 +0200
> From:  Stephen Berman via "Bug reports for GNU Emacs,
>  the Swiss army knife of text editors" <bug-gnu-emacs <at> gnu.org>
> 
> Trigger: After I debugged the problem on master and came up with the
> above patch, I wondered why I had never encountered the problem until
> recently, because most of the code involved hasn't changed since the
> current version of Todo mode was added to the Emacs repo twelve years
> ago.  So I executed the above recipe in the emacs-30 branch and was
> surprised to find that the bug does not happen there: after step 5, the
> category "test1" is displayed and there is no prompt for a Todo item.
> Debugging showed that this is because the value of `todo-categories' is
> nil in emacs-30, both before and after specifying a category to jump to.
> This difference between emacs-30 and master manifests itself in the
> function `todo-category-completions' (called from `todo-read-category')
> around the following code:
> 
> (with-current-buffer (find-file-noselect f 'nowarn)
>   [...]
>   (todo-mode)
>   [...])
> 
> In both master and emacs-30, before entering this sexp, the buffer-local
> value of `todo-categories' is nil, but after invoking `todo-mode' its
> value (for the buffer visiting the Todo file `f') becomes non-nil.
> After leaving the `with-current-buffer' form, `todo-categories' retains
> its non-nil value in master, but reverts to nil in emacs-30.  The mode
> function `todo-mode' calls `todo-modes-set-3', which contains the form
> `(setq-local todo-categories (todo-set-categories))'.  This led me to
> commit f3e0bdf1b98, and indeed, when I undo that change in master, the
> problematic prompt on calling `todo-jump-to-category' does not happen.

Stefan, I think this means we need to call out this change in NEWS as
an incompatible change (unless you think there's a bug in that change
which needs to be fixed, and will make this change compatible).

> Problem (pre-master): Then I tested invoking `todo-jump-to-category'
> from outside of a todo-mode buffer and specifying a non-existing
> category, and saw the same pattern, which, however, now reverses the
> problem status: the new (empty) category is displayed and there is the
> now expected prompt for a Todo item in master but, now wrongly, not in
> emacs-30; thus, in this case the behavior in emacs-30 (and earlier)
> contradicts the documentation.  To reproduce, carry out the above recipe
> (in master and in emacs-30), but in step 5 enter "test2" at the prompt
> instead of "test1".  (When I implemented `todo-jump-to-category', I
> apparently failed to test this case and haven't made use of it since.)
> 
> Applying the above patch to emacs-30 also fixes this problem, and with
> the patch the other case (specifying an existing category) still works
> correctly in emacs-30.  The fact that the latter case also works
> correctly in emacs-30 without the patch is evidently due to the
> problematic behavior of `setq-local' fixed by f3e0bdf1b98.  The patch
> has a narrow scope, so I think it's safe enough to commit to emacs-30,
> even though the bug there is not a regression; but if that's not
> acceptable, I'll commit it to master.

I'm okay with committing this to emacs-30.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78608; Package emacs. (Wed, 28 May 2025 15:06:02 GMT) Full text and rfc822 format available.

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

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: Stephen Berman <stephen.berman <at> gmx.net>, 78608 <at> debbugs.gnu.org
Subject: Re: bug#78608: 31.0.50; Todo mode bug revealed by setq-default change
Date: Wed, 28 May 2025 11:05:08 -0400
> Stefan, I think this means we need to call out this change in NEWS as
> an incompatible change (unless you think there's a bug in that change
> which needs to be fixed, and will make this change compatible).

Would the patch below be OK?
Or should I add a link to https://xkcd.com/1172/ ?  🙂


        Stefan


diff --git a/etc/NEWS b/etc/NEWS
index 33b042720b5..1bbad5a2e5e 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -2139,6 +2139,14 @@ enabled for files named "go.work".
 
 * Incompatible Lisp Changes in Emacs 31.1
 
+** 'setq-local' computes the value before making the variable local.
+The previous code made the variable buffer local before
+computing the value to assign to it.
+This bug fix is a subtle change to the semantics which should make
+no difference to the vast majority of uses but can occasionally affect
+code in surprising ways if the computation of the value refers to the
+variable.
+
 ** Nested backquotes are not supported any more in Pcase patterns.
 
 ---





Reply sent to Stephen Berman <stephen.berman <at> gmx.net>:
You have taken responsibility. (Wed, 28 May 2025 15:22:02 GMT) Full text and rfc822 format available.

Notification sent to Stephen Berman <stephen.berman <at> gmx.net>:
bug acknowledged by developer. (Wed, 28 May 2025 15:22:02 GMT) Full text and rfc822 format available.

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

From: Stephen Berman <stephen.berman <at> gmx.net>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: Stefan Monnier <monnier <at> iro.umontreal.ca>, 78608-done <at> debbugs.gnu.org
Subject: Re: bug#78608: 31.0.50; Todo mode bug revealed by setq-default change
Date: Wed, 28 May 2025 17:21:07 +0200
On Wed, 28 May 2025 13:45:33 +0300 Eli Zaretskii <eliz <at> gnu.org> wrote:

>> Date: Tue, 27 May 2025 17:53:24 +0200
>> From:  Stephen Berman via "Bug reports for GNU Emacs,
>>  the Swiss army knife of text editors" <bug-gnu-emacs <at> gnu.org>
[...]
>> Problem (pre-master): Then I tested invoking `todo-jump-to-category'
>> from outside of a todo-mode buffer and specifying a non-existing
>> category, and saw the same pattern, which, however, now reverses the
>> problem status: the new (empty) category is displayed and there is the
>> now expected prompt for a Todo item in master but, now wrongly, not in
>> emacs-30; thus, in this case the behavior in emacs-30 (and earlier)
>> contradicts the documentation.  To reproduce, carry out the above recipe
>> (in master and in emacs-30), but in step 5 enter "test2" at the prompt
>> instead of "test1".  (When I implemented `todo-jump-to-category', I
>> apparently failed to test this case and haven't made use of it since.)
>> 
>> Applying the above patch to emacs-30 also fixes this problem, and with
>> the patch the other case (specifying an existing category) still works
>> correctly in emacs-30.  The fact that the latter case also works
>> correctly in emacs-30 without the patch is evidently due to the
>> problematic behavior of `setq-local' fixed by f3e0bdf1b98.  The patch
>> has a narrow scope, so I think it's safe enough to commit to emacs-30,
>> even though the bug there is not a regression; but if that's not
>> acceptable, I'll commit it to master.
>
> I'm okay with committing this to emacs-30.

Thanks, done in commit 4507b6a9c75 and closing the bug.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78608; Package emacs. (Wed, 28 May 2025 15:55:02 GMT) Full text and rfc822 format available.

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: stephen.berman <at> gmx.net, 78608 <at> debbugs.gnu.org
Subject: Re: bug#78608: 31.0.50; Todo mode bug revealed by setq-default change
Date: Wed, 28 May 2025 18:53:50 +0300
> From: Stefan Monnier <monnier <at> iro.umontreal.ca>
> Cc: Stephen Berman <stephen.berman <at> gmx.net>,  78608 <at> debbugs.gnu.org
> Date: Wed, 28 May 2025 11:05:08 -0400
> 
>  * Incompatible Lisp Changes in Emacs 31.1
>  
> +** 'setq-local' computes the value before making the variable local.
> +The previous code made the variable buffer local before
> +computing the value to assign to it.
> +This bug fix is a subtle change to the semantics which should make
> +no difference to the vast majority of uses but can occasionally affect
> +code in surprising ways if the computation of the value refers to the
> +variable.

I think this should describe the case upon which Stephen stumbled:
code which uses setq-local inside a let-binding (perhaps an implicit
one, such as the one the various with-SOMETHING macros do), and
expects the buffer-local value to stay after the let-binding is
exited.

I'd remove the last sentence entirely, because it is not useful.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78608; Package emacs. (Wed, 28 May 2025 17:01:02 GMT) Full text and rfc822 format available.

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

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: stephen.berman <at> gmx.net, 78608 <at> debbugs.gnu.org
Subject: Re: bug#78608: 31.0.50; Todo mode bug revealed by setq-default change
Date: Wed, 28 May 2025 12:59:52 -0400
>>  * Incompatible Lisp Changes in Emacs 31.1
>>  
>> +** 'setq-local' computes the value before making the variable local.
>> +The previous code made the variable buffer local before
>> +computing the value to assign to it.
>> +This bug fix is a subtle change to the semantics which should make
>> +no difference to the vast majority of uses but can occasionally affect
>> +code in surprising ways if the computation of the value refers to the
>> +variable.
>
> I think this should describe the case upon which Stephen stumbled:
> code which uses setq-local inside a let-binding (perhaps an implicit
> one, such as the one the various with-SOMETHING macros do), and
> expects the buffer-local value to stay after the let-binding is
> exited.

Maybe you should write it, then because you seem to understand that case
better than I (I did look at the code to try and figure out what was the
specific origin of the problem but .. failed).  But note that it's only
one case that can be affected, there are others.

> I'd remove the last sentence entirely, because it is not useful.

I wrote it as a more generic description: the todo code is but one case
where the behavior difference can show up.  Maybe it's too generic, but
I don't know how to be more specific without being *too* specific
(i.e. fail to include cases which are affected).


        Stefan





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78608; Package emacs. (Wed, 28 May 2025 18:29:02 GMT) Full text and rfc822 format available.

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: stephen.berman <at> gmx.net, Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 78608 <at> debbugs.gnu.org
Subject: Re: bug#78608: 31.0.50; Todo mode bug revealed by setq-default change
Date: Wed, 28 May 2025 21:28:22 +0300
> From: Stefan Monnier <monnier <at> iro.umontreal.ca>
> Cc: stephen.berman <at> gmx.net,  78608 <at> debbugs.gnu.org
> Date: Wed, 28 May 2025 12:59:52 -0400
> 
> >>  * Incompatible Lisp Changes in Emacs 31.1
> >>  
> >> +** 'setq-local' computes the value before making the variable local.
> >> +The previous code made the variable buffer local before
> >> +computing the value to assign to it.
> >> +This bug fix is a subtle change to the semantics which should make
> >> +no difference to the vast majority of uses but can occasionally affect
> >> +code in surprising ways if the computation of the value refers to the
> >> +variable.
> >
> > I think this should describe the case upon which Stephen stumbled:
> > code which uses setq-local inside a let-binding (perhaps an implicit
> > one, such as the one the various with-SOMETHING macros do), and
> > expects the buffer-local value to stay after the let-binding is
> > exited.
> 
> Maybe you should write it, then because you seem to understand that case
> better than I (I did look at the code to try and figure out what was the
> specific origin of the problem but .. failed).  But note that it's only
> one case that can be affected, there are others.

Stephen, would you mind explaining in more detail what in that commit
caused the regression on the master branch?  I'd like us all to be on
the same page before we decide how (and whether) to document it.

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78608; Package emacs. (Wed, 28 May 2025 22:59:02 GMT) Full text and rfc822 format available.

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

From: Stephen Berman <stephen.berman <at> gmx.net>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: Stefan Monnier <monnier <at> iro.umontreal.ca>, 78608 <at> debbugs.gnu.org
Subject: Re: bug#78608: 31.0.50; Todo mode bug revealed by setq-default change
Date: Thu, 29 May 2025 00:58:22 +0200
On Wed, 28 May 2025 21:28:22 +0300 Eli Zaretskii <eliz <at> gnu.org> wrote:

>> From: Stefan Monnier <monnier <at> iro.umontreal.ca>
>> Cc: stephen.berman <at> gmx.net,  78608 <at> debbugs.gnu.org
>> Date: Wed, 28 May 2025 12:59:52 -0400
>> 
>> >>  * Incompatible Lisp Changes in Emacs 31.1
>> >>  
>> >> +** 'setq-local' computes the value before making the variable local.
>> >> +The previous code made the variable buffer local before
>> >> +computing the value to assign to it.
>> >> +This bug fix is a subtle change to the semantics which should make
>> >> +no difference to the vast majority of uses but can occasionally affect
>> >> +code in surprising ways if the computation of the value refers to the
>> >> +variable.
>> >
>> > I think this should describe the case upon which Stephen stumbled:
>> > code which uses setq-local inside a let-binding (perhaps an implicit
>> > one, such as the one the various with-SOMETHING macros do), and
>> > expects the buffer-local value to stay after the let-binding is
>> > exited.
>> 
>> Maybe you should write it, then because you seem to understand that case
>> better than I (I did look at the code to try and figure out what was the
>> specific origin of the problem but .. failed).  But note that it's only
>> one case that can be affected, there are others.
>
> Stephen, would you mind explaining in more detail what in that commit
> caused the regression on the master branch?  I'd like us all to be on
> the same page before we decide how (and whether) to document it.

Unfortunately, I have been unable to step through `setq-local' with
Edebug when the variable `todo-categories' gets set; typing `i' just
returns me to todo-read-category after the variable gets set.  So I only
see what I reported in the bug report, which I repeat here for
convenience:

"Th[e] difference between emacs-30 and master manifests itself in the
function `todo-category-completions' (called from `todo-read-category')
around the following code:

(with-current-buffer (find-file-noselect f 'nowarn)
  [...]
  (todo-mode)
  [...])

In both master and emacs-30, before entering this sexp, the buffer-local
value of `todo-categories' is nil, but after invoking `todo-mode' its
value (for the buffer visiting the Todo file `f') becomes non-nil.
After leaving the `with-current-buffer' form, `todo-categories' retains
its non-nil value in master, but reverts to nil in emacs-30.  The mode
function `todo-mode' calls `todo-modes-set-3', which contains the form
`(setq-local todo-categories (todo-set-categories))'.  This led me to
commit f3e0bdf1b98, and indeed, when I undo that change in master, the
problematic prompt on calling `todo-jump-to-category' does not happen."

Can either of you tell me how to debug `setq-local' or what to look for
in the `with-current-buffer' form to try and find the cause of the
difference between master and emacs-30?

Steve Berman




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78608; Package emacs. (Thu, 29 May 2025 06:15:02 GMT) Full text and rfc822 format available.

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: Stephen Berman <stephen.berman <at> gmx.net>
Cc: monnier <at> iro.umontreal.ca, 78608 <at> debbugs.gnu.org
Subject: Re: bug#78608: 31.0.50; Todo mode bug revealed by setq-default change
Date: Thu, 29 May 2025 09:14:26 +0300
> From: Stephen Berman <stephen.berman <at> gmx.net>
> Cc: Stefan Monnier <monnier <at> iro.umontreal.ca>,  78608 <at> debbugs.gnu.org
> Date: Thu, 29 May 2025 00:58:22 +0200
> 
> On Wed, 28 May 2025 21:28:22 +0300 Eli Zaretskii <eliz <at> gnu.org> wrote:
> 
> > Stephen, would you mind explaining in more detail what in that commit
> > caused the regression on the master branch?  I'd like us all to be on
> > the same page before we decide how (and whether) to document it.
> 
> Unfortunately, I have been unable to step through `setq-local' with
> Edebug when the variable `todo-categories' gets set; typing `i' just
> returns me to todo-read-category after the variable gets set.  So I only
> see what I reported in the bug report, which I repeat here for
> convenience:
> 
> "Th[e] difference between emacs-30 and master manifests itself in the
> function `todo-category-completions' (called from `todo-read-category')
> around the following code:
> 
> (with-current-buffer (find-file-noselect f 'nowarn)
>   [...]
>   (todo-mode)
>   [...])
> 
> In both master and emacs-30, before entering this sexp, the buffer-local
> value of `todo-categories' is nil, but after invoking `todo-mode' its
> value (for the buffer visiting the Todo file `f') becomes non-nil.
> After leaving the `with-current-buffer' form, `todo-categories' retains
> its non-nil value in master, but reverts to nil in emacs-30.  The mode
> function `todo-mode' calls `todo-modes-set-3', which contains the form
> `(setq-local todo-categories (todo-set-categories))'.  This led me to
> commit f3e0bdf1b98, and indeed, when I undo that change in master, the
> problematic prompt on calling `todo-jump-to-category' does not happen."

Yes, that was my understanding, and the reason why I thought this
change might affect other Lisp programs.

Stefan, does the above explain/describe the change in behavior of
setq-local in let-bound code, and is it the change you expect from the
changes you installed?

> Can either of you tell me how to debug `setq-local' or what to look for
> in the `with-current-buffer' form to try and find the cause of the
> difference between master and emacs-30?

I hope Stefan will be able to help you there.  But the first thing I'd
try when Edebug doesn't help is printf-debugging, i.e. using 'message'
to display values during execution.  Did you try that?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78608; Package emacs. (Thu, 29 May 2025 22:49:02 GMT) Full text and rfc822 format available.

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

From: Stephen Berman <stephen.berman <at> gmx.net>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: monnier <at> iro.umontreal.ca, 78608 <at> debbugs.gnu.org
Subject: Re: bug#78608: 31.0.50; Todo mode bug revealed by setq-default change
Date: Fri, 30 May 2025 00:48:13 +0200
[Message part 1 (text/plain, inline)]
On Thu, 29 May 2025 09:14:26 +0300 Eli Zaretskii <eliz <at> gnu.org> wrote:

>> From: Stephen Berman <stephen.berman <at> gmx.net>
>> Cc: Stefan Monnier <monnier <at> iro.umontreal.ca>,  78608 <at> debbugs.gnu.org
>> Date: Thu, 29 May 2025 00:58:22 +0200
>> 
>> On Wed, 28 May 2025 21:28:22 +0300 Eli Zaretskii <eliz <at> gnu.org> wrote:
>> 
>> > Stephen, would you mind explaining in more detail what in that commit
>> > caused the regression on the master branch?  I'd like us all to be on
>> > the same page before we decide how (and whether) to document it.
>> 
>> Unfortunately, I have been unable to step through `setq-local' with
>> Edebug when the variable `todo-categories' gets set; typing `i' just
>> returns me to todo-read-category after the variable gets set.  So I only
>> see what I reported in the bug report, which I repeat here for
>> convenience:
>> 
>> "Th[e] difference between emacs-30 and master manifests itself in the
>> function `todo-category-completions' (called from `todo-read-category')
>> around the following code:
>> 
>> (with-current-buffer (find-file-noselect f 'nowarn)
>>   [...]
>>   (todo-mode)
>>   [...])
>> 
>> In both master and emacs-30, before entering this sexp, the buffer-local
>> value of `todo-categories' is nil, but after invoking `todo-mode' its
>> value (for the buffer visiting the Todo file `f') becomes non-nil.
>> After leaving the `with-current-buffer' form, `todo-categories' retains
>> its non-nil value in master, but reverts to nil in emacs-30.  The mode
>> function `todo-mode' calls `todo-modes-set-3', which contains the form
>> `(setq-local todo-categories (todo-set-categories))'.  This led me to
>> commit f3e0bdf1b98, and indeed, when I undo that change in master, the
>> problematic prompt on calling `todo-jump-to-category' does not happen."
>
> Yes, that was my understanding, and the reason why I thought this
> change might affect other Lisp programs.
>
> Stefan, does the above explain/describe the change in behavior of
> setq-local in let-bound code, and is it the change you expect from the
> changes you installed?
>
>> Can either of you tell me how to debug `setq-local' or what to look for
>> in the `with-current-buffer' form to try and find the cause of the
>> difference between master and emacs-30?
>
> I hope Stefan will be able to help you there.  But the first thing I'd
> try when Edebug doesn't help is printf-debugging, i.e. using 'message'
> to display values during execution.  Did you try that?

I haven't tried that yet but in the attached file I've distilled the
todo-mode code involved in this issue, making it easier to see what
causes the different results with `setq-local' in master and emacs-30:

0. Start emacs from master with -Q.
1. Load the attached file.
2. Type `M-x srb-do RET'.
=> Now *Messages* contains the following:
   srb-val 1: nil
   srb-val 2: 42
   srb-val 3: 42
   Yes!
3. Kill emacs, visit the attached file and in the function `srb-set-val'
   comment out the line `(setq srb-val 42)' and uncomment the following
   line, so it becomes `42'.  Type `C-x C-s'.
4. Repeat steps 0-2.
=> Now *Messages* contains the following:
   srb-val 1: nil
   srb-val 2: 42
   srb-val 3: nil
   No!

Now repeat the above recipe with emacs-30 -Q: the results in *Message*
after steps 2 and 4 are the same:
   srb-val 1: nil
   srb-val 2: 42
   srb-val 3: nil
   No!

In short: with `setq-local' in master, if you do this:

   (setq-local var (setq var val))

within a `with-current-buffer' form, then `val' survives after exiting
the form, but not if you do this:

   (setq-local var val)

In emacs-30, `val' does not survive in either case.  I think this
difference is what Stefan was referring by "can occasionally affect code
in surprising ways if the computation of the value refers to the
variable."  But Stefan, when you said you failed to "figure out what was
the specific origin of the problem" in the todo-mode case, did you mean
something else than using `setq' within `setq-local'?

Steve Berman
[srb.el (application/emacs-lisp, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78608; Package emacs. (Sat, 31 May 2025 16:52:03 GMT) Full text and rfc822 format available.

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

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Stephen Berman <stephen.berman <at> gmx.net>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 78608 <at> debbugs.gnu.org
Subject: Re: bug#78608: 31.0.50; Todo mode bug revealed by setq-default change
Date: Sat, 31 May 2025 12:50:57 -0400
> In short: with `setq-local' in master, if you do this:
>
>    (setq-local var (setq var val))
>
> within a `with-current-buffer' form, then `val' survives after exiting
> the form, but not if you do this:
>
>    (setq-local var val)
>
> In emacs-30, `val' does not survive in either case.  I think this
> difference is what Stefan was referring by "can occasionally affect code
> in surprising ways if the computation of the value refers to the
> variable."

In the original problem that prompted the fix to `setq-local`, I think
there was no `setq` involved, but "refers to the variable" is probably
too vague (and suggests that merely asking for the var's value could
also be affected, which I believe is not the case).  So maybe:

    ... can occasionally affect code in surprising ways if the
    computation of the value itself modifies the variable.

where "modifies" could be a `defvar`, `setq`, `let`, ...

> But Stefan, when you said you failed to "figure out what was the
> specific origin of the problem" in the todo-mode case, did you mean
> something else than using `setq' within `setq-local'?

No, the "`setq' within `setq-local'" is the part that I failed to figure
out, thanks.


        Stefan





This bug report was last modified 5 days ago.

Previous Next


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