diff --git a/command_parse.go b/command_parse.go index a4d943848e..74a7db013b 100644 --- a/command_parse.go +++ b/command_parse.go @@ -4,6 +4,7 @@ import ( "fmt" "strings" "unicode" + "unicode/utf8" ) const ( @@ -133,7 +134,7 @@ func (cmd *Command) parseFlags(args Args) (Args, error) { if firstArg[1] == '-' { numMinuses++ shortOptionHandling = false - } else if !unicode.IsLetter(rune(firstArg[1])) { + } else if firstRune, _ := utf8.DecodeRuneInString(firstArg[1:]); !unicode.IsLetter(firstRune) { // this is not a flag tracef("parseFlags not a unicode letter. Stop parsing") posArgs = append(posArgs, rargs...) diff --git a/command_test.go b/command_test.go index 21754efeaa..d416534364 100644 --- a/command_test.go +++ b/command_test.go @@ -1229,6 +1229,27 @@ func TestCommand_FlagValuesKeepWhitespace(t *testing.T) { } } +func TestCommand_SingleRuneUnicodeFlag(t *testing.T) { + const name = "ש" + assert.Equal(t, "-", prefixFor(name)) + + var value string + var args []string + cmd := &Command{ + Name: "app", + Flags: []Flag{&StringFlag{Name: name}}, + Action: func(_ context.Context, cmd *Command) error { + value = cmd.String(name) + args = cmd.Args().Slice() + return nil + }, + } + + require.NoError(t, cmd.Run(buildTestContext(t), []string{"app", "-" + name, "value", "operand"})) + assert.Equal(t, "value", value) + assert.Equal(t, []string{"operand"}, args) +} + func TestCommand_EqualsFlagValueValidation(t *testing.T) { for _, kind := range []string{"int", "bool"} { for _, whitespace := range []string{"", " ", "\t"} { diff --git a/docs.go b/docs.go index 88461386b8..30c053ca81 100644 --- a/docs.go +++ b/docs.go @@ -5,10 +5,11 @@ import ( "os" "runtime" "strings" + "unicode/utf8" ) func prefixFor(name string) (prefix string) { - if len(name) == 1 { + if utf8.RuneCountInString(name) == 1 { prefix = "-" } else { prefix = "--"