@optique/core 1.2.8 → 1.2.10
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/displaywidth.cjs +13 -1
- package/dist/displaywidth.d.cts +10 -1
- package/dist/displaywidth.d.ts +10 -1
- package/dist/displaywidth.js +12 -1
- package/dist/doc.cjs +8 -4
- package/dist/doc.js +8 -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 -6
- package/dist/message.js +33 -7
- 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/package.json +2 -2
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
//#region src/internal/passthrough.ts
|
|
2
|
+
/** Retains the deepest diagnostic and highest matching lane priority. @internal */
|
|
3
|
+
function retainConsumingFailure(current, failure, priority) {
|
|
4
|
+
return {
|
|
5
|
+
failure: current != null && current.failure.consumed >= failure.consumed ? current.failure : failure,
|
|
6
|
+
priority: Math.max(current?.priority ?? -Infinity, priority)
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
const passThroughFailure = Symbol("passThroughFailure");
|
|
10
|
+
/**
|
|
11
|
+
* Gets the sibling failure that prevents pass-through capture at this cursor.
|
|
12
|
+
* Stale hints inherited through a successful child do not block later input.
|
|
13
|
+
* @param context The pass-through parser's context.
|
|
14
|
+
* @returns The failure at this cursor, or undefined if capture is allowed.
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
17
|
+
function getPassThroughFailure(context, capturePriority$1 = -Infinity) {
|
|
18
|
+
const hinted = context;
|
|
19
|
+
const hint = hinted[passThroughFailure];
|
|
20
|
+
return hint?.buffer === context.buffer && hint.optionsTerminated === context.optionsTerminated && hint.failure.priority >= capturePriority$1 ? hint.failure : void 0;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Carries a sibling's consuming failure into a child parse call. Only
|
|
24
|
+
* passThrough consults the hint; ordinary alternatives may still recover.
|
|
25
|
+
* @param context The child context, without modifying the parent's context.
|
|
26
|
+
* @param failure The deepest matching consuming failure at this input position.
|
|
27
|
+
* @returns A context with a hint for active option-like input, or the original.
|
|
28
|
+
* @internal
|
|
29
|
+
*/
|
|
30
|
+
function withPassThroughFailure(context, failure, capturePriority$1 = -Infinity) {
|
|
31
|
+
const token = context.buffer[0];
|
|
32
|
+
const existing = getPassThroughFailure(context);
|
|
33
|
+
if (existing != null && existing.priority < capturePriority$1) {
|
|
34
|
+
const hinted$1 = context;
|
|
35
|
+
const { [passThroughFailure]: _discarded,...rest } = hinted$1;
|
|
36
|
+
context = rest;
|
|
37
|
+
}
|
|
38
|
+
if (failure == null || failure.failure.consumed < 1 || failure.priority < capturePriority$1 || context.optionsTerminated || token == null || token === "--" || !/^[-/+]/.test(token)) return context;
|
|
39
|
+
const retained = getPassThroughFailure(context);
|
|
40
|
+
const combined = retainConsumingFailure(retained, failure.failure, failure.priority);
|
|
41
|
+
const hinted = {
|
|
42
|
+
...context,
|
|
43
|
+
[passThroughFailure]: {
|
|
44
|
+
buffer: context.buffer,
|
|
45
|
+
optionsTerminated: context.optionsTerminated,
|
|
46
|
+
failure: combined
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
return hinted;
|
|
50
|
+
}
|
|
51
|
+
/** Retains a child's rejected option failure only at the parent's cursor. @internal */
|
|
52
|
+
function retainConsumingFailureHint(current, context, next) {
|
|
53
|
+
if (next.buffer !== context.buffer || next.optionsTerminated !== context.optionsTerminated) return current;
|
|
54
|
+
const hint = getPassThroughFailure(next);
|
|
55
|
+
return hint == null ? current : retainConsumingFailure(current, hint.failure, hint.priority);
|
|
56
|
+
}
|
|
57
|
+
const capturePriority = Symbol("capturePriority");
|
|
58
|
+
/** Checks for capture through usage-preserving wrappers. @internal */
|
|
59
|
+
function hasPassThroughUsage(usage) {
|
|
60
|
+
return usage.some((term) => term.type === "passthrough" || (term.type === "optional" || term.type === "multiple") && hasPassThroughUsage(term.terms) || term.type === "exclusive" && term.terms.some(hasPassThroughUsage));
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Gets the priority of reachable capture, respecting an explicit override.
|
|
64
|
+
* @param parser The parser whose capture priority is needed.
|
|
65
|
+
* @param state The current parser state.
|
|
66
|
+
* @param token The current token, omitted for an unfiltered priority lookup.
|
|
67
|
+
* @returns The capture priority, or undefined when capture is absent.
|
|
68
|
+
* @internal
|
|
69
|
+
*/
|
|
70
|
+
function getPassThroughPriority(parser, state = parser.initialState, token) {
|
|
71
|
+
if (!hasPassThroughUsage(parser.usage)) return void 0;
|
|
72
|
+
const annotated = parser;
|
|
73
|
+
const hint = annotated[capturePriority];
|
|
74
|
+
if (hint == null) return parser.priority;
|
|
75
|
+
const priority = hint.getPriority == null ? hint.priority : hint.getPriority(state, token);
|
|
76
|
+
return priority == null ? void 0 : hint.ownerPriority === parser.priority ? priority : parser.priority;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Records capture priority separately from unrelated children's priorities.
|
|
80
|
+
* @param parser The newly constructed parser.
|
|
81
|
+
* @param children Its transparent children.
|
|
82
|
+
* @param getPriority Optional state-aware capture priority lookup.
|
|
83
|
+
* @internal
|
|
84
|
+
*/
|
|
85
|
+
function definePassThroughPriority(parser, children, getPriority) {
|
|
86
|
+
const priorities = children.filter((child) => hasPassThroughUsage(child.usage)).map((child) => getPassThroughPriority(child) ?? child.priority);
|
|
87
|
+
if (priorities.length === 0) return;
|
|
88
|
+
Object.defineProperty(parser, capturePriority, {
|
|
89
|
+
value: {
|
|
90
|
+
ownerPriority: parser.priority,
|
|
91
|
+
priority: Math.max(...priorities),
|
|
92
|
+
getPriority
|
|
93
|
+
},
|
|
94
|
+
enumerable: true
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Copies only a cursor-valid hint when rebuilding a child context.
|
|
99
|
+
* @param context The successful child's context.
|
|
100
|
+
* @returns Private hint properties, or an empty object for stale hints.
|
|
101
|
+
* @internal
|
|
102
|
+
*/
|
|
103
|
+
function getPassThroughFailureHint(context) {
|
|
104
|
+
const hinted = context;
|
|
105
|
+
const hint = hinted[passThroughFailure];
|
|
106
|
+
return hint != null && getPassThroughFailure(context) != null ? { [passThroughFailure]: hint } : {};
|
|
107
|
+
}
|
|
108
|
+
/** Finds a Boolean option through usage-preserving wrappers. */
|
|
109
|
+
function hasFlagUsage(usage, name) {
|
|
110
|
+
return usage.some((term) => term.type === "option" && term.metavar == null && term.names.some((optionName) => optionName === name) || (term.type === "optional" || term.type === "multiple") && hasFlagUsage(term.terms, name) || term.type === "exclusive" && term.terms.some((terms) => hasFlagUsage(terms, name)));
|
|
111
|
+
}
|
|
112
|
+
/** Matches exact options, attached values, and leading bundled flags. */
|
|
113
|
+
function matchesOptionToken(parser, token) {
|
|
114
|
+
if (token == null || token === "--" || !/^[-/+]/.test(token)) return false;
|
|
115
|
+
if (parser.leadingNames.has(token)) return true;
|
|
116
|
+
const slashOption = token.startsWith("/");
|
|
117
|
+
const separator = slashOption ? token.indexOf(":") : token.startsWith("-") ? token.indexOf("=") : -1;
|
|
118
|
+
if (separator > (slashOption ? 0 : 2) && parser.leadingNames.has(token.slice(0, separator))) return true;
|
|
119
|
+
const shortName = token.slice(0, 2);
|
|
120
|
+
return token.length > 2 && /^-[^-]$/.test(shortName) && parser.leadingNames.has(shortName) && hasFlagUsage(parser.usage, shortName);
|
|
121
|
+
}
|
|
122
|
+
const optionMatchKey = Symbol("optionMatch");
|
|
123
|
+
/**
|
|
124
|
+
* Records state-aware option matching without changing public leading names.
|
|
125
|
+
* @param parser The newly constructed transparent parser.
|
|
126
|
+
* @param match Finds a reachable known-option lane.
|
|
127
|
+
* @internal
|
|
128
|
+
*/
|
|
129
|
+
function defineOptionMatch(parser, match) {
|
|
130
|
+
Object.defineProperty(parser, optionMatchKey, {
|
|
131
|
+
value: {
|
|
132
|
+
ownerPriority: parser.priority,
|
|
133
|
+
match
|
|
134
|
+
},
|
|
135
|
+
enumerable: true
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Finds a matching option's actual priority, including selected command children.
|
|
140
|
+
* @param parser The parser to inspect.
|
|
141
|
+
* @param state Its current state.
|
|
142
|
+
* @param token The current token.
|
|
143
|
+
* @returns A reachable option match, or undefined.
|
|
144
|
+
* @internal
|
|
145
|
+
*/
|
|
146
|
+
function getOptionMatch(parser, state, token) {
|
|
147
|
+
if (token == null || token === "--" || !/^[-/+]/.test(token)) return void 0;
|
|
148
|
+
const annotated = parser;
|
|
149
|
+
const matcher = annotated[optionMatchKey];
|
|
150
|
+
if (matcher != null) {
|
|
151
|
+
const match = matcher.match(state, token);
|
|
152
|
+
return match == null || matcher.ownerPriority === parser.priority ? match : {
|
|
153
|
+
...match,
|
|
154
|
+
priority: parser.priority
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
return matchesOptionToken(parser, token) ? {
|
|
158
|
+
priority: parser.priority,
|
|
159
|
+
continuesCommand: false
|
|
160
|
+
} : void 0;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Combines option matches while retaining active command continuation.
|
|
164
|
+
* @param matches Matches from transparent children.
|
|
165
|
+
* @returns Their highest priority and whether any matching command continues.
|
|
166
|
+
* @internal
|
|
167
|
+
*/
|
|
168
|
+
function combineOptionMatches(matches) {
|
|
169
|
+
const found = matches.filter((match) => match != null);
|
|
170
|
+
return found.length === 0 ? void 0 : {
|
|
171
|
+
priority: Math.max(...found.map((match) => match.priority)),
|
|
172
|
+
continuesCommand: found.some((match) => match.continuesCommand)
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
const knownCompletionKey = Symbol("knownCompletion");
|
|
176
|
+
/** Marks a completion value that can be inspected without running user code. @internal */
|
|
177
|
+
function defineKnownCompletion(parser, value) {
|
|
178
|
+
defineKnownCompletionLookup(parser, (state) => ({ value: value(state) }));
|
|
179
|
+
}
|
|
180
|
+
/** Registers a known-value lookup that may decline unknown completion. @internal */
|
|
181
|
+
function defineKnownCompletionLookup(parser, value) {
|
|
182
|
+
Object.defineProperty(parser, knownCompletionKey, {
|
|
183
|
+
value: {
|
|
184
|
+
complete: parser.complete,
|
|
185
|
+
value
|
|
186
|
+
},
|
|
187
|
+
enumerable: true
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
/** Looks up a known value only while the original completion is intact. @internal */
|
|
191
|
+
function getKnownCompletion(parser, state) {
|
|
192
|
+
const annotated = parser;
|
|
193
|
+
const hint = annotated[knownCompletionKey];
|
|
194
|
+
return hint != null && hint.complete === parser.complete ? hint.value(state) : void 0;
|
|
195
|
+
}
|
|
196
|
+
/** Combines the priorities of currently reachable capture lanes. @internal */
|
|
197
|
+
function combinePassThroughPriorities(priorities) {
|
|
198
|
+
const found = priorities.filter((priority) => priority != null);
|
|
199
|
+
return found.length === 0 ? void 0 : Math.max(...found);
|
|
200
|
+
}
|
|
201
|
+
/** Forwards known completion through a state-preserving wrapper. @internal */
|
|
202
|
+
function delegateKnownCompletion(wrapper, inner) {
|
|
203
|
+
Object.defineProperty(wrapper, knownCompletionKey, {
|
|
204
|
+
value: {
|
|
205
|
+
complete: wrapper.complete,
|
|
206
|
+
value: (state) => getKnownCompletion(inner, state)
|
|
207
|
+
},
|
|
208
|
+
enumerable: true
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
//#endregion
|
|
213
|
+
export { combineOptionMatches, combinePassThroughPriorities, defineKnownCompletion, defineKnownCompletionLookup, defineOptionMatch, definePassThroughPriority, delegateKnownCompletion, getKnownCompletion, getOptionMatch, getPassThroughFailure, getPassThroughFailureHint, getPassThroughPriority, hasPassThroughUsage, matchesOptionToken, retainConsumingFailure, retainConsumingFailureHint, withPassThroughFailure };
|
package/dist/message.cjs
CHANGED
|
@@ -324,7 +324,8 @@ function formatMessage(msg, options = {}) {
|
|
|
324
324
|
if (match == null) break;
|
|
325
325
|
yield {
|
|
326
326
|
text: match[0],
|
|
327
|
-
width: require_displaywidth.getDisplayWidth(match[0])
|
|
327
|
+
width: require_displaywidth.getDisplayWidth(match[0]),
|
|
328
|
+
trimOnWrap: true
|
|
328
329
|
};
|
|
329
330
|
}
|
|
330
331
|
}
|
|
@@ -332,7 +333,8 @@ function formatMessage(msg, options = {}) {
|
|
|
332
333
|
const normalizedText = rawText.replace(/\n/g, " ");
|
|
333
334
|
if (normalizedText.trim() === "" && normalizedText.length > 0) yield {
|
|
334
335
|
text: " ",
|
|
335
|
-
width: 1
|
|
336
|
+
width: 1,
|
|
337
|
+
trimOnWrap: true
|
|
336
338
|
};
|
|
337
339
|
else {
|
|
338
340
|
wordPattern.lastIndex = 0;
|
|
@@ -341,7 +343,8 @@ function formatMessage(msg, options = {}) {
|
|
|
341
343
|
if (match == null) break;
|
|
342
344
|
yield {
|
|
343
345
|
text: match[0],
|
|
344
|
-
width: require_displaywidth.getDisplayWidth(match[0])
|
|
346
|
+
width: require_displaywidth.getDisplayWidth(match[0]),
|
|
347
|
+
trimOnWrap: true
|
|
345
348
|
};
|
|
346
349
|
}
|
|
347
350
|
}
|
|
@@ -381,7 +384,8 @@ function formatMessage(msg, options = {}) {
|
|
|
381
384
|
} else if (term.type === "values") for (let i = 0; i < term.values.length; i++) {
|
|
382
385
|
if (i > 0) yield {
|
|
383
386
|
text: " ",
|
|
384
|
-
width: 1
|
|
387
|
+
width: 1,
|
|
388
|
+
trimOnWrap: true
|
|
385
389
|
};
|
|
386
390
|
const value$1 = useQuotes ? JSON.stringify(term.values[i]) : term.values[i];
|
|
387
391
|
yield {
|
|
@@ -425,18 +429,40 @@ function formatMessage(msg, options = {}) {
|
|
|
425
429
|
}
|
|
426
430
|
let output = "";
|
|
427
431
|
let totalWidth = options.startWidth ?? 0;
|
|
428
|
-
|
|
432
|
+
let pendingWrap = false;
|
|
433
|
+
let atWrappedLineStart = false;
|
|
434
|
+
for (const token of stream()) {
|
|
435
|
+
let { text: text$1, width } = token;
|
|
429
436
|
if (width === -1) {
|
|
430
437
|
output += text$1;
|
|
431
438
|
totalWidth = 0;
|
|
439
|
+
pendingWrap = false;
|
|
440
|
+
atWrappedLineStart = false;
|
|
441
|
+
continue;
|
|
442
|
+
}
|
|
443
|
+
const wraps = pendingWrap || options.maxWidth != null && totalWidth > 0 && totalWidth + width > options.maxWidth;
|
|
444
|
+
if ((wraps || atWrappedLineStart) && token.trimOnWrap) {
|
|
445
|
+
const trimmed = text$1.trimStart();
|
|
446
|
+
width -= require_displaywidth.getDisplayWidth(text$1.slice(0, text$1.length - trimmed.length));
|
|
447
|
+
text$1 = trimmed;
|
|
448
|
+
if (text$1 === "") {
|
|
449
|
+
if (wraps) pendingWrap = true;
|
|
450
|
+
continue;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
if (pendingWrap && require_displaywidth.stripAnsi(text$1) === "") {
|
|
454
|
+
output += text$1;
|
|
432
455
|
continue;
|
|
433
456
|
}
|
|
434
|
-
if (
|
|
457
|
+
if (wraps) {
|
|
435
458
|
output += "\n";
|
|
436
459
|
totalWidth = 0;
|
|
460
|
+
pendingWrap = false;
|
|
461
|
+
atWrappedLineStart = true;
|
|
437
462
|
}
|
|
438
463
|
output += text$1;
|
|
439
464
|
totalWidth += width;
|
|
465
|
+
if (width > 0) atWrappedLineStart = false;
|
|
440
466
|
}
|
|
441
467
|
return output;
|
|
442
468
|
}
|
package/dist/message.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getDisplayWidth } from "./displaywidth.js";
|
|
1
|
+
import { getDisplayWidth, stripAnsi } from "./displaywidth.js";
|
|
2
2
|
|
|
3
3
|
//#region src/message.ts
|
|
4
4
|
/**
|
|
@@ -324,7 +324,8 @@ function formatMessage(msg, options = {}) {
|
|
|
324
324
|
if (match == null) break;
|
|
325
325
|
yield {
|
|
326
326
|
text: match[0],
|
|
327
|
-
width: getDisplayWidth(match[0])
|
|
327
|
+
width: getDisplayWidth(match[0]),
|
|
328
|
+
trimOnWrap: true
|
|
328
329
|
};
|
|
329
330
|
}
|
|
330
331
|
}
|
|
@@ -332,7 +333,8 @@ function formatMessage(msg, options = {}) {
|
|
|
332
333
|
const normalizedText = rawText.replace(/\n/g, " ");
|
|
333
334
|
if (normalizedText.trim() === "" && normalizedText.length > 0) yield {
|
|
334
335
|
text: " ",
|
|
335
|
-
width: 1
|
|
336
|
+
width: 1,
|
|
337
|
+
trimOnWrap: true
|
|
336
338
|
};
|
|
337
339
|
else {
|
|
338
340
|
wordPattern.lastIndex = 0;
|
|
@@ -341,7 +343,8 @@ function formatMessage(msg, options = {}) {
|
|
|
341
343
|
if (match == null) break;
|
|
342
344
|
yield {
|
|
343
345
|
text: match[0],
|
|
344
|
-
width: getDisplayWidth(match[0])
|
|
346
|
+
width: getDisplayWidth(match[0]),
|
|
347
|
+
trimOnWrap: true
|
|
345
348
|
};
|
|
346
349
|
}
|
|
347
350
|
}
|
|
@@ -381,7 +384,8 @@ function formatMessage(msg, options = {}) {
|
|
|
381
384
|
} else if (term.type === "values") for (let i = 0; i < term.values.length; i++) {
|
|
382
385
|
if (i > 0) yield {
|
|
383
386
|
text: " ",
|
|
384
|
-
width: 1
|
|
387
|
+
width: 1,
|
|
388
|
+
trimOnWrap: true
|
|
385
389
|
};
|
|
386
390
|
const value$1 = useQuotes ? JSON.stringify(term.values[i]) : term.values[i];
|
|
387
391
|
yield {
|
|
@@ -425,18 +429,40 @@ function formatMessage(msg, options = {}) {
|
|
|
425
429
|
}
|
|
426
430
|
let output = "";
|
|
427
431
|
let totalWidth = options.startWidth ?? 0;
|
|
428
|
-
|
|
432
|
+
let pendingWrap = false;
|
|
433
|
+
let atWrappedLineStart = false;
|
|
434
|
+
for (const token of stream()) {
|
|
435
|
+
let { text: text$1, width } = token;
|
|
429
436
|
if (width === -1) {
|
|
430
437
|
output += text$1;
|
|
431
438
|
totalWidth = 0;
|
|
439
|
+
pendingWrap = false;
|
|
440
|
+
atWrappedLineStart = false;
|
|
441
|
+
continue;
|
|
442
|
+
}
|
|
443
|
+
const wraps = pendingWrap || options.maxWidth != null && totalWidth > 0 && totalWidth + width > options.maxWidth;
|
|
444
|
+
if ((wraps || atWrappedLineStart) && token.trimOnWrap) {
|
|
445
|
+
const trimmed = text$1.trimStart();
|
|
446
|
+
width -= getDisplayWidth(text$1.slice(0, text$1.length - trimmed.length));
|
|
447
|
+
text$1 = trimmed;
|
|
448
|
+
if (text$1 === "") {
|
|
449
|
+
if (wraps) pendingWrap = true;
|
|
450
|
+
continue;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
if (pendingWrap && stripAnsi(text$1) === "") {
|
|
454
|
+
output += text$1;
|
|
432
455
|
continue;
|
|
433
456
|
}
|
|
434
|
-
if (
|
|
457
|
+
if (wraps) {
|
|
435
458
|
output += "\n";
|
|
436
459
|
totalWidth = 0;
|
|
460
|
+
pendingWrap = false;
|
|
461
|
+
atWrappedLineStart = true;
|
|
437
462
|
}
|
|
438
463
|
output += text$1;
|
|
439
464
|
totalWidth += width;
|
|
465
|
+
if (width > 0) atWrappedLineStart = false;
|
|
440
466
|
}
|
|
441
467
|
return output;
|
|
442
468
|
}
|
package/dist/modifiers.cjs
CHANGED
|
@@ -3,6 +3,7 @@ const require_message = require('./message.cjs');
|
|
|
3
3
|
const require_mode_dispatch = require('./internal/mode-dispatch.cjs');
|
|
4
4
|
const require_internal_parser = require('./internal/parser.cjs');
|
|
5
5
|
const require_annotation_state = require('./annotation-state.cjs');
|
|
6
|
+
const require_passthrough = require('./internal/passthrough.cjs');
|
|
6
7
|
const require_execution_context = require('./execution-context.cjs');
|
|
7
8
|
const require_phase2_seed = require('./phase2-seed.cjs');
|
|
8
9
|
const require_dependency_metadata = require('./dependency-metadata.cjs');
|
|
@@ -461,6 +462,9 @@ function optional(parser) {
|
|
|
461
462
|
require_internal_parser.defineParseLanes(optionalParser, adaptOptionalStyleParseLanes(parser));
|
|
462
463
|
require_internal_parser.defineInheritedAnnotationParser(optionalParser);
|
|
463
464
|
require_internal_parser.defineSourceBindingOnlyAnnotationCompletionParser(optionalParser);
|
|
465
|
+
require_passthrough.defineOptionMatch(optionalParser, (state, token) => require_passthrough.getOptionMatch(parser, normalizeOptionalLikeSuggestState(state, parser.initialState, parser), token));
|
|
466
|
+
require_passthrough.definePassThroughPriority(optionalParser, [parser], (state, token) => require_passthrough.getPassThroughPriority(parser, normalizeOptionalLikeSuggestState(state, parser.initialState, parser), token));
|
|
467
|
+
require_passthrough.defineKnownCompletionLookup(optionalParser, (state) => require_passthrough.getKnownCompletion(parser, deriveOptionalInnerParseState(state, parser)));
|
|
464
468
|
return fluent(optionalParser);
|
|
465
469
|
}
|
|
466
470
|
/**
|
|
@@ -696,6 +700,9 @@ function withDefault(parser, defaultValue, options) {
|
|
|
696
700
|
require_internal_parser.defineParseLanes(withDefaultParser, adaptOptionalStyleParseLanes(parser));
|
|
697
701
|
require_internal_parser.defineInheritedAnnotationParser(withDefaultParser);
|
|
698
702
|
require_internal_parser.defineSourceBindingOnlyAnnotationCompletionParser(withDefaultParser);
|
|
703
|
+
require_passthrough.defineOptionMatch(withDefaultParser, (state, token) => require_passthrough.getOptionMatch(parser, normalizeOptionalLikeSuggestState(state, parser.initialState, parser), token));
|
|
704
|
+
require_passthrough.definePassThroughPriority(withDefaultParser, [parser], (state, token) => require_passthrough.getPassThroughPriority(parser, normalizeOptionalLikeSuggestState(state, parser.initialState, parser), token));
|
|
705
|
+
require_passthrough.defineKnownCompletionLookup(withDefaultParser, (state) => require_passthrough.getKnownCompletion(parser, deriveOptionalInnerParseState(state, parser)));
|
|
699
706
|
return fluent(withDefaultParser);
|
|
700
707
|
}
|
|
701
708
|
/**
|
|
@@ -1679,6 +1686,19 @@ function multiple(parser, options = {}) {
|
|
|
1679
1686
|
enumerable: false
|
|
1680
1687
|
});
|
|
1681
1688
|
}
|
|
1689
|
+
const matchingItem = (state) => {
|
|
1690
|
+
const current = state.at(-1);
|
|
1691
|
+
if (current != null && !isTerminalMultipleItemState(current)) return { state: unwrapInjectedWrapper(current) };
|
|
1692
|
+
return state.length < max ? { state: parser.initialState } : void 0;
|
|
1693
|
+
};
|
|
1694
|
+
require_passthrough.defineOptionMatch(resultParser, (state, token) => {
|
|
1695
|
+
const item = matchingItem(state);
|
|
1696
|
+
return item == null ? void 0 : require_passthrough.getOptionMatch(parser, item.state, token);
|
|
1697
|
+
});
|
|
1698
|
+
require_passthrough.definePassThroughPriority(resultParser, [parser], (state, token) => {
|
|
1699
|
+
const item = matchingItem(state);
|
|
1700
|
+
return item == null ? void 0 : require_passthrough.getPassThroughPriority(parser, item.state, token);
|
|
1701
|
+
});
|
|
1682
1702
|
return fluent(resultParser);
|
|
1683
1703
|
}
|
|
1684
1704
|
/**
|
|
@@ -1809,6 +1829,8 @@ function nonEmpty(parser) {
|
|
|
1809
1829
|
configurable: true,
|
|
1810
1830
|
enumerable: false
|
|
1811
1831
|
});
|
|
1832
|
+
require_passthrough.defineOptionMatch(nonEmptyParser, (state, token) => require_passthrough.getOptionMatch(parser, state, token));
|
|
1833
|
+
require_passthrough.definePassThroughPriority(nonEmptyParser, [parser], (state, token) => require_passthrough.getPassThroughPriority(parser, state, token));
|
|
1812
1834
|
return fluent(nonEmptyParser);
|
|
1813
1835
|
}
|
|
1814
1836
|
const fluentParserMarker = Symbol.for("@optique/core/fluent");
|
package/dist/modifiers.js
CHANGED
|
@@ -3,6 +3,7 @@ import { formatMessage, message, text } from "./message.js";
|
|
|
3
3
|
import { dispatchByMode, dispatchIterableByMode, mapModeValue, wrapForMode } from "./internal/mode-dispatch.js";
|
|
4
4
|
import { defineInheritedAnnotationParser, defineParseLanes, defineSourceBindingOnlyAnnotationCompletionParser, getOwnParseLanes, unmatchedNonCliDependencySourceStateMarker } from "./internal/parser.js";
|
|
5
5
|
import { getDelegatedAnnotationState, hasDelegatedAnnotationCarrier, isAnnotationWrappedInitialState, normalizeDelegatedAnnotationState, normalizeNestedDelegatedAnnotationState } from "./annotation-state.js";
|
|
6
|
+
import { defineKnownCompletionLookup, defineOptionMatch, definePassThroughPriority, getKnownCompletion, getOptionMatch, getPassThroughPriority } from "./internal/passthrough.js";
|
|
6
7
|
import { mergeChildExec, withChildContext, withChildExecPath } from "./execution-context.js";
|
|
7
8
|
import { completeOrExtractPhase2Seed, extractPhase2Seed, extractPhase2SeedKey, phase2SeedFromValueResult } from "./phase2-seed.js";
|
|
8
9
|
import { composeDependencyMetadata } from "./dependency-metadata.js";
|
|
@@ -461,6 +462,9 @@ function optional(parser) {
|
|
|
461
462
|
defineParseLanes(optionalParser, adaptOptionalStyleParseLanes(parser));
|
|
462
463
|
defineInheritedAnnotationParser(optionalParser);
|
|
463
464
|
defineSourceBindingOnlyAnnotationCompletionParser(optionalParser);
|
|
465
|
+
defineOptionMatch(optionalParser, (state, token) => getOptionMatch(parser, normalizeOptionalLikeSuggestState(state, parser.initialState, parser), token));
|
|
466
|
+
definePassThroughPriority(optionalParser, [parser], (state, token) => getPassThroughPriority(parser, normalizeOptionalLikeSuggestState(state, parser.initialState, parser), token));
|
|
467
|
+
defineKnownCompletionLookup(optionalParser, (state) => getKnownCompletion(parser, deriveOptionalInnerParseState(state, parser)));
|
|
464
468
|
return fluent(optionalParser);
|
|
465
469
|
}
|
|
466
470
|
/**
|
|
@@ -696,6 +700,9 @@ function withDefault(parser, defaultValue, options) {
|
|
|
696
700
|
defineParseLanes(withDefaultParser, adaptOptionalStyleParseLanes(parser));
|
|
697
701
|
defineInheritedAnnotationParser(withDefaultParser);
|
|
698
702
|
defineSourceBindingOnlyAnnotationCompletionParser(withDefaultParser);
|
|
703
|
+
defineOptionMatch(withDefaultParser, (state, token) => getOptionMatch(parser, normalizeOptionalLikeSuggestState(state, parser.initialState, parser), token));
|
|
704
|
+
definePassThroughPriority(withDefaultParser, [parser], (state, token) => getPassThroughPriority(parser, normalizeOptionalLikeSuggestState(state, parser.initialState, parser), token));
|
|
705
|
+
defineKnownCompletionLookup(withDefaultParser, (state) => getKnownCompletion(parser, deriveOptionalInnerParseState(state, parser)));
|
|
699
706
|
return fluent(withDefaultParser);
|
|
700
707
|
}
|
|
701
708
|
/**
|
|
@@ -1679,6 +1686,19 @@ function multiple(parser, options = {}) {
|
|
|
1679
1686
|
enumerable: false
|
|
1680
1687
|
});
|
|
1681
1688
|
}
|
|
1689
|
+
const matchingItem = (state) => {
|
|
1690
|
+
const current = state.at(-1);
|
|
1691
|
+
if (current != null && !isTerminalMultipleItemState(current)) return { state: unwrapInjectedWrapper(current) };
|
|
1692
|
+
return state.length < max ? { state: parser.initialState } : void 0;
|
|
1693
|
+
};
|
|
1694
|
+
defineOptionMatch(resultParser, (state, token) => {
|
|
1695
|
+
const item = matchingItem(state);
|
|
1696
|
+
return item == null ? void 0 : getOptionMatch(parser, item.state, token);
|
|
1697
|
+
});
|
|
1698
|
+
definePassThroughPriority(resultParser, [parser], (state, token) => {
|
|
1699
|
+
const item = matchingItem(state);
|
|
1700
|
+
return item == null ? void 0 : getPassThroughPriority(parser, item.state, token);
|
|
1701
|
+
});
|
|
1682
1702
|
return fluent(resultParser);
|
|
1683
1703
|
}
|
|
1684
1704
|
/**
|
|
@@ -1809,6 +1829,8 @@ function nonEmpty(parser) {
|
|
|
1809
1829
|
configurable: true,
|
|
1810
1830
|
enumerable: false
|
|
1811
1831
|
});
|
|
1832
|
+
defineOptionMatch(nonEmptyParser, (state, token) => getOptionMatch(parser, state, token));
|
|
1833
|
+
definePassThroughPriority(nonEmptyParser, [parser], (state, token) => getPassThroughPriority(parser, state, token));
|
|
1812
1834
|
return fluent(nonEmptyParser);
|
|
1813
1835
|
}
|
|
1814
1836
|
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');
|
|
@@ -145,6 +146,7 @@ function constant(value) {
|
|
|
145
146
|
return { fragments: [] };
|
|
146
147
|
}
|
|
147
148
|
};
|
|
149
|
+
require_passthrough.defineKnownCompletion(result, (state) => require_annotation_state.normalizeInjectedAnnotationState(state));
|
|
148
150
|
Object.defineProperty(result, "placeholder", {
|
|
149
151
|
value,
|
|
150
152
|
configurable: true,
|
|
@@ -584,10 +586,15 @@ function option(...args) {
|
|
|
584
586
|
}
|
|
585
587
|
const invalidOption = context.buffer[0];
|
|
586
588
|
if (options.errors?.noMatch) {
|
|
589
|
+
if (typeof options.errors.noMatch !== "function") return {
|
|
590
|
+
success: false,
|
|
591
|
+
consumed: 0,
|
|
592
|
+
error: options.errors.noMatch
|
|
593
|
+
};
|
|
587
594
|
const candidates = /* @__PURE__ */ new Set();
|
|
588
595
|
for (const name of require_usage.extractOptionNames(context.usage)) candidates.add(name);
|
|
589
596
|
const suggestions = require_suggestion.findSimilar(invalidOption, candidates, require_suggestion.DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
590
|
-
const errorMessage =
|
|
597
|
+
const errorMessage = options.errors.noMatch(invalidOption, suggestions);
|
|
591
598
|
return {
|
|
592
599
|
success: false,
|
|
593
600
|
consumed: 0,
|
|
@@ -872,10 +879,15 @@ function flag(...args) {
|
|
|
872
879
|
}
|
|
873
880
|
const invalidOption = context.buffer[0];
|
|
874
881
|
if (options.errors?.noMatch) {
|
|
882
|
+
if (typeof options.errors.noMatch !== "function") return {
|
|
883
|
+
success: false,
|
|
884
|
+
consumed: 0,
|
|
885
|
+
error: options.errors.noMatch
|
|
886
|
+
};
|
|
875
887
|
const candidates = /* @__PURE__ */ new Set();
|
|
876
888
|
for (const name of require_usage.extractOptionNames(context.usage)) candidates.add(name);
|
|
877
889
|
const suggestions = require_suggestion.findSimilar(invalidOption, candidates, require_suggestion.DEFAULT_FIND_SIMILAR_OPTIONS);
|
|
878
|
-
const errorMessage =
|
|
890
|
+
const errorMessage = options.errors.noMatch(invalidOption, suggestions);
|
|
879
891
|
return {
|
|
880
892
|
success: false,
|
|
881
893
|
consumed: 0,
|
|
@@ -1184,7 +1196,7 @@ function argument(valueParser, options = {}) {
|
|
|
1184
1196
|
const syncValueParser = valueParser;
|
|
1185
1197
|
const dependencyMetadata = require_dependency_metadata.extractDependencyMetadata(valueParser);
|
|
1186
1198
|
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}`;
|
|
1187
|
-
const optionPattern =
|
|
1199
|
+
const optionPattern = /^(?!--=)(--?[a-z0-9-]+)(?:=|$)/i;
|
|
1188
1200
|
const term = {
|
|
1189
1201
|
type: "argument",
|
|
1190
1202
|
metavar: valueParser.metavar,
|
|
@@ -1211,14 +1223,15 @@ function argument(valueParser, options = {}) {
|
|
|
1211
1223
|
};
|
|
1212
1224
|
let i = 0;
|
|
1213
1225
|
let optionsTerminated = context.optionsTerminated;
|
|
1214
|
-
if (!optionsTerminated) {
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1226
|
+
if (!optionsTerminated) if (context.buffer[i] === "--") {
|
|
1227
|
+
optionsTerminated = true;
|
|
1228
|
+
i++;
|
|
1229
|
+
} else {
|
|
1230
|
+
const optionMatch = context.buffer[i].match(optionPattern);
|
|
1231
|
+
if (optionMatch != null) return {
|
|
1219
1232
|
success: false,
|
|
1220
1233
|
consumed: i,
|
|
1221
|
-
error: require_message.message`Expected an argument, but got an option: ${require_message.optionName(
|
|
1234
|
+
error: require_message.message`Expected an argument, but got an option: ${require_message.optionName(optionMatch[1])}.`
|
|
1222
1235
|
};
|
|
1223
1236
|
}
|
|
1224
1237
|
if (context.buffer.length < i + 1) return {
|
|
@@ -1704,6 +1717,22 @@ function command(name, parser, options = {}) {
|
|
|
1704
1717
|
configurable: true,
|
|
1705
1718
|
enumerable: false
|
|
1706
1719
|
});
|
|
1720
|
+
require_passthrough.definePassThroughPriority(result, [parser], (state, token) => {
|
|
1721
|
+
const active = normalizeCommandState(state);
|
|
1722
|
+
if (active == null) return void 0;
|
|
1723
|
+
const childState = active[0] === "matched" ? parser.initialState : active[1];
|
|
1724
|
+
return require_passthrough.getPassThroughPriority(parser, getCommandParseChildState(state, childState, parser), token);
|
|
1725
|
+
});
|
|
1726
|
+
require_passthrough.defineOptionMatch(result, (state, token) => {
|
|
1727
|
+
const active = normalizeCommandState(state);
|
|
1728
|
+
if (active == null) return void 0;
|
|
1729
|
+
const childState = active[0] === "matched" ? parser.initialState : active[1];
|
|
1730
|
+
const match = require_passthrough.getOptionMatch(parser, getCommandParseChildState(state, childState, parser), token);
|
|
1731
|
+
return match == null ? void 0 : {
|
|
1732
|
+
...match,
|
|
1733
|
+
continuesCommand: true
|
|
1734
|
+
};
|
|
1735
|
+
});
|
|
1707
1736
|
return require_modifiers.fluent(result);
|
|
1708
1737
|
}
|
|
1709
1738
|
/**
|
|
@@ -1777,6 +1806,8 @@ function passThrough(options = {}) {
|
|
|
1777
1806
|
consumed: 0,
|
|
1778
1807
|
error: require_message.message`No input to pass through.`
|
|
1779
1808
|
};
|
|
1809
|
+
const failure = require_passthrough.getPassThroughFailure(context, this?.priority ?? -10);
|
|
1810
|
+
if (failure != null) return failure.failure;
|
|
1780
1811
|
const token = context.buffer[0];
|
|
1781
1812
|
if (format === "greedy") {
|
|
1782
1813
|
const captured = [...context.buffer];
|
|
@@ -1888,6 +1919,11 @@ function passThrough(options = {}) {
|
|
|
1888
1919
|
return `passThrough(${format})`;
|
|
1889
1920
|
}
|
|
1890
1921
|
};
|
|
1922
|
+
require_passthrough.definePassThroughPriority(result, [result], (_state, token) => {
|
|
1923
|
+
if (token == null || format === "greedy") return result.priority;
|
|
1924
|
+
const accepts = format === "equalsOnly" ? equalsOptionPattern.test(token) : format === "nextToken" && optionPattern.test(token);
|
|
1925
|
+
return accepts ? result.priority : void 0;
|
|
1926
|
+
});
|
|
1891
1927
|
return require_modifiers.fluent(result);
|
|
1892
1928
|
}
|
|
1893
1929
|
|