Implementing efficient multiple undo

126

48

At the time this question was asked, version 10 was not out yet. The Front End of Mathematica 10 does have multiple undo, see the answer by John Fultz.

The Mathematica Front End's built-in Undo command can only undo a single editing step.

Has anyone implemented or seen implemented an efficient and comfortable multiple undo?

I have in mind ideas such as, CellEventActions that keeps a stack in the cell context pushing the cell state every time a key among a list (brackets, @, operators) is pressed. Some other shortcut to recover older states (or a palette, or perhaps tweaking the front end's .tr files??)

I am not familiar at all with typical text based implementations and their issues. I guess it wouldn't be a practical problem to lose the undo state between sessions, would it?

So, has this been done, or is it doable or practical? What are your thoughts?

Rojo

Posted 2012-02-18T07:37:48.867

Reputation: 40 993

http://undo-for-mathematica.alaifari.com/ – Nam Nguyen – 2013-12-26T02:34:06.973

@JacobAkkerboom I cannot find that sentence on that page, only this: "Post edited at the request of Wolfram Inc. To remove information about Mathematica 10 and new features coming for Wolfram Alfa etc. According to a Wolfram representative the entire conference is now covered by NDA and can not be blogged or tweeted about." – Alexey Popkov – 2014-01-08T10:34:49.020

@AlexeyPopkov ah well I assure you it was there. Thank you for noticing, I knew about the issue and that something would be/had been changed, but I did not realise this particular statement had been removed. I suppose I will give R Hall a break and remove the comment. – Jacob Akkerboom – 2014-01-08T10:44:54.370

1@JacobAkkerboom I believe you and the sentence I cited explains why such a significant statement was removed ("non-disclosure agreement"). But may be there is a video of this conference with that statement? In any case, thank you for citing, it is wonderful news. – Alexey Popkov – 2014-01-08T10:55:45.393

2

Now that Mathematica 10 has been released, note that among new features is: "Computation-aware multiple undo The problem of multiple undo in Mathematica has been solved!". See http://www.wolfram.com/mathematica/new-in-10/for-existing-users/.

– murray – 2014-07-09T18:57:36.157

Can't we use FrontEndExecute[FrontEndToken["Undo"]] to perform this. Looks like this could help. – GarouDan – 2012-06-25T23:08:26.980

@GarouDan it could help, but no more than clicking on Undo which seems to only work once in a row. Could you get that to work more than once in a row? – Rojo – 2012-06-25T23:17:06.423

The truth is I couldn't to perform Undo using that command. I tried some things but nothing worked. But if we can perform just a single action I would need a tool that put all command of a kind of stack. Looks complicated. – GarouDan – 2012-06-26T19:02:44.230

15I can't undertand. Why Mathematica is missing this? This action is extremly needed and useful. And missing until latest Mathematica versions. Lol. Why? Maybe someone should contact Mathematica and show this question for them. – GarouDan – 2012-06-26T19:03:50.097

@GarouDan: allowing for undos is something that is very costly, in memory. Since Mathematica sessions are usually, by natural, computationally intensive, it is a choice to not make undoes a priority, thus sparing everyone from the overhead of having to (potentially) save the output of very large computations. – Jérémie – 2012-08-15T01:11:55.457

The multiple undo in 10 is great but doesn't always undo as far as I'd like. Is there any documentation on the bounds of how far back in history undo works? – M.R. – 2016-01-19T01:04:21.077

@Jérémie Perhaps Undo could be an optional state that automatically turns itself off at the end of a session (or when commanded to do so). This way the user could decide when to accept the overhead when working on a delicate piece of code that may require using multiple Undos. – DavidC – 2012-09-24T22:46:57.293

would be nice to have an undo tree like in vim – kirill_igum – 2012-11-04T23:20:30.643

@Jérémie: Kernel sessions are computationally intensive. Undo would be a feature of the front-end. While graphics can use a fair amount of memory, that problem is surmountable (works fine in GIMP). – Mechanical snail – 2012-12-03T11:43:16.173

+1, I also proposed something like this in the mathgroup post linked here: http://groups.google.com/group/comp.soft-sys.math.mathematica/browse_thread/thread/22c78ca73df96e6d/a2415e9021f5d9df?lnk=gst&q=noeckel#a2415e9021f5d9df

– Jens – 2012-02-18T08:03:59.000

5

This certainly seems possible at least for the "Program" - style cells, and I have plans to integrate this as a feature in the next versions of the syntax highlighter, which you are probably familiar with. Since my highlighting engine is grabbing the cell's contents on every trigered event, this should be a relatively simple matter to do. One problem I face here is that I don't know how to trigger the CTRL key (or its equivalent on other platforms) yet.

– Leonid Shifrin – 2012-02-18T21:41:23.970

1@LeonidShifrin I would happily write Undo[] multiple times, don't let Ctrl get in your way. – David – 2012-03-06T07:35:59.113

@David I'll see what I can do :) – Leonid Shifrin – 2012-03-11T17:26:36.150

@rcollyer I'd be most happy to, but have no time now. I intend to do this and will do this in time. All I can say right now is that within my highlighter approach, this is possible. But, I first need to rewrite the highlighter engine, to make it cleaner and more extensible. I don't want to produce garbage :-) – Leonid Shifrin – 2012-03-13T08:42:51.797

