Max Nikulin <maniku...@gmail.com> writes:

> On 22/06/2022 19:13, Arthur Miller wrote:
>> Max Nikulin writes:
>> Menu should and application should be separated in my eyes. Menu is just a
>> graphical/audio? presentation of selectable choice to the user. As such it
>> should display choices, let user pick a choice, and return to the application
>> the picked choice. Compare to completing-read, or org-mks. I don't think we
>> should mingle application states and menu states.
>
> By state I mean some structure opaque to menu package. It just receives it 
> from
> caller as an optional argument and (when given) later passes it to
> handler. Maybe it is alien approach in LISP, but in C (where closures are
> impossible) it is a widely used technique. Functions having callback argument
> usually have another void* one that is later passed as an argument of the
> callback function in addition to other data.

I understand, I have done my share of C, and know what you mean. Say
posix thread will take a void* to user data, and pass it on. This is
exactly what this is about. It is just that we don't need an extra
structure to pass around. We have a menu entry, which *is* the user
data. Well at least most of it :). This structure looks like:

(key label user-data)

Where user-data is any elements in the list user wishes to pass on. I
don't even require the list to be a well-formed property list, I thought
it is left to the user. key = shortcut used to create mode-map and label
is the string displayed in the buffer. Later this string could be used
for compleating read/isearch or whatever, if it is desired to provide
such interface. But really those two elements are the required
ones and in the first place in the template. The rest is up to client
code.

Compare to org-capture-templates as illustration. We don need to keep it
compatible with org-capture, so it has to recognize two-elements form:
(key label) which has special meaning, and that translates to all other
clients. I could transform those, but I don't think it is worth work. I
will also see if I can rework it to use another two element form:

(:separator separator-string).

I disslike the tripple nesting of lists: a menu is a list of tables
which are each list of lists. I used this approach to implicitly tell
where separators are to be drawn, but after second thought, I think it
will be prettier and more intuitive for client code to explicitly note
where separator is. Maybe I could even mix vertical and horizontal
separators in same menu. I'll see if I have time and interest to
implement that one :).


> (org-buffer-menu
>  '(("a" "Option A" (1))
>    ("b" "Option B" (2)))
>  :handler
>  (lambda (entry state)
>   (message "value %S state %S" (nth 2 entry) state))
>  :state
>  '(1 2 3))
>
> Menu caller does not care whether some buffer is created to present menu. Menu
> has no idea what state may contain, it just passes it to the handler. When 
> menu
> is implemented as a buffer with keymap then state is stored as a buffer-local
> variable.

Exactly, and this is exactly what happens when you pass in a
handler. The handler gets the entry, which can contain whatever client
data is. Again, compare to org-capture-template.

One can mentally see a menu entry as two lists:

(key label) and (user-data1 ... user-dataN).

They are just lumped into one list (key label user-data1 ... user-dataN).

There is no point of separating this into two lists, since we need
backward compatibility with org-capture-templates.

> As to your current implementation of org-select, I do not like that it is
> responsibility of caller to create different buffer names to enable multiple
> instances of menu. I would prefer to control single/multiple instances 
> through a
> boolean argument of org-select.

How can we know what client application would be called? In which way
can we guess we are called from org-capture or org-agenda org some
user-app? Or I don't udnerstand what you mean here?

Reason I removed :transient as the flag to say the menu should dissapear
after the choice is made, is that it puts control into two places and
messes up the code. Since a hanlder can do anything anyway, it has to be
checked in both places. So I removed the transient flag, and lets just
the handler do it. In that case we know where the buffer handling
happens. I think it eases up usage and implementation. If you have some
cleaner approach sure, it is appreaciated. 

> Arthur, I see that I should response to more your comments. However I am 
> unable
> to identify source of disagreement, likely it is some different

I didn't know we are in disagreement :-).

>  likely it is some different
> assumptions. 

Could be. Could be that we think about same thing, but we see it a bit
differently. People solve things differently, so would probably have
different solutions if we worked separately on this. I think it is normal.

> assumptions. That is why I decided to concentrate on a couple of questions in
> this message.

It is ok. I hope I made it more clear how I am thinking about this.

best regards
/a

Reply via email to