design reminder -- thinking about undo


Subject: design reminder -- thinking about undo
From: Paul Rohr (paul@abisource.com)
Date: Thu Mar 02 2000 - 11:59:33 CST


AbiWord has a lot of subtle features that Just Work, but one of the coolest
(and most easily forgotten) is infinite undo. It's a feature that people
get used to very quickly, but never think to check for. The only time they
notice is when it doesn't work, and then they think...

... well, let's just say they think bad thoughts. :-)

Thus, we put a ton of effort into the product very early on (before it could
even format properly), to use piece tables to make sure that every editing
operation which changed the state of the document could be completely
reversed via an undo command, then reapplied via redo.

To help make undo "feel" more reasonable, there's also logic in there which
helps coalesce a sequence of similar actions into a single undo/redo event.
Thus, for example, typing can be undone and redone in chunks, instead of on
a per-character basis. Also, there are a number of user-atomic actions
which actually invoke a series of document-level changes, but which should
again be undone or redone as a single unit. Again, we've already done the
work needed to fine-tune the code so that for existing features this all
Just Works.

Try it:

  - Type a sentence with a single italic word somewhere in the middle.
  - Undo slowly until it disappears.
  - Notice how the formatting disappears as a separate step from the typing?
  - Did you backspace at all anywhere in the sentence?
  - Most people do, and each time that happens you get another undo step.
  - Redo slowly until the entire sentence reappears.
  - See how the same (simplified) sequence of events gets replayed?

  - Now cut and paste that entire sentence somewhere else, and type some more.
  - Undo and redo that sequence of events, noticing the granularity.

The reason I bring this up now is because I've realized from scanning a few
patches recently that many folks developing new editing features don't seem
to realize that they need to think about *all* of the following:

  - how to make the original change,
  - how much of that change should be undone as a single step, and
  - whether a series of such changes should be coalesced into a single step.

Once you know the answers to these questions, it's a lot easier to make undo
Just Work for your new feature, too, since you can model your code on some
existing editing feature which answers those questions in the same way.

Practical implications:
----------------------
1. If you're adding a new edit method which will change the state of the
document, make sure it only calls a *single* view-level method to do so.
(This may mean adding a new view-level method.) Otherwise, if your edit
method invokes two discrete view-level editing operations, those changes
will produce *two* user-visible undo actions instead of one.

To see whether you've got this right, invoke your edit method once, and then
hit undo once. Are you back where you started, or is the change only
partially undone?

2. For whatever your new edit method is, try doing it five times in a row,
then hit undo. Should that sequence of changes be:

  (a) coalesced into a single undo step (like typing or deleting) or
  (b) should it be five steps (like paste or toggle bold)?

If the answer is (a), then we'll probably need to figure out how to move
knowledge of that editing operation further down into the piece table, where
undo/redo coalescing happens.

Paul



This archive was generated by hypermail 2b25 : Thu Mar 02 2000 - 11:54:05 CST