From d0ff245582450a0cfda69c51073dce3ae2f99bda Mon Sep 17 00:00:00 2001 From: ChaosMakerMLG Date: Mon, 8 Dec 2025 12:06:01 +0100 Subject: [PATCH] path formatting fixed, long flag support, command execution path now gets passed with the command result to not make it dependant on dynamic bash variable unlike previously implemented with pwd (prev. working dir) --- src/lib/stores/bash/bash.ts | 12 ++--- src/lib/stores/bash/commands/cd.ts | 2 +- src/lib/stores/bash/commands/ls.ts | 81 ++++++++++++++++++++++------- src/lib/stores/bash/static.ts | 12 +---- src/lib/stores/terminal/terminal.ts | 18 ++++--- 5 files changed, 82 insertions(+), 43 deletions(-) diff --git a/src/lib/stores/bash/bash.ts b/src/lib/stores/bash/bash.ts index 5e2cc0a..2c4dffc 100644 --- a/src/lib/stores/bash/bash.ts +++ b/src/lib/stores/bash/bash.ts @@ -96,7 +96,7 @@ export class Bash { } executeCommand(commandName: string, args: CommandArgs): void { - let result: Result = { exitCode: ExitCode.ERROR }; + let result: Result = { exitCode: ExitCode.ERROR, path: this.getCwd() }; const command = this._commands[commandName]; if (!command) this.throwError(result); @@ -110,7 +110,7 @@ export class Bash { let out: Result = command.method.call(this, args); console.log(out); - this.appendNewResult(this.getCwd(), out.data?.data, this.user.history[0]); + this.appendNewResult(out.path, out.data?.data, this.user.history[0]); } throwError(result: Result): void { @@ -130,9 +130,9 @@ export class Bash { } } - private appendNewResult(workingDir: number, output: any, cmd: string) { + private appendNewResult(inode: number, output: any, cmd: string) { const data: PrintData = { - path: this.vfs.formatPath(this.vfs.getPathByInode(workingDir)), + path: this.vfs.formatPath(this.vfs.getPathByInode(inode)), output: output, cmd: cmd }; @@ -140,10 +140,10 @@ export class Bash { this._terminal.PrintOutput(data); } - formatBytes(bytes: number, dPoint?: number): string { + formatBytes(bytes: number, dPoint?: number, pow: 1024 | 1000 = 1024): string { if (!+bytes) return '0'; - const k: number = 1024; + const k: number = pow; const dp: number = dPoint ? (dPoint < 0 ? 0 : dPoint) : 1; const units: string[] = ['', 'K', 'M', 'G', 'T', 'P']; diff --git a/src/lib/stores/bash/commands/cd.ts b/src/lib/stores/bash/commands/cd.ts index d5e09e9..854558c 100644 --- a/src/lib/stores/bash/commands/cd.ts +++ b/src/lib/stores/bash/commands/cd.ts @@ -3,7 +3,7 @@ import { Type, type TreeNode } from '../fs'; import type { CommandArgs, ICommand, Result } from '../static'; export const cmd_cd = function (this: Bash, args: CommandArgs): Result { - let result: Result = { exitCode: ExitCode.ERROR }; + let result: Result = { exitCode: ExitCode.ERROR, path: this.getCwd() }; const path = args.args[0]; let targetNode: TreeNode | null; diff --git a/src/lib/stores/bash/commands/ls.ts b/src/lib/stores/bash/commands/ls.ts index 5fc463b..7d85e2e 100644 --- a/src/lib/stores/bash/commands/ls.ts +++ b/src/lib/stores/bash/commands/ls.ts @@ -4,6 +4,7 @@ import { Sort } from '../sort'; import type { CommandArgs, ICommand, Result, resultData } from '../static'; type LsEntry = { + inode: number | null; perms: string; children: string; owners: string; @@ -38,7 +39,7 @@ const months: readonly string[] = [ export const cmd_ls = function (this: Bash, args: CommandArgs): Result { const resultData: resultData = { cmd: 'ls', data: null, args: args }; - const result: Result = { exitCode: ExitCode.ERROR, data: resultData }; + const result: Result = { exitCode: ExitCode.ERROR, path: this.getCwd(), data: resultData }; const nodes: TreeNode[] = []; //Check if args contain any nonexistent flags, if so add it to an array and check its length. if 0 no bad flags @@ -66,15 +67,28 @@ export const cmd_ls = function (this: Bash, args: CommandArgs): Result { function result_ls(this: Bash, data: any, args: CommandArgs): HTMLElement { const dummysonoerror: HTMLElement = document.createElement('div'); - const flagInfo = checkFlags(args.flags, ls.flags); + const flagInfo = checkFlags(args.flags); const nodes: TreeNode[] = data; - const f_a: boolean = flagInfo.has('a') || flagInfo.has('f'); - const f_h: boolean = flagInfo.has('h'); + const f_a: boolean = flagInfo.has('a') || flagInfo.has('all'); + const f_A: boolean = flagInfo.has('A') || flagInfo.has('almost-all'); + const f_G: boolean = flagInfo.has('G') || flagInfo.has('no-group'); + const f_h: boolean = flagInfo.has('h') || flagInfo.has('human-readable'); + const f_r: boolean = flagInfo.has('r') || flagInfo.has('reverse'); + const f_Q: boolean = flagInfo.has('Q') || flagInfo.has('quote-name'); + const f_n: boolean = flagInfo.has('n') || flagInfo.has('numeric-uid-gid'); + const f_N: boolean = flagInfo.has('N') || flagInfo.has('literal'); + const f_L: boolean = flagInfo.has('L') || flagInfo.has('dereference'); + const f_i: boolean = flagInfo.has('i') || flagInfo.has('inode'); + const f_help: boolean = flagInfo.has('help'); + const f_si: boolean = flagInfo.has('si'); + const f_l: boolean = flagInfo.has('l'); const f_U: boolean = flagInfo.has('U'); const f_f: boolean = flagInfo.has('f'); + const f_g: boolean = flagInfo.has('g'); + const f_o: boolean = flagInfo.has('o'); - if (flagInfo.has('l') || flagInfo.has('g') || flagInfo.has('o')) { + if (f_l || f_g || f_o) { const w: HTMLElement = document.createElement('div'); for (const node of nodes) { @@ -84,33 +98,37 @@ function result_ls(this: Bash, data: any, args: CommandArgs): HTMLElement { if (!f_U && !f_f) { //TODO: Add sort by option later on - Sort.nodeArraySort.call(this, children, flagInfo.has('r')); + Sort.nodeArraySort.call(this, children, f_r); } const sizes = children.map((child) => child.size); const maxSizeWidth = Math.max(...sizes.map((size) => size)); for (const child of children) { - if (child.name.startsWith('.') && !(f_a || flagInfo.has('A'))) continue; + if (child.name.startsWith('.') && !(f_a || f_A)) continue; const cols: LsEntry = { + inode: null, perms: formatPermission(child), children: formatChildren(child), owners: formatOwners.call(this, child, flagInfo), - size: formatSize.call(this, f_h, child, maxSizeWidth), + size: formatSize.call(this, f_h, child, maxSizeWidth, f_si), modt: formatModtime(child), name: formatName(child, flagInfo) }; + if (f_i) cols.inode = child.inode; + rows.push(LsEntryUtils.toString(cols)); } - if (f_a && !flagInfo.has('A')) { + if (f_a && !f_A) { const current: LsEntry = { + inode: null, perms: formatPermission(node), children: formatChildren(node), owners: formatOwners.call(this, node, flagInfo), - size: formatSize.call(this, f_h, node, maxSizeWidth), + size: formatSize.call(this, f_h, node, maxSizeWidth, f_si), modt: formatModtime(node), name: '.' }; @@ -121,16 +139,22 @@ function result_ls(this: Bash, data: any, args: CommandArgs): HTMLElement { if (node.parent) { const parentNode: TreeNode = this.getFs().getNodeByINode(node.parent); parent = { + inode: null, perms: formatPermission(parentNode), children: formatChildren(parentNode), owners: formatOwners.call(this, parentNode, flagInfo), - size: formatSize.call(this, f_h, parentNode, maxSizeWidth), + size: formatSize.call(this, f_h, parentNode, maxSizeWidth, f_si), modt: formatModtime(parentNode), name: '..' }; } - if (flagInfo.has('r')) { + if (f_i) { + current.inode = node.inode; + parent.inode = node.parent ? node.parent : node.inode; + } + + if (f_r) { rows.push(LsEntryUtils.toString(parent), LsEntryUtils.toString(current)); } else { rows.unshift(LsEntryUtils.toString(current), LsEntryUtils.toString(parent)); @@ -203,12 +227,17 @@ function formatChildren(node: TreeNode): string { return c.length > 1 ? c : ` ${c}`; } -function formatSize(this: Bash, humanReadable: boolean, node: TreeNode, max: number): string { - const byteSize: number = node.type === Type.Directory ? 4096 : 1; //TEMP, later calculate the size. +function formatSize( + this: Bash, + humanReadable: boolean, + node: TreeNode, + max: number, + f_si: boolean +): string { let size: string; if (humanReadable) { - size = this.formatBytes(byteSize); - } else size = byteSize.toString(); + size = this.formatBytes(node.size, 1, f_si ? 1000 : 1024); + } else size = node.size.toString(); return size.padStart(max, ' '); } @@ -243,7 +272,7 @@ function formatName(node: TreeNode, flag: any) { return flag.has('p') && node.type === Type.Directory ? `${name}/` : name; } -const checkFlags = (pFlags: string[], dFlags: string[]) => { +const checkFlags = (pFlags: string[]) => { const flagSet = new Set(pFlags); return { has: (flag: string) => flagSet.has(flag) }; @@ -273,7 +302,23 @@ export const ls: ICommand = { 'n', 'N', 'L', - 'm' + 'm', + 'i', + 'sort', + 'time', + 'help', + 'all', + 'almost-all', + 'no-group', + 'human-readable', + 'reverse', + 'quote-name', + 'indicator-style', + 'literal', + 'numeric-uid-gid', + 'inode', + 'si', + 'dereference' ] as string[], help: 'PATH TO HELP.MD', root: false diff --git a/src/lib/stores/bash/static.ts b/src/lib/stores/bash/static.ts index f36d41b..de724ce 100644 --- a/src/lib/stores/bash/static.ts +++ b/src/lib/stores/bash/static.ts @@ -22,6 +22,7 @@ export type resultData = { export type Result = { exitCode: ExitCode; + path: number; //the inode of the place that the command was executed in data?: resultData; }; @@ -73,18 +74,7 @@ export const PASSWD: User[] = [ } ]; -export const cmd_return = function (this: Bash, args: CommandArgs): Result { - let result: Result = { exitCode: ExitCode.ERROR }; - return result; -}; - export const COMMANDS = { - return: { - method: cmd_return, - flags: [] as string[], - help: 'PATH TO HELP.MD', - root: false - }, cd, ls } as const satisfies Record; diff --git a/src/lib/stores/terminal/terminal.ts b/src/lib/stores/terminal/terminal.ts index 232e25b..3a8adc4 100644 --- a/src/lib/stores/terminal/terminal.ts +++ b/src/lib/stores/terminal/terminal.ts @@ -66,17 +66,21 @@ export class Terminal { for (let i = 0; i < args.length; i++) { let curr = args[i]; + console.log(curr); - if (!curr.startsWith('-')) result.args.args.push(curr); - else { + if (curr.startsWith('--')) { + curr = curr.replaceAll('--', ''); + if (curr.length === 0) continue; + + result.args.flags.push(curr); + } else if (curr.startsWith('-')) { curr = curr.replaceAll('-', ''); + if (curr.length === 0) continue; - if (curr.length > 0) { - for (let n = 0; n < curr.length; n++) { - result.args.flags.push(curr[n]); - } + for (let n = 0; n < curr.length; n++) { + result.args.flags.push(curr[n]); } - } + } else result.args.args.push(curr); } return result;