From 458b87255f4f97de8f98d0fca64a568d267b1b03 Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Tue, 2 Nov 2021 15:30:14 -0400 Subject: [PATCH] save editor selection and cursor in ktxt2 --- projects/kiss-vscode/src/ktxt2/KTxt2Editor.hx | 6 +- .../kiss-vscode/src/ktxt2/KTxt2Editor.kiss | 96 +++++++++++++++++-- 2 files changed, 91 insertions(+), 11 deletions(-) diff --git a/projects/kiss-vscode/src/ktxt2/KTxt2Editor.hx b/projects/kiss-vscode/src/ktxt2/KTxt2Editor.hx index e85ab175..c04418be 100644 --- a/projects/kiss-vscode/src/ktxt2/KTxt2Editor.hx +++ b/projects/kiss-vscode/src/ktxt2/KTxt2Editor.hx @@ -21,8 +21,10 @@ typedef MessageToEditor = { typedef EditorState = { text:String, scrollY:Float, - elementScrollY:Int - // TODO active editor, selection & range etc + elementScrollY:Int, + activeEditorIdx:Int, + startCursorPos:Int, + endCursorPos:Int }; @:build(kiss.Kiss.build()) diff --git a/projects/kiss-vscode/src/ktxt2/KTxt2Editor.kiss b/projects/kiss-vscode/src/ktxt2/KTxt2Editor.kiss index 10f468be..508e4069 100644 --- a/projects/kiss-vscode/src/ktxt2/KTxt2Editor.kiss +++ b/projects/kiss-vscode/src/ktxt2/KTxt2Editor.kiss @@ -12,7 +12,13 @@ (function :EditorState getState [] (ifLet [s (the EditorState (vscode.getState))] s - (object scrollY 0 elementScrollY 0 text ""))) + (object + scrollY 0 + elementScrollY 0 + text "" + activeEditorIdx -1 + startCursorPos -1 + endCursorPos -1))) (function :Void setState [:EditorState state] (vscode.setState state)) @@ -62,12 +68,31 @@ (set elementScrollY state.elementScrollY) (updateContent state.text) (setScrollY state.scrollY) + (when (<= 0 state.activeEditorIdx) + (let [e (nth editors state.activeEditorIdx)] + (e.focus) + (if (<= 0 state.endCursorPos) + { + (e.setSelection + (Range.fromPositions + (.getPositionAt (e.getModel) state.startCursorPos) + (.getPositionAt (e.getModel) state.endCursorPos))) + } + (if (<= 0 state.startCursorPos) + { + (e.setPosition (.getPositionAt (e.getModel) state.startCursorPos)) + }))) + ((activateEditor state.activeEditorIdx))) + }))) (var MONACO_CHECK_MILLI 100) (function :Void whenMonacoIsAvailable [:Void->Void doThis] (if Lib.global.monaco - (doThis) + { + (set Range Lib.global.monaco.Range) + (doThis) + } (window.setTimeout ->(whenMonacoIsAvailable doThis) MONACO_CHECK_MILLI))) (var &mut :Map editTimeoutHandles (new Map)) @@ -85,8 +110,11 @@ EDIT_TIMEOUT_MILLI))) (var &mut :Dynamic activeEditor) +(var :Array editors []) (function monacoEditor [div style content language readOnly :Dynamic->Void onChange] - (let [:Dynamic e + (let [eIdx + editors.length + :Dynamic e (Lib.global.monaco.editor.create div (objectWith [ @@ -105,12 +133,65 @@ (e.layout) }] (updateSize) - (e.onDidFocusEditorText ->(set activeEditor e)) - (e.onDidBlurEditorText ->(when (= activeEditor e) (set activeEditor null))) + (e.onDidFocusEditorText (activateEditor eIdx)) + (e.onDidChangeCursorPosition + ->evt (when (Range.isEmpty (activeEditor.getSelection)) + (let [s (getState)] + (set s.startCursorPos (.getOffsetAt (e.getModel) evt.position)) + (set s.endCursorPos -1) + (setState s)) + + // Delay updating the block + (when (dictGet editTimeoutHandles eIdx) + (onChange e)))) + (e.onDidChangeCursorSelection + ->evt { + (let [s (getState)] + (set s.startCursorPos (.getOffsetAt (e.getModel) (evt.selection.getStartPosition))) + (set s.endCursorPos (.getOffsetAt (e.getModel) (evt.selection.getEndPosition))) + (setState s)) + + // Delay updating the block + (when (dictGet editTimeoutHandles eIdx) + (onChange e)) + }) + (e.onDidBlurEditorText (deactivateEditor eIdx)) (e.onDidContentSizeChange updateSize) (e.onDidChangeModelContent ->[&opt _] (onChange e)) + (editors.push e) e)) +(var &mut :Dynamic Range) + +(function activateEditor [eIdx] + ->{ + (set activeEditor (nth editors eIdx)) + (let [s (getState)] + (set s.activeEditorIdx eIdx) + (let [sel (activeEditor.getSelection)] + (if (Range.isEmpty sel) + // set state's cursor position + { + (set s.startCursorPos (activeEditor.getOffsetAt (activeEditor.getPosition))) + (set s.endCursorPos -1) + } + // set state's selection + { + (set s.startCursorPos (activeEditor.getOffsetAt (sel.getStartPosition))) + (set s.endCursorPos (activeEditor.getOffsetAt (sel.getEndPosition))) + })) + (setState s)) + }) + +(function deactivateEditor [eIdx] + ->(when (= activeEditor (nth editors eIdx)) + (set activeEditor null) + (let [s (getState)] + (set s.activeEditorIdx -1) + (set s.startCursorPos -1) + (set s.endCursorPos -1) + (setState s)))) + (function replaceComment [element newText] (case element ((Comment (object text text start start end end)) @@ -220,10 +301,7 @@ (outerDiv.appendChild exportLink) (content.appendChild outerDiv) (content.appendChild (document.createElement "br")) - (content.appendChild blockLinkAfter) - - )) - + (content.appendChild blockLinkAfter))) (var &mut updatingContent false)