Consider case when sorting strings
This makes sorting flags and other sections consistent with how most command line tools function, by placing both flags `-A` and `-a` before a flag `-B`.
This commit is contained in:
parent
7bc6a0acff
commit
b44660ac3d
@ -10,7 +10,7 @@ type CommandCategory struct {
|
||||
}
|
||||
|
||||
func (c CommandCategories) Less(i, j int) bool {
|
||||
return c[i].Name < c[j].Name
|
||||
return lexicographicLess(c[i].Name, c[j].Name)
|
||||
}
|
||||
|
||||
func (c CommandCategories) Len() int {
|
||||
|
@ -73,7 +73,7 @@ func (c CommandsByName) Len() int {
|
||||
}
|
||||
|
||||
func (c CommandsByName) Less(i, j int) bool {
|
||||
return c[i].Name < c[j].Name
|
||||
return lexicographicLess(c[i].Name, c[j].Name)
|
||||
}
|
||||
|
||||
func (c CommandsByName) Swap(i, j int) {
|
||||
|
2
flag.go
2
flag.go
@ -53,7 +53,7 @@ func (f FlagsByName) Len() int {
|
||||
}
|
||||
|
||||
func (f FlagsByName) Less(i, j int) bool {
|
||||
return f[i].GetName() < f[j].GetName()
|
||||
return lexicographicLess(f[i].GetName(), f[j].GetName())
|
||||
}
|
||||
|
||||
func (f FlagsByName) Swap(i, j int) {
|
||||
|
29
sort.go
Normal file
29
sort.go
Normal file
@ -0,0 +1,29 @@
|
||||
package cli
|
||||
|
||||
import "unicode"
|
||||
|
||||
// lexicographicLess compares strings alphabetically considering case.
|
||||
func lexicographicLess(i, j string) bool {
|
||||
iRunes := []rune(i)
|
||||
jRunes := []rune(j)
|
||||
|
||||
lenShared := len(iRunes)
|
||||
if lenShared > len(jRunes) {
|
||||
lenShared = len(jRunes)
|
||||
}
|
||||
|
||||
for index := 0; index < lenShared; index++ {
|
||||
ir := iRunes[index]
|
||||
jr := jRunes[index]
|
||||
|
||||
if lir, ljr := unicode.ToLower(ir), unicode.ToLower(jr); lir != ljr {
|
||||
return lir < ljr
|
||||
}
|
||||
|
||||
if ir != jr {
|
||||
return ir < jr
|
||||
}
|
||||
}
|
||||
|
||||
return i < j
|
||||
}
|
30
sort_test.go
Normal file
30
sort_test.go
Normal file
@ -0,0 +1,30 @@
|
||||
package cli
|
||||
|
||||
import "testing"
|
||||
|
||||
var lexicographicLessTests = []struct {
|
||||
i string
|
||||
j string
|
||||
expected bool
|
||||
}{
|
||||
{"", "a", true},
|
||||
{"a", "", false},
|
||||
{"a", "a", false},
|
||||
{"a", "A", false},
|
||||
{"A", "a", true},
|
||||
{"aa", "a", false},
|
||||
{"a", "aa", true},
|
||||
{"a", "b", true},
|
||||
{"a", "B", true},
|
||||
{"A", "b", true},
|
||||
{"A", "B", true},
|
||||
}
|
||||
|
||||
func TestLexicographicLess(t *testing.T) {
|
||||
for _, test := range lexicographicLessTests {
|
||||
actual := lexicographicLess(test.i, test.j)
|
||||
if test.expected != actual {
|
||||
t.Errorf(`expected string "%s" to come before "%s"`, test.i, test.j)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user