tab completion
This commit is contained in:
parent
51d319a8b9
commit
258c804593
24
src/js/completion.ts
Normal file
24
src/js/completion.ts
Normal file
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
// elements we know will be there... right?
|
// elements we know will be there... right?
|
||||||
export const cmdLine = $("command-line") as HTMLDivElement
|
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
|
export const scrollback = $("scrollback") as HTMLUListElement
|
||||||
|
|
||||||
// finds an element by ID
|
// finds an element by ID
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
////
|
////
|
||||||
// We try to keep the command textbox focused at all times.
|
// We try to keep the command textbox focused at all times.
|
||||||
|
|
||||||
import { cmdTextbox } from "./dom.js"
|
import { cmdInput } from "./dom.js"
|
||||||
|
|
||||||
export function initFocus() {
|
export function initFocus() {
|
||||||
window.addEventListener("click", focusHandler)
|
window.addEventListener("click", focusHandler)
|
||||||
|
|
@ -9,7 +9,7 @@ export function initFocus() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function focusTextbox() {
|
export function focusTextbox() {
|
||||||
cmdTextbox.focus()
|
cmdInput.focus()
|
||||||
}
|
}
|
||||||
|
|
||||||
// clicking anywhere outside of a link should focus the prompt, unless the user is
|
// 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
|
// who knows where they clicked... just focus the textbox
|
||||||
if (!(target instanceof HTMLElement)) {
|
if (!(target instanceof HTMLElement)) {
|
||||||
cmdTextbox.focus()
|
cmdInput.focus()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -32,7 +32,7 @@ export function focusHandler(e: MouseEvent) {
|
||||||
|
|
||||||
const selection = window.getSelection() || ""
|
const selection = window.getSelection() || ""
|
||||||
if (selection.toString() === "")
|
if (selection.toString() === "")
|
||||||
cmdTextbox.focus()
|
cmdInput.focus()
|
||||||
|
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
return true
|
return true
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
////
|
////
|
||||||
// Command input history storage and navigation.
|
// Command input history storage and navigation.
|
||||||
|
|
||||||
import { cmdTextbox } from "./dom.js"
|
import { cmdInput } from "./dom.js"
|
||||||
|
|
||||||
const history: string[] = ["one", "two", "three"]
|
const history: string[] = ["one", "two", "three"]
|
||||||
let idx = -1
|
let idx = -1
|
||||||
let savedInput = ""
|
let savedInput = ""
|
||||||
|
|
||||||
export function initHistory() {
|
export function initHistory() {
|
||||||
cmdTextbox.addEventListener("keydown", navigateHistory)
|
cmdInput.addEventListener("keydown", navigateHistory)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addToHistory(input: string) {
|
export function addToHistory(input: string) {
|
||||||
|
|
@ -30,9 +30,9 @@ function navigateHistory(e: KeyboardEvent) {
|
||||||
if (idx >= history.length - 1) return
|
if (idx >= history.length - 1) return
|
||||||
|
|
||||||
if (idx === -1)
|
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
|
if (idx >= history.length) idx = history.length - 1
|
||||||
} else if (e.key === "ArrowDown" || (e.ctrlKey && e.key === "n")) {
|
} else if (e.key === "ArrowDown" || (e.ctrlKey && e.key === "n")) {
|
||||||
|
|
@ -40,12 +40,12 @@ function navigateHistory(e: KeyboardEvent) {
|
||||||
|
|
||||||
console.log(idx, savedInput)
|
console.log(idx, savedInput)
|
||||||
if (idx <= 0) {
|
if (idx <= 0) {
|
||||||
cmdTextbox.value = savedInput
|
cmdInput.value = savedInput
|
||||||
idx = -1
|
idx = -1
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdTextbox.value = history[--idx] || ""
|
cmdInput.value = history[--idx] || ""
|
||||||
|
|
||||||
if (idx < -1) idx = -1
|
if (idx < -1) idx = -1
|
||||||
} else if (idx !== -1) {
|
} else if (idx !== -1) {
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,35 @@
|
||||||
////
|
////
|
||||||
// Terminal input is handled by a <textarea> and friends.
|
// Terminal input is handled by a <textarea> and friends.
|
||||||
|
|
||||||
import { cmdTextbox, cmdLine } from "./dom.js"
|
import { cmdInput, cmdLine } from "./dom.js"
|
||||||
import { runCommand } from "./shell.js"
|
import { runCommand } from "./shell.js"
|
||||||
import { resetHistory } from "./history.js"
|
import { resetHistory } from "./history.js"
|
||||||
|
|
||||||
export function initInput() {
|
export function initInput() {
|
||||||
cmdTextbox.addEventListener("keydown", inputHandler)
|
cmdInput.addEventListener("keydown", inputHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
function inputHandler(event: KeyboardEvent) {
|
function inputHandler(event: KeyboardEvent) {
|
||||||
const target = event.target as HTMLElement
|
const target = event.target as HTMLElement
|
||||||
if (target?.id !== cmdTextbox.id) return
|
if (target?.id !== cmdInput.id) return
|
||||||
|
|
||||||
if (event.key === "Escape" || (event.ctrlKey && event.key === "c")) {
|
if (event.key === "Escape" || (event.ctrlKey && event.key === "c")) {
|
||||||
cmdTextbox.value = ""
|
cmdInput.value = ""
|
||||||
resetHistory()
|
resetHistory()
|
||||||
} else if (event.key === "Tab") {
|
} else if (event.key === "Tab") {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
} else if (event.shiftKey && event.key === "Enter") {
|
} else if (event.shiftKey && event.key === "Enter") {
|
||||||
cmdTextbox.rows += 1
|
cmdInput.rows += 1
|
||||||
cmdLine.dataset.extended = "true"
|
cmdLine.dataset.extended = "true"
|
||||||
} else if (event.key === "Enter") {
|
} else if (event.key === "Enter") {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
runCommand(cmdTextbox.value)
|
runCommand(cmdInput.value)
|
||||||
clearInput()
|
clearInput()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearInput() {
|
function clearInput() {
|
||||||
cmdTextbox.value = ""
|
cmdInput.value = ""
|
||||||
cmdTextbox.rows = 1
|
cmdInput.rows = 1
|
||||||
cmdLine.dataset.extended = "false"
|
cmdLine.dataset.extended = "false"
|
||||||
}
|
}
|
||||||
|
|
@ -1,14 +1,16 @@
|
||||||
import { initResize } from "./resize.js"
|
import { initCompletion } from "./completion.js"
|
||||||
import { initInput } from "./input.js"
|
|
||||||
import { initFocus } from "./focus.js"
|
import { initFocus } from "./focus.js"
|
||||||
import { initHistory } from "./history.js"
|
import { initHistory } from "./history.js"
|
||||||
|
import { initInput } from "./input.js"
|
||||||
|
import { initResize } from "./resize.js"
|
||||||
import { startVramCounter } from "./vram.js"
|
import { startVramCounter } from "./vram.js"
|
||||||
import { startConnection } from "./websocket.js"
|
import { startConnection } from "./websocket.js"
|
||||||
|
|
||||||
|
initCompletion()
|
||||||
initFocus()
|
initFocus()
|
||||||
initResize()
|
|
||||||
initInput()
|
|
||||||
initHistory()
|
initHistory()
|
||||||
|
initInput()
|
||||||
|
initResize()
|
||||||
|
|
||||||
startConnection()
|
startConnection()
|
||||||
startVramCounter()
|
startVramCounter()
|
||||||
|
|
@ -44,5 +44,4 @@ export function addOutput(id: string, output: string) {
|
||||||
item.dataset.id = id
|
item.dataset.id = id
|
||||||
|
|
||||||
scrollback.append(item)
|
scrollback.append(item)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -18,7 +18,8 @@ export function runCommand(input: string) {
|
||||||
|
|
||||||
if (browserCommands[cmd]) {
|
if (browserCommands[cmd]) {
|
||||||
const result = browserCommands[cmd]()
|
const result = browserCommands[cmd]()
|
||||||
if (result) addOutput(id, result)
|
if (typeof result === "string")
|
||||||
|
addOutput(id, result)
|
||||||
setStatus(id, "ok")
|
setStatus(id, "ok")
|
||||||
} else {
|
} else {
|
||||||
send({ id, type: "input", data: input })
|
send({ id, type: "input", data: input })
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user