Recent Changes - Search:

WikiDoc

Categories

ModesAndStates

<JK Dec 2003>

Perhaps 90 % of the following is either uninteresting or besides the point, but if the remaining 10 % can serve as inspiration for something useful it will have served its purpose. Feel free to delete.

The need of a more differentiated mode concept is emerging. The needs group around two issues:

  • the range of available configurations (currently called modes) should no longer be arranged in a flat list, but rather in a more structured way.

  • the concept of mode should not apply only to windows but also to smaller quantities (juxtaposition of modes inside a window), or that a window could be in more than one mode at the time (superposition of modes).

The first issue should lead to some simplification and factorisation of the mode concept itself, while the second will lead to more complex relations between modes and text. It seems that the first issue should be addressed first, and that some of the cases of the second issue would even be adressed automatically by good approaches to the first (e.g. superposiiton could be avoided).

This page holds an outline of the idea I propose for the first issue. Concerning the second issue, there are some loose comments at the page Development.GuestModes?.

Vince adds: this proposal seems only to suggest that there is an extended 'Bind' command. How do you propose menus, modeVars, hooks, colouring, etc. are handled?

Also, one minor comment on what you describe: unBind is really defined as a 'destroy binding' operation, not as a 'this binding doesn't apply to this context' (e.g. in Alpha at present you can't do unBind Return {call...} Tcl to remove a global binding from Tcl mode).

Content/function --- mode/state

Windows in Alpha typically have content related to some programming language. To each language there should correspond a mode with certain appropriate settings, colourings, bindings, etc. Orthogonal to this classification it makes sense instead to categorise Alpha windows by their function: most windows are EDITING WINDOWS in which you write some text and save it for later use. Other windows are SHELL-LIKE; they represent an interface to some more or less interactive process. Examples of this are Alpha's shell (Cmd-Y), the Dictionary Console, various incarnations of TeX Consoles, or interfaces to other external processes. These windows, although you can edit them, are not in general meant for saving. Other windows of slightly different nature are BROWSER WINDOWS (as produced by batch searchs), or DIFF WINDOWS for file comparison. Yet another type of window are the READER WINDOWS (read-only); here several things work differently, like for example most keys --- which don't work at all! Other sorts of windows include rendering of html, address book windows, and so on --- the possibilities are limited only by the imagination of the developers.

In this proposal the categories of the content classification are called MODES, while the categories of the function classification are called STATES. (This terminology is completely open for discussion of course --- see the end of this page for a discussion of the clash in terminology with the notion of 'saved states'.)

This orthogonality understood, it becomes clear that several of the modes in the current sense should really rather be states, in order not to exclude functionality provided by true modes: for example, 'browser' should not be a mode but a state, to allow the mode to follow the content of the window (depending of the mode of the fileset being batch searched); ditto for 'diff'. Most importantly, 'Shel' as we know it from current Alpha is really just shell state of Tcl mode. The interactive aspects (characteristic for the proposed shell state) should be decoupled from Tcl and serve also other modes. Frederic's InSh package represents an important step in this direction.

So, every window should be in a mode (Tcl, TeX, HTML, etc.) and in a state (editing state, shell state, browser state, etc.) In most cases, mode Foo in the old terminology will correspond to editing state of the new mode Foo, but modes with the -shell flag set will rather correspond to other states of another mode. Notably, the current Shel mode will correspond to shell state of Tcl mode, and the current Brws mode will be browser state of the mode of the file or fileset in which the batch search was performed. As an example of a window that changes state: the TeX Console of tetexComm will be in shell state as long as tex is running and we are interacting, and pass to browser state when error browsing starts. Meanwhile it stays in TeX mode (or perhaps rather TeX-log mode).

Orthogonalilty of modes and states does not mean independence: not every combination is necessarily possible (what would be shell state of Text mode? some sort of chat window?), and a given state (e.g. shell state) may mean somewhat different things in different modes. The notion of mode is still the primary category, and the possible states of a given mode can be seen merely as submodes. Each mode is granted control over which states it will allow.

In this sense, all this is nothing but reorganising the flat list of modes (in the old sense) into a two-dimensional structure, and the transition to the new scheme will consist (in a first step) just in plotting the flat list into the new chart --- most of the list will map to the base line of the chart, since most existing modes will correspond to editing state, the ground state. In the first transitional phase, each mode might only allow one state, namely editing state (or perhaps browser state is also induced for free). Gradually then, each mode Foo that can see any advantage in the new scheme could migrate, setting its entry in the global array which defined the shape of the chart:

 
    availableStates(Foo) [list editing browser shell]

