@optique/core 1.0.15-dev.2813 → 1.0.15-dev.2816
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 +90 -16
- package/dist/completion.js +90 -16
- package/package.json +1 -1
package/dist/completion.cjs
CHANGED
|
@@ -1186,8 +1186,10 @@ def args-split []: string -> list<string> {
|
|
|
1186
1186
|
mut current_token = ""
|
|
1187
1187
|
mut result: list<string> = []
|
|
1188
1188
|
mut prev_state = $STATE_NORMAL
|
|
1189
|
+
mut ends_with_delimiter = false
|
|
1189
1190
|
|
|
1190
1191
|
for char in ($in | split chars) {
|
|
1192
|
+
$ends_with_delimiter = false
|
|
1191
1193
|
if $state == $STATE_ESCAPE {
|
|
1192
1194
|
$current_token = $current_token + $char
|
|
1193
1195
|
$state = $prev_state
|
|
@@ -1200,6 +1202,7 @@ def args-split []: string -> list<string> {
|
|
|
1200
1202
|
} else if $char == '"' {
|
|
1201
1203
|
$state = $STATE_IN_DOUBLE_QUOTE
|
|
1202
1204
|
} else if ($char in $WHITESPACES) {
|
|
1205
|
+
$ends_with_delimiter = true
|
|
1203
1206
|
if ($current_token | is-not-empty) {
|
|
1204
1207
|
$result = $result | append $current_token
|
|
1205
1208
|
$current_token = ""
|
|
@@ -1221,12 +1224,52 @@ def args-split []: string -> list<string> {
|
|
|
1221
1224
|
}
|
|
1222
1225
|
}
|
|
1223
1226
|
}
|
|
1224
|
-
|
|
1227
|
+
# A quote left open at the end starts the argument being completed, even
|
|
1228
|
+
# when nothing follows it yet
|
|
1229
|
+
if ($current_token | is-not-empty) or ($state in [$STATE_IN_SINGLE_QUOTE $STATE_IN_DOUBLE_QUOTE]) {
|
|
1225
1230
|
$result = $result | append $current_token
|
|
1226
1231
|
}
|
|
1232
|
+
# Whitespace outside quotes at the end starts a new, still empty argument
|
|
1233
|
+
if $ends_with_delimiter {
|
|
1234
|
+
$result = $result | append ''
|
|
1235
|
+
}
|
|
1227
1236
|
$result
|
|
1228
1237
|
}
|
|
1229
1238
|
|
|
1239
|
+
# Helper to tell whether Nushell would not read a value back verbatim as a
|
|
1240
|
+
# single argument. A leading ! is included because the line editor expands
|
|
1241
|
+
# history (e.g., !!) there. With --allow-expansion, a leading tilde and n-dot
|
|
1242
|
+
# path segments (e.g., ...) are allowed to expand.
|
|
1243
|
+
def needs-quote [--allow-expansion]: string -> bool {
|
|
1244
|
+
let value = $in
|
|
1245
|
+
let special = ["'" '"' '\`' "#" "(" ")" "[" "]" "{" "}" "|" ";" "&" "$" "*" "?" "<" ">"]
|
|
1246
|
+
(
|
|
1247
|
+
($value =~ '\\s')
|
|
1248
|
+
or ($special | any {|c| $value | str contains $c })
|
|
1249
|
+
or ($value =~ '^(\\+\\+|[-+*/])?=$')
|
|
1250
|
+
or ($value | str starts-with '!')
|
|
1251
|
+
or ((not $allow_expansion) and (
|
|
1252
|
+
($value | str starts-with '~')
|
|
1253
|
+
or ($value | split row -r '[/\\\\]' | any {|s| $s =~ '^\\.{3,}$' })
|
|
1254
|
+
))
|
|
1255
|
+
)
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
# Helper to quote a value so that Nushell reads it back verbatim as a
|
|
1259
|
+
# single argument. The line editor expands history at a ! that follows
|
|
1260
|
+
# whitespace even inside quotes, so such a ! is put between two quoted parts,
|
|
1261
|
+
# right after a quote, where it is left alone.
|
|
1262
|
+
def quote-arg []: string -> string {
|
|
1263
|
+
let value = $in
|
|
1264
|
+
if ($value | is-empty) or not ($value | needs-quote) {
|
|
1265
|
+
$value
|
|
1266
|
+
} else if ($value | str contains "'") {
|
|
1267
|
+
'"' + ($value | str replace -a '\\' '\\\\' | str replace -a '"' '\\"' | str replace -ar '(\\s)!' '\${1}"!"') + '"'
|
|
1268
|
+
} else {
|
|
1269
|
+
"'" + ($value | str replace -ar '(\\s)!' "\${1}'!'") + "'"
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1230
1273
|
# Completion command that calls back to the CLI
|
|
1231
1274
|
export def "${functionName}" [context: string] {
|
|
1232
1275
|
# Split context into tokens, handling quotes properly
|
|
@@ -1239,18 +1282,11 @@ export def "${functionName}" [context: string] {
|
|
|
1239
1282
|
[]
|
|
1240
1283
|
}
|
|
1241
1284
|
|
|
1242
|
-
# If context ends with whitespace, add empty string to represent the new argument
|
|
1243
|
-
let args_with_empty = if ($context | str ends-with ' ') {
|
|
1244
|
-
$args | append ''
|
|
1245
|
-
} else {
|
|
1246
|
-
$args
|
|
1247
|
-
}
|
|
1248
|
-
|
|
1249
1285
|
# Ensure at least one argument (empty string) to get completions not script
|
|
1250
|
-
let final_args = if ($
|
|
1286
|
+
let final_args = if ($args | is-empty) {
|
|
1251
1287
|
['']
|
|
1252
1288
|
} else {
|
|
1253
|
-
$
|
|
1289
|
+
$args
|
|
1254
1290
|
}
|
|
1255
1291
|
|
|
1256
1292
|
let output = try {
|
|
@@ -1432,19 +1468,45 @@ ${escapedArgs ? ` ^${programName} ${escapedArgs} ...$final_args | complete |
|
|
|
1432
1468
|
if ($parsed.parent | is-empty) { "" } else if ($parsed.parent | str ends-with "/") { $parsed.parent } else { $parsed.parent + "/" }
|
|
1433
1469
|
}
|
|
1434
1470
|
|
|
1435
|
-
# Format file completions
|
|
1471
|
+
# Format file completions, quoting names that Nushell would not read
|
|
1472
|
+
# back as a single argument
|
|
1436
1473
|
$filtered | each {|item|
|
|
1437
|
-
let
|
|
1438
|
-
|
|
1474
|
+
let base = if $item.type == dir {
|
|
1475
|
+
($item.name | path basename) + "/"
|
|
1439
1476
|
} else {
|
|
1440
|
-
$
|
|
1477
|
+
$item.name | path basename
|
|
1478
|
+
}
|
|
1479
|
+
let name = $dir_prefix + $base
|
|
1480
|
+
# Nushell expands a leading tilde even in a file name, but not after ./
|
|
1481
|
+
let spelled = if ($dir_prefix | is-empty) and ($base | str starts-with '~') {
|
|
1482
|
+
'./' + $base
|
|
1483
|
+
} else {
|
|
1484
|
+
$name
|
|
1485
|
+
}
|
|
1486
|
+
# A tilde or n-dot prefix typed by the user is meant to be expanded
|
|
1487
|
+
# by Nushell, which quoting would prevent, so expand such a prefix
|
|
1488
|
+
# here when the value has to be quoted
|
|
1489
|
+
let literal_ndots = ($base | str replace -r '[/\\\\]$' '') =~ '^\\.{3,}$'
|
|
1490
|
+
let expandable = ($dir_prefix | str starts-with '~') or ($dir_prefix | split row -r '[/\\\\]' | any {|s| $s =~ '^\\.{3,}$' })
|
|
1491
|
+
let value = if not ($literal_ndots or ($spelled | needs-quote --allow-expansion)) {
|
|
1492
|
+
$spelled
|
|
1493
|
+
} else if $expandable {
|
|
1494
|
+
let expanded_prefix = ($dir_prefix | path expand --no-symlink)
|
|
1495
|
+
let expanded_prefix = if ($expanded_prefix | str ends-with "/") { $expanded_prefix } else { $expanded_prefix + "/" }
|
|
1496
|
+
($expanded_prefix + $base) | quote-arg
|
|
1497
|
+
} else {
|
|
1498
|
+
$spelled | quote-arg
|
|
1499
|
+
}
|
|
1500
|
+
if $value == $name {
|
|
1501
|
+
{ value: $value }
|
|
1502
|
+
} else {
|
|
1503
|
+
{ value: $value, display_override: $name }
|
|
1441
1504
|
}
|
|
1442
|
-
{ value: $name }
|
|
1443
1505
|
}
|
|
1444
1506
|
} else {
|
|
1445
1507
|
# Regular literal completion - split by tab
|
|
1446
1508
|
let parts = ($line | split row "\t")
|
|
1447
|
-
if ($parts | length) >= 2 {
|
|
1509
|
+
let record = if ($parts | length) >= 2 {
|
|
1448
1510
|
# value\\tdescription format
|
|
1449
1511
|
{ value: ($parts | get 0), description: ($parts | get 1) }
|
|
1450
1512
|
} else if ($parts | length) == 1 and ($parts | get 0 | is-not-empty) {
|
|
@@ -1453,6 +1515,18 @@ ${escapedArgs ? ` ^${programName} ${escapedArgs} ...$final_args | complete |
|
|
|
1453
1515
|
} else {
|
|
1454
1516
|
null
|
|
1455
1517
|
}
|
|
1518
|
+
# Quote values that Nushell would not read back as a single argument,
|
|
1519
|
+
# while the menu keeps showing them as they are
|
|
1520
|
+
if $record == null {
|
|
1521
|
+
null
|
|
1522
|
+
} else {
|
|
1523
|
+
let value = ($record.value | quote-arg)
|
|
1524
|
+
if $value == $record.value {
|
|
1525
|
+
$record
|
|
1526
|
+
} else {
|
|
1527
|
+
$record | upsert value $value | insert display_override $record.value
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1456
1530
|
}
|
|
1457
1531
|
} | flatten | compact
|
|
1458
1532
|
}
|
package/dist/completion.js
CHANGED
|
@@ -1186,8 +1186,10 @@ def args-split []: string -> list<string> {
|
|
|
1186
1186
|
mut current_token = ""
|
|
1187
1187
|
mut result: list<string> = []
|
|
1188
1188
|
mut prev_state = $STATE_NORMAL
|
|
1189
|
+
mut ends_with_delimiter = false
|
|
1189
1190
|
|
|
1190
1191
|
for char in ($in | split chars) {
|
|
1192
|
+
$ends_with_delimiter = false
|
|
1191
1193
|
if $state == $STATE_ESCAPE {
|
|
1192
1194
|
$current_token = $current_token + $char
|
|
1193
1195
|
$state = $prev_state
|
|
@@ -1200,6 +1202,7 @@ def args-split []: string -> list<string> {
|
|
|
1200
1202
|
} else if $char == '"' {
|
|
1201
1203
|
$state = $STATE_IN_DOUBLE_QUOTE
|
|
1202
1204
|
} else if ($char in $WHITESPACES) {
|
|
1205
|
+
$ends_with_delimiter = true
|
|
1203
1206
|
if ($current_token | is-not-empty) {
|
|
1204
1207
|
$result = $result | append $current_token
|
|
1205
1208
|
$current_token = ""
|
|
@@ -1221,12 +1224,52 @@ def args-split []: string -> list<string> {
|
|
|
1221
1224
|
}
|
|
1222
1225
|
}
|
|
1223
1226
|
}
|
|
1224
|
-
|
|
1227
|
+
# A quote left open at the end starts the argument being completed, even
|
|
1228
|
+
# when nothing follows it yet
|
|
1229
|
+
if ($current_token | is-not-empty) or ($state in [$STATE_IN_SINGLE_QUOTE $STATE_IN_DOUBLE_QUOTE]) {
|
|
1225
1230
|
$result = $result | append $current_token
|
|
1226
1231
|
}
|
|
1232
|
+
# Whitespace outside quotes at the end starts a new, still empty argument
|
|
1233
|
+
if $ends_with_delimiter {
|
|
1234
|
+
$result = $result | append ''
|
|
1235
|
+
}
|
|
1227
1236
|
$result
|
|
1228
1237
|
}
|
|
1229
1238
|
|
|
1239
|
+
# Helper to tell whether Nushell would not read a value back verbatim as a
|
|
1240
|
+
# single argument. A leading ! is included because the line editor expands
|
|
1241
|
+
# history (e.g., !!) there. With --allow-expansion, a leading tilde and n-dot
|
|
1242
|
+
# path segments (e.g., ...) are allowed to expand.
|
|
1243
|
+
def needs-quote [--allow-expansion]: string -> bool {
|
|
1244
|
+
let value = $in
|
|
1245
|
+
let special = ["'" '"' '\`' "#" "(" ")" "[" "]" "{" "}" "|" ";" "&" "$" "*" "?" "<" ">"]
|
|
1246
|
+
(
|
|
1247
|
+
($value =~ '\\s')
|
|
1248
|
+
or ($special | any {|c| $value | str contains $c })
|
|
1249
|
+
or ($value =~ '^(\\+\\+|[-+*/])?=$')
|
|
1250
|
+
or ($value | str starts-with '!')
|
|
1251
|
+
or ((not $allow_expansion) and (
|
|
1252
|
+
($value | str starts-with '~')
|
|
1253
|
+
or ($value | split row -r '[/\\\\]' | any {|s| $s =~ '^\\.{3,}$' })
|
|
1254
|
+
))
|
|
1255
|
+
)
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
# Helper to quote a value so that Nushell reads it back verbatim as a
|
|
1259
|
+
# single argument. The line editor expands history at a ! that follows
|
|
1260
|
+
# whitespace even inside quotes, so such a ! is put between two quoted parts,
|
|
1261
|
+
# right after a quote, where it is left alone.
|
|
1262
|
+
def quote-arg []: string -> string {
|
|
1263
|
+
let value = $in
|
|
1264
|
+
if ($value | is-empty) or not ($value | needs-quote) {
|
|
1265
|
+
$value
|
|
1266
|
+
} else if ($value | str contains "'") {
|
|
1267
|
+
'"' + ($value | str replace -a '\\' '\\\\' | str replace -a '"' '\\"' | str replace -ar '(\\s)!' '\${1}"!"') + '"'
|
|
1268
|
+
} else {
|
|
1269
|
+
"'" + ($value | str replace -ar '(\\s)!' "\${1}'!'") + "'"
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1230
1273
|
# Completion command that calls back to the CLI
|
|
1231
1274
|
export def "${functionName}" [context: string] {
|
|
1232
1275
|
# Split context into tokens, handling quotes properly
|
|
@@ -1239,18 +1282,11 @@ export def "${functionName}" [context: string] {
|
|
|
1239
1282
|
[]
|
|
1240
1283
|
}
|
|
1241
1284
|
|
|
1242
|
-
# If context ends with whitespace, add empty string to represent the new argument
|
|
1243
|
-
let args_with_empty = if ($context | str ends-with ' ') {
|
|
1244
|
-
$args | append ''
|
|
1245
|
-
} else {
|
|
1246
|
-
$args
|
|
1247
|
-
}
|
|
1248
|
-
|
|
1249
1285
|
# Ensure at least one argument (empty string) to get completions not script
|
|
1250
|
-
let final_args = if ($
|
|
1286
|
+
let final_args = if ($args | is-empty) {
|
|
1251
1287
|
['']
|
|
1252
1288
|
} else {
|
|
1253
|
-
$
|
|
1289
|
+
$args
|
|
1254
1290
|
}
|
|
1255
1291
|
|
|
1256
1292
|
let output = try {
|
|
@@ -1432,19 +1468,45 @@ ${escapedArgs ? ` ^${programName} ${escapedArgs} ...$final_args | complete |
|
|
|
1432
1468
|
if ($parsed.parent | is-empty) { "" } else if ($parsed.parent | str ends-with "/") { $parsed.parent } else { $parsed.parent + "/" }
|
|
1433
1469
|
}
|
|
1434
1470
|
|
|
1435
|
-
# Format file completions
|
|
1471
|
+
# Format file completions, quoting names that Nushell would not read
|
|
1472
|
+
# back as a single argument
|
|
1436
1473
|
$filtered | each {|item|
|
|
1437
|
-
let
|
|
1438
|
-
|
|
1474
|
+
let base = if $item.type == dir {
|
|
1475
|
+
($item.name | path basename) + "/"
|
|
1439
1476
|
} else {
|
|
1440
|
-
$
|
|
1477
|
+
$item.name | path basename
|
|
1478
|
+
}
|
|
1479
|
+
let name = $dir_prefix + $base
|
|
1480
|
+
# Nushell expands a leading tilde even in a file name, but not after ./
|
|
1481
|
+
let spelled = if ($dir_prefix | is-empty) and ($base | str starts-with '~') {
|
|
1482
|
+
'./' + $base
|
|
1483
|
+
} else {
|
|
1484
|
+
$name
|
|
1485
|
+
}
|
|
1486
|
+
# A tilde or n-dot prefix typed by the user is meant to be expanded
|
|
1487
|
+
# by Nushell, which quoting would prevent, so expand such a prefix
|
|
1488
|
+
# here when the value has to be quoted
|
|
1489
|
+
let literal_ndots = ($base | str replace -r '[/\\\\]$' '') =~ '^\\.{3,}$'
|
|
1490
|
+
let expandable = ($dir_prefix | str starts-with '~') or ($dir_prefix | split row -r '[/\\\\]' | any {|s| $s =~ '^\\.{3,}$' })
|
|
1491
|
+
let value = if not ($literal_ndots or ($spelled | needs-quote --allow-expansion)) {
|
|
1492
|
+
$spelled
|
|
1493
|
+
} else if $expandable {
|
|
1494
|
+
let expanded_prefix = ($dir_prefix | path expand --no-symlink)
|
|
1495
|
+
let expanded_prefix = if ($expanded_prefix | str ends-with "/") { $expanded_prefix } else { $expanded_prefix + "/" }
|
|
1496
|
+
($expanded_prefix + $base) | quote-arg
|
|
1497
|
+
} else {
|
|
1498
|
+
$spelled | quote-arg
|
|
1499
|
+
}
|
|
1500
|
+
if $value == $name {
|
|
1501
|
+
{ value: $value }
|
|
1502
|
+
} else {
|
|
1503
|
+
{ value: $value, display_override: $name }
|
|
1441
1504
|
}
|
|
1442
|
-
{ value: $name }
|
|
1443
1505
|
}
|
|
1444
1506
|
} else {
|
|
1445
1507
|
# Regular literal completion - split by tab
|
|
1446
1508
|
let parts = ($line | split row "\t")
|
|
1447
|
-
if ($parts | length) >= 2 {
|
|
1509
|
+
let record = if ($parts | length) >= 2 {
|
|
1448
1510
|
# value\\tdescription format
|
|
1449
1511
|
{ value: ($parts | get 0), description: ($parts | get 1) }
|
|
1450
1512
|
} else if ($parts | length) == 1 and ($parts | get 0 | is-not-empty) {
|
|
@@ -1453,6 +1515,18 @@ ${escapedArgs ? ` ^${programName} ${escapedArgs} ...$final_args | complete |
|
|
|
1453
1515
|
} else {
|
|
1454
1516
|
null
|
|
1455
1517
|
}
|
|
1518
|
+
# Quote values that Nushell would not read back as a single argument,
|
|
1519
|
+
# while the menu keeps showing them as they are
|
|
1520
|
+
if $record == null {
|
|
1521
|
+
null
|
|
1522
|
+
} else {
|
|
1523
|
+
let value = ($record.value | quote-arg)
|
|
1524
|
+
if $value == $record.value {
|
|
1525
|
+
$record
|
|
1526
|
+
} else {
|
|
1527
|
+
$record | upsert value $value | insert display_override $record.value
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1456
1530
|
}
|
|
1457
1531
|
} | flatten | compact
|
|
1458
1532
|
}
|