From fcce2ac4c05b671180a6bbfce49b82bfd022d295 Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Thu, 12 Mar 2026 21:04:52 -0600 Subject: [PATCH] refactoring key events so all Insert mode are together... may regret that later but its cleaner now. Getting delete line working --- src/cg/06-textEditor.cg | 155 +++++++++++++++++----------------------- 1 file changed, 66 insertions(+), 89 deletions(-) diff --git a/src/cg/06-textEditor.cg b/src/cg/06-textEditor.cg index 81de2ca..d503538 100644 --- a/src/cg/06-textEditor.cg +++ b/src/cg/06-textEditor.cg @@ -18,6 +18,19 @@ textEditor = name \ lines = split "\n" source; + clampCursor = state \ + line = nth state.cursorRow state.lines ~ unwrapOr ""; + + newRow = max 0 state.cursorRow; + newRow2 = min (len state.lines - 1) newRow; + + maxCol = state.mode + | Insert \ len line + | Normal \ max 0 (len line - 1); + newCol2 = min maxCol (max 0 state.cursorCol); + + state.{ cursorRow = newRow2, cursorCol = newCol2 }; + write = state \ content = join "\n" state.lines; { state = state, emit = [rebindAt [buffersKey, name] content] }; @@ -62,12 +75,26 @@ textEditor = name \ state = state.{ lines = newLines, cursorRow = cursorRow, + cursorCol = 0, undoStack = newUndoStack, mode = Insert }, emit = [] }; + deleteLine = state \ + stateSnapshot = { lines = state.lines, cursorRow = state.cursorRow, cursorCol = state.cursorCol }; + newUndoStack = [stateSnapshot, ...state.undoStack]; + newLines = [...(take (state.cursorRow) state.lines), ...(drop (state.cursorRow + 1) state.lines)]; + { + state = clampCursor state.{ + lines = newLines, + undoStack = newUndoStack, + pending = None + }, + emit = [] + }; + escape = state \ { state = state.{ mode = Normal }, emit = [] }; undo = state \ state.undoStack @@ -111,19 +138,6 @@ textEditor = name \ { state = state.{ lines = newLines2, cursorCol = 0, cursorRow = state.cursorRow + 1 }, emit = [] }; - clampCursor = state \ - line = nth state.cursorRow state.lines ~ unwrapOr ""; - - newRow = max 0 state.cursorRow; - newRow2 = min (len state.lines - 1) newRow; - - maxCol = state.mode - | Insert \ len line - | Normal \ max 0 (len line - 1); - newCol2 = min maxCol (max 0 state.cursorCol); - - state.{ cursorRow = newRow2, cursorCol = newCol2 }; - upArrow = state \ newState = clampCursor state.{ cursorRow = state.cursorRow - 1 }; { state = newState, emit = [] }; @@ -186,85 +200,48 @@ textEditor = name \ scrollY = 0, undoStack = [], redoStack = [], - mode = Normal # Normal | Insert | Visual + mode = Normal, # Normal | Insert | Visual + pending = None # Some "d" | Some "g" | etc. }, - update = state event \ event - | Scrolled delta \ ( - maxLineLen = fold (acc line \ max acc (len line)) 0 state.lines; - totalW = maxLineLen * charW * scale + maxLineLen * charGap; - totalH = len state.lines * lineH; - newX = max 0 (min (totalW - ctx.w) (state.scrollX + delta.deltaX)); - newY = max 0 (min (totalH - ctx.h) (state.scrollY + delta.deltaY)); - { state = state.{ scrollY = newY, scrollX = newX }, emit = [] }) + update = state event \ state.mode + | Insert \ (event + | Key { key = "Escape" } \ escape state + | Key { key = "Control" } \ escape state + | Key { key = "Backspace" } \ backspace state + | Key { key = "Enter" } \ enter state + | Key { key = k } \ insertChar k state) + | Normal \ (event + | Scrolled delta \ ( + maxLineLen = fold (acc line \ max acc (len line)) 0 state.lines; + totalW = maxLineLen * charW * scale + maxLineLen * charGap; + totalH = len state.lines * lineH; + newX = max 0 (min (totalW - ctx.w) (state.scrollX + delta.deltaX)); + newY = max 0 (min (totalH - ctx.h) (state.scrollY + delta.deltaY)); + { state = state.{ scrollY = newY, scrollX = newX }, emit = [] }) - | Key { key = "ArrowDown" } \ withScroll (downArrow state) - | Key { key = "j" } \ (state.mode - | Insert \ insertChar "j" state - | Normal \ withScroll (downArrow state)) - - | Key { key = "ArrowUp" } \ withScroll (upArrow state) - | Key { key = "k" } \ (state.mode - | Insert \ insertChar "k" state - | Normal \ withScroll(upArrow state)) - - | Key { key = "ArrowLeft" } \ withScroll (leftArrow state) - | Key { key = "h" } \ (state.mode - | Insert \ insertChar "h" state - | Normal \ withScroll(leftArrow state)) - - | Key { key = "ArrowRight" } \ withScroll (rightArrow state) - | Key { key = "l" } \ (state.mode - | Insert \ insertChar "l" state - | Normal \ withScroll(rightArrow state)) - - | Key { key = "i" } \ (state.mode - | Insert \ insertChar "i" state - | Normal \ insertMode state) - - | Key { key = "o" } \ (state.mode - | Insert \ insertChar "o" state - | Normal \ openLine state) - - | Key { key = "d", ctrl = True } \ scrollHalfDown state ctx - | Key { key = "u", ctrl = True } \ scrollHalfUp state ctx - - | Key { key = "u" } \ (state.mode - | Insert \ insertChar "u" state - | Normal \ undo state) - - | Key { key = "r", ctrl = True } \ (state.mode - | Insert \ { state = state, emit = [] } - | Normal \ redo state) - - | Key { key = "W", shift = True } \ (state.mode - | Insert \ insertChar "W" state - | Normal \ write state) - - | Key { key = "W", ctrl = True, shift = True } \ (state.mode - | Insert \ insertChar "W" state - | Normal \ write state) - - | Key { key = "A", ctrl = True, shift = True } \ (state.mode - | Insert \ insertChar "A" state - | Normal \ apply state) - - | Key { key = "Escape" } \ escape state - - | Key { key = "Backspace" } \ (state.mode - | Insert \ backspace state - | _ \ { state = state, emit = [] }) - - | Key { key = "Enter" } \ (state.mode - | Insert \ enter state - | _ \ { state = state, emit = [] }) - - # any other key - | Key { key = key, printable = True } \ (state.mode - | Insert \ insertChar key state - | _ \ { state = state, emit = [] }) - - | _ \ { state = state, emit = [] }, + | Key { key = "ArrowDown" } \ withScroll (downArrow state) + | Key { key = "j" } \ withScroll (downArrow state) + | Key { key = "ArrowUp" } \ withScroll (upArrow state) + | Key { key = "k" } \ withScroll(upArrow state) + | Key { key = "ArrowLeft" } \ withScroll (leftArrow state) + | Key { key = "h" } \ withScroll(leftArrow state) + | Key { key = "ArrowRight" } \ withScroll (rightArrow state) + | Key { key = "l" } \ withScroll(rightArrow state) + | Key { key = "i" } \ insertMode state + | Key { key = "o" } \ openLine state + | Key { key = "d", ctrl = True } \ scrollHalfDown state ctx + | Key { key = "u", ctrl = True } \ scrollHalfUp state ctx + | Key { key = "u" } \ undo state + | Key { key = "d" } \ (state.pending + | Some "d" \ deleteLine state + | _ \ { state = state.{ pending = Some "d" }, emit = [] }) + | Key { key = "r", ctrl = True } \ redo state + | Key { key = "W", ctrl = True, shift = True } \ write state + | Key { key = "A", ctrl = True, shift = True } \ apply state + # any other key or event + | _ \ { state = state, emit = [] } + ), view = state emit \ cursorX = state.cursorCol * charW * scale + charGap * state.cursorCol;