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

Autocomplete: subcommands are run while in autocompletion mode #272

Closed
Zyko0 opened this issue Aug 25, 2015 · 6 comments
Closed

Autocomplete: subcommands are run while in autocompletion mode #272

Zyko0 opened this issue Aug 25, 2015 · 6 comments
Labels
help wanted please help if you can! kind/bug describes or fixes a bug

Comments

@Zyko0
Copy link

Zyko0 commented Aug 25, 2015

It appears that when I do:

./mybinary -a arg -n <tab><tab>
-a   : a correct flag
arg : a correct arg
-n   : an incorrect flag

my client tries to run -n or whatever the last arg is, and ends up showing my app's help.
Sometimes when "-n" is a correct command, it's executed and showing in the argument selection while it should not.

I decided to take a look at cli functions:
-> codegangsta/cli/help.go

func checkCommandCompletions(c *Context, name string) bool {
        if c.Bool(BashCompletionFlag.Name) && c.App.EnableBashCompletion {
                ShowCommandCompletions(c, name)
                return true
        }
        return false
}

And I noticed that c.Bool(BashCompletionFlag.Name) was false sometimes, while I am pressing tab and not running the program.

I replaced this code by :

func checkCommandCompletions(c *Context, name string) bool {
        if c.App.EnableBashCompletion {
                for i := range os.Args {
                        if strings.Contains(os.Args[i], "generate-bash-completion") {
                                ShowCommandCompletions(c, name)
                                return true
                        }
                }
        }
        return false
}

And also here :
https://github.com/codegangsta/cli/blob/master/command.go#L53-L129

I moved the context declaration and the checkCommandCompletions call, next to the set.SetOutput call like this :

[...]
 if ctx.App.EnableBashCompletion {
                c.Flags = append(c.Flags, BashCompletionFlag)
        }

        set := flagSet(c.Name, c.Flags)
        set.SetOutput(ioutil.Discard)
// New completion check
        context := NewContext(ctx.App, set, ctx)

        if checkCommandCompletions(context, c.Name) {
                return nil
        }
// End of completion check
        firstFlagIndex := -1
        terminatorIndex := -1
[...]

That way, the cli doesn't call command or help ( if the command doesn't exist ) anymore if bash completion is enabled.
It's working very well for me but I'm sure there's a better way to do it.

Thanks in advance,

@Zyko0
Copy link
Author

Zyko0 commented Sep 15, 2015

Anyone had the same issue?
(It should be labeled as #bug)

@mikkeloscar
Copy link

I ran into this bug. It happens when you pass arguments like this myprog --arg-that-takes-value --generate-bash-completion

In this case --generate-bash-completion is treated as the value of --arg-that-takes-value and thus messes stuff up.

I think the best solution would be to parse --generate-bash-completion from os.Args as one of the very first things, and separate it from the rest of the logic.

@jszwedko
Copy link
Contributor

Indeed, this does seem like a bug. I'll try to find some time to address this, but I'm happy to review any pull requests to push this along.

@tianon
Copy link
Member

tianon commented Jun 1, 2016

This could be mitigated slightly by changing the script to insert --generate-bash-completion as the very first flag instead of just adding it to the end.

@wav
Copy link

wav commented Sep 9, 2016

Based on @tianon's suggestion something like this could be done. It appears to work for regular Commands with bash completion, I haven't used for SubCommands.

if [ $COMP_CWORD -eq 1 ]; then
  opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-bash-completion )
else
  opts=$(${COMP_WORDS[@]:0:2} --generate-bash-completion ${COMP_WORDS[@]:2:$COMP_CWORD} )   
fi
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )

@coilysiren
Copy link
Member

Given that this is from last year, I think I'm comfortable closing it 🙂 feel free to re-open / open a new issue / comment in support if there's still interest here!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted please help if you can! kind/bug describes or fixes a bug
Projects
None yet
Development

No branches or pull requests

6 participants