Skip to content

Commit 53242f1

Browse files
committed
Move custom-completion auto-generate scripts to needs-update
1 parent 095fa41 commit 53242f1

File tree

5 files changed

+322
-99
lines changed

5 files changed

+322
-99
lines changed
Lines changed: 6 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,8 @@
1-
# auto-generate completions
1+
# Note
22

3-
- basic helpers to parse --help information from cli commands and export nu completions source
4-
- basic helpers tp parse .fish complete files and export nu completions source
3+
Completions in this directory were generated via the auto-generate scripts.
4+
These scripts are currently outdated and will not work in recent releases
5+
of Nushell. The scripts themselves have been moved to `<repo_root>/need-update/custom-completions/auto-generate`
6+
until they are updated.
57

6-
# parse-fish
7-
8-
## current
9-
- only parses out simple complete's with no complete's boolean arguments like -f
10-
- does not map fish autocomplete helpers to nu-complete helps (a nu library of autocomplete utils would be neat)
11-
12-
## usage
13-
14-
be in a directory with one or more .fish completion scripts
15-
16-
A good one is
17-
18-
`git clone https://github.com/fish-shell/fish-shell`
19-
`cd fish-shell/share/completions`
20-
21-
To build all .fish files in the current directory `build-completions-from-pwd`
22-
23-
```nu
24-
build-completions-from-pwd
25-
ls *.nu
26-
```
27-
28-
To build a single .fish file and choose the output file
29-
```nu
30-
build-completion cargo.fish cargo.nu
31-
```
32-
# parse-help
33-
34-
## current limitations
35-
36-
- Only flags are parsed, arguments are not parsed and ...args is injected at the end to catch all
37-
- Some examples of `--flags` in descriptions can throw off the regex and get included in the parsed flags
38-
- `<format>` (types) to flags are parsed, but not added to the nu shell completion type hints
39-
40-
## usage
41-
42-
generate and save source to a file
43-
44-
```nu
45-
source parse-help.nu
46-
cargo --help | parse-help | make-completion cargo | save cargo.nu
47-
```
48-
49-
## example
50-
51-
This can be saved to a file and sourced. Example of output
52-
53-
```nu
54-
extern "cargo" [
55-
--version(-V) #Print version info and exit
56-
--list #List installed commands
57-
--explain #Run `rustc --explain CODE`
58-
--verbose(-v) #Use verbose output (-vv very verbose/build.rs output)
59-
--quiet(-q) #Do not print cargo log messages
60-
--color #Coloring: auto, always, never
61-
--frozen #Require Cargo.lock and cache are up to date
62-
--locked #Require Cargo.lock is up to date
63-
--offline #Run without accessing the network
64-
--config #Override a configuration value (unstable)
65-
--help(-h) #Print help information
66-
...args
67-
]
68-
69-
extern "nu" [
70-
--help(-h) #Display this help message
71-
--stdin #redirect the stdin
72-
--login(-l) #start as a login shell
73-
--interactive(-i) #start as an interactive shell
74-
--version(-v) #print the version
75-
--perf(-p) #start and print performance metrics during startup
76-
--testbin #run internal test binary
77-
--commands(-c) #run the given commands and then exit
78-
--config #start with an alternate config file
79-
--env-config #start with an alternate environment config file
80-
--log-level #log level for performance logs
81-
--threads(-t) #threads to use for parallel commands
82-
...args
83-
]
84-
```
85-
86-
Which outputs like so on tab completion for `cargo --`
87-
```
88-
❯ | cargo --
89-
--color Coloring: auto, always, never
90-
--config Override a configuration value (unstable)
91-
--explain Run `rustc --explain CODE`
92-
--frozen Require Cargo.lock and cache are up to date
93-
--help Display this help message
94-
--help Print help information
95-
--list List installed commands
96-
--locked Require Cargo.lock is up to date
97-
--offline Run without accessing the network
98-
--quiet Do not print cargo log messages
99-
--verbose Use verbose output (-vv very verbose/build.rs output)
100-
--version Print version info and exit
101-
```
8+
Completions in this directory should still work in recent Nushell releases.

