move components/client to rt (runtime) directory

This commit is contained in:
2025-02-22 15:40:33 -05:00
parent 8dee9cdeff
commit dc082b0ddf
25 changed files with 1 additions and 124 deletions

View File

@ -0,0 +1,6 @@
import type { Args, Term } from "../list";
export default function cat(term: Term, args: Args): boolean {
return true
}

View File

@ -0,0 +1,13 @@
import { set_working_dir, SetDirStatus } from "../../fs/fn"
import type { Args, Term } from "../list"
export default function cd(term: Term, args: Args): boolean {
const new_dir_status = set_working_dir(args[1])
if (new_dir_status === SetDirStatus.NotADirectory) {
// return <p>{"cd: \""}{bold(args[1])}{"\" is not a directory"}</p>
} else if (new_dir_status === SetDirStatus.NotFound) {
// return <p>{"cd: The directory \""}{bold(args[1])}{"\" does not exist"}</p>
}
return true
}

View File

@ -0,0 +1,19 @@
import type { Args, Term } from "../list"
export default function clear(term: Term, args: Args): boolean {
Array.from(term.children).forEach(node => {
if (node.tagName === "DIV") {
if (node.className === "shell-prompt") {
const input = node.getElementsByClassName("shell-ps1")[0] as HTMLInputElement
if (input.disabled || input.value === "clear") {
node.remove()
}
} else {
node.remove()
}
} else if (node.tagName === "P") {
node.remove()
}
})
return true
}

View File

@ -0,0 +1,22 @@
import type { Args, Term } from "../list";
import stdout from "../../../elements/stdout";
import SubCommand from "../subcommand";
import history from "../../history";
const history_command = new SubCommand("Show and manipulate command history")
history_command.add("show", "Show the history", function(term: Term, _args: Args) {
history.file.inner.forEach((entry, ind) => term.appendChild(stdout(`${ind} ${entry}`)))
})
history_command.add("clear", "Delete the entire command history", function(term: Term, _args: Args) {
const entries = history.file.inner.length
history.file.inner = []
term.appendChild(stdout(`Cleared ${entries} entries from the history.`))
})
export default function history_cmd(term: Term, args: Args) {
history_command.process(term, args)
return true
}

View File

@ -0,0 +1,11 @@
import type { Args, Term } from "../list";
export default function ls(term: Term, args: Args): boolean {
// if (args[1] === undefined) {
// for (const dir_name in working_dir) {
// }
// return <p>{`${working_dir}`}</p>
// }
return true
}

View File

@ -0,0 +1,9 @@
import { get_working_dir_name_full } from "../../fs/fn";
import type { Args, Term } from "../list";
import stdout from "../../../elements/stdout";
export default function pwd(term: Term, args: Args): boolean {
term.appendChild(stdout(get_working_dir_name_full()))
return true
}

View File

@ -0,0 +1,38 @@
import { bold } from "../color";
import { to_args, trim } from "./parse";
import commands, { type Command } from "./list";
import history from "../history";
import stdout from "../../elements/stdout";
type Term = HTMLElement
function valid_command(term: Term, args: string[]) {
for (const command_in_list in commands) {
const command = args[0]
if (command === command_in_list) {
return (commands[command_in_list] as Command)(term, args)
}
}
return
}
function unknown_command(cmd_name: string) {
const unknown_element = stdout("shell: Unknown command: ")
unknown_element.appendChild(bold(cmd_name))
return unknown_element
}
export default function run(term: Term, stdin: string) {
const args = to_args(trim(stdin))
const valid = valid_command(term, args)
const command = args[0] as string
if (command !== "" && !valid) {
return unknown_command(command)
}
history.add(args.join(" "))
return false
}
export { unknown_command }

View File

@ -0,0 +1,30 @@
import history from "./builtin/history"
import clear from "./builtin/clear"
import pwd from "./builtin/pwd"
import cat from "./builtin/cat"
import cd from "./builtin/cd"
import ls from "./builtin/ls"
type Term = HTMLElement
type Args = string[]
type Command = (term: Term, args: Args) => boolean
interface CommandsList {
[index: string]: Command,
}
const commands: CommandsList = {
["history"]: history,
["clear"]: clear,
["pwd"]: pwd,
["cat"]: cat,
["cd"]: cd,
["ls"]: ls,
}
export default commands
export {
type Command,
type Term,
type Args
}

View File

@ -0,0 +1,14 @@
function trim(stdin: string): string {
const trimmed_str: string[] = []
stdin.split(" ").forEach(s => { if (s !== "") { trimmed_str.push(s) } })
return trimmed_str.join(" ")
}
function to_args(trimmed_str: string): string[] {
return trimmed_str.split(" ")
}
export {
trim,
to_args
}

View File

@ -0,0 +1,63 @@
import stdout, { stdout_grid } from "../../elements/stdout";
import { bold } from "../color";
import type { Args, Term } from "./list";
type SubCommandClosure = (term: Term, args: Args) => void
interface SubCommandAction {
inner: SubCommandClosure,
description: string,
}
interface SubCommands {
[index: string]: SubCommandAction,
}
const SubCommand = class {
public data: SubCommands //data? less goo!
constructor(description: string) {
this.data = {}
this.data.help = {} as SubCommandAction
this.data.help.description = "Display help info"
this.data.help.inner = (term: Term, _args: Args) => {
const descriptions: string[] = []
Object.values(this.data).forEach(sub_cmd => descriptions.push(sub_cmd.description))
term.appendChild(stdout(description))
term.appendChild(stdout_grid(Object.keys(this.data), descriptions))
}
}
public process(term: Term, args: Args) {
const subc = args[1]
if (subc) {
const subc_f = this.data[subc]
if (subc_f) {
subc_f.inner(term, args)
} else {
term.appendChild(SubCommand.unknown(subc))
this.data.help.inner(term, args)
}
} else {
this.data.help.inner(term, args)
}
}
public add(name: string, description: string, f: SubCommandClosure) {
this.data[name] = {} as SubCommandAction
this.data[name].description = description
this.data[name].inner = f
}
public static unknown(subcmd_name: string) {
const subcmd_unknown = stdout("Unknown sub-command: ")
subcmd_unknown.appendChild(bold(subcmd_name))
return subcmd_unknown
}
}
export default SubCommand
export {
type SubCommand,
type SubCommandAction
}