fix: avoid OOM during completion script generation
This commit is contained in:
parent
47a15d7a9a
commit
b9c57bbb97
@ -442,17 +442,17 @@ function generateZshSubcmdList(cmd: Command): string {
|
||||
}
|
||||
|
||||
function generateZshSubcommands(program: Command, prefix: string): string {
|
||||
let script = "";
|
||||
const segments: string[] = [];
|
||||
for (const cmd of program.commands) {
|
||||
const cmdName = cmd.name();
|
||||
const funcName = `_${prefix}_${cmdName.replace(/-/g, "_")}`;
|
||||
|
||||
// Recurse first
|
||||
script += generateZshSubcommands(cmd, `${prefix}_${cmdName.replace(/-/g, "_")}`);
|
||||
segments.push(generateZshSubcommands(cmd, `${prefix}_${cmdName.replace(/-/g, "_")}`));
|
||||
|
||||
const subCommands = cmd.commands;
|
||||
if (subCommands.length > 0) {
|
||||
script += `
|
||||
segments.push(`
|
||||
${funcName}() {
|
||||
local -a commands
|
||||
local -a options
|
||||
@ -470,17 +470,17 @@ ${funcName}() {
|
||||
;;
|
||||
esac
|
||||
}
|
||||
`;
|
||||
`);
|
||||
} else {
|
||||
script += `
|
||||
segments.push(`
|
||||
${funcName}() {
|
||||
_arguments -C \\
|
||||
${generateZshArgs(cmd)}
|
||||
}
|
||||
`;
|
||||
`);
|
||||
}
|
||||
}
|
||||
return script;
|
||||
return segments.join("");
|
||||
}
|
||||
|
||||
function generateBashCompletion(program: Command): string {
|
||||
@ -529,11 +529,11 @@ function generateBashSubcommand(cmd: Command): string {
|
||||
function generatePowerShellCompletion(program: Command): string {
|
||||
const rootCmd = program.name();
|
||||
|
||||
const visit = (cmd: Command, parents: string[]): string => {
|
||||
const visit = (cmd: Command, parents: string[]): string[] => {
|
||||
const cmdName = cmd.name();
|
||||
const fullPath = [...parents, cmdName].join(" ");
|
||||
|
||||
let script = "";
|
||||
const segments: string[] = [];
|
||||
|
||||
// Command completion for this level
|
||||
const subCommands = cmd.commands.map((c) => c.name());
|
||||
@ -541,25 +541,25 @@ function generatePowerShellCompletion(program: Command): string {
|
||||
const allCompletions = [...subCommands, ...options].map((s) => `'${s}'`).join(",");
|
||||
|
||||
if (allCompletions.length > 0) {
|
||||
script += `
|
||||
segments.push(`
|
||||
if ($commandPath -eq '${fullPath}') {
|
||||
$completions = @(${allCompletions})
|
||||
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
|
||||
}
|
||||
}
|
||||
`;
|
||||
`);
|
||||
}
|
||||
|
||||
// Recurse
|
||||
for (const sub of cmd.commands) {
|
||||
script += visit(sub, [...parents, cmdName]);
|
||||
segments.push(...visit(sub, [...parents, cmdName]));
|
||||
}
|
||||
|
||||
return script;
|
||||
return segments;
|
||||
};
|
||||
|
||||
const rootBody = visit(program, []);
|
||||
const rootBody = visit(program, []).join("");
|
||||
|
||||
return `
|
||||
Register-ArgumentCompleter -Native -CommandName ${rootCmd} -ScriptBlock {
|
||||
@ -593,65 +593,57 @@ Register-ArgumentCompleter -Native -CommandName ${rootCmd} -ScriptBlock {
|
||||
|
||||
function generateFishCompletion(program: Command): string {
|
||||
const rootCmd = program.name();
|
||||
let script = "";
|
||||
const segments: string[] = [];
|
||||
|
||||
const visit = (cmd: Command, parents: string[]) => {
|
||||
const cmdName = cmd.name();
|
||||
const fullPath = [...parents];
|
||||
if (parents.length > 0) {
|
||||
fullPath.push(cmdName);
|
||||
} // Only push if not root, or consistent root handling
|
||||
|
||||
// Fish uses 'seen_subcommand_from' to determine context.
|
||||
// For root: complete -c openclaw -n "__fish_use_subcommand" -a "subcmd" -d "desc"
|
||||
|
||||
// Root logic
|
||||
if (parents.length === 0) {
|
||||
// Subcommands of root
|
||||
for (const sub of cmd.commands) {
|
||||
script += buildFishSubcommandCompletionLine({
|
||||
rootCmd,
|
||||
condition: "__fish_use_subcommand",
|
||||
name: sub.name(),
|
||||
description: sub.description(),
|
||||
});
|
||||
segments.push(
|
||||
buildFishSubcommandCompletionLine({
|
||||
rootCmd,
|
||||
condition: "__fish_use_subcommand",
|
||||
name: sub.name(),
|
||||
description: sub.description(),
|
||||
}),
|
||||
);
|
||||
}
|
||||
// Options of root
|
||||
for (const opt of cmd.options) {
|
||||
script += buildFishOptionCompletionLine({
|
||||
rootCmd,
|
||||
condition: "__fish_use_subcommand",
|
||||
flags: opt.flags,
|
||||
description: opt.description,
|
||||
});
|
||||
segments.push(
|
||||
buildFishOptionCompletionLine({
|
||||
rootCmd,
|
||||
condition: "__fish_use_subcommand",
|
||||
flags: opt.flags,
|
||||
description: opt.description,
|
||||
}),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// Nested commands
|
||||
// Logic: if seen subcommand matches parents...
|
||||
// But fish completion logic is simpler if we just say "if we haven't seen THIS command yet but seen parent"
|
||||
// Actually, a robust fish completion often requires defining a function to check current line.
|
||||
// For simplicity, we'll assume standard fish helper __fish_seen_subcommand_from.
|
||||
|
||||
// To properly scope to 'openclaw gateway' and not 'openclaw other gateway', we need to check the sequence.
|
||||
// A simplified approach:
|
||||
|
||||
// Subcommands
|
||||
for (const sub of cmd.commands) {
|
||||
script += buildFishSubcommandCompletionLine({
|
||||
rootCmd,
|
||||
condition: `__fish_seen_subcommand_from ${cmdName}`,
|
||||
name: sub.name(),
|
||||
description: sub.description(),
|
||||
});
|
||||
segments.push(
|
||||
buildFishSubcommandCompletionLine({
|
||||
rootCmd,
|
||||
condition: `__fish_seen_subcommand_from ${cmdName}`,
|
||||
name: sub.name(),
|
||||
description: sub.description(),
|
||||
}),
|
||||
);
|
||||
}
|
||||
// Options
|
||||
for (const opt of cmd.options) {
|
||||
script += buildFishOptionCompletionLine({
|
||||
rootCmd,
|
||||
condition: `__fish_seen_subcommand_from ${cmdName}`,
|
||||
flags: opt.flags,
|
||||
description: opt.description,
|
||||
});
|
||||
segments.push(
|
||||
buildFishOptionCompletionLine({
|
||||
rootCmd,
|
||||
condition: `__fish_seen_subcommand_from ${cmdName}`,
|
||||
flags: opt.flags,
|
||||
description: opt.description,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -661,5 +653,5 @@ function generateFishCompletion(program: Command): string {
|
||||
};
|
||||
|
||||
visit(program, []);
|
||||
return script;
|
||||
return segments.join("");
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user