From 0a60d472eaf1a08d7b497ca6ca3be46ffc6182af Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Mon, 9 Feb 2026 20:35:17 -0700 Subject: [PATCH] Fixing keydown events. --- src/cg/03-ui-components.cg | 30 ++++++++++++++++-------------- src/cg/05-palette.cg | 10 ++++++---- src/cg/10-os.cg | 2 ++ src/parser.ts | 3 ++- src/runtime-compiled.ts | 18 +++++++++++------- 5 files changed, 37 insertions(+), 26 deletions(-) diff --git a/src/cg/03-ui-components.cg b/src/cg/03-ui-components.cg index ecb0916..c99181c 100644 --- a/src/cg/03-ui-components.cg +++ b/src/cg/03-ui-components.cg @@ -95,31 +95,32 @@ textInput = config \ ui.stateful { # update : State \ Event \ State update = state event \ event - | ArrowLeft \ + | Key { key = c, printable = True } \ + _ = debug "text keydown" c; + newText = insertChar state.text state.cursorPos c; + newCursorPos = state.cursorPos + 1; + newScroll = calcScrollOffset newText newCursorPos state.scrollOffset config.w; + newState = state.{ text = newText, cursorPos = newCursorPos, scrollOffset = newScroll }; + { state = newState, emit = [config.onChange newText] } + + | Key { key = "ArrowLeft" } \ newCursorPos = max 0 (state.cursorPos - 1); newScroll = calcScrollOffset state.text newCursorPos state.scrollOffset config.w; newState = state.{ text = state.text, cursorPos = newCursorPos, scrollOffset = newScroll }; - { state = newState, emit = [config.onKeyDown] } + { state = newState, emit = [] } - | ArrowRight \ + | Key { key = "ArrowRight" } \ newCursorPos = min (len state.text) (state.cursorPos + 1); newScroll = calcScrollOffset state.text newCursorPos state.scrollOffset config.w; newState = state.{ text = state.text, cursorPos = newCursorPos, scrollOffset = newScroll }; - { state = newState, emit = [config.onKeyDown] } + { state = newState, emit = [] } - | Backspace \ + | Key { key = "Backspace" } \ newText = deleteChar state.text state.cursorPos; newCursorPos = max 0 (state.cursorPos - 1); newScroll = calcScrollOffset newText newCursorPos state.scrollOffset config.w; newState = state.{ text = newText, cursorPos = newCursorPos, scrollOffset = newScroll }; - { state = newState, emit = [config.onChange newText, config.onKeyDown] } - - | Char c \ - newText = insertChar state.text state.cursorPos c; - newCursorPos = state.cursorPos + 1; - newScroll = calcScrollOffset newText newCursorPos state.scrollOffset config.w; - newState = state.{ text = newText, cursorPos = newCursorPos, scrollOffset = newScroll }; - { state = newState, emit = [config.onChange newText, config.onKeyDown] } + { state = newState, emit = [config.onChange newText] } | Clicked coords \ newCursorPos = findCursorPos state.text coords.x state.scrollOffset 8; @@ -129,7 +130,8 @@ textInput = config \ ui.stateful { | Focused \ { state = state.{ focused = True }, emit = [] } | Blurred \ { state = state.{ focused = False }, emit = [] } - | event \ { state = state, emit = [config.onKeyDown event] }, + | Key { key = k } \ { state = state, emit = [\ config.onKeyDown k ] } + | _ \ { state = state, emit = [] }, view = state \ textBeforeCursor = slice state.text 0 state.cursorPos; diff --git a/src/cg/05-palette.cg b/src/cg/05-palette.cg index d21a390..b4e8e7b 100644 --- a/src/cg/05-palette.cg +++ b/src/cg/05-palette.cg @@ -52,10 +52,12 @@ palette = config \ w = contentWidth, h = textInputHeight, onChange = text \ batch [config.state.query := text, config.state.focusedIndex := 0], - onKeyDown = key \ key - | ArrowUp \ config.state.focusedIndex := max 0 (config.state.focusedIndex - 1) - | ArrowDown \ config.state.focusedIndex := (config.state.focusedIndex + 1) - | Enter \ (\ config.onSelect (unwrapOr "" (nth config.state.focusedIndex results))) + onKeyDown = key \ + _ = debug "palette key" key; + key + | "ArrowUp" \ config.state.focusedIndex := max 0 (config.state.focusedIndex - 1) + | "ArrowDown" \ config.state.focusedIndex := (config.state.focusedIndex + 1) + | "Enter" \ (\ config.onSelect (unwrapOr "" (nth config.state.focusedIndex results))) | _ \ noOp }, ui.clip { diff --git a/src/cg/10-os.cg b/src/cg/10-os.cg index c77991d..a523974 100644 --- a/src/cg/10-os.cg +++ b/src/cg/10-os.cg @@ -9,6 +9,8 @@ osState = { init = {}; update = state event \ event + | Key { key = "p", meta = True } \ togglePalette + | Key { key = k } \ debug "key" k | _ \ state; view = state viewport \ diff --git a/src/parser.ts b/src/parser.ts index 24d6483..af4708a 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -298,7 +298,8 @@ export class Parser { return kind === 'underscore' || kind === 'ident' || kind === 'type-ident' || kind === 'int' || kind === 'float' || kind === 'string' || - kind === 'open-paren'; + kind === 'open-paren' || kind === 'open-brace' || + kind === 'open-bracket'; } private parseLambda(): AST { diff --git a/src/runtime-compiled.ts b/src/runtime-compiled.ts index 529a796..14469e8 100644 --- a/src/runtime-compiled.ts +++ b/src/runtime-compiled.ts @@ -205,13 +205,17 @@ export function runAppCompiled(app: App, canvas: HTMLCanvasElement, rt: any) { }); window.addEventListener('keydown', (e) => { - let event: any; - - if (e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) { - event = { _tag: 'Char', _0: e.key }; - } else { - event = { _tag: e.key }; - } + const event = { + _tag: 'Key', + _0: { + key: e.key, + ctrl: { _tag: e.ctrlKey ? 'True' : 'False' }, + meta: { _tag: e.metaKey ? 'True' : 'False' }, + alt: { _tag: e.altKey ? 'True' : 'False' }, + shift: { _tag: e.shiftKey ? 'True' : 'False' }, + printable: { _tag: e.key.length === 1 ? 'True' : 'False' } + } + }; if (focusedComponentKey) { handleComponentEvent(focusedComponentKey, event);