@optique/core 1.3.1 → 1.3.3
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 +260 -40
- package/dist/constructs.js +260 -40
- package/dist/doc.cjs +11 -3
- package/dist/doc.js +12 -4
- package/dist/extension.cjs +17 -0
- package/dist/extension.d.cts +13 -1
- package/dist/extension.d.ts +13 -1
- package/dist/extension.js +17 -1
- package/dist/internal/passthrough.cjs +230 -0
- package/dist/internal/passthrough.js +213 -0
- package/dist/message.cjs +32 -5
- package/dist/message.js +33 -6
- package/dist/modifiers.cjs +22 -0
- package/dist/modifiers.js +22 -0
- package/dist/primitives.cjs +45 -9
- package/dist/primitives.js +45 -9
- package/dist/suggestion.cjs +3 -1
- package/dist/suggestion.js +3 -1
- package/dist/terminal-internal.cjs +4 -1
- package/dist/terminal-internal.d.cts +5 -0
- package/dist/terminal-internal.d.ts +5 -0
- package/dist/terminal-internal.js +4 -1
- package/dist/terminal-separators.cjs +13 -0
- package/dist/terminal-separators.js +12 -0
- package/dist/terminal.cjs +4 -1
- package/dist/terminal.js +5 -1
- package/dist/text-layout.cjs +14 -1
- package/dist/text-layout.d.cts +8 -1
- package/dist/text-layout.d.ts +8 -1
- package/dist/text-layout.js +13 -1
- package/package.json +2 -2
package/dist/message.cjs
CHANGED
|
@@ -347,7 +347,8 @@ function renderMessage(msg, options, theme, ambient) {
|
|
|
347
347
|
yield {
|
|
348
348
|
text: match[0],
|
|
349
349
|
width: require_displaywidth.getDisplayWidth(match[0]),
|
|
350
|
-
scopes: []
|
|
350
|
+
scopes: [],
|
|
351
|
+
trimOnWrap: true
|
|
351
352
|
};
|
|
352
353
|
}
|
|
353
354
|
}
|
|
@@ -356,7 +357,8 @@ function renderMessage(msg, options, theme, ambient) {
|
|
|
356
357
|
if (normalizedText.trim() === "" && normalizedText.length > 0) yield {
|
|
357
358
|
text: " ",
|
|
358
359
|
width: 1,
|
|
359
|
-
scopes: []
|
|
360
|
+
scopes: [],
|
|
361
|
+
trimOnWrap: true
|
|
360
362
|
};
|
|
361
363
|
else {
|
|
362
364
|
wordPattern.lastIndex = 0;
|
|
@@ -366,7 +368,8 @@ function renderMessage(msg, options, theme, ambient) {
|
|
|
366
368
|
yield {
|
|
367
369
|
text: match[0],
|
|
368
370
|
width: require_displaywidth.getDisplayWidth(match[0]),
|
|
369
|
-
scopes: []
|
|
371
|
+
scopes: [],
|
|
372
|
+
trimOnWrap: true
|
|
370
373
|
};
|
|
371
374
|
}
|
|
372
375
|
}
|
|
@@ -383,22 +386,46 @@ function renderMessage(msg, options, theme, ambient) {
|
|
|
383
386
|
}
|
|
384
387
|
const tokens = [];
|
|
385
388
|
let totalWidth = initialWidth;
|
|
386
|
-
|
|
389
|
+
let pendingWrap = false;
|
|
390
|
+
let atWrappedLineStart = false;
|
|
391
|
+
for (let token of stream()) {
|
|
387
392
|
if (token.width === -1) {
|
|
388
393
|
tokens.push(token);
|
|
389
394
|
totalWidth = 0;
|
|
395
|
+
pendingWrap = false;
|
|
396
|
+
atWrappedLineStart = false;
|
|
397
|
+
continue;
|
|
398
|
+
}
|
|
399
|
+
const wraps = pendingWrap || options.maxWidth != null && totalWidth > 0 && totalWidth + token.width > options.maxWidth;
|
|
400
|
+
if ((wraps || atWrappedLineStart) && token.trimOnWrap) {
|
|
401
|
+
const text$1 = token.text.trimStart();
|
|
402
|
+
token = {
|
|
403
|
+
...token,
|
|
404
|
+
text: text$1,
|
|
405
|
+
width: token.width - require_displaywidth.getDisplayWidth(token.text.slice(0, token.text.length - text$1.length))
|
|
406
|
+
};
|
|
407
|
+
if (text$1 === "") {
|
|
408
|
+
if (wraps) pendingWrap = true;
|
|
409
|
+
continue;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
if (pendingWrap && require_displaywidth.stripAnsi(token.text) === "") {
|
|
413
|
+
tokens.push(token);
|
|
390
414
|
continue;
|
|
391
415
|
}
|
|
392
|
-
if (
|
|
416
|
+
if (wraps) {
|
|
393
417
|
tokens.push({
|
|
394
418
|
text: "\n",
|
|
395
419
|
width: -1,
|
|
396
420
|
scopes: []
|
|
397
421
|
});
|
|
398
422
|
totalWidth = 0;
|
|
423
|
+
pendingWrap = false;
|
|
424
|
+
atWrappedLineStart = true;
|
|
399
425
|
}
|
|
400
426
|
tokens.push(token);
|
|
401
427
|
totalWidth += token.width;
|
|
428
|
+
if (token.width > 0) atWrappedLineStart = false;
|
|
402
429
|
}
|
|
403
430
|
return require_terminal_internal.serializeTokens(tokens, useColors, ambient == null ? resetSuffix : "", ambient);
|
|
404
431
|
}
|
package/dist/message.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getDisplayWidth } from "./displaywidth.js";
|
|
1
|
+
import { getDisplayWidth, stripAnsi } from "./displaywidth.js";
|
|
2
2
|
import { formatTerminalTerm, fragmentTokens, serializeTokens } from "./terminal-internal.js";
|
|
3
3
|
import { messageRenderers } from "./message-registry.js";
|
|
4
4
|
|
|
@@ -347,7 +347,8 @@ function renderMessage(msg, options, theme, ambient) {
|
|
|
347
347
|
yield {
|
|
348
348
|
text: match[0],
|
|
349
349
|
width: getDisplayWidth(match[0]),
|
|
350
|
-
scopes: []
|
|
350
|
+
scopes: [],
|
|
351
|
+
trimOnWrap: true
|
|
351
352
|
};
|
|
352
353
|
}
|
|
353
354
|
}
|
|
@@ -356,7 +357,8 @@ function renderMessage(msg, options, theme, ambient) {
|
|
|
356
357
|
if (normalizedText.trim() === "" && normalizedText.length > 0) yield {
|
|
357
358
|
text: " ",
|
|
358
359
|
width: 1,
|
|
359
|
-
scopes: []
|
|
360
|
+
scopes: [],
|
|
361
|
+
trimOnWrap: true
|
|
360
362
|
};
|
|
361
363
|
else {
|
|
362
364
|
wordPattern.lastIndex = 0;
|
|
@@ -366,7 +368,8 @@ function renderMessage(msg, options, theme, ambient) {
|
|
|
366
368
|
yield {
|
|
367
369
|
text: match[0],
|
|
368
370
|
width: getDisplayWidth(match[0]),
|
|
369
|
-
scopes: []
|
|
371
|
+
scopes: [],
|
|
372
|
+
trimOnWrap: true
|
|
370
373
|
};
|
|
371
374
|
}
|
|
372
375
|
}
|
|
@@ -383,22 +386,46 @@ function renderMessage(msg, options, theme, ambient) {
|
|
|
383
386
|
}
|
|
384
387
|
const tokens = [];
|
|
385
388
|
let totalWidth = initialWidth;
|
|
386
|
-
|
|
389
|
+
let pendingWrap = false;
|
|
390
|
+
let atWrappedLineStart = false;
|
|
391
|
+
for (let token of stream()) {
|
|
387
392
|
if (token.width === -1) {
|
|
388
393
|
tokens.push(token);
|
|
389
394
|
totalWidth = 0;
|
|
395
|
+
pendingWrap = false;
|
|
396
|
+
atWrappedLineStart = false;
|
|
397
|
+
continue;
|
|
398
|
+
}
|
|
399
|
+
const wraps = pendingWrap || options.maxWidth != null && totalWidth > 0 && totalWidth + token.width > options.maxWidth;
|
|
400
|
+
if ((wraps || atWrappedLineStart) && token.trimOnWrap) {
|
|
401
|
+
const text$1 = token.text.trimStart();
|
|
402
|
+
token = {
|
|
403
|
+
...token,
|
|
404
|
+
text: text$1,
|
|
405
|
+
width: token.width - getDisplayWidth(token.text.slice(0, token.text.length - text$1.length))
|
|
406
|
+
};
|
|
407
|
+
if (text$1 === "") {
|
|
408
|
+
if (wraps) pendingWrap = true;
|
|
409
|
+
continue;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
if (pendingWrap && stripAnsi(token.text) === "") {
|
|
413
|
+
tokens.push(token);
|
|
390
414
|
continue;
|
|
391
415
|
}
|
|
392
|
-
if (
|
|
416
|
+
if (wraps) {
|
|
393
417
|
tokens.push({
|
|
394
418
|
text: "\n",
|
|
395
419
|
width: -1,
|
|
396
420
|
scopes: []
|
|
397
421
|
});
|
|
398
422
|
totalWidth = 0;
|
|
423
|
+
pendingWrap = false;
|
|
424
|
+
atWrappedLineStart = true;
|
|
399
425
|
}
|
|
400
426
|
tokens.push(token);
|
|
401
427
|
totalWidth += token.width;
|
|
428
|
+
if (token.width > 0) atWrappedLineStart = false;
|
|
402
429
|
}
|
|
403
430
|
return serializeTokens(tokens, useColors, ambient == null ? resetSuffix : "", ambient);
|
|
404
431
|
}
|
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_passthrough = require('./internal/passthrough.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,6 +479,9 @@ 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);
|
|
482
|
+
require_passthrough.defineOptionMatch(optionalParser, (state, token) => require_passthrough.getOptionMatch(parser, normalizeOptionalLikeSuggestState(state, parser.initialState, parser), token));
|
|
483
|
+
require_passthrough.definePassThroughPriority(optionalParser, [parser], (state, token) => require_passthrough.getPassThroughPriority(parser, normalizeOptionalLikeSuggestState(state, parser.initialState, parser), token));
|
|
484
|
+
require_passthrough.defineKnownCompletionLookup(optionalParser, (state) => require_passthrough.getKnownCompletion(parser, deriveOptionalInnerParseState(state, parser)));
|
|
481
485
|
return fluent(optionalParser);
|
|
482
486
|
}
|
|
483
487
|
/**
|
|
@@ -729,6 +733,9 @@ function withDefault(parser, defaultValue, options) {
|
|
|
729
733
|
require_internal_parser.defineParseLanes(withDefaultParser, adaptOptionalStyleParseLanes(parser));
|
|
730
734
|
require_internal_parser.defineInheritedAnnotationParser(withDefaultParser);
|
|
731
735
|
require_internal_parser.defineSourceBindingOnlyAnnotationCompletionParser(withDefaultParser);
|
|
736
|
+
require_passthrough.defineOptionMatch(withDefaultParser, (state, token) => require_passthrough.getOptionMatch(parser, normalizeOptionalLikeSuggestState(state, parser.initialState, parser), token));
|
|
737
|
+
require_passthrough.definePassThroughPriority(withDefaultParser, [parser], (state, token) => require_passthrough.getPassThroughPriority(parser, normalizeOptionalLikeSuggestState(state, parser.initialState, parser), token));
|
|
738
|
+
require_passthrough.defineKnownCompletionLookup(withDefaultParser, (state) => require_passthrough.getKnownCompletion(parser, deriveOptionalInnerParseState(state, parser)));
|
|
732
739
|
return fluent(withDefaultParser);
|
|
733
740
|
}
|
|
734
741
|
/**
|
|
@@ -1714,6 +1721,19 @@ function multiple(parser, options = {}) {
|
|
|
1714
1721
|
enumerable: false
|
|
1715
1722
|
});
|
|
1716
1723
|
}
|
|
1724
|
+
const matchingItem = (state) => {
|
|
1725
|
+
const current = state.at(-1);
|
|
1726
|
+
if (current != null && !isTerminalMultipleItemState(current)) return { state: unwrapInjectedWrapper(current) };
|
|
1727
|
+
return state.length < max ? { state: parser.initialState } : void 0;
|
|
1728
|
+
};
|
|
1729
|
+
require_passthrough.defineOptionMatch(resultParser, (state, token) => {
|
|
1730
|
+
const item = matchingItem(state);
|
|
1731
|
+
return item == null ? void 0 : require_passthrough.getOptionMatch(parser, item.state, token);
|
|
1732
|
+
});
|
|
1733
|
+
require_passthrough.definePassThroughPriority(resultParser, [parser], (state, token) => {
|
|
1734
|
+
const item = matchingItem(state);
|
|
1735
|
+
return item == null ? void 0 : require_passthrough.getPassThroughPriority(parser, item.state, token);
|
|
1736
|
+
});
|
|
1717
1737
|
return fluent(resultParser);
|
|
1718
1738
|
}
|
|
1719
1739
|
/**
|
|
@@ -1850,6 +1870,8 @@ function nonEmpty(parser) {
|
|
|
1850
1870
|
enumerable: false
|
|
1851
1871
|
});
|
|
1852
1872
|
require_dependency_runtime.defineForwardedEffectfulSchedulingNodes(nonEmptyParser, parser);
|
|
1873
|
+
require_passthrough.defineOptionMatch(nonEmptyParser, (state, token) => require_passthrough.getOptionMatch(parser, state, token));
|
|
1874
|
+
require_passthrough.definePassThroughPriority(nonEmptyParser, [parser], (state, token) => require_passthrough.getPassThroughPriority(parser, state, token));
|
|
1853
1875
|
return fluent(nonEmptyParser);
|
|
1854
1876
|
}
|
|
1855
1877
|
const fluentParserMarker = Symbol.for("@optique/core/fluent");
|
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 { defineKnownCompletionLookup, defineOptionMatch, definePassThroughPriority, getKnownCompletion, getOptionMatch, getPassThroughPriority } from "./internal/passthrough.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,6 +479,9 @@ function optional(parser) {
|
|
|
478
479
|
defineParseLanes(optionalParser, adaptOptionalStyleParseLanes(parser));
|
|
479
480
|
defineInheritedAnnotationParser(optionalParser);
|
|
480
481
|
defineSourceBindingOnlyAnnotationCompletionParser(optionalParser);
|
|
482
|
+
defineOptionMatch(optionalParser, (state, token) => getOptionMatch(parser, normalizeOptionalLikeSuggestState(state, parser.initialState, parser), token));
|
|
483
|
+
definePassThroughPriority(optionalParser, [parser], (state, token) => getPassThroughPriority(parser, normalizeOptionalLikeSuggestState(state, parser.initialState, parser), token));
|
|
484
|
+
defineKnownCompletionLookup(optionalParser, (state) => getKnownCompletion(parser, deriveOptionalInnerParseState(state, parser)));
|
|
481
485
|
return fluent(optionalParser);
|
|
482
486
|
}
|
|
483
487
|
/**
|
|
@@ -729,6 +733,9 @@ function withDefault(parser, defaultValue, options) {
|
|
|
729
733
|
defineParseLanes(withDefaultParser, adaptOptionalStyleParseLanes(parser));
|
|
730
734
|
defineInheritedAnnotationParser(withDefaultParser);
|
|
731
735
|
defineSourceBindingOnlyAnnotationCompletionParser(withDefaultParser);
|
|
736
|
+
defineOptionMatch(withDefaultParser, (state, token) => getOptionMatch(parser, normalizeOptionalLikeSuggestState(state, parser.initialState, parser), token));
|
|
737
|
+
definePassThroughPriority(withDefaultParser, [parser], (state, token) => getPassThroughPriority(parser, normalizeOptionalLikeSuggestState(state, parser.initialState, parser), token));
|
|
738
|
+
defineKnownCompletionLookup(withDefaultParser, (state) => getKnownCompletion(parser, deriveOptionalInnerParseState(state, parser)));
|
|
732
739
|
return fluent(withDefaultParser);
|
|
733
740
|
}
|
|
734
741
|
/**
|
|
@@ -1714,6 +1721,19 @@ function multiple(parser, options = {}) {
|
|
|
1714
1721
|
enumerable: false
|
|
1715
1722
|
});
|
|
1716
1723
|
}
|
|
1724
|
+
const matchingItem = (state) => {
|
|
1725
|
+
const current = state.at(-1);
|
|
1726
|
+
if (current != null && !isTerminalMultipleItemState(current)) return { state: unwrapInjectedWrapper(current) };
|
|
1727
|
+
return state.length < max ? { state: parser.initialState } : void 0;
|
|
1728
|
+
};
|
|
1729
|
+
defineOptionMatch(resultParser, (state, token) => {
|
|
1730
|
+
const item = matchingItem(state);
|
|
1731
|
+
return item == null ? void 0 : getOptionMatch(parser, item.state, token);
|
|
1732
|
+
});
|
|
1733
|
+
definePassThroughPriority(resultParser, [parser], (state, token) => {
|
|
1734
|
+
const item = matchingItem(state);
|
|
1735
|
+
return item == null ? void 0 : getPassThroughPriority(parser, item.state, token);
|
|
1736
|
+
});
|
|
1717
1737
|
return fluent(resultParser);
|
|
1718
1738
|
}
|
|
1719
1739
|
/**
|
|
@@ -1850,6 +1870,8 @@ function nonEmpty(parser) {
|
|
|
1850
1870
|
enumerable: false
|
|
1851
1871
|
});
|
|
1852
1872
|
defineForwardedEffectfulSchedulingNodes(nonEmptyParser, parser);
|
|
1873
|
+
defineOptionMatch(nonEmptyParser, (state, token) => getOptionMatch(parser, state, token));
|
|
1874
|
+
definePassThroughPriority(nonEmptyParser, [parser], (state, token) => getPassThroughPriority(parser, state, token));
|
|
1853
1875
|
return fluent(nonEmptyParser);
|
|
1854
1876
|
}
|
|
1855
1877
|
const fluentParserMarker = Symbol.for("@optique/core/fluent");
|
package/dist/primitives.cjs
CHANGED
|
@@ -6,6 +6,7 @@ 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_passthrough = require('./internal/passthrough.cjs');
|
|
9
10
|
const require_command_alias = require('./internal/command-alias.cjs');
|
|
10
11
|
const require_execution_context = require('./execution-context.cjs');
|
|
11
12
|
const require_phase2_seed = require('./phase2-seed.cjs');
|
|
@@ -151,6 +152,7 @@ function constant(value) {
|
|
|
151
152
|
return { fragments: [] };
|
|
152
153
|
}
|
|
153
154
|
};
|
|
155
|
+
require_passthrough.defineKnownCompletion(result, (state) => require_annotation_state.normalizeInjectedAnnotationState(state));
|
|
154
156
|
Object.defineProperty(result, "placeholder", {
|
|
155
157
|
value,
|
|
156
158
|
configurable: true,
|
|
@@ -590,10 +592,15 @@ function option(...args) {
|
|
|
590
592
|
}
|
|
591
593
|
const invalidOption = context.buffer[0];
|
|
592
594
|
if (options.errors?.noMatch) {
|
|
595
|
+
if (typeof options.errors.noMatch !== "function") return {
|
|
596
|
+
success: false,
|
|
597
|
+
consumed: 0,
|
|
598
|
+
error: options.errors.noMatch
|
|
599
|
+
};
|
|
593
600
|
const candidates = /* @__PURE__ */ new Set();
|
|
594
601
|
for (const name of require_usage.extractOptionNames(context.usage)) candidates.add(name);
|
|
595
602
|
const suggestions = require_suggestion.findSimilar(invalidOption, candidates, require_suggestion.DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
596
|
-
const errorMessage =
|
|
603
|
+
const errorMessage = options.errors.noMatch(invalidOption, suggestions);
|
|
597
604
|
return {
|
|
598
605
|
success: false,
|
|
599
606
|
consumed: 0,
|
|
@@ -878,10 +885,15 @@ function flag(...args) {
|
|
|
878
885
|
}
|
|
879
886
|
const invalidOption = context.buffer[0];
|
|
880
887
|
if (options.errors?.noMatch) {
|
|
888
|
+
if (typeof options.errors.noMatch !== "function") return {
|
|
889
|
+
success: false,
|
|
890
|
+
consumed: 0,
|
|
891
|
+
error: options.errors.noMatch
|
|
892
|
+
};
|
|
881
893
|
const candidates = /* @__PURE__ */ new Set();
|
|
882
894
|
for (const name of require_usage.extractOptionNames(context.usage)) candidates.add(name);
|
|
883
895
|
const suggestions = require_suggestion.findSimilar(invalidOption, candidates, require_suggestion.DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
884
|
-
const errorMessage =
|
|
896
|
+
const errorMessage = options.errors.noMatch(invalidOption, suggestions);
|
|
885
897
|
return {
|
|
886
898
|
success: false,
|
|
887
899
|
consumed: 0,
|
|
@@ -1190,7 +1202,7 @@ function argument(valueParser, options = {}) {
|
|
|
1190
1202
|
const syncValueParser = valueParser;
|
|
1191
1203
|
const dependencyMetadata = require_dependency_metadata.extractDependencyMetadata(valueParser);
|
|
1192
1204
|
const formatInvalidValueError = (error) => options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(error) : options.errors.invalidValue : require_message.message`${require_message.metavar(valueParser.metavar)}: ${error}`;
|
|
1193
|
-
const optionPattern =
|
|
1205
|
+
const optionPattern = /^(?!--=)(--?[a-z0-9-]+)(?:=|$)/i;
|
|
1194
1206
|
const term = {
|
|
1195
1207
|
type: "argument",
|
|
1196
1208
|
metavar: valueParser.metavar,
|
|
@@ -1217,14 +1229,15 @@ function argument(valueParser, options = {}) {
|
|
|
1217
1229
|
};
|
|
1218
1230
|
let i = 0;
|
|
1219
1231
|
let optionsTerminated = context.optionsTerminated;
|
|
1220
|
-
if (!optionsTerminated) {
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1232
|
+
if (!optionsTerminated) if (context.buffer[i] === "--") {
|
|
1233
|
+
optionsTerminated = true;
|
|
1234
|
+
i++;
|
|
1235
|
+
} else {
|
|
1236
|
+
const optionMatch = context.buffer[i].match(optionPattern);
|
|
1237
|
+
if (optionMatch != null) return {
|
|
1225
1238
|
success: false,
|
|
1226
1239
|
consumed: i,
|
|
1227
|
-
error: require_message.message`Expected an argument, but got an option: ${require_message.optionName(
|
|
1240
|
+
error: require_message.message`Expected an argument, but got an option: ${require_message.optionName(optionMatch[1])}.`
|
|
1228
1241
|
};
|
|
1229
1242
|
}
|
|
1230
1243
|
if (context.buffer.length < i + 1) return {
|
|
@@ -1734,6 +1747,22 @@ function command(name, parser, options = {}) {
|
|
|
1734
1747
|
configurable: true,
|
|
1735
1748
|
enumerable: false
|
|
1736
1749
|
});
|
|
1750
|
+
require_passthrough.definePassThroughPriority(result, [parser], (state, token) => {
|
|
1751
|
+
const active = normalizeCommandState(state);
|
|
1752
|
+
if (active == null) return void 0;
|
|
1753
|
+
const childState = active[0] === "matched" ? parser.initialState : active[1];
|
|
1754
|
+
return require_passthrough.getPassThroughPriority(parser, getCommandParseChildState(state, childState, parser), token);
|
|
1755
|
+
});
|
|
1756
|
+
require_passthrough.defineOptionMatch(result, (state, token) => {
|
|
1757
|
+
const active = normalizeCommandState(state);
|
|
1758
|
+
if (active == null) return void 0;
|
|
1759
|
+
const childState = active[0] === "matched" ? parser.initialState : active[1];
|
|
1760
|
+
const match = require_passthrough.getOptionMatch(parser, getCommandParseChildState(state, childState, parser), token);
|
|
1761
|
+
return match == null ? void 0 : {
|
|
1762
|
+
...match,
|
|
1763
|
+
continuesCommand: true
|
|
1764
|
+
};
|
|
1765
|
+
});
|
|
1737
1766
|
return require_modifiers.fluent(result);
|
|
1738
1767
|
}
|
|
1739
1768
|
/**
|
|
@@ -1807,6 +1836,8 @@ function passThrough(options = {}) {
|
|
|
1807
1836
|
consumed: 0,
|
|
1808
1837
|
error: require_message.message`No input to pass through.`
|
|
1809
1838
|
};
|
|
1839
|
+
const failure = require_passthrough.getPassThroughFailure(context, this?.priority ?? -10);
|
|
1840
|
+
if (failure != null) return failure.failure;
|
|
1810
1841
|
const token = context.buffer[0];
|
|
1811
1842
|
if (format === "greedy") {
|
|
1812
1843
|
const captured = [...context.buffer];
|
|
@@ -1918,6 +1949,11 @@ function passThrough(options = {}) {
|
|
|
1918
1949
|
return `passThrough(${format})`;
|
|
1919
1950
|
}
|
|
1920
1951
|
};
|
|
1952
|
+
require_passthrough.definePassThroughPriority(result, [result], (_state, token) => {
|
|
1953
|
+
if (token == null || format === "greedy") return result.priority;
|
|
1954
|
+
const accepts = format === "equalsOnly" ? equalsOptionPattern.test(token) : format === "nextToken" && optionPattern.test(token);
|
|
1955
|
+
return accepts ? result.priority : void 0;
|
|
1956
|
+
});
|
|
1921
1957
|
return require_modifiers.fluent(result);
|
|
1922
1958
|
}
|
|
1923
1959
|
|
package/dist/primitives.js
CHANGED
|
@@ -6,6 +6,7 @@ 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 { defineKnownCompletion, defineOptionMatch, definePassThroughPriority, getOptionMatch, getPassThroughFailure, getPassThroughPriority } from "./internal/passthrough.js";
|
|
9
10
|
import { hiddenCommandAliasesKey } from "./internal/command-alias.js";
|
|
10
11
|
import { mergeChildExec, withChildContext, withChildExecPath } from "./execution-context.js";
|
|
11
12
|
import { completeOrExtractPhase2Seed, extractPhase2SeedKey } from "./phase2-seed.js";
|
|
@@ -151,6 +152,7 @@ function constant(value) {
|
|
|
151
152
|
return { fragments: [] };
|
|
152
153
|
}
|
|
153
154
|
};
|
|
155
|
+
defineKnownCompletion(result, (state) => normalizeInjectedAnnotationState(state));
|
|
154
156
|
Object.defineProperty(result, "placeholder", {
|
|
155
157
|
value,
|
|
156
158
|
configurable: true,
|
|
@@ -590,10 +592,15 @@ function option(...args) {
|
|
|
590
592
|
}
|
|
591
593
|
const invalidOption = context.buffer[0];
|
|
592
594
|
if (options.errors?.noMatch) {
|
|
595
|
+
if (typeof options.errors.noMatch !== "function") return {
|
|
596
|
+
success: false,
|
|
597
|
+
consumed: 0,
|
|
598
|
+
error: options.errors.noMatch
|
|
599
|
+
};
|
|
593
600
|
const candidates = /* @__PURE__ */ new Set();
|
|
594
601
|
for (const name of extractOptionNames(context.usage)) candidates.add(name);
|
|
595
602
|
const suggestions = findSimilar(invalidOption, candidates, DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
596
|
-
const errorMessage =
|
|
603
|
+
const errorMessage = options.errors.noMatch(invalidOption, suggestions);
|
|
597
604
|
return {
|
|
598
605
|
success: false,
|
|
599
606
|
consumed: 0,
|
|
@@ -878,10 +885,15 @@ function flag(...args) {
|
|
|
878
885
|
}
|
|
879
886
|
const invalidOption = context.buffer[0];
|
|
880
887
|
if (options.errors?.noMatch) {
|
|
888
|
+
if (typeof options.errors.noMatch !== "function") return {
|
|
889
|
+
success: false,
|
|
890
|
+
consumed: 0,
|
|
891
|
+
error: options.errors.noMatch
|
|
892
|
+
};
|
|
881
893
|
const candidates = /* @__PURE__ */ new Set();
|
|
882
894
|
for (const name of extractOptionNames(context.usage)) candidates.add(name);
|
|
883
895
|
const suggestions = findSimilar(invalidOption, candidates, DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
884
|
-
const errorMessage =
|
|
896
|
+
const errorMessage = options.errors.noMatch(invalidOption, suggestions);
|
|
885
897
|
return {
|
|
886
898
|
success: false,
|
|
887
899
|
consumed: 0,
|
|
@@ -1190,7 +1202,7 @@ function argument(valueParser, options = {}) {
|
|
|
1190
1202
|
const syncValueParser = valueParser;
|
|
1191
1203
|
const dependencyMetadata = extractDependencyMetadata(valueParser);
|
|
1192
1204
|
const formatInvalidValueError = (error) => options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(error) : options.errors.invalidValue : message`${metavar(valueParser.metavar)}: ${error}`;
|
|
1193
|
-
const optionPattern =
|
|
1205
|
+
const optionPattern = /^(?!--=)(--?[a-z0-9-]+)(?:=|$)/i;
|
|
1194
1206
|
const term = {
|
|
1195
1207
|
type: "argument",
|
|
1196
1208
|
metavar: valueParser.metavar,
|
|
@@ -1217,14 +1229,15 @@ function argument(valueParser, options = {}) {
|
|
|
1217
1229
|
};
|
|
1218
1230
|
let i = 0;
|
|
1219
1231
|
let optionsTerminated = context.optionsTerminated;
|
|
1220
|
-
if (!optionsTerminated) {
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1232
|
+
if (!optionsTerminated) if (context.buffer[i] === "--") {
|
|
1233
|
+
optionsTerminated = true;
|
|
1234
|
+
i++;
|
|
1235
|
+
} else {
|
|
1236
|
+
const optionMatch = context.buffer[i].match(optionPattern);
|
|
1237
|
+
if (optionMatch != null) return {
|
|
1225
1238
|
success: false,
|
|
1226
1239
|
consumed: i,
|
|
1227
|
-
error: message`Expected an argument, but got an option: ${optionName(
|
|
1240
|
+
error: message`Expected an argument, but got an option: ${optionName(optionMatch[1])}.`
|
|
1228
1241
|
};
|
|
1229
1242
|
}
|
|
1230
1243
|
if (context.buffer.length < i + 1) return {
|
|
@@ -1734,6 +1747,22 @@ function command(name, parser, options = {}) {
|
|
|
1734
1747
|
configurable: true,
|
|
1735
1748
|
enumerable: false
|
|
1736
1749
|
});
|
|
1750
|
+
definePassThroughPriority(result, [parser], (state, token) => {
|
|
1751
|
+
const active = normalizeCommandState(state);
|
|
1752
|
+
if (active == null) return void 0;
|
|
1753
|
+
const childState = active[0] === "matched" ? parser.initialState : active[1];
|
|
1754
|
+
return getPassThroughPriority(parser, getCommandParseChildState(state, childState, parser), token);
|
|
1755
|
+
});
|
|
1756
|
+
defineOptionMatch(result, (state, token) => {
|
|
1757
|
+
const active = normalizeCommandState(state);
|
|
1758
|
+
if (active == null) return void 0;
|
|
1759
|
+
const childState = active[0] === "matched" ? parser.initialState : active[1];
|
|
1760
|
+
const match = getOptionMatch(parser, getCommandParseChildState(state, childState, parser), token);
|
|
1761
|
+
return match == null ? void 0 : {
|
|
1762
|
+
...match,
|
|
1763
|
+
continuesCommand: true
|
|
1764
|
+
};
|
|
1765
|
+
});
|
|
1737
1766
|
return fluent(result);
|
|
1738
1767
|
}
|
|
1739
1768
|
/**
|
|
@@ -1807,6 +1836,8 @@ function passThrough(options = {}) {
|
|
|
1807
1836
|
consumed: 0,
|
|
1808
1837
|
error: message`No input to pass through.`
|
|
1809
1838
|
};
|
|
1839
|
+
const failure = getPassThroughFailure(context, this?.priority ?? -10);
|
|
1840
|
+
if (failure != null) return failure.failure;
|
|
1810
1841
|
const token = context.buffer[0];
|
|
1811
1842
|
if (format === "greedy") {
|
|
1812
1843
|
const captured = [...context.buffer];
|
|
@@ -1918,6 +1949,11 @@ function passThrough(options = {}) {
|
|
|
1918
1949
|
return `passThrough(${format})`;
|
|
1919
1950
|
}
|
|
1920
1951
|
};
|
|
1952
|
+
definePassThroughPriority(result, [result], (_state, token) => {
|
|
1953
|
+
if (token == null || format === "greedy") return result.priority;
|
|
1954
|
+
const accepts = format === "equalsOnly" ? equalsOptionPattern.test(token) : format === "nextToken" && optionPattern.test(token);
|
|
1955
|
+
return accepts ? result.priority : void 0;
|
|
1956
|
+
});
|
|
1921
1957
|
return fluent(result);
|
|
1922
1958
|
}
|
|
1923
1959
|
|
package/dist/suggestion.cjs
CHANGED
|
@@ -86,8 +86,10 @@ function findSimilar(input, candidates, options = {}) {
|
|
|
86
86
|
const normalizedCandidate = caseSensitive ? candidate : candidate.toLowerCase();
|
|
87
87
|
if (seen.has(candidate)) continue;
|
|
88
88
|
seen.add(candidate);
|
|
89
|
+
if (normalizedInput === normalizedCandidate) return [candidate];
|
|
90
|
+
const minimumDistance = Math.abs(normalizedInput.length - normalizedCandidate.length);
|
|
91
|
+
if (minimumDistance > maxDistance || minimumDistance / input.length > maxDistanceRatio) continue;
|
|
89
92
|
const distance = levenshteinDistance(normalizedInput, normalizedCandidate);
|
|
90
|
-
if (distance === 0) return [candidate];
|
|
91
93
|
const distanceRatio = distance / input.length;
|
|
92
94
|
if (distance <= maxDistance && distanceRatio <= maxDistanceRatio) matches.push({
|
|
93
95
|
candidate,
|
package/dist/suggestion.js
CHANGED
|
@@ -86,8 +86,10 @@ function findSimilar(input, candidates, options = {}) {
|
|
|
86
86
|
const normalizedCandidate = caseSensitive ? candidate : candidate.toLowerCase();
|
|
87
87
|
if (seen.has(candidate)) continue;
|
|
88
88
|
seen.add(candidate);
|
|
89
|
+
if (normalizedInput === normalizedCandidate) return [candidate];
|
|
90
|
+
const minimumDistance = Math.abs(normalizedInput.length - normalizedCandidate.length);
|
|
91
|
+
if (minimumDistance > maxDistance || minimumDistance / input.length > maxDistanceRatio) continue;
|
|
89
92
|
const distance = levenshteinDistance(normalizedInput, normalizedCandidate);
|
|
90
|
-
if (distance === 0) return [candidate];
|
|
91
93
|
const distanceRatio = distance / input.length;
|
|
92
94
|
if (distance <= maxDistance && distanceRatio <= maxDistanceRatio) matches.push({
|
|
93
95
|
candidate,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const require_displaywidth = require('./displaywidth.cjs');
|
|
2
|
+
const require_terminal_separators = require('./terminal-separators.cjs');
|
|
2
3
|
const require_terminal = require('./terminal.cjs');
|
|
3
4
|
|
|
4
5
|
//#region src/terminal-internal.ts
|
|
@@ -151,6 +152,7 @@ function sameStyle(a, b) {
|
|
|
151
152
|
}
|
|
152
153
|
function* fragmentTokens(fragment, scopes = [], inherited = {}) {
|
|
153
154
|
if (fragment.type === "text") {
|
|
155
|
+
const marks = require_terminal_separators.wrapTrimmableFragments.has(fragment) ? { trimOnWrap: true } : {};
|
|
154
156
|
const lines = fragment.text.split("\n");
|
|
155
157
|
for (let i = 0; i < lines.length; i++) {
|
|
156
158
|
if (i > 0) yield {
|
|
@@ -161,7 +163,8 @@ function* fragmentTokens(fragment, scopes = [], inherited = {}) {
|
|
|
161
163
|
if (lines[i].length > 0 || lines.length === 1) yield {
|
|
162
164
|
text: lines[i],
|
|
163
165
|
width: require_displaywidth.getDisplayWidth(lines[i]),
|
|
164
|
-
scopes
|
|
166
|
+
scopes,
|
|
167
|
+
...marks
|
|
165
168
|
};
|
|
166
169
|
}
|
|
167
170
|
return;
|
|
@@ -16,6 +16,11 @@ interface TerminalToken {
|
|
|
16
16
|
readonly programBoundary?: boolean;
|
|
17
17
|
/** Enables only the legacy default formatter whitespace behavior. */
|
|
18
18
|
readonly legacyWhitespace?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Leading whitespace only separates the token from preceding content, so
|
|
21
|
+
* message wrapping may drop it when the token starts a wrapped line.
|
|
22
|
+
*/
|
|
23
|
+
readonly trimOnWrap?: boolean;
|
|
19
24
|
}
|
|
20
25
|
declare function terminalText(text: string): TerminalFragment;
|
|
21
26
|
declare function formatTerminalTerm(term: TerminalTerm, theme?: TerminalTheme, quotes?: boolean, usage?: TerminalFormatContext["usage"]): TerminalFragment;
|
|
@@ -16,6 +16,11 @@ interface TerminalToken {
|
|
|
16
16
|
readonly programBoundary?: boolean;
|
|
17
17
|
/** Enables only the legacy default formatter whitespace behavior. */
|
|
18
18
|
readonly legacyWhitespace?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Leading whitespace only separates the token from preceding content, so
|
|
21
|
+
* message wrapping may drop it when the token starts a wrapped line.
|
|
22
|
+
*/
|
|
23
|
+
readonly trimOnWrap?: boolean;
|
|
19
24
|
}
|
|
20
25
|
declare function terminalText(text: string): TerminalFragment;
|
|
21
26
|
declare function formatTerminalTerm(term: TerminalTerm, theme?: TerminalTheme, quotes?: boolean, usage?: TerminalFormatContext["usage"]): TerminalFragment;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getDisplayWidth } from "./displaywidth.js";
|
|
2
|
+
import { wrapTrimmableFragments } from "./terminal-separators.js";
|
|
2
3
|
import { defaultTerminalTheme } from "./terminal.js";
|
|
3
4
|
|
|
4
5
|
//#region src/terminal-internal.ts
|
|
@@ -151,6 +152,7 @@ function sameStyle(a, b) {
|
|
|
151
152
|
}
|
|
152
153
|
function* fragmentTokens(fragment, scopes = [], inherited = {}) {
|
|
153
154
|
if (fragment.type === "text") {
|
|
155
|
+
const marks = wrapTrimmableFragments.has(fragment) ? { trimOnWrap: true } : {};
|
|
154
156
|
const lines = fragment.text.split("\n");
|
|
155
157
|
for (let i = 0; i < lines.length; i++) {
|
|
156
158
|
if (i > 0) yield {
|
|
@@ -161,7 +163,8 @@ function* fragmentTokens(fragment, scopes = [], inherited = {}) {
|
|
|
161
163
|
if (lines[i].length > 0 || lines.length === 1) yield {
|
|
162
164
|
text: lines[i],
|
|
163
165
|
width: getDisplayWidth(lines[i]),
|
|
164
|
-
scopes
|
|
166
|
+
scopes,
|
|
167
|
+
...marks
|
|
165
168
|
};
|
|
166
169
|
}
|
|
167
170
|
return;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/terminal-separators.ts
|
|
3
|
+
/**
|
|
4
|
+
* Text fragments that only separate the items around them, such as the
|
|
5
|
+
* spaces the default `values` formatter puts between values. When message
|
|
6
|
+
* wrapping moves such a fragment to the start of a new line, its leading
|
|
7
|
+
* whitespace may be dropped.
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
const wrapTrimmableFragments = /* @__PURE__ */ new WeakSet();
|
|
11
|
+
|
|
12
|
+
//#endregion
|
|
13
|
+
exports.wrapTrimmableFragments = wrapTrimmableFragments;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/terminal-separators.ts
|
|
2
|
+
/**
|
|
3
|
+
* Text fragments that only separate the items around them, such as the
|
|
4
|
+
* spaces the default `values` formatter puts between values. When message
|
|
5
|
+
* wrapping moves such a fragment to the start of a new line, its leading
|
|
6
|
+
* whitespace may be dropped.
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
const wrapTrimmableFragments = /* @__PURE__ */ new WeakSet();
|
|
10
|
+
|
|
11
|
+
//#endregion
|
|
12
|
+
export { wrapTrimmableFragments };
|