mirror of
https://github.com/spf13/cobra
synced 2024-11-16 18:57:08 +00:00
"fixing oddities with fuzzy searching and bug with active help"
This commit is contained in:
parent
4ad4930a12
commit
f366bb2799
1 changed files with 88 additions and 28 deletions
|
@ -31,7 +31,7 @@ let cobra_apps = ["%[1]s"]
|
|||
|
||||
# An external completer that works with any cobra based
|
||||
# command line application (e.g. kubectl, minikube)
|
||||
let cobra_completer = {|spans|
|
||||
let-env cobra_completer = {|spans|
|
||||
let cmd = $spans.0
|
||||
|
||||
if not ($cobra_apps | where $cmd =~ $it | is-empty) {
|
||||
|
@ -43,44 +43,96 @@ let cobra_completer = {|spans|
|
|||
|
||||
let last_span = ($spans | last | str trim)
|
||||
|
||||
# skip the first entry in the span (the command) and join the rest of the span to create __complete args
|
||||
let cmd_args = ($spans | skip 1 | str join ' ')
|
||||
def exec_complete [
|
||||
--fuzzy,
|
||||
spans: list
|
||||
] {
|
||||
let params = {
|
||||
last_span: ($spans | last | str trim),
|
||||
spans: $spans
|
||||
}
|
||||
|
||||
# If there is an equals in the last span
|
||||
# parse the span into two
|
||||
let params = if $last_span =~ '=' {
|
||||
let split = ($last_span | split row '=')
|
||||
if ($split | length) > 1 {
|
||||
{
|
||||
last_span: ($split | last),
|
||||
spans: ($spans | drop | append ($split | first) | append ($split | last))
|
||||
}
|
||||
} else {
|
||||
{
|
||||
last_span: '',
|
||||
spans: ($spans | drop | append ($split | first) | append '')
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$params
|
||||
}
|
||||
|
||||
# If the last span entry was empty add "" to the end of the command args
|
||||
let cmd_args = if ($last_span | is-empty) {
|
||||
$'($cmd_args) ""'
|
||||
} else {
|
||||
$cmd_args
|
||||
let last_span = $params.last_span
|
||||
let spans = $params.spans
|
||||
|
||||
# Drop the last param so we can fuzzy search on it
|
||||
let spans = if $fuzzy {
|
||||
$spans | drop
|
||||
} else {
|
||||
$spans
|
||||
}
|
||||
|
||||
# skip the first entry in the span (the command) and join the rest of the span to create __complete args
|
||||
let cmd_args = ($spans | skip 1 | str join ' ')
|
||||
|
||||
# If the last span entry was empty add "" to the end of the command args
|
||||
let cmd_args = if ($last_span | is-empty) or $fuzzy {
|
||||
$'($cmd_args) ""'
|
||||
} else {
|
||||
$cmd_args
|
||||
}
|
||||
|
||||
# The full command to be executed with active help disable (Nushell does not support active help)
|
||||
let full_cmd = $'COBRA_ACTIVE_HELP=0 ($cmd) __complete ($cmd_args)'
|
||||
|
||||
# Since nushell doesn't have anything like eval, execute in a subshell
|
||||
let result = (do -i { nu -c $"'($full_cmd)'" } | complete)
|
||||
|
||||
# Create a record with all completion related info.
|
||||
# directive and directive_str are for posterity
|
||||
let stdout_lines = ($result.stdout | lines)
|
||||
let directive = ($stdout_lines | last | str trim | str replace ":" "" | into int)
|
||||
let completions = ($stdout_lines | drop | parse -r '([\w\-\.:\+\=]*)\t?(.*)' | rename value description)
|
||||
let completions = if $fuzzy {
|
||||
$completions | where $it.value =~ $last_span
|
||||
|
||||
} else {
|
||||
($completions | where {|it| $it.value | str starts-with $last_span })
|
||||
}
|
||||
|
||||
{
|
||||
directive: $directive,
|
||||
completions: $completions
|
||||
}
|
||||
}
|
||||
|
||||
# The full command to be executed with active help disable (Nushell does not support active help)
|
||||
let full_cmd = $'%[7]s=0 ($cmd) __complete ($cmd_args)'
|
||||
|
||||
# Since nushell doesn't have anything like eval, execute in a subshell
|
||||
let result = (do -i { nu -c $"'($full_cmd)'" } | complete)
|
||||
|
||||
# Create a record with all completion related info.
|
||||
# directive and directive_str are for posterity
|
||||
let stdout_lines = ($result.stdout | lines)
|
||||
let directive = ($stdout_lines | last | str trim | str replace ":" "" | into int)
|
||||
let completions = ($stdout_lines | drop | parse -r '([\w\-\.:\+\=]*)\t?(.*)' | rename value description)
|
||||
|
||||
# filter completions that don't contain the last span, for fuzzy searches
|
||||
let filtered = ($completions | where $it.value =~ $last_span)
|
||||
let completions = if not ($filtered | is-empty) {
|
||||
$filtered
|
||||
let result = (exec_complete $spans)
|
||||
let result = if (not ($last_span | is-empty)) and ($result.completions | is-empty) {
|
||||
exec_complete --fuzzy $spans
|
||||
} else {
|
||||
$completions
|
||||
$result
|
||||
}
|
||||
|
||||
let directive = $result.directive
|
||||
let completions = $result.completions
|
||||
|
||||
# Add space at the end of each completion
|
||||
let completions = if $directive != $ShellCompDirectiveNoSpace {
|
||||
($completions | each {|it| {value: $"($it.value) ", description: $it.description}})
|
||||
$completions | each {|it| {value: $"($it.value) ", description: $it.description}}
|
||||
} else {
|
||||
$completions
|
||||
}
|
||||
|
||||
if $last_span =~ '=' {
|
||||
let return_val = if $last_span =~ '=' {
|
||||
# if the completion is of the form -n= return flag as part of the completion so that it doesn't get replaced
|
||||
$completions | each {|it| $"($last_span | split row '=' | first)=($it.value)" }
|
||||
} else if $directive == $ShellCompDirectiveNoFileComp {
|
||||
|
@ -93,12 +145,20 @@ let cobra_completer = {|spans|
|
|||
} else {
|
||||
$completions
|
||||
}
|
||||
|
||||
$return_val
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
`, name, ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
|
||||
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, activeHelpEnvVar(name)))
|
||||
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs))
|
||||
|
||||
_, err := buf.WriteTo(w)
|
||||
return err
|
||||
|
|
Loading…
Reference in a new issue