Skip to content

Commit

Permalink
Merge pull request urfave#1918 from dearchap/issue_1916
Browse files Browse the repository at this point in the history
Fix:(issue_1916) Fix subcommand flag completion
  • Loading branch information
dearchap authored Jun 1, 2024
2 parents de45d2d + 043c05c commit 1210bdf
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 35 deletions.
2 changes: 1 addition & 1 deletion command.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ func (cmd *Command) setupDefaults(osArgs []string) {

if cmd.ShellComplete == nil {
tracef("setting default ShellComplete (cmd=%[1]q)", cmd.Name)
cmd.ShellComplete = DefaultCompleteWithFlags(cmd)
cmd.ShellComplete = DefaultCompleteWithFlags
}

if cmd.Name == "" && isRoot {
Expand Down
16 changes: 16 additions & 0 deletions completion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ func TestCompletionSubcommand(t *testing.T) {
Commands: []*Command{
{
Name: "xyz",
Flags: []Flag{
&StringFlag{
Name: "g",
Aliases: []string{
"t",
},
},
},
},
},
},
Expand All @@ -80,6 +88,14 @@ func TestCompletionSubcommand(t *testing.T) {
out.String(), "xyz",
"Expected output to contain shell name %[1]q", "xyz",
)

out.Reset()

r.NoError(cmd.Run(buildTestContext(t), []string{"foo", "bar", "xyz", "-", "--generate-shell-completion"}))
r.Containsf(
out.String(), "-g",
"Expected output to contain flag %[1]q", "-g",
)
}

func TestCompletionInvalidShell(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion godoc-current.txt
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ func DefaultAppComplete(ctx context.Context, cmd *Command)
DefaultAppComplete prints the list of subcommands as the default app
completion method

func DefaultCompleteWithFlags(cmd *Command) func(ctx context.Context, cmd *Command)
func DefaultCompleteWithFlags(ctx context.Context, cmd *Command)
func FlagNames(name string, aliases []string) []string
func HandleExitCoder(err error)
HandleExitCoder handles errors implementing ExitCoder by printing their
Expand Down
59 changes: 28 additions & 31 deletions help.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ func ShowAppHelp(cmd *Command) error {

// DefaultAppComplete prints the list of subcommands as the default app completion method
func DefaultAppComplete(ctx context.Context, cmd *Command) {
DefaultCompleteWithFlags(nil)(ctx, cmd)
DefaultCompleteWithFlags(ctx, cmd)
}

func printCommandSuggestions(commands []*Command, writer io.Writer) {
Expand Down Expand Up @@ -219,37 +219,34 @@ func printFlagSuggestions(lastArg string, flags []Flag, writer io.Writer) {
}
}

func DefaultCompleteWithFlags(cmd *Command) func(ctx context.Context, cmd *Command) {
return func(_ context.Context, cmd *Command) {
args := os.Args
if cmd != nil && cmd.flagSet != nil && cmd.parent != nil {
args = cmd.Args().Slice()
tracef("running default complete with flags[%v] on command %[1]q", args, cmd.Name)
} else {
tracef("running default complete with os.Args flags")
}
argsLen := len(args)
if argsLen > 2 {
lastArg := args[argsLen-2]

if strings.HasPrefix(lastArg, "-") {
if cmd != nil {
printFlagSuggestions(lastArg, cmd.Flags, cmd.Root().Writer)

return
}

printFlagSuggestions(lastArg, cmd.Flags, cmd.Root().Writer)

return
}
}
func DefaultCompleteWithFlags(ctx context.Context, cmd *Command) {
args := os.Args
if cmd != nil && cmd.flagSet != nil && cmd.parent != nil {
args = cmd.Args().Slice()
tracef("running default complete with flags[%v] on command %[2]q", args, cmd.Name)
} else {
tracef("running default complete with os.Args flags[%v]", args)
}
argsLen := len(args)
lastArg := ""
// parent command will have --generate-shell-completion so we need
// to account for that
if argsLen > 1 {
lastArg = args[argsLen-2]
} else if argsLen > 0 {
lastArg = args[argsLen-1]
}

if strings.HasPrefix(lastArg, "-") {
tracef("printing flag suggestion for flag[%v] on command %[1]q", lastArg, cmd.Name)
printFlagSuggestions(lastArg, cmd.Flags, cmd.Root().Writer)
return
}

if cmd != nil {
tracef("printing command suggestions on command %[1]q", cmd.Name)
printCommandSuggestions(cmd.Commands, cmd.Root().Writer)
return
}
if cmd != nil {
tracef("printing command suggestions on command %[1]q", cmd.Name)
printCommandSuggestions(cmd.Commands, cmd.Root().Writer)
return
}
}

Expand Down
2 changes: 1 addition & 1 deletion help_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1212,7 +1212,7 @@ func TestDefaultCompleteWithFlags(t *testing.T) {
for k, v := range tc.env {
t.Setenv(k, v)
}
f := DefaultCompleteWithFlags(tc.cmd)
f := DefaultCompleteWithFlags
f(context.Background(), tc.cmd)

written := writer.String()
Expand Down
2 changes: 1 addition & 1 deletion testdata/godoc-v3.x.txt
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ func DefaultAppComplete(ctx context.Context, cmd *Command)
DefaultAppComplete prints the list of subcommands as the default app
completion method

func DefaultCompleteWithFlags(cmd *Command) func(ctx context.Context, cmd *Command)
func DefaultCompleteWithFlags(ctx context.Context, cmd *Command)
func FlagNames(name string, aliases []string) []string
func HandleExitCoder(err error)
HandleExitCoder handles errors implementing ExitCoder by printing their
Expand Down

0 comments on commit 1210bdf

Please sign in to comment.