Fix a subcommand matching
This PR fixes an issue where a subcommand matches the current set of commands being examined. Fixes issue https://github.com/posener/complete/issues/46
This commit is contained in:
parent
f4461a52b6
commit
d3c10410d6
|
@ -74,6 +74,12 @@ func (c *Command) predict(a Args) (options []string, only bool) {
|
|||
return
|
||||
}
|
||||
}
|
||||
|
||||
// We matched so stop searching. Continuing to search can accidentally
|
||||
// match a subcommand with current set of commands, see issue #46.
|
||||
if subCommandFound {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// if last completed word is a global flag that we need to complete
|
||||
|
|
|
@ -184,6 +184,81 @@ func TestCompleter_Complete(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestCompleter_Complete_SharedPrefix(t *testing.T) {
|
||||
t.Parallel()
|
||||
initTests()
|
||||
|
||||
c := Command{
|
||||
Sub: Commands{
|
||||
"status": {
|
||||
Flags: Flags{
|
||||
"-f3": PredictNothing,
|
||||
},
|
||||
},
|
||||
"job": {
|
||||
Sub: Commands{
|
||||
"status": {
|
||||
Flags: Flags{
|
||||
"-f4": PredictNothing,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Flags: Flags{
|
||||
"-o": PredictFiles("*.txt"),
|
||||
},
|
||||
GlobalFlags: Flags{
|
||||
"-h": PredictNothing,
|
||||
"-global1": PredictAnything,
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
args string
|
||||
want []string
|
||||
}{
|
||||
{
|
||||
args: "",
|
||||
want: []string{"status", "job", "-h", "-global1", "-o"},
|
||||
},
|
||||
{
|
||||
args: "-",
|
||||
want: []string{"-h", "-global1", "-o"},
|
||||
},
|
||||
{
|
||||
args: "j",
|
||||
want: []string{"job"},
|
||||
},
|
||||
{
|
||||
args: "job ",
|
||||
want: []string{"-h", "-global1", "status"},
|
||||
},
|
||||
{
|
||||
args: "job status ",
|
||||
want: []string{"-f4", "-h", "-global1"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.args, func(t *testing.T) {
|
||||
|
||||
tt.args = "cmd " + tt.args
|
||||
os.Setenv(envComplete, tt.args)
|
||||
line, _ := getLine()
|
||||
|
||||
got := c.Predict(newArgs(line))
|
||||
|
||||
sort.Strings(tt.want)
|
||||
sort.Strings(got)
|
||||
|
||||
if !equalSlices(got, tt.want) {
|
||||
t.Errorf("failed '%s'\ngot = %s\nwant: %s", t.Name(), got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func equalSlices(a, b []string) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
|
|
Loading…
Reference in New Issue