You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
For some use cases of command line completion it would be helpful if there was a means to override the default behaviour of generating the completion list for flags.
# when hitting tab to generate command line completion ValidArgsFunction is called if present
appcli command arg1
# when hitting tab to generate command line completion getCompletions() handles the return values and ValidArgsFunction is not called
appcli command arg1 -
Most use cases of modifying the return list can be handled by leveraging MarkFlagsMutuallyExclusive(), but this only works for defined flags.
For context aware situations where the presence of a specific argument in the command line would modify which flags should be available it would be nice if getCompletions() called the command's ValidArgsFunction , which would allow the developer to customize the return list.
I can conceive of at least two implementations to add this functionality/feature to Cobra:
Change the default behaviour in getCompletions() such that whenever ValidArgsFunction is present it is always called. Likely not a good choice as it would break backward compatibility for the current implementation.
Introduce a new feature flag for commands to cause getCompletions() to call defer processing of a flag '-' to the command's ValidArgsFunction, if present. If ValidArgsFunction is not present, one of two behaviours could be entertained, either:
return an error indicating the feature was enabled, but the function was not defined, or
process the completion as it currently does.
The value of adding this capability is it provides the developer greater control of the command line completion results when the default behaviour does not satisfy the use case. The code written in ValidArgsFunction does not need any additional support to take advantage of this.
Example:
For the 'command' with three flags defined --flag1, --flag2, & --flag3 and the following:
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list := []string{}
if len(args) == 0 {
// add valid flags and presets
list = append(list, "--flag1")
list = append(list, "--flag2")
list = append(list, "--flag3")
list = append(list, "arg1")
list = append(list, "arg2")
list = append(list, "arg3")
} else {
list = append(list, "--flag1")
list = append(list, "--flag2")
}
return list, cobra.ShellCompDirectiveNoFileComp
},
A more sophisticated implementation might look like:
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list := []string{}
if len(args) == 0 {
// add valid flags and presets
list = []string{ "arg1", "arg2", "arg3"} {
list = append( list, flagHintsRevised( cmd, []string{})...)
} else {
list = flagHintsRevised( cmd, "--flag3")
}
return list, cobra.ShellCompDirectiveNoFileComp
},
using the support functions:
func flagHintsRevised(cmd *cobra.Command, forceRemovalList []string) []string {
list := []string{}
flagset := cmd.Flags()
// has at least 1 non-hidden flag
if !flagset.HasAvailableFlags() {
return list
}
flagset.VisitAll(func(
flag *pflag.Flag,
) {
if !flag.Hidden && !flag.Changed && !isFlagInList(flag, forceRemovalList) {
if flag.Name != "" {
list = append(list, "--" + flag.Name)
}
if flag.Shorthand != "" {
list = append( "-" + flag.Shorthand)
}
}
})
return list
}
func isFlagInList(flag *pflag.Flag, list []string) bool {
for _, v := range list {
if v == flag.Name || v == flag.Shorthand {
return true
}
}
return false
}
The text was updated successfully, but these errors were encountered:
Thinking quickly, another solution could be that instead of reusing ValidArgsFunction, we could add a new ValidFlagFunction. This approach may make it easier to reason about the list of completions to return since it would not require to pay attention if the first character is a - in ValidArgsFunction.
This approach would also preserve backwards compatibility.
One risk in not completing flags automatically though is that if a flag is added later on, the developer may forget to add it to its own custom completion function.
For some use cases of command line completion it would be helpful if there was a means to override the default behaviour of generating the completion list for flags.
Most use cases of modifying the return list can be handled by leveraging MarkFlagsMutuallyExclusive(), but this only works for defined flags.
For context aware situations where the presence of a specific argument in the command line would modify which flags should be available it would be nice if getCompletions() called the command's ValidArgsFunction , which would allow the developer to customize the return list.
I can conceive of at least two implementations to add this functionality/feature to Cobra:
Change the default behaviour in getCompletions() such that whenever ValidArgsFunction is present it is always called. Likely not a good choice as it would break backward compatibility for the current implementation.
Introduce a new feature flag for commands to cause getCompletions() to call defer processing of a flag '-' to the command's ValidArgsFunction, if present. If ValidArgsFunction is not present, one of two behaviours could be entertained, either:
The value of adding this capability is it provides the developer greater control of the command line completion results when the default behaviour does not satisfy the use case. The code written in ValidArgsFunction does not need any additional support to take advantage of this.
Example:
For the 'command' with three flags defined
--flag1
,--flag2
, &--flag3
and the following:A more sophisticated implementation might look like:
using the support functions:
The text was updated successfully, but these errors were encountered: