Skip to content

Commit f30735f

Browse files
committed
fix(sort): make filenames start with digits prior than letters
1 parent b6e153a commit f30735f

File tree

2 files changed

+75
-12
lines changed

2 files changed

+75
-12
lines changed

src/util/compareNumInFilename.go

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,7 @@ func compareIgnoreAsciiCase(prev, next []byte) (less, ok bool) {
7171
return
7272
}
7373

74-
func CompareNumInFilename(prev, next []byte) (less, ok bool) {
75-
if len(prev) == 0 && len(next) == 0 {
76-
return false, false
77-
} else if len(prev) == 0 {
78-
return true, true
79-
} else if len(next) == 0 {
80-
return false, true
81-
}
82-
74+
func compareNumString(prev, next []byte) (less, ok bool) {
8375
common := findCommonPrefix(prev, next)
8476
if common > 0 {
8577
prev = prev[common:]
@@ -101,7 +93,8 @@ func CompareNumInFilename(prev, next []byte) (less, ok bool) {
10193
return prevDigitsLen < nextDigitsLen, true
10294
}
10395

104-
if prevDigitsLen == 0 { // prevDigitsLen and nextDigitsLen is 0
96+
if prevDigitsLen == 0 { // prevDigitsLen == nextDigitsLen == 0
97+
// "." is the beginning of next part, so current part is ended
10598
switch {
10699
case prev[0] == '.' && next[0] != '.':
107100
return true, true
@@ -112,10 +105,59 @@ func CompareNumInFilename(prev, next []byte) (less, ok bool) {
112105
}
113106
}
114107

108+
// prevDigitsLen == nextDigitsLen
115109
compareResult := bytes.Compare(prevDigits, nextDigits)
116110
if compareResult != 0 {
117111
return compareResult < 0, true
118-
} else {
119-
return CompareNumInFilename(prev[prevDigitsLen:], next[nextDigitsLen:])
120112
}
113+
114+
// prevDigits == nextDigits
115+
prev = prev[prevDigitsLen:]
116+
next = next[nextDigitsLen:]
117+
if len(prev) == 0 && len(next) == 0 {
118+
return false, false
119+
} else if len(prev) == 0 {
120+
return true, true
121+
} else if len(next) == 0 {
122+
return false, true
123+
}
124+
return compareNumString(prev, next)
125+
126+
}
127+
128+
func isAlnum(b byte) bool {
129+
return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || (b >= '0' && b <= '9')
130+
}
131+
132+
func isDigit(b byte) bool {
133+
return b >= '0' && b <= '9'
134+
}
135+
136+
func isAlpha(b byte) bool {
137+
return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z')
138+
}
139+
140+
func CompareNumInFilename(prev, next []byte) (less, ok bool) {
141+
if len(prev) == 0 && len(next) == 0 {
142+
return false, false
143+
} else if len(prev) == 0 {
144+
return true, true
145+
} else if len(next) == 0 {
146+
return false, true
147+
}
148+
149+
// at very first beginning
150+
// filename starts with "." is prior, then digits, then letters
151+
switch {
152+
case prev[0] == '.' && isAlnum(next[0]):
153+
return true, true
154+
case next[0] == '.' && isAlnum(prev[0]):
155+
return false, true
156+
case isDigit(prev[0]) && isAlpha(next[0]):
157+
return true, true
158+
case isDigit(next[0]) && isAlpha(prev[0]):
159+
return false, true
160+
}
161+
162+
return compareNumString(prev, next)
121163
}

src/util/compareNumInFilename_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,27 @@ func TestCompareNumInFilename(t *testing.T) {
6161
if !less {
6262
t.Error(prev, next)
6363
}
64+
65+
prev = ".gitignore"
66+
next = "a.txt"
67+
less, _ = CompareNumInFilename([]byte(prev), []byte(next))
68+
if !less {
69+
t.Error(prev, next)
70+
}
71+
72+
prev = ".gitignore"
73+
next = "1.txt"
74+
less, _ = CompareNumInFilename([]byte(prev), []byte(next))
75+
if !less {
76+
t.Error(prev, next)
77+
}
78+
79+
prev = "1.txt"
80+
next = "a.txt"
81+
less, _ = CompareNumInFilename([]byte(prev), []byte(next))
82+
if !less {
83+
t.Error(prev, next)
84+
}
6485
}
6586

6687
func TestExtractPrefixDigits(t *testing.T) {

0 commit comments

Comments
 (0)