@optique/core 1.3.0-dev.2524 → 1.3.0-dev.2530
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/doc.cjs +93 -84
- package/dist/doc.d.cts +12 -1
- package/dist/doc.d.ts +12 -1
- package/dist/doc.js +88 -79
- package/dist/facade.cjs +49 -15
- package/dist/facade.d.cts +12 -1
- package/dist/facade.d.ts +12 -1
- package/dist/facade.js +48 -14
- package/dist/index.cjs +3 -0
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/dist/internal/terminal.cjs +7 -0
- package/dist/internal/terminal.d.cts +4 -0
- package/dist/internal/terminal.d.ts +4 -0
- package/dist/internal/terminal.js +5 -0
- package/dist/message-registry.cjs +6 -0
- package/dist/message-registry.d.cts +7 -0
- package/dist/message-registry.d.ts +7 -0
- package/dist/message-registry.js +5 -0
- package/dist/message-renderer.cjs +26 -0
- package/dist/message-renderer.d.cts +19 -0
- package/dist/message-renderer.d.ts +19 -0
- package/dist/message-renderer.js +26 -0
- package/dist/message.cjs +49 -85
- package/dist/message.d.cts +31 -1
- package/dist/message.d.ts +31 -1
- package/dist/message.js +49 -86
- package/dist/terminal-internal.cjs +259 -0
- package/dist/terminal-internal.d.cts +36 -0
- package/dist/terminal-internal.d.ts +36 -0
- package/dist/terminal-internal.js +253 -0
- package/dist/terminal.cjs +74 -0
- package/dist/terminal.d.cts +129 -0
- package/dist/terminal.d.ts +129 -0
- package/dist/terminal.js +73 -0
- package/dist/usage.cjs +108 -134
- package/dist/usage.d.cts +6 -0
- package/dist/usage.d.ts +6 -0
- package/dist/usage.js +108 -134
- package/package.json +18 -2
- package/skills/optique/SKILL.md +3 -3
package/dist/usage.cjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const require_displaywidth = require('./displaywidth.cjs');
|
|
2
|
+
const require_terminal_internal = require('./terminal-internal.cjs');
|
|
2
3
|
const require_validate = require('./validate.cjs');
|
|
3
4
|
|
|
4
5
|
//#region src/usage.ts
|
|
@@ -182,6 +183,10 @@ function extractArgumentMetavars(usage) {
|
|
|
182
183
|
* whitespace-only, or contains control characters.
|
|
183
184
|
*/
|
|
184
185
|
function formatUsage(programName, usage, options = {}) {
|
|
186
|
+
options = {
|
|
187
|
+
...options,
|
|
188
|
+
theme: require_terminal_internal.cacheTerminalTheme(options.theme)
|
|
189
|
+
};
|
|
185
190
|
require_validate.validateProgramName(programName);
|
|
186
191
|
usage = normalizeUsage(filterUsageForDisplay(usage));
|
|
187
192
|
if (options.expandCommands) {
|
|
@@ -197,29 +202,23 @@ function formatUsage(programName, usage, options = {}) {
|
|
|
197
202
|
if (lines.length > 0) return lines.join("\n");
|
|
198
203
|
}
|
|
199
204
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
if (text === " ") continue;
|
|
218
|
-
}
|
|
219
|
-
output += text;
|
|
220
|
-
lineWidth += width;
|
|
221
|
-
}
|
|
222
|
-
return output;
|
|
205
|
+
const programTokens = layoutUsageTokens(require_terminal_internal.fragmentTokens(require_terminal_internal.formatTerminalTerm({
|
|
206
|
+
type: "programName",
|
|
207
|
+
programName
|
|
208
|
+
}, options.theme)), options);
|
|
209
|
+
const terms = [...formatUsageTerms(usage, options)];
|
|
210
|
+
if (terms.length === 0) return require_terminal_internal.serializeTokens(programTokens, options.colors);
|
|
211
|
+
const width = programTokens.reduce((n, token) => token.width === -1 ? 0 : n + token.width, 0);
|
|
212
|
+
const separator = options.maxWidth != null && width + 1 + terms[0].width > options.maxWidth ? {
|
|
213
|
+
text: "\n",
|
|
214
|
+
width: -1,
|
|
215
|
+
scopes: []
|
|
216
|
+
} : {
|
|
217
|
+
text: " ",
|
|
218
|
+
width: 1,
|
|
219
|
+
scopes: []
|
|
220
|
+
};
|
|
221
|
+
return require_terminal_internal.serializeTokens([...programTokens, separator], options.colors) + wrapUsageTokens(terms, options, separator.width === -1 ? 0 : width + 1);
|
|
223
222
|
}
|
|
224
223
|
/**
|
|
225
224
|
* Normalizes a usage description by flattening nested exclusive terms,
|
|
@@ -454,7 +453,8 @@ function* formatUsageTerms(terms, options) {
|
|
|
454
453
|
for (const t of terms) {
|
|
455
454
|
if (i > 0) yield {
|
|
456
455
|
text: " ",
|
|
457
|
-
width: 1
|
|
456
|
+
width: 1,
|
|
457
|
+
scopes: []
|
|
458
458
|
};
|
|
459
459
|
yield* formatUsageTermInternal(t, options);
|
|
460
460
|
i++;
|
|
@@ -470,139 +470,113 @@ function* formatUsageTerms(terms, options) {
|
|
|
470
470
|
* @returns A formatted string representation of the usage term.
|
|
471
471
|
*/
|
|
472
472
|
function formatUsageTerm(term, options = {}) {
|
|
473
|
+
options = {
|
|
474
|
+
...options,
|
|
475
|
+
theme: require_terminal_internal.cacheTerminalTheme(options.theme)
|
|
476
|
+
};
|
|
473
477
|
const hiddenCheck = options.context === "doc" ? isDocHidden : isUsageHidden;
|
|
474
478
|
const visibleTerms = filterUsageForDisplay([term], hiddenCheck);
|
|
475
479
|
if (visibleTerms.length < 1) return "";
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
480
|
+
return wrapUsageTokens(formatUsageTermInternal(visibleTerms[0], options), options);
|
|
481
|
+
}
|
|
482
|
+
function wrapUsageTokens(input, options, initialWidth = 0) {
|
|
483
|
+
return require_terminal_internal.serializeTokens(layoutUsageTokens(input, options, initialWidth), options.colors);
|
|
484
|
+
}
|
|
485
|
+
function layoutUsageTokens(input, options, initialWidth = 0) {
|
|
486
|
+
let lineWidth = initialWidth;
|
|
487
|
+
const output = [];
|
|
488
|
+
for (const token of input) {
|
|
489
|
+
if (options.maxWidth != null && lineWidth > 0 && lineWidth + token.width > options.maxWidth) {
|
|
490
|
+
const last = output.at(-1);
|
|
491
|
+
if (last?.text.endsWith(" ") && (!options.colors || last.scopes.length === 0)) output[output.length - 1] = {
|
|
492
|
+
...last,
|
|
493
|
+
text: last.text.slice(0, -1),
|
|
494
|
+
width: last.width - 1
|
|
495
|
+
};
|
|
496
|
+
output.push({
|
|
497
|
+
text: "\n",
|
|
498
|
+
width: -1,
|
|
499
|
+
scopes: []
|
|
500
|
+
});
|
|
482
501
|
lineWidth = 0;
|
|
483
|
-
if (text === " ") continue;
|
|
502
|
+
if (token.text === " ") continue;
|
|
484
503
|
}
|
|
485
|
-
output
|
|
486
|
-
lineWidth += width;
|
|
504
|
+
output.push(token);
|
|
505
|
+
lineWidth += token.width;
|
|
487
506
|
}
|
|
488
507
|
return output;
|
|
489
508
|
}
|
|
490
509
|
function* formatUsageTermInternal(term, options) {
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
510
|
+
function leaf(t, usage) {
|
|
511
|
+
return require_terminal_internal.fragmentTokens(require_terminal_internal.formatTerminalTerm(t, options.theme, false, usage));
|
|
512
|
+
}
|
|
513
|
+
function punctuation(punctuation$1, kind) {
|
|
514
|
+
return leaf({
|
|
515
|
+
type: "syntaxPunctuation",
|
|
516
|
+
punctuation: punctuation$1,
|
|
517
|
+
kind
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
const space = {
|
|
521
|
+
text: " ",
|
|
522
|
+
width: 1,
|
|
523
|
+
scopes: []
|
|
495
524
|
};
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
};
|
|
509
|
-
yield {
|
|
510
|
-
text: options?.colors ? `\x1b[3m${optionName}\x1b[0m` : optionName,
|
|
511
|
-
width: require_displaywidth.getDisplayWidth(optionName)
|
|
512
|
-
};
|
|
513
|
-
i++;
|
|
525
|
+
if (term.type === "argument") yield* leaf({
|
|
526
|
+
type: "metavar",
|
|
527
|
+
metavar: term.metavar
|
|
528
|
+
}, "argument");
|
|
529
|
+
else if (term.type === "option") {
|
|
530
|
+
const names = options.onlyShortestOptions ? [term.names.reduce((a, b) => require_displaywidth.getDisplayWidth(a) <= require_displaywidth.getDisplayWidth(b) ? a : b)] : term.names;
|
|
531
|
+
for (let i = 0; i < names.length; i++) {
|
|
532
|
+
if (i > 0) yield* punctuation(options.optionsSeparator ?? "/", "optionSeparator");
|
|
533
|
+
yield* leaf({
|
|
534
|
+
type: "optionName",
|
|
535
|
+
optionName: names[i]
|
|
536
|
+
});
|
|
514
537
|
}
|
|
515
|
-
if (term.metavar != null) {
|
|
516
|
-
yield
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
text: options?.colors ? `\x1b[4m\x1b[2m${term.metavar}\x1b[0m` : term.metavar,
|
|
522
|
-
width: require_displaywidth.getDisplayWidth(term.metavar)
|
|
523
|
-
};
|
|
538
|
+
if (!options.onlyShortestOptions && term.metavar != null) {
|
|
539
|
+
yield space;
|
|
540
|
+
yield* leaf({
|
|
541
|
+
type: "metavar",
|
|
542
|
+
metavar: term.metavar
|
|
543
|
+
}, "optionValue");
|
|
524
544
|
}
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
};
|
|
545
|
+
} else if (term.type === "command") yield* leaf({
|
|
546
|
+
type: "optionName",
|
|
547
|
+
optionName: term.name
|
|
548
|
+
}, "command");
|
|
530
549
|
else if (term.type === "optional") {
|
|
531
|
-
yield
|
|
532
|
-
text: options?.colors ? `\x1b[2m[\x1b[0m` : "[",
|
|
533
|
-
width: 1
|
|
534
|
-
};
|
|
550
|
+
yield* punctuation("[", "optionalOpen");
|
|
535
551
|
yield* formatUsageTerms(term.terms, options);
|
|
536
|
-
yield
|
|
537
|
-
text: options?.colors ? `\x1b[2m]\x1b[0m` : "]",
|
|
538
|
-
width: 1
|
|
539
|
-
};
|
|
552
|
+
yield* punctuation("]", "optionalClose");
|
|
540
553
|
} else if (term.type === "exclusive") {
|
|
541
|
-
yield
|
|
542
|
-
|
|
543
|
-
width: 1
|
|
544
|
-
};
|
|
545
|
-
let i = 0;
|
|
546
|
-
for (const termGroup of term.terms) {
|
|
554
|
+
yield* punctuation("(", "groupOpen");
|
|
555
|
+
for (let i = 0; i < term.terms.length; i++) {
|
|
547
556
|
if (i > 0) {
|
|
548
|
-
yield
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
};
|
|
552
|
-
yield {
|
|
553
|
-
text: "|",
|
|
554
|
-
width: 1
|
|
555
|
-
};
|
|
556
|
-
yield {
|
|
557
|
-
text: " ",
|
|
558
|
-
width: 1
|
|
559
|
-
};
|
|
557
|
+
yield space;
|
|
558
|
+
yield* punctuation("|", "alternative");
|
|
559
|
+
yield space;
|
|
560
560
|
}
|
|
561
|
-
yield* formatUsageTerms(
|
|
562
|
-
i++;
|
|
561
|
+
yield* formatUsageTerms(term.terms[i], options);
|
|
563
562
|
}
|
|
564
|
-
yield
|
|
565
|
-
text: options?.colors ? `\x1b[2m)\x1b[0m` : ")",
|
|
566
|
-
width: 1
|
|
567
|
-
};
|
|
563
|
+
yield* punctuation(")", "groupClose");
|
|
568
564
|
} else if (term.type === "sequence") yield* formatUsageTerms(term.terms, options);
|
|
569
565
|
else if (term.type === "multiple") {
|
|
570
|
-
if (term.min < 1) yield
|
|
571
|
-
text: options?.colors ? `\x1b[2m[\x1b[0m` : "[",
|
|
572
|
-
width: 1
|
|
573
|
-
};
|
|
566
|
+
if (term.min < 1) yield* punctuation("[", "optionalOpen");
|
|
574
567
|
for (let i = 0; i < Math.max(1, term.min); i++) {
|
|
575
|
-
if (i > 0) yield
|
|
576
|
-
text: " ",
|
|
577
|
-
width: 1
|
|
578
|
-
};
|
|
568
|
+
if (i > 0) yield space;
|
|
579
569
|
yield* formatUsageTerms(term.terms, options);
|
|
580
570
|
}
|
|
581
|
-
yield
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
text: term.value,
|
|
591
|
-
width: require_displaywidth.getDisplayWidth(term.value)
|
|
592
|
-
};
|
|
593
|
-
else if (term.type === "passthrough") {
|
|
594
|
-
const text = "[...]";
|
|
595
|
-
yield {
|
|
596
|
-
text: options?.colors ? `\x1b[2m${text}\x1b[0m` : text,
|
|
597
|
-
width: 5
|
|
598
|
-
};
|
|
599
|
-
} else if (term.type === "ellipsis") {
|
|
600
|
-
const text = "...";
|
|
601
|
-
yield {
|
|
602
|
-
text: options?.colors ? `\x1b[2m${text}\x1b[0m` : text,
|
|
603
|
-
width: 3
|
|
604
|
-
};
|
|
605
|
-
} else throw new TypeError(`Unknown usage term type: ${term["type"]}.`);
|
|
571
|
+
yield* punctuation("...", "ellipsis");
|
|
572
|
+
if (term.min < 1) yield* punctuation("]", "optionalClose");
|
|
573
|
+
} else if (term.type === "literal") yield* leaf({
|
|
574
|
+
type: "value",
|
|
575
|
+
value: term.value
|
|
576
|
+
}, "literal");
|
|
577
|
+
else if (term.type === "passthrough") yield* punctuation("[...]", "passthrough");
|
|
578
|
+
else if (term.type === "ellipsis") yield* punctuation("...", "ellipsis");
|
|
579
|
+
else throw new TypeError(`Unknown usage term type: ${term["type"]}.`);
|
|
606
580
|
}
|
|
607
581
|
|
|
608
582
|
//#endregion
|
package/dist/usage.d.cts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { NonEmptyString } from "./nonempty.cjs";
|
|
2
|
+
import { TerminalTheme } from "./terminal.cjs";
|
|
2
3
|
|
|
3
4
|
//#region src/usage.d.ts
|
|
4
5
|
|
|
@@ -340,6 +341,11 @@ declare function extractArgumentMetavars(usage: Usage): Set<string>;
|
|
|
340
341
|
* Options for formatting usage descriptions.
|
|
341
342
|
*/
|
|
342
343
|
interface UsageFormatOptions {
|
|
344
|
+
/**
|
|
345
|
+
* Semantic terminal theme.
|
|
346
|
+
* @since 1.3.0
|
|
347
|
+
*/
|
|
348
|
+
readonly theme?: TerminalTheme;
|
|
343
349
|
/**
|
|
344
350
|
* When `true`, expands commands in the usage description
|
|
345
351
|
* to multiple lines, showing each command on a new line.
|
package/dist/usage.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { NonEmptyString } from "./nonempty.js";
|
|
2
|
+
import { TerminalTheme } from "./terminal.js";
|
|
2
3
|
|
|
3
4
|
//#region src/usage.d.ts
|
|
4
5
|
|
|
@@ -340,6 +341,11 @@ declare function extractArgumentMetavars(usage: Usage): Set<string>;
|
|
|
340
341
|
* Options for formatting usage descriptions.
|
|
341
342
|
*/
|
|
342
343
|
interface UsageFormatOptions {
|
|
344
|
+
/**
|
|
345
|
+
* Semantic terminal theme.
|
|
346
|
+
* @since 1.3.0
|
|
347
|
+
*/
|
|
348
|
+
readonly theme?: TerminalTheme;
|
|
343
349
|
/**
|
|
344
350
|
* When `true`, expands commands in the usage description
|
|
345
351
|
* to multiple lines, showing each command on a new line.
|
package/dist/usage.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getDisplayWidth } from "./displaywidth.js";
|
|
2
|
+
import { cacheTerminalTheme, formatTerminalTerm, fragmentTokens, serializeTokens } from "./terminal-internal.js";
|
|
2
3
|
import { validateProgramName } from "./validate.js";
|
|
3
4
|
|
|
4
5
|
//#region src/usage.ts
|
|
@@ -182,6 +183,10 @@ function extractArgumentMetavars(usage) {
|
|
|
182
183
|
* whitespace-only, or contains control characters.
|
|
183
184
|
*/
|
|
184
185
|
function formatUsage(programName, usage, options = {}) {
|
|
186
|
+
options = {
|
|
187
|
+
...options,
|
|
188
|
+
theme: cacheTerminalTheme(options.theme)
|
|
189
|
+
};
|
|
185
190
|
validateProgramName(programName);
|
|
186
191
|
usage = normalizeUsage(filterUsageForDisplay(usage));
|
|
187
192
|
if (options.expandCommands) {
|
|
@@ -197,29 +202,23 @@ function formatUsage(programName, usage, options = {}) {
|
|
|
197
202
|
if (lines.length > 0) return lines.join("\n");
|
|
198
203
|
}
|
|
199
204
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
if (text === " ") continue;
|
|
218
|
-
}
|
|
219
|
-
output += text;
|
|
220
|
-
lineWidth += width;
|
|
221
|
-
}
|
|
222
|
-
return output;
|
|
205
|
+
const programTokens = layoutUsageTokens(fragmentTokens(formatTerminalTerm({
|
|
206
|
+
type: "programName",
|
|
207
|
+
programName
|
|
208
|
+
}, options.theme)), options);
|
|
209
|
+
const terms = [...formatUsageTerms(usage, options)];
|
|
210
|
+
if (terms.length === 0) return serializeTokens(programTokens, options.colors);
|
|
211
|
+
const width = programTokens.reduce((n, token) => token.width === -1 ? 0 : n + token.width, 0);
|
|
212
|
+
const separator = options.maxWidth != null && width + 1 + terms[0].width > options.maxWidth ? {
|
|
213
|
+
text: "\n",
|
|
214
|
+
width: -1,
|
|
215
|
+
scopes: []
|
|
216
|
+
} : {
|
|
217
|
+
text: " ",
|
|
218
|
+
width: 1,
|
|
219
|
+
scopes: []
|
|
220
|
+
};
|
|
221
|
+
return serializeTokens([...programTokens, separator], options.colors) + wrapUsageTokens(terms, options, separator.width === -1 ? 0 : width + 1);
|
|
223
222
|
}
|
|
224
223
|
/**
|
|
225
224
|
* Normalizes a usage description by flattening nested exclusive terms,
|
|
@@ -454,7 +453,8 @@ function* formatUsageTerms(terms, options) {
|
|
|
454
453
|
for (const t of terms) {
|
|
455
454
|
if (i > 0) yield {
|
|
456
455
|
text: " ",
|
|
457
|
-
width: 1
|
|
456
|
+
width: 1,
|
|
457
|
+
scopes: []
|
|
458
458
|
};
|
|
459
459
|
yield* formatUsageTermInternal(t, options);
|
|
460
460
|
i++;
|
|
@@ -470,139 +470,113 @@ function* formatUsageTerms(terms, options) {
|
|
|
470
470
|
* @returns A formatted string representation of the usage term.
|
|
471
471
|
*/
|
|
472
472
|
function formatUsageTerm(term, options = {}) {
|
|
473
|
+
options = {
|
|
474
|
+
...options,
|
|
475
|
+
theme: cacheTerminalTheme(options.theme)
|
|
476
|
+
};
|
|
473
477
|
const hiddenCheck = options.context === "doc" ? isDocHidden : isUsageHidden;
|
|
474
478
|
const visibleTerms = filterUsageForDisplay([term], hiddenCheck);
|
|
475
479
|
if (visibleTerms.length < 1) return "";
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
480
|
+
return wrapUsageTokens(formatUsageTermInternal(visibleTerms[0], options), options);
|
|
481
|
+
}
|
|
482
|
+
function wrapUsageTokens(input, options, initialWidth = 0) {
|
|
483
|
+
return serializeTokens(layoutUsageTokens(input, options, initialWidth), options.colors);
|
|
484
|
+
}
|
|
485
|
+
function layoutUsageTokens(input, options, initialWidth = 0) {
|
|
486
|
+
let lineWidth = initialWidth;
|
|
487
|
+
const output = [];
|
|
488
|
+
for (const token of input) {
|
|
489
|
+
if (options.maxWidth != null && lineWidth > 0 && lineWidth + token.width > options.maxWidth) {
|
|
490
|
+
const last = output.at(-1);
|
|
491
|
+
if (last?.text.endsWith(" ") && (!options.colors || last.scopes.length === 0)) output[output.length - 1] = {
|
|
492
|
+
...last,
|
|
493
|
+
text: last.text.slice(0, -1),
|
|
494
|
+
width: last.width - 1
|
|
495
|
+
};
|
|
496
|
+
output.push({
|
|
497
|
+
text: "\n",
|
|
498
|
+
width: -1,
|
|
499
|
+
scopes: []
|
|
500
|
+
});
|
|
482
501
|
lineWidth = 0;
|
|
483
|
-
if (text === " ") continue;
|
|
502
|
+
if (token.text === " ") continue;
|
|
484
503
|
}
|
|
485
|
-
output
|
|
486
|
-
lineWidth += width;
|
|
504
|
+
output.push(token);
|
|
505
|
+
lineWidth += token.width;
|
|
487
506
|
}
|
|
488
507
|
return output;
|
|
489
508
|
}
|
|
490
509
|
function* formatUsageTermInternal(term, options) {
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
510
|
+
function leaf(t, usage) {
|
|
511
|
+
return fragmentTokens(formatTerminalTerm(t, options.theme, false, usage));
|
|
512
|
+
}
|
|
513
|
+
function punctuation(punctuation$1, kind) {
|
|
514
|
+
return leaf({
|
|
515
|
+
type: "syntaxPunctuation",
|
|
516
|
+
punctuation: punctuation$1,
|
|
517
|
+
kind
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
const space = {
|
|
521
|
+
text: " ",
|
|
522
|
+
width: 1,
|
|
523
|
+
scopes: []
|
|
495
524
|
};
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
};
|
|
509
|
-
yield {
|
|
510
|
-
text: options?.colors ? `\x1b[3m${optionName}\x1b[0m` : optionName,
|
|
511
|
-
width: getDisplayWidth(optionName)
|
|
512
|
-
};
|
|
513
|
-
i++;
|
|
525
|
+
if (term.type === "argument") yield* leaf({
|
|
526
|
+
type: "metavar",
|
|
527
|
+
metavar: term.metavar
|
|
528
|
+
}, "argument");
|
|
529
|
+
else if (term.type === "option") {
|
|
530
|
+
const names = options.onlyShortestOptions ? [term.names.reduce((a, b) => getDisplayWidth(a) <= getDisplayWidth(b) ? a : b)] : term.names;
|
|
531
|
+
for (let i = 0; i < names.length; i++) {
|
|
532
|
+
if (i > 0) yield* punctuation(options.optionsSeparator ?? "/", "optionSeparator");
|
|
533
|
+
yield* leaf({
|
|
534
|
+
type: "optionName",
|
|
535
|
+
optionName: names[i]
|
|
536
|
+
});
|
|
514
537
|
}
|
|
515
|
-
if (term.metavar != null) {
|
|
516
|
-
yield
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
text: options?.colors ? `\x1b[4m\x1b[2m${term.metavar}\x1b[0m` : term.metavar,
|
|
522
|
-
width: getDisplayWidth(term.metavar)
|
|
523
|
-
};
|
|
538
|
+
if (!options.onlyShortestOptions && term.metavar != null) {
|
|
539
|
+
yield space;
|
|
540
|
+
yield* leaf({
|
|
541
|
+
type: "metavar",
|
|
542
|
+
metavar: term.metavar
|
|
543
|
+
}, "optionValue");
|
|
524
544
|
}
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
};
|
|
545
|
+
} else if (term.type === "command") yield* leaf({
|
|
546
|
+
type: "optionName",
|
|
547
|
+
optionName: term.name
|
|
548
|
+
}, "command");
|
|
530
549
|
else if (term.type === "optional") {
|
|
531
|
-
yield
|
|
532
|
-
text: options?.colors ? `\x1b[2m[\x1b[0m` : "[",
|
|
533
|
-
width: 1
|
|
534
|
-
};
|
|
550
|
+
yield* punctuation("[", "optionalOpen");
|
|
535
551
|
yield* formatUsageTerms(term.terms, options);
|
|
536
|
-
yield
|
|
537
|
-
text: options?.colors ? `\x1b[2m]\x1b[0m` : "]",
|
|
538
|
-
width: 1
|
|
539
|
-
};
|
|
552
|
+
yield* punctuation("]", "optionalClose");
|
|
540
553
|
} else if (term.type === "exclusive") {
|
|
541
|
-
yield
|
|
542
|
-
|
|
543
|
-
width: 1
|
|
544
|
-
};
|
|
545
|
-
let i = 0;
|
|
546
|
-
for (const termGroup of term.terms) {
|
|
554
|
+
yield* punctuation("(", "groupOpen");
|
|
555
|
+
for (let i = 0; i < term.terms.length; i++) {
|
|
547
556
|
if (i > 0) {
|
|
548
|
-
yield
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
};
|
|
552
|
-
yield {
|
|
553
|
-
text: "|",
|
|
554
|
-
width: 1
|
|
555
|
-
};
|
|
556
|
-
yield {
|
|
557
|
-
text: " ",
|
|
558
|
-
width: 1
|
|
559
|
-
};
|
|
557
|
+
yield space;
|
|
558
|
+
yield* punctuation("|", "alternative");
|
|
559
|
+
yield space;
|
|
560
560
|
}
|
|
561
|
-
yield* formatUsageTerms(
|
|
562
|
-
i++;
|
|
561
|
+
yield* formatUsageTerms(term.terms[i], options);
|
|
563
562
|
}
|
|
564
|
-
yield
|
|
565
|
-
text: options?.colors ? `\x1b[2m)\x1b[0m` : ")",
|
|
566
|
-
width: 1
|
|
567
|
-
};
|
|
563
|
+
yield* punctuation(")", "groupClose");
|
|
568
564
|
} else if (term.type === "sequence") yield* formatUsageTerms(term.terms, options);
|
|
569
565
|
else if (term.type === "multiple") {
|
|
570
|
-
if (term.min < 1) yield
|
|
571
|
-
text: options?.colors ? `\x1b[2m[\x1b[0m` : "[",
|
|
572
|
-
width: 1
|
|
573
|
-
};
|
|
566
|
+
if (term.min < 1) yield* punctuation("[", "optionalOpen");
|
|
574
567
|
for (let i = 0; i < Math.max(1, term.min); i++) {
|
|
575
|
-
if (i > 0) yield
|
|
576
|
-
text: " ",
|
|
577
|
-
width: 1
|
|
578
|
-
};
|
|
568
|
+
if (i > 0) yield space;
|
|
579
569
|
yield* formatUsageTerms(term.terms, options);
|
|
580
570
|
}
|
|
581
|
-
yield
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
text: term.value,
|
|
591
|
-
width: getDisplayWidth(term.value)
|
|
592
|
-
};
|
|
593
|
-
else if (term.type === "passthrough") {
|
|
594
|
-
const text = "[...]";
|
|
595
|
-
yield {
|
|
596
|
-
text: options?.colors ? `\x1b[2m${text}\x1b[0m` : text,
|
|
597
|
-
width: 5
|
|
598
|
-
};
|
|
599
|
-
} else if (term.type === "ellipsis") {
|
|
600
|
-
const text = "...";
|
|
601
|
-
yield {
|
|
602
|
-
text: options?.colors ? `\x1b[2m${text}\x1b[0m` : text,
|
|
603
|
-
width: 3
|
|
604
|
-
};
|
|
605
|
-
} else throw new TypeError(`Unknown usage term type: ${term["type"]}.`);
|
|
571
|
+
yield* punctuation("...", "ellipsis");
|
|
572
|
+
if (term.min < 1) yield* punctuation("]", "optionalClose");
|
|
573
|
+
} else if (term.type === "literal") yield* leaf({
|
|
574
|
+
type: "value",
|
|
575
|
+
value: term.value
|
|
576
|
+
}, "literal");
|
|
577
|
+
else if (term.type === "passthrough") yield* punctuation("[...]", "passthrough");
|
|
578
|
+
else if (term.type === "ellipsis") yield* punctuation("...", "ellipsis");
|
|
579
|
+
else throw new TypeError(`Unknown usage term type: ${term["type"]}.`);
|
|
606
580
|
}
|
|
607
581
|
|
|
608
582
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@optique/core",
|
|
3
|
-
"version": "1.3.0-dev.
|
|
3
|
+
"version": "1.3.0-dev.2530",
|
|
4
4
|
"description": "Type-safe combinatorial command-line interface parser",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"CLI",
|
|
@@ -211,6 +211,22 @@
|
|
|
211
211
|
},
|
|
212
212
|
"import": "./dist/valueparser.js",
|
|
213
213
|
"require": "./dist/valueparser.cjs"
|
|
214
|
+
},
|
|
215
|
+
"./terminal": {
|
|
216
|
+
"types": {
|
|
217
|
+
"import": "./dist/terminal.d.ts",
|
|
218
|
+
"require": "./dist/terminal.d.cts"
|
|
219
|
+
},
|
|
220
|
+
"import": "./dist/terminal.js",
|
|
221
|
+
"require": "./dist/terminal.cjs"
|
|
222
|
+
},
|
|
223
|
+
"./internal/terminal": {
|
|
224
|
+
"types": {
|
|
225
|
+
"import": "./dist/internal/terminal.d.ts",
|
|
226
|
+
"require": "./dist/internal/terminal.d.cts"
|
|
227
|
+
},
|
|
228
|
+
"import": "./dist/internal/terminal.js",
|
|
229
|
+
"require": "./dist/internal/terminal.cjs"
|
|
214
230
|
}
|
|
215
231
|
},
|
|
216
232
|
"imports": {
|
|
@@ -221,7 +237,7 @@
|
|
|
221
237
|
},
|
|
222
238
|
"sideEffects": false,
|
|
223
239
|
"devDependencies": {
|
|
224
|
-
"@optique/env": "1.3.0-dev.
|
|
240
|
+
"@optique/env": "1.3.0-dev.2530+970f0e16",
|
|
225
241
|
"@types/node": "^24.0.0",
|
|
226
242
|
"fast-check": "^4.7.0",
|
|
227
243
|
"tsdown": "^0.13.0",
|