move components/client to rt (runtime) directory
This commit is contained in:
6
src/rt/shell/command/builtin/cat.ts
Normal file
6
src/rt/shell/command/builtin/cat.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import type { Args, Term } from "../list";
|
||||
|
||||
export default function cat(term: Term, args: Args): boolean {
|
||||
|
||||
return true
|
||||
}
|
13
src/rt/shell/command/builtin/cd.ts
Normal file
13
src/rt/shell/command/builtin/cd.ts
Normal 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
|
||||
}
|
19
src/rt/shell/command/builtin/clear.ts
Normal file
19
src/rt/shell/command/builtin/clear.ts
Normal 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
|
||||
}
|
22
src/rt/shell/command/builtin/history.ts
Normal file
22
src/rt/shell/command/builtin/history.ts
Normal 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
|
||||
}
|
11
src/rt/shell/command/builtin/ls.ts
Normal file
11
src/rt/shell/command/builtin/ls.ts
Normal 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
|
||||
}
|
9
src/rt/shell/command/builtin/pwd.ts
Normal file
9
src/rt/shell/command/builtin/pwd.ts
Normal 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
|
||||
}
|
38
src/rt/shell/command/command.ts
Normal file
38
src/rt/shell/command/command.ts
Normal 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 }
|
30
src/rt/shell/command/list.ts
Normal file
30
src/rt/shell/command/list.ts
Normal 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
|
||||
}
|
14
src/rt/shell/command/parse.ts
Normal file
14
src/rt/shell/command/parse.ts
Normal 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
|
||||
}
|
63
src/rt/shell/command/subcommand.ts
Normal file
63
src/rt/shell/command/subcommand.ts
Normal 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
|
||||
}
|
Reference in New Issue
Block a user