@flowscripter/dynamic-cli-framework 1.2.2 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README/core-service-providers.md +2 -2
- package/README/development.md +3 -6
- package/README/implementation-details.md +17 -17
- package/README/key-concepts.md +17 -17
- package/README.md +4 -4
- package/bun.lock +0 -2
- package/index.ts +22 -30
- package/package.json +19 -19
- package/src/api/argument/Argument.ts +1 -1
- package/src/api/argument/ArgumentValueTypes.ts +3 -10
- package/src/api/argument/ComplexOption.ts +5 -9
- package/src/api/command/GlobalCommand.ts +1 -4
- package/src/api/service/core/ArgumentPrompterService.ts +1 -3
- package/src/api/service/core/AsciiBannerGeneratorService.ts +1 -4
- package/src/api/service/core/CompletionService.ts +2 -6
- package/src/api/service/core/ImagePrinterService.ts +1 -2
- package/src/api/service/core/KeyValueService.ts +1 -2
- package/src/api/service/core/PrettyPrinterService.ts +1 -4
- package/src/api/service/core/PrinterService.ts +8 -9
- package/src/api/service/core/PrompterService.ts +4 -11
- package/src/api/service/core/ShutdownService.ts +1 -2
- package/src/api/service/core/SyntaxHighlighterService.ts +1 -5
- package/src/api/service/core/Table.ts +7 -25
- package/src/api/service/core/TreePrinterService.ts +1 -2
- package/src/cli/BaseCLI.ts +17 -47
- package/src/cli/DefaultRuntimeCLI.ts +1 -4
- package/src/command/CompletionCommand.ts +19 -45
- package/src/command/MultiCommandCliHelpCommand.ts +45 -92
- package/src/command/SingleCommandCliHelpCommand.ts +17 -28
- package/src/command/UsageCommand.ts +6 -12
- package/src/command/VersionCommand.ts +2 -6
- package/src/launcher.ts +4 -2
- package/src/runtime/DefaultContext.ts +2 -5
- package/src/runtime/argument/ArgumentTypeGuards.ts +1 -3
- package/src/runtime/command/CommandTypeGuards.ts +5 -14
- package/src/runtime/command/CommandValidator.ts +56 -118
- package/src/runtime/parser.ts +13 -17
- package/src/runtime/registry/CommandRegistry.ts +2 -7
- package/src/runtime/registry/DefaultCommandRegistry.ts +32 -84
- package/src/runtime/registry/DefaultServiceProviderRegistry.ts +3 -9
- package/src/runtime/runner.ts +103 -142
- package/src/runtime/scanner.ts +28 -46
- package/src/runtime/values/ValuePopulationResult.ts +1 -2
- package/src/runtime/values/argumentValueMerge.ts +16 -28
- package/src/runtime/values/argumentValueValidation.ts +21 -67
- package/src/runtime/values/globalCommandValuePopulation.ts +9 -18
- package/src/runtime/values/subCommandValuePopulation.ts +42 -65
- package/src/service/argumentPrompter/ArgumentPrompterServiceProvider.ts +3 -10
- package/src/service/argumentPrompter/DefaultArgumentPrompterService.ts +22 -59
- package/src/service/asciiBannerGenerator/AsciiBannerGeneratorServiceProvider.ts +5 -14
- package/src/service/asciiBannerGenerator/DefaultAsciiBannerGeneratorService.ts +59 -77
- package/src/service/banner/BannerServiceProvider.ts +13 -35
- package/src/service/banner/command/NoBannerCommand.ts +2 -8
- package/src/service/chiselAsciiBannerGenerator/ChiselFontAsciiBannerGeneratorService.ts +5 -10
- package/src/service/completion/CompletionServiceProvider.ts +20 -48
- package/src/service/completion/DefaultCompletionService.ts +17 -56
- package/src/service/completion/shell/ShellHandler.ts +1 -3
- package/src/service/completion/shell/fish.ts +1 -1
- package/src/service/completion/shell/powershell.ts +2 -12
- package/src/service/completion/shell/zsh.ts +1 -1
- package/src/service/configuration/ConfigurationServiceProvider.ts +40 -133
- package/src/service/configuration/DefaultKeyValueService.ts +6 -20
- package/src/service/configuration/DefaultSecretService.ts +10 -14
- package/src/service/configuration/command/ConfigCommand.ts +1 -4
- package/src/service/configuration/command/DumpConfigCommand.ts +9 -21
- package/src/service/dataDumpGenerator/DataDumpGeneratorServiceProvider.ts +5 -14
- package/src/service/dataDumpGenerator/DefaultDataDumpGeneratorService.ts +5 -12
- package/src/service/imagePrinter/DefaultImagePrinterService.ts +1 -5
- package/src/service/imagePrinter/ImagePrinterServiceProvider.ts +1 -4
- package/src/service/prettyPrinter/DefaultPrettyPrinterService.ts +4 -12
- package/src/service/prettyPrinter/PrettyPrinterServiceProvider.ts +3 -10
- package/src/service/printer/DefaultPrinterService.ts +20 -83
- package/src/service/printer/PrinterServiceProvider.ts +3 -11
- package/src/service/printer/command/DarkModeCommand.ts +3 -10
- package/src/service/printer/command/LogLevelCommand.ts +7 -26
- package/src/service/printer/command/NoColorCommand.ts +3 -10
- package/src/service/printer/command/NoHyperlinksCommand.ts +3 -10
- package/src/service/printer/terminal/Progress.ts +99 -90
- package/src/service/printer/terminal/Spinner.ts +7 -26
- package/src/service/prompter/DefaultPrompterService.ts +2 -6
- package/src/service/prompter/PrompterServiceProvider.ts +3 -11
- package/src/service/prompter/command/NoPromptCommand.ts +3 -10
- package/src/service/prompter/prompt/PromptContext.ts +5 -18
- package/src/service/prompter/prompt/promptMultiSelect.ts +6 -21
- package/src/service/prompter/prompt/promptOpenUrl.ts +7 -22
- package/src/service/prompter/prompt/promptSingleSelect.ts +6 -23
- package/src/service/prompter/prompt/promptText.ts +10 -27
- package/src/service/prompter/prompt/promptToggle.ts +8 -8
- package/src/service/shutdown/ShutdownServiceProvider.ts +3 -10
- package/src/service/syntaxHighlighter/DefaultSyntaxHighlighterService.ts +13 -26
- package/src/service/syntaxHighlighter/SyntaxHighlighterServiceProvider.ts +8 -21
- package/src/service/tableGenerator/DefaultTableGeneratorService.ts +44 -68
- package/src/service/tableGenerator/TableGeneratorServiceProvider.ts +7 -16
- package/src/service/treePrinter/DefaultTreePrinterService.ts +2 -7
- package/src/service/treePrinter/TreePrinterServiceProvider.ts +4 -12
- package/src/terminal/ImageRenderer.ts +35 -54
- package/src/terminal/PngDecoder.ts +10 -19
- package/src/terminal/TtyStyler.ts +11 -9
- package/src/terminal/TtyTerminal.ts +2 -10
- package/src/terminal/supportsHyperlinks.ts +4 -10
- package/src/util/configHelper.ts +3 -10
- package/src/util/envVarHelper.ts +50 -88
- package/src/util/helpHelper.ts +123 -193
- package/src/util/logger.ts +12 -42
- package/src/util/runnerHelper.ts +20 -61
- package/tests/cli/BaseCLI.test.ts +23 -80
- package/tests/command/CompletionCommand.test.ts +1 -6
- package/tests/command/MultiCommandCliHelpCommand.test.ts +51 -205
- package/tests/command/SingleCommandCliHelpCommand.test.ts +21 -103
- package/tests/command/UsageCommand.test.ts +4 -10
- package/tests/fixtures/Command.ts +87 -68
- package/tests/fixtures/CommandRegistry.ts +1 -3
- package/tests/fixtures/Context.ts +3 -11
- package/tests/fixtures/ServiceProviderRegistry.ts +1 -1
- package/tests/fixtures/prettierPluginFoo.ts +1 -1
- package/tests/fixtures/util.ts +2 -8
- package/tests/runtime/argument/ArgumentTypeGuards.test.ts +1 -3
- package/tests/runtime/command/CommandValidator.test.ts +881 -604
- package/tests/runtime/parser.test.ts +222 -246
- package/tests/runtime/registry/DefaultCommandRegistry.test.ts +15 -37
- package/tests/runtime/registry/DefaultServiceProviderRegistry.test.ts +2 -8
- package/tests/runtime/runner.test.ts +231 -281
- package/tests/runtime/scanner.test.ts +277 -475
- package/tests/runtime/values/argumentValueMerge.test.ts +133 -81
- package/tests/runtime/values/argumentValueValidation.test.ts +444 -588
- package/tests/runtime/values/globalCommandValuePopulation.test.ts +71 -253
- package/tests/runtime/values/subCommandValuePopulation.test.ts +1342 -1570
- package/tests/service/argumentPrompter/ArgumentPrompterServiceProvider.test.ts +3 -12
- package/tests/service/argumentPrompter/DefaultArgumentPrompterService.test.ts +36 -45
- package/tests/service/asciiBannerGenerator/AsciiBannerGeneratorServiceProvider.test.ts +2 -8
- package/tests/service/asciiBannerGenerator/DefaultAsciiBannerGeneratorService.test.ts +40 -62
- package/tests/service/banner/BannerServiceProvider.test.ts +5 -18
- package/tests/service/banner/command/NoBannerCommand.test.ts +1 -4
- package/tests/service/completion/CompletionServiceProvider.test.ts +145 -214
- package/tests/service/completion/DefaultCompletionService.test.ts +17 -79
- package/tests/service/completion/shell/fish.test.ts +1 -3
- package/tests/service/configuration/ConfigurationServiceProvider.test.ts +26 -75
- package/tests/service/configuration/DefaultKeyValueService.test.ts +9 -21
- package/tests/service/configuration/DefaultSecretService.test.ts +7 -15
- package/tests/service/configuration/command/DumpConfigCommand.test.ts +4 -13
- package/tests/service/dataDumpGenerator/DataDumpGeneratorServiceProvider.test.ts +6 -12
- package/tests/service/dataDumpGenerator/DefaultDataDumpGeneratorService.test.ts +1 -10
- package/tests/service/imagePrinter/DefaultImagePrinterService.test.ts +5 -70
- package/tests/service/prettyPrinter/DefaultPrettyPrinterService.test.ts +4 -11
- package/tests/service/prettyPrinter/PrettyPrinterServiceProvider.test.ts +2 -6
- package/tests/service/printer/DefaultPrinterService.test.ts +57 -255
- package/tests/service/printer/PrinterServiceProvider.test.ts +2 -8
- package/tests/service/printer/command/DarkModeCommand.test.ts +4 -12
- package/tests/service/printer/command/LogLevelCommand.test.ts +4 -17
- package/tests/service/printer/command/NoColorCommand.test.ts +4 -12
- package/tests/service/printer/command/NoHyperlinksCommand.test.ts +7 -21
- package/tests/service/printer/terminal/Progress.test.ts +1 -3
- package/tests/service/printer/terminal/Spinner.test.ts +2 -8
- package/tests/service/prompter/DefaultPrompterService.test.ts +52 -69
- package/tests/service/prompter/PrompterServiceProvider.test.ts +2 -8
- package/tests/service/shutdown/ShutdownServiceProvider.test.ts +1 -3
- package/tests/service/syntaxHighlighter/DefaultSyntaxHighlighterService.test.ts +13 -99
- package/tests/service/syntaxHighlighter/SyntaxHighlighterServiceProvider.test.ts +2 -7
- package/tests/service/tableGenerator/DefaultTableGeneratorService.test.ts +12 -33
- package/tests/service/tableGenerator/TableGeneratorServiceProvider.test.ts +2 -2
- package/tests/service/treePrinter/DefaultTreePrinterService.test.ts +4 -6
- package/tests/service/treePrinter/TreePrinterServiceProvider.test.ts +4 -8
- package/tests/terminal/ImageRenderer.test.ts +2 -11
- package/tests/terminal/PngDecoder.test.ts +2 -6
- package/tests/util/configHelper.test.ts +55 -137
- package/tests/util/envVarHelper.test.ts +46 -110
|
@@ -10,10 +10,7 @@ import { PromptType } from "../../api/service/core/PrompterService.ts";
|
|
|
10
10
|
import type PrompterService from "../../api/service/core/PrompterService.ts";
|
|
11
11
|
import { KEY_VALUE_SERVICE_ID } from "../../api/service/core/KeyValueService.ts";
|
|
12
12
|
import type KeyValueService from "../../api/service/core/KeyValueService.ts";
|
|
13
|
-
import {
|
|
14
|
-
Icon,
|
|
15
|
-
PRINTER_SERVICE_ID,
|
|
16
|
-
} from "../../api/service/core/PrinterService.ts";
|
|
13
|
+
import { Icon, PRINTER_SERVICE_ID } from "../../api/service/core/PrinterService.ts";
|
|
17
14
|
import type PrinterService from "../../api/service/core/PrinterService.ts";
|
|
18
15
|
import getLogger from "../../util/logger.ts";
|
|
19
16
|
|
|
@@ -25,10 +22,7 @@ export default class CompletionServiceProvider implements ServiceProvider {
|
|
|
25
22
|
readonly #completionService: DefaultCompletionService;
|
|
26
23
|
#cliName = "";
|
|
27
24
|
|
|
28
|
-
public constructor(
|
|
29
|
-
servicePriority: number,
|
|
30
|
-
completionService: DefaultCompletionService,
|
|
31
|
-
) {
|
|
25
|
+
public constructor(servicePriority: number, completionService: DefaultCompletionService) {
|
|
32
26
|
this.servicePriority = servicePriority;
|
|
33
27
|
this.#completionService = completionService;
|
|
34
28
|
}
|
|
@@ -47,28 +41,20 @@ export default class CompletionServiceProvider implements ServiceProvider {
|
|
|
47
41
|
return;
|
|
48
42
|
}
|
|
49
43
|
if (!context.doesServiceExist(KEY_VALUE_SERVICE_ID)) {
|
|
50
|
-
logger.debug(
|
|
51
|
-
() => "KeyValueService not available, skipping auto-prompt",
|
|
52
|
-
);
|
|
44
|
+
logger.debug(() => "KeyValueService not available, skipping auto-prompt");
|
|
53
45
|
return;
|
|
54
46
|
}
|
|
55
47
|
|
|
56
|
-
const keyValueService = context.getServiceById(
|
|
57
|
-
KEY_VALUE_SERVICE_ID,
|
|
58
|
-
) as KeyValueService;
|
|
48
|
+
const keyValueService = context.getServiceById(KEY_VALUE_SERVICE_ID) as KeyValueService;
|
|
59
49
|
if (await keyValueService.hasKey("completion-status")) {
|
|
60
50
|
const status = await keyValueService.getKey("completion-status");
|
|
61
51
|
if (status === "installed" || status === "declined") {
|
|
62
|
-
logger.debug(
|
|
63
|
-
() => `Completion status is '${status}', skipping auto-prompt`,
|
|
64
|
-
);
|
|
52
|
+
logger.debug(() => `Completion status is '${status}', skipping auto-prompt`);
|
|
65
53
|
return;
|
|
66
54
|
}
|
|
67
55
|
}
|
|
68
56
|
|
|
69
|
-
const prompterService = context.getServiceById(
|
|
70
|
-
PROMPTER_SERVICE_ID,
|
|
71
|
-
) as PrompterService;
|
|
57
|
+
const prompterService = context.getServiceById(PROMPTER_SERVICE_ID) as PrompterService;
|
|
72
58
|
if (!prompterService.promptEnabled) {
|
|
73
59
|
logger.debug(() => "Prompting is disabled, skipping auto-prompt");
|
|
74
60
|
return;
|
|
@@ -76,9 +62,7 @@ export default class CompletionServiceProvider implements ServiceProvider {
|
|
|
76
62
|
|
|
77
63
|
const detectedShells = await this.#detectAvailableShells();
|
|
78
64
|
if (detectedShells.length === 0) {
|
|
79
|
-
logger.debug(
|
|
80
|
-
() => "No supported shells detected, skipping auto-prompt",
|
|
81
|
-
);
|
|
65
|
+
logger.debug(() => "No supported shells detected, skipping auto-prompt");
|
|
82
66
|
return;
|
|
83
67
|
}
|
|
84
68
|
|
|
@@ -134,14 +118,9 @@ export default class CompletionServiceProvider implements ServiceProvider {
|
|
|
134
118
|
await this.#installCompletion(context, shellType);
|
|
135
119
|
await keyValueService.setKey("completion-status", "installed");
|
|
136
120
|
} catch (error) {
|
|
137
|
-
logger.error(
|
|
138
|
-
"Failed to install completion: %s",
|
|
139
|
-
(error as Error).message,
|
|
140
|
-
);
|
|
121
|
+
logger.error("Failed to install completion: %s", (error as Error).message);
|
|
141
122
|
if (context.doesServiceExist(PRINTER_SERVICE_ID)) {
|
|
142
|
-
const printerService = context.getServiceById(
|
|
143
|
-
PRINTER_SERVICE_ID,
|
|
144
|
-
) as PrinterService;
|
|
123
|
+
const printerService = context.getServiceById(PRINTER_SERVICE_ID) as PrinterService;
|
|
145
124
|
await printerService.error(
|
|
146
125
|
`Failed to install completion: ${(error as Error).message}`,
|
|
147
126
|
Icon.FAILURE,
|
|
@@ -160,15 +139,9 @@ export default class CompletionServiceProvider implements ServiceProvider {
|
|
|
160
139
|
return available;
|
|
161
140
|
}
|
|
162
141
|
|
|
163
|
-
async #installCompletion(
|
|
164
|
-
context: Context,
|
|
165
|
-
shellType: ShellType,
|
|
166
|
-
): Promise<void> {
|
|
142
|
+
async #installCompletion(context: Context, shellType: ShellType): Promise<void> {
|
|
167
143
|
const configPath = this.#completionService.getDefaultConfigPath(shellType);
|
|
168
|
-
const bootstrapScript = this.#completionService.getBootstrapScript(
|
|
169
|
-
shellType,
|
|
170
|
-
this.#cliName,
|
|
171
|
-
);
|
|
144
|
+
const bootstrapScript = this.#completionService.getBootstrapScript(shellType, this.#cliName);
|
|
172
145
|
const beginMarker = `# BEGIN ${this.#cliName} completion`;
|
|
173
146
|
const endMarker = `# END ${this.#cliName} completion`;
|
|
174
147
|
const block = `${beginMarker}\n${bootstrapScript}\n${endMarker}`;
|
|
@@ -184,25 +157,24 @@ export default class CompletionServiceProvider implements ServiceProvider {
|
|
|
184
157
|
const beginIdx = existingContent.indexOf(beginMarker);
|
|
185
158
|
const endIdx = existingContent.indexOf(endMarker);
|
|
186
159
|
if (beginIdx !== -1 && endIdx !== -1) {
|
|
187
|
-
newContent =
|
|
160
|
+
newContent =
|
|
161
|
+
existingContent.substring(0, beginIdx) +
|
|
188
162
|
block +
|
|
189
163
|
existingContent.substring(endIdx + endMarker.length);
|
|
190
164
|
} else {
|
|
191
|
-
const separator =
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
165
|
+
const separator =
|
|
166
|
+
existingContent.length > 0 && !existingContent.endsWith("\n")
|
|
167
|
+
? "\n\n"
|
|
168
|
+
: existingContent.length > 0
|
|
169
|
+
? "\n"
|
|
170
|
+
: "";
|
|
197
171
|
newContent = existingContent + separator + block + "\n";
|
|
198
172
|
}
|
|
199
173
|
|
|
200
174
|
await Bun.write(configPath, newContent);
|
|
201
175
|
|
|
202
176
|
if (context.doesServiceExist(PRINTER_SERVICE_ID)) {
|
|
203
|
-
const printerService = context.getServiceById(
|
|
204
|
-
PRINTER_SERVICE_ID,
|
|
205
|
-
) as PrinterService;
|
|
177
|
+
const printerService = context.getServiceById(PRINTER_SERVICE_ID) as PrinterService;
|
|
206
178
|
await printerService.info(
|
|
207
179
|
`Shell completion installed for ${shellType}. Restart your shell or run 'source ${configPath}' to activate.`,
|
|
208
180
|
Icon.SUCCESS,
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import type CompletionService from "../../api/service/core/CompletionService.ts";
|
|
2
|
-
import {
|
|
3
|
-
type CompletionItem,
|
|
4
|
-
ShellType,
|
|
5
|
-
} from "../../api/service/core/CompletionService.ts";
|
|
2
|
+
import { type CompletionItem, ShellType } from "../../api/service/core/CompletionService.ts";
|
|
6
3
|
import type CommandRegistry from "../../runtime/registry/CommandRegistry.ts";
|
|
7
4
|
import type ShellHandler from "./shell/ShellHandler.ts";
|
|
8
5
|
import BashShellHandler from "./shell/bash.ts";
|
|
@@ -38,10 +35,7 @@ export default class DefaultCompletionService implements CompletionService {
|
|
|
38
35
|
return this.#getHandler(shellType).validateEnvironment();
|
|
39
36
|
}
|
|
40
37
|
|
|
41
|
-
formatCompletions(
|
|
42
|
-
shellType: ShellType,
|
|
43
|
-
completions: ReadonlyArray<CompletionItem>,
|
|
44
|
-
): string {
|
|
38
|
+
formatCompletions(shellType: ShellType, completions: ReadonlyArray<CompletionItem>): string {
|
|
45
39
|
return this.#getHandler(shellType).formatCompletions(completions);
|
|
46
40
|
}
|
|
47
41
|
|
|
@@ -70,28 +64,19 @@ export default class DefaultCompletionService implements CompletionService {
|
|
|
70
64
|
const previousWords = relevantWords.slice(0, -1);
|
|
71
65
|
const endsWithSpace = beforeCursor.endsWith(" ");
|
|
72
66
|
|
|
73
|
-
if (
|
|
74
|
-
relevantWords.length === 0 ||
|
|
75
|
-
(relevantWords.length === 1 && !endsWithSpace)
|
|
76
|
-
) {
|
|
67
|
+
if (relevantWords.length === 0 || (relevantWords.length === 1 && !endsWithSpace)) {
|
|
77
68
|
return Promise.resolve(this.#completeCommandName(currentWord));
|
|
78
69
|
}
|
|
79
70
|
|
|
80
71
|
if (endsWithSpace) {
|
|
81
72
|
const commandWord = relevantWords[0]!;
|
|
82
|
-
return Promise.resolve(
|
|
83
|
-
this.#completeAfterCommand(commandWord, relevantWords.slice(1), ""),
|
|
84
|
-
);
|
|
73
|
+
return Promise.resolve(this.#completeAfterCommand(commandWord, relevantWords.slice(1), ""));
|
|
85
74
|
}
|
|
86
75
|
|
|
87
76
|
const commandWord = previousWords[0];
|
|
88
77
|
if (commandWord) {
|
|
89
78
|
return Promise.resolve(
|
|
90
|
-
this.#completeAfterCommand(
|
|
91
|
-
commandWord,
|
|
92
|
-
previousWords.slice(1),
|
|
93
|
-
currentWord,
|
|
94
|
-
),
|
|
79
|
+
this.#completeAfterCommand(commandWord, previousWords.slice(1), currentWord),
|
|
95
80
|
);
|
|
96
81
|
}
|
|
97
82
|
|
|
@@ -105,14 +90,10 @@ export default class DefaultCompletionService implements CompletionService {
|
|
|
105
90
|
): ReadonlyArray<CompletionItem> {
|
|
106
91
|
// Check for group:member pattern
|
|
107
92
|
if (commandWord.includes(":")) {
|
|
108
|
-
const result =
|
|
109
|
-
|
|
93
|
+
const result =
|
|
94
|
+
this.#commandRegistry!.getGroupCommandAndMemberSubCommandByJoinedName(commandWord);
|
|
110
95
|
if (result) {
|
|
111
|
-
return this.#completeSubCommandArgs(
|
|
112
|
-
result.command,
|
|
113
|
-
intermediateWords,
|
|
114
|
-
currentWord,
|
|
115
|
-
);
|
|
96
|
+
return this.#completeSubCommandArgs(result.command, intermediateWords, currentWord);
|
|
116
97
|
}
|
|
117
98
|
}
|
|
118
99
|
|
|
@@ -120,9 +101,7 @@ export default class DefaultCompletionService implements CompletionService {
|
|
|
120
101
|
if (currentWord.includes(":")) {
|
|
121
102
|
const colonIdx = currentWord.indexOf(":");
|
|
122
103
|
const groupPart = currentWord.substring(0, colonIdx);
|
|
123
|
-
const groupCommand = this.#commandRegistry!.getGroupCommandByName(
|
|
124
|
-
groupPart,
|
|
125
|
-
);
|
|
104
|
+
const groupCommand = this.#commandRegistry!.getGroupCommandByName(groupPart);
|
|
126
105
|
if (groupCommand) {
|
|
127
106
|
return groupCommand.memberSubCommands
|
|
128
107
|
.filter((sc) => `${groupPart}:${sc.name}`.startsWith(currentWord))
|
|
@@ -136,17 +115,11 @@ export default class DefaultCompletionService implements CompletionService {
|
|
|
136
115
|
// Check sub-command
|
|
137
116
|
const subCommand = this.#commandRegistry!.getSubCommandByName(commandWord);
|
|
138
117
|
if (subCommand) {
|
|
139
|
-
return this.#completeSubCommandArgs(
|
|
140
|
-
subCommand,
|
|
141
|
-
intermediateWords,
|
|
142
|
-
currentWord,
|
|
143
|
-
);
|
|
118
|
+
return this.#completeSubCommandArgs(subCommand, intermediateWords, currentWord);
|
|
144
119
|
}
|
|
145
120
|
|
|
146
121
|
// Check group command (suggest members)
|
|
147
|
-
const groupCommand = this.#commandRegistry!.getGroupCommandByName(
|
|
148
|
-
commandWord,
|
|
149
|
-
);
|
|
122
|
+
const groupCommand = this.#commandRegistry!.getGroupCommandByName(commandWord);
|
|
150
123
|
if (groupCommand) {
|
|
151
124
|
return groupCommand.memberSubCommands
|
|
152
125
|
.filter((sc) => sc.name.startsWith(currentWord))
|
|
@@ -171,8 +144,7 @@ export default class DefaultCompletionService implements CompletionService {
|
|
|
171
144
|
}
|
|
172
145
|
|
|
173
146
|
// Group:member joined names
|
|
174
|
-
const groupAndMembers = this.#commandRegistry
|
|
175
|
-
.getGroupAndMemberCommandsByJoinedName();
|
|
147
|
+
const groupAndMembers = this.#commandRegistry!.getGroupAndMemberCommandsByJoinedName();
|
|
176
148
|
for (const [joinedName, entry] of groupAndMembers) {
|
|
177
149
|
if (joinedName.startsWith(prefix)) {
|
|
178
150
|
completions.push({
|
|
@@ -203,8 +175,7 @@ export default class DefaultCompletionService implements CompletionService {
|
|
|
203
175
|
}
|
|
204
176
|
|
|
205
177
|
// Global modifier commands (with -- prefix)
|
|
206
|
-
const modifierCommands = this.#commandRegistry
|
|
207
|
-
.getGlobalModifierCommands();
|
|
178
|
+
const modifierCommands = this.#commandRegistry!.getGlobalModifierCommands();
|
|
208
179
|
for (const cmd of modifierCommands) {
|
|
209
180
|
const prefixed = `--${cmd.name}`;
|
|
210
181
|
if (prefixed.startsWith(prefix)) {
|
|
@@ -270,9 +241,7 @@ export default class DefaultCompletionService implements CompletionService {
|
|
|
270
241
|
for (const opt of subCommand.options) {
|
|
271
242
|
if ("name" in opt) {
|
|
272
243
|
const optName = `--${(opt as Option).name}`;
|
|
273
|
-
if (
|
|
274
|
-
!previousArgs.includes(optName) && optName.startsWith(currentWord)
|
|
275
|
-
) {
|
|
244
|
+
if (!previousArgs.includes(optName) && optName.startsWith(currentWord)) {
|
|
276
245
|
completions.push({
|
|
277
246
|
value: optName,
|
|
278
247
|
description: (opt as Option).description,
|
|
@@ -282,10 +251,7 @@ export default class DefaultCompletionService implements CompletionService {
|
|
|
282
251
|
}
|
|
283
252
|
|
|
284
253
|
// Suggest positional allowable values
|
|
285
|
-
const positionalIndex = this.#countPositionalArgs(
|
|
286
|
-
previousArgs,
|
|
287
|
-
subCommand,
|
|
288
|
-
);
|
|
254
|
+
const positionalIndex = this.#countPositionalArgs(previousArgs, subCommand);
|
|
289
255
|
if (positionalIndex < subCommand.positionals.length) {
|
|
290
256
|
const positional = subCommand.positionals[positionalIndex]!;
|
|
291
257
|
if (positional.allowableValues) {
|
|
@@ -300,10 +266,7 @@ export default class DefaultCompletionService implements CompletionService {
|
|
|
300
266
|
return completions;
|
|
301
267
|
}
|
|
302
268
|
|
|
303
|
-
#countPositionalArgs(
|
|
304
|
-
args: ReadonlyArray<string>,
|
|
305
|
-
subCommand: SubCommand,
|
|
306
|
-
): number {
|
|
269
|
+
#countPositionalArgs(args: ReadonlyArray<string>, subCommand: SubCommand): number {
|
|
307
270
|
let count = 0;
|
|
308
271
|
let i = 0;
|
|
309
272
|
while (i < args.length) {
|
|
@@ -312,9 +275,7 @@ export default class DefaultCompletionService implements CompletionService {
|
|
|
312
275
|
// Skip option and its value
|
|
313
276
|
const optName = arg.startsWith("--") ? arg.substring(2) : undefined;
|
|
314
277
|
const option = optName
|
|
315
|
-
? subCommand.options.find(
|
|
316
|
-
(o) => "name" in o && (o as Option).name === optName,
|
|
317
|
-
)
|
|
278
|
+
? subCommand.options.find((o) => "name" in o && (o as Option).name === optName)
|
|
318
279
|
: undefined;
|
|
319
280
|
if (option && option.type !== undefined) {
|
|
320
281
|
i++; // skip the option value
|
|
@@ -10,7 +10,5 @@ export default interface ShellHandler {
|
|
|
10
10
|
getBootstrapScript(cliName: string): string;
|
|
11
11
|
validateEnvironment(): Promise<boolean>;
|
|
12
12
|
formatCompletions(completions: ReadonlyArray<CompletionItem>): string;
|
|
13
|
-
parseCompletionContext(
|
|
14
|
-
args: ReadonlyArray<string>,
|
|
15
|
-
): CompletionContext;
|
|
13
|
+
parseCompletionContext(args: ReadonlyArray<string>): CompletionContext;
|
|
16
14
|
}
|
|
@@ -31,7 +31,7 @@ export default class FishShellHandler implements ShellHandler {
|
|
|
31
31
|
|
|
32
32
|
formatCompletions(completions: ReadonlyArray<CompletionItem>): string {
|
|
33
33
|
return completions
|
|
34
|
-
.map((c) => c.description ? `${c.value}\t${c.description}` : c.value)
|
|
34
|
+
.map((c) => (c.description ? `${c.value}\t${c.description}` : c.value))
|
|
35
35
|
.join("\n");
|
|
36
36
|
}
|
|
37
37
|
|
|
@@ -10,19 +10,9 @@ import type { CompletionContext } from "./ShellHandler.ts";
|
|
|
10
10
|
export default class PowerShellShellHandler implements ShellHandler {
|
|
11
11
|
getDefaultConfigPath(): string {
|
|
12
12
|
if (process.platform === "win32") {
|
|
13
|
-
return join(
|
|
14
|
-
homedir(),
|
|
15
|
-
"Documents",
|
|
16
|
-
"PowerShell",
|
|
17
|
-
"Microsoft.PowerShell_profile.ps1",
|
|
18
|
-
);
|
|
13
|
+
return join(homedir(), "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1");
|
|
19
14
|
}
|
|
20
|
-
return join(
|
|
21
|
-
homedir(),
|
|
22
|
-
".config",
|
|
23
|
-
"powershell",
|
|
24
|
-
"Microsoft.PowerShell_profile.ps1",
|
|
25
|
-
);
|
|
15
|
+
return join(homedir(), ".config", "powershell", "Microsoft.PowerShell_profile.ps1");
|
|
26
16
|
}
|
|
27
17
|
|
|
28
18
|
getBootstrapScript(cliName: string): string {
|
|
@@ -38,7 +38,7 @@ export default class ZshShellHandler implements ShellHandler {
|
|
|
38
38
|
|
|
39
39
|
formatCompletions(completions: ReadonlyArray<CompletionItem>): string {
|
|
40
40
|
return completions
|
|
41
|
-
.map((c) => c.description ? `${c.value}:${c.description}` : c.value)
|
|
41
|
+
.map((c) => (c.description ? `${c.value}:${c.description}` : c.value))
|
|
42
42
|
.join("\n");
|
|
43
43
|
}
|
|
44
44
|
|