diff options
| author | Junegunn Choi <junegunn.c@gmail.com> | 2015-04-14 21:45:37 +0900 |
|---|---|---|
| committer | Junegunn Choi <junegunn.c@gmail.com> | 2015-04-14 21:45:37 +0900 |
| commit | 5c25984ea01677eb759501a5cff3fa63d2d460d8 (patch) | |
| tree | f73b7dd481bcb277372e8ac6f11a7ddede995ad1 /src/algo/algo.go | |
| parent | 319d6ced80712eedc818d6d9f9982be4860b2c01 (diff) | |
| download | fzf-5c25984ea01677eb759501a5cff3fa63d2d460d8.tar.gz | |
Fix Unicode case handling (#186)
Diffstat (limited to 'src/algo/algo.go')
| -rw-r--r-- | src/algo/algo.go | 37 |
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 |
