GNU bug report logs - #60712
28.2; customize-set-variable won't let you change the type of a choice

Previous Next

Package: emacs;

Reported by: Omar Antolín Camarena <omar.antolin <at> gmail.com>

Date: Tue, 10 Jan 2023 17:37:02 UTC

Severity: normal

Found in version 28.2

Done: Eli Zaretskii <eliz <at> gnu.org>

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 60712 in the body.
You can then email your comments to 60712 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#60712; Package emacs. (Tue, 10 Jan 2023 17:37:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Omar Antolín Camarena <omar.antolin <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Tue, 10 Jan 2023 17:37:02 GMT) Full text and rfc822 format available.

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

From: Omar Antolín Camarena <omar.antolin <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: 28.2; customize-set-variable won't let you change the type of a choice
Date: Tue, 10 Jan 2023 11:35:46 -0600
If you declare a user option as follows:

(defcustom bool-or-alist '((a . 4) (b . 7))
  "A made up option to illustrate a problem."
  :type '(choice boolean (alist :key-type symbol :value-type integer)))

And then run M-x customize-set-variable to change the value to t the
change fails with the message:

widget-prompt-value: Value does not match alist type

That :type specification works just fine with the customize UI using
customize-variable, it's just a problem with customize-set-variable.

I think the problem is that widget-choice-prompt-value figures which
branch of the choice the variable currenty has and then expects the new
type to be the same.

If you tag everything, then customize-set-variable works just fine:

(defcustom bool-or-alist '((a . 4) (b . 7))
  "A made up option to illustrate a problem."
  :type '(choice (const :tag "Yes" t)
                 (const :tag "No" nil)
                 (alist :tag "An alist"
                        :key-type symbol :value-type integer)))


In GNU Emacs 28.2 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.34, cairo version 1.16.0)
 of 2022-10-25, modified by Debian built on x86-conova-01
Windowing system distributor 'The X.Org Foundation', version 11.0.12008000
System Description: Debian GNU/Linux 11 (bullseye)

Configured using:
 'configure --build x86_64-linux-gnu --prefix=/usr
 --sharedstatedir=/var/lib --libexecdir=/usr/libexec
 --localstatedir=/var/lib --infodir=/usr/share/info
 --mandir=/usr/share/man --with-libsystemd --with-pop=yes
 --enable-locallisppath=/etc/emacs:/usr/local/share/emacs/28.2/site-lisp:/usr/local/share/emacs/site-lisp:/usr/share/emacs/28.2/site-lisp:/usr/share/emacs/site-lisp
 --with-sound=alsa --without-gconf --with-mailutils
 --with-native-compilation --build x86_64-linux-gnu --prefix=/usr
 --sharedstatedir=/var/lib --libexecdir=/usr/libexec
 --localstatedir=/var/lib --infodir=/usr/share/info
 --mandir=/usr/share/man --with-libsystemd --with-pop=yes
 --enable-locallisppath=/etc/emacs:/usr/local/share/emacs/28.2/site-lisp:/usr/local/share/emacs/site-lisp:/usr/share/emacs/28.2/site-lisp:/usr/share/emacs/site-lisp
 --with-sound=alsa --without-gconf --with-mailutils
 --with-native-compilation --with-cairo --with-x=yes
 --with-x-toolkit=gtk3 --with-toolkit-scroll-bars 'CFLAGS=-g -O2
 -ffile-prefix-map=/build/emacs-mlMHQs/emacs-28.2+1=.
 -fstack-protector-strong -Wformat -Werror=format-security -Wall'
 'CPPFLAGS=-Wdate-time -D_FORTIFY_SOURCE=2' LDFLAGS=-Wl,-z,relro'

Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG
JSON LCMS2 LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 M17N_FLT MODULES
NATIVE_COMP NOTIFY INOTIFY PDUMPER PNG RSVG SECCOMP SOUND THREADS TIFF
TOOLKIT_SCROLL_BARS X11 XDBE XIM XPM GTK3 ZLIB

