Skip to content

Commit f02de06

Browse files
committed
subCommands
1 parent 4eb129a commit f02de06

File tree

2 files changed

+29
-28
lines changed

2 files changed

+29
-28
lines changed

src/citty.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ export default async function tab<T extends ArgsDef = ArgsDef>(instance: Command
8181

8282
await handleSubCommands(completion, subCommands);
8383

84+
// console.log("LOOK HERE", subCommands)
85+
8486
if (instance.args) {
8587
for (const [argName, argConfig] of Object.entries(instance.args)) {
8688
const conf = argConfig as PositionalArgDef;

src/index.ts

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,14 @@ export class Completion {
8585
commands = new Map<string, Command>();
8686

8787
addCommand(name: string, description: string, handler: Handler, parent?: string) {
88-
const key = parent ? `${parent} ${name}` : name
89-
this.commands.set(key, { description, handler, options: new Map(), parent: parent ? this.commands.get(parent)! : this.commands.get('')! });
90-
return key
88+
const key = parent ? `${parent} ${name}` : name;
89+
this.commands.set(key, {
90+
description,
91+
handler,
92+
options: new Map(),
93+
parent: parent ? this.commands.get(parent)! : undefined,
94+
});
95+
return key;
9196
}
9297

9398
addOption(command: string, option: string, description: string, handler: Handler) {
@@ -96,7 +101,7 @@ export class Completion {
96101
throw new Error(`Command ${command} not found.`);
97102
}
98103
cmd.options.set(option, { description, handler });
99-
return option
104+
return option;
100105
}
101106

102107
async parse(args: string[], potentialCommand: string) {
@@ -119,12 +124,12 @@ export class Completion {
119124
if (handler) {
120125
const flagSuggestions = await handler(previousArgs, toComplete, endsWithSpace);
121126
completions.push(
122-
...flagSuggestions.filter(comp => comp.value.startsWith(toComplete)).map(
123-
(comp) => `${comp.value}\t${comp.description ?? ""}`
124-
)
127+
...flagSuggestions
128+
.filter(comp => comp.value.startsWith(toComplete))
129+
.map(comp => `${comp.value}\t${comp.description ?? ""}`)
125130
);
126131
directive = ShellCompDirective.ShellCompDirectiveNoFileComp;
127-
completions.forEach((comp) => console.log(comp));
132+
completions.forEach(comp => console.log(comp));
128133
console.log(`:${directive}`);
129134
return;
130135
}
@@ -143,7 +148,7 @@ export class Completion {
143148
if (handler) {
144149
const suggestions = await handler(previousArgs, valueToComplete, endsWithSpace);
145150
completions.push(...suggestions.map(
146-
(comp) => `${comp.value}\t${comp.description ?? ""}`
151+
comp => `${comp.value}\t${comp.description ?? ""}`
147152
));
148153
}
149154
} else if (!endsWithSpace) {
@@ -168,7 +173,7 @@ export class Completion {
168173

169174
completions.push(
170175
...availableFlags.map(
171-
(flag) => `${flag}\t${options.get(flag)!.description ?? ""}`
176+
flag => `${flag}\t${options.get(flag)!.description ?? ""}`
172177
)
173178
);
174179
} else {
@@ -177,33 +182,27 @@ export class Completion {
177182
if (handler) {
178183
const suggestions = await handler(previousArgs, toComplete, endsWithSpace);
179184
completions.push(...suggestions.map(
180-
(comp) => `${comp.value}\t${comp.description ?? ""}`
185+
comp => `${comp.value}\t${comp.description ?? ""}`
181186
));
182187
}
183-
184188
}
185-
} else if (!toComplete && endsWithSpace) {
186-
directive = ShellCompDirective.ShellCompDirectiveNoFileComp;
189+
} else {
190+
const availableSubcommands = [...this.commands.keys()]
191+
.filter(cmd => cmd.startsWith(potentialCommand) && cmd !== potentialCommand)
192+
.map(cmd => cmd.replace(`${potentialCommand} `, "").split(" ")[0])
193+
.filter((subcmd, index, self) => self.indexOf(subcmd) === index) // Remove duplicates
194+
.filter(subcmd => subcmd.startsWith(toComplete));
187195

188196
completions.push(
189-
...Object.keys(this.commands)
190-
.filter((cmd) => cmd !== "complete")
191-
.map((cmd) => `${cmd}\t${this.commands[cmd].description}`)
197+
...availableSubcommands.map(
198+
subcmd => `${subcmd}\t${this.commands.get(`${potentialCommand} ${subcmd}`)?.description ?? ""}`
199+
)
192200
);
193201

194-
const positionalCompletions = positionalMap.get(potentialCommand) || [];
195-
for (const positional of positionalCompletions) {
196-
const suggestions = await positional.completion(previousArgs, "");
197-
completions.push(
198-
...suggestions.map((comp) => `${comp.action}\t${comp.description ?? ""}`)
199-
);
200-
if (suggestions.length > 0) {
201-
directive = ShellCompDirective.ShellCompDirectiveNoFileComp;
202-
}
203-
}
202+
directive = ShellCompDirective.ShellCompDirectiveNoFileComp;
204203
}
205204

206-
completions.forEach((comp) => console.log(comp));
205+
completions.forEach(comp => console.log(comp));
207206
console.log(`:${directive}`);
208207
}
209208
}

0 commit comments

Comments
 (0)