mirror of
https://github.com/asdf-vm/asdf.git
synced 2024-12-23 20:05:09 -07:00
feat(golang-rewrite): self-contained completion code
* Add `asdf completion` command * Move completion files to `cli/completions` * Add completions for Bash, Zsh, Fish, Elvish, and Nushell * Update Zsh completion code to work with new completion install method
This commit is contained in:
parent
08ca28f53d
commit
c8593842ee
49
cli/cli.go
49
cli/cli.go
@ -2,6 +2,7 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@ -71,6 +72,13 @@ func Execute(version string) {
|
||||
return extensionCommand(logger, args)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "completion",
|
||||
Action: func(cCtx *cli.Context) error {
|
||||
shell := cCtx.Args().Get(0)
|
||||
return completionCommand(logger, shell)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "current",
|
||||
Flags: []cli.Flag{
|
||||
@ -307,6 +315,47 @@ func Execute(version string) {
|
||||
}
|
||||
}
|
||||
|
||||
//go:embed completions/asdf.bash
|
||||
var bashCompletions string
|
||||
|
||||
//go:embed completions/asdf.zsh
|
||||
var zshCompletions string
|
||||
|
||||
//go:embed completions/asdf.fish
|
||||
var fishCompletions string
|
||||
|
||||
//go:embed completions/asdf.nu
|
||||
var nuCompletions string
|
||||
|
||||
//go:embed completions/asdf.elv
|
||||
var elvishCompletions string
|
||||
|
||||
func completionCommand(l *log.Logger, shell string) error {
|
||||
switch shell {
|
||||
case "bash":
|
||||
fmt.Print(bashCompletions)
|
||||
return nil
|
||||
case "zsh":
|
||||
fmt.Print(zshCompletions)
|
||||
return nil
|
||||
case "fish":
|
||||
fmt.Print(fishCompletions)
|
||||
return nil
|
||||
case "nushell":
|
||||
fmt.Print(nuCompletions)
|
||||
return nil
|
||||
case "elvish":
|
||||
fmt.Print(elvishCompletions)
|
||||
return nil
|
||||
default:
|
||||
fmtString := `No completions available for shell with name %s
|
||||
Completions are available for: bash, zsh, fish, nushell, elvish`
|
||||
msg := fmt.Sprintf(fmtString, shell)
|
||||
l.Print(msg)
|
||||
return errors.New(msg)
|
||||
}
|
||||
}
|
||||
|
||||
// This function is a whole mess and needs to be refactored
|
||||
func currentCommand(logger *log.Logger, tool string, noHeader bool) error {
|
||||
conf, err := config.LoadConfig()
|
||||
|
148
cli/completions/asdf.elv
Normal file
148
cli/completions/asdf.elv
Normal file
@ -0,0 +1,148 @@
|
||||
# Setup argument completions
|
||||
fn arg-completer {|@argz|
|
||||
set argz = $argz[1..-1] # strip 'asdf' and trailing empty string
|
||||
var num = (count $argz)
|
||||
if (== $num 0) {
|
||||
# list all subcommands
|
||||
find $asdf_dir'/lib/commands' -name 'command-*' | each {|cmd|
|
||||
put (re:replace '.*/command-(.*)\.bash' '${1}' $cmd)
|
||||
}
|
||||
put 'plugin'
|
||||
} else {
|
||||
if (match $argz 'current') {
|
||||
# asdf current <name>
|
||||
asdf plugin-list
|
||||
} elif (match $argz 'env') {
|
||||
# asdf env <command>
|
||||
ls-shims
|
||||
} elif (match $argz 'env' '.*') {
|
||||
# asdf env <command> [util]
|
||||
ls-executables
|
||||
} elif (match $argz 'exec') {
|
||||
# asdf exec <command>
|
||||
ls-shims
|
||||
} elif (match $argz 'global') {
|
||||
# asdf global <name>
|
||||
asdf plugin-list
|
||||
} elif (match $argz 'global' '.*') {
|
||||
# asdf global <name> <version>
|
||||
ls-installed-versions $argz[-1]
|
||||
} elif (match $argz 'install') {
|
||||
# asdf install <name>
|
||||
asdf plugin-list
|
||||
} elif (match $argz 'install' '.*') {
|
||||
# asdf install <name> <version>
|
||||
ls-all-versions $argz[-1]
|
||||
} elif (match $argz 'install' '.*' '.*') {
|
||||
# asdf install <name> <version> [--keep-download]
|
||||
put '--keep-download'
|
||||
} elif (match $argz 'latest') {
|
||||
# asdf latest <name>
|
||||
asdf plugin-list
|
||||
} elif (match $argz 'latest' '.*') {
|
||||
# asdf latest <name> [<version>]
|
||||
ls-all-versions $argz[-1]
|
||||
} elif (match $argz 'list-all') {
|
||||
# asdf list all <name>
|
||||
asdf plugin-list
|
||||
} elif (match $argz 'list-all' '.*') {
|
||||
# asdf list all <name> [<version>]
|
||||
ls-all-versions $argz[-1]
|
||||
} elif (match $argz 'list') {
|
||||
# asdf list <name>
|
||||
asdf plugin-list
|
||||
} elif (match $argz 'list' '.*') {
|
||||
# asdf list <name> [<version>]
|
||||
ls-installed-versions $argz[-1]
|
||||
} elif (match $argz 'local') {
|
||||
# asdf local <name> [-p|--parent]
|
||||
asdf plugin-list
|
||||
put '-p'
|
||||
put '--parent'
|
||||
} elif (match $argz 'local' '(-p|(--parent))') {
|
||||
# asdf local <name> [-p|--parent] <version>
|
||||
asdf plugin-list
|
||||
} elif (match $argz 'local' '.*') {
|
||||
# asdf local <name> [-p|--parent]
|
||||
# asdf local <name> <version>
|
||||
ls-installed-versions $argz[-1]
|
||||
put '-p'
|
||||
put '--parent'
|
||||
} elif (match $argz 'local' '(-p|(--parent))' '.*') {
|
||||
# asdf local [-p|--parent] <name> <version>
|
||||
ls-installed-versions $argz[-1]
|
||||
} elif (match $argz 'local' '.*' '(-p|(--parent))') {
|
||||
# asdf local <name> [-p|--parent] <version>
|
||||
ls-installed-versions $argz[-2]
|
||||
} elif (match $argz 'local' '.*' '.*') {
|
||||
# asdf local <name> <version> [-p|--parent]
|
||||
put '-p'
|
||||
put '--parent'
|
||||
} elif (or (match $argz 'plugin-add') (match $argz 'plugin' 'add')) {
|
||||
# asdf plugin add <name>
|
||||
asdf plugin-list-all | each {|line|
|
||||
put (re:replace '([^\s]+)\s+.*' '${1}' $line)
|
||||
}
|
||||
} elif (or (match $argz 'plugin-list') (match $argz 'plugin' 'list')) {
|
||||
# asdf plugin list
|
||||
put '--urls'
|
||||
put '--refs'
|
||||
put 'all'
|
||||
} elif (or (match $argz 'plugin-push') (match $argz 'plugin' 'push')) {
|
||||
# asdf plugin push <name>
|
||||
asdf plugin-list
|
||||
} elif (or (match $argz 'plugin-remove') (match $argz 'plugin' 'remove')) {
|
||||
# asdf plugin remove <name>
|
||||
asdf plugin-list
|
||||
} elif (and (>= (count $argz) 3) (match $argz[..3] 'plugin-test' '.*' '.*')) {
|
||||
# asdf plugin-test <plugin-name> <plugin-url> [--asdf-tool-version <version>] [--asdf-plugin-gitref <git-ref>] [test-command*]
|
||||
put '--asdf-plugin-gitref'
|
||||
put '--asdf-tool-version'
|
||||
ls-executables
|
||||
ls-shims
|
||||
} elif (and (>= (count $argz) 4) (match $argz[..4] 'plugin' 'test' '.*' '.*')) {
|
||||
# asdf plugin test <plugin-name> <plugin-url> [--asdf-tool-version <version>] [--asdf-plugin-gitref <git-ref>] [test-command*]
|
||||
put '--asdf-plugin-gitref'
|
||||
put '--asdf-tool-version'
|
||||
ls-executables
|
||||
ls-shims
|
||||
} elif (or (match $argz 'plugin-update') (match $argz 'plugin' 'update')) {
|
||||
# asdf plugin update <name>
|
||||
asdf plugin-list
|
||||
put '--all'
|
||||
} elif (match $argz 'plugin') {
|
||||
# list plugin-* subcommands
|
||||
find $asdf_dir'/lib/commands' -name 'command-plugin-*' | each {|cmd|
|
||||
put (re:replace '.*/command-plugin-(.*)\.bash' '${1}' $cmd)
|
||||
}
|
||||
} elif (match $argz 'reshim') {
|
||||
# asdf reshim <name>
|
||||
asdf plugin-list
|
||||
} elif (match $argz 'reshim' '.*') {
|
||||
# asdf reshim <name> <version>
|
||||
ls-installed-versions $argz[-1]
|
||||
} elif (match $argz 'shim-versions') {
|
||||
# asdf shim-versions <command>
|
||||
ls-shims
|
||||
} elif (match $argz 'uninstall') {
|
||||
# asdf uninstall <name>
|
||||
asdf plugin-list
|
||||
} elif (match $argz 'uninstall' '.*') {
|
||||
# asdf uninstall <name> <version>
|
||||
ls-installed-versions $argz[-1]
|
||||
} elif (match $argz 'update') {
|
||||
if (== $num 1) {
|
||||
# asdf update
|
||||
put '--head'
|
||||
}
|
||||
} elif (match $argz 'where') {
|
||||
# asdf where <name>
|
||||
asdf plugin-list
|
||||
} elif (match $argz 'where' '.*') {
|
||||
# asdf where <name> [<version>]
|
||||
ls-installed-versions $argz[-1]
|
||||
} elif (match $argz 'which') {
|
||||
ls-shims
|
||||
}
|
||||
}
|
||||
}
|
250
cli/completions/asdf.nu
Normal file
250
cli/completions/asdf.nu
Normal file
@ -0,0 +1,250 @@
|
||||
module asdf {
|
||||
|
||||
def "complete asdf sub-commands" [] {
|
||||
[
|
||||
"plugin",
|
||||
"list",
|
||||
"install",
|
||||
"uninstall",
|
||||
"current",
|
||||
"where",
|
||||
"which",
|
||||
"local",
|
||||
"global",
|
||||
"shell",
|
||||
"latest",
|
||||
"help",
|
||||
"exec",
|
||||
"env",
|
||||
"info",
|
||||
"reshim",
|
||||
"shim-version",
|
||||
"update"
|
||||
]
|
||||
}
|
||||
|
||||
def "complete asdf installed" [] {
|
||||
^asdf plugin list | lines | each { |line| $line | str trim }
|
||||
}
|
||||
|
||||
|
||||
def "complete asdf plugin sub-commands" [] {
|
||||
[
|
||||
"list",
|
||||
"list all",
|
||||
"add",
|
||||
"remove",
|
||||
"update"
|
||||
]
|
||||
}
|
||||
|
||||
def "complete asdf installed plugins" [] {
|
||||
^asdf plugin list | lines | each { |line|
|
||||
$line | str trim
|
||||
}
|
||||
}
|
||||
|
||||
def "complete asdf plugin versions all" [context: string] {
|
||||
let plugin = $context | str trim | split words | last
|
||||
^asdf list all $plugin
|
||||
| lines
|
||||
| each { |line| $line | str trim }
|
||||
| prepend "latest"
|
||||
}
|
||||
|
||||
def "complete asdf plugin versions installed" [context: string] {
|
||||
let plugin = $context | str trim | split words | last
|
||||
let versions = ^asdf list $plugin
|
||||
| lines
|
||||
| each { |line| $line | str trim }
|
||||
| each { |version| if ($version | str starts-with "*") {{value: ($version | str substring 1..), description: "current version"}} else {{value: $version, description: ""}} }
|
||||
|
||||
let latest = ^asdf latest $plugin | str trim
|
||||
|
||||
if ($versions | get value | any {|el| $el == $latest}) {
|
||||
$versions | prepend {value: "latest", description: $"alias to ($latest)"}
|
||||
} else {
|
||||
$versions
|
||||
}
|
||||
}
|
||||
|
||||
# ASDF version manager
|
||||
export extern main [
|
||||
subcommand?: string@"complete asdf sub-commands"
|
||||
]
|
||||
|
||||
# Manage plugins
|
||||
export extern "asdf plugin" [
|
||||
subcommand?: string@"complete asdf plugin sub-commands"
|
||||
]
|
||||
|
||||
# List installed plugins
|
||||
export def "asdf plugin list" [
|
||||
--urls # Show urls
|
||||
--refs # Show refs
|
||||
] {
|
||||
|
||||
let params = [
|
||||
{name: 'urls', enabled: $urls, flag: '--urls',
|
||||
template: '\s+?(?P<repository>(?:http[s]?|git).+\.git|/.+)'}
|
||||
{name: 'refs', enabled: $refs, flag: '--refs',
|
||||
template: '\s+?(?P<branch>\w+)\s+(?P<ref>\w+)'}
|
||||
]
|
||||
|
||||
let template = '(?P<name>.+)' + (
|
||||
$params |
|
||||
where enabled |
|
||||
get --ignore-errors template |
|
||||
str join '' |
|
||||
str trim
|
||||
)
|
||||
|
||||
let flags = ($params | where enabled | get --ignore-errors flag | default '' )
|
||||
|
||||
^asdf plugin list ...$flags | lines | parse -r $template | str trim
|
||||
}
|
||||
|
||||
# list all available plugins
|
||||
export def "asdf plugin list all" [] {
|
||||
let template = '(?P<name>.+)\s+?(?P<installed>[*]?)(?P<repository>(?:git|http|https).+)'
|
||||
let is_installed = { |it| $it.installed == '*' }
|
||||
|
||||
^asdf plugin list all |
|
||||
lines |
|
||||
parse -r $template |
|
||||
str trim |
|
||||
update installed $is_installed |
|
||||
sort-by name
|
||||
}
|
||||
|
||||
# Add a plugin
|
||||
export extern "asdf plugin add" [
|
||||
name: string # Name of the plugin
|
||||
git_url?: string # Git url of the plugin
|
||||
]
|
||||
|
||||
# Remove an installed plugin and their package versions
|
||||
export extern "asdf plugin remove" [
|
||||
name: string@"complete asdf installed plugins" # Name of the plugin
|
||||
]
|
||||
|
||||
# Update a plugin
|
||||
export extern "asdf plugin update" [
|
||||
name: string@"complete asdf installed plugins" # Name of the plugin
|
||||
git_ref?: string # Git ref to update the plugin
|
||||
]
|
||||
|
||||
# Update all plugins to the latest commit
|
||||
export extern "asdf plugin update --all" []
|
||||
|
||||
# install a package version
|
||||
export extern "asdf install" [
|
||||
name?: string@"complete asdf installed plugins" # Name of the package
|
||||
version?: string@"complete asdf plugin versions all" # Version of the package or latest
|
||||
]
|
||||
|
||||
|
||||
# Remove an installed package version
|
||||
export extern "asdf uninstall" [
|
||||
name: string@"complete asdf installed" # Name of the package
|
||||
version: string@"complete asdf plugin versions installed" # Version of the package
|
||||
]
|
||||
|
||||
# Display current version
|
||||
export extern "asdf current" [
|
||||
name?: string@"complete asdf installed" # Name of installed version of a package
|
||||
]
|
||||
|
||||
# Display path of an executable
|
||||
export extern "asdf which" [
|
||||
command: string # Name of command
|
||||
]
|
||||
|
||||
# Display install path for an installled package version
|
||||
export extern "asdf where" [
|
||||
name: string@"complete asdf installed" # Name of installed package
|
||||
version?: string@"complete asdf plugin versions installed" # Version of installed package
|
||||
]
|
||||
|
||||
# Set the package local version
|
||||
export extern "asdf local" [
|
||||
name: string@"complete asdf installed" # Name of the package
|
||||
version?: string@"complete asdf plugin versions installed" # Version of the package or latest
|
||||
]
|
||||
|
||||
# Set the package global version
|
||||
export extern "asdf global" [
|
||||
name: string@"complete asdf installed" # Name of the package
|
||||
version?: string@"complete asdf plugin versions installed" # Version of the package or latest
|
||||
]
|
||||
|
||||
# Set the package to version in the current shell
|
||||
export extern "asdf shell" [
|
||||
name: string@"complete asdf installed" # Name of the package
|
||||
version?: string@"complete asdf plugin versions installed" # Version of the package or latest
|
||||
]
|
||||
|
||||
# Show latest stable version of a package
|
||||
export extern "asdf latest" [
|
||||
name: string@"complete asdf installed" # Name of the package
|
||||
version?: string@"complete asdf plugin versions installed" # Filter latest stable version from this version
|
||||
]
|
||||
|
||||
# Show latest stable version for all installed packages
|
||||
export extern "asdf latest --all" []
|
||||
|
||||
# List installed package versions
|
||||
export extern "asdf list" [
|
||||
name?: string@"complete asdf installed" # Name of the package
|
||||
version?: string@"complete asdf plugin versions installed" # Filter the version
|
||||
]
|
||||
|
||||
# List all available package versions
|
||||
export def "asdf list all" [
|
||||
name: string@"complete asdf installed" # Name of the package
|
||||
version?: string@"complete asdf plugin versions installed"="" # Filter the version
|
||||
] {
|
||||
^asdf list all $name $version | lines | parse "{version}" | str trim
|
||||
}
|
||||
|
||||
# Show documentation for plugin
|
||||
export extern "asdf help" [
|
||||
name: string@"complete asdf installed" # Name of the plugin
|
||||
version?: string@"complete asdf plugin versions installed" # Version of the plugin
|
||||
]
|
||||
|
||||
# Execute a command shim for the current version
|
||||
export extern "asdf exec" [
|
||||
command: string # Name of the command
|
||||
...args: any # Arguments to pass to the command
|
||||
]
|
||||
|
||||
# Run util (default: env) inside the environment used for command shim execution
|
||||
export extern "asdf env" [
|
||||
command?: string # Name of the command
|
||||
util?: string = 'env' # Name of util to run
|
||||
]
|
||||
|
||||
# Show information about OS, Shell and asdf Debug
|
||||
export extern "asdf info" []
|
||||
|
||||
# Recreate shims for version package
|
||||
export extern "asdf reshim" [
|
||||
name?: string@"complete asdf installed" # Name of the package
|
||||
version?: string@"complete asdf plugin versions installed" # Version of the package
|
||||
]
|
||||
|
||||
# List the plugins and versions that provide a command
|
||||
export extern "asdf shim-version" [
|
||||
command: string # Name of the command
|
||||
]
|
||||
|
||||
# Update asdf to the latest version on the stable branch
|
||||
export extern "asdf update" []
|
||||
|
||||
# Update asdf to the latest version on the main branch
|
||||
export extern "asdf update --head" []
|
||||
|
||||
}
|
||||
|
||||
use asdf *
|
@ -1,4 +1,5 @@
|
||||
#compdef asdf
|
||||
compdef _asdf asdf
|
||||
#description tool to manage versions of multiple runtimes
|
||||
|
||||
local curcontext="$curcontext" state state_descr line subcmd
|
||||
@ -90,6 +91,7 @@ _asdf__installed_versions_of_plus_system() {
|
||||
compadd -a versions
|
||||
}
|
||||
|
||||
_asdf() {
|
||||
|
||||
local -i IntermediateCount=0
|
||||
|
||||
@ -117,6 +119,8 @@ _asdf__dash_commands() {
|
||||
subcmd="${subcmd}-${words[2+IntermediateCount]}"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
case "$subcmd" in
|
||||
(plugin|shim|list)
|
||||
_asdf__dash_commands
|
||||
@ -220,3 +224,4 @@ case "$subcmd" in
|
||||
(( CURRENT == 3 )) && compadd -- --head
|
||||
;;
|
||||
esac
|
||||
}
|
@ -31,7 +31,7 @@ run_shfmt_stylecheck() {
|
||||
|
||||
print.info "Checking .bash with shfmt"
|
||||
shfmt --language-dialect bash --indent 2 "${shfmt_flag}" \
|
||||
completions/*.bash \
|
||||
cli/completions/*.bash \
|
||||
bin/asdf \
|
||||
bin/private/asdf-exec \
|
||||
lib/utils.bash \
|
||||
@ -55,7 +55,7 @@ run_shellcheck_linter() {
|
||||
|
||||
print.info "Checking .bash files with Shellcheck"
|
||||
shellcheck --shell bash --external-sources \
|
||||
completions/*.bash \
|
||||
cli/completions/*.bash \
|
||||
bin/asdf \
|
||||
bin/private/asdf-exec \
|
||||
lib/utils.bash \
|
||||
@ -123,7 +123,7 @@ run_fish_linter() {
|
||||
printf "%s\n" "[WARNING] fish_indent not found. Skipping .fish files."
|
||||
else
|
||||
print.info "Checking .fish files with fish_indent"
|
||||
fish_indent "${flag}" ./**/*.fish
|
||||
fish_indent "${flag}" ./cli/completions/asdf.fish
|
||||
fi
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user