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