Every so often I look at the stubs of my generic undo library and find it woefully inadequate. I try to find more info about what's needed and how to implement it, but come up short.
It seems every GNOME program with undo has created its own special code for it. The code should be common and widespread. There are at least two attempts to create a generic facility, but they're out-of-date and unused.
I'm not sure what are the requirements. My best guess is:
- Contextual records so that undo can be limited to a selected scope. (E.g., Select a paragraph and undo changes to it, though other changes may have been made elsewhere later.) Maybe context should just be application-specific data.
- Two LIFO structures (per context?): one for Undo, one for Redo. Or, perhaps, a single structure (array, list, whatever) and a pointer to the current position.
- An Action structure with callbacks for Undo and Redo, data needed for those, and the data needed to represent it in menus or lists.
- Action compression for actions which, once done, should be treated as a unit for undoing and redoing.
- Disposal of no longer relevant data.
- (De)Serialization: To store and restore undo data between runs.
Especially because of the last item, I worry that a library for just undo is a bad solution. The serialized form could be made at least as human-readable as XML. If I can read the serialized form, then I can modify it wholesale in a text editor, open the document, and press Undo repeatedly to make the app do anything it can undo or redo. In other words, the serialization is a script.
And that's where I give up. The task is no longer just keeping some lists, it's writing a scripting or macro language. And how many of these do we already have? How many are fit to be read and edited by non-programmers? Should the primitives of the language (e.g., "insert" and "delete") be translatable? If so, will the syntax make sense? (Maybe "insert text" in English should be ordered as "text insert" in some other language.)
I could try to ignore the obvious (to me) extension of undo/redo into scripting, but I have trouble working that way.