From 019c576f1dcaa2de2ca0bcf5f27186ad5cd99030 Mon Sep 17 00:00:00 2001 From: Matthieu Jolimaitre Date: Thu, 26 Jun 2025 15:03:27 +0200 Subject: [PATCH] Optimize process management and add terminal scrolling functionality Improved process handling, added go_up option for scrolling the terminal to the start of the command at each run. --- deno.json | 2 +- regar.ts | 29 +++++++++++++++++++++++------ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/deno.json b/deno.json index cd99b02..a634c3d 100644 --- a/deno.json +++ b/deno.json @@ -1,3 +1,3 @@ { - "fmt": { "useTabs": true, "lineWidth": 120 } + "fmt": { "useTabs": true, "lineWidth": 120 } } diff --git a/regar.ts b/regar.ts index d30b5c4..0b188d4 100755 --- a/regar.ts +++ b/regar.ts @@ -5,10 +5,10 @@ import { Command } from "https://deno.land/x/cliffy@v1.0.0-rc.4/command/mod.ts"; import { Channel, Constructible, InstanceOf } from "https://git.barnulf.net/mb/barnulf_ts/raw/branch/master/mod.ts"; async function main() { - const { do_clear, command, extensions, files, strategy } = await parse_args(); + const { do_clear, command, extensions, files, strategy, go_up } = await parse_args(); const channel = new Channel(); files.map((path) => new Watcher(path, extensions).spin(channel)); - new Runner(command, strategy, do_clear).spin(channel); + new Runner(command, strategy, do_clear, go_up).spin(channel); } async function parse_args() { @@ -20,15 +20,18 @@ async function parse_args() { .option("-s, --soft", "Ends the child process by sending an interuption and waiting for it to shut down.") .option("-w, --wait", "Wait for the child process to complete without terminating it. (default)") .option("-e, --extensions ", "Comma separated whitelist of extensions to whatch.") - .option("-c, --clear", "Clear the terminal on restart").parse(); + .option("-c, --clear", "Clear the terminal on restart.", { default: false }) + .option("-u, --up", "Scroll the terminal to the start of the command at each run.", { default: false }) + .parse(); const [command, ...files] = args; let strategy: ShutdownStrategy = new WaitStrategy(); if (options.soft) strategy = new SoftStrategy(); if (options.hard) strategy = new HardStrategy(); if (options.wait) strategy = new WaitStrategy(); const extensions = options.extensions?.split(","); - const do_clear = options.clear ?? false; - return { command, files, strategy, extensions, do_clear }; + const do_clear = options.clear; + const go_up = options.up; + return { command, files, strategy, extensions, do_clear, go_up }; } class Watcher { @@ -58,6 +61,7 @@ class Runner { private command: string, private strategy: ShutdownStrategy, private do_clear: boolean, + private go_up: boolean, ) {} public async spin(channel: Channel) { @@ -77,6 +81,8 @@ class Runner { private launch() { const args = ["-c", this.command]; log("running", this.command); + if (this.go_up) this.save_cursor(); + console.log(); const process = new Deno.Command("sh", { args }).spawn(); process.status.then(this.on_end()); return process; @@ -102,9 +108,18 @@ class Runner { const end_ms = Date.now(); const time_ms = end_ms - start_ms; const secs = time_ms / 1000; + if (this.go_up) this.restore_cursor(); log("terminated", `${secs} s`); }; } + + private save_cursor() { + console.log("\x1bs"); + } + + private restore_cursor() { + console.log("\x1b[u"); + } } interface ShutdownStrategy { @@ -166,7 +181,9 @@ function catch_[]>(op: () => T, ...catchings: for (const [kind, strategy] of catchings) { if (!(exception instanceof kind)) continue; if (strategy === "ignore") return; - return strategy(exception); + // trust + // deno-lint-ignore no-explicit-any + return strategy(exception as any); } } }