mirror of
https://github.com/Llewellynvdm/fzf.git
synced 2025-01-11 10:38:12 +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
|
@rxflag = argv.delete('+i') ? 0 : Regexp::IGNORECASE
|
||||||
@sort = %w[+s --no-sort].map { |e| argv.delete e }.compact.empty? ?
|
@sort = %w[+s --no-sort].map { |e| argv.delete e }.compact.empty? ?
|
||||||
ENV.fetch('FZF_DEFAULT_SORT', 500).to_i : nil
|
ENV.fetch('FZF_DEFAULT_SORT', 500).to_i : nil
|
||||||
@color = %w[+c --no-color].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?
|
@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 ' '
|
rest = argv.join ' '
|
||||||
if sort = rest.match(/(-s|--sort=?) ?([0-9]+)/)
|
if sort = rest.match(/(-s|--sort=?) ?([0-9]+)/)
|
||||||
usage 1 unless @sort
|
usage 1 unless @sort
|
||||||
@ -109,6 +110,7 @@ class FZF
|
|||||||
$stderr.puts %[usage: fzf [options]
|
$stderr.puts %[usage: fzf [options]
|
||||||
|
|
||||||
-m, --multi Enable multi-select
|
-m, --multi Enable multi-select
|
||||||
|
-x, --extended Extended mode
|
||||||
-s, --sort=MAX Maximum number of matched items to sort. Default: 500.
|
-s, --sort=MAX Maximum number of matched items to sort. Default: 500.
|
||||||
+s, --no-sort Do not sort the result. Keep the sequence unchanged.
|
+s, --no-sort Do not sort the result. Keep the sequence unchanged.
|
||||||
+i Case-sensitive match
|
+i Case-sensitive match
|
||||||
@ -451,7 +453,7 @@ class FZF
|
|||||||
|
|
||||||
def start_search
|
def start_search
|
||||||
main = Thread.current
|
main = Thread.current
|
||||||
matcher = FuzzyMatcher.new @rxflag
|
matcher = (@xmode ? XFuzzyMatcher : FuzzyMatcher).new @rxflag
|
||||||
searcher = Thread.new {
|
searcher = Thread.new {
|
||||||
lists = []
|
lists = []
|
||||||
events = {}
|
events = {}
|
||||||
@ -599,7 +601,7 @@ class FZF
|
|||||||
end
|
end
|
||||||
} if @multi
|
} if @multi
|
||||||
},
|
},
|
||||||
:left => proc { cursor = [0, cursor - 1].max },
|
:left => proc { cursor = [0, cursor - 1].max },
|
||||||
:right => proc { cursor = [input.length, cursor + 1].min },
|
:right => proc { cursor = [input.length, cursor + 1].min },
|
||||||
}
|
}
|
||||||
actions[ctrl(:b)] = actions[:left]
|
actions[ctrl(:b)] = actions[:left]
|
||||||
@ -657,7 +659,7 @@ class FZF
|
|||||||
end
|
end
|
||||||
|
|
||||||
class FuzzyMatcher < Matcher
|
class FuzzyMatcher < Matcher
|
||||||
attr_reader :cache
|
attr_reader :cache, :rxflag
|
||||||
|
|
||||||
def initialize rxflag
|
def initialize rxflag
|
||||||
@cache = Hash.new { |h, k| h[k] = {} }
|
@cache = Hash.new { |h, k| h[k] = {} }
|
||||||
@ -665,17 +667,20 @@ class FZF
|
|||||||
@rxflag = rxflag
|
@rxflag = rxflag
|
||||||
end
|
end
|
||||||
|
|
||||||
def match list, q, prefix, suffix
|
def fuzzy_regex q
|
||||||
regexp = @regexp[q] ||= begin
|
@regexp[q] ||= begin
|
||||||
q = q.downcase if @rxflag != 0
|
q = q.downcase if @rxflag != 0
|
||||||
Regexp.new(convert_query(q).inject('') { |sum, e|
|
Regexp.new(convert_query(q).inject('') { |sum, e|
|
||||||
e = Regexp.escape e
|
e = Regexp.escape e
|
||||||
sum << "#{e}[^#{e}]*?"
|
sum << "#{e}[^#{e}]*?"
|
||||||
}, @rxflag)
|
}, @rxflag)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def match list, q, prefix, suffix
|
||||||
|
regexp = fuzzy_regex q
|
||||||
|
|
||||||
cache = @cache[list.object_id]
|
cache = @cache[list.object_id]
|
||||||
|
|
||||||
prefix_cache = nil
|
prefix_cache = nil
|
||||||
(prefix.length - 1).downto(1) do |len|
|
(prefix.length - 1).downto(1) do |len|
|
||||||
break if prefix_cache = cache[prefix[0, len]]
|
break if prefix_cache = cache[prefix[0, len]]
|
||||||
@ -696,6 +701,42 @@ class FZF
|
|||||||
}.compact
|
}.compact
|
||||||
end
|
end
|
||||||
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
|
end#FZF
|
||||||
|
|
||||||
FZF.new(ARGV, $stdin).start if $0 == __FILE__
|
FZF.new(ARGV, $stdin).start if $0 == __FILE__
|
||||||
|
Loading…
Reference in New Issue
Block a user