needs-update/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Warning
2+
3+
Files in this directory have been confirmed as not currently working in recent Nushell releases
4+
and will need updates due to breaking changes.
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# auto-generate completions
2+
3+
- basic helpers to parse --help information from cli commands and export nu completions source
4+
- basic helpers tp parse .fish complete files and export nu completions source
5+
6+
# parse-fish
7+
8+
## current
9+
- only parses out simple complete's with no complete's boolean arguments like -f
10+
- does not map fish autocomplete helpers to nu-complete helps (a nu library of autocomplete utils would be neat)
11+
12+
## usage
13+
14+
be in a directory with one or more .fish completion scripts
15+
16+
A good one is
17+
18+
`git clone https://github.com/fish-shell/fish-shell`
19+
`cd fish-shell/share/completions`
20+
21+
To build all .fish files in the current directory `build-completions-from-pwd`
22+
23+
```nu
24+
build-completions-from-pwd
25+
ls *.nu
26+
```
27+
28+
To build a single .fish file and choose the output file
29+
```nu
30+
build-completion cargo.fish cargo.nu
31+
```
32+
# parse-help
33+
34+
## current limitations
35+
36+
- Only flags are parsed, arguments are not parsed and ...args is injected at the end to catch all
37+
- Some examples of `--flags` in descriptions can throw off the regex and get included in the parsed flags
38+
- `<format>` (types) to flags are parsed, but not added to the nu shell completion type hints
39+
40+
## usage
41+
42+
generate and save source to a file
43+
44+
```nu
45+
source parse-help.nu
46+
cargo --help | parse-help | make-completion cargo | save cargo.nu
47+
```
48+
49+
## example
50+
51+
This can be saved to a file and sourced. Example of output
52+
53+
```nu
54+
extern "cargo" [
55+
--version(-V) #Print version info and exit
56+
--list #List installed commands
57+
--explain #Run `rustc --explain CODE`
58+
--verbose(-v) #Use verbose output (-vv very verbose/build.rs output)
59+
--quiet(-q) #Do not print cargo log messages
60+
--color #Coloring: auto, always, never
61+
--frozen #Require Cargo.lock and cache are up to date
62+
--locked #Require Cargo.lock is up to date
63+
--offline #Run without accessing the network
64+
--config #Override a configuration value (unstable)
65+
--help(-h) #Print help information
66+
...args
67+
]
68+
69+
extern "nu" [
70+
--help(-h) #Display this help message
71+
--stdin #redirect the stdin
72+
--login(-l) #start as a login shell
73+
--interactive(-i) #start as an interactive shell
74+
--version(-v) #print the version
75+
--perf(-p) #start and print performance metrics during startup
76+
--testbin #run internal test binary
77+
--commands(-c) #run the given commands and then exit
78+
--config #start with an alternate config file
79+
--env-config #start with an alternate environment config file
80+
--log-level #log level for performance logs
81+
--threads(-t) #threads to use for parallel commands
82+
...args
83+
]
84+
```
85+
86+
Which outputs like so on tab completion for `cargo --`
87+
```
88+
❯ | cargo --
89+
--color Coloring: auto, always, never
90+
--config Override a configuration value (unstable)
91+
--explain Run `rustc --explain CODE`
92+
--frozen Require Cargo.lock and cache are up to date
93+
--help Display this help message
94+
--help Print help information
95+
--list List installed commands
96+
--locked Require Cargo.lock is up to date
97+
--offline Run without accessing the network
98+
--quiet Do not print cargo log messages
99+
--verbose Use verbose output (-vv very verbose/build.rs output)
100+
--version Print version info and exit
101+
```
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# a .fish complete file usually looks like a like
2+
# `complete -c command -n '__fish_seen_subcommand_from arg' -a arg -l long -s short -d 'description'
3+
# attempt to loosely pasrse it and convert to nu completions
4+
5+
# parse every .fish file in the current directory and make a .nu completions file of it
6+
def build-completions-from-pwd [] {
7+
ls *.fish | par-each { |f|
8+
let out = ($f.name | str replace ".fish" ".nu")
9+
print $"building nushell completions from ($f.name)"
10+
build-completion $f.name $out
11+
}
12+
}
13+
14+
# build a completion form a .fish file and generate a .nu file
15+
def build-completion [fish_file: path, nu_file: path] {
16+
open $fish_file | parse-fish | make-commands-completion | str join "\n\n" | save $nu_file
17+
}
18+
19+
# parse a .fish file based on autogenerated complete syntax
20+
# returns a table of flags to arguments
21+
# currently only handles complete's args that don't use boolean flags (e.g. -f)
22+
def parse-fish [] {
23+
let data = (
24+
$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
27+
| flatten # merge them all into a top level label
28+
)
29+
# default every column in the table to "" to make processing easier
30+
# 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
36+
}
37+
38+
# tokenize each line of the fish file into a list of tokens
39+
# make use of detect columns -n which with one like properly tokenizers arguments including across quotes
40+
def tokenize-complete-lines [] {
41+
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
49+
}
50+
| where ($it | length) > 0 # remove any empty lines
51+
| get tokens # get the list of tokens
52+
}
53+
54+
# turn a list of tokens for a line into a record of {flag: arg}
55+
def pair-args [] {
56+
where $it != complete # drop complete command as we don't need it
57+
| window 2 -s 2 # group by ordered pairs, using window 2 -s 2 instead of group 2 to automatically drop any left overs
58+
| each { |pair|
59+
[
60+
{$"($pair.0 | str trim -c '-')": ($pair.1 | unquote)} # turn into a [{<flag> :<arg>}] removing quotes
61+
]
62+
}
63+
| reduce { |it, acc| $acc | merge $it } # merge the list of records into one big record
64+
}
65+
66+
def unquote [] {
67+
str trim -c "\'" # trim '
68+
| str trim -c "\"" # trim "
69+
}
70+
71+
# remove any entries which contain things in subcommands that may be fish functions or incorrect parses
72+
def cleanup_subcommands [] {
73+
where (not ($it.a | str contains "$")) and (not ($it.a | str starts-with "-")) and (not ($it.a starts-with "("))
74+
}
75+
76+
# from a parsed fish table, create the completion for it's command and sub commands
77+
def make-commands-completion [] {
78+
let fishes = $in
79+
$fishes
80+
| get c # c is the command name
81+
| uniq # is cloned on every complete line
82+
| each { |command|
83+
$fishes | where c == $command | make-subcommands-completion $command
84+
}
85+
}
86+
87+
# make the action nu completion string from subcommand and args
88+
# subcommand can be empty which will be the root command
89+
def make-subcommands-completion [parents: list] {
90+
let quote = '"' # "
91+
let fishes = $in
92+
$fishes
93+
| group-by a # group by sub command (a flag)
94+
| transpose name args # turn it into a table of name to arguments
95+
| 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]"
116+
}
117+
}
118+
119+
# build the list of flag string in nu syntax
120+
def build-flags [] {
121+
each { |subargs|
122+
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+
)
130+
}
131+
}
132+
}

0 commit comments

Comments
 (0)