Skip to content

Commit 24c4d59

Browse files
committed
Fix conflicting flag column names
'c' and 'C' conflicted, leading to get c getting the C column Clear out 'complete ' earlier, in tokenize-complete-lines. Parse and pair flags without values as well.
1 parent 5c2f678 commit 24c4d59

File tree

1 file changed

+54
-25
lines changed

1 file changed

+54
-25
lines changed

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

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,26 +22,24 @@ def build-completion [fish_file: path, nu_file: path] {
2222
def parse-fish [] {
2323
let data = (
2424
$in | tokenize-complete-lines
25-
| where (($it | length) mod 2) == 1 # currently we only support complete args that all have args (pairs). including 'complete' this means an odd number of tokens
26-
| each { |tokens| $tokens | pair-args } # turn the tokens into a list of pairs
25+
| each { |tokens| $tokens | pair-tokens | translate-pairs } # turn the tokens into a list of pairs
2726
| flatten # merge them all into a top level label
2827
)
2928
# default every column in the table to "" to make processing easier
3029
# some values having null often breaks nu or requires lots of checking
31-
$data | columns | reduce -f $data { |c, acc|
32-
$acc | default "" $c
33-
}
34-
| default "" a
35-
| cleanup_subcommands # clean garbage subcommands
30+
$data | columns | reduce -f $data { |c, acc| $acc | default "" $c }
31+
| default "" arguments
32+
| cleanup_subcommands # clean garbage subcommands
3633
}
3734

3835
# tokenize each line of the fish file into a list of tokens
3936
# make use of detect columns -n which with one like properly tokenizers arguments including across quotes
4037
def tokenize-complete-lines [] {
4138
lines
42-
| where $it starts-with 'complete' # only complete command lines
39+
| where $it starts-with 'complete ' # only complete command lines
4340
| each {
44-
str replace -a "\\\\'" "" # remove escaped quotes ' which break detect columns
41+
str substring 9.. # clear out complete command, keep args
42+
| str replace -a "\\\\'" "" # remove escaped quotes ' which break detect columns
4543
| str replace -a "-f " "" # remove -f which is a boolean flag we don't support yet
4644
| detect columns -n
4745
| transpose -i tokens
@@ -51,34 +49,65 @@ def tokenize-complete-lines [] {
5149

5250
# turn a list of tokens for a line into a record of {flag: arg}
5351
def pair-args [] {
54-
where $it != complete # drop complete command as we don't need it
55-
| window 2 -s 2 # group by ordered pairs, using window 2 -s 2 instead of group 2 to automatically drop any left overs
52+
window 2 --remainder
5653
| each { |pair|
54+
let name = $pair.0 | map-flag-name
55+
let value = $pair.1 | unquote
5756
[
58-
{$"($pair.0 | str trim -c '-')": ($pair.1 | unquote)} # turn into a [{<flag> :<arg>}] removing quotes
57+
{$name: $value} # turn into a [{<flag> :<arg>}] removing quotes
5958
]
6059
}
6160
| reduce { |it, acc| $acc | merge $it } # merge the list of records into one big record
6261
}
6362

63+
def pair-tokens [] {
64+
window 2 --remainder | where $it.0 starts-with '-' | each { if $in.1 starts-with '-' { [$in.0] } else { $in } }
65+
}
66+
67+
def translate-pairs [] {
68+
each {|pair|
69+
match $in.0 {
70+
'-c' | '--command' => { command: ($in.1 | unquote) }
71+
'-s' | '--short-option' => { short-option: ($in.1 | unquote) }
72+
'-l' | '--long-option' => { long-option: ($in.1 | unquote) }
73+
'-d' | '--description' => { description: ($in.1 | unquote) }
74+
'-o' | '--old-option' => { old-option: ($in.1 | unquote) }
75+
'-F' | '--force-files' => { force-files: true }
76+
'-f' | '--no-files' => { no-files: true }
77+
'-r' | '--require-parameter' => { require-parameter: true }
78+
'-x' | '--exclusive' => { require-parameter: true, no-files: true }
79+
'-a' | '--arguments' => { arguments: ($in.1 | unquote) }
80+
'-n' | '--condition' => { condition: ($in.1 | unquote) }
81+
'-k' | '--keep-order' => { keep-order: true }
82+
'-C' | '--do-complete' => { do-complete: ($in.1 | unquote) } # try to find all possible completions for the specified string. Otherwise use the current command line.
83+
'--escape' => { escape: true } # when used with -C escape special characters
84+
_ => { $'unknown_($in.0)': (if ($in | length) == 2 { $pair.1 }) }
85+
}
86+
}
87+
| reduce {|it,acc| $acc | merge $it }
88+
}
89+
6490
def unquote [] {
6591
str trim -c "\'" # trim '
6692
| str trim -c "\"" # trim "
6793
}
6894

6995
# remove any entries which contain things in subcommands that may be fish functions or incorrect parses
7096
def cleanup_subcommands [] {
71-
where (not ($it.a | str contains "$")) and (not ($it.a | str starts-with "-")) and (not ($it.a starts-with "("))
97+
where ((not ($it.arguments | str contains "$"))
98+
and (not ($it.arguments | str starts-with "-"))
99+
and (not ($it.arguments starts-with "("))
100+
)
72101
}
73102

74103
# from a parsed fish table, create the completion for it's command and sub commands
75104
def make-commands-completion [] {
76105
let fishes = $in
77106
$fishes
78-
| get c # c is the command name
79-
| uniq # is cloned on every complete line
107+
| get command
108+
| uniq # command is cloned on every complete line
80109
| each { |command|
81-
$fishes | where c == $command | make-subcommands-completion [$command]
110+
$fishes | where command == $command | make-subcommands-completion [$command]
82111
| str join "\n\n"
83112
}
84113
}
@@ -91,23 +120,23 @@ def make-subcommands-completion [parents: list<string>] {
91120
let fishes = $in
92121

93122
$fishes
94-
| group-by a # group by sub command (a flag)
123+
| group-by arguments # group by sub command (arguments flag)
95124
| transpose name args # turn it into a table of name to arguments
96125
| each {|subcommand|
97126
[
98127
# description
99-
(if ('d' in ($subcommand.args | columns)) and ($subcommand.args.d != "") { $"# ($subcommand.args.d.0)\n" })
128+
(if ('description' in ($subcommand.args | columns)) and ($subcommand.args.description != "") { $"# ($subcommand.args.description.0)\n" })
100129
# extern name
101130
$'extern "($parents | append $subcommand.name | str join " " | str trim)"'
102131
# params
103132
" [\n"
104133
(
105134
$fishes
106-
| if ('n' in ($subcommand | columns)) {
135+
| if ('condition' in ($subcommand | columns)) {
107136
if ($subcommand.name != "") {
108-
where ($it.n | str contains $subcommand.name) # for subcommand -> any where n matches `__fish_seen_subcommand_from arg` for the subcommand name
137+
where ($it.condition | str contains $subcommand.name) # for subcommand -> any where n matches `__fish_seen_subcommand_from arg` for the subcommand name
109138
} else {
110-
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
139+
where ($it.condition == "__fish_use_subcommand") and ($it.arguments == "") # for root command -> any where n == __fish_use_subcommand and a is empty. otherwise a means a subcommand
111140
}
112141
} else {
113142
$fishes # catch all
@@ -127,13 +156,13 @@ def make-subcommands-completion [parents: list<string>] {
127156
def build-flags [] {
128157
$in
129158
| each { |subargs|
130-
if ('l' in ($subargs | columns)) and ($subargs.l != "") {
159+
if ('long-option' in ($subargs | columns)) and ($subargs.long-option != "") {
131160
[
132-
"\t--" $subargs.l
161+
"\t--" $subargs.long-option
133162
(
134163
[
135-
(if ('s' in ($subargs | columns)) and ($subargs.s != "") { [ "(-" $subargs.s ")" ] | str join })
136-
(if ('d' in ($subargs | columns)) and ($subargs.d != "") { [ "\t\t\t\t\t# " $subargs.d ] | str join })
164+
(if ('short-option' in ($subargs | columns)) and ($subargs.short-option != "") { [ "(-" $subargs.short-option ")" ] | str join })
165+
(if ('description' in ($subargs | columns)) and ($subargs.description != "") { [ "\t\t\t\t\t# " $subargs.description ] | str join })
137166
] | str join
138167
)
139168
] | str join

0 commit comments

Comments
 (0)