Other modes like HTML, which might not have much advantage from the new scheme, will never need to do anything... [[Or who knows? the mere existence of the possibility of an interactive state of html mode might lead somebody to invent it: it could be something like writing a line of html code (ignoring headers and such), press <return>, and in the nearby open web-browser window, the rendered result of this line appears. This might be an interesting synchronicity feature --- or it might be completely useless; html writers will tell.]]

Since the distinction content/function appears to be rather deep, one could expect that building it into the very mode concept will allow simplifications and easier factorisation of code. One main concern and motivation for all this is the possibility of a more generic shell notion. Isn't it possible to lift Shel mode out of its current place in the flat list of modes, and let it define something generic that could be the shell state of many modes corresponding to scripting languages or math programmes? This is also the most difficult part of the new design, because it is clear that the shell specifications differ a lot from mode to mode (compare the Alpha shell with a TeX Console --- should these disparate things really be forced into the same framework?) The challenge is to make the shell notion generic and flexible --- any mode should be able to override the generic approach if needed, with plugins, hooks, mode procs or whatever.

These problems should not halt the development in my opinion. On the contrary I think the best way to go is to implement the notions, and then start implementing shell states of the modes in need of it --- time will tell how the factorisation is best defined.

Implementation

Presumably the state concept could be implemented just as modes are implemented: a global variable which changes according to the frontmost window, and perhaps with a state indicator of some sort (similar to the mode indicator?), changeState hooks, etc. The state flag -shell already exist, and it should just be raised to a more prominent status and have more mechanisms attached to it, or rather: be incorporated into the general notion of state.

So now there are two global variables instead of one. It remains to go through all references to the old notion of mode and decide whether this should rather depend on state --- in most cases it will probably depend on both. This can probably also be done gradually.

Once the general notion of state exists, it should be discussed how the functionality of each state can best be generalised so that as many modes as possible can take advantage of the same modules of code. This problematic applies in particular to the standard states: shell and browser. (Note that editing state can probably be considered as a 'ground' state, and that the other states might be defined relative to the ground state. Thus perhaps instead of defining what a given state should do, explain what it should do differently from editing state...?)

One area where different states of the same mode will need to differ is that of key bindings. Typically shell states will want another interpreation of <return>, <tab>, and arrow keys. One practical approach to defining bindings would be to have one Bind command and in the end of its argument instead of having the mode, have two arguments: mode and state.

Possible syntaxes for a Bind statement could be

 
    Bind 'letter' <modifiers>  someFunction Mode/state

to indicate that it will only take effect in that combination of mode and state, or the usual old syntax

 
    Bind 'letter' <modifiers>  someFunction Mode

for bindings that are common to all states of a mode.

One could also imagine a binding of form

 
    Bind 'letter' <modifiers>  someFunction global/state

which means that the given state of any mode (if it exists) has the binding, with the convention that Mode-specific bindings always override global ones. Hence one could define for example

 
    Bind 'Return' { mode::proc sendCommandToProcess } global/shell

then have a fallback such proc, and a mode specific proc for each mode. A mode Foo *not* wanting this could do

 
    unBind 'Return' { mode::proc sendCommandToProcess } Foo/shell

if <return> has a completely different meaning in shell state of mode Foo.

All this is just a new way of organising the different slates of setting that make up a mode. But I think there are many advantages to this more structured approach. In addition of those outlined for Tcl/Shel, it will also help to keep the number of modes down to a reasonable size. (I previously proposed a notion of hidden modes for all the current modes that are in reality expression of a state. This proposal will be withdrawn.)

Shell state

The main motivation for the whole concept of state (although I try to argue that it is nearly forced upon us by the natural distinction between content and function) is the proliferation of interactive interfaces to text based unix programmes: in due time Alpha will become the preferred interface to unix and the text-based parts of your computer, just like its great image emacs.

For every scripting language or math programme there will be an Alpha interface, and certainly these interfaces could take great advantage of the corresponding modes that mostly already exist in Alpha. There will be two "workings" for each language or programme: one for editing source code in that language, and another for communicating with the corresponding interpreter or compiler. Both these workings relate to the same programming language so they should be the same mode, but one should be in editing state, the other in shell state.

