Hold on... this is a biggie! I've been concentrating on the frontends recently and will continue to do so until I knock them into better shape. What follows is a direct consequence of this.
In what follows, by "insets" I mean "insets with parameters that can be modified with a dialog" Currently LyX is in a mess when it comes to insets and how to apply changes to them from the frontends. We store a pointer to the inset in the frontend and apply any changes directly. This breaks the "everything has an LFUN and goes through dispatch" rule and means further that modifying existing insets using (shock!) the LyX server is impossible. Some hard coded fudges exist but they're crap, can't cope with "complex" inset parameters and are all-together not satisfactory. I have been thinking about a Better Way. It will result in far fewer LFUNs and greater flexibility. Here's the plan: Communicating info to the GUI frontend =============================== We can tell LyX to open or close the dialog for an existing inset: LFUN_INSET_DIALOG_OPEN LFUN_INSET_DIALOG_CLOSE Note that we need just two LFUNs here. LyX will find the next inset following the current cursor position and apply the LFUNs to it. This is similar to the toggle scheme that JMarc and I played with some time ago (and that I'm going to resurrect). Indeed I think we should also have LFUN_INSET_DIALOG_TOGGLE that invokes the two LFUNs above. We can tell LyX to open an inset dialog when no inset exists, the idea being that the user can then subsequently create an inset by apply()ing the dialog's parameters. We'll need LFUNs for each inset type: LFUN_BIBTEX_DIALOG_OPEN LFUN_CITATION_DIALOG_OPEN LFUN_TABULAR_DIALOG_OPEN Communicating info to the LyX server ============================== If we want to modify an existing inset using the LyX server and thence the outside world, we must first pass this info /to/ the outside world. For this I propose LFUN_INSET_TO_LYXSERVER So what to pass and how? I propose using the Inset::write method to output the info in a consistent, documented format. We should also output the LyX format version, so that the outside app knows how to read the data. Thus it would receive buffer BUFFER_ID inset INSET_ID \lyxformat 220 \begin_inset LatexCommand \citet{Butler:Tsuda97,Tsuda:etal99} \end_inset It should receive BUFFER_ID for the not-too-distant-day when we can have multiple buffers being edited at the same time. It must receive INSET_ID so that the outside program can modify the data and then have it applied to the correct inset. Communicating info back to LyX from the world outside ============================================ Both the LyX server and the GUI frontends will use the same LFUNs To apply data to create a new inset at the current cursor position: LFUN_INSET_CREATE To apply data to an existing inset (and hence modify it): LFUN_INSET_MODIFY Both LFUNs will go through dispatch (of course) and so the data must be in the form of a string. I propose using the inset::write method for this too LFUN_INSET_CREATE would result in buffer BUFFER_ID \lyxformat 220 \begin_inset LatexCommand \citet{Butler:Tsuda97,Tsuda:etal99} \end_inset being passed through dispatch. The lyxformat data will enable us to read data from eg pybliographer that hasn't quite kept up with us or wishes to support a few LyX versions. We just send the string to José and Dekel's python scripts before passing it to the inset::read method. LFUN_INSET_MODIFY needs also the INSET_ID to be passed buffer BUFFER_ID inset INSET_ID \lyxformat 220 \begin_inset LatexCommand \citet{Butler:Tsuda97,Tsuda:etal99} \end_inset What we lose =========== The ability to create new insets directly from the minibuffer. Currently citation-insert Baker will insert a citation to Baker directly in the text. I think that's just hard-coding useless code for the sake of it. It can't be scaled to complex parameters and is neither generic nor powerful. Problems ======= The only real problem with this whole approach lies with INSET_ID. What should I use? The inset address? Will it be expensive to find the inset? (Currently we store the inset pointer in the frontend and apply() directly, but that circumvents dispatch() and isn't very nice, as I've already mentioned.) What do you think about the plan? Is it feasible? I think that it will clean up the whole area and will adapt automatically as LyX evolves. Thoughts welcome and good night ;-) Angus