From a84162d708a212165e1f0989c097d4007d235d29 Mon Sep 17 00:00:00 2001 From: Jacob Gonzalez Date: Wed, 18 May 2022 15:36:49 +1000 Subject: [PATCH] Auto generation completion help parser (#223) * basic regex parsing flags * addressed multiline description * readme and usage * move to custom-completions/auto-generated * put tests into module * add comments and limitations --- custom-completions/auto-generate/README.md | 73 +++++++++++++++++ .../auto-generate/completions.nu | 66 ++++++++++++++++ .../auto-generate/parse-help.nu | 79 +++++++++++++++++++ custom-completions/auto-generate/usage.nu | 13 +++ 4 files changed, 231 insertions(+) create mode 100644 custom-completions/auto-generate/README.md create mode 100644 custom-completions/auto-generate/completions.nu create mode 100644 custom-completions/auto-generate/parse-help.nu create mode 100644 custom-completions/auto-generate/usage.nu diff --git a/custom-completions/auto-generate/README.md b/custom-completions/auto-generate/README.md new file mode 100644 index 0000000..20fd858 --- /dev/null +++ b/custom-completions/auto-generate/README.md @@ -0,0 +1,73 @@ +# completions + +basic helper to parse --help information from cli commands and export nu completions source + +# 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 +- `` (types) to flags are parsed, but not added to the nu shell completion type hints + +## usage + +A basic example in [usage.nu](usage.nu) + +generate and print source to tty + +```nu +cargo --help | parse-help | make-completion cargo | nu-highlight +``` + +## 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 +``` \ No newline at end of file diff --git a/custom-completions/auto-generate/completions.nu b/custom-completions/auto-generate/completions.nu new file mode 100644 index 0000000..f1c605b --- /dev/null +++ b/custom-completions/auto-generate/completions.nu @@ -0,0 +1,66 @@ +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 +] + +extern "bat" [ + --show-all(-A) # Show non-printable characters like space, tab or newline. This option can also be used + --plain(-p) # Only show plain style, no decorations. This is an alias for '--style=plain'. When '-p' + --pager # =never'). + --language(-l) # Explicitly set the language for syntax highlighting. The language can be specified as a + --highlight-line(-H) # ... + --file-name # ... + --diff(-d) # Only show lines that have been added/removed/modified with respect to the Git index. Use + --diff-context # =N to control how much context you want to see. + --diff-context # Include N lines of context around added/removed/modified lines when using '--diff'. + --tabs # Set the tab width to T spaces. Use a width of 0 to pass tabs through directly + --wrap # Specify the text-wrapping mode (*auto*, never, character). The '--terminal-width' option + --terminal-width # Explicitly set the width of the terminal instead of determining it automatically. If + --number(-n) # Only show line numbers, no other decorations. This is an alias for '--style=numbers' + --color # Specify when to use colored output. The automatic mode only enables colors if an + --italic-text # Specify when to use ANSI sequences for italic text in the output. Possible values: + --decorations # Specify when to use the decorations that have been specified via '--style'. The + --force-colorization(-f) # Alias for '--decorations=always --color=always'. This is useful if the output of bat is + --paging # Specify when to use the pager. To disable the pager, use --paging=never' or its + --pager # Determine which pager is used. This option will override the PAGER and BAT_PAGER + --map-syntax(-m) # ... + --ignored-suffix # ... + --theme # Set the theme for syntax highlighting. Use '--list-themes' to see all available themes. + --list-themes # Display a list of supported themes for syntax highlighting. + --style # Configure which elements (line numbers, file headers, grid borders, Git modifications, + --line-range(-r) # ... + --list-languages(-L) # Display a list of supported languages for syntax highlighting. + --unbuffered(-u) # This option exists for POSIX-compliance reasons ('u' is for 'unbuffered'). The output is + --diagnostic # Show diagnostic information for bug reports. + --acknowledgements # Show acknowledgements. + --help(-h) # Print this help message. + --version(-V) # Show version information. + ...args +] + diff --git a/custom-completions/auto-generate/parse-help.nu b/custom-completions/auto-generate/parse-help.nu new file mode 100644 index 0000000..7c29c44 --- /dev/null +++ b/custom-completions/auto-generate/parse-help.nu @@ -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 description ' + $in | parse -r '\s\s+(?:-(?P\w)[,\s]+)?(?:--(?P[\w-]+))\s*(?:<(?P.*)>)?\s*(?P.*)?' +} + +# 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 | empty?) == false { + build-string "(-" $it.short ")" + }) (if ($it.description | empty?) == false { + build-string "\t\t# " $it.description + }) + } | str collect "\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 })] + ] + } +} diff --git a/custom-completions/auto-generate/usage.nu b/custom-completions/auto-generate/usage.nu new file mode 100644 index 0000000..ad6828d --- /dev/null +++ b/custom-completions/auto-generate/usage.nu @@ -0,0 +1,13 @@ +# something like this in $nu.env-path + +rm completions.nu + +source parse-help.nu + +cargo --help | parse-help | build-string ($in | make-completion cargo) "\n\n" | save --append $"completions.nu" +nu --help | parse-help | build-string ($in | make-completion nu) "\n\n" | save --append $"completions.nu" +bat --help | parse-help | build-string ($in | make-completion bat) "\n\n" | save --append $"completions.nu" + +# source this file in $nu.config-path + +source completions.nu