mirror of
https://github.com/purrgrammer/grimoire.git
synced 2026-04-18 11:27:04 +02:00
feat: add title command line flag
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import { parse as parseShellTokens } from "shell-quote";
|
||||
import { manPages } from "@/types/man";
|
||||
import { extractGlobalFlagsFromTokens, type GlobalFlags } from "./global-flags";
|
||||
|
||||
export interface ParsedCommand {
|
||||
commandName: string;
|
||||
@@ -6,20 +8,57 @@ export interface ParsedCommand {
|
||||
fullInput: string;
|
||||
command?: (typeof manPages)[string];
|
||||
props?: any;
|
||||
title?: string;
|
||||
error?: string;
|
||||
globalFlags?: GlobalFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a command string into its components.
|
||||
* Returns basic parsing info without executing argParser.
|
||||
*
|
||||
* Now supports:
|
||||
* - Proper quote handling via shell-quote
|
||||
* - Global flag extraction (--title, etc.)
|
||||
*/
|
||||
export function parseCommandInput(input: string): ParsedCommand {
|
||||
const parts = input.trim().split(/\s+/);
|
||||
const commandName = parts[0]?.toLowerCase() || "";
|
||||
const args = parts.slice(1);
|
||||
const fullInput = input.trim();
|
||||
|
||||
// Pre-process: Escape $ to prevent shell-quote from expanding variables
|
||||
// We use $me and $contacts as literal syntax, not shell variables
|
||||
const DOLLAR_PLACEHOLDER = "___DOLLAR___";
|
||||
const escapedInput = fullInput.replace(/\$/g, DOLLAR_PLACEHOLDER);
|
||||
|
||||
// Tokenize with quote support (on escaped input)
|
||||
const rawTokens = parseShellTokens(escapedInput);
|
||||
|
||||
// Convert tokens to strings and restore $ characters
|
||||
const tokens = rawTokens.map((token) => {
|
||||
const str = typeof token === "string" ? token : String(token);
|
||||
return str.replace(new RegExp(DOLLAR_PLACEHOLDER, "g"), "$");
|
||||
});
|
||||
|
||||
// Extract global flags before command parsing
|
||||
let globalFlags: GlobalFlags = {};
|
||||
let remainingTokens = tokens;
|
||||
|
||||
try {
|
||||
const extracted = extractGlobalFlagsFromTokens(tokens);
|
||||
globalFlags = extracted.globalFlags;
|
||||
remainingTokens = extracted.remainingTokens;
|
||||
} catch (error) {
|
||||
// Global flag parsing error
|
||||
return {
|
||||
commandName: "",
|
||||
args: [],
|
||||
fullInput,
|
||||
error: error instanceof Error ? error.message : "Failed to parse global flags",
|
||||
};
|
||||
}
|
||||
|
||||
// Parse command from remaining tokens
|
||||
const commandName = remainingTokens[0]?.toLowerCase() || "";
|
||||
const args = remainingTokens.slice(1);
|
||||
|
||||
const command = commandName && manPages[commandName];
|
||||
|
||||
if (!commandName) {
|
||||
@@ -27,6 +66,7 @@ export function parseCommandInput(input: string): ParsedCommand {
|
||||
commandName: "",
|
||||
args: [],
|
||||
fullInput: "",
|
||||
globalFlags,
|
||||
error: "No command provided",
|
||||
};
|
||||
}
|
||||
@@ -36,6 +76,7 @@ export function parseCommandInput(input: string): ParsedCommand {
|
||||
commandName,
|
||||
args,
|
||||
fullInput,
|
||||
globalFlags,
|
||||
error: `Unknown command: ${commandName}`,
|
||||
};
|
||||
}
|
||||
@@ -45,6 +86,7 @@ export function parseCommandInput(input: string): ParsedCommand {
|
||||
args,
|
||||
fullInput,
|
||||
command,
|
||||
globalFlags,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -65,16 +107,9 @@ export async function executeCommandParser(
|
||||
? await Promise.resolve(parsed.command.argParser(parsed.args))
|
||||
: parsed.command.defaultProps || {};
|
||||
|
||||
// Generate title
|
||||
const title =
|
||||
parsed.args.length > 0
|
||||
? `${parsed.commandName.toUpperCase()} ${parsed.args.join(" ")}`
|
||||
: parsed.commandName.toUpperCase();
|
||||
|
||||
return {
|
||||
...parsed,
|
||||
props,
|
||||
title,
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user