Saturday, March 24, 2007

Documenting user interfaces the smart way

One thing that was always painful with jEdit was keeping the code and documentation in sync. For example, take keyboard shortcuts. For every command that I documented, I would manually enter the shortcut in the documentation, and before every release, I'd have to go through documentation by hand and ensure the shortcuts were up to date. Extremely tedious busy-work. At the time, I wasn't smart enough to understand what Emacs really meant by "self-documenting", but now that I've been exposed to more development tools and language paradigms, I'm starting to come around.

For a while now the Factor UI has had "commands", which are a concept found in many other UI toolkits, as well as jEdit, Emacs, etc. A command is an abstraction over an operation which can be performed by the user, and is often associated with a keyboard shortcut, can be added to toolbars and menus, and so on. in Factor 0.89, I refactored things so that commands are just words with some properties set.

Consider the article on the UI walker. For a long time now, the shortcut/command table there is automatically generated, with a markup element which refers to a command map by name, like the following:{ $commands walker-gadget "toolbar" }However the keyboard shortcut "C+A+w" is hard-coded there, and in fact as of Factor 0.88, it is out of date; it is just "C+w" now. The problem was that while command maps were "well-known" and were easy to identify by name, commands were not, they were just tuples floating around in hashtables (with no obvious "primary key" for you database people). Now that commands are words, I defined a new markup element which is rendered as the shortcut associated to a given command in a specific command map. For example,{ $command interactor "quotation" walk }The result looks exactly the same, but it is kept up to date when command maps change.

This is just the beginning. I want the Factor UI to feel like an extension of the language. This quality is hard to put in words, but perhaps CLIM comes closest to achieving this goal.