mirror of
https://github.com/RGBCube/nu_scripts
synced 2025-07-30 21:57:44 +00:00
Move custom-completion auto-generate scripts to needs-update
(#1076)
A user in Discord recently tried to run the auto-generate script to create completions from `<command> --help` and had issues. In examining the scripts, I found that they used `build-string`, which was deprecated and removed over 2 years ago. In order to prevent future confusion until (and if) these files are updated, I'm moving them to a `needs-update` directory in the repo. Any other outdated files can be moved there as well.
This commit is contained in:
parent
e956708244
commit
a19339cdaa
5 changed files with 322 additions and 99 deletions
|
@ -1,101 +1,8 @@
|
|||
# auto-generate completions
|
||||
# Note
|
||||
|
||||
- basic helpers to parse --help information from cli commands and export nu completions source
|
||||
- basic helpers tp parse .fish complete files and export nu completions source
|
||||
Completions in this directory were generated via the auto-generate scripts.
|
||||
These scripts are currently outdated and will not work in recent releases
|
||||
of Nushell. The scripts themselves have been moved to `<repo_root>/need-update/custom-completions/auto-generate`
|
||||
until they are updated.
|
||||
|
||||
# parse-fish
|
||||
|
||||
## current
|
||||
- only parses out simple complete's with no complete's boolean arguments like -f
|
||||
- does not map fish autocomplete helpers to nu-complete helps (a nu library of autocomplete utils would be neat)
|
||||
|
||||
## usage
|
||||
|
||||
be in a directory with one or more .fish completion scripts
|
||||
|
||||
A good one is
|
||||
|
||||
`git clone https://github.com/fish-shell/fish-shell`
|
||||
`cd fish-shell/share/completions`
|
||||
|
||||
To build all .fish files in the current directory `build-completions-from-pwd`
|
||||
|
||||
```nu
|
||||
build-completions-from-pwd
|
||||
ls *.nu
|
||||
```
|
||||
|
||||
To build a single .fish file and choose the output file
|
||||
```nu
|
||||
build-completion cargo.fish cargo.nu
|
||||
```
|
||||
# parse-help
|
||||
|
||||
## current limitations
|
||||
|
||||
- Only flags are parsed, arguments are not parsed and ...args is injected at the end to catch all
|
||||
- Some examples of `--flags` in descriptions can throw off the regex and get included in the parsed flags
|
||||
- `<format>` (types) to flags are parsed, but not added to the nu shell completion type hints
|
||||
|
||||
## usage
|
||||
|
||||
generate and save source to a file
|
||||
|
||||
```nu
|
||||
source parse-help.nu
|
||||
cargo --help | parse-help | make-completion cargo | save cargo.nu
|
||||
```
|
||||
|
||||
## example
|
||||
|
||||
This can be saved to a file and sourced. Example of output
|
||||
|
||||
```nu
|
||||
extern "cargo" [
|
||||
--version(-V) #Print version info and exit
|
||||
--list #List installed commands
|
||||
--explain #Run `rustc --explain CODE`
|
||||
--verbose(-v) #Use verbose output (-vv very verbose/build.rs output)
|
||||
--quiet(-q) #Do not print cargo log messages
|
||||
--color #Coloring: auto, always, never
|
||||
--frozen #Require Cargo.lock and cache are up to date
|
||||
--locked #Require Cargo.lock is up to date
|
||||
--offline #Run without accessing the network
|
||||
--config #Override a configuration value (unstable)
|
||||
--help(-h) #Print help information
|
||||
...args
|
||||
]
|
||||
|
||||
extern "nu" [
|
||||
--help(-h) #Display this help message
|
||||
--stdin #redirect the stdin
|
||||
--login(-l) #start as a login shell
|
||||
--interactive(-i) #start as an interactive shell
|
||||
--version(-v) #print the version
|
||||
--perf(-p) #start and print performance metrics during startup
|
||||
--testbin #run internal test binary
|
||||
--commands(-c) #run the given commands and then exit
|
||||
--config #start with an alternate config file
|
||||
--env-config #start with an alternate environment config file
|
||||
--log-level #log level for performance logs
|
||||
--threads(-t) #threads to use for parallel commands
|
||||
...args
|
||||
]
|
||||
```
|
||||
|
||||
Which outputs like so on tab completion for `cargo --`
|
||||
```
|
||||
❯ | cargo --
|
||||
--color Coloring: auto, always, never
|
||||
--config Override a configuration value (unstable)
|
||||
--explain Run `rustc --explain CODE`
|
||||
--frozen Require Cargo.lock and cache are up to date
|
||||
--help Display this help message
|
||||
--help Print help information
|
||||
--list List installed commands
|
||||
--locked Require Cargo.lock is up to date
|
||||
--offline Run without accessing the network
|
||||
--quiet Do not print cargo log messages
|
||||
--verbose Use verbose output (-vv very verbose/build.rs output)
|
||||
--version Print version info and exit
|
||||
```
|
||||
Completions in this directory should still work in recent Nushell releases.
|
||||
|
|
4
needs-update/README.md
Normal file
4
needs-update/README.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Warning
|
||||
|
||||
Files in this directory have been confirmed as not currently working in recent Nushell releases
|
||||
and will need updates due to breaking changes.
|
101
needs-update/custom-completions/auto-generate/README.md
Normal file
101
needs-update/custom-completions/auto-generate/README.md
Normal file
|
@ -0,0 +1,101 @@
|
|||
# auto-generate completions
|
||||
|
||||
- basic helpers to parse --help information from cli commands and export nu completions source
|
||||
- basic helpers tp parse .fish complete files and export nu completions source
|
||||
|
||||
# parse-fish
|
||||
|
||||
## current
|
||||
- only parses out simple complete's with no complete's boolean arguments like -f
|
||||
- does not map fish autocomplete helpers to nu-complete helps (a nu library of autocomplete utils would be neat)
|
||||
|
||||
## usage
|
||||
|
||||
be in a directory with one or more .fish completion scripts
|
||||
|
||||
A good one is
|
||||
|
||||
`git clone https://github.com/fish-shell/fish-shell`
|
||||
`cd fish-shell/share/completions`
|
||||
|
||||
To build all .fish files in the current directory `build-completions-from-pwd`
|
||||
|
||||
```nu
|
||||
build-completions-from-pwd
|
||||
ls *.nu
|
||||
```
|
||||
|
||||
To build a single .fish file and choose the output file
|
||||
```nu
|
||||
build-completion cargo.fish cargo.nu
|
||||
```
|
||||
# parse-help
|
||||
|
||||
## current limitations
|
||||
|
||||
- Only flags are parsed, arguments are not parsed and ...args is injected at the end to catch all
|
||||
- Some examples of `--flags` in descriptions can throw off the regex and get included in the parsed flags
|
||||
- `<format>` (types) to flags are parsed, but not added to the nu shell completion type hints
|
||||
|
||||
## usage
|
||||
|
||||
generate and save source to a file
|
||||
|
||||
```nu
|
||||
source parse-help.nu
|
||||
cargo --help | parse-help | make-completion cargo | save cargo.nu
|
||||
```
|
||||
|
||||
## example
|
||||
|
||||
This can be saved to a file and sourced. Example of output
|
||||
|
||||
```nu
|
||||
extern "cargo" [
|
||||
--version(-V) #Print version info and exit
|
||||
--list #List installed commands
|
||||
--explain #Run `rustc --explain CODE`
|
||||
--verbose(-v) #Use verbose output (-vv very verbose/build.rs output)
|
||||
--quiet(-q) #Do not print cargo log messages
|
||||
--color #Coloring: auto, always, never
|
||||
--frozen #Require Cargo.lock and cache are up to date
|
||||
--locked #Require Cargo.lock is up to date
|
||||
--offline #Run without accessing the network
|
||||
--config #Override a configuration value (unstable)
|
||||
--help(-h) #Print help information
|
||||
...args
|
||||
]
|
||||
|
||||
extern "nu" [
|
||||
--help(-h) #Display this help message
|
||||
--stdin #redirect the stdin
|
||||
--login(-l) #start as a login shell
|
||||
--interactive(-i) #start as an interactive shell
|
||||
--version(-v) #print the version
|
||||
--perf(-p) #start and print performance metrics during startup
|
||||
--testbin #run internal test binary
|
||||
--commands(-c) #run the given commands and then exit
|
||||
--config #start with an alternate config file
|
||||
--env-config #start with an alternate environment config file
|
||||
--log-level #log level for performance logs
|
||||
--threads(-t) #threads to use for parallel commands
|
||||
...args
|
||||
]
|
||||
```
|
||||
|
||||
Which outputs like so on tab completion for `cargo --`
|
||||
```
|
||||
❯ | cargo --
|
||||
--color Coloring: auto, always, never
|
||||
--config Override a configuration value (unstable)
|
||||
--explain Run `rustc --explain CODE`
|
||||
--frozen Require Cargo.lock and cache are up to date
|
||||
--help Display this help message
|
||||
--help Print help information
|
||||
--list List installed commands
|
||||
--locked Require Cargo.lock is up to date
|
||||
--offline Run without accessing the network
|
||||
--quiet Do not print cargo log messages
|
||||
--verbose Use verbose output (-vv very verbose/build.rs output)
|
||||
--version Print version info and exit
|
||||
```
|
132
needs-update/custom-completions/auto-generate/parse-fish.nu
Normal file
132
needs-update/custom-completions/auto-generate/parse-fish.nu
Normal file
|
@ -0,0 +1,132 @@
|
|||
# a .fish complete file usually looks like a like
|
||||
# `complete -c command -n '__fish_seen_subcommand_from arg' -a arg -l long -s short -d 'description'
|
||||
# attempt to loosely pasrse it and convert to nu completions
|
||||
|
||||
# parse every .fish file in the current directory and make a .nu completions file of it
|
||||
def build-completions-from-pwd [] {
|
||||
ls *.fish | par-each { |f|
|
||||
let out = ($f.name | str replace ".fish" ".nu")
|
||||
print $"building nushell completions from ($f.name)"
|
||||
build-completion $f.name $out
|
||||
}
|
||||
}
|
||||
|
||||
# build a completion form a .fish file and generate a .nu file
|
||||
def build-completion [fish_file: path, nu_file: path] {
|
||||
open $fish_file | parse-fish | make-commands-completion | str join "\n\n" | save $nu_file
|
||||
}
|
||||
|
||||
# parse a .fish file based on autogenerated complete syntax
|
||||
# returns a table of flags to arguments
|
||||
# currently only handles complete's args that don't use boolean flags (e.g. -f)
|
||||
def parse-fish [] {
|
||||
let data = (
|
||||
$in | tokenize-complete-lines
|
||||
| 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
|
||||
| each { |tokens| $tokens | pair-args } # turn the tokens into a list of pairs
|
||||
| flatten # merge them all into a top level label
|
||||
)
|
||||
# default every column in the table to "" to make processing easier
|
||||
# some values having null often breaks nu or requires lots of checking
|
||||
$data | columns | reduce -f $data { |c, acc|
|
||||
$acc | default "" $c
|
||||
}
|
||||
| default "" a
|
||||
| cleanup_subcommands # clean garbage subcommands
|
||||
}
|
||||
|
||||
# tokenize each line of the fish file into a list of tokens
|
||||
# make use of detect columns -n which with one like properly tokenizers arguments including across quotes
|
||||
def tokenize-complete-lines [] {
|
||||
lines
|
||||
| each { |line|
|
||||
$line
|
||||
| where $line starts-with complete
|
||||
| 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
|
||||
| detect columns -n
|
||||
| transpose -i tokens # turn columns into items, each is a token
|
||||
}
|
||||
| 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}
|
||||
def pair-args [] {
|
||||
where $it != complete # drop complete command as we don't need it
|
||||
| window 2 -s 2 # group by ordered pairs, using window 2 -s 2 instead of group 2 to automatically drop any left overs
|
||||
| each { |pair|
|
||||
[
|
||||
{$"($pair.0 | str trim -c '-')": ($pair.1 | unquote)} # turn into a [{<flag> :<arg>}] removing quotes
|
||||
]
|
||||
}
|
||||
| reduce { |it, acc| $acc | merge $it } # merge the list of records into one big record
|
||||
}
|
||||
|
||||
def unquote [] {
|
||||
str trim -c "\'" # trim '
|
||||
| str trim -c "\"" # trim "
|
||||
}
|
||||
|
||||
# remove any entries which contain things in subcommands that may be fish functions or incorrect parses
|
||||
def cleanup_subcommands [] {
|
||||
where (not ($it.a | str contains "$")) and (not ($it.a | str starts-with "-")) and (not ($it.a starts-with "("))
|
||||
}
|
||||
|
||||
# from a parsed fish table, create the completion for it's command and sub commands
|
||||
def make-commands-completion [] {
|
||||
let fishes = $in
|
||||
$fishes
|
||||
| get c # c is the command name
|
||||
| uniq # is cloned on every complete line
|
||||
| each { |command|
|
||||
$fishes | where c == $command | make-subcommands-completion $command
|
||||
}
|
||||
}
|
||||
|
||||
# make the action nu completion string from subcommand and args
|
||||
# subcommand can be empty which will be the root command
|
||||
def make-subcommands-completion [parents: list] {
|
||||
let quote = '"' # "
|
||||
let fishes = $in
|
||||
$fishes
|
||||
| group-by a # group by sub command (a flag)
|
||||
| transpose name args # turn it into a table of name to arguments
|
||||
| each {|subcommand|
|
||||
build-string (
|
||||
if ('d' in ($subcommand.args | columns)) and ($subcommand.args.d != "") {
|
||||
build-string "# " ($subcommand.args.d.0) "\n" # (sub)command description
|
||||
}) "extern " $quote ($parents | str join " ") (
|
||||
if $subcommand.name != "" {
|
||||
build-string " " $subcommand.name # sub command if present
|
||||
}) $quote " [\n" (
|
||||
$fishes
|
||||
| if ('n' in ($in | columns)) {
|
||||
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
|
||||
} else {
|
||||
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
|
||||
}
|
||||
} else {
|
||||
$fishes # catch all
|
||||
}
|
||||
| build-flags
|
||||
| str join "\n"
|
||||
) "\n\t...args\n]"
|
||||
}
|
||||
}
|
||||
|
||||
# build the list of flag string in nu syntax
|
||||
def build-flags [] {
|
||||
each { |subargs|
|
||||
if ('l' in ($subargs | columns)) and ($subargs.l != "") {
|
||||
build-string "\t--" $subargs.l (build-string
|
||||
(if ('s' in ($subargs | columns)) and ($subargs.s != "") {
|
||||
build-string "(-" $subargs.s ")"
|
||||
}) (if ('d' in ($subargs | columns)) and ($subargs.d != "") {
|
||||
build-string "\t\t\t\t\t# " $subargs.d
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
79
needs-update/custom-completions/auto-generate/parse-help.nu
Normal file
79
needs-update/custom-completions/auto-generate/parse-help.nu
Normal file
|
@ -0,0 +1,79 @@
|
|||
|
||||
|
||||
# parses a input string in --help format and returns a table of parsed flags
|
||||
def parse-help [] {
|
||||
# help format ' -s, --long <format> description '
|
||||
$in | parse -r '\s\s+(?:-(?P<short>\w)[,\s]+)?(?:--(?P<long>[\w-]+))\s*(?:<(?P<format>.*)>)?\s*(?P<description>.*)?'
|
||||
}
|
||||
|
||||
# takes a table of parsed help commands in format [short? long format? description]
|
||||
def make-completion [command_name: string] {
|
||||
build-string "extern \"" $command_name "\" [\n" ($in | each { |it|
|
||||
build-string "\t--" $it.long (if ($it.short | is-empty) == false {
|
||||
build-string "(-" $it.short ")"
|
||||
}) (if ($it.description | is-empty) == false {
|
||||
build-string "\t\t# " $it.description
|
||||
})
|
||||
} | str join "\n") "\n\t...args\n]"
|
||||
}
|
||||
|
||||
module tests {
|
||||
def test-cargo [] {
|
||||
let expect = [
|
||||
[short long format description];
|
||||
[V version '' 'Print version info and exit']
|
||||
['' list '' 'List installed commands']
|
||||
['' explain 'CODE' 'Run `rustc --explain CODE`']
|
||||
[v verbose '' 'Use verbose output (-vv very verbose/build.rs output)']
|
||||
[q quiet '' 'Do not print cargo log messages']
|
||||
['' color 'WHEN' 'Coloring: auto, always, never']
|
||||
['' frozen '' 'Require Cargo.lock and cache are up to date']
|
||||
['' locked '' 'Require Cargo.lock is up to date']
|
||||
['' offline '' 'Run without accessing the network']
|
||||
['' config 'KEY=VALUE' 'Override a configuration value (unstable)']
|
||||
[h help '' 'Print help information']
|
||||
]
|
||||
|
||||
let result = (cargo --help | parse-help)
|
||||
|
||||
if $result == $expect {
|
||||
"passed"
|
||||
} else {
|
||||
$result
|
||||
}
|
||||
}
|
||||
|
||||
def test-nu [] {
|
||||
let expect = [
|
||||
[short long format description];
|
||||
[h help '' 'Display this help message']
|
||||
['' stdin '' 'redirect the stdin']
|
||||
[l login '' 'start as a login shell']
|
||||
[i interactive '' 'start as an interactive shell']
|
||||
[v version '' 'print the version']
|
||||
[p perf '' 'start and print performance metrics during startup']
|
||||
['' testbin 'String' 'run internal test binary']
|
||||
[c commands 'String' 'run the given commands and then exit']
|
||||
['' config 'String' 'start with an alternate config file']
|
||||
['' env-config 'String' 'start with an alternate environment config file']
|
||||
['' log-level 'String' 'log level for performance logs']
|
||||
['t' threads 'Int' 'threads to use for parallel commands']
|
||||
]
|
||||
|
||||
let result = (nu --help | parse-help)
|
||||
|
||||
if $result == $expect {
|
||||
"passed"
|
||||
} else {
|
||||
$result
|
||||
}
|
||||
}
|
||||
|
||||
export def run-tests [] {
|
||||
[
|
||||
[test result];
|
||||
['cargo' (do { test-cargo })]
|
||||
['nu' (do { test-nu })]
|
||||
]
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue