Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Completion does not work correctly if there is a @ symbol in the string #2144

Open
Bernigend opened this issue May 7, 2024 · 2 comments
Open

Comments

@Bernigend
Copy link

Summary

If the flag can take values that contain the "@" character, then value substitution stops working after entering this character.

Examples

All available values

[$] clddev systemctl status2 --unit
group1@subunit   group2@subunit2  unit1            unit1_long

Value which starts with group

[$] clddev systemctl status2 --unit group
group1@subunit   group2@subunit2

Value with symbol @

[$] clddev systemctl status2 --unit group1@sub

And it is empty

How to reproduce

package status2

import (
	"github.com/spf13/cobra"
)

func Cmd() *cobra.Command {
	cmd := &cobra.Command{
		Use:  "status2",
		RunE: Handler,
	}

	cmd.Flags().String("unit", "", "systemctl status unit")
	cmd.RegisterFlagCompletionFunc("unit", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return []string{
			"unit1",
			"unit1_long",
			"group1@subunit",
			"group2@subunit2",
		}, 0
	})

	return cmd
}

func Handler(cmd *cobra.Command, args []string) error {
	return nil
}

Log

========= starting completion logic ==========
cur is , words[*] is clddev systemctl status2 --unit , #words[@] is 5, cword is 4
Truncated words[*]: clddev systemctl status2 --unit ,
lastParam , lastChar
Adding extra empty parameter
Calling clddev __complete systemctl status2 --unit  ''
The completion directive is: 0
The completions are: unit1
unit1_long
group1@subunit
group2@subunit2

__clddev_handle_completion_types: COMP_TYPE is 63

========= starting completion logic ==========
cur is group, words[*] is clddev systemctl status2 --unit group, #words[@] is 5, cword is 4
Truncated words[*]: clddev systemctl status2 --unit group,
lastParam group, lastChar p
Calling clddev __complete systemctl status2 --unit group
The completion directive is: 0
The completions are: unit1
unit1_long
group1@subunit
group2@subunit2

__clddev_handle_completion_types: COMP_TYPE is 9

========= starting completion logic ==========
cur is group, words[*] is clddev systemctl status2 --unit group, #words[@] is 5, cword is 4
Truncated words[*]: clddev systemctl status2 --unit group,
lastParam group, lastChar p
Calling clddev __complete systemctl status2 --unit group
The completion directive is: 0
The completions are: unit1
unit1_long
group1@subunit
group2@subunit2

__clddev_handle_completion_types: COMP_TYPE is 63

========= starting completion logic ==========
cur is @, words[*] is clddev systemctl status2 --unit group1 @, #words[@] is 6, cword is 5
Truncated words[*]: clddev systemctl status2 --unit group1 @,
lastParam @, lastChar @
Calling clddev __complete systemctl status2 --unit group1 @
The completion directive is: 0
The completions are:
__clddev_handle_completion_types: COMP_TYPE is 9

========= starting completion logic ==========
cur is @, words[*] is clddev systemctl status2 --unit group1 @, #words[@] is 6, cword is 5
Truncated words[*]: clddev systemctl status2 --unit group1 @,
lastParam @, lastChar @
Calling clddev __complete systemctl status2 --unit group1 @
The completion directive is: 0
The completions are:
__clddev_handle_completion_types: COMP_TYPE is 63

========= starting completion logic ==========
cur is sub, words[*] is clddev systemctl status2 --unit group1 @ sub, #words[@] is 7, cword is 6
Truncated words[*]: clddev systemctl status2 --unit group1 @ sub,
lastParam sub, lastChar b
Calling clddev __complete systemctl status2 --unit group1 @ sub
The completion directive is: 0
The completions are:
__clddev_handle_completion_types: COMP_TYPE is 9

========= starting completion logic ==========
cur is sub, words[*] is clddev systemctl status2 --unit group1 @ sub, #words[@] is 7, cword is 6
Truncated words[*]: clddev systemctl status2 --unit group1 @ sub,
lastParam sub, lastChar b
Calling clddev __complete systemctl status2 --unit group1 @ sub
The completion directive is: 0
The completions are:
__clddev_handle_completion_types: COMP_TYPE is 63
@marckhouzam
Copy link
Collaborator

I’ll have to play around to understand better but you could try changing the content of COMP_WORDBREAKS. Maybe it’ll help

@nirs
Copy link
Contributor

nirs commented May 17, 2024

@Bernigend I could not reproduce the issue with your example since it is not complete.

I tried to reproduce with the following, which seem to work as expected:

package main

import (
	"log"

	"github.com/spf13/cobra"
)

func main() {
	root := &cobra.Command{
		Use:   "cobra-test",
		Short: "test short",
	}

	child := &cobra.Command{
		Use:   "child",
		Short: "child short",
		Run: func(cmd *cobra.Command, args []string) {
			log.Printf("child run with args: %v", args)
		},
	}

	child.Flags().String("unit", "", "unit help")
	child.RegisterFlagCompletionFunc("unit", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		words := []string{
			"value",
			"pre@post1",
			"pre@post2",
		}
		return words, cobra.ShellCompDirectiveDefault
	})

	root.AddCommand(child)

	if err := root.Execute(); err != nil {
		log.Fatal(err)
	}
}

Example completion value with @

$ cobra-test child --unit pre@post[tab]
pre@post1  pre@post2  

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants