cobra
cobra copied to clipboard
Shell completions with whitespace seem to work differently on bash vs. other supported shells
Other shell completions escape whitespace in completions, but bash completions seems to add completions with whitespace as multiple suggestions or multiple arguments depending on bash version. I would expect also bash completions to escape whitespace in completions from ValidArgsFunction
.
bash v3:
$ ./sh-completion-demo whitespace [TAB][TAB]
no-whitespace with whitespace
$ ./sh-completion-demo whitespace w[TAB]
$ ./sh-completion-demo whitespace with whitespace
bash v4 & v5
$ ./sh-completion-demo whitespace [TAB][TAB]
no-whitespace whitespace with
fish:
> ./sh-completion-demo whitespace [TAB]
no-whitespace with whitespace
> ./sh-completion-demo whitespace w[TAB]
> ./sh-completion-demo whitespace with\ whitespace
zsh:
% ./sh-completion-demo whitespace [TAB]
no-whitespace with whitespace
% ./sh-completion-demo whitespace w[TAB]
% ./sh-completion-demo whitespace with\ whitespace
powershell
> .\sh-completion-demo.exe whitespace [TAB]
> .\sh-completion-demo.exe whitespace with` whitespace
Minimal code to reproduce above usage with github.com/spf13/cobra v1.5.0
(Gist):
package main
import (
"fmt"
"os"
"github.com/spf13/cobra"
)
var RootCmd = &cobra.Command{
Use: "sh-completion-demo",
Long: "Demo shell completion with whitespace",
}
var WhitespaceCmd = &cobra.Command{
Use: "whitespace",
Short: "Noun with completion that includes whitespace",
RunE: func(cmd *cobra.Command, args []string) error {
if args[0] != "with whitespace" && args[0] != "no-whitespace" {
return fmt.Errorf(`argument must be "with whitespace" or "no-whitespace"`)
}
return nil
},
SilenceUsage: true,
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{"with whitespace", "no-whitespace"}, cobra.ShellCompDirectiveNoFileComp
},
}
func init() {
RootCmd.AddCommand(WhitespaceCmd)
}
func main() {
if err := RootCmd.Execute(); err != nil {
os.Exit(1)
}
}
@scop, you may have some expertise on this. Do you have special handling if a completion has a space in it for bash?
Hi @kangasta ;)
It's annoyingly difficult in bash.
A cheap generic way is to fake the completions to be filenames. That does take care of the escaping, but it's obviously semantically incorrect for completions that really aren't filenames. And it may have side effects.
Another one is to run the strings through printf %q ...
here and there in the completion code. Some related discussion e.g. at https://stackoverflow.com/questions/26509260/bash-tab-completion-with-spaces
Anyway I believe neither of these options is currently available for cobra users. I'll have a quick peek at PR #1743.
The Cobra project currently lacks enough contributors to adequately respond to all issues. This bot triages issues and PRs according to the following rules:
- After 60d of inactivity, lifecycle/stale is applied. - After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied and the issue is closed. You can:
- Make a comment to remove the stale label and show your support. The 60 days reset. - If an issue has lifecycle/rotten and is closed, comment and ask maintainers if they'd be interseted in reopening
Rebased related PR and added comment there as well: #1743
The Cobra project currently lacks enough contributors to adequately respond to all issues. This bot triages issues and PRs according to the following rules:
- After 60d of inactivity, lifecycle/stale is applied. - After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied and the issue is closed. You can:
- Make a comment to remove the stale label and show your support. The 60 days reset. - If an issue has lifecycle/rotten and is closed, comment and ask maintainers if they'd be interested in reopening
Adding a comment to keep this from being closed.
I ran across this the other day. This isn't just limited to whitespace, but all characters that need escaping in bash. My completions were using >
, which is kinda unfortunate because cobra started redirecting output to random places during completion