From 07ffb6793aa28eb1f8d2fe82b4f7755ef2fee3bf Mon Sep 17 00:00:00 2001 From: Chapman Pendery Date: Wed, 25 Oct 2023 13:03:07 -0700 Subject: [PATCH] feat: add support for a session execution duration Signed-off-by: Chapman Pendery --- src/commands/root.ts | 22 ++++++++++++++++++---- src/index.ts | 1 + src/runtime/utils.ts | 2 +- src/ui/ui-root.tsx | 5 +++-- src/utils/cache.ts | 4 ++-- 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/commands/root.ts b/src/commands/root.ts index 44f2500..ebe6a93 100644 --- a/src/commands/root.ts +++ b/src/commands/root.ts @@ -2,7 +2,7 @@ // Licensed under the MIT License. import { render } from "../ui/ui-root.js"; -import { executeShellCommandTTY } from "../runtime/utils.js"; +import { executeShellCommandTTY, ExecuteShellCommandTTYResult } from "../runtime/utils.js"; import { saveCommand, loadCommand } from "../utils/cache.js"; import { supportedShells as shells } from "../utils/bindings.js"; @@ -12,6 +12,7 @@ type RootCommandOptions = { shell: string | undefined; command: string | undefined; history: boolean | undefined; + duration: string | undefined; }; export const action = async (options: RootCommandOptions) => { @@ -26,10 +27,23 @@ export const action = async (options: RootCommandOptions) => { process.exit(1); } - const commandToExecute = await render(options.command); - await saveCommand(commandToExecute); + let executed = false; + const commands = []; + let result: ExecuteShellCommandTTYResult = { code: 0 }; + while (options.duration === "session" || !executed) { + const commandToExecute = await render(options.command); + + if (commandToExecute == null) { + result = { code: 0 }; + break; + } + + commands.push(commandToExecute); + result = await executeShellCommandTTY(shell, commandToExecute); + executed = true; + } + await saveCommand(commands); - const result = await executeShellCommandTTY(shell, commandToExecute); if (result.code) { process.exit(result.code); } else { diff --git a/src/index.ts b/src/index.ts index 49078fd..a0ae9fb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -20,6 +20,7 @@ program .option("-s, --shell ", `shell to use for command execution, supported shells: ${supportedShells}`) .option("-c, --command ", "command to use as initial input") .option("--history", "get the last command execute") + .option("-d, --duration ", "duration of the autocomplete session, supported durations: single, session", "session") .action(action); program.addCommand(bind); diff --git a/src/runtime/utils.ts b/src/runtime/utils.ts index 84e6428..82bed32 100644 --- a/src/runtime/utils.ts +++ b/src/runtime/utils.ts @@ -3,7 +3,7 @@ import { exec, spawn } from "node:child_process"; -type ExecuteShellCommandTTYResult = { +export type ExecuteShellCommandTTYResult = { code: number | null; }; diff --git a/src/ui/ui-root.tsx b/src/ui/ui-root.tsx index 0656c93..94755d0 100644 --- a/src/ui/ui-root.tsx +++ b/src/ui/ui-root.tsx @@ -11,7 +11,7 @@ import Suggestions from "./suggestions.js"; import Input from "./input.js"; const Prompt = "> "; -let uiResult = ""; +let uiResult = undefined; function UI({ startingCommand }: { startingCommand: string }) { const { exit } = useApp(); @@ -71,7 +71,8 @@ function UI({ startingCommand }: { startingCommand: string }) { ); } -export const render = async (command: string | undefined) => { +export const render = async (command: string | undefined): Promise => { + uiResult = undefined; const { waitUntilExit } = inkRender(); await waitUntilExit(); diff --git a/src/utils/cache.ts b/src/utils/cache.ts index 28bc75e..cd7f0f1 100644 --- a/src/utils/cache.ts +++ b/src/utils/cache.ts @@ -10,11 +10,11 @@ const cacheFolder = ".inshellisense"; const folderPath = path.join(os.homedir(), cacheFolder); const cachePath = path.join(os.homedir(), cacheFolder, "inshellisense.cache"); -export const saveCommand = async (command: string) => { +export const saveCommand = async (command: string[]) => { if (!fs.existsSync(folderPath)) { await fsAsync.mkdir(folderPath); } - await fsAsync.writeFile(cachePath, command); + await fsAsync.writeFile(cachePath, command.map((c, idx) => `${idx.toString().padStart(5)} ${c}`).join("\n")); }; export const loadCommand = async (): Promise => {