# So I added this small feature to v10 called multiple undo

GROUPS:
 John Fultz 18 Votes If you've seen me speak at the Wolfram Tech conferences, or chatted with me by email or on any of the various Mathematica forums, you probably eventually get the message from me that folks at WRI pay attention to what you have to say. It's one of the things that I'm actually quite proud of my colleagues for...I see a bunch of them all over the place out in the public, mixing it up with our user base, and hearing what the community has to say about our product, and then discussing those things internally.So for a company with that kind of attitude, you've got to know that we were impressed at the level of organized vigilance on the part of the community in letting us know that Multiple Undo Is Important. It's a sometimes difficult position we're in because there are lots of people that we'd really like to satisfy, and in many cases with concepts that are genuinely useful and interesting. But like any company, there are limits to our resources, and prioritization is necessary. And sometimes really good ideas might be prioritized downward for any number of reasons...sometimes because very difficult choices had to be made, and sometimes for less noble (and in retrospect, perhaps silly) reasons. But you can bet that when Stephen Wolfram was faced at almost every user event with one of you folks consistently reminding him of the need for multiple undo, that there would come a day when he would insist that I completely clear my plate and make multiple undo my very top priority.So, thanks for that! It's been an interesting project with lots of challenges, and one which I'm very proud to have worked on. Now, for those who wish to indulge my tireless droning, here's a bit of info about the feature. Multiple undo is a better single undo than our single undo system ever was. One of my happy moments was, after integrating the feature into our development build, I went through all of our open single undo bugs. And, without intending to do so, I had fixed over dozen outstanding single undo bugs. One of the things I realized quickly as I was implementing multiple undo was that it's very confusing to realize where you're at in history. Did I leave undo in a state where the Input and Output cells correspond to one another, or are they subtly different? So I added a feature to make it eminently clear by dimming Output cells that don't match their Input counterparts. Furthermore, the dimming will only take effect if you make an edit that actually changes how things evaluate. For example, adding a comment or a non-lexical space to an Input cell will not dim the Output cell. Undo just wasn't so easy to implement in an environment which sits on top of a sophisticated typesetting system, is fully user-programmable, can have simultaneous streams of action which should be unwound from one another for undo purposes. So undo has highly efficient internal consistency checks. Should a bug or limitation occur that might create a state inconsistent with history, the system stops undo from continuing and prevents damage from being done to your data. By default, undo is limited only by memory, but it's highly memory efficient. Usually flipping Dynamic variable states is not undoable. However, you can make changes to a DynamicModule variable undoable by using the UndoTrackedVariables option. Also, each input field has its own independently tracked undo state which will keep track of changes which are produced programmatically or by hand. And we're not finished. Unfortunately, I'm still aware of a few bugs in the system which I'll be working on. And I have a few plans for expanding functionality, including: Allow user-assigned memory limits to undo state (which is documented, but not quite done in the initial v10 release...sorry about that!) More memory efficiency, including sharing of objects which might show up multiple times in undo history. Better programmatic control of and access to undo state Allow efficient disk spooling of undo state to reduce memory. Which, incidentally, is almost all we need to support crash recovery of files. And, well, need I say it again? Whatever good ideas we hear from you, the community. Enough words from me. Pipe up if you see any problems or have any suggestions concerning undo.
3 months ago
10 Replies
 Rodrigo Murta 9 Votes Congratulations John! It's an amazing advance to user experience.For me, this was the biggest complaint from new users. And now has just gone.
3 months ago
 Patrick Scheibe 5 Votes John, I just wanted to let you know how much I appreciate your efforts. Not only that you implemented multiple undo for version 10, but the general attitude to listen what the users have to say and to explain why some features don't work or cannot be implemented easily. I'm always amazed that you still show up in the stackexchange chat every now and then, although everyone will instantly fire questions at you. I do know that a company like Wolfram always sits in many chairs when it comes to feature/design decisions and that Wolfram needs to make profit, because after all the employees like you need to be paid. This makes it even more precious that so many of you guys try to connect to the user base.Thank you and all the people having "Comments & opinions expressed here are mine, and not those of my employer" in their SE profile for that.Patrick
3 months ago
 Michael Croucher 2 Votes Hi JohnBy far, this is the best feature in Mathematica 10. I hope to meet you some day and buy you a well-deserved drink. Thank you!Questions: Is it possible to determine how much memory is being used by the undo feature? I'd like to be able to see it grow or shrink as I do stuff Is it possible to see some sort of representation of the history? Cheers,Mike Croucher
3 months ago
 John Fultz 2 Votes Yes, there is some of the information you can get to programmatically (and even triggered using Dynamic). But it's undocumented and should not be considered an interface that will be stable through future versions. CurrentValue[FEPrivateUndoInformation[_NotebookObject, _Integer:1]]Every notebook has its own undo manager, so the NotebookObject reports undo information for that notebook only. Input fields also have their own undo manager, if you wanted to see the undo information for an InputFieldBox, you could pass in a BoxObject instead.The integer is just an indication of how many levels of the stack you want returned. The default is 1 (just the most recent thing). If you want everything, just pass a big machine integer, like 999999.Also, you can use RedoInformation to get information about the redo stack instead.Example: CurrentValue[FEPrivateUndoInformation[EvaluationNotebook[], 999999]]
3 months ago
 Frank Kampas 3 Votes Multiple undo has been number 1 on my wish list for years. Naturally, now that it's been done, I tell what number 2 is: the ability to split the notebook view and look at two different parts at the same time. That's so I can look at functions I've defined at the top of the notebook when I go to use them at the bottom.
3 months ago
 David Reiss 3 Votes Thank you John. And, I am sure, a loud thank you from the silent majority as well.However, the Redo documentation seems to need editing as it talks about Undo rather than Redo and seems to say that one can only do a single level of Redo/Undo. (But Redo does work!... it's just a documentation issue.)http://reference.wolfram.com/language/ref/menuitem/Redo.html