|
|
@ -110,7 +110,7 @@ when /darwin/
|
|
|
|
ret
|
|
|
|
ret
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
def self.nfc str, b = 0, e = 0
|
|
|
|
def self.nfc str, offsets = []
|
|
|
|
ret = ''
|
|
|
|
ret = ''
|
|
|
|
omap = []
|
|
|
|
omap = []
|
|
|
|
pend = []
|
|
|
|
pend = []
|
|
|
@ -138,7 +138,10 @@ when /darwin/
|
|
|
|
ret << c
|
|
|
|
ret << c
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return [ret, omap[b] || 0, omap[e] || ((omap.last || 0) + 1)]
|
|
|
|
return [ret,
|
|
|
|
|
|
|
|
offsets.map { |pair|
|
|
|
|
|
|
|
|
b, e = pair
|
|
|
|
|
|
|
|
[omap[b] || 0, omap[e] || ((omap.last || 0) + 1)] }]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
@ -212,6 +215,69 @@ def ctrl char
|
|
|
|
char.to_s.ord - 'a'.ord + 1
|
|
|
|
char.to_s.ord - 'a'.ord + 1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def format line, limit, offsets
|
|
|
|
|
|
|
|
offsets ||= []
|
|
|
|
|
|
|
|
maxe = offsets.map { |e| e.last }.max || 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Overflow
|
|
|
|
|
|
|
|
if width(line) > limit
|
|
|
|
|
|
|
|
ewidth = width(line[0...maxe])
|
|
|
|
|
|
|
|
# Stri..
|
|
|
|
|
|
|
|
if ewidth <= limit - 2
|
|
|
|
|
|
|
|
line, _ = trim line, limit - 2, false
|
|
|
|
|
|
|
|
line << '..'
|
|
|
|
|
|
|
|
# ..ring
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
# ..ri..
|
|
|
|
|
|
|
|
line = line[0...maxe] + '..' if ewidth < width(line) - 2
|
|
|
|
|
|
|
|
line, diff = trim line, limit - 2, true
|
|
|
|
|
|
|
|
offsets = offsets.map { |pair|
|
|
|
|
|
|
|
|
b, e = pair
|
|
|
|
|
|
|
|
b += 2 - diff
|
|
|
|
|
|
|
|
e += 2 - diff
|
|
|
|
|
|
|
|
b = [2, b].max
|
|
|
|
|
|
|
|
[b, e]
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
line = '..' + line
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tokens = []
|
|
|
|
|
|
|
|
index = 0
|
|
|
|
|
|
|
|
offsets.select { |pair| pair.first < pair.last }.
|
|
|
|
|
|
|
|
sort_by { |pair| pair }.each do |pair|
|
|
|
|
|
|
|
|
b, e = pair.map { |x| [index, x].max }
|
|
|
|
|
|
|
|
tokens << [line[index...b], false]
|
|
|
|
|
|
|
|
tokens << [line[b...e], true]
|
|
|
|
|
|
|
|
index = e
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
tokens << [line[index..-1], false]
|
|
|
|
|
|
|
|
tokens.reject { |pair| pair.first.empty? }
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def print_item row, tokens, chosen, selected
|
|
|
|
|
|
|
|
# Cursor
|
|
|
|
|
|
|
|
C.setpos row, 0
|
|
|
|
|
|
|
|
C.clrtoeol
|
|
|
|
|
|
|
|
cprint chosen ? '>' : ' ', color(:red, true)
|
|
|
|
|
|
|
|
cprint selected ? '>' : ' ',
|
|
|
|
|
|
|
|
chosen ? color(:chosen) : (selected ? color(:red, true) : 0)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Highlighted item
|
|
|
|
|
|
|
|
C.attron color(:chosen, true) if chosen
|
|
|
|
|
|
|
|
tokens.each do |pair|
|
|
|
|
|
|
|
|
token, highlighted = pair
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if highlighted
|
|
|
|
|
|
|
|
cprint token, color(chosen ? :match! : :match, chosen)
|
|
|
|
|
|
|
|
C.attron color(:chosen, true) if chosen
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
C.addstr token
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
C.attroff color(:chosen, true) if chosen
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
if RUBY_VERSION.split('.').map { |e| e.rjust(3, '0') }.join > '001009'
|
|
|
|
if RUBY_VERSION.split('.').map { |e| e.rjust(3, '0') }.join > '001009'
|
|
|
|
@wrx = Regexp.new '\p{Han}|\p{Katakana}|\p{Hiragana}|\p{Hangul}'
|
|
|
|
@wrx = Regexp.new '\p{Han}|\p{Katakana}|\p{Hiragana}|\p{Hangul}'
|
|
|
|
def width str
|
|
|
|
def width str
|
|
|
@ -421,7 +487,7 @@ searcher = Thread.new {
|
|
|
|
(partial_cache ? partial_cache.map { |e| e.first } : list).map { |line|
|
|
|
|
(partial_cache ? partial_cache.map { |e| e.first } : list).map { |line|
|
|
|
|
# Ignore errors: e.g. invalid byte sequence in UTF-8
|
|
|
|
# Ignore errors: e.g. invalid byte sequence in UTF-8
|
|
|
|
md = line.match(regexp) rescue nil
|
|
|
|
md = line.match(regexp) rescue nil
|
|
|
|
md && [line, *md.offset(0)]
|
|
|
|
md && [line, [md.offset(0)]]
|
|
|
|
}.compact
|
|
|
|
}.compact
|
|
|
|
end)
|
|
|
|
end)
|
|
|
|
end
|
|
|
|
end
|
|
|
@ -431,9 +497,11 @@ searcher = Thread.new {
|
|
|
|
|
|
|
|
|
|
|
|
mcount = matches.length
|
|
|
|
mcount = matches.length
|
|
|
|
if @sort && mcount <= @sort && !q.empty?
|
|
|
|
if @sort && mcount <= @sort && !q.empty?
|
|
|
|
matches.replace matches.sort_by { |triple|
|
|
|
|
matches.replace matches.sort_by { |tuple|
|
|
|
|
line, b, e = triple
|
|
|
|
line, offsets = tuple
|
|
|
|
[b ? (e - b) : 0, line.length, line]
|
|
|
|
matchlen = offsets.map { |pair| pair.last }.max || 0 -
|
|
|
|
|
|
|
|
offsets.map { |pair| pair.first }.min || 0
|
|
|
|
|
|
|
|
[matchlen, line.length, line]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end#new_search
|
|
|
|
end#new_search
|
|
|
@ -462,50 +530,12 @@ searcher = Thread.new {
|
|
|
|
maxc = C.cols - 3
|
|
|
|
maxc = C.cols - 3
|
|
|
|
matches[0, max_items].each_with_index do |item, idx|
|
|
|
|
matches[0, max_items].each_with_index do |item, idx|
|
|
|
|
next if !new_search && !((vcursor-1)..(vcursor+1)).include?(idx)
|
|
|
|
next if !new_search && !((vcursor-1)..(vcursor+1)).include?(idx)
|
|
|
|
|
|
|
|
|
|
|
|
line, b, e = convert_item item
|
|
|
|
|
|
|
|
b ||= 0
|
|
|
|
|
|
|
|
e ||= 0
|
|
|
|
|
|
|
|
row = cursor_y - idx - 2
|
|
|
|
row = cursor_y - idx - 2
|
|
|
|
chosen = idx == vcursor
|
|
|
|
chosen = idx == vcursor
|
|
|
|
|
|
|
|
|
|
|
|
# Overflow
|
|
|
|
|
|
|
|
if width(line) > maxc
|
|
|
|
|
|
|
|
ewidth = width(line[0...e])
|
|
|
|
|
|
|
|
# Stri..
|
|
|
|
|
|
|
|
if ewidth <= maxc - 2
|
|
|
|
|
|
|
|
line, _ = trim line, maxc - 2, false
|
|
|
|
|
|
|
|
line << '..'
|
|
|
|
|
|
|
|
# ..ring
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
# ..ri..
|
|
|
|
|
|
|
|
line = line[0...e] + '..' if ewidth < width(line) - 2
|
|
|
|
|
|
|
|
line, diff = trim line, maxc - 2, true
|
|
|
|
|
|
|
|
b += 2 - diff
|
|
|
|
|
|
|
|
e += 2 - diff
|
|
|
|
|
|
|
|
b = [2, b].max
|
|
|
|
|
|
|
|
line = '..' + line
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
C.setpos row, 0
|
|
|
|
|
|
|
|
C.clrtoeol
|
|
|
|
|
|
|
|
cprint chosen ? '>' : ' ', color(:red, true)
|
|
|
|
|
|
|
|
selected = selects.include?([*item][0])
|
|
|
|
selected = selects.include?([*item][0])
|
|
|
|
cprint selected ? '>' : ' ',
|
|
|
|
line, offsets = convert_item item
|
|
|
|
chosen ? color(:chosen) : (selected ? color(:red, true) : 0)
|
|
|
|
tokens = format line, maxc, offsets
|
|
|
|
|
|
|
|
print_item row, tokens, chosen, selected
|
|
|
|
C.attron color(:chosen, true) if chosen
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if b < e
|
|
|
|
|
|
|
|
C.addstr line[0, b]
|
|
|
|
|
|
|
|
cprint line[b...e], color(chosen ? :match! : :match, chosen)
|
|
|
|
|
|
|
|
C.attron color(:chosen, true) if chosen
|
|
|
|
|
|
|
|
C.addstr line[e..-1] || ''
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
C.addstr line
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
C.attroff color(:chosen, true) if chosen
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
print_info selects.length if !@lists.empty? || events[:loaded]
|
|
|
|
print_info selects.length if !@lists.empty? || events[:loaded]
|
|
|
|