Better handling of NFD chars

This commit is contained in:
Junegunn Choi 2013-11-17 12:32:38 +09:00
parent 84921df0e3
commit 423e26b0c9
3 changed files with 30 additions and 25 deletions

37
fzf
View File

@ -137,21 +137,21 @@ class FZF
NFC_END = NFC_BEGIN + CHOSUNGS * JUNGSUNGS * JONGSUNGS NFC_END = NFC_BEGIN + CHOSUNGS * JUNGSUNGS * JONGSUNGS
def self.nfd str def self.nfd str
ret = '' str.split(//).map do |c|
str.split(//).each do |c|
cp = c.ord cp = c.ord
if cp >= NFC_BEGIN && cp < NFC_END if cp >= NFC_BEGIN && cp < NFC_END
chr = ''
idx = cp - NFC_BEGIN idx = cp - NFC_BEGIN
cho = CHOSUNG + idx / JJCOUNT cho = CHOSUNG + idx / JJCOUNT
jung = JUNGSUNG + (idx % JJCOUNT) / JONGSUNGS jung = JUNGSUNG + (idx % JJCOUNT) / JONGSUNGS
jong = JONGSUNG + idx % JONGSUNGS jong = JONGSUNG + idx % JONGSUNGS
ret << cho << jung chr << cho << jung
ret << jong if jong != JONGSUNG chr << jong if jong != JONGSUNG
chr
else else
ret << c c
end end
end end
ret
end end
def self.to_nfc arr def self.to_nfc arr
@ -215,16 +215,14 @@ class FZF
class Matcher class Matcher
def query_chars q def query_chars q
UConv.nfd(q).split(//) UConv.nfd(q)
end
def sanitize q
UConv.nfd(q).join
end end
end end
else else
module UConv
def self.nfd str
str
end
end
def convert_item item def convert_item item
item item
end end
@ -233,6 +231,10 @@ class FZF
def query_chars q def query_chars q
q.split(//) q.split(//)
end end
def sanitize q
q
end
end end
end end
@ -755,7 +757,8 @@ class FZF
q = q.downcase if @rxflag != 0 q = q.downcase if @rxflag != 0
Regexp.new(query_chars(q).inject('') { |sum, e| Regexp.new(query_chars(q).inject('') { |sum, e|
e = Regexp.escape e e = Regexp.escape e
sum << "#{e}[^#{e}]*?" sum << (e.length > 1 ? "(?:#{e}).*?" : # FIXME: not equivalent
"#{e}[^#{e}]*?")
}, @rxflag) }, @rxflag)
end end
end end
@ -810,13 +813,13 @@ class FZF
nil nil
when /^'/ when /^'/
w.length > 1 ? w.length > 1 ?
Regexp.new(UConv.nfd(Regexp.escape(w[1..-1])), rxflag) : nil Regexp.new(sanitize(Regexp.escape(w[1..-1])), rxflag) : nil
when /^\^/ when /^\^/
w.length > 1 ? w.length > 1 ?
Regexp.new('^' << UConv.nfd(Regexp.escape(w[1..-1])), rxflag) : nil Regexp.new('^' << sanitize(Regexp.escape(w[1..-1])), rxflag) : nil
when /\$$/ when /\$$/
w.length > 1 ? w.length > 1 ?
Regexp.new(UConv.nfd(Regexp.escape(w[0..-2])) << '$', rxflag) : nil Regexp.new(sanitize(Regexp.escape(w[0..-2])) << '$', rxflag) : nil
else else
fuzzy_regex w fuzzy_regex w
end, invert ] end, invert ]

View File

@ -1,7 +1,7 @@
# coding: utf-8 # coding: utf-8
Gem::Specification.new do |spec| Gem::Specification.new do |spec|
spec.name = 'fzf' spec.name = 'fzf'
spec.version = '0.4.1' spec.version = '0.4.2'
spec.authors = ['Junegunn Choi'] spec.authors = ['Junegunn Choi']
spec.email = ['junegunn.c@gmail.com'] spec.email = ['junegunn.c@gmail.com']
spec.description = %q{Fuzzy finder for your shell} spec.description = %q{Fuzzy finder for your shell}

View File

@ -293,20 +293,22 @@ class TestFZF < MiniTest::Unit::TestCase
def test_nfd def test_nfd
nfc = '한글' nfc = '한글'
nfd = FZF::UConv.nfd(nfc) nfd = FZF::UConv.nfd(nfc)
assert_equal 6, nfd.length assert_equal 2, nfd.length
assert_equal NFD, nfd assert_equal 6, nfd.join.length
assert_equal NFD, nfd.join
end end
def test_nfd_fuzzy_matcher def test_nfd_fuzzy_matcher
matcher = FZF::FuzzyMatcher.new 0 matcher = FZF::FuzzyMatcher.new 0
match = matcher.match([NFD], '할', '', '') assert_equal [], matcher.match([NFD + NFD], '할', '', '')
assert_equal [[NFD, [[0, 6]]]], match match = matcher.match([NFD + NFD], '글글', '', '')
assert_equal ['한글', [[0, 2]]], FZF::UConv.nfc(*match.first) assert_equal [[NFD + NFD, [[3, 12]]]], match
assert_equal ['한글한글', [[1, 4]]], FZF::UConv.nfc(*match.first)
end end
def test_nfd_extended_fuzzy_matcher def test_nfd_extended_fuzzy_matcher
matcher = FZF::ExtendedFuzzyMatcher.new 0 matcher = FZF::ExtendedFuzzyMatcher.new 0
assert_equal [], matcher.match([NFD], "'", '', '') assert_equal [], matcher.match([NFD], "'글글", '', '')
match = matcher.match([NFD], "'한글", '', '') match = matcher.match([NFD], "'한글", '', '')
assert_equal [[NFD, [[0, 6]]]], match assert_equal [[NFD, [[0, 6]]]], match
assert_equal ['한글', [[0, 2]]], FZF::UConv.nfc(*match.first) assert_equal ['한글', [[0, 2]]], FZF::UConv.nfc(*match.first)