Important settings:
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix

Major mode: ELisp/l

Minor modes in effect:
  shell-dirtrack-mode: t
  global-org-modern-mode: t
  outline-minor-mode: t
  beginend-global-mode: t
  beginend-prog-mode: t
  marginalia-mode: t
  vertico-multiform-mode: t
  vertico-mode: t
  minibuffer-electric-default-mode: t
  minibuffer-depth-indicate-mode: t
  repeat-mode: t
  recentf-mode: t
  override-global-mode: t
  tooltip-mode: t
  global-eldoc-mode: t
  eldoc-mode: t
  show-paren-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  tab-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  line-number-mode: t
  transient-mark-mode: t

Load-path shadows:
/home/omarantolin/.emacs.d/elpa/transient-20230107.1528/transient hides /usr/share/emacs/28.2/lisp/transient

Features:
(shadow emacsbug vc-git vc-dispatcher ispell shell various-toggles time
smiley gnus-async gnus-bcklg gnus-ml disp-table mailalias qp
message-extras smtpmail sendmail sort hippie-exp gnus-cite mail-extr
face-remap ecomplete nndraft nnmh utf-7 gnus-agent gnus-srvr gnus-score
score-mode nnvirtual gnus-msg gnus-art mm-uu mml2015 mm-view mml-smime
smime dig nntp gnus-cache gnus-sum shr kinsoku svg dom gnus-group
gnus-undo gnus-start gnus-dbus dbus xml gnus-cloud nnimap nnmail
mail-source utf7 netrc nnoo parse-time gnus-spec gnus-int gnus-range
gnus-win gnus nnheader xref consult-icomplete icomplete flymake-proc
flymake project osm-ol org-modern org-config my-website org-extras
embark-org org-element avl-tree generator org ob ob-tangle ob-ref ob-lob
ob-table ob-exp org-macro org-footnote org-src ob-comint org-pcomplete
pcomplete org-list org-faces org-entities org-version ob-emacs-lisp
ob-core ob-eval org-table oc-basic bibtex iso8601 ol org-keys oc
org-compat advice org-macs org-loaddefs format-spec cal-menu calendar
cal-loaddefs pcase dash s modus-vivendi-tinted-theme modus-vivendi-theme
modus-vivendi-deuteranopia-theme modus-operandi-tinted-theme
modus-operandi-deuteranopia-theme compile find-func autoload radix-tree
lisp-mnt tar-mode arc-mode archive-mode mm-archive message dired
dired-loaddefs rfc822 mml mml-sec epa derived gnus-util rmail
rmail-loaddefs time-date mailabbrev gmm-utils mailheader mm-decode
mm-bodies mm-encode mail-utils mule-util executable cus-edit cus-start
cus-load gnutls network-stream url-http mail-parse rfc2231 rfc2047
rfc2045 mm-util ietf-drums mail-prsvr url-gw nsm rmc puny url-cache
url-auth epg rfc6068 epg-config noutline outline gap-config gap-mode
gap-process comint ansi-color ring email-config smerge-mode diff
pdf-loader cdlatex reftex reftex-loaddefs reftex-vars diff-mode diminish
beginend consult-imenu imenu embark-this-buffer embark-consult
consult-vertico consult compat compat-29 bookmark text-property-search
pp embark ffap thingatpt marginalia vertico-multiform vertico orderless
minibuf-eldef mb-depth block-undo visiting-buffer repeat recentf
tree-widget wid-edit modus-operandi-theme modus-themes use-package
use-package-ensure use-package-delight use-package-diminish
use-package-bind-key bind-key easy-mmode use-package-core finder-inf
edmacro kmacro tex-site info package browse-url url url-proxy
url-privacy url-expand url-methods url-history url-cookie url-domsuf
url-util mailcap url-handlers url-parse auth-source eieio eieio-core
eieio-loaddefs password-cache json map url-vars comp comp-cstr warnings
subr-x rx cl-seq cl-macs cl-extra help-mode seq byte-opt gv bytecomp
byte-compile cconv cl-loaddefs cl-lib iso-transl tooltip eldoc paren
electric uniquify ediff-hook vc-hooks lisp-float-type elisp-mode mwheel
term/x-win x-win term/common-win x-dnd tool-bar dnd fontset image
regexp-opt fringe tabulated-list replace newcomment text-mode lisp-mode
prog-mode register page tab-bar menu-bar rfn-eshadow isearch easymenu
timer select scroll-bar mouse jit-lock font-lock syntax font-core
term/tty-colors frame minibuffer cl-generic cham georgian utf-8-lang
misc-lang vietnamese tibetan thai tai-viet lao korean japanese eucjp-ms
cp51932 hebrew greek romanian slovak czech european ethiopic indian
cyrillic chinese composite emoji-zwj charscript charprop case-table
epa-hook jka-cmpr-hook help simple abbrev obarray cl-preloaded nadvice
button loaddefs faces cus-face macroexp files window text-properties
overlay sha1 md5 base64 format env code-pages mule custom widget
hashtable-print-readable backquote threads dbusbind inotify lcms2
dynamic-setting system-font-setting font-render-setting cairo
move-toolbar gtk x-toolkit x multi-tty make-network-process
native-compile emacs)

