A Modern Undo - Making undo usable beyond the last few changes
September 6th, 2006
Undo is one of the most fundamental features of modern software applications, yet it has hardly evolved since it was invented. And this is even though it widely acknowledged to be mostly useless when going beyond a few changes. This article presents a set of solutions to make undo far more useful. They not just blue sky ideas but actual features implemented and functional in e - the Collaborative Text Editor for Windows.
“By [undoing] repeatedly, you can gradually work your way back to a point before your mistake. This is convenient if you’ve made a mistake four or five commands back. It is marginally useful if you’ve made a mistake twenty or thirty characters back. And it is completely useless if your mistake is ancient history.” - Learning GNU Emacs (page 42)
Most modern software has an unlimited undo history, tracing the changes all the way back to the document creation. Yet, as the above quote attest, it is mostly useless beyond a few edits.
For some reason the introduction of unlimited undo seemed to be the end of innovations in this area. Maybe it was the because of the name. It was a convenient tick mark in the feature list, and what could you possible wish for beyond “unlimited”?
The main reason that undo has been mostly useless beyond the last few changes is that users get anxious in three ways:
- They lose any idea of where they are in the undo history.
Solution: Keep them oriented with a Visual Undo History. - They get unsure about what they actually just undid.
Solution: Show the actual change in context. - They get afraid of losing what they just undid.
Solution: Ensure they never lose their old changes by branching.
A Visual Undo History
By showing a visual representation of the undo history, we help the user to keep his orientation. We can even add helpful markers like for when the document was last saved. This also makes it easy to jump around in the undo history.
Being capable of quickly jumping back and forth from a previous document state can be extremely useful. Anybody who have done some writing have probably tried to let some paragraphs, which should be deleted, stand because of a nagging feeling that parts of it might be useful later. When you know that you can always jump back and retrieve whatever parts you find useful, you can write much more freely.
Visualizing the Undo History

The undo history is shown in a separate window which updates live as the user types. The vertical line of small circles on the left shows the history of the changes. Each circle represents the document as it was at a specific point in time. By clicking on a circle the user can revert the document to the previous state.
To the right of each circle is a one-line summery of the changes that lead to it’s current state. Changes are indicated by colors: green for insertion and red for deletion. It is put in context by the gray text surrounding it. The window is resizable so you can easily enlarge it to see more of the change.
The solid blue circle indicates the users current position in the history and the small marker (in dark blue) indicates when the document was last saved.
The history is pretty terse but users quickly learn to scan over it, easily spotting the major insertions and deletions.
Showing the change in context
For the undo history to have any value, we have to show the changes in context. Showing the user that he deleted a few letters in a set of changes that could be done hours (or days) ago, doesn’t give him much idea of what really happened. But if you show it in context, with the words that the letters were part of surrounding them, it becomes much easier to remember where the change fit in the bigger picture.
Branching

