carapace
Completion script generator for cobra with support for:
Status
WIP: works, but expect some api changes and small hiccups like a special character not yet escaped
Usage
Calling carapace.Gen
on any command is enough to enable completion script generation using the hidden command.
Invocations to carapace.Gen
must be after the command was added to the parent command so that the uids are correct.
import (
"github.com/rsteube/carapace"
)
carapace.Gen(myCmd)
FlagCompletions
Completion for flags can be configured with FlagCompletion
and a map consisting of name and action.
carapace.Gen(myCmd).FlagCompletion(carapace.ActionMap{
"flagName": carapace.ActionValues("a", "b", "c"),
...
})
PositionalCompletions
Completion for positional arguments can be configured with PositionalCompletion
and a list of actions.
carapace.Gen(callbackCmd).PositionalCompletion(
carapace.ActionValues("a", "b", "c"),
...
)
Hidden Command
When carapace.Gen(myCmd)
is invoked a hidden command (_carapace
) is added to the root command unless it already exists. This handles completion script generation and callbacks.
Uid
Uids are generated to identify corresponding completions:
_{rootCmd}__{subCommand1}__{subCommand2}#{position}
for positional arguments
_{rootCmd}__{subCommand1}__{subCommand2}##{flagName}
for flags
Action
An action indicates how to complete a flag or a positional argument. See action.go and the examples below for current implementations. A range of custom actions can be found at rsteube/carapace-bin
ActionMessage
carapace.ActionMessage("message example")
// #./example action --message <TAB>
// message example
ActionValuesDescribed
carapace.ActionValuesDescribed(
"values", "valueDescription",
"example", "exampleDescription"),
// #./example action --values_described <TAB>
// example -- exampleDescription
// values -- valueDescription
ActionCallback
ActionCallback is a special action where the program itself provides the completion dynamically. For this the hidden command is called with a uid and the current command line content which then lets cobra parse existing flags and invokes the callback function after that.
carapace.ActionCallback(func(args []string) carapace.Action {
if conditionCmd.Flag("required").Value.String() == "valid" {
return carapace.ActionValues("condition fulfilled")
} else {
return carapace.ActionMessage("flag --required must be set to valid: " + conditionCmd.Flag("required").Value.String())
}
})
// #./example condition --required invalid <TAB>
// flag --required must be set to valid: invalid
Since callbacks are simply invocations of the program they can be tested directly.
./example _carapace bash '_example__condition#1' example condition --required invalid
#compgen -W $'_\nERR (flag --required must be set to valid: invalid)' -- "${cur//\\ / }" | sed "s!^${curprefix//\\ / }!!"
./example _carapace elvish '_example__condition#1' example condition --required invalid
#edit:complex-candidate ERR &display-suffix=' (flag --required must be set to valid: invalid)'
#edit:complex-candidate _ &display-suffix=' ()'
./example _carapace fish '_example__condition#1' example condition --required invalid
#echo -e ERR\tflag --required must be set to valid: invalid\n_\t\n\n
./example _carapace powershell '_example__condition#1' example condition --required invalid
#[CompletionResult]::new('ERR', 'ERR', [CompletionResultType]::ParameterValue, ' ')
#[CompletionResult]::new('flag --required must be set to valid: invalid', 'flag --required must be set to valid: invalid', [CompletionResultType]::ParameterValue, ' ')
./example _carapace xonsh '_example__condition#1' example condition --required invalid
#{
# RichCompletion('_', display='_', description='flag --required must be set to valid: invalid', prefix_len=0),
# RichCompletion('ERR', display='ERR', description='flag --required must be set to valid: invalid', prefix_len=0),
#}
./example _carapace zsh '_example__condition#1' example condition --required invalid
#{local _comp_desc=('_' 'ERR (flag --required must be set to valid: invalid)');compadd -S '' -d _comp_desc '_' 'ERR'}
ActionMultiParts
ActionMultiParts is a callback action where parts of an argument can be completed separately (e.g. user:group from chown). Divider can be empty as well, but note that bash
and fish
will add the space suffix for anything other than /=@:.,
(it still works, but after each selection backspace is needed to continue the completion).
func ActionUserGroup() carapace.Action {
return carapace.ActionMultiParts(":", func(args []string, parts []string) carapace.Action {
switch len(parts) {
case 0:
return ActionUsers().Invoke(args).Suffix(":").ToA()
case 1:
return ActionGroups()
default:
return carapace.ActionValues()
}
})
}
Shell Completion Documentation
Additional information can be found at:
Standalone Mode
Carapace can also be used to provide completion for arbitrary commands as well (similar to aws_completer).
See rsteube/carapace-bin for examples. There is also a binary to parse flags from gnu help pages at caraparse.
Example
An example implementation can be found in the example folder.
cd example
go build .
# bash
PATH=$PATH:$(pwd)
source <(example _carapace bash)
# elvish (-source will be replaced in next version: `eval (example _carapace elvish | slurp`)
)
paths=[$@paths (pwd)]
example _carapace elvish > example.elv
-source example.elv
# fish
set PATH $PATH (pwd)
example _carapace fish | source
# oil
PATH=$PATH:$(pwd)
source <(example _carapace oil)
# powershell
Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete
$env:PATH += ":$pwd"
example _carapace powershell | out-string | Invoke-Expression
# xonsh
$PATH.append($(pwd))
exec($(example _carapace xonsh))
# zsh
PATH=$PATH:$(pwd)
source <(example _carapace zsh)
example <TAB>
or use docker-compose:
docker-compose run --rm build
docker-compose run --rm [bash|elvish|fish|oil|powershell|xonsh|zsh]
example <TAB>
Projects
- carapace-bin multi-shell multi-command argument completer
- gh github cli with added completions (fork)
- lab cli client for GitLab