I would like to persist the Ace Editor's UndoManager
instance across browser sessions, the way the Cloud9 IDE seems to.
I have tried to stringify the UndoManager
object so that I may store it somewhere to later retrieve it like so:
let undoManager = editorHTML.getSession().getUndoManager();
let undoManagerStr = JSON.stringify(undoManager);
But the stringify call throws the exception Uncaught TypeError: Converting circular structure to JSON
I've also tried extracting pieces of the object for storage:
let redoStackStr = JSON.stringify(undoManager.$redoStack, null, 2);
let undoStackStr = JSON.stringify(undoManager.$undoStack, null, 2);
let dirtyCounter = undoManager.dirtyCounter;
.
let manager = new ace.UndoManager();
if(redoStackStr && undoStackStr && dirtyCounter) {
manager.$redoStack = JSON.parse(redoStackStr);
manager.$undoStack = JSON.parse(undoStackStr);
manager.dirtyCounter = dirtyCounter;
}
editorHTML.getSession().setUndoManager(manager)
But Ace doesn't like this at all and bombs out on CTRL-Z
I would prefer not to have to write my own file history manager when one already exists.
Edit
I was able to solve this using the answer selected below, but only after upgrading to Ace editor version 1.4.2. The above code was my attempt after analyzing the UndoManager
in version 1.2.8, which is why it's so different.
With ace 1.4 the second method you mention works, the only problem in your example is that dirtyCounter is undefined
UndoManager = require("ace/undomanager").UndoManager
undoManager = editor.session.$undoManager
var str = JSON.stringify({
$redoStack: undoManager.$redoStack,
$undoStack: undoManager.$undoStack,
mark: undoManager.mark,
$rev: undoManager.$rev,
})
var manager = new UndoManager();
if (str) {
var json = JSON.parse(str)
manager.$redoStack = json.$redoStack;
manager.$undoStack = json.$undoStack
manager.mark = json.mark
manager.$rev = json.$rev
}
editor.getSession().setUndoManager(manager)
But note that this will fail if you do this for sessions with different values.