mirror of
https://github.com/Llewellynvdm/fzf.git
synced 2024-12-23 11:29:01 +00:00
Prototype implementation of extended mode (#1)
This commit is contained in:
parent
90ad6d50b8
commit
545e8bfcee
57
fzf
57
fzf
@ -70,8 +70,9 @@ class FZF
|
||||
@rxflag = argv.delete('+i') ? 0 : Regexp::IGNORECASE
|
||||
@sort = %w[+s --no-sort].map { |e| argv.delete e }.compact.empty? ?
|
||||
ENV.fetch('FZF_DEFAULT_SORT', 500).to_i : nil
|
||||
@color = %w[+c --no-color].map { |e| argv.delete e }.compact.empty?
|
||||
@multi = !%w[-m --multi].map { |e| argv.delete e }.compact.empty?
|
||||
@color = %w[+c --no-color].map { |e| argv.delete e }.compact.empty?
|
||||
@multi = !%w[-m --multi].map { |e| argv.delete e }.compact.empty?
|
||||
@xmode = !%w[-x --extended].map { |e| argv.delete e }.compact.empty?
|
||||
rest = argv.join ' '
|
||||
if sort = rest.match(/(-s|--sort=?) ?([0-9]+)/)
|
||||
usage 1 unless @sort
|
||||
@ -109,6 +110,7 @@ class FZF
|
||||
$stderr.puts %[usage: fzf [options]
|
||||
|
||||
-m, --multi Enable multi-select
|
||||
-x, --extended Extended mode
|
||||
-s, --sort=MAX Maximum number of matched items to sort. Default: 500.
|
||||
+s, --no-sort Do not sort the result. Keep the sequence unchanged.
|
||||
+i Case-sensitive match
|
||||
@ -451,7 +453,7 @@ class FZF
|
||||
|
||||
def start_search
|
||||
main = Thread.current
|
||||
matcher = FuzzyMatcher.new @rxflag
|
||||
matcher = (@xmode ? XFuzzyMatcher : FuzzyMatcher).new @rxflag
|
||||
searcher = Thread.new {
|
||||
lists = []
|
||||
events = {}
|
||||
@ -599,7 +601,7 @@ class FZF
|
||||
end
|
||||
} if @multi
|
||||
},
|
||||
:left => proc { cursor = [0, cursor - 1].max },
|
||||
:left => proc { cursor = [0, cursor - 1].max },
|
||||
:right => proc { cursor = [input.length, cursor + 1].min },
|
||||
}
|
||||
actions[ctrl(:b)] = actions[:left]
|
||||
@ -657,7 +659,7 @@ class FZF
|
||||
end
|
||||
|
||||
class FuzzyMatcher < Matcher
|
||||
attr_reader :cache
|
||||
attr_reader :cache, :rxflag
|
||||
|
||||
def initialize rxflag
|
||||
@cache = Hash.new { |h, k| h[k] = {} }
|
||||
@ -665,17 +667,20 @@ class FZF
|
||||
@rxflag = rxflag
|
||||
end
|
||||
|
||||
def match list, q, prefix, suffix
|
||||
regexp = @regexp[q] ||= begin
|
||||
def fuzzy_regex q
|
||||
@regexp[q] ||= begin
|
||||
q = q.downcase if @rxflag != 0
|
||||
Regexp.new(convert_query(q).inject('') { |sum, e|
|
||||
e = Regexp.escape e
|
||||
sum << "#{e}[^#{e}]*?"
|
||||
}, @rxflag)
|
||||
end
|
||||
end
|
||||
|
||||
def match list, q, prefix, suffix
|
||||
regexp = fuzzy_regex q
|
||||
|
||||
cache = @cache[list.object_id]
|
||||
|
||||
prefix_cache = nil
|
||||
(prefix.length - 1).downto(1) do |len|
|
||||
break if prefix_cache = cache[prefix[0, len]]
|
||||
@ -696,6 +701,42 @@ class FZF
|
||||
}.compact
|
||||
end
|
||||
end
|
||||
|
||||
class XFuzzyMatcher < FuzzyMatcher
|
||||
def match list, q, prefix, suffix
|
||||
regexps = q.strip.split(/\s+/).map { |w|
|
||||
invert =
|
||||
if w =~ /^!/
|
||||
w = w[1..-1]
|
||||
true
|
||||
end
|
||||
|
||||
[ case w
|
||||
when ''
|
||||
nil
|
||||
when /^\^/
|
||||
w.length > 1 ? Regexp.new('^' << w[1..-1], rxflag) : nil
|
||||
when /\$$/
|
||||
w.length > 1 ? Regexp.new(w[0..-2] << '$', rxflag) : nil
|
||||
else
|
||||
fuzzy_regex w
|
||||
end, invert ]
|
||||
}.select { |pair| pair.first }
|
||||
|
||||
list.map { |line|
|
||||
offsets = []
|
||||
regexps.all? { |pair|
|
||||
regexp, invert = pair
|
||||
md = line.match(regexp) rescue nil
|
||||
if md && !invert
|
||||
offsets << md.offset(0)
|
||||
elsif !md && invert
|
||||
true
|
||||
end
|
||||
} && [line, offsets]
|
||||
}.select { |e| e }
|
||||
end
|
||||
end
|
||||
end#FZF
|
||||
|
||||
FZF.new(ARGV, $stdin).start if $0 == __FILE__
|
||||
|
Loading…
Reference in New Issue
Block a user