From 258c8045930112341204dd8bea52c7a4c480aeba Mon Sep 17 00:00:00 2001 From: Chris Wanstrath Date: Sat, 20 Sep 2025 20:42:42 -0700 Subject: [PATCH] tab completion --- src/js/completion.ts | 24 ++++++++++++++++++++++++ src/js/dom.ts | 2 +- src/js/focus.ts | 8 ++++---- src/js/history.ts | 12 ++++++------ src/js/input.ts | 16 ++++++++-------- src/js/main.ts | 10 ++++++---- src/js/scrollback.ts | 1 - src/js/shell.ts | 3 ++- 8 files changed, 51 insertions(+), 25 deletions(-) create mode 100644 src/js/completion.ts diff --git a/src/js/completion.ts b/src/js/completion.ts new file mode 100644 index 0000000..5942e08 --- /dev/null +++ b/src/js/completion.ts @@ -0,0 +1,24 @@ +//// +// tab completion + +import { cmdInput } from "./dom.js" +import { commands } from "./commands.js" + +export function initCompletion() { + cmdInput.addEventListener("keydown", handleCompletion) +} + +function handleCompletion(e: KeyboardEvent) { + if (e.key !== "Tab") return + + e.preventDefault() + const input = cmdInput.value + + for (const command of commands) { + console.log(input, command) + if (command.startsWith(input)) { + cmdInput.value = command + return + } + } +} \ No newline at end of file diff --git a/src/js/dom.ts b/src/js/dom.ts index 1df502a..b2fc711 100644 --- a/src/js/dom.ts +++ b/src/js/dom.ts @@ -3,7 +3,7 @@ // elements we know will be there... right? export const cmdLine = $("command-line") as HTMLDivElement -export const cmdTextbox = $("command-textbox") as HTMLTextAreaElement +export const cmdInput = $("command-textbox") as HTMLTextAreaElement export const scrollback = $("scrollback") as HTMLUListElement // finds an element by ID diff --git a/src/js/focus.ts b/src/js/focus.ts index 8e4c00c..b696441 100644 --- a/src/js/focus.ts +++ b/src/js/focus.ts @@ -1,7 +1,7 @@ //// // We try to keep the command textbox focused at all times. -import { cmdTextbox } from "./dom.js" +import { cmdInput } from "./dom.js" export function initFocus() { window.addEventListener("click", focusHandler) @@ -9,7 +9,7 @@ export function initFocus() { } export function focusTextbox() { - cmdTextbox.focus() + cmdInput.focus() } // clicking anywhere outside of a link should focus the prompt, unless the user is @@ -19,7 +19,7 @@ export function focusHandler(e: MouseEvent) { // who knows where they clicked... just focus the textbox if (!(target instanceof HTMLElement)) { - cmdTextbox.focus() + cmdInput.focus() return } @@ -32,7 +32,7 @@ export function focusHandler(e: MouseEvent) { const selection = window.getSelection() || "" if (selection.toString() === "") - cmdTextbox.focus() + cmdInput.focus() e.preventDefault() return true diff --git a/src/js/history.ts b/src/js/history.ts index 0d65815..bdc7bf0 100644 --- a/src/js/history.ts +++ b/src/js/history.ts @@ -1,14 +1,14 @@ //// // Command input history storage and navigation. -import { cmdTextbox } from "./dom.js" +import { cmdInput } from "./dom.js" const history: string[] = ["one", "two", "three"] let idx = -1 let savedInput = "" export function initHistory() { - cmdTextbox.addEventListener("keydown", navigateHistory) + cmdInput.addEventListener("keydown", navigateHistory) } export function addToHistory(input: string) { @@ -30,9 +30,9 @@ function navigateHistory(e: KeyboardEvent) { if (idx >= history.length - 1) return if (idx === -1) - savedInput = cmdTextbox.value + savedInput = cmdInput.value - cmdTextbox.value = history[++idx] || "" + cmdInput.value = history[++idx] || "" if (idx >= history.length) idx = history.length - 1 } else if (e.key === "ArrowDown" || (e.ctrlKey && e.key === "n")) { @@ -40,12 +40,12 @@ function navigateHistory(e: KeyboardEvent) { console.log(idx, savedInput) if (idx <= 0) { - cmdTextbox.value = savedInput + cmdInput.value = savedInput idx = -1 return } - cmdTextbox.value = history[--idx] || "" + cmdInput.value = history[--idx] || "" if (idx < -1) idx = -1 } else if (idx !== -1) { diff --git a/src/js/input.ts b/src/js/input.ts index b1e1b2a..d216ac4 100644 --- a/src/js/input.ts +++ b/src/js/input.ts @@ -1,35 +1,35 @@ //// // Terminal input is handled by a