choey
choey

Reputation: 63

Persist the ACE editor UndoManager across sessions

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.

Upvotes: 0

Views: 277

Answers (1)

a user
a user

Reputation: 24104

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.

Upvotes: 1

Related Questions