ls command now prints output in short format aswell (no flags support yet)
This commit is contained in:
@@ -105,7 +105,6 @@ function result_ls(this: Bash, data: any, args: CommandArgs): HTMLElement {
|
|||||||
for (const node of nodes) {
|
for (const node of nodes) {
|
||||||
const elem: HTMLElement = document.createElement('div');
|
const elem: HTMLElement = document.createElement('div');
|
||||||
const children: TreeNode[] = node.children.map((child) => this.getFs().getNodeByINode(child));
|
const children: TreeNode[] = node.children.map((child) => this.getFs().getNodeByINode(child));
|
||||||
const rows: string[] = [];
|
|
||||||
const timeArg = valuedArgs.find((flag) => flag.startsWith('time'));
|
const timeArg = valuedArgs.find((flag) => flag.startsWith('time'));
|
||||||
const shouldNamesShift: boolean = children.some((child) => child.name.match(/\s/) !== null);
|
const shouldNamesShift: boolean = children.some((child) => child.name.match(/\s/) !== null);
|
||||||
let timestamp: SortNodeBy.ATIME | SortNodeBy.CTIME | SortNodeBy.MTIME = SortNodeBy.MTIME;
|
let timestamp: SortNodeBy.ATIME | SortNodeBy.CTIME | SortNodeBy.MTIME = SortNodeBy.MTIME;
|
||||||
@@ -131,114 +130,150 @@ function result_ls(this: Bash, data: any, args: CommandArgs): HTMLElement {
|
|||||||
Sort.nodeArraySort.call(this, children, f_r, sortBy);
|
Sort.nodeArraySort.call(this, children, f_r, sortBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f_l || f_g || f_o) {
|
if (f_l || f_g || f_o) {
|
||||||
|
const rows: string[] = [];
|
||||||
|
|
||||||
for (const node of nodes) {
|
for (const node of nodes) {
|
||||||
const maxSizeWidth = Math.max(
|
const maxSizeWidth = Math.max(
|
||||||
...children.map((child) => child.size.toString().length));
|
...children.map((child) => child.size.toString().length));
|
||||||
|
|
||||||
for (const child of children) {
|
for (const child of children) {
|
||||||
if (child.name.startsWith('.') && !(f_a || f_A)) continue;
|
if (child.name.startsWith('.') && !(f_a || f_A)) continue;
|
||||||
|
|
||||||
const entry: LsEntry = {
|
const entry: LsEntry = {
|
||||||
inode: null,
|
|
||||||
perms: formatPermission(child),
|
|
||||||
children: formatChildren(child),
|
|
||||||
owners: formatOwners.call(this, child, flagInfo),
|
|
||||||
size: formatSize.call(this, f_h, child, maxSizeWidth, f_si),
|
|
||||||
modt: formatModtime(child, timestamp),
|
|
||||||
name: formatName(child, flagInfo, shouldNamesShift)
|
|
||||||
};
|
|
||||||
|
|
||||||
if (f_i) entry.inode = child.inode;
|
|
||||||
|
|
||||||
rows.push(LsEntryUtils.toString(entry));
|
|
||||||
}
|
|
||||||
|
|
||||||
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, f_si),
|
|
||||||
modt: formatModtime(node, timestamp),
|
|
||||||
name: shouldNamesShift ? ' .' : '.'
|
|
||||||
};
|
|
||||||
let parent: LsEntry = {
|
|
||||||
...current,
|
|
||||||
name: shouldNamesShift ? ' ..' : '..'
|
|
||||||
};
|
|
||||||
if (node.parent) {
|
|
||||||
const parentNode: TreeNode = this.getFs().getNodeByINode(node.parent);
|
|
||||||
parent = {
|
|
||||||
inode: null,
|
inode: null,
|
||||||
perms: formatPermission(parentNode),
|
perms: formatPermission(child),
|
||||||
children: formatChildren(parentNode),
|
children: formatChildren(child),
|
||||||
owners: formatOwners.call(this, parentNode, flagInfo),
|
owners: formatOwners.call(this, child, flagInfo),
|
||||||
size: formatSize.call(this, f_h, parentNode, maxSizeWidth, f_si),
|
size: formatSize.call(this, f_h, child, maxSizeWidth, f_si),
|
||||||
modt: formatModtime(parentNode, timestamp),
|
modt: formatModtime(child, timestamp),
|
||||||
|
name: formatName(child, flagInfo, shouldNamesShift)
|
||||||
|
};
|
||||||
|
|
||||||
|
if (f_i) entry.inode = child.inode;
|
||||||
|
|
||||||
|
rows.push(LsEntryUtils.toString(entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
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, f_si),
|
||||||
|
modt: formatModtime(node, timestamp),
|
||||||
|
name: shouldNamesShift ? ' .' : '.'
|
||||||
|
};
|
||||||
|
let parent: LsEntry = {
|
||||||
|
...current,
|
||||||
name: shouldNamesShift ? ' ..' : '..'
|
name: shouldNamesShift ? ' ..' : '..'
|
||||||
};
|
};
|
||||||
|
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, f_si),
|
||||||
|
modt: formatModtime(parentNode, timestamp),
|
||||||
|
name: shouldNamesShift ? ' ..' : '..'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f_i) {
|
//TODO: Calculate the total size of contents in the node
|
||||||
current.inode = node.inode;
|
rows.unshift('total ' + node.children.length.toString());
|
||||||
parent.inode = node.parent ? node.parent : node.inode;
|
|
||||||
|
if (nodes.length > 1) {
|
||||||
|
const nodePath: string =
|
||||||
|
node.name === '/' ? '/:' : `${this.getFs().getPathByInode(node.inode).slice(1)}:`;
|
||||||
|
rows.unshift(nodePath);
|
||||||
|
rows.push('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f_r) {
|
|
||||||
rows.push(LsEntryUtils.toString(parent), LsEntryUtils.toString(current));
|
|
||||||
} else {
|
for (let i = 0; i < rows.length; i++) {
|
||||||
rows.unshift(LsEntryUtils.toString(current), LsEntryUtils.toString(parent));
|
const p: HTMLElement = document.createElement('p');
|
||||||
|
|
||||||
|
|
||||||
|
p.innerText = rows[i];
|
||||||
|
|
||||||
|
elem.appendChild(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
w.appendChild(elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Calculate the total size of contents in the node
|
|
||||||
rows.unshift('total ' + node.children.length.toString());
|
|
||||||
|
|
||||||
if (nodes.length > 1) {
|
|
||||||
const nodePath: string =
|
|
||||||
node.name === '/' ? '/:' : `${this.getFs().getPathByInode(node.inode).slice(1)}:`;
|
|
||||||
rows.unshift(nodePath);
|
|
||||||
rows.push('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (let i = 0; i < rows.length; i++) {
|
|
||||||
const p: HTMLElement = document.createElement('p');
|
|
||||||
|
|
||||||
|
|
||||||
p.innerText = rows[i];
|
|
||||||
|
|
||||||
elem.appendChild(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
w.appendChild(elem);
|
|
||||||
}
|
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
const maxWidth: number = (this.getTerminalWidth() / this.getTerminalFontSize()) * 0.8;
|
const maxWidth: number = Math.ceil((this.getTerminalWidth() / this.getTerminalFontSize()) * 0.8);
|
||||||
const nameLengths: number[] = nodes.map(node => node.name.length);
|
const nameLengths: number[] = children.map(node => node.name.length);
|
||||||
|
|
||||||
let columns: string[][] = [];
|
let columns: string[][] = [];
|
||||||
|
let colWidths: number[];
|
||||||
let lowBound: number = 1;
|
let lowBound: number = 1;
|
||||||
let highBound: number = Math.floor(maxWidth / 3);
|
let highBound: number = Math.floor(maxWidth / 3);
|
||||||
let c: number = (lowBound + highBound) / 2;
|
|
||||||
|
|
||||||
nodeBinarySearch(nodes.length, nameLengths, lowBound, highBound, maxWidth);
|
|
||||||
|
|
||||||
for(let i = 0; i < c -1; i++) {
|
while(lowBound + 1 < highBound) {
|
||||||
const colSize: number = i < (nodes.length % c) ? nodes.length : nodes.length -1;
|
let c: number = Math.ceil((lowBound + highBound) / 2);
|
||||||
|
|
||||||
for(let j = 0; j < colSize -1; j++){
|
columns = [];
|
||||||
if(j >= nodes.length -1) break;
|
colWidths = [];
|
||||||
|
|
||||||
columns[i].push(nodes[j].name);
|
for(let i = 0; i < c; i++) {
|
||||||
}
|
columns[i] = [];
|
||||||
|
for(let j = 0; j < Math.ceil((children.length / c)); j++){
|
||||||
|
const fileIndex: number = i * Math.floor((children.length / c)) + j;
|
||||||
|
columns[i].push(children[fileIndex].name);
|
||||||
|
}
|
||||||
|
colWidths.push(Math.max(...columns[i].map((string) => string.length)));
|
||||||
|
}
|
||||||
|
|
||||||
|
let calcWidth: number =
|
||||||
|
Math.ceil(colWidths.reduce((result, value) => result + value) + ((c-1) * 2));
|
||||||
|
|
||||||
|
if(calcWidth <= maxWidth) {
|
||||||
|
lowBound = c;
|
||||||
|
}
|
||||||
|
else highBound = c;
|
||||||
}
|
}
|
||||||
//w.appendChild();
|
|
||||||
|
const wrapper: HTMLElement = document.createElement('div');
|
||||||
|
wrapper.style.display = 'flex';
|
||||||
|
wrapper.style.columnGap = `${this.getTerminalFontSize() * 2}px`;
|
||||||
|
|
||||||
|
for(let i = 0; i < columns.length -1; i++) {
|
||||||
|
const col: HTMLElement = document.createElement('div');
|
||||||
|
for(let j = 0; j < columns[i].length -1; j++) {
|
||||||
|
const name: HTMLElement = document.createElement('p');
|
||||||
|
name.innerText = columns[i][j];
|
||||||
|
col.appendChild(name);
|
||||||
|
}
|
||||||
|
wrapper.appendChild(col);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nodes.length > 1) {
|
||||||
|
const nodePath: HTMLElement = document.createElement('p');
|
||||||
|
nodePath.innerText = node.name === '/' ? '/:' : `${this.getFs().getPathByInode(node.inode).slice(1)}:`;
|
||||||
|
w.appendChild(nodePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
w.appendChild(wrapper);
|
||||||
}
|
}
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
@@ -248,20 +283,29 @@ function nodeBinarySearch(
|
|||||||
nameLengths: number[],
|
nameLengths: number[],
|
||||||
low: number,
|
low: number,
|
||||||
high: number,
|
high: number,
|
||||||
max: number) {
|
max: number): number {
|
||||||
|
|
||||||
let c: number = (low + high) / 2;
|
let cols: number = Math.floor((low + high) / 2);
|
||||||
|
|
||||||
|
console.log("new bounds", low, high);
|
||||||
|
|
||||||
if(low + 1 < high) {
|
if(low + 1 < high) {
|
||||||
|
|
||||||
|
|
||||||
const calcWidth: number =
|
const calcWidth: number =
|
||||||
nameLengths.reduce((result, value) => result + value) + (c-1) * 2
|
Math.ceil(nameLengths.reduce((result, value) => result + value) + ((cols-1) * 2));
|
||||||
|
|
||||||
|
console.log(calcWidth, "calcWidth");
|
||||||
|
console.log(cols);
|
||||||
|
|
||||||
if (calcWidth <= max) {
|
if (calcWidth <= max) {
|
||||||
low = c;
|
low = cols;
|
||||||
} else high = c;
|
} else high = cols;
|
||||||
|
|
||||||
nodeBinarySearch(n, nameLengths, low, high, max);
|
nodeBinarySearch(n, nameLengths, low, high, max);
|
||||||
}
|
}
|
||||||
|
console.log("out values", low, cols);
|
||||||
|
return low
|
||||||
}
|
}
|
||||||
|
|
||||||
function isValidNodeSortMethod(value: string): value is SortNodeBy {
|
function isValidNodeSortMethod(value: string): value is SortNodeBy {
|
||||||
|
|||||||
@@ -107,7 +107,6 @@ export class Terminal {
|
|||||||
const width = this.callbacks.getWidth?.();
|
const width = this.callbacks.getWidth?.();
|
||||||
if(!width) { throw new Error('somehow width is undefined still after all the checks'); }
|
if(!width) { throw new Error('somehow width is undefined still after all the checks'); }
|
||||||
|
|
||||||
console.log(width);
|
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +114,6 @@ export class Terminal {
|
|||||||
const size = this.callbacks.getFontSize?.();
|
const size = this.callbacks.getFontSize?.();
|
||||||
if(!size) { throw new Error('somehow font size is undefined still after all the checks'); }
|
if(!size) { throw new Error('somehow font size is undefined still after all the checks'); }
|
||||||
|
|
||||||
console.log(size);
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
}
|
}
|
||||||
//gets an int from padding property value (which is a string) by cutting last 2 letters "px" and parsing to int
|
//gets an int from padding property value (which is a string) by cutting last 2 letters "px" and parsing to int
|
||||||
const padding: number = parseInt(window.getComputedStyle(e, null).getPropertyValue('padding').slice(0, -2));
|
const padding: number = parseInt(window.getComputedStyle(e, null).getPropertyValue('padding').slice(0, -2));
|
||||||
console.log(padding);
|
|
||||||
return e.clientWidth - (padding * 2);
|
return e.clientWidth - (padding * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,12 +30,15 @@
|
|||||||
if(!e) {
|
if(!e) {
|
||||||
throw new Error('cant get font size of the terminal element. its null');
|
throw new Error('cant get font size of the terminal element. its null');
|
||||||
}
|
}
|
||||||
const size: number = parseInt(window.getComputedStyle(e, null).getPropertyValue('font-size').slice(0, -2));
|
|
||||||
return size;
|
const canvas = document.createElement('canvas');
|
||||||
|
const ctx = canvas.getContext('2d')!;
|
||||||
|
ctx.font = `${window.getComputedStyle(e, null).getPropertyValue('font-size')} 'JetBrains Mono', monospace;`;
|
||||||
|
return ctx.measureText('M').width;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleInput(e: KeyboardEvent) {
|
function handleInput(event: KeyboardEvent) {
|
||||||
switch (e.key) {
|
switch (event.key) {
|
||||||
case 'Enter': {
|
case 'Enter': {
|
||||||
terminal.executeCommand(inputValue);
|
terminal.executeCommand(inputValue);
|
||||||
updateTerminal();
|
updateTerminal();
|
||||||
@@ -55,6 +57,13 @@
|
|||||||
//TODO: Make a traverse history function with up/down args
|
//TODO: Make a traverse history function with up/down args
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const elem = document.getElementById('cout');
|
||||||
|
if(!elem){
|
||||||
|
throw new Error('cant scroll to bottom, element is null');
|
||||||
|
}
|
||||||
|
|
||||||
|
elem.scrollTop = elem.scrollHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Callback initializer
|
//Callback initializer
|
||||||
@@ -95,8 +104,8 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<label for="input" onkeydowncapture={(e) => handleInput(e)}>
|
<label for="input" onkeydowncapture={(e) => handleInput(e)} class="w-11/12">
|
||||||
<div id="terminal" class="terminal-window shadow-() size-full rounded-md shadow-bg">
|
<div id="terminal" class="terminal-window shadow-() h-full w-full rounded-md shadow-bg">
|
||||||
<div
|
<div
|
||||||
class="terminal-bar flex h-9 w-full flex-row items-center rounded-t-md bg-bg-dark text-center font-terminal text-sm font-bold text-primary-dark light:bg-bg-dark-light light:text-primary-light"
|
class="terminal-bar flex h-9 w-full flex-row items-center rounded-t-md bg-bg-dark text-center font-terminal text-sm font-bold text-primary-dark light:bg-bg-dark-light light:text-primary-light"
|
||||||
>
|
>
|
||||||
@@ -105,7 +114,7 @@
|
|||||||
<button class="size-2.5 cursor-pointer rounded-full p-0" title=""></button>
|
<button class="size-2.5 cursor-pointer rounded-full p-0" title=""></button>
|
||||||
<button class="size-2.5 cursor-pointer rounded-full p-0" title=""></button>
|
<button class="size-2.5 cursor-pointer rounded-full p-0" title=""></button>
|
||||||
</div>
|
</div>
|
||||||
<div class=" flex">
|
<div class=" flex mr-2 grow">
|
||||||
<h5>{username}</h5>
|
<h5>{username}</h5>
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<h5 class=" mr-2">@terminal: </h5>
|
<h5 class=" mr-2">@terminal: </h5>
|
||||||
@@ -113,7 +122,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="inner-content scroll-hidden h-[860px] origin-top overflow-y-auto rounded-b-md bg-bg-light-dark p-4 text-text-dark shadow-subtle light:bg-bg-lighter-light light:text-text-light"
|
class="inner-content scroll-hidden h-7/8 origin-top overflow-y-auto rounded-b-md bg-bg-light-dark p-4 text-text-dark shadow-subtle light:bg-bg-lighter-light light:text-text-light"
|
||||||
id="cout"
|
id="cout"
|
||||||
>
|
>
|
||||||
<div id="outputWrapper"></div>
|
<div id="outputWrapper"></div>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Settings></Settings>
|
<Settings></Settings>
|
||||||
<div class="h-dvh w-full p-24">
|
<div class="h-dvh w-full p-24 flex justify-center">
|
||||||
<TerminalModule />
|
<TerminalModule />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user