From 670bf03f86dfd647c3ea2c0fd6b7de52d262f925 Mon Sep 17 00:00:00 2001 From: Hans van Luttikhuizen-Ross Date: Tue, 9 Apr 2024 10:20:20 +0200 Subject: [PATCH] Implement cd command --- assets/js/shell/commands.ts | 9 ++- assets/js/shell/commands/ChangeDirectory.ts | 84 +++++++++++++++++++++ assets/js/shell/commands/List.ts | 35 ++++----- assets/js/shell/helpers.ts | 22 ++++++ 4 files changed, 127 insertions(+), 23 deletions(-) create mode 100644 assets/js/shell/commands/ChangeDirectory.ts create mode 100644 assets/js/shell/helpers.ts diff --git a/assets/js/shell/commands.ts b/assets/js/shell/commands.ts index 85fcc66..f6ea5cc 100644 --- a/assets/js/shell/commands.ts +++ b/assets/js/shell/commands.ts @@ -3,5 +3,12 @@ import { Command } from "./Command"; import { Clear } from "./commands/Clear"; import { Kitties } from "./commands/Kitties"; import { List } from "./commands/List"; +import { ChangeDirectory } from "./commands/ChangeDirectory"; -export const commands: Command[] = [new Clear(), new Help(), new Kitties(), new List()]; +export const commands: Command[] = [ + new ChangeDirectory(), + new Clear(), + new Help(), + new Kitties(), + new List(), +]; diff --git a/assets/js/shell/commands/ChangeDirectory.ts b/assets/js/shell/commands/ChangeDirectory.ts new file mode 100644 index 0000000..10e5f65 --- /dev/null +++ b/assets/js/shell/commands/ChangeDirectory.ts @@ -0,0 +1,84 @@ +import { Command } from "../Command"; + +import { getAllPages, getPagesInPath } from "../helpers"; +import { HugoPage } from "../../types/hugo"; + +export class ChangeDirectory implements Command { + public readonly name: string = "cd"; + + public execute(consoleElement: HTMLDivElement, args: string[] = []): void { + if (args.length === 0) { + const outputElement = document.createElement("pre"); + outputElement.textContent = "cd: missing argument"; + consoleElement.appendChild(outputElement); + return; + } + + if (args.length > 1) { + const outputElement = document.createElement("pre"); + outputElement.textContent = "cd: too many arguments"; + consoleElement.appendChild(outputElement); + return; + } + + const allPages = getAllPages(); + const pagesInPath = getPagesInPath(window.location.pathname); + + // Change to root directory + if (!args.length || ["/", "~"].includes(args[0])) { + window.location.pathname = "/"; + return; + } + + const inputPath = args[0].replace(/\/$/, "").replace(/^~\//, "/").toLowerCase(); + + // Change to current directory + if (inputPath === ".") { + // noinspection SillyAssignmentJS + window.location.pathname = window.location.pathname; + return; + } + + // Change to parent directory + if (inputPath === "..") { + if (window.location.pathname === "/") { + return; + } + + window.location.pathname = window.location.pathname + .split("/") + .filter((s) => s !== "") + .slice(0, -1) + .join("/") + .concat("/"); + } + + // Change to an absolute path + if (inputPath.startsWith("/") || inputPath.startsWith("~/")) { + const page = allPages.find( + (p: HugoPage) => + p.Path.toLowerCase() === inputPath || + "/" + p.Section.toLowerCase() + "/" + p.Slug === inputPath, + ); + + if (page !== undefined) { + window.location.pathname = "/" + page.Section.toLowerCase() + "/" + page.Slug; + return; + } + return; + } + + // Change to a relative path + console.log(inputPath, pagesInPath); + if ( + pagesInPath.find( + (p: HugoPage) => + p.Path.replace(window.location.pathname, "").toLowerCase() === inputPath || + p.Slug === inputPath, + ) + ) { + window.location.pathname = window.location.pathname.concat(inputPath).concat("/"); + return; + } + } +} diff --git a/assets/js/shell/commands/List.ts b/assets/js/shell/commands/List.ts index d342ecd..574afc2 100644 --- a/assets/js/shell/commands/List.ts +++ b/assets/js/shell/commands/List.ts @@ -1,14 +1,11 @@ import { Command } from "../Command"; -// @ts-ignore -import params from "@params"; import { HugoPage } from "../../types/hugo"; +import { getPagesInPath } from "../helpers"; export class List implements Command { public readonly name: string = "ls"; - let pages = JSON.parse(params.pages) as HugoPage[]; - pages.sort((a: HugoPage, b: HugoPage) => b.Path.localeCompare(a.Path)); public execute(consoleElement: HTMLDivElement, args: string[]): void { if (args.length > 0) { const outputElement = document.createElement("pre"); @@ -17,22 +14,16 @@ export class List implements Command { return; } + const currentPath = window.location.pathname; + let pages = getPagesInPath(currentPath); + // Set up output elements const currentDirectoryElement = document.createElement("pre"); currentDirectoryElement.textContent = "."; const outputElements = [currentDirectoryElement]; - // Get current path - const currentPath = window.location.pathname; - // Filter pages based on current path - if (currentPath === "/") { - pages = pages - .filter((page: HugoPage) => page.Path.split("/").length === 2) - .filter((page: HugoPage) => page.Path !== "/"); - } else { - pages = pages.filter((page: HugoPage) => page.Path.startsWith(currentPath)); - + if (currentPath !== "/") { // Add parent directory const parentDirectoryElement = document.createElement("pre"); parentDirectoryElement.textContent = ".."; @@ -41,21 +32,21 @@ export class List implements Command { } // Add pages to output elements - pages.forEach((page: HugoPage) => { - const outputElement = document.createElement("pre"); + const pageElements = pages.map((page: HugoPage): HTMLPreElement => { + const pageElement = document.createElement("pre"); if (page.Slug) { - outputElement.textContent = page.Slug.concat("/"); + pageElement.textContent = page.Slug.concat("/"); } else { - outputElement.textContent = page.Path.replace(currentPath, "").concat("/"); + pageElement.textContent = page.Path.replace(currentPath, "").concat("/"); } - outputElements.push(outputElement); + return pageElement; }); + outputElements.push(...pageElements); + // Append output elements to console - outputElements.forEach((element: HTMLPreElement) => { - consoleElement.appendChild(element); - }); + consoleElement.append(...outputElements); } } diff --git a/assets/js/shell/helpers.ts b/assets/js/shell/helpers.ts new file mode 100644 index 0000000..114e348 --- /dev/null +++ b/assets/js/shell/helpers.ts @@ -0,0 +1,22 @@ +// @ts-ignore +import params from "@params"; +import { HugoPage } from "../types/hugo"; + +export function getAllPages(): HugoPage[] { + const pages = JSON.parse(params.pages) as HugoPage[]; + + return pages.sort((a: HugoPage, b: HugoPage) => b.Path.localeCompare(a.Path)); +} + +export function getPagesInPath(path: string): HugoPage[] { + const pages = getAllPages(); + + // Filter pages based on current path + if (path === "/") { + return pages + .filter((page: HugoPage) => page.Path.split("/").length === 2) + .filter((page: HugoPage) => page.Path !== "/"); + } else { + return pages.filter((page: HugoPage) => page.Path.startsWith(path)); + } +}