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;