@optique/core 0.6.0-dev.102 → 0.6.0-dev.104
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/completion.cjs +230 -0
- package/dist/completion.d.cts +6 -1
- package/dist/completion.d.ts +6 -1
- package/dist/completion.js +230 -1
- package/dist/facade.cjs +15 -10
- package/dist/facade.d.cts +9 -0
- package/dist/facade.d.ts +9 -0
- package/dist/facade.js +16 -11
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/package.json +1 -1
package/dist/completion.cjs
CHANGED
|
@@ -348,6 +348,235 @@ complete -c ${programName} -f -a '(${functionName})'
|
|
|
348
348
|
}
|
|
349
349
|
};
|
|
350
350
|
/**
|
|
351
|
+
* The Nushell completion generator.
|
|
352
|
+
* @since 0.6.0
|
|
353
|
+
*/
|
|
354
|
+
const nu = {
|
|
355
|
+
name: "nu",
|
|
356
|
+
generateScript(programName, args = []) {
|
|
357
|
+
const escapedArgs = args.map((arg) => `'${arg.replace(/'/g, "''")}'`).join(" ");
|
|
358
|
+
const safeName = programName.replace(/[^a-zA-Z0-9]+/g, "-");
|
|
359
|
+
const functionName = `nu-complete-${safeName}`;
|
|
360
|
+
return `
|
|
361
|
+
# Helper to split args respecting quotes and whitespace
|
|
362
|
+
def args-split []: string -> list<string> {
|
|
363
|
+
let STATE_NORMAL = 0
|
|
364
|
+
let STATE_IN_SINGLE_QUOTE = 1
|
|
365
|
+
let STATE_IN_DOUBLE_QUOTE = 2
|
|
366
|
+
let STATE_ESCAPE = 3
|
|
367
|
+
let WHITESPACES = [" " "\\t" "\\n" "\\r"]
|
|
368
|
+
|
|
369
|
+
mut state = $STATE_NORMAL
|
|
370
|
+
mut current_token = ""
|
|
371
|
+
mut result: list<string> = []
|
|
372
|
+
mut prev_state = $STATE_NORMAL
|
|
373
|
+
|
|
374
|
+
for char in ($in | split chars) {
|
|
375
|
+
if $state == $STATE_ESCAPE {
|
|
376
|
+
$current_token = $current_token + $char
|
|
377
|
+
$state = $prev_state
|
|
378
|
+
} else if $char == '\\\\' {
|
|
379
|
+
$prev_state = $state
|
|
380
|
+
$state = $STATE_ESCAPE
|
|
381
|
+
} else if $state == $STATE_NORMAL {
|
|
382
|
+
if $char == "'" {
|
|
383
|
+
$state = $STATE_IN_SINGLE_QUOTE
|
|
384
|
+
} else if $char == '"' {
|
|
385
|
+
$state = $STATE_IN_DOUBLE_QUOTE
|
|
386
|
+
} else if ($char in $WHITESPACES) {
|
|
387
|
+
if ($current_token | is-not-empty) {
|
|
388
|
+
$result = $result | append $current_token
|
|
389
|
+
$current_token = ""
|
|
390
|
+
}
|
|
391
|
+
} else {
|
|
392
|
+
$current_token = $current_token + $char
|
|
393
|
+
}
|
|
394
|
+
} else if $state == $STATE_IN_SINGLE_QUOTE {
|
|
395
|
+
if $char == "'" {
|
|
396
|
+
$state = $STATE_NORMAL
|
|
397
|
+
} else {
|
|
398
|
+
$current_token = $current_token + $char
|
|
399
|
+
}
|
|
400
|
+
} else if $state == $STATE_IN_DOUBLE_QUOTE {
|
|
401
|
+
if $char == '"' {
|
|
402
|
+
$state = $STATE_NORMAL
|
|
403
|
+
} else {
|
|
404
|
+
$current_token = $current_token + $char
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
if ($current_token | is-not-empty) {
|
|
409
|
+
$result = $result | append $current_token
|
|
410
|
+
}
|
|
411
|
+
$result
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
# Completion command that calls back to the CLI
|
|
415
|
+
export def "${functionName}" [context: string] {
|
|
416
|
+
# Split context into tokens, handling quotes properly
|
|
417
|
+
let tokens = $context | args-split
|
|
418
|
+
|
|
419
|
+
# Remove the command name (first token) to get arguments
|
|
420
|
+
let args = if ($tokens | length) > 1 {
|
|
421
|
+
$tokens | skip 1
|
|
422
|
+
} else {
|
|
423
|
+
[]
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
# If context ends with whitespace, add empty string to represent the new argument
|
|
427
|
+
let args_with_empty = if ($context | str ends-with ' ') {
|
|
428
|
+
$args | append ''
|
|
429
|
+
} else {
|
|
430
|
+
$args
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
# Ensure at least one argument (empty string) to get completions not script
|
|
434
|
+
let final_args = if ($args_with_empty | is-empty) {
|
|
435
|
+
['']
|
|
436
|
+
} else {
|
|
437
|
+
$args_with_empty
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
let output = try {
|
|
441
|
+
${escapedArgs ? ` ^${programName} ${escapedArgs} ...$final_args | complete | get stdout\n` : ` ^${programName} ...$final_args | complete | get stdout\n`} } catch {
|
|
442
|
+
""
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
# Process each line of output
|
|
446
|
+
$output | lines | each {|line|
|
|
447
|
+
if ($line | str starts-with '__FILE__:') {
|
|
448
|
+
# Parse file completion directive: __FILE__:type:extensions:pattern:hidden
|
|
449
|
+
let parts = ($line | split row ':')
|
|
450
|
+
let type = ($parts | get 1)
|
|
451
|
+
let extensions = ($parts | get 2)
|
|
452
|
+
let pattern = ($parts | get 3)
|
|
453
|
+
let hidden = ($parts | get 4) == '1'
|
|
454
|
+
|
|
455
|
+
# Extract prefix from the last argument if it exists
|
|
456
|
+
let prefix = if ($final_args | length) > 0 {
|
|
457
|
+
$final_args | last
|
|
458
|
+
} else {
|
|
459
|
+
""
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
# Generate file completions based on type
|
|
463
|
+
# Use current directory if prefix is empty
|
|
464
|
+
let ls_pattern = if ($prefix | is-empty) { "." } else { $prefix + "*" }
|
|
465
|
+
|
|
466
|
+
let items = try {
|
|
467
|
+
match $type {
|
|
468
|
+
"file" => {
|
|
469
|
+
if ($extensions | is-empty) {
|
|
470
|
+
ls $ls_pattern | where type == file
|
|
471
|
+
} else {
|
|
472
|
+
let ext_list = ($extensions | split row ',')
|
|
473
|
+
ls $ls_pattern | where type == file | where {|f|
|
|
474
|
+
let ext = ($f.name | path parse | get extension)
|
|
475
|
+
$ext in $ext_list
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
},
|
|
479
|
+
"directory" => {
|
|
480
|
+
ls $ls_pattern | where type == dir
|
|
481
|
+
},
|
|
482
|
+
"any" => {
|
|
483
|
+
if ($extensions | is-empty) {
|
|
484
|
+
ls $ls_pattern
|
|
485
|
+
} else {
|
|
486
|
+
let ext_list = ($extensions | split row ',')
|
|
487
|
+
let dirs = ls $ls_pattern | where type == dir
|
|
488
|
+
let files = ls $ls_pattern | where type == file | where {|f|
|
|
489
|
+
let ext = ($f.name | path parse | get extension)
|
|
490
|
+
$ext in $ext_list
|
|
491
|
+
}
|
|
492
|
+
$dirs | append $files
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
} catch {
|
|
497
|
+
[]
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
# Filter out hidden files unless requested
|
|
501
|
+
let filtered = if $hidden or ($prefix | str starts-with '.') {
|
|
502
|
+
$items
|
|
503
|
+
} else {
|
|
504
|
+
$items | where {|item|
|
|
505
|
+
let basename = ($item.name | path basename)
|
|
506
|
+
not ($basename | str starts-with '.')
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
# Format file completions
|
|
511
|
+
$filtered | each {|item|
|
|
512
|
+
let name = if $item.type == dir {
|
|
513
|
+
($item.name | path basename) + "/"
|
|
514
|
+
} else {
|
|
515
|
+
$item.name | path basename
|
|
516
|
+
}
|
|
517
|
+
{ value: $name }
|
|
518
|
+
}
|
|
519
|
+
} else {
|
|
520
|
+
# Regular literal completion - split by tab
|
|
521
|
+
let parts = ($line | split row "\t")
|
|
522
|
+
if ($parts | length) >= 2 {
|
|
523
|
+
# value\\tdescription format
|
|
524
|
+
{ value: ($parts | get 0), description: ($parts | get 1) }
|
|
525
|
+
} else if ($parts | length) == 1 and ($parts | get 0 | is-not-empty) {
|
|
526
|
+
# Just value
|
|
527
|
+
{ value: ($parts | get 0) }
|
|
528
|
+
} else {
|
|
529
|
+
null
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
} | flatten | compact
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
# Custom completer for external commands
|
|
536
|
+
# This function will be called by Nushell's completion system
|
|
537
|
+
def --env "${functionName}-external" [] {
|
|
538
|
+
let existing_completer = $env.config.completions.external.completer
|
|
539
|
+
|
|
540
|
+
$env.config.completions.external.completer = {|spans|
|
|
541
|
+
# Check if this is for our program
|
|
542
|
+
if ($spans.0 == "${programName}") {
|
|
543
|
+
# Build context string from spans
|
|
544
|
+
let context = $spans | str join ' '
|
|
545
|
+
${functionName} $context
|
|
546
|
+
} else if ($existing_completer != null) {
|
|
547
|
+
# Delegate to existing completer
|
|
548
|
+
do $existing_completer $spans
|
|
549
|
+
} else {
|
|
550
|
+
# No completions
|
|
551
|
+
null
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
$env.config.completions.external.enable = true
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
# Auto-setup: register the completer when this module is imported
|
|
559
|
+
${functionName}-external
|
|
560
|
+
`;
|
|
561
|
+
},
|
|
562
|
+
*encodeSuggestions(suggestions) {
|
|
563
|
+
let i = 0;
|
|
564
|
+
for (const suggestion of suggestions) {
|
|
565
|
+
if (i > 0) yield "\n";
|
|
566
|
+
if (suggestion.kind === "literal") {
|
|
567
|
+
const description = suggestion.description == null ? "" : require_message.formatMessage(suggestion.description, { colors: false });
|
|
568
|
+
yield `${suggestion.text}\t${description}`;
|
|
569
|
+
} else {
|
|
570
|
+
const extensions = suggestion.extensions?.join(",") || "";
|
|
571
|
+
const hidden = suggestion.includeHidden ? "1" : "0";
|
|
572
|
+
const description = suggestion.description == null ? "" : require_message.formatMessage(suggestion.description, { colors: false });
|
|
573
|
+
yield `__FILE__:${suggestion.type}:${extensions}:${suggestion.pattern || ""}:${hidden}\t${description}`;
|
|
574
|
+
}
|
|
575
|
+
i++;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
};
|
|
579
|
+
/**
|
|
351
580
|
* The PowerShell completion generator.
|
|
352
581
|
* @since 0.6.0
|
|
353
582
|
*/
|
|
@@ -509,5 +738,6 @@ ${escapedArgs ? ` \$completionArgs += @(${escapedArgs})
|
|
|
509
738
|
//#endregion
|
|
510
739
|
exports.bash = bash;
|
|
511
740
|
exports.fish = fish;
|
|
741
|
+
exports.nu = nu;
|
|
512
742
|
exports.pwsh = pwsh;
|
|
513
743
|
exports.zsh = zsh;
|
package/dist/completion.d.cts
CHANGED
|
@@ -42,10 +42,15 @@ declare const zsh: ShellCompletion;
|
|
|
42
42
|
* @since 0.6.0
|
|
43
43
|
*/
|
|
44
44
|
declare const fish: ShellCompletion;
|
|
45
|
+
/**
|
|
46
|
+
* The Nushell completion generator.
|
|
47
|
+
* @since 0.6.0
|
|
48
|
+
*/
|
|
49
|
+
declare const nu: ShellCompletion;
|
|
45
50
|
/**
|
|
46
51
|
* The PowerShell completion generator.
|
|
47
52
|
* @since 0.6.0
|
|
48
53
|
*/
|
|
49
54
|
declare const pwsh: ShellCompletion;
|
|
50
55
|
//#endregion
|
|
51
|
-
export { ShellCompletion, bash, fish, pwsh, zsh };
|
|
56
|
+
export { ShellCompletion, bash, fish, nu, pwsh, zsh };
|
package/dist/completion.d.ts
CHANGED
|
@@ -42,10 +42,15 @@ declare const zsh: ShellCompletion;
|
|
|
42
42
|
* @since 0.6.0
|
|
43
43
|
*/
|
|
44
44
|
declare const fish: ShellCompletion;
|
|
45
|
+
/**
|
|
46
|
+
* The Nushell completion generator.
|
|
47
|
+
* @since 0.6.0
|
|
48
|
+
*/
|
|
49
|
+
declare const nu: ShellCompletion;
|
|
45
50
|
/**
|
|
46
51
|
* The PowerShell completion generator.
|
|
47
52
|
* @since 0.6.0
|
|
48
53
|
*/
|
|
49
54
|
declare const pwsh: ShellCompletion;
|
|
50
55
|
//#endregion
|
|
51
|
-
export { ShellCompletion, bash, fish, pwsh, zsh };
|
|
56
|
+
export { ShellCompletion, bash, fish, nu, pwsh, zsh };
|
package/dist/completion.js
CHANGED
|
@@ -348,6 +348,235 @@ complete -c ${programName} -f -a '(${functionName})'
|
|
|
348
348
|
}
|
|
349
349
|
};
|
|
350
350
|
/**
|
|
351
|
+
* The Nushell completion generator.
|
|
352
|
+
* @since 0.6.0
|
|
353
|
+
*/
|
|
354
|
+
const nu = {
|
|
355
|
+
name: "nu",
|
|
356
|
+
generateScript(programName, args = []) {
|
|
357
|
+
const escapedArgs = args.map((arg) => `'${arg.replace(/'/g, "''")}'`).join(" ");
|
|
358
|
+
const safeName = programName.replace(/[^a-zA-Z0-9]+/g, "-");
|
|
359
|
+
const functionName = `nu-complete-${safeName}`;
|
|
360
|
+
return `
|
|
361
|
+
# Helper to split args respecting quotes and whitespace
|
|
362
|
+
def args-split []: string -> list<string> {
|
|
363
|
+
let STATE_NORMAL = 0
|
|
364
|
+
let STATE_IN_SINGLE_QUOTE = 1
|
|
365
|
+
let STATE_IN_DOUBLE_QUOTE = 2
|
|
366
|
+
let STATE_ESCAPE = 3
|
|
367
|
+
let WHITESPACES = [" " "\\t" "\\n" "\\r"]
|
|
368
|
+
|
|
369
|
+
mut state = $STATE_NORMAL
|
|
370
|
+
mut current_token = ""
|
|
371
|
+
mut result: list<string> = []
|
|
372
|
+
mut prev_state = $STATE_NORMAL
|
|
373
|
+
|
|
374
|
+
for char in ($in | split chars) {
|
|
375
|
+
if $state == $STATE_ESCAPE {
|
|
376
|
+
$current_token = $current_token + $char
|
|
377
|
+
$state = $prev_state
|
|
378
|
+
} else if $char == '\\\\' {
|
|
379
|
+
$prev_state = $state
|
|
380
|
+
$state = $STATE_ESCAPE
|
|
381
|
+
} else if $state == $STATE_NORMAL {
|
|
382
|
+
if $char == "'" {
|
|
383
|
+
$state = $STATE_IN_SINGLE_QUOTE
|
|
384
|
+
} else if $char == '"' {
|
|
385
|
+
$state = $STATE_IN_DOUBLE_QUOTE
|
|
386
|
+
} else if ($char in $WHITESPACES) {
|
|
387
|
+
if ($current_token | is-not-empty) {
|
|
388
|
+
$result = $result | append $current_token
|
|
389
|
+
$current_token = ""
|
|
390
|
+
}
|
|
391
|
+
} else {
|
|
392
|
+
$current_token = $current_token + $char
|
|
393
|
+
}
|
|
394
|
+
} else if $state == $STATE_IN_SINGLE_QUOTE {
|
|
395
|
+
if $char == "'" {
|
|
396
|
+
$state = $STATE_NORMAL
|
|
397
|
+
} else {
|
|
398
|
+
$current_token = $current_token + $char
|
|
399
|
+
}
|
|
400
|
+
} else if $state == $STATE_IN_DOUBLE_QUOTE {
|
|
401
|
+
if $char == '"' {
|
|
402
|
+
$state = $STATE_NORMAL
|
|
403
|
+
} else {
|
|
404
|
+
$current_token = $current_token + $char
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
if ($current_token | is-not-empty) {
|
|
409
|
+
$result = $result | append $current_token
|
|
410
|
+
}
|
|
411
|
+
$result
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
# Completion command that calls back to the CLI
|
|
415
|
+
export def "${functionName}" [context: string] {
|
|
416
|
+
# Split context into tokens, handling quotes properly
|
|
417
|
+
let tokens = $context | args-split
|
|
418
|
+
|
|
419
|
+
# Remove the command name (first token) to get arguments
|
|
420
|
+
let args = if ($tokens | length) > 1 {
|
|
421
|
+
$tokens | skip 1
|
|
422
|
+
} else {
|
|
423
|
+
[]
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
# If context ends with whitespace, add empty string to represent the new argument
|
|
427
|
+
let args_with_empty = if ($context | str ends-with ' ') {
|
|
428
|
+
$args | append ''
|
|
429
|
+
} else {
|
|
430
|
+
$args
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
# Ensure at least one argument (empty string) to get completions not script
|
|
434
|
+
let final_args = if ($args_with_empty | is-empty) {
|
|
435
|
+
['']
|
|
436
|
+
} else {
|
|
437
|
+
$args_with_empty
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
let output = try {
|
|
441
|
+
${escapedArgs ? ` ^${programName} ${escapedArgs} ...$final_args | complete | get stdout\n` : ` ^${programName} ...$final_args | complete | get stdout\n`} } catch {
|
|
442
|
+
""
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
# Process each line of output
|
|
446
|
+
$output | lines | each {|line|
|
|
447
|
+
if ($line | str starts-with '__FILE__:') {
|
|
448
|
+
# Parse file completion directive: __FILE__:type:extensions:pattern:hidden
|
|
449
|
+
let parts = ($line | split row ':')
|
|
450
|
+
let type = ($parts | get 1)
|
|
451
|
+
let extensions = ($parts | get 2)
|
|
452
|
+
let pattern = ($parts | get 3)
|
|
453
|
+
let hidden = ($parts | get 4) == '1'
|
|
454
|
+
|
|
455
|
+
# Extract prefix from the last argument if it exists
|
|
456
|
+
let prefix = if ($final_args | length) > 0 {
|
|
457
|
+
$final_args | last
|
|
458
|
+
} else {
|
|
459
|
+
""
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
# Generate file completions based on type
|
|
463
|
+
# Use current directory if prefix is empty
|
|
464
|
+
let ls_pattern = if ($prefix | is-empty) { "." } else { $prefix + "*" }
|
|
465
|
+
|
|
466
|
+
let items = try {
|
|
467
|
+
match $type {
|
|
468
|
+
"file" => {
|
|
469
|
+
if ($extensions | is-empty) {
|
|
470
|
+
ls $ls_pattern | where type == file
|
|
471
|
+
} else {
|
|
472
|
+
let ext_list = ($extensions | split row ',')
|
|
473
|
+
ls $ls_pattern | where type == file | where {|f|
|
|
474
|
+
let ext = ($f.name | path parse | get extension)
|
|
475
|
+
$ext in $ext_list
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
},
|
|
479
|
+
"directory" => {
|
|
480
|
+
ls $ls_pattern | where type == dir
|
|
481
|
+
},
|
|
482
|
+
"any" => {
|
|
483
|
+
if ($extensions | is-empty) {
|
|
484
|
+
ls $ls_pattern
|
|
485
|
+
} else {
|
|
486
|
+
let ext_list = ($extensions | split row ',')
|
|
487
|
+
let dirs = ls $ls_pattern | where type == dir
|
|
488
|
+
let files = ls $ls_pattern | where type == file | where {|f|
|
|
489
|
+
let ext = ($f.name | path parse | get extension)
|
|
490
|
+
$ext in $ext_list
|
|
491
|
+
}
|
|
492
|
+
$dirs | append $files
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
} catch {
|
|
497
|
+
[]
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
# Filter out hidden files unless requested
|
|
501
|
+
let filtered = if $hidden or ($prefix | str starts-with '.') {
|
|
502
|
+
$items
|
|
503
|
+
} else {
|
|
504
|
+
$items | where {|item|
|
|
505
|
+
let basename = ($item.name | path basename)
|
|
506
|
+
not ($basename | str starts-with '.')
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
# Format file completions
|
|
511
|
+
$filtered | each {|item|
|
|
512
|
+
let name = if $item.type == dir {
|
|
513
|
+
($item.name | path basename) + "/"
|
|
514
|
+
} else {
|
|
515
|
+
$item.name | path basename
|
|
516
|
+
}
|
|
517
|
+
{ value: $name }
|
|
518
|
+
}
|
|
519
|
+
} else {
|
|
520
|
+
# Regular literal completion - split by tab
|
|
521
|
+
let parts = ($line | split row "\t")
|
|
522
|
+
if ($parts | length) >= 2 {
|
|
523
|
+
# value\\tdescription format
|
|
524
|
+
{ value: ($parts | get 0), description: ($parts | get 1) }
|
|
525
|
+
} else if ($parts | length) == 1 and ($parts | get 0 | is-not-empty) {
|
|
526
|
+
# Just value
|
|
527
|
+
{ value: ($parts | get 0) }
|
|
528
|
+
} else {
|
|
529
|
+
null
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
} | flatten | compact
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
# Custom completer for external commands
|
|
536
|
+
# This function will be called by Nushell's completion system
|
|
537
|
+
def --env "${functionName}-external" [] {
|
|
538
|
+
let existing_completer = $env.config.completions.external.completer
|
|
539
|
+
|
|
540
|
+
$env.config.completions.external.completer = {|spans|
|
|
541
|
+
# Check if this is for our program
|
|
542
|
+
if ($spans.0 == "${programName}") {
|
|
543
|
+
# Build context string from spans
|
|
544
|
+
let context = $spans | str join ' '
|
|
545
|
+
${functionName} $context
|
|
546
|
+
} else if ($existing_completer != null) {
|
|
547
|
+
# Delegate to existing completer
|
|
548
|
+
do $existing_completer $spans
|
|
549
|
+
} else {
|
|
550
|
+
# No completions
|
|
551
|
+
null
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
$env.config.completions.external.enable = true
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
# Auto-setup: register the completer when this module is imported
|
|
559
|
+
${functionName}-external
|
|
560
|
+
`;
|
|
561
|
+
},
|
|
562
|
+
*encodeSuggestions(suggestions) {
|
|
563
|
+
let i = 0;
|
|
564
|
+
for (const suggestion of suggestions) {
|
|
565
|
+
if (i > 0) yield "\n";
|
|
566
|
+
if (suggestion.kind === "literal") {
|
|
567
|
+
const description = suggestion.description == null ? "" : formatMessage(suggestion.description, { colors: false });
|
|
568
|
+
yield `${suggestion.text}\t${description}`;
|
|
569
|
+
} else {
|
|
570
|
+
const extensions = suggestion.extensions?.join(",") || "";
|
|
571
|
+
const hidden = suggestion.includeHidden ? "1" : "0";
|
|
572
|
+
const description = suggestion.description == null ? "" : formatMessage(suggestion.description, { colors: false });
|
|
573
|
+
yield `__FILE__:${suggestion.type}:${extensions}:${suggestion.pattern || ""}:${hidden}\t${description}`;
|
|
574
|
+
}
|
|
575
|
+
i++;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
};
|
|
579
|
+
/**
|
|
351
580
|
* The PowerShell completion generator.
|
|
352
581
|
* @since 0.6.0
|
|
353
582
|
*/
|
|
@@ -507,4 +736,4 @@ ${escapedArgs ? ` \$completionArgs += @(${escapedArgs})
|
|
|
507
736
|
};
|
|
508
737
|
|
|
509
738
|
//#endregion
|
|
510
|
-
export { bash, fish, pwsh, zsh };
|
|
739
|
+
export { bash, fish, nu, pwsh, zsh };
|
package/dist/facade.cjs
CHANGED
|
@@ -264,7 +264,7 @@ function classifyResult(result, args) {
|
|
|
264
264
|
* Handles shell completion requests.
|
|
265
265
|
* @since 0.6.0
|
|
266
266
|
*/
|
|
267
|
-
function handleCompletion(completionArgs, programName, parser, stdout, stderr, onCompletion, onError, colors) {
|
|
267
|
+
function handleCompletion(completionArgs, programName, parser, stdout, stderr, onCompletion, onError, availableShells, colors) {
|
|
268
268
|
if (completionArgs.length === 0) {
|
|
269
269
|
stderr("Error: Missing shell name for completion.\n");
|
|
270
270
|
stderr("Usage: " + programName + " completion <shell> [args...]\n");
|
|
@@ -272,12 +272,6 @@ function handleCompletion(completionArgs, programName, parser, stdout, stderr, o
|
|
|
272
272
|
}
|
|
273
273
|
const shellName = completionArgs[0];
|
|
274
274
|
const args = completionArgs.slice(1);
|
|
275
|
-
const availableShells = {
|
|
276
|
-
bash: require_completion.bash,
|
|
277
|
-
fish: require_completion.fish,
|
|
278
|
-
pwsh: require_completion.pwsh,
|
|
279
|
-
zsh: require_completion.zsh
|
|
280
|
-
};
|
|
281
275
|
const shell = availableShells[shellName];
|
|
282
276
|
if (!shell) {
|
|
283
277
|
const available = [];
|
|
@@ -340,17 +334,28 @@ function run(parser, programName, args, options = {}) {
|
|
|
340
334
|
const completionMode = options.completion?.mode ?? "both";
|
|
341
335
|
const onCompletion = options.completion?.onShow ?? (() => ({}));
|
|
342
336
|
if (options.completion) {
|
|
343
|
-
|
|
337
|
+
const defaultShells = {
|
|
338
|
+
bash: require_completion.bash,
|
|
339
|
+
fish: require_completion.fish,
|
|
340
|
+
nu: require_completion.nu,
|
|
341
|
+
pwsh: require_completion.pwsh,
|
|
342
|
+
zsh: require_completion.zsh
|
|
343
|
+
};
|
|
344
|
+
const availableShells = options.completion.shells ? {
|
|
345
|
+
...defaultShells,
|
|
346
|
+
...options.completion.shells
|
|
347
|
+
} : defaultShells;
|
|
348
|
+
if ((completionMode === "command" || completionMode === "both") && args.length >= 1 && args[0] === "completion") return handleCompletion(args.slice(1), programName, parser, stdout, stderr, onCompletion, onError, availableShells, colors);
|
|
344
349
|
if (completionMode === "option" || completionMode === "both") for (let i = 0; i < args.length; i++) {
|
|
345
350
|
const arg = args[i];
|
|
346
351
|
if (arg.startsWith("--completion=")) {
|
|
347
352
|
const shell = arg.slice(13);
|
|
348
353
|
const completionArgs = args.slice(i + 1);
|
|
349
|
-
return handleCompletion([shell, ...completionArgs], programName, parser, stdout, stderr, onCompletion, onError, colors);
|
|
354
|
+
return handleCompletion([shell, ...completionArgs], programName, parser, stdout, stderr, onCompletion, onError, availableShells, colors);
|
|
350
355
|
} else if (arg === "--completion" && i + 1 < args.length) {
|
|
351
356
|
const shell = args[i + 1];
|
|
352
357
|
const completionArgs = args.slice(i + 2);
|
|
353
|
-
return handleCompletion([shell, ...completionArgs], programName, parser, stdout, stderr, onCompletion, onError, colors);
|
|
358
|
+
return handleCompletion([shell, ...completionArgs], programName, parser, stdout, stderr, onCompletion, onError, availableShells, colors);
|
|
354
359
|
}
|
|
355
360
|
}
|
|
356
361
|
}
|
package/dist/facade.d.cts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Message } from "./message.cjs";
|
|
2
2
|
import { ShowDefaultOptions } from "./doc.cjs";
|
|
3
3
|
import { InferValue, Parser } from "./parser.cjs";
|
|
4
|
+
import { ShellCompletion } from "./completion.cjs";
|
|
4
5
|
|
|
5
6
|
//#region src/facade.d.ts
|
|
6
7
|
|
|
@@ -103,6 +104,14 @@ interface RunOptions<THelp, TError> {
|
|
|
103
104
|
* @default `"both"`
|
|
104
105
|
*/
|
|
105
106
|
readonly mode?: "command" | "option" | "both";
|
|
107
|
+
/**
|
|
108
|
+
* Available shell completions. By default, includes `bash`, `fish`, `nu`,
|
|
109
|
+
* `pwsh`, and `zsh`. You can provide additional custom shell completions or
|
|
110
|
+
* override the defaults.
|
|
111
|
+
*
|
|
112
|
+
* @default `{ bash, fish, nu, pwsh, zsh }`
|
|
113
|
+
*/
|
|
114
|
+
readonly shells?: Record<string, ShellCompletion>;
|
|
106
115
|
/**
|
|
107
116
|
* Callback function invoked when completion is requested. The function can
|
|
108
117
|
* optionally receive an exit code parameter.
|
package/dist/facade.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Message } from "./message.js";
|
|
2
2
|
import { ShowDefaultOptions } from "./doc.js";
|
|
3
3
|
import { InferValue, Parser } from "./parser.js";
|
|
4
|
+
import { ShellCompletion } from "./completion.js";
|
|
4
5
|
|
|
5
6
|
//#region src/facade.d.ts
|
|
6
7
|
|
|
@@ -103,6 +104,14 @@ interface RunOptions<THelp, TError> {
|
|
|
103
104
|
* @default `"both"`
|
|
104
105
|
*/
|
|
105
106
|
readonly mode?: "command" | "option" | "both";
|
|
107
|
+
/**
|
|
108
|
+
* Available shell completions. By default, includes `bash`, `fish`, `nu`,
|
|
109
|
+
* `pwsh`, and `zsh`. You can provide additional custom shell completions or
|
|
110
|
+
* override the defaults.
|
|
111
|
+
*
|
|
112
|
+
* @default `{ bash, fish, nu, pwsh, zsh }`
|
|
113
|
+
*/
|
|
114
|
+
readonly shells?: Record<string, ShellCompletion>;
|
|
106
115
|
/**
|
|
107
116
|
* Callback function invoked when completion is requested. The function can
|
|
108
117
|
* optionally receive an exit code parameter.
|
package/dist/facade.js
CHANGED
|
@@ -2,7 +2,7 @@ import { formatMessage, message, optionName, text, value } from "./message.js";
|
|
|
2
2
|
import { longestMatch, object } from "./constructs.js";
|
|
3
3
|
import { formatUsage } from "./usage.js";
|
|
4
4
|
import { formatDocPage } from "./doc.js";
|
|
5
|
-
import { bash, fish, pwsh, zsh } from "./completion.js";
|
|
5
|
+
import { bash, fish, nu, pwsh, zsh } from "./completion.js";
|
|
6
6
|
import { multiple, optional } from "./modifiers.js";
|
|
7
7
|
import { string } from "./valueparser.js";
|
|
8
8
|
import { argument, command, constant, flag } from "./primitives.js";
|
|
@@ -264,7 +264,7 @@ function classifyResult(result, args) {
|
|
|
264
264
|
* Handles shell completion requests.
|
|
265
265
|
* @since 0.6.0
|
|
266
266
|
*/
|
|
267
|
-
function handleCompletion(completionArgs, programName, parser, stdout, stderr, onCompletion, onError, colors) {
|
|
267
|
+
function handleCompletion(completionArgs, programName, parser, stdout, stderr, onCompletion, onError, availableShells, colors) {
|
|
268
268
|
if (completionArgs.length === 0) {
|
|
269
269
|
stderr("Error: Missing shell name for completion.\n");
|
|
270
270
|
stderr("Usage: " + programName + " completion <shell> [args...]\n");
|
|
@@ -272,12 +272,6 @@ function handleCompletion(completionArgs, programName, parser, stdout, stderr, o
|
|
|
272
272
|
}
|
|
273
273
|
const shellName = completionArgs[0];
|
|
274
274
|
const args = completionArgs.slice(1);
|
|
275
|
-
const availableShells = {
|
|
276
|
-
bash,
|
|
277
|
-
fish,
|
|
278
|
-
pwsh,
|
|
279
|
-
zsh
|
|
280
|
-
};
|
|
281
275
|
const shell = availableShells[shellName];
|
|
282
276
|
if (!shell) {
|
|
283
277
|
const available = [];
|
|
@@ -340,17 +334,28 @@ function run(parser, programName, args, options = {}) {
|
|
|
340
334
|
const completionMode = options.completion?.mode ?? "both";
|
|
341
335
|
const onCompletion = options.completion?.onShow ?? (() => ({}));
|
|
342
336
|
if (options.completion) {
|
|
343
|
-
|
|
337
|
+
const defaultShells = {
|
|
338
|
+
bash,
|
|
339
|
+
fish,
|
|
340
|
+
nu,
|
|
341
|
+
pwsh,
|
|
342
|
+
zsh
|
|
343
|
+
};
|
|
344
|
+
const availableShells = options.completion.shells ? {
|
|
345
|
+
...defaultShells,
|
|
346
|
+
...options.completion.shells
|
|
347
|
+
} : defaultShells;
|
|
348
|
+
if ((completionMode === "command" || completionMode === "both") && args.length >= 1 && args[0] === "completion") return handleCompletion(args.slice(1), programName, parser, stdout, stderr, onCompletion, onError, availableShells, colors);
|
|
344
349
|
if (completionMode === "option" || completionMode === "both") for (let i = 0; i < args.length; i++) {
|
|
345
350
|
const arg = args[i];
|
|
346
351
|
if (arg.startsWith("--completion=")) {
|
|
347
352
|
const shell = arg.slice(13);
|
|
348
353
|
const completionArgs = args.slice(i + 1);
|
|
349
|
-
return handleCompletion([shell, ...completionArgs], programName, parser, stdout, stderr, onCompletion, onError, colors);
|
|
354
|
+
return handleCompletion([shell, ...completionArgs], programName, parser, stdout, stderr, onCompletion, onError, availableShells, colors);
|
|
350
355
|
} else if (arg === "--completion" && i + 1 < args.length) {
|
|
351
356
|
const shell = args[i + 1];
|
|
352
357
|
const completionArgs = args.slice(i + 2);
|
|
353
|
-
return handleCompletion([shell, ...completionArgs], programName, parser, stdout, stderr, onCompletion, onError, colors);
|
|
358
|
+
return handleCompletion([shell, ...completionArgs], programName, parser, stdout, stderr, onCompletion, onError, availableShells, colors);
|
|
354
359
|
}
|
|
355
360
|
}
|
|
356
361
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -37,6 +37,7 @@ exports.message = require_message.message;
|
|
|
37
37
|
exports.metavar = require_message.metavar;
|
|
38
38
|
exports.multiple = require_modifiers.multiple;
|
|
39
39
|
exports.normalizeUsage = require_usage.normalizeUsage;
|
|
40
|
+
exports.nu = require_completion.nu;
|
|
40
41
|
exports.object = require_constructs.object;
|
|
41
42
|
exports.option = require_primitives.option;
|
|
42
43
|
exports.optionName = require_message.optionName;
|
package/dist/index.d.cts
CHANGED
|
@@ -6,6 +6,6 @@ import { MultipleErrorOptions, MultipleOptions, WithDefaultError, WithDefaultOpt
|
|
|
6
6
|
import { ArgumentErrorOptions, ArgumentOptions, CommandErrorOptions, CommandOptions, FlagErrorOptions, FlagOptions, OptionErrorOptions, OptionOptions, argument, command, constant, flag, option } from "./primitives.cjs";
|
|
7
7
|
import { DocState, InferValue, Parser, ParserContext, ParserResult, Result, Suggestion, getDocPage, parse, suggest } from "./parser.cjs";
|
|
8
8
|
import { LongestMatchErrorOptions, LongestMatchOptions, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, concat, group, longestMatch, merge, object, or, tuple } from "./constructs.cjs";
|
|
9
|
+
import { ShellCompletion, bash, fish, nu, pwsh, zsh } from "./completion.cjs";
|
|
9
10
|
import { RunError, RunOptions, run } from "./facade.cjs";
|
|
10
|
-
|
|
11
|
-
export { ArgumentErrorOptions, ArgumentOptions, ChoiceOptions, CommandErrorOptions, CommandOptions, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, DocState, FlagErrorOptions, FlagOptions, FloatOptions, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, LongestMatchErrorOptions, LongestMatchOptions, Message, MessageFormatOptions, MessageTerm, MultipleErrorOptions, MultipleOptions, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionName, OptionOptions, OrErrorOptions, OrOptions, Parser, ParserContext, ParserResult, Result, RunError, RunOptions, ShellCompletion, ShowDefaultOptions, StringOptions, Suggestion, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, WithDefaultError, WithDefaultOptions, argument, bash, choice, command, concat, constant, envVar, fish, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, group, integer, isValueParser, locale, longestMatch, map, merge, message, metavar, multiple, normalizeUsage, object, option, optionName, optionNames, optional, or, parse, pwsh, run, string, suggest, text, tuple, url, uuid, value, values, withDefault, zsh };
|
|
11
|
+
export { ArgumentErrorOptions, ArgumentOptions, ChoiceOptions, CommandErrorOptions, CommandOptions, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, DocState, FlagErrorOptions, FlagOptions, FloatOptions, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, LongestMatchErrorOptions, LongestMatchOptions, Message, MessageFormatOptions, MessageTerm, MultipleErrorOptions, MultipleOptions, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionName, OptionOptions, OrErrorOptions, OrOptions, Parser, ParserContext, ParserResult, Result, RunError, RunOptions, ShellCompletion, ShowDefaultOptions, StringOptions, Suggestion, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, WithDefaultError, WithDefaultOptions, argument, bash, choice, command, concat, constant, envVar, fish, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, group, integer, isValueParser, locale, longestMatch, map, merge, message, metavar, multiple, normalizeUsage, nu, object, option, optionName, optionNames, optional, or, parse, pwsh, run, string, suggest, text, tuple, url, uuid, value, values, withDefault, zsh };
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,6 @@ import { MultipleErrorOptions, MultipleOptions, WithDefaultError, WithDefaultOpt
|
|
|
6
6
|
import { ArgumentErrorOptions, ArgumentOptions, CommandErrorOptions, CommandOptions, FlagErrorOptions, FlagOptions, OptionErrorOptions, OptionOptions, argument, command, constant, flag, option } from "./primitives.js";
|
|
7
7
|
import { DocState, InferValue, Parser, ParserContext, ParserResult, Result, Suggestion, getDocPage, parse, suggest } from "./parser.js";
|
|
8
8
|
import { LongestMatchErrorOptions, LongestMatchOptions, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, concat, group, longestMatch, merge, object, or, tuple } from "./constructs.js";
|
|
9
|
+
import { ShellCompletion, bash, fish, nu, pwsh, zsh } from "./completion.js";
|
|
9
10
|
import { RunError, RunOptions, run } from "./facade.js";
|
|
10
|
-
|
|
11
|
-
export { ArgumentErrorOptions, ArgumentOptions, ChoiceOptions, CommandErrorOptions, CommandOptions, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, DocState, FlagErrorOptions, FlagOptions, FloatOptions, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, LongestMatchErrorOptions, LongestMatchOptions, Message, MessageFormatOptions, MessageTerm, MultipleErrorOptions, MultipleOptions, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionName, OptionOptions, OrErrorOptions, OrOptions, Parser, ParserContext, ParserResult, Result, RunError, RunOptions, ShellCompletion, ShowDefaultOptions, StringOptions, Suggestion, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, WithDefaultError, WithDefaultOptions, argument, bash, choice, command, concat, constant, envVar, fish, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, group, integer, isValueParser, locale, longestMatch, map, merge, message, metavar, multiple, normalizeUsage, object, option, optionName, optionNames, optional, or, parse, pwsh, run, string, suggest, text, tuple, url, uuid, value, values, withDefault, zsh };
|
|
11
|
+
export { ArgumentErrorOptions, ArgumentOptions, ChoiceOptions, CommandErrorOptions, CommandOptions, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, DocState, FlagErrorOptions, FlagOptions, FloatOptions, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, LongestMatchErrorOptions, LongestMatchOptions, Message, MessageFormatOptions, MessageTerm, MultipleErrorOptions, MultipleOptions, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionName, OptionOptions, OrErrorOptions, OrOptions, Parser, ParserContext, ParserResult, Result, RunError, RunOptions, ShellCompletion, ShowDefaultOptions, StringOptions, Suggestion, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, WithDefaultError, WithDefaultOptions, argument, bash, choice, command, concat, constant, envVar, fish, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, group, integer, isValueParser, locale, longestMatch, map, merge, message, metavar, multiple, normalizeUsage, nu, object, option, optionName, optionNames, optional, or, parse, pwsh, run, string, suggest, text, tuple, url, uuid, value, values, withDefault, zsh };
|
package/dist/index.js
CHANGED
|
@@ -2,11 +2,11 @@ import { envVar, formatMessage, message, metavar, optionName, optionNames, text,
|
|
|
2
2
|
import { concat, group, longestMatch, merge, object, or, tuple } from "./constructs.js";
|
|
3
3
|
import { formatUsage, formatUsageTerm, normalizeUsage } from "./usage.js";
|
|
4
4
|
import { formatDocPage } from "./doc.js";
|
|
5
|
-
import { bash, fish, pwsh, zsh } from "./completion.js";
|
|
5
|
+
import { bash, fish, nu, pwsh, zsh } from "./completion.js";
|
|
6
6
|
import { WithDefaultError, map, multiple, optional, withDefault } from "./modifiers.js";
|
|
7
7
|
import { choice, float, integer, isValueParser, locale, string, url, uuid } from "./valueparser.js";
|
|
8
8
|
import { argument, command, constant, flag, option } from "./primitives.js";
|
|
9
9
|
import { getDocPage, parse, suggest } from "./parser.js";
|
|
10
10
|
import { RunError, run } from "./facade.js";
|
|
11
11
|
|
|
12
|
-
export { RunError, WithDefaultError, argument, bash, choice, command, concat, constant, envVar, fish, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, group, integer, isValueParser, locale, longestMatch, map, merge, message, metavar, multiple, normalizeUsage, object, option, optionName, optionNames, optional, or, parse, pwsh, run, string, suggest, text, tuple, url, uuid, value, values, withDefault, zsh };
|
|
12
|
+
export { RunError, WithDefaultError, argument, bash, choice, command, concat, constant, envVar, fish, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, group, integer, isValueParser, locale, longestMatch, map, merge, message, metavar, multiple, normalizeUsage, nu, object, option, optionName, optionNames, optional, or, parse, pwsh, run, string, suggest, text, tuple, url, uuid, value, values, withDefault, zsh };
|