Skip to content

Commit c62a46d

Browse files
authored
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 ] ```
1 parent 98973a2 commit c62a46d

File tree

1 file changed

+51
-40
lines changed

1 file changed

+51
-40
lines changed

needs-update/custom-completions/auto-generate/parse-fish.nu

Lines changed: 51 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,15 @@ def parse-fish [] {
3939
# make use of detect columns -n which with one like properly tokenizers arguments including across quotes
4040
def tokenize-complete-lines [] {
4141
lines
42-
| each { |line|
43-
$line
44-
| where $line starts-with complete
45-
| str replace -a "\\\\'" "" # remove escaped quotes ' which break detect columns
46-
| str replace -a "-f " "" # remove -f which is a boolean flag we don't support yet
47-
| detect columns -n
48-
| transpose -i tokens # turn columns into items, each is a token
42+
| where ($it | str length) > 0 # remove any empty lines
43+
| where $it starts-with 'complete' # only complete command lines
44+
| each {
45+
str replace -a "\\\\'" "" # remove escaped quotes ' which break detect columns
46+
| str replace -a "-f " "" # remove -f which is a boolean flag we don't support yet
47+
| detect columns -n
48+
| transpose -i tokens
49+
| get tokens
4950
}
50-
| where ($it | length) > 0 # remove any empty lines
51-
| get tokens # get the list of tokens
5251
}
5352

5453
# turn a list of tokens for a line into a record of {flag: arg}
@@ -80,53 +79,65 @@ def make-commands-completion [] {
8079
| get c # c is the command name
8180
| uniq # is cloned on every complete line
8281
| each { |command|
83-
$fishes | where c == $command | make-subcommands-completion $command
82+
$fishes | where c == $command | make-subcommands-completion [$command]
83+
| str join "\n\n"
8484
}
8585
}
8686

8787
# make the action nu completion string from subcommand and args
8888
# subcommand can be empty which will be the root command
89-
def make-subcommands-completion [parents: list] {
90-
let quote = '"' # "
89+
def make-subcommands-completion [parents: list<string>] {
90+
let quote = '"' # a `"`
91+
9192
let fishes = $in
93+
9294
$fishes
9395
| group-by a # group by sub command (a flag)
9496
| transpose name args # turn it into a table of name to arguments
9597
| each {|subcommand|
96-
build-string (
97-
if ('d' in ($subcommand.args | columns)) and ($subcommand.args.d != "") {
98-
build-string "# " ($subcommand.args.d.0) "\n" # (sub)command description
99-
}) "extern " $quote ($parents | str join " ") (
100-
if $subcommand.name != "" {
101-
build-string " " $subcommand.name # sub command if present
102-
}) $quote " [\n" (
103-
$fishes
104-
| if ('n' in ($in | columns)) {
105-
if ($subcommand.name != "") {
106-
where ($it.n | str contains $subcommand.name) # for subcommand -> any where n matches `__fish_seen_subcommand_from arg` for the subcommand name
107-
} else {
108-
where ($it.n == "__fish_use_subcommand") and ($it.a == "") # for root command -> any where n == __fish_use_subcommand and a is empty. otherwise a means a subcommand
109-
}
110-
} else {
111-
$fishes # catch all
112-
}
113-
| build-flags
114-
| str join "\n"
115-
) "\n\t...args\n]"
98+
[
99+
# description
100+
(if ('d' in ($subcommand.args | columns)) and ($subcommand.args.d != "") { $"# ($subcommand.args.d.0)\n" })
101+
# extern name
102+
$'extern "($parents | append $subcommand.name | str join " " | str trim)"'
103+
# params
104+
" [\n"
105+
(
106+
$fishes
107+
| if ('n' in ($subcommand | columns)) {
108+
if ($subcommand.name != "") {
109+
where ($it.n | str contains $subcommand.name) # for subcommand -> any where n matches `__fish_seen_subcommand_from arg` for the subcommand name
110+
} else {
111+
where ($it.n == "__fish_use_subcommand") and ($it.a == "") # for root command -> any where n == __fish_use_subcommand and a is empty. otherwise a means a subcommand
112+
}
113+
} else {
114+
$fishes # catch all
115+
}
116+
| build-flags
117+
| str join "\n"
118+
)
119+
"\n\t...args"
120+
"\n]"
121+
]
122+
| str join
116123
}
117124
}
118125

119126
# build the list of flag string in nu syntax
127+
# record<c, n, a, d, o> -> list<string>
120128
def build-flags [] {
121-
each { |subargs|
129+
$in
130+
| each { |subargs|
122131
if ('l' in ($subargs | columns)) and ($subargs.l != "") {
123-
build-string "\t--" $subargs.l (build-string
124-
(if ('s' in ($subargs | columns)) and ($subargs.s != "") {
125-
build-string "(-" $subargs.s ")"
126-
}) (if ('d' in ($subargs | columns)) and ($subargs.d != "") {
127-
build-string "\t\t\t\t\t# " $subargs.d
128-
})
129-
)
132+
[
133+
"\t--" $subargs.l
134+
(
135+
[
136+
(if ('s' in ($subargs | columns)) and ($subargs.s != "") { [ "(-" $subargs.s ")" ] | str join })
137+
(if ('d' in ($subargs | columns)) and ($subargs.d != "") { [ "\t\t\t\t\t# " $subargs.d ] | str join })
138+
] | str join
139+
)
140+
] | str join
130141
}
131142
}
132143
}

0 commit comments

Comments
 (0)