The development of these interfaces is still in an initial phase. It has become clear that a whole lot of technology is common for all these interfaces (although of course there are also quite disparate individual features involved). They will all need to define a lot of stuff (prompt handling and command history) that the old Shel mode has already defined, and which could be reused if suitably generalised.

Time will tell how much shell functionality can be factored out to work for several different modes. The work of Fr√İd√İric on InSh indicates that it might be possible to factor quite a lot: InSh implements a completely generic interactive interface to (in principle) any interactive text based unix programme. Here, the user's key presses are transmitted raw to the external process, and the input from the external process is written verbatim to the shell window. In many cases however, it would seem natural to try to improve on the unix interactive interface instead of just importing it as is.

Note that many command line math programmes never tried to implement any good interface themselves. They are *designed* to be interfaced in an editor --- typically the preferred interface is emacs! Where such an emacs interface exists, of course it will be advisable to let it inspire Alpha's interface, although typically many things can be done in a more logical way...

Among the things that can be improved upon is command history, command completion, and prompts. A very illustrative example is the existing Alpha Shell, which can be seen as a shell-state Tcl mode thing interfacing a Tcl interpreter. But in fact it does a lot of preprocessing which makes it much more userfriendly than standard tclsh, e.g. command history interface and command completion... Concerning prompt handling, the same philosophy applies: Alpha can easily be *more* powerful than the external programme it is interfacing, like having "<file tail pwd?>" as prompts instead of merely "%".

Other examples of tiny adjustments are found in tetexComm, where certain commands from the user to tex are intercepted: the 'e' command is intercepted: instead of telling tex to tell Alpha to go to a given line, we go directly to that line. (This requires knowledge about include files.) This design was necessary in the beginning, before the existence of 'alphac', but even today I don't think it is completely crazy to make this shortcut... Another interception is that of 'x': it is actually sent, but the preserveOldAuxFile trick is performed first.

When a general shell-state notion emerges, of course it is desirable that it be as general as possible (i.e. like InSh), but it should also allow mode-specific plug-ins. So what will be common for such shells? they will have certain prompts, there will be an external process to process the command and return a results, and this result should be presented in the shell window in the appropriate place. Then there may be a command history, and perhaps a mechanism for jumping back to previous prompts and execute them again. (This is already a lot fancier than most interactive unix programmes --- this functionality will be one advantage of running the programme in Alpha and not just switch to the Terminal and run them there.)

So each mode will have to provide information about prompt handling (or instruction to use the raw prompts from the process), and information about pre-processing of command strings or post-processing of strings returned from the process (which again, could be trivial information). And first of all the mode will have to explain which external programme is used and how it is called. This last bundle of instructions in turn should be api'fied too, and 'InSh' and app::setupLineBasedInteraction show the direction to go. (And a proposed generalisation of setupLineBasedInteraction is in the wraps.)

It should be noted that instead of trying to squeeze some exotic shell instance into the general shell state notion --- or worse, over-generalise the shell state notion just to make it accomodate that exotic case --- one could consider inventing a new state. For example, one could argue that a tex console is not really shell like, because even if some limited interaction exists, most of what is shown in the window is rather of type 'messages' than return values of commands. Well, why not invent a CONSOLE STATE, which could also accomodate interfaces to gcc, fink, unison, or others. Another situation which is perhaps too exotic for the shell state notion is the Dictionary console --- here at least some flag like 'outputReplacesWholeConsole' would be needed --- perhaps it is more reasonable to define a new state for this purpose...

Some other standard states

BROWSER STATE: Browser state is just a browser window, but where keyword and comment colouring depends on the mode of the fileset in which the batch search takes place. This will immedately improve the usability of the browser window over the current generic browser 'mode', because the colours will make it much easier to spot exactly what you are looking for, and in particular the comment colours will make is easier to ignore those lines.

DIFF STATE: The content of the diff windows will be some text in some language, hence the mode is actually determined by that. But the functionality of such a window, with patches, conflict solving, or whatever you want, is probably sufficiently different from other ways of manipulating the text to merit its own state. For example, search could work like this with two windows open at nearly-identical files: search simultaneously in both windows, etc.

