Max Nikulin writes: > On 21/06/2022 11:07, Ihor Radchenko wrote: >> Max Nikulin writes: >> The other question is altering the org-capture code. >> I think that it is too early to discuss org-capture part just yet. >> Lets first finalize the generic library itself and discuss the >> appropriate adjustments to >> org-capture/org-agenda/org-export/org-todo/etc code later. > > From my point of view changing menu without adjusting calling logic is a kind of > trade-off with uncertain net result. New UI may significantly affect different > user expectations. It seems this is the point of our disagreement. You tend to > consider menu in isolation trying to postpone the question concerning > interaction of code running before menu creation and handlers of menu items > (they are not belong to the same call stack any more). > > What I am really afraid is words like: > >> Sure. That somewhere can be buffer-local variable inside the capture >> menu buffer. Or global variable. Or closure. How is it relevant to the >> capture menu? Yepp, it can't saved in a buffer-local before the buffer is created. > I am trying to avoid implementation of menu that would make passing state to > handlers unreliable or prohibitively complicated. 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. However, there is a slight complication compared to completing-read or org-mks in regard that those are used to make only one selection and exit, while this menu is supposed to be used that way, or to be used in a way that it survives multiple selections. To me this seems as clearly per menu entry behaviour. For exmaple in org-agenda menu, some actions will make menu exit, while some will keep the menu alive (for example '*'). One solution is to have some flag passed per entry to signal to the menu to kill itself upon selection. The other one, the easier, is to let the applicaiton code handle the menu kill. I took the second one to minimize on number of flags that needs to be passed and documented, but I agree it is not the cleanest way, so I can change to use a flag if it is considered a better option. > Global variables are certainly not an option because such approach does not > allow several instances of menu created in parallel. Yes, please, lets try to minimize number of globals. Actually I would be happiest with a functional approach where everything is communicated via function arguments and return values. > To use buffer-local variables some support from the side of menu library is > required. Buffer does not exist when menu function is called. So either some > callback should be passed to menu to be invoked when a new buffer is created for > menu or that buffer should be returned from the menu creating function. Unsure > if (current-buffer) would be a reliable approach. > > Closures should work, but would be it convenient enough? We are using list to pass both menus and menu entries. Application can stick in some args used by the menu. > Maybe some intermediate layer should be introduced to make alternative > implementation of menu (transient, completing read, etc.) easier. I don't think it is the topic and scope of this menu. It would be another layer on its own, and definitely another project, I think. > I believe, discussing design of menu without evaluation if it is suitable to > features that should use it (capture, agenda, etc.), there is a risk to create > unreasonable restrictions on further steps. I definitely agree. Designing a good API is hard. I personally always think that frameworks should not be designed in advance. I am more of a pragmatic, and prefer to see actual working use-cases and design a framework after the experience, not try to desing a framework by guessing the potential use-cases. That is why I said that I am not interested in turning this into a framework. I have try to design here something that can be used to implement existing org-capture, org-agenda & co on top of it. > That is why I consider the following aspects of menu design as essential ones: > - A clearly determined way to pass some state from a function that requests > creation of menu to handlers of menu items. Menu entries (lists) > - When a non-blocking technique to wait user decision is used, multiple > instances of the same menu should be allowed. Still have to be worked on. > - Defined extension points for alternative implementations to avoid code > duplication and divergence of behavior. That would be some framework layer. > My fear is that if such points are ignored in the beginning, it may become > impossible later. It's lisp, anything is possible ^^ ;-). No, but serioiusly, there is not much of extension points here. It is a keymap and buffer text generated automatically from a list of templates and few "visual" options. An application can even discard entire buffer and draw its own text out of templates as it pleases, it wouldn't matter. My goal was to create something very simple to use from a programming perspective. Compared to other similar options like make-help-screen and org-mks this puts both key handling, actions and labels into same spot, so there is only one place to maintain later on, and client code needs needs just to specify the most minimal lisp one is interested to execute, ie. I don't need to create lambdas if some function is not already defined. Sort of, that is how at least I would like to use it. I don't know if that is good or bad practice, or how robust the code is, I am not super familiar with lisp and org-mode to be honest. Attached is another experiment. In this version each entry can have attached handler, and I provide two simple handers: run-once and run-multiple times. For applications that need more advanced handling, they are supposed to provide own handler and to take care of killing the menu buffer. I do have thoughts to rework the drawing code once more to allow entries in form of: (:separator sepeartor-string), similar as it takes group entries for submenus. It would allow for mixing horizontal and vertical layouts, but I am not sure if that is a good feature to have. It certainly isn't needed. I have reworked a bit org-capture, but I haven't yet worked on org-agenda restrictions and other details.