Memory information:
((conses 16 702294 624224)
 (symbols 48 38966 5)
 (strings 32 166505 121826)
 (string-bytes 1 6784094)
 (vectors 16 68620)
 (vector-slots 8 1605969 120250)
 (floats 8 382 426)
 (intervals 56 1843 739)
 (buffers 992 20))




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#60712; Package emacs. (Sun, 16 Jul 2023 12:20:01 GMT) Full text and rfc822 format available.

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

From: Mauro Aranda <maurooaranda <at> gmail.com>
To: Omar Antolín Camarena <omar.antolin <at> gmail.com>
Cc: 60712 <at> debbugs.gnu.org
Subject: Re: bug#60712: 28.2; customize-set-variable won't let you change the
 type of a choice
Date: Sun, 16 Jul 2023 09:18:54 -0300
Omar Antolín Camarena <omar.antolin <at> gmail.com> writes:

> If you declare a user option as follows:
>
> (defcustom bool-or-alist '((a . 4) (b . 7))
>   "A made up option to illustrate a problem."
>   :type '(choice boolean (alist :key-type symbol :value-type integer)))
>
> And then run M-x customize-set-variable to change the value to t the
> change fails with the message:
>
> widget-prompt-value: Value does not match alist type

I didn't manage to reproduce it with this recipe.  What I had to do
was, after emacs -Q:

(defcustom bool-or-alist '((a . 4) (b . 7))
  "A made up option to illustrate a problem."
  :type '(choice boolean (alist :key-type symbol :value-type integer)))

M-x customize-set-variable RET bool-or-alist

I get a prompt:
[boolean] [choice] Set customized value for bool-or-ailst to true:
If I answer y or n, there's no problem, bool-or-alist will be t or nil.

M-x customize-set-variable RET bool-or-alist

New prompt:
[alist] [choice] Set customized value for bool-or-alist to:
Here if you answer t, you get the message:
widget-prompt-value: Value does not match alist type

Which is not surprising, since t is not an alist and the prompt says its
expecting an alist.

What's surprising is that the prompt is choosing one of the two options
beforehand.  I mean, going back to the original definition and
re-evaluating, say that I want to use customize-set-variable to change
the alist.  I can't do that right away: I have to set it to t or nil,
and then execute customize-set-variable again to set it to an alist.
Not good.

> I think the problem is that widget-choice-prompt-value figures which
> branch of the choice the variable currenty has and then expects the new
> type to be the same.

> If you tag everything, then customize-set-variable works just fine:
>
> (defcustom bool-or-alist '((a . 4) (b . 7))
>   "A made up option to illustrate a problem."
>   :type '(choice (const :tag "Yes" t)
>                  (const :tag "No" nil)
>                  (alist :tag "An alist"
>                         :key-type symbol :value-type integer)))
>

Yes, but it's not because of the tags.  It's just that previously the
choice widget had two choice, and now it has three, and since there's at
least two options to pick (excluding the current),
widget-choice-prompt-value won't choose for you one of the options
beforehand.

We have this condition in widget-choice-prompt-value:
((and (= (length args) 2)
      (memq old args))
 (if (eq old (nth 0 args))
     (nth 1 args)
   (nth 0 args)))

ARGS holds the choices available in the choice widget and OLD has
the choice that matches the current value of the choice widget, before
the user enters a new one.  This branch has been in the code since like
forever, but I can't explain why it's good to have it.





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#60712; Package emacs. (Sun, 16 Jul 2023 13:28:02 GMT) Full text and rfc822 format available.

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

From: Mauro Aranda <maurooaranda <at> gmail.com>
To: 60712 <at> debbugs.gnu.org
Cc: Omar Antolín Camarena <omar.antolin <at> gmail.com>
Subject: Re: bug#60712: 28.2; customize-set-variable won't let you change the
 type of a choice
Date: Sun, 16 Jul 2023 10:27:39 -0300
[Message part 1 (text/plain, inline)]
Mauro Aranda <maurooaranda <at> gmail.com> writes:

> We have this condition in widget-choice-prompt-value:
> ((and (= (length args) 2)
>       (memq old args))
>  (if (eq old (nth 0 args))
>      (nth 1 args)
>    (nth 0 args)))
>
> ARGS holds the choices available in the choice widget and OLD has
> the choice that matches the current value of the choice widget, before
> the user enters a new one.  This branch has been in the code since like
> forever, but I can't explain why it's good to have it.

So, we should respect the value of widget-choice-toggle also when
prompting, of course.  I attach a patch to fix it.
[0001-Don-t-always-toggle-a-choice-when-prompting.patch (text/x-patch, attachment)]

Reply sent to Eli Zaretskii <eliz <at> gnu.org>:
You have taken responsibility. (Sat, 22 Jul 2023 12:59:02 GMT) Full text and rfc822 format available.

Notification sent to Omar Antolín Camarena <omar.antolin <at> gmail.com>:
bug acknowledged by developer. (Sat, 22 Jul 2023 12:59:02 GMT) Full text and rfc822 format available.

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: Mauro Aranda <maurooaranda <at> gmail.com>
Cc: omar.antolin <at> gmail.com, 60712-done <at> debbugs.gnu.org
Subject: Re: bug#60712: 28.2;
 customize-set-variable won't let you change the type of a choice
Date: Sat, 22 Jul 2023 15:59:15 +0300
> Cc: Omar Antolín Camarena <omar.antolin <at> gmail.com>
> Date: Sun, 16 Jul 2023 10:27:39 -0300
> From: Mauro Aranda <maurooaranda <at> gmail.com>
> 
> Mauro Aranda <maurooaranda <at> gmail.com> writes:
> 
>  > We have this condition in widget-choice-prompt-value:
>  > ((and (= (length args) 2)
>  >       (memq old args))
>  >  (if (eq old (nth 0 args))
>  >      (nth 1 args)
>  >    (nth 0 args)))
>  >
>  > ARGS holds the choices available in the choice widget and OLD has
>  > the choice that matches the current value of the choice widget, before
>  > the user enters a new one.  This branch has been in the code since like
>  > forever, but I can't explain why it's good to have it.
> 
> So, we should respect the value of widget-choice-toggle also when
> prompting, of course.  I attach a patch to fix it.

Thanks, installed on the master branch, and closing the bug.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Sun, 20 Aug 2023 11:24:04 GMT) Full text and rfc822 format available.

This bug report was last modified 248 days ago.

Previous Next


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