@optique/core 0.7.0-dev.149 → 0.7.0-dev.152

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.
@@ -242,6 +242,7 @@ function longestMatch(...args) {
242
242
  },
243
243
  getDocFragments(state, _defaultValue) {
244
244
  let description;
245
+ let footer;
245
246
  let fragments;
246
247
  if (state.kind === "unavailable" || state.state == null) fragments = parsers.flatMap((p) => p.getDocFragments({ kind: "unavailable" }).fragments);
247
248
  else {
@@ -252,12 +253,14 @@ function longestMatch(...args) {
252
253
  state: result.next.state
253
254
  });
254
255
  description = docResult.description;
256
+ footer = docResult.footer;
255
257
  fragments = docResult.fragments;
256
258
  } else fragments = parsers.flatMap((p) => p.getDocFragments({ kind: "unavailable" }).fragments);
257
259
  }
258
260
  return {
259
261
  description,
260
- fragments
262
+ fragments,
263
+ footer
261
264
  };
262
265
  }
263
266
  };
@@ -242,6 +242,7 @@ function longestMatch(...args) {
242
242
  },
243
243
  getDocFragments(state, _defaultValue) {
244
244
  let description;
245
+ let footer;
245
246
  let fragments;
246
247
  if (state.kind === "unavailable" || state.state == null) fragments = parsers.flatMap((p) => p.getDocFragments({ kind: "unavailable" }).fragments);
247
248
  else {
@@ -252,12 +253,14 @@ function longestMatch(...args) {
252
253
  state: result.next.state
253
254
  });
254
255
  description = docResult.description;
256
+ footer = docResult.footer;
255
257
  fragments = docResult.fragments;
256
258
  } else fragments = parsers.flatMap((p) => p.getDocFragments({ kind: "unavailable" }).fragments);
257
259
  }
258
260
  return {
259
261
  description,
260
- fragments
262
+ fragments,
263
+ footer
261
264
  };
262
265
  }
263
266
  };