What happens if you undo a lot of changes, start making new edits and suddenly discover that you undid too far? How do you get back what you undid by mistake? In most applications you don’t. Everything that was underneath you in the undo history was lost.
By allowing branches in the undo history any such loss can be avoided. Whenever you go back in history and start making changes a new branch is created.
Basically your work is held to be sacred, and an application should never let you accidentally lose any work. So you can always go back to a previous branch and continue to work from there, or maybe just copy the useful parts back to your current branch.
Persistence & Crash recovery
In just about all applications the undo history is lost the moment you close the document. There is really no reason for this since the undo history (if it is properly implemented) hardly takes up any space, and there is no guarantee that you won’t need it at a later time.
In e you always have the full undo history, even after reloading a document from a previous session. Should the computer crash (or lose power) while you are working, it will just start up where you left of.
Innovation
It is amazing that a feature as fundamental as undo has seen so little innovation over time. And it is even scarier that it has been implemented in a way that leaves anything beyond the last few changes mostly useless. Especially considering how many system & programmer resources that are used to keep track of the unlimited undo
It really makes you wonder how many other fundamental software features that could be radically improved if you just looked at them with new eyes.
Reality Now
So is this the pinnacle of undo functionality. Not at all. There are lots of possible improvements, like partial & selective undo or interactive diffs, which are obvious next steps and could be very useful.
But it is easy just to come up with critique and blue sky ideas which have no basis in reality. So I have limited this article to features which are actually implemented and functional, so you can try them out in the e text editor right now.
Experience with the text editor has shown that these basic improvements to the undo functionality greatly improves the writing experience. Making users much more confident in modifying and experimenting with their text.
It is my hope that showing that this is possible will raise the expectations of users, so that they will no longer accept applications that routinely lose or make inaccessible parts of their work.
September 6th, 2006 at 3:51 pm
“checkpoints” would solve a lot of these problems. Rather than view changes individually, allow users to say “this batch of changes is a single change”. They can undo the individual changes, or they can rollback to a previous checkpoint. This would be practical if you inferred stable checkpoints, i.e. the user hasn’t done anything for a few minutes. Then you can implement all the other version control ideas into a terribly complex undo feature.
September 6th, 2006 at 3:58 pm
Seems to complicated for regular or efficient usage.
Rather than “intelligent undo” I’d rather have a “checkpoint version” feature that enabled me to save specific versions of a file while working on it, then discard them when I did a “final save” or some such.
Checkpointing corresponds more to how I create work as opposed to intelligent undo’s emphasis on wholesalve retention of intermediate steps…
September 6th, 2006 at 4:09 pm
“checkpoints” are actually supported in the e text editor. You can “Commit” the document, which equates to saying “this batch of changes is a single change”. This creates a milestone of the documents current state to which you can add comments and labels. All milestones can be viewed on a nice timeline.
But checkpoints don’t help you in the time between committing milestones, that is why we also want an undo that ensures that users never lose any parts of their work.
September 6th, 2006 at 5:09 pm
I definitely think branched undos would help a lot of applications.
Browsers:
A feature like this would be a great replacement for the back/forward system in browsers, which is exactly an undo/redo system. I’ve had some thoughts on making a branching browsing history system which would be like tabbed browsing on steroids. (NOTE: I hate losing my history when I’ve hit back a few times and then meant to go forward back to my location but lost my forward history because I clicked on something else)
Semantic undo/redo:
Another way to encourage experimentation would be to have documents to have more structure than just global raw text history. What if each paragraph could have it’s own history. This could get confusing, obviously a complete UI overhaul to support this type of system would be needed. But it would encourage making different versions of paragraphs to see how they all fit together.
September 6th, 2006 at 5:16 pm
The idea is good. Really annoying part of undo is when you go back, change something (semi-unrelated) and now can’t go ‘forward’ again.
September 6th, 2006 at 8:44 pm
essentially: being able to ‘delete’ (undo) a specific step i’ve taken way back without affecting the steps that ive made since
September 6th, 2006 at 10:30 pm
Visual undo lists and branching are currently available in the Adobe Photoshop History Panel, if you know how to use it. I believe this particular implementation is patented.
September 7th, 2006 at 12:51 am
I think you are asking from an undo system what a versioning system already provides.
September 7th, 2006 at 2:13 am
Even more important to me is not dumping the undo while the document remains open. With many current applications, you can *only* undo to the last save.
My personal method is any time I pause to think or go for a coffee or whatever, I save. This often results in me not being able to undo something… and is utterly stupid.
September 7th, 2006 at 2:07 pm
An undo/redo functionality using a slider was implemented in the ‘PE’ editor included in OS/2 in the early 1990’s.
September 8th, 2006 at 1:50 am
why can’t applications implement emacs-style undo (but unlimited)? if you type a character, then old undos become candidates for being undone. you can’t lose anything…
September 9th, 2006 at 11:44 pm
Most “unlimited” undo systems (as you allude to in #X above) lose changes when you undo them and then do something else. Emacs’s undo has never had this problem, because the “undos” just add onto the end of the list of things that can be undone, but this makes it even harder to get oriented. Most of the time I prefer the more common undo/redo style.
The current version of Emacs (since, maybe, three years ago) has “local undo” — if you have transient-mark-mode activated so that the current region is highlighted (like the “selection” in PARC-UI-derived software) then undo only works inside that region. It doesn’t work 100% of the time (this is probably impossible in the general case, but you could probably do a better job than Emacs does; perhaps SubEthaEdit’s data structure might be better for this), but it works well enough to be a major improvement in Emacs’s undo functionality, putting Emacs head and shoulders above every other piece of software I’ve ever used.
Generally “local undo” is the foundation of a lot of shared-document-editing systems that haven’t made it out of research labs.
cgoban supports branching “undo” lists and has a tree display for them as well, but that’s partly because it works in a domain (go games) where everyone agrees that the timeline of the production of the final result is as interesting as the final result itself. That’s been true as long as I’ve used cgoban, which is
December 4th, 2006 at 2:16 pm
Dude! Brilliant.
This is just the sort of thing that is desperately needed in every app. We have these massive harddrives and gigs of ram and insane dual core processors, why not use them to perfect the basics instead of gloming on more and more features?!
Any chance of porting that part over to TextMate?
February 22nd, 2007 at 12:27 pm
I agree, this is brilliant. It’s strange it doesn’t exist in more applications, but I agree that maybe the ‘unlimited’ wording might have something to do with that.
Keep up the good work
April 18th, 2007 at 2:23 pm
Well said! I think this is very insightful and I agree that better undo would benefit many application domains, and indeed, many different interaction modes. The future is all about undoing! Yes!