From ee7b2168d953c232ecf25ee795b5997b1c6c136d Mon Sep 17 00:00:00 2001 From: rhpidfyre Date: Fri, 7 Feb 2025 02:45:36 -0500 Subject: [PATCH] fs functions wip, set_working_dir needs to work --- src/components/react/shell/color.tsx | 4 +- src/components/react/shell/command/list.ts | 26 ----------- src/components/react/shell/command/list.tsx | 48 +++++++++++++++++++++ src/components/react/shell/command/run.tsx | 24 +++++------ src/components/react/shell/events.tsx | 4 +- src/components/react/shell/fs.ts | 46 -------------------- src/components/react/shell/fs/fn.ts | 35 +++++++++++++++ src/components/react/shell/fs/fs.ts | 47 ++++++++++++++++++++ src/components/react/shell/prompt.tsx | 9 ++-- src/components/react/terminal/exec.tsx | 4 +- tsconfig.json | 2 +- 11 files changed, 153 insertions(+), 96 deletions(-) delete mode 100644 src/components/react/shell/command/list.ts create mode 100644 src/components/react/shell/command/list.tsx delete mode 100644 src/components/react/shell/fs.ts create mode 100644 src/components/react/shell/fs/fn.ts create mode 100644 src/components/react/shell/fs/fs.ts diff --git a/src/components/react/shell/color.tsx b/src/components/react/shell/color.tsx index 1f779c4..43df7c7 100644 --- a/src/components/react/shell/color.tsx +++ b/src/components/react/shell/color.tsx @@ -2,6 +2,7 @@ const red = (s: string) => {s} const green = (s: string) => {s} const blue = (s: string) => {s} const cyan = (s: string) => {s} +const bold = (s: string) => {s} export default function rgb(s: string, Ru8: number, Gu8: number, Bu8: number) { return {s} @@ -11,5 +12,6 @@ export { red, green, blue, - cyan + cyan, + bold } \ No newline at end of file diff --git a/src/components/react/shell/command/list.ts b/src/components/react/shell/command/list.ts deleted file mode 100644 index a64ceb4..0000000 --- a/src/components/react/shell/command/list.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { working_dir } from "../fs" - -type args = string[] - -function ls(args: args) { - console.log(args) -} - -function pwd(args: args) { - -} - -function cat(args: args) { - -} - -interface commands_list { - [index: string]: (args: args) => void -} -const commands: commands_list = { - ["ls"]: ls, - ["pwd"]: pwd, - ["cat"]: cat, -} - -export default commands \ No newline at end of file diff --git a/src/components/react/shell/command/list.tsx b/src/components/react/shell/command/list.tsx new file mode 100644 index 0000000..324018e --- /dev/null +++ b/src/components/react/shell/command/list.tsx @@ -0,0 +1,48 @@ +import type { JSX } from "react" +import { Entry } from "../fs/fs" +import { blue } from "../color" +import { set_working_dir } from "../fs/fn" + +type args = string[] +type command = JSX.Element | undefined + +function parse_ls(entries: JSX.Element[]) { + return
+ +
+} + +function cd(args: args): command { + set_working_dir(args[1]) +} + +function ls(args: args): command { + // if (args[1] === undefined) { + // for (const dir_name in working_dir) { + + // } + // return

{`${working_dir}`}

+ // } +} + +function pwd(args: args): command { + const tree: string[] = [] + + return

{`${tree.join("/")}`}

+} + +function cat(args: args): command { + return +} + +interface commands_list { + [index: string]: (args: args) => command +} +const commands: commands_list = { + ["cd"]: cd, + ["ls"]: ls, + ["pwd"]: pwd, + ["cat"]: cat, +} + +export default commands \ No newline at end of file diff --git a/src/components/react/shell/command/run.tsx b/src/components/react/shell/command/run.tsx index 52c0396..69fa564 100644 --- a/src/components/react/shell/command/run.tsx +++ b/src/components/react/shell/command/run.tsx @@ -1,14 +1,10 @@ import type { JSX } from "react"; -import type { Root } from "react-dom/client"; -import { type newElement } from "../../terminal/exec"; - import commands from "./list"; - -type Renderer = React.Dispatch> +import { bold } from "../color"; function trim(stdin: string): string { const trimmed_str: string[] = [] - stdin.split(" ").forEach(s => { if (s != "") { trimmed_str.push(s) } }) + stdin.split(" ").forEach(s => { if (s !== "") { trimmed_str.push(s) } }) return trimmed_str.join(" ") } @@ -16,26 +12,26 @@ function to_args(trimmed_str: string): string[] { return trimmed_str.split(" ") } -function valid_command(args: string[]): boolean { +function valid_command(args: string[]): JSX.Element | undefined { for (const command_in_list in commands) { const command = args[0] if (command === command_in_list) { - commands[command_in_list](args) - return true + return commands[command_in_list](args) } } - return false + return } -function unknown_command(name: string) { - return

{`sh: Unknown command: ${name}`}

+function unknown_command(cmd_name: string) { + return

{"shell: Unknown command: "}{bold(cmd_name)}

} export default function run(stdin: string) { const args = to_args(trim(stdin)) + const command = valid_command(args) - if (args[0] !== "" && !valid_command(args)) { + if (args[0] !== "" && !command) { return unknown_command(args[0]) } - return <> + return command ? command : <> } \ No newline at end of file diff --git a/src/components/react/shell/events.tsx b/src/components/react/shell/events.tsx index 9f013ed..94fb4be 100644 --- a/src/components/react/shell/events.tsx +++ b/src/components/react/shell/events.tsx @@ -33,14 +33,14 @@ function new_prompt(): JSX.Element { return display_prompt() } -function keyboard_events(terminal_window: HTMLElement, new_element_f: newElement) { +function keyboard_events(terminal_window: HTMLElement, new_elements_f: newElement) { const terminal_event = (keyboard_event: KeyboardEvent) => { if (keyboard_event.key === Key.Enter) { const current_prompt = get_current_prompt() if (current_prompt) { const prompt = new_prompt() const output = run(current_prompt.value) - new_element_f([output, prompt]) + new_elements_f([output, prompt]) terminal_window.removeEventListener("keydown", terminal_event) } } else if (keyboard_event.key === Key.ArrowUp) { diff --git a/src/components/react/shell/fs.ts b/src/components/react/shell/fs.ts deleted file mode 100644 index 56006b6..0000000 --- a/src/components/react/shell/fs.ts +++ /dev/null @@ -1,46 +0,0 @@ -let working_dir = "user" - -const enum EntryType { - Directory, - File -} -const enum Permissions { - r, - w, - rw -} - -type File = string -type Entry = { - readonly inner: T, - readonly type: EntryType, - readonly permissions: Permissions -} -function Entry(inner: T, permissions: Permissions): Entry { - const type = typeof inner == "object" ? EntryType.Directory : EntryType.File - return { - inner: inner, - type: type, - permissions: permissions - } -} - -const user = { - ["about_me.txt"]: Entry("", Permissions.rw), - ["services.txt"]: Entry("", Permissions.rw) -} -const home = { - ["user"]: Entry(user, Permissions.rw) -} -const root = { - ["bin"]: Entry({}, Permissions.r), - ["home"]: Entry(home, Permissions.r) -} -const fs = { - ["/"]: Entry(root, Permissions.r) -} - -export { - fs, - working_dir -} \ No newline at end of file diff --git a/src/components/react/shell/fs/fn.ts b/src/components/react/shell/fs/fn.ts new file mode 100644 index 0000000..8a91bf4 --- /dev/null +++ b/src/components/react/shell/fs/fn.ts @@ -0,0 +1,35 @@ +import { fs } from "./fs" + +let working_dir = ["/", "home", "user"] + +function get_working_dir_name_full(): string { + const w_dir_clone = [...working_dir] + const root = w_dir_clone.shift() + if (root) { + return root+w_dir_clone.join("/") + } + return "shift-error" +} + +function get_working_dir_name(): string { + return working_dir[working_dir.length-1] +} + +function set_working_dir(name: string) { + let new_dir; + const w_dir_clone = [...working_dir] + w_dir_clone.push(name) + w_dir_clone.map(p => p !== "/" ? p+"/" : p).forEach(f => { + for (let i = 0; i { + readonly inner: T, + readonly name: string, + readonly type: EntryType, + readonly permissions: Permissions +} +function Entry(name: string, inner: T, permissions: Permissions): Entry { + return { + type: typeof inner == "object" ? EntryType.Directory : EntryType.File, + inner: inner, + name: name, + permissions: permissions + } +} + +export { + fs, + EntryType, + Permissions, + Entry +} \ No newline at end of file diff --git a/src/components/react/shell/prompt.tsx b/src/components/react/shell/prompt.tsx index cd2845a..a6f4033 100644 --- a/src/components/react/shell/prompt.tsx +++ b/src/components/react/shell/prompt.tsx @@ -1,4 +1,4 @@ -import { working_dir } from "./fs" +import { get_working_dir_name_full } from "./fs/fn" import { cyan, green } from "./color" const userAgent = navigator.userAgent @@ -9,13 +9,14 @@ if (browser_name_fallible) { browser_name = browser_name_fallible[0] === "Firefox" ? "gecko" : "chromium" } -function GetWorkingDir() { - return working_dir === "user" ? "~" : working_dir +function working_dir() { + const name = get_working_dir_name_full() + return name === "user" ? "~" : name } export default function Display() { const user = cyan("user") - const dir = green(GetWorkingDir()) + const dir = green(working_dir()) return

{user}@{browser_name} {dir}{"> "}

} diff --git a/src/components/react/terminal/exec.tsx b/src/components/react/terminal/exec.tsx index 5b4da0e..f812d5b 100644 --- a/src/components/react/terminal/exec.tsx +++ b/src/components/react/terminal/exec.tsx @@ -20,9 +20,9 @@ type newElement = (elements: JSX.Element[]) => void export default function Shell() { if (terminal_window) { const [renderedElements, renderElement] = useState([display_prompt()]) - const new_element_f = (elements: JSX.Element[]) => renderElement([...renderedElements, ...elements]) + const new_elements_f = (elements: JSX.Element[]) => renderElement([...renderedElements, ...elements]) - keyboard_events(terminal_window, new_element_f) + keyboard_events(terminal_window, new_elements_f) return renderedElements.map((element, k) => {element}) } diff --git a/tsconfig.json b/tsconfig.json index 8b67c1f..5b3089e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,7 +8,7 @@ "dist" ], "compilerOptions": { - "noImplicitAny": true, + "noImplicitAny": true, "jsx": "react-jsx", "jsxImportSource": "react" }