From c62ebf6d092243c3b2a09c75d9cf6f803cf3fe2a Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Mon, 4 Aug 2025 13:53:19 +0530 Subject: [PATCH 1/2] fix: #1753 Undo in Monaco --- src/lib/components/DesktopEditor.svelte | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/lib/components/DesktopEditor.svelte b/src/lib/components/DesktopEditor.svelte index 47612015..d73b20d3 100644 --- a/src/lib/components/DesktopEditor.svelte +++ b/src/lib/components/DesktopEditor.svelte @@ -170,7 +170,14 @@ const newText = editorMode === 'code' ? code : mermaid; if (newText !== currentText) { editor.setScrollTop(0); - editor.setValue(newText); + editor.pushUndoStop(); + editor.executeEdits('updateCode', [ + { + range: model.getFullModelRange(), + text: newText + } + ]); + editor.pushUndoStop(); currentText = newText; renderAIPromptGutterGlyphIcon(); } From 1f0812496eda6fecff3da197e5a871b425c2d28d Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Mon, 8 Jun 2026 18:40:07 +0530 Subject: [PATCH 2/2] fix: prevent state feedback loop when updating Monaco via executeEdits Guard programmatic editor updates so sample diagrams and URL loads do not re-trigger onUpdate, which caused infinite state/URL churn and failing e2e tests. Co-authored-by: Cursor --- src/lib/components/DesktopEditor.svelte | 28 +++++++++++++++---------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/lib/components/DesktopEditor.svelte b/src/lib/components/DesktopEditor.svelte index d73b20d3..e945a1fa 100644 --- a/src/lib/components/DesktopEditor.svelte +++ b/src/lib/components/DesktopEditor.svelte @@ -27,6 +27,7 @@ lineNumbersMinChars: 4 } satisfies monaco.editor.IStandaloneEditorConstructionOptions; let currentText = ''; + let isUpdatingFromState = false; let showPopup = $state(false); let popupPosition = $state({ top: 0, lineNumber: 0 }); let decorationsCollection: monaco.editor.IEditorDecorationsCollection | undefined; @@ -142,7 +143,7 @@ editor.onDidChangeModelContent(({ isFlush }) => { const newText = editor?.getValue(); - if (!newText || currentText === newText || isFlush) { + if (!newText || currentText === newText || isFlush || isUpdatingFromState) { return; } currentText = newText; @@ -169,16 +170,21 @@ // Update editor text if it's different const newText = editorMode === 'code' ? code : mermaid; if (newText !== currentText) { - editor.setScrollTop(0); - editor.pushUndoStop(); - editor.executeEdits('updateCode', [ - { - range: model.getFullModelRange(), - text: newText - } - ]); - editor.pushUndoStop(); - currentText = newText; + isUpdatingFromState = true; + try { + editor.setScrollTop(0); + editor.pushUndoStop(); + editor.executeEdits('updateCode', [ + { + range: model.getFullModelRange(), + text: newText + } + ]); + editor.pushUndoStop(); + currentText = newText; + } finally { + isUpdatingFromState = false; + } renderAIPromptGutterGlyphIcon(); }