Skip to content

Shell completions with whitespace seem to work differently on bash vs. other supported shells #1740

@kangasta

Description

@kangasta

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)
	}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions