Guest modes

<JK:Dec2003>

This page is a scratch pad containing some loose ideas that perhaps might find their way into the main page AlphaTcl and Modes once they have matured a little bit more... I meant to organise this into something readable, but now after several months there is still no sign of progress...


Remark: The notion of multi-modes has been considered in emacs (cf. Paolo Gianrossi: http://yersinia.org/homes/paolino/emacs/multi-mode-mode.el ). Here specific tags in the text delimit the regions of each mode...


Juxtaposition

The notion of juxtaposition of modes would come in handy in situations like HTML documents containing java script, a Tcl document containing lots of of comments (for which some sort of plain Text mode would be a more appropriate editing environment), texi or dtx documents etc. The issue comes up in general when you are documenting some code or language, e.g. writing a wiki page about AlphaTcl --- most of that document should certainly be in Text or Wiki mode, but all those four-space indented code snippets would benefit from Tcl mode features...

In all these cases it seems there is one of the involved modes which is

primary and others secondary. In other words, it will always be clear which mode is embedded in the other (e.g. a HTML document with java script could not be sent directly to a javascript compiler, and a wiki page about Tcl could not be compiled in Tcl).

In any case it will seem to be a practical advantage to stipulate that Every window is in one (primary) mode. And then it may contain cells with behaviour of foreign (secondary) modes. It is up to the 'mother' mode to specify cells to host other modes. In a non-hierarchical model, which mode would make this decision?

Alpha already has a primitive version of this sort of workings, namely comment areas: for example, indentation works differently in commented areas of (say) a Tcl document than in a clean Tcl context.

[In a separate thread I am brewing on a general notion of worksheet: worksheets are basically Text documents with certain cells linked to an external programme. These cells should certainly benefit from functionality inherited from the mode corresponding to the external programme. With the notion of worksheets, there is possibility for blurring the distinction of primary and secondary mode: in one end of the spectrum of worksheets we are just having a Text document with a few active cells; in the other end of the spectrum we have a shell! --- a shell with perhaps a few lines of plain text (cf. Maple worksheets and Mathematica notepads).]

Guest modes

OK, so every document is in one mode. This mode is granted permission to define GUEST MODES. This means two things: define guest regions (a proc to decide whethere we are in a guest region), turn on a discrete lamp somewhere to indicate to the user that now there is a guest mode, and define which aspects of the guest mode should be active. Here it may be convenient to formalise the notion of aspect of a mode: let's say there are some basic aspects (cf. discussion on the page AlphaTcl and Modes: colouring, key bindings, completions, automatisms, settings, menus-and-menu-items, file extension mapping... Now not all of these are suited for import. For example it might be better to let the menus stay constant. Certainly file extension mapping is not importable since it refers to whole documents, not small chunks. Probably the definition of child cells should not be importable --- it will be too confusing to have grandchildren (or to allow slaves to have slaves, or guests to have guests, or whatever will be the terminology). Probably, it will also be necessary not to allow guests to keep their notion of comments. A guest cell may be commented out in the mother mode, and if the guest cell overrides the notion of comment char this will not be properly detected. Conversely, a guest cell may contain guest-comments, but this does not mean that the text chunk is ignored by the compiler of the main mode, so the question isInComment? should not refer to the comment definition of the imported mode. So let us agree that comment handling is not an importable aspect either.

The main interest is perhaps key bindings, automatisms, and settings. Settings: e.g. fillColumn, wrap. More generally, everything automatic (not trickered by menu choice or key binding) will probably be importable: the fact that a feature is automatic (colouring, completion, indentation, wrapping) means that it is determined by the context, and the cell is precisely a context.

Concerning key bindings, it would not be desirable simply to turn off all bindings of the master mode and give control to the invited mode --- what about then those keybindings of the master mode that control the guest? We cannot just import bindings one by one either, because there is a priori no way to know what bindings the visiting mode might have that could conflict with the ones of the master mode... Certain key bindings of the visiting mode would not make sense at all in a small cell --- they might be document based. For example 'TypesetDocument', many navigation procs, nextFunction, nextSection, and such --- these should probably not be exportable. Also functions marks popup menus... not exportable.

So there is here a whole complex of issues to deal with: which features are exportable and which are not? Perhaps it depends on which modes exporting to which primary mode. In any case there is a notion of some sort of limited or restricted version of each mode, export-only, In the vision of Modes and states each mode has an EXPORT STATE.

Implementation

In contrast to the primitive comment-block secondary behaviour we know from current Alpha, it seems some new monitoring mechanism will be needed. For comment areas, the only modified behaviour is that of indentation: hence the task of detecting whether we are in a commented area can be handled when needed, every time <return> is invoked (possibly automatically). For the envisaged child mode concept, EVERY key press would have to poll the cell-detector, because completions might be cell specific... Hence it would seem better to record this information at a low level, as a value of a global variable, just like the current implementation of 'mode'.

Now the current modes can only change in a few ways: either when a new window comes to front, or if the user specifically requests the change. Hence it is easy to keep the mode variable up to date. For the notion of guest mode, the mode can change much more easily: a cursor movement, or even a typed character --- it might be the cell delimiting character!

So what can we do? it will seem necessary to monitor every typed character in one way or another. Experience with the isIn procs shows it can be a quite time consuming to determine whether the cursor is a given type of area...

Perhaps some accumulative approach could be put in place: I mean, this question has to be asked for every typed character, but this also means that for every typed character we know what the active mode/guestmode was just before the character was typed. Hence it will be enough to 'compute the difference': does the typed character make any difference compared to the state of the previous position? Of course this will not work for cursor movements: perhaps it is really necessary each time the cursor is moved discontinuously to call the general cell-detector to compute the current mode/geustmode from scratch...

[Vince] adds. One way around the implementation difficulties you describe is to put the onus on the user: to enter a sub-mode, the user must explicitly type some key combination (option-m, say), which searches for surrounding 'guest mode tags'. In many ways this would be better, since it might be annoying to have the sub-mode change just while paging-down through a large document. The one case where it would be worse would be in a comment-editing environment.

How should syntax-colouring work? Should or could Alpha allocate a particular window region to colour differently?

Terminology

In any case, I guess, the notion of mode is just an abstraction for a pile of features active at any given time or point, and this pile of features is perhaps internally just a flat list anyway. So what is going to change is just this abstraction level, the organisation of the concepts which allows user and developer to understand how Alpha changes within a document. So it will be pretty important to have good terminology --- there are many possibilities:

Host mode and guest modes.

Primary mode and secondary modes.

Persistsent mode and temporary modes.

Master and slave modes.

Home mode and imported modes.

Mother mode and child modes.


Unrelated remark:

Superimposing modes or some sort of inheritance mechanism...

One could imagine for example TclTk 'mode' as a superset of Tcl mode, or a descendant, or whatever will be the terminology. One could go further and layout all modes in a tree-like structure, with C, Tcl, Perl, etc inheriting functionality from a more abstract Programming Mode, while TeX, HTML, and XML inherit from Markup Mode. (Some notions of current Alpha are actually Programming Mode centric, like the Functions Popup Menu, others notions like wrapping and filling are really Markup Mode centric...) I have no idea how this remark could lead to anything useful...


Here's how I would implement the sub-mode-selection process. The user is responsible for selecting some text and then setting the submode for that text from a menu somewhere. Then the window would hold some meta-data indicating the first and last positions in the text buffer and assigning this pair to the appropriate mode. This meta-data would then be stored with the window (assuming that we're saving Window State information). Movement of the cursor into and out of this region would trigger a mode change. Notice that normal typing (where constantly checking position to decide our mode might unacceptably slow down Alpha) should not result in crossing these internal mode boundaries (it should expand the boundary, like coloring) so Alpha only needs to check to see if it needs to change mode when we jump around in the text.

Ah, but it is a pain in the mouse to actually select text and then change mode manually. I agree, so mode developers could do this programmatically in the most common cases. For example, the person writing HTML mode could do the following:

agm Feb102004

[Vince] suggests that rather than the user having to select some text, any mode which wants to support guest modes could define a procedure which the user can trigger ('activate child mode'?), which (while it could use a selection if one was given) would normally search forwards and backwards until it found a region it considers viable for the child mode. This would then activate the child mode on that region. Immediately the insert position is moved out of the child region, the child mode would be deactivated. It might even be possible to activate the child mode as an embedded window within the main document, containing the given text.


Category Development

Category Modes