Repository navigation
Case insensitive commands/sub-commands? #2526
Answered
by
pballada
stevewi-niteflyte
asked this question in
Q&A
|
Is there a way to do this? It's some measure of protection against fat-finger Caps-Lock incidents... ;-) |
Answered by
pballada
Nov 3, 2026
Replies: 1 comment 1 reply
|
There's no built-in flag for it. Matching is exact ( In name := cmd.parsedArgs.First()
if cmd.SuggestCommandFunc != nil && name != "--" {
name = cmd.SuggestCommandFunc(cmd.Commands, name)
}
subCmd = cmd.Command(name)So whatever your function returns is the name used for the lookup. Map the typed name to the real one, ignoring case: import (
"context"
"os"
"strings"
"github.com/urfave/cli/v3"
)
func caseInsensitiveCommand(commands []*cli.Command, provided string) string {
for _, c := range commands {
for _, n := range c.Names() { // Name + Aliases
if strings.EqualFold(n, provided) {
return n
}
}
}
return provided // unknown: leave it alone, so CommandNotFound / default command still work
}
// The hook is per command, so set it on every level.
func withCaseInsensitiveCommands(cmd *cli.Command) *cli.Command {
cmd.SuggestCommandFunc = caseInsensitiveCommand
for _, sub := range cmd.Commands {
withCaseInsensitiveCommands(sub)
}
return cmd
}
func main() {
root := withCaseInsensitiveCommands(&cli.Command{
Name: "app",
Commands: []*cli.Command{ /* ... */ },
})
_ = root.Run(context.Background(), os.Args)
}
Two details:
Flags are separate. Their names are still matched exactly. Upper-case |
1 reply
Answer selected by
stevewi-niteflyte
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
There's no built-in flag for it. Matching is exact (
HasNameisslices.Contains(cmd.Names(), name)), but v3 has a hook in exactly the right place:SuggestCommandFunc.In
command_run.go, before looking up the subcommand, the command does this:So whatever your function returns is the name used for the lookup. Map the typed name to the real one, ignoring case: