summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJunegunn Choi <junegunn.c@gmail.com>2014-02-02 01:45:44 +0900
committerJunegunn Choi <junegunn.c@gmail.com>2014-02-02 01:45:44 +0900
commit301290663d69dd451d18237c98f6bb7ed19d1834 (patch)
treec98f95f29af563df86fd5d8c29e431f28f764225
parent1155da7e1cf0e5c87bb36231c25dd1cd031d9de6 (diff)
Add -f (--filter) option (#15)
This commit adds --filter option so that fzf can be used as a simple unix filter instead of being an interactive fuzzy finder.
-rw-r--r--README.md1
-rwxr-xr-xfzf74
-rw-r--r--test/test_fzf.rb18
3 files changed, 62 insertions, 31 deletions
diff --git a/README.md b/README.md
index 61e83fe0..89b8f31c 100644
--- a/README.md
+++ b/README.md
@@ -55,6 +55,7 @@ usage: fzf [options]
-m, --multi Enable multi-select
-x, --extended Extended-search mode
-q, --query=STR Initial query
+ -f, --filter=STR Filter mode. Do not start interactive finder.
-s, --sort=MAX Maximum number of matched items to sort (default: 1000)
+s, --no-sort Do not sort the result. Keep the sequence unchanged.
-i Case-insensitive match (default: smart-case match)
diff --git a/fzf b/fzf
index 37773692..d29f0b35 100755
--- a/fzf
+++ b/fzf
@@ -7,7 +7,7 @@
# / __/ / /_/ __/
# /_/ /___/_/ Fuzzy finder for your shell
#
-# Version: 0.7.2-devel (February 1, 2014)
+# Version: 0.7.2 (February 2, 2014)
#
# Author: Junegunn Choi
# URL: https://github.com/junegunn/fzf
@@ -50,7 +50,7 @@ end
class FZF
C = Curses
- attr_reader :rxflag, :sort, :color, :mouse, :multi, :query, :extended
+ attr_reader :rxflag, :sort, :color, :mouse, :multi, :query, :filter, :extended
class AtomicVar
def initialize value
@@ -63,10 +63,8 @@ class FZF
end
def set value = nil
- if block_given?
- @mutex.synchronize { @value = yield @value }
- else
- @mutex.synchronize { @value = value }
+ @mutex.synchronize do
+ @value = block_given? ? yield(@value) : value
end
end
@@ -82,6 +80,7 @@ class FZF
@multi = false
@extended = false
@mouse = true
+ @filter = nil
argv =
if opts = ENV['FZF_DEFAULT_OPTS']
@@ -109,6 +108,11 @@ class FZF
@query = AtomicVar.new query.dup
when /^-q(.*)$/, /^--query=(.*)$/
@query = AtomicVar.new($1)
+ when '-f', '--filter'
+ usage 1, 'query string required' unless query = argv.shift
+ @filter = query
+ when /^-f(.*)$/, /^--filter=(.*)$/
+ @filter = $1
when '-s', '--sort'
usage 1, 'sort size required' unless sort = argv.shift
usage 1, 'invalid sort size' unless sort =~ /^[0-9]+$/
@@ -126,27 +130,44 @@ class FZF
@events = {}
@new = []
@queue = Queue.new
- @query ||= AtomicVar.new('')
- @cursor_x = AtomicVar.new(@query.length)
- @matches = AtomicVar.new([])
- @count = AtomicVar.new(0)
- @vcursor = AtomicVar.new(0)
- @vcursors = AtomicVar.new(Set.new)
- @spinner = AtomicVar.new('-\|/-\|/'.split(//))
- @selects = AtomicVar.new({}) # ordered >= 1.9
- @main = Thread.current
- @stdout = $stdout.clone
- @plcount = 0
+
+ unless @filter
+ @query ||= AtomicVar.new('')
+ @cursor_x = AtomicVar.new(@query.length)
+ @matches = AtomicVar.new([])
+ @count = AtomicVar.new(0)
+ @vcursor = AtomicVar.new(0)
+ @vcursors = AtomicVar.new(Set.new)
+ @spinner = AtomicVar.new('-\|/-\|/'.split(//))
+ @selects = AtomicVar.new({}) # ordered >= 1.9
+ @main = Thread.current
+ @plcount = 0
+ end
end
def start
- $stdout.reopen($stderr)
+ if @filter
+ start_reader(false).join
+ filter_list @new
+ else
+ @stdout = $stdout.clone
+ $stdout.reopen($stderr)
- init_screen
- start_reader
- start_renderer
- start_search
- start_loop
+ start_reader true
+ init_screen
+ start_renderer
+ start_search
+ start_loop
+ end
+ end
+
+ def filter_list list
+ matcher = (@extended ? ExtendedFuzzyMatcher : FuzzyMatcher).new @rxflag
+ matches = matcher.match(list, @filter, '', '')
+ if @sort && matches.length <= @sort
+ matches = sort_by_rank(matches)
+ end
+ matches.each { |m| puts m.first }
end
def version
@@ -168,6 +189,7 @@ class FZF
-m, --multi Enable multi-select
-x, --extended Extended-search mode
-q, --query=STR Initial query
+ -f, --filter=STR Filter mode. Do not start interactive finder.
-s, --sort=MAX Maximum number of matched items to sort (default: 1000)
+s, --no-sort Do not sort the result. Keep the sequence unchanged.
-i Case-insensitive match (default: smart-case match)
@@ -535,7 +557,7 @@ class FZF
C.refresh
end
- def start_reader
+ def start_reader curses
stream =
if @source.tty?
if default_command = ENV['FZF_DEFAULT_COMMAND']
@@ -546,7 +568,7 @@ class FZF
exit 1
end
else
- $stdin.reopen IO.open(IO.sysopen('/dev/tty'), 'r')
+ $stdin.reopen IO.open(IO.sysopen('/dev/tty'), 'r') if curses
@source
end
@@ -555,7 +577,7 @@ class FZF
emit(:new) { @new << line.chomp }
end
emit(:loaded) { true }
- @spinner.clear
+ @spinner.clear if curses
end
end
diff --git a/test/test_fzf.rb b/test/test_fzf.rb
index 3f61f0f1..4be0846f 100644
--- a/test/test_fzf.rb
+++ b/test/test_fzf.rb
@@ -29,11 +29,13 @@ class TestFZF < MiniTest::Unit::TestCase
fzf = FZF.new []
assert_equal 20000, fzf.sort
- ENV['FZF_DEFAULT_OPTS'] = '-x -m -s 10000 -q " hello world " +c --no-mouse'
+ ENV['FZF_DEFAULT_OPTS'] = '-x -m -s 10000 -q " hello world " +c --no-mouse -f "goodbye world"'
fzf = FZF.new []
assert_equal 10000, fzf.sort
assert_equal ' hello world ',
fzf.query.get
+ assert_equal 'goodbye world',
+ fzf.filter
assert_equal true, fzf.extended
assert_equal true, fzf.multi
assert_equal false, fzf.color
@@ -42,42 +44,48 @@ class TestFZF < MiniTest::Unit::TestCase
def test_option_parser
# Long opts
- fzf = FZF.new %w[--sort=2000 --no-color --multi +i --query hello --extended --no-mouse]
+ fzf = FZF.new %w[--sort=2000 --no-color --multi +i --query hello
+ --filter=howdy --extended --no-mouse]
assert_equal 2000, fzf.sort
assert_equal true, fzf.multi
assert_equal false, fzf.color
assert_equal false, fzf.mouse
assert_equal 0, fzf.rxflag
assert_equal 'hello', fzf.query.get
+ assert_equal 'howdy', fzf.filter
assert_equal true, fzf.extended
fzf = FZF.new %w[--sort=2000 --no-color --multi +i --query hello
+ --filter a --filter b
--no-sort -i --color --no-multi]
assert_equal nil, fzf.sort
assert_equal false, fzf.multi
assert_equal true, fzf.color
assert_equal true, fzf.mouse
assert_equal 1, fzf.rxflag
+ assert_equal 'b', fzf.filter
assert_equal 'hello', fzf.query.get
assert_equal false, fzf.extended
# Short opts
- fzf = FZF.new %w[-s 2000 +c -m +i -qhello -x]
+ fzf = FZF.new %w[-s 2000 +c -m +i -qhello -x -fhowdy]
assert_equal 2000, fzf.sort
assert_equal true, fzf.multi
assert_equal false, fzf.color
assert_equal 0, fzf.rxflag
assert_equal 'hello', fzf.query.get
+ assert_equal 'howdy', fzf.filter
assert_equal true, fzf.extended
# Left-to-right
- fzf = FZF.new %w[-s 2000 +c -m +i -qhello -x
- -s 3000 -c +m -i -q world +x]
+ fzf = FZF.new %w[-s 2000 +c -m +i -qhello -x -fgoodbye
+ -s 3000 -c +m -i -q world +x -fworld]
assert_equal 3000, fzf.sort
assert_equal false, fzf.multi
assert_equal true, fzf.color
assert_equal 1, fzf.rxflag
assert_equal 'world', fzf.query.get
+ assert_equal 'world', fzf.filter
assert_equal false, fzf.extended
fzf = FZF.new %w[--query hello +s -s 2000 --query=world]