@optique/core 1.4.0-dev.2606 → 1.4.0-dev.2607
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/dist/constructs.cjs +129 -78
- package/dist/constructs.js +129 -78
- package/dist/facade.cjs +3 -69
- package/dist/facade.js +1 -67
- package/dist/modifiers.cjs +6 -5
- package/dist/modifiers.js +6 -5
- package/dist/primitives.cjs +57 -13
- package/dist/primitives.d.cts +3 -3
- package/dist/primitives.d.ts +3 -3
- package/dist/primitives.js +57 -13
- package/dist/short-option.cjs +197 -0
- package/dist/short-option.js +186 -0
- package/dist/usage-internals.cjs +73 -0
- package/dist/usage-internals.js +71 -1
- package/package.json +2 -2
- package/skills/optique/SKILL.md +7 -7
package/dist/facade.js
CHANGED
|
@@ -12,6 +12,7 @@ import { collectExplicitSourceValues, collectExplicitSourceValuesAsync, createDe
|
|
|
12
12
|
import { createInputTrace } from "./input-trace.js";
|
|
13
13
|
import { attemptParseAsync, attemptParseSync, createEffectfulCompletionSession, createParserContext, getDocPage } from "./internal/parser.js";
|
|
14
14
|
import { bash, fish, nu, pwsh, zsh } from "./completion.js";
|
|
15
|
+
import { collectActiveOptionNames, collectRootOptionNames } from "./usage-internals.js";
|
|
15
16
|
import { allowDuplicateLeadingCommandNamesKey, hiddenCommandAliasesKey } from "./internal/command-alias.js";
|
|
16
17
|
import { completeOrExtractPhase2Seed } from "./phase2-seed.js";
|
|
17
18
|
import { multiple, optional, withDefault } from "./modifiers.js";
|
|
@@ -756,76 +757,9 @@ function collectActiveValueOptionNames(usage, commandPath, includeDirectAfterCom
|
|
|
756
757
|
for (const name of optionNames.flag) names.delete(name);
|
|
757
758
|
return names;
|
|
758
759
|
}
|
|
759
|
-
function collectRootOptionNames(usage, names, rootLeadingNames) {
|
|
760
|
-
for (const term of usage) collectRootOptionNamesFromTerm(term, names, rootLeadingNames);
|
|
761
|
-
}
|
|
762
|
-
function collectRootOptionNamesFromTerm(term, names, rootLeadingNames) {
|
|
763
|
-
switch (term.type) {
|
|
764
|
-
case "option":
|
|
765
|
-
for (const name of term.names) {
|
|
766
|
-
if (!rootLeadingNames.has(name)) continue;
|
|
767
|
-
if (term.metavar != null) names.value.add(name);
|
|
768
|
-
else names.flag.add(name);
|
|
769
|
-
}
|
|
770
|
-
return;
|
|
771
|
-
case "optional":
|
|
772
|
-
case "multiple":
|
|
773
|
-
case "sequence":
|
|
774
|
-
collectRootOptionNames(term.terms, names, rootLeadingNames);
|
|
775
|
-
return;
|
|
776
|
-
case "exclusive":
|
|
777
|
-
for (const branch of term.terms) collectRootOptionNames(branch, names, rootLeadingNames);
|
|
778
|
-
return;
|
|
779
|
-
case "argument":
|
|
780
|
-
case "command":
|
|
781
|
-
case "literal":
|
|
782
|
-
case "passthrough":
|
|
783
|
-
case "ellipsis": return;
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
function collectActiveOptionNames(usage, commandPath, names, fromExclusive, includeDirectAfterCommandOptions) {
|
|
787
|
-
if (commandPath.length === 0) {
|
|
788
|
-
collectOptionNamesAtCurrentCommandDepth(usage, names, false);
|
|
789
|
-
return;
|
|
790
|
-
}
|
|
791
|
-
const [commandName, ...rest] = commandPath;
|
|
792
|
-
for (let i = 0; i < usage.length; i++) {
|
|
793
|
-
const term = usage[i];
|
|
794
|
-
if (term.type === "command" && term.name === commandName) {
|
|
795
|
-
const remainingUsage = usage.slice(i + 1);
|
|
796
|
-
if (rest.length === 0) collectOptionNamesAtCurrentCommandDepth(remainingUsage, names, !fromExclusive && includeDirectAfterCommandOptions);
|
|
797
|
-
else collectActiveOptionNames(remainingUsage, rest, names, fromExclusive, includeDirectAfterCommandOptions);
|
|
798
|
-
} else if (term.type === "exclusive") for (const branch of term.terms) collectActiveOptionNames(branch, commandPath, names, true, includeDirectAfterCommandOptions);
|
|
799
|
-
else if (term.type === "optional" || term.type === "multiple" || term.type === "sequence") collectActiveOptionNames(term.terms, commandPath, names, fromExclusive, includeDirectAfterCommandOptions);
|
|
800
|
-
}
|
|
801
|
-
}
|
|
802
760
|
function isRootOptionToken(token, rootOptionSuggestions) {
|
|
803
761
|
return token != null && rootOptionSuggestions.some((suggestion) => token === suggestion.text || token.startsWith(`${suggestion.text}=`));
|
|
804
762
|
}
|
|
805
|
-
function collectOptionNamesAtCurrentCommandDepth(usage, names, afterMatchedCommand) {
|
|
806
|
-
for (const term of usage) if (collectOptionNamesAtCurrentCommandDepthFromTerm(term, names, afterMatchedCommand)) return;
|
|
807
|
-
}
|
|
808
|
-
function collectOptionNamesAtCurrentCommandDepthFromTerm(term, names, afterMatchedCommand) {
|
|
809
|
-
switch (term.type) {
|
|
810
|
-
case "command": return !afterMatchedCommand;
|
|
811
|
-
case "option":
|
|
812
|
-
if (term.metavar != null) for (const name of term.names) names.value.add(name);
|
|
813
|
-
else for (const name of term.names) names.flag.add(name);
|
|
814
|
-
return false;
|
|
815
|
-
case "optional":
|
|
816
|
-
case "multiple":
|
|
817
|
-
case "sequence":
|
|
818
|
-
collectOptionNamesAtCurrentCommandDepth(term.terms, names, afterMatchedCommand);
|
|
819
|
-
return false;
|
|
820
|
-
case "exclusive":
|
|
821
|
-
for (const branch of term.terms) collectOptionNamesAtCurrentCommandDepth(branch, names, false);
|
|
822
|
-
return false;
|
|
823
|
-
case "argument":
|
|
824
|
-
case "literal":
|
|
825
|
-
case "passthrough":
|
|
826
|
-
case "ellipsis": return false;
|
|
827
|
-
}
|
|
828
|
-
}
|
|
829
763
|
function getRootMetaOptionSuggestions(helpOptionConfig, helpOptionNames, versionOptionConfig, versionOptionNames) {
|
|
830
764
|
const suggestions = [];
|
|
831
765
|
if (helpOptionConfig != null && !isSuggestionHidden(helpOptionConfig.hidden)) suggestions.push(...helpOptionNames.map((name) => ({
|
package/dist/modifiers.cjs
CHANGED
|
@@ -4,6 +4,7 @@ const require_mode_dispatch = require('./internal/mode-dispatch.cjs');
|
|
|
4
4
|
const require_dependency_runtime = require('./dependency-runtime.cjs');
|
|
5
5
|
const require_internal_parser = require('./internal/parser.cjs');
|
|
6
6
|
const require_annotation_state = require('./annotation-state.cjs');
|
|
7
|
+
const require_short_option = require('./short-option.cjs');
|
|
7
8
|
const require_execution_context = require('./execution-context.cjs');
|
|
8
9
|
const require_phase2_seed = require('./phase2-seed.cjs');
|
|
9
10
|
const require_dependency_metadata = require('./dependency-metadata.cjs');
|
|
@@ -478,7 +479,7 @@ function optional(parser) {
|
|
|
478
479
|
require_internal_parser.defineParseLanes(optionalParser, adaptOptionalStyleParseLanes(parser));
|
|
479
480
|
require_internal_parser.defineInheritedAnnotationParser(optionalParser);
|
|
480
481
|
require_internal_parser.defineSourceBindingOnlyAnnotationCompletionParser(optionalParser);
|
|
481
|
-
return fluent(optionalParser);
|
|
482
|
+
return fluent(require_short_option.scopeParser(optionalParser, require_short_option.combinedOptionScope([parser])));
|
|
482
483
|
}
|
|
483
484
|
/**
|
|
484
485
|
* Error type for structured error messages in {@link withDefault} default value callbacks.
|
|
@@ -729,7 +730,7 @@ function withDefault(parser, defaultValue, options) {
|
|
|
729
730
|
require_internal_parser.defineParseLanes(withDefaultParser, adaptOptionalStyleParseLanes(parser));
|
|
730
731
|
require_internal_parser.defineInheritedAnnotationParser(withDefaultParser);
|
|
731
732
|
require_internal_parser.defineSourceBindingOnlyAnnotationCompletionParser(withDefaultParser);
|
|
732
|
-
return fluent(withDefaultParser);
|
|
733
|
+
return fluent(require_short_option.scopeParser(withDefaultParser, require_short_option.combinedOptionScope([parser])));
|
|
733
734
|
}
|
|
734
735
|
/**
|
|
735
736
|
* Creates a parser that transforms the result value of another parser using
|
|
@@ -918,7 +919,7 @@ function map(parser, transform) {
|
|
|
918
919
|
if (composed != null) mappedParser.dependencyMetadata = composed;
|
|
919
920
|
}
|
|
920
921
|
require_dependency_runtime.defineForwardedEffectfulSchedulingNodes(mappedParser, parser);
|
|
921
|
-
return fluent(mappedParser);
|
|
922
|
+
return fluent(require_short_option.scopeParser(mappedParser, require_short_option.combinedOptionScope([parser])));
|
|
922
923
|
}
|
|
923
924
|
const deferredValueBrand = Symbol.for("@optique/core/deferredValue");
|
|
924
925
|
/**
|
|
@@ -1714,7 +1715,7 @@ function multiple(parser, options = {}) {
|
|
|
1714
1715
|
enumerable: false
|
|
1715
1716
|
});
|
|
1716
1717
|
}
|
|
1717
|
-
return fluent(resultParser);
|
|
1718
|
+
return fluent(require_short_option.scopeParser(resultParser, require_short_option.combinedOptionScope([parser])));
|
|
1718
1719
|
}
|
|
1719
1720
|
/**
|
|
1720
1721
|
* Creates a parser that requires the wrapped parser to consume at least one
|
|
@@ -1850,7 +1851,7 @@ function nonEmpty(parser) {
|
|
|
1850
1851
|
enumerable: false
|
|
1851
1852
|
});
|
|
1852
1853
|
require_dependency_runtime.defineForwardedEffectfulSchedulingNodes(nonEmptyParser, parser);
|
|
1853
|
-
return fluent(nonEmptyParser);
|
|
1854
|
+
return fluent(require_short_option.scopeParser(nonEmptyParser, require_short_option.combinedOptionScope([parser])));
|
|
1854
1855
|
}
|
|
1855
1856
|
const fluentParserMarker = Symbol.for("@optique/core/fluent");
|
|
1856
1857
|
/**
|
package/dist/modifiers.js
CHANGED
|
@@ -4,6 +4,7 @@ import { dispatchByMode, dispatchIterableByMode, mapModeValue, wrapForMode } fro
|
|
|
4
4
|
import { defineForwardedEffectfulSchedulingNodes } from "./dependency-runtime.js";
|
|
5
5
|
import { defineInheritedAnnotationParser, defineParseLanes, defineSourceBindingOnlyAnnotationCompletionParser, getOwnParseLanes, unmatchedNonCliDependencySourceStateMarker } from "./internal/parser.js";
|
|
6
6
|
import { getDelegatedAnnotationState, hasDelegatedAnnotationCarrier, isAnnotationWrappedInitialState, normalizeDelegatedAnnotationState, normalizeNestedDelegatedAnnotationState } from "./annotation-state.js";
|
|
7
|
+
import { combinedOptionScope, scopeParser } from "./short-option.js";
|
|
7
8
|
import { mergeChildExec, withChildContext, withChildExecPath } from "./execution-context.js";
|
|
8
9
|
import { completeOrExtractPhase2Seed, extractPhase2Seed, extractPhase2SeedKey, phase2SeedFromValueResult } from "./phase2-seed.js";
|
|
9
10
|
import { composeDependencyMetadata } from "./dependency-metadata.js";
|
|
@@ -478,7 +479,7 @@ function optional(parser) {
|
|
|
478
479
|
defineParseLanes(optionalParser, adaptOptionalStyleParseLanes(parser));
|
|
479
480
|
defineInheritedAnnotationParser(optionalParser);
|
|
480
481
|
defineSourceBindingOnlyAnnotationCompletionParser(optionalParser);
|
|
481
|
-
return fluent(optionalParser);
|
|
482
|
+
return fluent(scopeParser(optionalParser, combinedOptionScope([parser])));
|
|
482
483
|
}
|
|
483
484
|
/**
|
|
484
485
|
* Error type for structured error messages in {@link withDefault} default value callbacks.
|
|
@@ -729,7 +730,7 @@ function withDefault(parser, defaultValue, options) {
|
|
|
729
730
|
defineParseLanes(withDefaultParser, adaptOptionalStyleParseLanes(parser));
|
|
730
731
|
defineInheritedAnnotationParser(withDefaultParser);
|
|
731
732
|
defineSourceBindingOnlyAnnotationCompletionParser(withDefaultParser);
|
|
732
|
-
return fluent(withDefaultParser);
|
|
733
|
+
return fluent(scopeParser(withDefaultParser, combinedOptionScope([parser])));
|
|
733
734
|
}
|
|
734
735
|
/**
|
|
735
736
|
* Creates a parser that transforms the result value of another parser using
|
|
@@ -918,7 +919,7 @@ function map(parser, transform) {
|
|
|
918
919
|
if (composed != null) mappedParser.dependencyMetadata = composed;
|
|
919
920
|
}
|
|
920
921
|
defineForwardedEffectfulSchedulingNodes(mappedParser, parser);
|
|
921
|
-
return fluent(mappedParser);
|
|
922
|
+
return fluent(scopeParser(mappedParser, combinedOptionScope([parser])));
|
|
922
923
|
}
|
|
923
924
|
const deferredValueBrand = Symbol.for("@optique/core/deferredValue");
|
|
924
925
|
/**
|
|
@@ -1714,7 +1715,7 @@ function multiple(parser, options = {}) {
|
|
|
1714
1715
|
enumerable: false
|
|
1715
1716
|
});
|
|
1716
1717
|
}
|
|
1717
|
-
return fluent(resultParser);
|
|
1718
|
+
return fluent(scopeParser(resultParser, combinedOptionScope([parser])));
|
|
1718
1719
|
}
|
|
1719
1720
|
/**
|
|
1720
1721
|
* Creates a parser that requires the wrapped parser to consume at least one
|
|
@@ -1850,7 +1851,7 @@ function nonEmpty(parser) {
|
|
|
1850
1851
|
enumerable: false
|
|
1851
1852
|
});
|
|
1852
1853
|
defineForwardedEffectfulSchedulingNodes(nonEmptyParser, parser);
|
|
1853
|
-
return fluent(nonEmptyParser);
|
|
1854
|
+
return fluent(scopeParser(nonEmptyParser, combinedOptionScope([parser])));
|
|
1854
1855
|
}
|
|
1855
1856
|
const fluentParserMarker = Symbol.for("@optique/core/fluent");
|
|
1856
1857
|
/**
|
package/dist/primitives.cjs
CHANGED
|
@@ -6,13 +6,14 @@ const require_mode_dispatch = require('./internal/mode-dispatch.cjs');
|
|
|
6
6
|
const require_internal_dependency = require('./internal/dependency.cjs');
|
|
7
7
|
const require_dependency_runtime = require('./dependency-runtime.cjs');
|
|
8
8
|
const require_annotation_state = require('./annotation-state.cjs');
|
|
9
|
+
const require_usage_internals = require('./usage-internals.cjs');
|
|
10
|
+
const require_short_option = require('./short-option.cjs');
|
|
9
11
|
const require_command_alias = require('./internal/command-alias.cjs');
|
|
10
12
|
const require_execution_context = require('./execution-context.cjs');
|
|
11
13
|
const require_phase2_seed = require('./phase2-seed.cjs');
|
|
12
14
|
const require_dependency_metadata = require('./dependency-metadata.cjs');
|
|
13
15
|
const require_modifiers = require('./modifiers.cjs');
|
|
14
16
|
const require_suggestion = require('./suggestion.cjs');
|
|
15
|
-
const require_usage_internals = require('./usage-internals.cjs');
|
|
16
17
|
const require_valueparser = require('./valueparser.cjs');
|
|
17
18
|
|
|
18
19
|
//#region src/primitives.ts
|
|
@@ -256,11 +257,25 @@ function* getSuggestionsWithDependency(valueParser, prefix, dependencyRegistry,
|
|
|
256
257
|
*/
|
|
257
258
|
function* suggestOptionSync(optionNames$1, valueParser, hidden, description, context, prefix) {
|
|
258
259
|
if (hidden) return;
|
|
260
|
+
if (context.optionsTerminated) return;
|
|
261
|
+
const waitingForValue = context.buffer.length > 0 && optionNames$1.includes(context.buffer[context.buffer.length - 1]);
|
|
262
|
+
if (valueParser != null && !waitingForValue && !isTerminalValueState(context.state)) {
|
|
263
|
+
const attached = require_short_option.attachedValuePrefix(context, prefix, optionNames$1);
|
|
264
|
+
if (attached != null) {
|
|
265
|
+
if (attached.value.length === 0 && optionNames$1.includes(prefix)) yield {
|
|
266
|
+
kind: "literal",
|
|
267
|
+
text: prefix,
|
|
268
|
+
...description != null ? { description } : {}
|
|
269
|
+
};
|
|
270
|
+
if (valueParser.suggest != null) for (const suggestion of getSuggestionsWithDependency(valueParser, attached.value, context.dependencyRegistry, context.exec)) yield require_short_option.prefixSuggestion(attached.head, suggestion);
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
259
274
|
const equalsIndex = prefix.indexOf("=");
|
|
260
|
-
if (equalsIndex >= 0) {
|
|
275
|
+
if (equalsIndex >= 0 && !waitingForValue) {
|
|
261
276
|
const optionPart = prefix.slice(0, equalsIndex);
|
|
262
277
|
const valuePart = prefix.slice(equalsIndex + 1);
|
|
263
|
-
if (optionNames$1.includes(optionPart)) {
|
|
278
|
+
if (optionNames$1.includes(optionPart) && !/^-[^-]$/.test(optionPart)) {
|
|
264
279
|
if (valueParser && valueParser.suggest) {
|
|
265
280
|
const valueSuggestions = getSuggestionsWithDependency(valueParser, valuePart, context.dependencyRegistry, context.exec);
|
|
266
281
|
for (const suggestion of valueSuggestions) if (suggestion.kind === "literal") yield {
|
|
@@ -341,11 +356,25 @@ async function* getSuggestionsWithDependencyAsync(valueParser, prefix, dependenc
|
|
|
341
356
|
*/
|
|
342
357
|
async function* suggestOptionAsync(optionNames$1, valueParser, hidden, description, context, prefix) {
|
|
343
358
|
if (hidden) return;
|
|
359
|
+
if (context.optionsTerminated) return;
|
|
360
|
+
const waitingForValue = context.buffer.length > 0 && optionNames$1.includes(context.buffer[context.buffer.length - 1]);
|
|
361
|
+
if (valueParser != null && !waitingForValue && !isTerminalValueState(context.state)) {
|
|
362
|
+
const attached = require_short_option.attachedValuePrefix(context, prefix, optionNames$1);
|
|
363
|
+
if (attached != null) {
|
|
364
|
+
if (attached.value.length === 0 && optionNames$1.includes(prefix)) yield {
|
|
365
|
+
kind: "literal",
|
|
366
|
+
text: prefix,
|
|
367
|
+
...description != null ? { description } : {}
|
|
368
|
+
};
|
|
369
|
+
if (valueParser.suggest != null) for await (const suggestion of getSuggestionsWithDependencyAsync(valueParser, attached.value, context.dependencyRegistry, context.exec)) yield require_short_option.prefixSuggestion(attached.head, suggestion);
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
344
373
|
const equalsIndex = prefix.indexOf("=");
|
|
345
|
-
if (equalsIndex >= 0) {
|
|
374
|
+
if (equalsIndex >= 0 && !waitingForValue) {
|
|
346
375
|
const optionPart = prefix.slice(0, equalsIndex);
|
|
347
376
|
const valuePart = prefix.slice(equalsIndex + 1);
|
|
348
|
-
if (optionNames$1.includes(optionPart)) {
|
|
377
|
+
if (optionNames$1.includes(optionPart) && !/^-[^-]$/.test(optionPart)) {
|
|
349
378
|
if (valueParser && valueParser.suggest) {
|
|
350
379
|
const valueSuggestions = getSuggestionsWithDependencyAsync(valueParser, valuePart, context.dependencyRegistry, context.exec);
|
|
351
380
|
for await (const suggestion of valueSuggestions) if (suggestion.kind === "literal") yield {
|
|
@@ -524,10 +553,18 @@ function option(...args) {
|
|
|
524
553
|
};
|
|
525
554
|
});
|
|
526
555
|
}
|
|
527
|
-
const prefixes = optionNames$1.filter((name) => name.startsWith("--") || name.startsWith("/") || name.startsWith("-") && name.length > 2).map((name) =>
|
|
528
|
-
|
|
556
|
+
const prefixes = optionNames$1.filter((name) => name.startsWith("--") || name.startsWith("/") || name.startsWith("-") && name.length > 2).map((name) => ({
|
|
557
|
+
optionName: name,
|
|
558
|
+
prefix: name.startsWith("/") ? `${name}:` : `${name}=`
|
|
559
|
+
}));
|
|
560
|
+
if (valueParser != null && optionNames$1.some((name) => /^-[^-]$/.test(name) && context.buffer[0].startsWith(name)) && !require_short_option.fullNameOwnsToken(context, context.buffer[0])) {
|
|
561
|
+
for (const name of optionNames$1) if (/^-[^-]$/.test(name)) prefixes.push({
|
|
562
|
+
optionName: name,
|
|
563
|
+
prefix: name
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
for (const { prefix, optionName: optionName$1 } of prefixes) {
|
|
529
567
|
if (!context.buffer[0].startsWith(prefix)) continue;
|
|
530
|
-
const optionName$1 = prefix.slice(0, -1);
|
|
531
568
|
if (hasParsedOptionValue(context.state, valueParser)) return {
|
|
532
569
|
success: false,
|
|
533
570
|
consumed: 1,
|
|
@@ -568,7 +605,7 @@ function option(...args) {
|
|
|
568
605
|
if (valueParser == null) {
|
|
569
606
|
const shortOptions = optionNames$1.filter((name) => name.match(/^-[^-]$/));
|
|
570
607
|
for (const shortOption of shortOptions) {
|
|
571
|
-
if (!context.buffer[0].startsWith(shortOption)) continue;
|
|
608
|
+
if (!context.buffer[0].startsWith(shortOption) || require_short_option.fullNameOwnsToken(context, context.buffer[0])) continue;
|
|
572
609
|
if (hasParsedOptionValue(context.state, valueParser)) return {
|
|
573
610
|
success: false,
|
|
574
611
|
consumed: 1,
|
|
@@ -857,7 +894,7 @@ function flag(...args) {
|
|
|
857
894
|
}
|
|
858
895
|
const shortOptions = optionNames$1.filter((name) => name.match(/^-[^-]$/));
|
|
859
896
|
for (const shortOption of shortOptions) {
|
|
860
|
-
if (!context.buffer[0].startsWith(shortOption)) continue;
|
|
897
|
+
if (!context.buffer[0].startsWith(shortOption) || require_short_option.fullNameOwnsToken(context, context.buffer[0])) continue;
|
|
861
898
|
if (context.state?.success) return {
|
|
862
899
|
success: false,
|
|
863
900
|
consumed: 1,
|
|
@@ -1078,7 +1115,7 @@ function negatableFlag(names, options = {}) {
|
|
|
1078
1115
|
}
|
|
1079
1116
|
for (const shortOption of optionNames$1) {
|
|
1080
1117
|
if (!shortOption.match(/^-[^-]$/)) continue;
|
|
1081
|
-
if (!context.buffer[0].startsWith(shortOption)) continue;
|
|
1118
|
+
if (!context.buffer[0].startsWith(shortOption) || require_short_option.fullNameOwnsToken(context, context.buffer[0])) continue;
|
|
1082
1119
|
return parseMatchedNegatableFlag(context, shortOption, valueByName.get(shortOption), [context.buffer[0].slice(0, 2)], 1, [`-${context.buffer[0].slice(2)}`, ...context.buffer.slice(1)], options);
|
|
1083
1120
|
}
|
|
1084
1121
|
const invalidOption = context.buffer[0];
|
|
@@ -1434,6 +1471,7 @@ function validateUniqueCommandNames(names) {
|
|
|
1434
1471
|
function* suggestCommandSync(context, prefix, name, aliases, parser, options) {
|
|
1435
1472
|
if (require_usage.isSuggestionHidden(options.hidden)) return;
|
|
1436
1473
|
const state = normalizeCommandState(context.state);
|
|
1474
|
+
if (state != null) context = require_short_option.withParserOptionScope(context, parser);
|
|
1437
1475
|
if (state === void 0) {
|
|
1438
1476
|
const description = options.brief ?? options.description;
|
|
1439
1477
|
for (const commandName of [name, ...aliases]) if (commandName.startsWith(prefix)) yield {
|
|
@@ -1447,6 +1485,7 @@ function* suggestCommandSync(context, prefix, name, aliases, parser, options) {
|
|
|
1447
1485
|
async function* suggestCommandAsync(context, prefix, name, aliases, parser, options) {
|
|
1448
1486
|
if (require_usage.isSuggestionHidden(options.hidden)) return;
|
|
1449
1487
|
const state = normalizeCommandState(context.state);
|
|
1488
|
+
if (state != null) context = require_short_option.withParserOptionScope(context, parser);
|
|
1450
1489
|
if (state === void 0) {
|
|
1451
1490
|
const description = options.brief ?? options.description;
|
|
1452
1491
|
for (const commandName of [name, ...aliases]) if (commandName.startsWith(prefix)) yield {
|
|
@@ -1487,6 +1526,8 @@ function command(name, parser, options = {}) {
|
|
|
1487
1526
|
const isAsync = parser.mode === "async";
|
|
1488
1527
|
const syncInnerParser = parser;
|
|
1489
1528
|
const asyncInnerParser = parser;
|
|
1529
|
+
const commandScope = require_short_option.selectableOptionScope(() => new Set(commandNames));
|
|
1530
|
+
const enteredScope = require_short_option.combinedOptionScope([parser]);
|
|
1490
1531
|
const result = {
|
|
1491
1532
|
[Symbol.for("@optique/core/commandParser")]: true,
|
|
1492
1533
|
mode: parser.mode,
|
|
@@ -1554,6 +1595,7 @@ function command(name, parser, options = {}) {
|
|
|
1554
1595
|
] : baseError
|
|
1555
1596
|
};
|
|
1556
1597
|
}
|
|
1598
|
+
commandScope.select(context, enteredScope);
|
|
1557
1599
|
return {
|
|
1558
1600
|
success: true,
|
|
1559
1601
|
next: {
|
|
@@ -1584,7 +1626,7 @@ function command(name, parser, options = {}) {
|
|
|
1584
1626
|
}
|
|
1585
1627
|
return parseResult;
|
|
1586
1628
|
};
|
|
1587
|
-
return require_mode_dispatch.dispatchByMode(parser.mode, () => wrapState(syncInnerParser.parse(require_execution_context.withChildContext(context, name, innerState, parser.usage))), async () => wrapState(await parser.parse(require_execution_context.withChildContext(context, name, innerState, parser.usage))));
|
|
1629
|
+
return require_mode_dispatch.dispatchByMode(parser.mode, () => wrapState(syncInnerParser.parse(require_execution_context.withChildContext(require_short_option.withParserOptionScope(context, parser), name, innerState, parser.usage))), async () => wrapState(await parser.parse(require_execution_context.withChildContext(require_short_option.withParserOptionScope(context, parser), name, innerState, parser.usage))));
|
|
1588
1630
|
}
|
|
1589
1631
|
return {
|
|
1590
1632
|
success: false,
|
|
@@ -1734,7 +1776,9 @@ function command(name, parser, options = {}) {
|
|
|
1734
1776
|
configurable: true,
|
|
1735
1777
|
enumerable: false
|
|
1736
1778
|
});
|
|
1737
|
-
return require_modifiers.fluent(result)
|
|
1779
|
+
return require_modifiers.fluent(require_short_option.scopeParser(result, commandScope.source, (context) => {
|
|
1780
|
+
if (normalizeCommandState(context.state) != null) commandScope.select(context, enteredScope);
|
|
1781
|
+
}));
|
|
1738
1782
|
}
|
|
1739
1783
|
/**
|
|
1740
1784
|
* Creates a parser that collects unrecognized options and passes them through.
|
package/dist/primitives.d.cts
CHANGED
|
@@ -104,7 +104,7 @@ interface OptionErrorOptions {
|
|
|
104
104
|
/**
|
|
105
105
|
* Creates a parser for various styles of command-line options that take an
|
|
106
106
|
* argument value, such as `--option=value`, `-option=value`, `-o value`,
|
|
107
|
-
* or `/option:value`.
|
|
107
|
+
* `-ovalue`, or `/option:value`.
|
|
108
108
|
* @template M The execution mode of the parser.
|
|
109
109
|
* @template T The type of value this parser produces.
|
|
110
110
|
* @param args The {@link OptionName}s to parse, followed by
|
|
@@ -118,7 +118,7 @@ declare function option<M extends Mode, T>(...args: readonly [OptionName, ...rea
|
|
|
118
118
|
/**
|
|
119
119
|
* Creates a parser for various styles of command-line options that take an
|
|
120
120
|
* argument value, such as `--option=value`, `-option=value`, `-o value`,
|
|
121
|
-
* or `/option:value`.
|
|
121
|
+
* `-ovalue`, or `/option:value`.
|
|
122
122
|
* @template M The execution mode of the parser.
|
|
123
123
|
* @template T The type of value this parser produces.
|
|
124
124
|
* @param args The {@link OptionName}s to parse, followed by
|
|
@@ -140,7 +140,7 @@ declare function option(...optionNames: readonly [OptionName, ...readonly Option
|
|
|
140
140
|
/**
|
|
141
141
|
* Creates a parser for various styles of command-line options that take an
|
|
142
142
|
* argument value, such as `--option=value`, `-option=value`, `-o value`,
|
|
143
|
-
* or `/option:value`.
|
|
143
|
+
* `-ovalue`, or `/option:value`.
|
|
144
144
|
* @param args The {@link OptionName}s to parse, followed by
|
|
145
145
|
* an optional {@link OptionOptions} object that allows you to
|
|
146
146
|
* specify a description or other metadata.
|
package/dist/primitives.d.ts
CHANGED
|
@@ -104,7 +104,7 @@ interface OptionErrorOptions {
|
|
|
104
104
|
/**
|
|
105
105
|
* Creates a parser for various styles of command-line options that take an
|
|
106
106
|
* argument value, such as `--option=value`, `-option=value`, `-o value`,
|
|
107
|
-
* or `/option:value`.
|
|
107
|
+
* `-ovalue`, or `/option:value`.
|
|
108
108
|
* @template M The execution mode of the parser.
|
|
109
109
|
* @template T The type of value this parser produces.
|
|
110
110
|
* @param args The {@link OptionName}s to parse, followed by
|
|
@@ -118,7 +118,7 @@ declare function option<M extends Mode, T>(...args: readonly [OptionName, ...rea
|
|
|
118
118
|
/**
|
|
119
119
|
* Creates a parser for various styles of command-line options that take an
|
|
120
120
|
* argument value, such as `--option=value`, `-option=value`, `-o value`,
|
|
121
|
-
* or `/option:value`.
|
|
121
|
+
* `-ovalue`, or `/option:value`.
|
|
122
122
|
* @template M The execution mode of the parser.
|
|
123
123
|
* @template T The type of value this parser produces.
|
|
124
124
|
* @param args The {@link OptionName}s to parse, followed by
|
|
@@ -140,7 +140,7 @@ declare function option(...optionNames: readonly [OptionName, ...readonly Option
|
|
|
140
140
|
/**
|
|
141
141
|
* Creates a parser for various styles of command-line options that take an
|
|
142
142
|
* argument value, such as `--option=value`, `-option=value`, `-o value`,
|
|
143
|
-
* or `/option:value`.
|
|
143
|
+
* `-ovalue`, or `/option:value`.
|
|
144
144
|
* @param args The {@link OptionName}s to parse, followed by
|
|
145
145
|
* an optional {@link OptionOptions} object that allows you to
|
|
146
146
|
* specify a description or other metadata.
|
package/dist/primitives.js
CHANGED
|
@@ -6,13 +6,14 @@ import { dispatchByMode, dispatchIterableByMode, wrapForMode } from "./internal/
|
|
|
6
6
|
import { getDefaultValuesFunction, getDependencyIds, getSnapshottedDefaultDependencyValues, isDerivedValueParser, suggestWithDependency } from "./internal/dependency.js";
|
|
7
7
|
import { effectfulSchedulingNodesKey, exclusiveSourceScopeKey, includeSourceFailureChain, recordDerivedRawInput, replayDerivedParser, replayDerivedParserAsync, sourceCollectionExpansionKey } from "./dependency-runtime.js";
|
|
8
8
|
import { getWrappedChildParseState, getWrappedChildState, isAnnotationWrappedInitialState, normalizeInjectedAnnotationState } from "./annotation-state.js";
|
|
9
|
+
import { extractLeadingCommandNames } from "./usage-internals.js";
|
|
10
|
+
import { attachedValuePrefix, combinedOptionScope, fullNameOwnsToken, prefixSuggestion, scopeParser, selectableOptionScope, withParserOptionScope } from "./short-option.js";
|
|
9
11
|
import { hiddenCommandAliasesKey } from "./internal/command-alias.js";
|
|
10
12
|
import { mergeChildExec, withChildContext, withChildExecPath } from "./execution-context.js";
|
|
11
13
|
import { completeOrExtractPhase2Seed, extractPhase2SeedKey } from "./phase2-seed.js";
|
|
12
14
|
import { extractDependencyMetadata } from "./dependency-metadata.js";
|
|
13
15
|
import { fluent } from "./modifiers.js";
|
|
14
16
|
import { DEFAULT_FIND_SIMILAR_OPTIONS, createErrorWithSuggestions, createSuggestionMessage, expandCommandAliasSuggestions, findSimilar } from "./suggestion.js";
|
|
15
|
-
import { extractLeadingCommandNames } from "./usage-internals.js";
|
|
16
17
|
import { isValueParser } from "./valueparser.js";
|
|
17
18
|
|
|
18
19
|
//#region src/primitives.ts
|
|
@@ -256,11 +257,25 @@ function* getSuggestionsWithDependency(valueParser, prefix, dependencyRegistry,
|
|
|
256
257
|
*/
|
|
257
258
|
function* suggestOptionSync(optionNames$1, valueParser, hidden, description, context, prefix) {
|
|
258
259
|
if (hidden) return;
|
|
260
|
+
if (context.optionsTerminated) return;
|
|
261
|
+
const waitingForValue = context.buffer.length > 0 && optionNames$1.includes(context.buffer[context.buffer.length - 1]);
|
|
262
|
+
if (valueParser != null && !waitingForValue && !isTerminalValueState(context.state)) {
|
|
263
|
+
const attached = attachedValuePrefix(context, prefix, optionNames$1);
|
|
264
|
+
if (attached != null) {
|
|
265
|
+
if (attached.value.length === 0 && optionNames$1.includes(prefix)) yield {
|
|
266
|
+
kind: "literal",
|
|
267
|
+
text: prefix,
|
|
268
|
+
...description != null ? { description } : {}
|
|
269
|
+
};
|
|
270
|
+
if (valueParser.suggest != null) for (const suggestion of getSuggestionsWithDependency(valueParser, attached.value, context.dependencyRegistry, context.exec)) yield prefixSuggestion(attached.head, suggestion);
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
259
274
|
const equalsIndex = prefix.indexOf("=");
|
|
260
|
-
if (equalsIndex >= 0) {
|
|
275
|
+
if (equalsIndex >= 0 && !waitingForValue) {
|
|
261
276
|
const optionPart = prefix.slice(0, equalsIndex);
|
|
262
277
|
const valuePart = prefix.slice(equalsIndex + 1);
|
|
263
|
-
if (optionNames$1.includes(optionPart)) {
|
|
278
|
+
if (optionNames$1.includes(optionPart) && !/^-[^-]$/.test(optionPart)) {
|
|
264
279
|
if (valueParser && valueParser.suggest) {
|
|
265
280
|
const valueSuggestions = getSuggestionsWithDependency(valueParser, valuePart, context.dependencyRegistry, context.exec);
|
|
266
281
|
for (const suggestion of valueSuggestions) if (suggestion.kind === "literal") yield {
|
|
@@ -341,11 +356,25 @@ async function* getSuggestionsWithDependencyAsync(valueParser, prefix, dependenc
|
|
|
341
356
|
*/
|
|
342
357
|
async function* suggestOptionAsync(optionNames$1, valueParser, hidden, description, context, prefix) {
|
|
343
358
|
if (hidden) return;
|
|
359
|
+
if (context.optionsTerminated) return;
|
|
360
|
+
const waitingForValue = context.buffer.length > 0 && optionNames$1.includes(context.buffer[context.buffer.length - 1]);
|
|
361
|
+
if (valueParser != null && !waitingForValue && !isTerminalValueState(context.state)) {
|
|
362
|
+
const attached = attachedValuePrefix(context, prefix, optionNames$1);
|
|
363
|
+
if (attached != null) {
|
|
364
|
+
if (attached.value.length === 0 && optionNames$1.includes(prefix)) yield {
|
|
365
|
+
kind: "literal",
|
|
366
|
+
text: prefix,
|
|
367
|
+
...description != null ? { description } : {}
|
|
368
|
+
};
|
|
369
|
+
if (valueParser.suggest != null) for await (const suggestion of getSuggestionsWithDependencyAsync(valueParser, attached.value, context.dependencyRegistry, context.exec)) yield prefixSuggestion(attached.head, suggestion);
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
344
373
|
const equalsIndex = prefix.indexOf("=");
|
|
345
|
-
if (equalsIndex >= 0) {
|
|
374
|
+
if (equalsIndex >= 0 && !waitingForValue) {
|
|
346
375
|
const optionPart = prefix.slice(0, equalsIndex);
|
|
347
376
|
const valuePart = prefix.slice(equalsIndex + 1);
|
|
348
|
-
if (optionNames$1.includes(optionPart)) {
|
|
377
|
+
if (optionNames$1.includes(optionPart) && !/^-[^-]$/.test(optionPart)) {
|
|
349
378
|
if (valueParser && valueParser.suggest) {
|
|
350
379
|
const valueSuggestions = getSuggestionsWithDependencyAsync(valueParser, valuePart, context.dependencyRegistry, context.exec);
|
|
351
380
|
for await (const suggestion of valueSuggestions) if (suggestion.kind === "literal") yield {
|
|
@@ -524,10 +553,18 @@ function option(...args) {
|
|
|
524
553
|
};
|
|
525
554
|
});
|
|
526
555
|
}
|
|
527
|
-
const prefixes = optionNames$1.filter((name) => name.startsWith("--") || name.startsWith("/") || name.startsWith("-") && name.length > 2).map((name) =>
|
|
528
|
-
|
|
556
|
+
const prefixes = optionNames$1.filter((name) => name.startsWith("--") || name.startsWith("/") || name.startsWith("-") && name.length > 2).map((name) => ({
|
|
557
|
+
optionName: name,
|
|
558
|
+
prefix: name.startsWith("/") ? `${name}:` : `${name}=`
|
|
559
|
+
}));
|
|
560
|
+
if (valueParser != null && optionNames$1.some((name) => /^-[^-]$/.test(name) && context.buffer[0].startsWith(name)) && !fullNameOwnsToken(context, context.buffer[0])) {
|
|
561
|
+
for (const name of optionNames$1) if (/^-[^-]$/.test(name)) prefixes.push({
|
|
562
|
+
optionName: name,
|
|
563
|
+
prefix: name
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
for (const { prefix, optionName: optionName$1 } of prefixes) {
|
|
529
567
|
if (!context.buffer[0].startsWith(prefix)) continue;
|
|
530
|
-
const optionName$1 = prefix.slice(0, -1);
|
|
531
568
|
if (hasParsedOptionValue(context.state, valueParser)) return {
|
|
532
569
|
success: false,
|
|
533
570
|
consumed: 1,
|
|
@@ -568,7 +605,7 @@ function option(...args) {
|
|
|
568
605
|
if (valueParser == null) {
|
|
569
606
|
const shortOptions = optionNames$1.filter((name) => name.match(/^-[^-]$/));
|
|
570
607
|
for (const shortOption of shortOptions) {
|
|
571
|
-
if (!context.buffer[0].startsWith(shortOption)) continue;
|
|
608
|
+
if (!context.buffer[0].startsWith(shortOption) || fullNameOwnsToken(context, context.buffer[0])) continue;
|
|
572
609
|
if (hasParsedOptionValue(context.state, valueParser)) return {
|
|
573
610
|
success: false,
|
|
574
611
|
consumed: 1,
|
|
@@ -857,7 +894,7 @@ function flag(...args) {
|
|
|
857
894
|
}
|
|
858
895
|
const shortOptions = optionNames$1.filter((name) => name.match(/^-[^-]$/));
|
|
859
896
|
for (const shortOption of shortOptions) {
|
|
860
|
-
if (!context.buffer[0].startsWith(shortOption)) continue;
|
|
897
|
+
if (!context.buffer[0].startsWith(shortOption) || fullNameOwnsToken(context, context.buffer[0])) continue;
|
|
861
898
|
if (context.state?.success) return {
|
|
862
899
|
success: false,
|
|
863
900
|
consumed: 1,
|
|
@@ -1078,7 +1115,7 @@ function negatableFlag(names, options = {}) {
|
|
|
1078
1115
|
}
|
|
1079
1116
|
for (const shortOption of optionNames$1) {
|
|
1080
1117
|
if (!shortOption.match(/^-[^-]$/)) continue;
|
|
1081
|
-
if (!context.buffer[0].startsWith(shortOption)) continue;
|
|
1118
|
+
if (!context.buffer[0].startsWith(shortOption) || fullNameOwnsToken(context, context.buffer[0])) continue;
|
|
1082
1119
|
return parseMatchedNegatableFlag(context, shortOption, valueByName.get(shortOption), [context.buffer[0].slice(0, 2)], 1, [`-${context.buffer[0].slice(2)}`, ...context.buffer.slice(1)], options);
|
|
1083
1120
|
}
|
|
1084
1121
|
const invalidOption = context.buffer[0];
|
|
@@ -1434,6 +1471,7 @@ function validateUniqueCommandNames(names) {
|
|
|
1434
1471
|
function* suggestCommandSync(context, prefix, name, aliases, parser, options) {
|
|
1435
1472
|
if (isSuggestionHidden(options.hidden)) return;
|
|
1436
1473
|
const state = normalizeCommandState(context.state);
|
|
1474
|
+
if (state != null) context = withParserOptionScope(context, parser);
|
|
1437
1475
|
if (state === void 0) {
|
|
1438
1476
|
const description = options.brief ?? options.description;
|
|
1439
1477
|
for (const commandName of [name, ...aliases]) if (commandName.startsWith(prefix)) yield {
|
|
@@ -1447,6 +1485,7 @@ function* suggestCommandSync(context, prefix, name, aliases, parser, options) {
|
|
|
1447
1485
|
async function* suggestCommandAsync(context, prefix, name, aliases, parser, options) {
|
|
1448
1486
|
if (isSuggestionHidden(options.hidden)) return;
|
|
1449
1487
|
const state = normalizeCommandState(context.state);
|
|
1488
|
+
if (state != null) context = withParserOptionScope(context, parser);
|
|
1450
1489
|
if (state === void 0) {
|
|
1451
1490
|
const description = options.brief ?? options.description;
|
|
1452
1491
|
for (const commandName of [name, ...aliases]) if (commandName.startsWith(prefix)) yield {
|
|
@@ -1487,6 +1526,8 @@ function command(name, parser, options = {}) {
|
|
|
1487
1526
|
const isAsync = parser.mode === "async";
|
|
1488
1527
|
const syncInnerParser = parser;
|
|
1489
1528
|
const asyncInnerParser = parser;
|
|
1529
|
+
const commandScope = selectableOptionScope(() => new Set(commandNames));
|
|
1530
|
+
const enteredScope = combinedOptionScope([parser]);
|
|
1490
1531
|
const result = {
|
|
1491
1532
|
[Symbol.for("@optique/core/commandParser")]: true,
|
|
1492
1533
|
mode: parser.mode,
|
|
@@ -1554,6 +1595,7 @@ function command(name, parser, options = {}) {
|
|
|
1554
1595
|
] : baseError
|
|
1555
1596
|
};
|
|
1556
1597
|
}
|
|
1598
|
+
commandScope.select(context, enteredScope);
|
|
1557
1599
|
return {
|
|
1558
1600
|
success: true,
|
|
1559
1601
|
next: {
|
|
@@ -1584,7 +1626,7 @@ function command(name, parser, options = {}) {
|
|
|
1584
1626
|
}
|
|
1585
1627
|
return parseResult;
|
|
1586
1628
|
};
|
|
1587
|
-
return dispatchByMode(parser.mode, () => wrapState(syncInnerParser.parse(withChildContext(context, name, innerState, parser.usage))), async () => wrapState(await parser.parse(withChildContext(context, name, innerState, parser.usage))));
|
|
1629
|
+
return dispatchByMode(parser.mode, () => wrapState(syncInnerParser.parse(withChildContext(withParserOptionScope(context, parser), name, innerState, parser.usage))), async () => wrapState(await parser.parse(withChildContext(withParserOptionScope(context, parser), name, innerState, parser.usage))));
|
|
1588
1630
|
}
|
|
1589
1631
|
return {
|
|
1590
1632
|
success: false,
|
|
@@ -1734,7 +1776,9 @@ function command(name, parser, options = {}) {
|
|
|
1734
1776
|
configurable: true,
|
|
1735
1777
|
enumerable: false
|
|
1736
1778
|
});
|
|
1737
|
-
return fluent(result)
|
|
1779
|
+
return fluent(scopeParser(result, commandScope.source, (context) => {
|
|
1780
|
+
if (normalizeCommandState(context.state) != null) commandScope.select(context, enteredScope);
|
|
1781
|
+
}));
|
|
1738
1782
|
}
|
|
1739
1783
|
/**
|
|
1740
1784
|
* Creates a parser that collects unrecognized options and passes them through.
|