summaryrefslogtreecommitdiff
path: root/src/algo/algo.go
diff options
context:
space:
mode:
authorJunegunn Choi <junegunn.c@gmail.com>2015-04-14 21:45:37 +0900
committerJunegunn Choi <junegunn.c@gmail.com>2015-04-14 21:45:37 +0900
commit5c25984ea01677eb759501a5cff3fa63d2d460d8 (patch)
treef73b7dd481bcb277372e8ac6f11a7ddede995ad1 /src/algo/algo.go
parent319d6ced80712eedc818d6d9f9982be4860b2c01 (diff)
downloadfzf-5c25984ea01677eb759501a5cff3fa63d2d460d8.tar.gz
Fix Unicode case handling (#186)
Diffstat (limited to 'src/algo/algo.go')
-rw-r--r--src/algo/algo.go37
1 files changed, 25 insertions, 12 deletions
diff --git a/src/algo/algo.go b/src/algo/algo.go
index 60c436e5..36c8d873 100644
--- a/src/algo/algo.go
+++ b/src/algo/algo.go
@@ -1,6 +1,9 @@
package algo
-import "strings"
+import (
+ "strings"
+ "unicode"
+)
/*
* String matching algorithms here do not use strings.ToLower to avoid
@@ -34,8 +37,17 @@ func FuzzyMatch(caseSensitive bool, input *string, pattern []rune) (int, int) {
for index, char := range runes {
// This is considerably faster than blindly applying strings.ToLower to the
// whole string
- if !caseSensitive && char >= 65 && char <= 90 {
- char += 32
+ if !caseSensitive {
+ // Partially inlining `unicode.ToLower`. Ugly, but makes a noticeable
+ // difference in CPU cost. (Measured on Go 1.4.1. Also note that the Go
+ // compiler as of now does not inline non-leaf functions.)
+ if char >= 'A' && char <= 'Z' {
+ char += 32
+ runes[index] = char
+ } else if char > unicode.MaxASCII {
+ char = unicode.To(unicode.LowerCase, char)
+ runes[index] = char
+ }
}
if char == pattern[pidx] {
if sidx < 0 {
@@ -52,9 +64,6 @@ func FuzzyMatch(caseSensitive bool, input *string, pattern []rune) (int, int) {
pidx--
for index := eidx - 1; index >= sidx; index-- {
char := runes[index]
- if !caseSensitive && char >= 65 && char <= 90 {
- char += 32
- }
if char == pattern[pidx] {
if pidx--; pidx < 0 {
sidx = index
@@ -110,8 +119,12 @@ func ExactMatchNaive(caseSensitive bool, input *string, pattern []rune) (int, in
pidx := 0
for index := 0; index < numRunes; index++ {
char := runes[index]
- if !caseSensitive && char >= 65 && char <= 90 {
- char += 32
+ if !caseSensitive {
+ if char >= 'A' && char <= 'Z' {
+ char += 32
+ } else if char > unicode.MaxASCII {
+ char = unicode.To(unicode.LowerCase, char)
+ }
}
if pattern[pidx] == char {
pidx++
@@ -135,8 +148,8 @@ func PrefixMatch(caseSensitive bool, input *string, pattern []rune) (int, int) {
for index, r := range pattern {
char := runes[index]
- if !caseSensitive && char >= 65 && char <= 90 {
- char += 32
+ if !caseSensitive {
+ char = unicode.ToLower(char)
}
if char != r {
return -1, -1
@@ -156,8 +169,8 @@ func SuffixMatch(caseSensitive bool, input *string, pattern []rune) (int, int) {
for index, r := range pattern {
char := runes[index+diff]
- if !caseSensitive && char >= 65 && char <= 90 {
- char += 32
+ if !caseSensitive {
+ char = unicode.ToLower(char)
}
if char != r {
return -1, -1