Add inverse of decoration step to history

Is it possible to add the inverse of add a step to the undo history?

For example, if a change deletes a decoration, tr.setMeta({ type: 'deleteDecoration' ... }) and I’d like to do something like tr.setInverse({ type: 'addDecoration' ... })

2 Likes

No, the history just tracks document changes and not transactions or any other metadata.

So is what I’m trying to do (to undo a deleted decoration) not possible with the history plugin at all?

Another path i just though of is to keep my own separate history for decorations and chain the undo/redo commands… not sure whether you’d recommend this

No. It would be desirable to be able to add arbitrary events to the undo history, but that doesn’t actually exist yet (and it’s not entirely clear how that would work to support things like restoring metadata on deleted ranges when you un-delete them).

Ok, I opened an issue to start discussion: feature request: add arbitrary events to the undo history · Issue #800 · ProseMirror/prosemirror · GitHub

Is there a reason why re-calculating the decorations after each state change isn’t appropriate for you here? Is it a matter of preventing unnecessary work to recreate these decorations? or is there another issue you’re running in to?

Preventing unnecessary work - e.g. for comments, I’d have to separate keep a separate history of the deleted external data associated with the decoration

I’d want to support undo/redo for ranges that I render using decorations and store in a plugin, so that when content history is undone, the ranges are correctly restored. It sounds like I’ll need to fork the history plugin and add some extra facilities. Before I jump into it does anyone have any advice for me? e.g. an approach to take, dragons to watch out for, etc

1 Like

Add link to fork here. If I end up needing it I’d be happy to collaborate

Also, I’m not sure if this is something @marijn will consider adding to history plugin itself the above issue is pending response

For this purpose I’m currently diffing the doc (using findDiffStart and findDiffEnd) and just rebuilding the ranges by finding them from the markup. Not ideal but it works!

Would you mind sharing an example? Thanks!

@bradleyayers, @alidcastano, @rich
Folks, I stuck with the same issue. Comments feature is implemented using decorators and undo doesn’t revert them once user undo deletion of text with comments.

How did you manage to handle this? Please, share your experience if possible.

I added a couple of new steps that don’t modify the document (in that way they are no-ops), but instead contain information that can be used by a plugin to track ranges in a data structure that’s store separate to the doc. I had to fork ProseMirror a bit to add in a hook that would let me handle the undo/redo portion of it, but I don’t recommend that. Instead I suggest contributing to the latest RFC for tracers https://github.com/ProseMirror/rfcs/pull/12

Thank you @bradleyayers