Subject: Re: bug#64046: 30.0.50; Quoting in customize choice tags

From: Stephen Berman <[email-masked]>
Date: Mon, 28 Aug 2023 15:50:10 +0200

On Mon, 28 Aug 2023 11:33:09 +0200 Ola x Nilsson <[email-masked]> wrote:

> On Fri, Aug 25 2023, Stephen Berman wrote:
>
>> On Fri, 25 Aug 2023 10:02:35 +0200 Ola x Nilsson <[email-masked]> wrote:
>>
>>> On Thu, Aug 24 2023, Mauro Aranda wrote:
>>>
>>>> Stephen Berman <[email-masked]> writes:
>>>>
>>>>> On Thu, 24 Aug 2023 17:14:53 -0300 Mauro Aranda
>>>>   <[email-masked]> wrote:
>> [...]
>>>>>> Thinking about it, why do we need to call substitute-command-keys on the
>>>>>> VALUE part (i.e., the cdr of the cons cell), in case of simple item
>>>>>> definitions?
>>>>>>
>>>>>> I re-read the bug report, but I didn't find any reference to why that is
>>>>>> a need.  Did I miss something?
>>>>>
>>>>> Well, the VALUE is displayed on entering a choice.  That is, when I do
>>>>>
>>>>> M-: (widget-choose "Title" '(("Use `a'" . "Use `1'") ("Use `b'"
>>>>   . "Use `2'")))
>>>>>
>>>>> I see curve-quoting in the widget-choose buffer:
>>>>>
>>>>>    Available choices:
>>>>>
>>>>>    0 = Use ‘a’
>>>>>    1 = Use ‘b’
>>>>>
>>>>>    C-g = Quit
>>>>>
>>>>> and when I enter e.g. `0' at the "Title: " prompt in the minibuffer, it
>>>>> displays "Use ‘1’", i.e., with curve-quoting.  But if I omit the call to
>>>>> substitute-command-keys on the cdr in widget-choose, then typing `0' at
>>>>> the "Title: " prompt displays "Use `1'", i.e. with grave-quoting.  But I
>>>>> don't know which one is the intended result.
>>>>
>>>> I see, thank you.  Your last patch looks good to me, then.
>>>
>>> The cdr is the return value, I would expect widget-choose to not
>>> modify that. 
>>
>> I think this is indeed the correct expectation and I should have
>> recognized it instead of looking only at appearances.  But do you agree
>> that applying (at least) quote substitution to the car of the simple
>> item definition is appropriate here?  If so, there is still the question
>> of whether to use substitute-command-keys or just substitute-quotes.
>> I'm inclined to stick with the former but would be fine with going with
>> the latter.
>
> I agree that quote substition should be done on the car of simple item
> definitions.  I have no opinion on susbstitute-command-keys vs
> substitute-quotes.  But I came to think about the TITLE argument,
> shouldn't quote substition be performed on it as well?

I think you're right about that as well, since the title is simply a
display feature.  AFAIK it wouldn't make a noticeable difference for
existing uses of widget-choose in the Customize UI (in the Value menu
the title is simply "Choice" and in the State menu it's "Operation on
<option name>"), but it might be relevant for third party uses or future
uses in Emacs, as well as for ad-hoc uses of simple item definitions.
So applying substition to all uses of TITLE seems appropriate.  The
below patch does this, and also corrects my previous patch by excluding
substition from the cdr of simple item definitions.

Thanks for your feedback.

Steve Berman

diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el
index a70598bb6c9..b712be1986b 100644
--- a/lisp/wid-edit.el
+++ b/lisp/wid-edit.el
@@ -282,16 +282,20 @@ widget-choose
 If ITEMS has simple item definitions, then this function returns the VALUE of
 the chosen element.  If ITEMS is a keymap, then the return value is the symbol
 in the key vector, as in the argument of `define-key'."
-  ;; Apply quote substitution to customize choice menu item text,
+  ;; Apply quote substitution to choice menu title and item text,
   ;; whether it occurs in a widget buffer or in a popup menu.
   (let ((items (mapc (lambda (x)
-                       (when (consp x)
-                         (dotimes (i (1- (length x)))
-                           (when (stringp (nth i x))
-                             (setcar (nthcdr i x)
-                                     (substitute-command-keys
-                                      (car (nthcdr i x))))))))
-		     items)))
+                       (if (proper-list-p x)
+                           (dotimes (i (1- (length x)))
+                             (when (stringp (nth i x))
+                               (setcar (nthcdr i x)
+                                       (substitute-command-keys
+                                        (car (nthcdr i x))))))
+                         ;; ITEMS has simple item definitions.
+                         (when (and (consp x) (stringp (car x)))
+                           (setcar x (substitute-command-keys (car x))))))
+		     items))
+        (title (substitute-command-keys title)))
     (cond ((and (< (length items) widget-menu-max-size)
 	        event (display-popup-menus-p))
 	   ;; Mouse click.