@LeonidShifrin, that's too bad. I'll look forward to it when you get the time, then. – rcollyer – 2012-03-13T13:59:13.090

@rcollyer Sorry to disappoint. But this certainly looks like a problem for which careful and extensible design is essential, because there are just too many things which can not be guessed (at least by me) in advance here - and addressing those better not require a full rewrite. This also will not exist in isolation, but I rather plan it to be a part of a larger toolkit, so a good integration with other stuff will be essential as well. – Leonid Shifrin – 2012-03-13T14:05:57.363

@LeonidShifrin I figured that careful consideration would be required. As part of a general toolkit, would be very nice indeed. So, we'll see it when it gets done. Until then, good luck with it. – rcollyer – 2012-03-13T14:08:14.263

@rcollyer Thanks! – Leonid Shifrin – 2012-03-13T14:09:42.657

2http://undo-for-mathematica.alaifari.com/ – Tyilo – 2013-08-24T22:45:29.643

@Tyilo I'm not sure Tom Bombadil (79) can help the case here... – István Zachar – 2013-08-26T22:38:47.323

Answers

49

I implemented a multiple undo mechanism in v10.

It's not as perfect as I would like it to be, yet, but it does a pretty decent job in my experience. And a few of the documented options for it got ahead of the implementation...think of some of that stuff as a "coming soon".

Feel free to ping me on any problems you find with it.

Edit: In 10.0.2, all of the documented options are implemented except for "SpoolDirectory".

John Fultz

Posted 2012-02-18T07:37:48.867

Reputation: 12 166

How perfect would you like it to be? As in what specific elements would you have liked it to have? – jVincent – 2014-07-13T20:23:42.987

@jVincent Speaking as someone who had to think about every aspect of the system, I'm always seeing lots of bugs and limitations, many of which might be rarely noticed outside of Wolfram. In some cases, things that should be undoable but aren't. In some cases, undo falls over and does the wrong thing (I have significant internal consistency checks that tend to prevent undo from causing harm, but it will stop and wipe the undo stack in such a case). But my own priority/embarrassment list might not match those found by users. So, we'll see what the community judgment is. :) – John Fultz – 2014-07-15T17:34:38.777

2Awesome! First complaint: I should be able to hold down ⌘Z or ⇧⌘Z and have it repeatedly undo/redo :) – jtbandes – 2014-07-17T08:00:52.947

@jtbandes Thanks for the complaint (really!)...that's a pretty decent suggestion. It's odd that I've never tried that before despite the fact that I commonly do it in text editors. – John Fultz – 2014-07-28T00:57:31.453

Can you please take a look at this? It seems to be a bug in the undo feature (confirmed by Rolf). I'm just posting that here since you implemented the feature :)

– Öskå – 2015-01-16T19:46:23.687

19

I made a simple version control and undo function. (Since it uses system commands right now it is only tested for Linux. Windows support is added but not tested. MacOS is not tested either.)

Here is the link to undo.m or the github if you just want to try it (and trust me enough to run the code without checking) run

Get["https://raw.github.com/jensbob/mathematica_undo/master/undo.m"]

Would be great to have some feedback with ideas how to improve it, also I didn't test this a lot but it seems to be working fine. It is probably not the most efficient way but I think it is a good start.

From the readme:


This package adds a poor mans version control and undo functionality to Mathematica. For a previously saved notebook 'notebook.nb' a version info file 'notebook.nb.undo.mx' is created and every time changes are committed a backup file 'notebook.nb[version].bak' is created. System menu entries in insert are created.


Keyboard Shortcuts

Alt+z : Undo

Alt+x : Redo

Alt+s : Commit

Alt+d : Opens CommitInfo Dialog


Usage: Evaluate the following commands

ManualCommit (Default) - Only do commits manually.

AutoCommit - Turn on automatic commits. Every time a cell is evaluated a new commit is made. (This can lead to a lot of files)

CronCommit[n] - makes a new commit every n minutes.

CommitNow - Making a commit CommitInfo - Show a list of all Versions CommitClean - Remove all commited files

Undo - Undo to the previous commit Redo - Undo to the next commit GotoCommit[n] - Go to the n-th version


NOTICE

When altering not the latest version, the changes (when running undo or redo) are not saved, only when running 'commit' these changes are changed (with a new highest version number). Only changes to the version with the highest version number are changed upon 'undo'

Whether a commit needs to be made when running undo is checked with a system variable that can be altered by manually saving the document. Leading to possible loss of changes. For best results do not save the notebook manually and turn auto save off - just use commit to save the work.

EDIT: This version also has problems with individual context for each notebook, so just be warned. :)

jens_bo

Posted 2012-02-18T07:37:48.867

Reputation: 1 704

thanks to Chris Degnen for helping with the keyboard shortcuts. http://mathematica.stackexchange.com/questions/16165/how-can-i-set-a-keyboard-shortcut-to-run-a-command

– jens_bo – 2012-12-12T16:04:44.867

from looking at the code, it should work under OS X (the default shell is bash) – acl – 2012-12-12T22:48:56.070