1
Fork 0
mirror of https://github.com/RGBCube/nu_scripts synced 2025-08-01 06:37:46 +00:00

Fix parse-fish.nu (#1094)

Adjust so it does not throw syntax errors and works for at least some
sampled `.fish` files.

Related #968, #258, #256

---

Sample `abook`:

```nushell
nu ❯ rm abook.nu -f; build-completion abook.fish abook.nu; open abook.nu
# Show usage
extern "abook" [
        --add-email                                     # Read email message from stdin and add the sender
        --add-email-quiet                                       # Same as --add-email. Without confirmation
        --convert                                       # Convert address book files
        --informat                                      # Input file format
        --outformat                                     # Output file format
        --formats                                       # Print available formats
        ...args
]
```
This commit is contained in:
Jan Klass 2025-04-20 17:03:24 +02:00 committed by GitHub
parent 98973a271f
commit c62a46d6e3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -39,16 +39,15 @@ def parse-fish [] {
# make use of detect columns -n which with one like properly tokenizers arguments including across quotes # make use of detect columns -n which with one like properly tokenizers arguments including across quotes
def tokenize-complete-lines [] { def tokenize-complete-lines [] {
lines lines
| each { |line| | where ($it | str length) > 0 # remove any empty lines
$line | where $it starts-with 'complete' # only complete command lines
| where $line starts-with complete | each {
| str replace -a "\\\\'" "" # remove escaped quotes ' which break detect columns str replace -a "\\\\'" "" # remove escaped quotes ' which break detect columns
| str replace -a "-f " "" # remove -f which is a boolean flag we don't support yet | str replace -a "-f " "" # remove -f which is a boolean flag we don't support yet
| detect columns -n | detect columns -n
| transpose -i tokens # turn columns into items, each is a token | transpose -i tokens
| get tokens
} }
| where ($it | length) > 0 # remove any empty lines
| get tokens # get the list of tokens
} }
# turn a list of tokens for a line into a record of {flag: arg} # turn a list of tokens for a line into a record of {flag: arg}
@ -80,28 +79,32 @@ def make-commands-completion [] {
| get c # c is the command name | get c # c is the command name
| uniq # is cloned on every complete line | uniq # is cloned on every complete line
| each { |command| | each { |command|
$fishes | where c == $command | make-subcommands-completion $command $fishes | where c == $command | make-subcommands-completion [$command]
| str join "\n\n"
} }
} }
# make the action nu completion string from subcommand and args # make the action nu completion string from subcommand and args
# subcommand can be empty which will be the root command # subcommand can be empty which will be the root command
def make-subcommands-completion [parents: list] { def make-subcommands-completion [parents: list<string>] {
let quote = '"' # " let quote = '"' # a `"`
let fishes = $in let fishes = $in
$fishes $fishes
| group-by a # group by sub command (a flag) | group-by a # group by sub command (a flag)
| transpose name args # turn it into a table of name to arguments | transpose name args # turn it into a table of name to arguments
| each {|subcommand| | each {|subcommand|
build-string ( [
if ('d' in ($subcommand.args | columns)) and ($subcommand.args.d != "") { # description
build-string "# " ($subcommand.args.d.0) "\n" # (sub)command description (if ('d' in ($subcommand.args | columns)) and ($subcommand.args.d != "") { $"# ($subcommand.args.d.0)\n" })
}) "extern " $quote ($parents | str join " ") ( # extern name
if $subcommand.name != "" { $'extern "($parents | append $subcommand.name | str join " " | str trim)"'
build-string " " $subcommand.name # sub command if present # params
}) $quote " [\n" ( " [\n"
(
$fishes $fishes
| if ('n' in ($in | columns)) { | if ('n' in ($subcommand | columns)) {
if ($subcommand.name != "") { if ($subcommand.name != "") {
where ($it.n | str contains $subcommand.name) # for subcommand -> any where n matches `__fish_seen_subcommand_from arg` for the subcommand name where ($it.n | str contains $subcommand.name) # for subcommand -> any where n matches `__fish_seen_subcommand_from arg` for the subcommand name
} else { } else {
@ -112,21 +115,29 @@ def make-subcommands-completion [parents: list] {
} }
| build-flags | build-flags
| str join "\n" | str join "\n"
) "\n\t...args\n]" )
"\n\t...args"
"\n]"
]
| str join
} }
} }
# build the list of flag string in nu syntax # build the list of flag string in nu syntax
# record<c, n, a, d, o> -> list<string>
def build-flags [] { def build-flags [] {
each { |subargs| $in
| each { |subargs|
if ('l' in ($subargs | columns)) and ($subargs.l != "") { if ('l' in ($subargs | columns)) and ($subargs.l != "") {
build-string "\t--" $subargs.l (build-string [
(if ('s' in ($subargs | columns)) and ($subargs.s != "") { "\t--" $subargs.l
build-string "(-" $subargs.s ")" (
}) (if ('d' in ($subargs | columns)) and ($subargs.d != "") { [
build-string "\t\t\t\t\t# " $subargs.d (if ('s' in ($subargs | columns)) and ($subargs.s != "") { [ "(-" $subargs.s ")" ] | str join })
}) (if ('d' in ($subargs | columns)) and ($subargs.d != "") { [ "\t\t\t\t\t# " $subargs.d ] | str join })
] | str join
) )
] | str join
} }
} }
} }