Change Object coordinate systems when dealing with undo

Hi Marijn - as always, thanks for your tireless work on this fantastic library. I have a question about batched changes and undo.

Suppose I have a scheme-mode editor with the following contents:
(+ 1 (* 2 3))
…and I execute the following code:

  editor.operation(() => {
    editor.replaceRange(" 1", {line: 0, ch: 12}, {line: 0, ch: 12});
    editor.replaceRange("",  {line: 0, ch:  3}, {line: 0, ch:  4});

…I get (+ (* 2 3) 1), as expected (two spaces after the +). A quick log of the changes event shows that all the locations are in the pre-change coordinate system, in keeping with the documentation:
{from: {line: 0, ch: 12}, removed: [""], text:[" 1"], to:{line: 0, ch: 12}}
{from: {line: 0, ch: 3} , removed:["1"], text:[""], to:{line: 0, ch: 4} }

When I initiate an undo event, I get the following changes:
{from: {line: 0, ch: 3}, removed:[""], text:["1"], to:{line: 0, ch: 3}, origin: "undo" }
{from: {line: 0, ch: 12},removed:[" 1"],text:[""], to:{line: 0, ch: 14},origin: "undo" }

Note that the second change object refers to " 1" as falling between ch 12 and 14 - but that’s only accurate in the coordinate system after “1” is inserted at ch 3.

I thought that batched changes all lived in the same (pre-batch) coordinate system. Clearly that’s not right. Does each change live in the coordinate system created by the one before it – even when batched? Are undo operations are handled differently somehow? Is it some other option I haven’t considered? :slight_smile:

Yes, this is how it works.

1 Like