diff --git a/src/codeMirrorToAm.ts b/src/codeMirrorToAm.ts index cc10242..30eb3eb 100644 --- a/src/codeMirrorToAm.ts +++ b/src/codeMirrorToAm.ts @@ -37,11 +37,13 @@ export default function ( ( fromA: number, toA: number, - _fromB: number, + fromB: number, _toB: number, inserted: Text ) => { - am.splice(doc, path, fromA, toA - fromA, inserted.toString()) + // We are cloning the path as `am.splice` calls `.unshift` on it, modifying it in place, + // causing the path to be broken on subsequent changes + am.splice(doc, path.slice(), fromB, toA - fromA, inserted.toString()) } ) } diff --git a/test/Editor.cy.tsx b/test/Editor.cy.tsx index 79f47f4..af1ee2f 100644 --- a/test/Editor.cy.tsx +++ b/test/Editor.cy.tsx @@ -78,6 +78,38 @@ describe("", () => { assert.equal(doc.text, "Hello") }) }) + + it("handles moving lines", () => { + const { handle } = makeHandle("Hello\nWorld") + mount() + cy.get("div.cm-content").type("{ctrl+end}{alt+upArrow}") + cy.get("div.cm-content").should( + "have.html", + expectedHtml(["World", "Hello"], 1) + ) + cy.wait(100).then(async () => { + const doc = await handle.doc() + assert.equal(doc.text, "World\nHello") + }) + }) + + it("handles multiple cursors", () => { + const { handle } = makeHandle("Hello\nWorld\nThere!") + mount() + cy.get("div.cm-content>.cm-line").eq(0).click() + cy.get("div.cm-content>.cm-line").eq(1).click({ ctrlKey: true }) + cy.get("div.cm-content>.cm-line").eq(2).click({ ctrlKey: true }) + cy.get("div.cm-content").type(" Lines{home}{shift+rightArrow}{del}") + cy.get("div.cm-content>.cm-line").eq(0).click() + cy.get("div.cm-content").should( + "have.html", + expectedHtml(["ello Lines", "orld Lines", "here! Lines"], 0) + ) + cy.wait(100).then(async () => { + const doc = await handle.doc() + assert.equal(doc.text, "ello Lines\norld Lines\nhere! Lines") + }) + }) }) describe("remote changes", () => {