package/dist/facade.cjs CHANGED
@@ -54,27 +54,41 @@ function createVersionParser(mode) {
54
54
  /**
55
55
  * Creates completion parsers based on the specified mode.
56
56
  */
57
- function createCompletionParser(mode, programName, availableShells) {
57
+ function createCompletionParser(mode, programName, availableShells, name = "both") {
58
58
  const shellList = [];
59
59
  for (const shell in availableShells) {
60
60
  if (shellList.length > 0) shellList.push(require_message.text(", "));
61
61
  shellList.push(require_message.value(shell));
62
62
  }
63
- const completionCommand = require_primitives.command("completion", require_constructs.object({
63
+ const completionInner = require_constructs.object({
64
64
  shell: require_modifiers.optional(require_primitives.argument(require_valueparser.string({ metavar: "SHELL" }), { description: require_message.message`Shell type (${shellList}). Generate completion script when used alone, or provide completions when followed by arguments.` })),
65
65
  args: require_modifiers.multiple(require_primitives.argument(require_valueparser.string({ metavar: "ARG" }), { description: require_message.message`Command line arguments for completion suggestions (used by shell integration; you usually don't need to provide this).` }))
66
- }), {
66
+ });
67
+ const commandName = name === "plural" ? "completions" : "completion";
68
+ const completionCommandConfig = {
67
69
  brief: require_message.message`Generate shell completion script or provide completions.`,
68
70
  description: require_message.message`Generate shell completion script or provide completions.`,
69
71
  footer: require_message.message`Examples:
70
- Bash: ${require_message.commandLine(`eval "$(${programName} completion bash)"`)}
71
- zsh: ${require_message.commandLine(`eval "$(${programName} completion zsh)"`)}
72
- fish: ${require_message.commandLine(`eval "$(${programName} completion fish)"`)}
73
- PowerShell: ${require_message.commandLine(`${programName} completion pwsh > ${programName}-completion.ps1; . ./${programName}-completion.ps1`)}
74
- Nushell: ${require_message.commandLine(`${programName} completion nu | save ${programName}-completion.nu; source ./${programName}-completion.nu`)}
72
+ Bash: ${require_message.commandLine(`eval "$(${programName} ${commandName} bash)"`)}
73
+ zsh: ${require_message.commandLine(`eval "$(${programName} ${commandName} zsh)"`)}
74
+ fish: ${require_message.commandLine(`eval "$(${programName} ${commandName} fish)"`)}
75
+ PowerShell: ${require_message.commandLine(`${programName} ${commandName} pwsh > ${programName}-completion.ps1; . ./${programName}-completion.ps1`)}
76
+ Nushell: ${require_message.commandLine(`${programName} ${commandName} nu | save ${programName}-completion.nu; source ./${programName}-completion.nu`)}
75
77
  `
76
- });
77
- const completionOption = require_primitives.option("--completion", require_valueparser.string({ metavar: "SHELL" }), { description: require_message.message`Generate shell completion script.` });
78
+ };
79
+ const completionCommands = [];
80
+ if (name === "singular" || name === "both") completionCommands.push(require_primitives.command("completion", completionInner, completionCommandConfig));
81
+ if (name === "plural" || name === "both") completionCommands.push(require_primitives.command("completions", completionInner, completionCommandConfig));
82
+ const completionCommand = require_constructs.longestMatch(...completionCommands);
83
+ const completionOptionNames = [];
84
+ if (name === "singular" || name === "both") completionOptionNames.push("--completion");
85
+ if (name === "plural" || name === "both") completionOptionNames.push("--completions");
86
+ const completionOptionArgs = [
87
+ ...completionOptionNames,
88
+ require_valueparser.string({ metavar: "SHELL" }),
89
+ { description: require_message.message`Generate shell completion script.` }
90
+ ];
91
+ const completionOption = require_primitives.option(...completionOptionArgs);
78
92
  switch (mode) {
79
93
  case "command": return {
80
94
  completionCommand,
@@ -412,6 +426,7 @@ function run(parser, programName, args, options = {}) {
412
426
  const versionValue = options.version?.value ?? "";
413
427
  const onVersion = options.version?.onShow ?? (() => ({}));
414
428
  const completionMode = options.completion?.mode ?? "both";
429
+ const completionName = options.completion?.name ?? "both";
415
430
  const onCompletion = options.completion?.onShow ?? (() => ({}));
416
431
  const defaultShells = {
417
432
  bash: require_completion.bash,
@@ -438,20 +453,26 @@ function run(parser, programName, args, options = {}) {
438
453
  const completionParsers = completion === "none" ? {
439
454
  completionCommand: null,
440
455
  completionOption: null
441
- } : createCompletionParser(completion, programName, availableShells);
456
+ } : createCompletionParser(completion, programName, availableShells, completionName);
442
457
  if (options.completion) {
443
458
  const hasHelpOption = args.includes("--help");
444
- if ((completionMode === "command" || completionMode === "both") && args.length >= 1 && args[0] === "completion" && !hasHelpOption) return handleCompletion(args.slice(1), programName, parser, completionParsers.completionCommand, stdout, stderr, onCompletion, onError, availableShells, colors, maxWidth);
459
+ if ((completionMode === "command" || completionMode === "both") && args.length >= 1 && ((completionName === "singular" || completionName === "both" ? args[0] === "completion" : false) || (completionName === "plural" || completionName === "both" ? args[0] === "completions" : false)) && !hasHelpOption) return handleCompletion(args.slice(1), programName, parser, completionParsers.completionCommand, stdout, stderr, onCompletion, onError, availableShells, colors, maxWidth);
445
460
  if (completionMode === "option" || completionMode === "both") for (let i = 0; i < args.length; i++) {
446
461
  const arg = args[i];
447
- if (arg.startsWith("--completion=")) {
448
- const shell = arg.slice(13);
462
+ const singularMatch = completionName === "singular" || completionName === "both" ? arg.startsWith("--completion=") : false;
463
+ const pluralMatch = completionName === "plural" || completionName === "both" ? arg.startsWith("--completions=") : false;
464
+ if (singularMatch || pluralMatch) {
465
+ const shell = arg.slice(arg.indexOf("=") + 1);
449
466
  const completionArgs = args.slice(i + 1);
450
467
  return handleCompletion([shell, ...completionArgs], programName, parser, completionParsers.completionCommand, stdout, stderr, onCompletion, onError, availableShells, colors, maxWidth);
451
- } else if (arg === "--completion" && i + 1 < args.length) {
452
- const shell = args[i + 1];
453
- const completionArgs = args.slice(i + 2);
454
- return handleCompletion([shell, ...completionArgs], programName, parser, completionParsers.completionCommand, stdout, stderr, onCompletion, onError, availableShells, colors, maxWidth);
468
+ } else {
469
+ const singularMatchExact = completionName === "singular" || completionName === "both" ? arg === "--completion" : false;
470
+ const pluralMatchExact = completionName === "plural" || completionName === "both" ? arg === "--completions" : false;
471
+ if ((singularMatchExact || pluralMatchExact) && i + 1 < args.length) {
472
+ const shell = args[i + 1];
473
+ const completionArgs = args.slice(i + 2);
474
+ return handleCompletion([shell, ...completionArgs], programName, parser, completionParsers.completionCommand, stdout, stderr, onCompletion, onError, availableShells, colors, maxWidth);
475
+ }
455
476
  }
456
477
  }
457
478
  }
@@ -474,7 +495,7 @@ function run(parser, programName, args, options = {}) {
474
495
  const versionAsCommand = version === "command" || version === "both";
475
496
  const completionAsCommand = completion === "command" || completion === "both";
476
497
  const requestedCommand = classified.commands[0];
477
- if (requestedCommand === "completion" && completionAsCommand && completionParsers.completionCommand) helpGeneratorParser = completionParsers.completionCommand;
498
+ if ((requestedCommand === "completion" || requestedCommand === "completions") && completionAsCommand && completionParsers.completionCommand) helpGeneratorParser = completionParsers.completionCommand;
478
499
  else if (requestedCommand === "help" && helpAsCommand && helpParsers.helpCommand) helpGeneratorParser = helpParsers.helpCommand;
479
500
  else if (requestedCommand === "version" && versionAsCommand && versionParsers.versionCommand) helpGeneratorParser = versionParsers.versionCommand;
480
501
  else {
@@ -494,7 +515,7 @@ function run(parser, programName, args, options = {}) {
494
515
  }
495
516
  const doc = require_parser.getDocPage(helpGeneratorParser, classified.commands);
496
517
  if (doc != null) {
497
- const isMetaCommandHelp = requestedCommand === "completion" || requestedCommand === "help" || requestedCommand === "version";
518
+ const isMetaCommandHelp = (completionName === "singular" || completionName === "both" ? requestedCommand === "completion" : false) || (completionName === "plural" || completionName === "both" ? requestedCommand === "completions" : false) || requestedCommand === "help" || requestedCommand === "version";
498
519
  const augmentedDoc = {
499
520
  ...doc,
500
521
  brief: !isMetaCommandHelp ? brief ?? doc.brief : doc.brief,
package/dist/facade.d.cts CHANGED
@@ -104,6 +104,16 @@ interface RunOptions<THelp, TError> {
104
104
  * @default `"both"`
105
105
  */
106
106
  readonly mode?: "command" | "option" | "both";
107
+ /**
108
+ * Determines whether to use singular or plural naming for completion command/option.
109
+ *
110
+ * - `"singular"`: Use `completion` / `--completion`
111
+ * - `"plural"`: Use `completions` / `--completions`
112
+ * - `"both"`: Use both singular and plural forms
113
+ *
114
+ * @default `"both"`
115
+ */
116
+ readonly name?: "singular" | "plural" | "both";
107
117
  /**
108
118
  * Available shell completions. By default, includes `bash`, `fish`, `nu`,
109
119
  * `pwsh`, and `zsh`. You can provide additional custom shell completions or
package/dist/facade.d.ts CHANGED
@@ -104,6 +104,16 @@ interface RunOptions<THelp, TError> {
104
104
  * @default `"both"`
105
105
  */
106
106
  readonly mode?: "command" | "option" | "both";
107
+ /**
108
+ * Determines whether to use singular or plural naming for completion command/option.
109
+ *
110
+ * - `"singular"`: Use `completion` / `--completion`
111
+ * - `"plural"`: Use `completions` / `--completions`
112
+ * - `"both"`: Use both singular and plural forms
113
+ *
114
+ * @default `"both"`
115
+ */
116
+ readonly name?: "singular" | "plural" | "both";
107
117
  /**
108
118
  * Available shell completions. By default, includes `bash`, `fish`, `nu`,
109
119
  * `pwsh`, and `zsh`. You can provide additional custom shell completions or
package/dist/facade.js CHANGED
@@ -54,27 +54,41 @@ function createVersionParser(mode) {
54
54
  /**
55
55
  * Creates completion parsers based on the specified mode.
56
56
  */
57
- function createCompletionParser(mode, programName, availableShells) {
57
+ function createCompletionParser(mode, programName, availableShells, name = "both") {
58
58
  const shellList = [];
59
59
  for (const shell in availableShells) {
60
60
  if (shellList.length > 0) shellList.push(text(", "));
61
61
  shellList.push(value(shell));
62
62
  }
63
- const completionCommand = command("completion", object({
63
+ const completionInner = object({
64
64
  shell: optional(argument(string({ metavar: "SHELL" }), { description: message`Shell type (${shellList}). Generate completion script when used alone, or provide completions when followed by arguments.` })),
65
65
  args: multiple(argument(string({ metavar: "ARG" }), { description: message`Command line arguments for completion suggestions (used by shell integration; you usually don't need to provide this).` }))
66
- }), {
66
+ });
67
+ const commandName = name === "plural" ? "completions" : "completion";
68
+ const completionCommandConfig = {
67
69
  brief: message`Generate shell completion script or provide completions.`,
68
70
  description: message`Generate shell completion script or provide completions.`,
69
71
  footer: message`Examples:
70
- Bash: ${commandLine(`eval "$(${programName} completion bash)"`)}
71
- zsh: ${commandLine(`eval "$(${programName} completion zsh)"`)}
72
- fish: ${commandLine(`eval "$(${programName} completion fish)"`)}
73
- PowerShell: ${commandLine(`${programName} completion pwsh > ${programName}-completion.ps1; . ./${programName}-completion.ps1`)}
74
- Nushell: ${commandLine(`${programName} completion nu | save ${programName}-completion.nu; source ./${programName}-completion.nu`)}
72
+ Bash: ${commandLine(`eval "$(${programName} ${commandName} bash)"`)}
73
+ zsh: ${commandLine(`eval "$(${programName} ${commandName} zsh)"`)}
74
+ fish: ${commandLine(`eval "$(${programName} ${commandName} fish)"`)}
75
+ PowerShell: ${commandLine(`${programName} ${commandName} pwsh > ${programName}-completion.ps1; . ./${programName}-completion.ps1`)}
76
+ Nushell: ${commandLine(`${programName} ${commandName} nu | save ${programName}-completion.nu; source ./${programName}-completion.nu`)}
75
77
  `
76
- });
77
- const completionOption = option("--completion", string({ metavar: "SHELL" }), { description: message`Generate shell completion script.` });
78
+ };
79
+ const completionCommands = [];
80
+ if (name === "singular" || name === "both") completionCommands.push(command("completion", completionInner, completionCommandConfig));
81
+ if (name === "plural" || name === "both") completionCommands.push(command("completions", completionInner, completionCommandConfig));
82
+ const completionCommand = longestMatch(...completionCommands);
83
+ const completionOptionNames = [];
84
+ if (name === "singular" || name === "both") completionOptionNames.push("--completion");
85
+ if (name === "plural" || name === "both") completionOptionNames.push("--completions");
86
+ const completionOptionArgs = [
87
+ ...completionOptionNames,
88
+ string({ metavar: "SHELL" }),
89
+ { description: message`Generate shell completion script.` }
90
+ ];
91
+ const completionOption = option(...completionOptionArgs);
78
92
  switch (mode) {
79
93
  case "command": return {
80
94
  completionCommand,
@@ -412,6 +426,7 @@ function run(parser, programName, args, options = {}) {
412
426
  const versionValue = options.version?.value ?? "";
413
427
  const onVersion = options.version?.onShow ?? (() => ({}));
414
428
  const completionMode = options.completion?.mode ?? "both";
429
+ const completionName = options.completion?.name ?? "both";
415
430
  const onCompletion = options.completion?.onShow ?? (() => ({}));
416
431
  const defaultShells = {
417
432
  bash,
@@ -438,20 +453,26 @@ function run(parser, programName, args, options = {}) {
438
453
  const completionParsers = completion === "none" ? {
439
454
  completionCommand: null,
440
455
  completionOption: null
441
- } : createCompletionParser(completion, programName, availableShells);
456
+ } : createCompletionParser(completion, programName, availableShells, completionName);
442
457
  if (options.completion) {
443
458
  const hasHelpOption = args.includes("--help");
444
- if ((completionMode === "command" || completionMode === "both") && args.length >= 1 && args[0] === "completion" && !hasHelpOption) return handleCompletion(args.slice(1), programName, parser, completionParsers.completionCommand, stdout, stderr, onCompletion, onError, availableShells, colors, maxWidth);
459
+ if ((completionMode === "command" || completionMode === "both") && args.length >= 1 && ((completionName === "singular" || completionName === "both" ? args[0] === "completion" : false) || (completionName === "plural" || completionName === "both" ? args[0] === "completions" : false)) && !hasHelpOption) return handleCompletion(args.slice(1), programName, parser, completionParsers.completionCommand, stdout, stderr, onCompletion, onError, availableShells, colors, maxWidth);
445
460
  if (completionMode === "option" || completionMode === "both") for (let i = 0; i < args.length; i++) {
446
461
  const arg = args[i];
447
- if (arg.startsWith("--completion=")) {
448
- const shell = arg.slice(13);
462
+ const singularMatch = completionName === "singular" || completionName === "both" ? arg.startsWith("--completion=") : false;
463
+ const pluralMatch = completionName === "plural" || completionName === "both" ? arg.startsWith("--completions=") : false;
464
+ if (singularMatch || pluralMatch) {
465
+ const shell = arg.slice(arg.indexOf("=") + 1);
449
466
  const completionArgs = args.slice(i + 1);
450
467
  return handleCompletion([shell, ...completionArgs], programName, parser, completionParsers.completionCommand, stdout, stderr, onCompletion, onError, availableShells, colors, maxWidth);
451
- } else if (arg === "--completion" && i + 1 < args.length) {
452
- const shell = args[i + 1];
453
- const completionArgs = args.slice(i + 2);
454
- return handleCompletion([shell, ...completionArgs], programName, parser, completionParsers.completionCommand, stdout, stderr, onCompletion, onError, availableShells, colors, maxWidth);
468
+ } else {
469
+ const singularMatchExact = completionName === "singular" || completionName === "both" ? arg === "--completion" : false;
470
+ const pluralMatchExact = completionName === "plural" || completionName === "both" ? arg === "--completions" : false;
471
+ if ((singularMatchExact || pluralMatchExact) && i + 1 < args.length) {
472
+ const shell = args[i + 1];
473
+ const completionArgs = args.slice(i + 2);
474
+ return handleCompletion([shell, ...completionArgs], programName, parser, completionParsers.completionCommand, stdout, stderr, onCompletion, onError, availableShells, colors, maxWidth);
475
+ }
455
476
  }
456
477
  }
457
478
  }
@@ -474,7 +495,7 @@ function run(parser, programName, args, options = {}) {
474
495
  const versionAsCommand = version === "command" || version === "both";
475
496
  const completionAsCommand = completion === "command" || completion === "both";
476
497
  const requestedCommand = classified.commands[0];
477
- if (requestedCommand === "completion" && completionAsCommand && completionParsers.completionCommand) helpGeneratorParser = completionParsers.completionCommand;
498
+ if ((requestedCommand === "completion" || requestedCommand === "completions") && completionAsCommand && completionParsers.completionCommand) helpGeneratorParser = completionParsers.completionCommand;
478
499
  else if (requestedCommand === "help" && helpAsCommand && helpParsers.helpCommand) helpGeneratorParser = helpParsers.helpCommand;
479
500
  else if (requestedCommand === "version" && versionAsCommand && versionParsers.versionCommand) helpGeneratorParser = versionParsers.versionCommand;
480
501
  else {
@@ -494,7 +515,7 @@ function run(parser, programName, args, options = {}) {
494
515
  }
495
516
  const doc = getDocPage(helpGeneratorParser, classified.commands);
496
517
  if (doc != null) {
497
- const isMetaCommandHelp = requestedCommand === "completion" || requestedCommand === "help" || requestedCommand === "version";
518
+ const isMetaCommandHelp = (completionName === "singular" || completionName === "both" ? requestedCommand === "completion" : false) || (completionName === "plural" || completionName === "both" ? requestedCommand === "completions" : false) || requestedCommand === "help" || requestedCommand === "version";
498
519
  const augmentedDoc = {
499
520
  ...doc,
500
521
  brief: !isMetaCommandHelp ? brief ?? doc.brief : doc.brief,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/core",
3
- "version": "0.7.0-dev.149+59dd16c2",
3
+ "version": "0.7.0-dev.152+14108c27",
4
4
  "description": "Type-safe combinatorial command-line interface parser",
5
5
  "keywords": [
6
6
  "CLI",