From: Mauro Aranda <maurooaranda@gmail.com>
To: bovine@cyberscientist.ca
Cc: emacs-devel@gnu.org
Subject: Re: Community improvements to the Emacs Widget Library manual?
Date: Fri, 14 Jul 2023 21:08:25 -0300 [thread overview]
Message-ID: <09082742-1c5d-b8b6-49d8-dedcb5ee4347@gmail.com> (raw)
In-Reply-To: <8745efdbcf82ae2595a098fd09ba22d7@cyberscientist.ca>
bovine@cyberscientist.ca writes:
> On 2023-07-14 10:41, Mauro Aranda wrote:
>> Bryce Carson <bovine@cyberscientist.ca> writes:
>>
>>> Further, I can't seem to get these functions to work as documented or
>>> expected.
>>> Without these defined when I'm creating a widget with the following
>>> code, I do get a button but the internal value is displayed in the
>>> clickable
>>> button. I'd like the external value to be displayed in the button
>>> %v, just
>>> as the menu-tag is is "externally facing".
>>> <<widget>>=
>>> (define-widget 'project-widget 'list
>>> :tag (let ((s "\n\tProject"))
>>> (put-text-property 0 (length s) 'face 'bold s) s)
>>> :format "%t\n%v "
>>> :offset 0
>>> :indent 0
>>> :convert-widget 'widget-types-convert-widget
>>> :args '((menu-choice
>>> :tag "EmacSQL-supported backend"
>>> :format "%[%t%]: %[%v%]"
>>> :value "sqlite"
>>> :value-to-external <<menu-choice internal value to
>>> external lambda>>
>>> :value-to-internal <<menu-choice external value to
>>> internal lambda>>
>>> (choice-item :menu-tag "MySQL" :value "mysql")
>>> (choice-item :menu-tag "PostgreSQL" :value "postgresql")
>>> (choice-item :menu-tag "SQLite" :value "sqlite"))))
>>> <<menu-choice internal value to external lambda>>=
>>> (lambda (widget internal-value)
>>> "Converts lowercase, internal values to the casing of trademarks."
>>> (pcase internal-value
>>> ("mysql" "MySQL")
>>> ("sqlite" "SQLite")
>>> ("postgresql" "PostgreSQL")))
>>> <<menu-choice external value to internal lambda>>=
>>> (lambda (widget external-value)
>>> "Converts the casing of trademarked names to lowercase, internal
>>> values."
>>> (pcase external-value
>>> ("MySQL" "mysql")
>>> ("SQLite" "sqlite")
>> When possible, please post code that can be evaled without making
>> tweaks.
>> Some things I noted:
>> - Since the super is a list widget, then you don't need to specify
>> :convert-widget. The :convert-widget function is one of the few that
>> gets called for all supers, so you end up converting twice the widget.
>> In this case, it doesn't seem you want that.
>> - You're specifying a value in the internal format for the
>> menu-choice.
>> The manual specifies that when creating a widget or defining a new
>> one, the ‘:value’ should be in the external format.
>> - I think you should give similar conversion functions to all
>> choice-item, and also pass the :value in external format.
>> Let me know if you still find problems after fixing these things.
>
> I fixed those issues and I do not see the invalid or void state, but
> only nil is ever displayed in the buffer.
> Below is the code I defined.
OK, I think you ran into something that's unsupported (maybe a bug, but
I'm not quite sure).
And thank you for providing the code, it made things easier for me to
see it.
> (define-widget 'project-widget 'list
> "A mimimal example to demonstrate 'styled' choice item buttons in a
> choice menu."
> :tag (let ((s "\n\tProject"))
> (put-text-property 0 (length s) 'face 'bold s) s)
> :format "%t\n%v "
>
> :args '((menu-choice
> :tag "EmacSQL-supported backend"
> :size 50
> :format "%[%t%]: %[%v%] \n"
>
> :value "SQLite"
> :choice (database-choice-item :menu-tag "SQLite" :value
> "SQLite")
>
> :value-to-external menu-choice-value-to-external
> :value-to-internal menu-choice-value-to-internal
>
> (database-choice-item :menu-tag "MySQL" :value "MySQL")
> (database-choice-item :menu-tag "PostgreSQL" :value
> "PostgreSQL")
> (database-choice-item :menu-tag "SQLite" :value
> "SQLite"))))
The menu-choice creation assumes no difference between the internal
format and external format. So for now, try removing the
:value-to-external and :value-to-internal. I think it does that
because there's no big reason for converting a menu-choice value, since
the menu-choice will get its value from a valid choice, and the
individual choice is responsible for the conversion between formats.
Oh, and don't use :value and :choice at the same. Just use :value to
give it a default value. So this widget should be:
(define-widget 'project-widget 'list
"A mimimal example to demonstrate 'styled' choice item buttons in a
choice menu."
:tag (let ((s "\n\tProject"))
(put-text-property 0 (length s) 'face 'bold s) s)
:format "%t\n%v "
:args '((menu-choice
:tag "EmacSQL-supported backend"
:size 50
:format "%[%t%]: %[%v%] \n"
:value "MySQL"
(database-choice-item :menu-tag "MySQL" :value "MySQL")
(database-choice-item :menu-tag "PostgreSQL" :value
"PostgreSQL")
(database-choice-item :menu-tag "SQLite" :value
"SQLite"))))
> (define-widget 'database-choice-item 'choice-item
> nil
> :value-to-external #'menu-choice-value-to-external
> :value-to-internal #'menu-choice-value-to-internal)
And now, you need a :match function for this widget, so that when it
gets passed an external value, such as "MySQL", it returns non-nil.
So maybe something like this:
(define-widget 'database-choice-item 'choice-item
nil
:match (lambda (widget value)
(equal (widget-get widget :value) (widget-apply widget
:value-to-internal
value)))
:value-to-external #'menu-choice-value-to-external
:value-to-internal #'menu-choice-value-to-internal)
You need a custom :match function because otherwise the
database-choice-item would resort to matching like an item, and that's
not good when you have different internal and external formats.
Basically, if you use different formats, you should consider providing a
:match function yourself.
I think with these fixes, your code will run just as you expect it.
next prev parent reply other threads:[~2023-07-15 0:08 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-12 11:43 Community improvements to the Emacs Widget Library manual? Mauro Aranda
2023-07-12 20:17 ` Bryce
2023-07-14 6:32 ` Bryce Carson
2023-07-14 6:52 ` Bryce Carson
2023-07-14 6:56 ` Bryce Carson
2023-07-14 6:59 ` Bryce Carson
2023-07-14 7:07 ` Bryce Carson
2023-07-14 14:41 ` Mauro Aranda
2023-07-14 18:50 ` bovine
2023-07-15 0:08 ` Mauro Aranda [this message]
2023-07-14 10:48 ` Mauro Aranda
-- strict thread matches above, loose matches on Subject: below --
2023-07-09 12:17 Mauro Aranda
2023-07-12 4:07 ` Bryce
2023-07-12 11:34 ` Mauro Aranda
2023-07-13 3:30 ` Michael Heerdegen
2023-07-23 23:06 ` Bryce
2023-07-24 11:37 ` Eli Zaretskii
2023-07-08 20:18 Bryce Carson
2023-07-09 5:26 ` Eli Zaretskii
2023-07-09 12:02 ` Mauro Aranda
2023-07-09 12:16 ` Eli Zaretskii
2023-07-11 0:52 ` Bryce
2023-07-12 12:30 ` Eli Zaretskii
2023-07-12 16:42 ` Corwin Brust
2023-07-13 23:05 ` Bryce Carson
2023-07-10 3:38 ` Michael Heerdegen
2023-07-11 23:17 ` Bryce
2023-07-12 5:18 ` Michael Heerdegen
2023-07-12 7:21 ` Bryce
2023-07-13 2:59 ` Michael Heerdegen
2023-07-11 11:04 ` Kjartan Oli Agustsson
2023-07-14 2:02 ` Richard Stallman
2023-07-14 5:28 ` Bryce Carson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=09082742-1c5d-b8b6-49d8-dedcb5ee4347@gmail.com \
--to=maurooaranda@gmail.com \
--cc=bovine@cyberscientist.ca \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.