READER STATE: (This is meant for files which are read-only, but it is a more specific attribute than the mere read-only flag: there are other examples of read-only windows which are not reader windows, e.g. batch-search browser windows or rendered html...) At first look, reader state may seem like a uninteresting state --- why have such a state at all? isn't the lock/cvs icon sufficient? In fact, once it becomes a state a host of possibilities open up: how about some of the commands from vi in escaped mode? 'more' and 'less' commands? how about mimicking some navigation shortcuts from xdvi or ghostview? These make sense in any mode, and since now we can link such bindings to the state instead of just to the mode, all modes can get this for free (just as we already have a special treatment of <space>). (This sort of bindings could not be linked to read-only in the old situation, because also browser windows are read-only...) Two important examples of reader state are found in Tcl mode and Help mode: each of these could define tab (or enter, or another key) to some sort of next item navigation. [[Well, all this is equally useful in editing state... Perhaps you'll say that we don't need reader state, and that it is just a special case of editing --- but once you say 'special case of editing' you are already inside the whole state way of thinking... Perhaps it *is* a rather uninteresting state, but I think it is a state nevertheless.]]

Another possible state could be RENDERED STATE. Rendered state is read-only just like reader state, but in contrast to reader state it does not display the actual content of the file but rather a rendered version of it. This is pertinent for html mode and for wiki mode. New menus could appear when a document enters rendered state, like 'Set Bookmark', 'Download Link', etc. [[Of course all this already exists in the www menu, and what I am describing is just WWW mode! Well, yes, right, but perhaps this should rather be a particular state of html mode instead? Perhaps not... The main argument is that this particular use of Alpha is characterised by its function not its content... Change the state of such a window to editing: you'll get the source code shown instead (with the cursor at the appropriate place, if this is well-defined...), make some changes, change the state back to rendered state, etc. (Surely HTML mode sports much better interfaces to this sort of functionality --- each time I imagine some smart feature for html it is only to find that I am reinventing the wheel (and not in a very round way).) (Side question: Can wiki 'code' be rendered directly in Alpha?)]] The notion of rendering could make sense also in bib mode and in other documents implementing databases: the rendered version could look like when printing labels from an address database, or like the output of parray. And so on: perhaps rendered state is not a big deal either, but a state nevertheless...

Who knows? isn't mail mode rather a MAIL STATE? The content is usually just text, hence Text mode, but the surrounding 'widgets' (in the same text window) represent a different way of handling the text. If at first sight this sounds unnatural this is probably just because in any case Text mode is almost like absence of mode. But what if somebody wants to send a mail in html format? --- this is getting more and more widespread. He will realise that 'mail' is actually rather a state than a mode... What about the message listings? are these browser state windows in Mail mode, or Text mode? Perhaps they have special features which warrants the conception of a new state? Indeed, there is another obvious role for browser state of Mail or Text mode, namely for the result of searching the mailboxes. Perhaps the right interpretation of the situation is this: 'mbox' is a mode for editing raw berkeley mailboxes, and in a certain state you only see the message listings --- this state is not just browser state; browser state is used when you search you mailboxes for something... but note that browser state of mbox mode is somewhat different from browser state of other modes, since here we list not only which file the match is found in but also which mail inside it. [[So this paragraph started as an apology for some sort of mail state, but ended up as yet another argument for the viewpoint that 'browser' is a state not a mode...]]

In any case these ramblings support the observation (first made by Fr√İd√İric) that the notion of state must be dynamic: instead of a fixed number of predefined states it should be up to developers to invent new states when needed.

Who knows: someone writes a debugger for Tcl; clearly this should be in Tcl mode, but it will probably need features not conveniently covered by any of the above states, prompting for a notion of DEBUGGER STATE. (And because of the nice decoupling of function from content, perhaps this debugger will quickly be ported to other modes than Tcl!)

If somebody implements a messenger device, wouldn't that be too exotic for shell state, requiring instead a new CHAT STATE?

Or when Alpha finally gets a file browser (so that we can finally avoid that nasty Finder altogether) it will seem unlikely that any of the known states could accommodate that, we'll need a FINDER STATE.

GUEST STATE: There is another discussion about modes, namely concerning the idea that modes should not only be coupled to windows but also to smaller regions of text, cf. the page Development.GuestModes?. If certain regions can be in another mode than the main document, then only certain functionality of the visiting mode can be imported (for example all document specific functionality cannot be imported as it would clash with the functionality of the primary mode for the window). So a restricted version of the visiting mode should be active. This notion could conveniently be implemented as a particular state of the mode. So: GUEST STATE of a given mode contains all the functionality that it makes sense to export to a region in a window in another mode. So if a mode wants to offer the posibility of appearing as guest in certain regions in other-mode windows, then it has to define a guest state. (See Development.GuestModes?).

Page last modified on October 30, 2007, at 02:08 PM
Hosted on SourceForge.net Logo