Merge pull request #71 from junegunn/issue-70

Add options: --prompt and --print-query
This commit is contained in:
Junegunn Choi 2014-07-01 01:23:07 +09:00
commit 91401514ab
3 changed files with 68 additions and 51 deletions

View File

@ -81,12 +81,14 @@ usage: fzf [options]
+2, --no-256 Disable 256-color +2, --no-256 Disable 256-color
--black Use black background --black Use black background
--reverse Reverse orientation --reverse Reverse orientation
--prompt=STR Input prompt (default: '> ')
Scripting Scripting
-q, --query=STR Start the finder with the given query -q, --query=STR Start the finder with the given query
-1, --select-1 Automatically select the only match -1, --select-1 Automatically select the only match
-0, --exit-0 Exit immediately when there's no match -0, --exit-0 Exit immediately when there's no match
-f, --filter=STR Filter mode. Do not start interactive finder. -f, --filter=STR Filter mode. Do not start interactive finder.
--print-query Print query as the first line
Environment variables Environment variables
FZF_DEFAULT_COMMAND Default command to use when input is tty FZF_DEFAULT_COMMAND Default command to use when input is tty

32
fzf
View File

@ -7,7 +7,7 @@
# / __/ / /_/ __/ # / __/ / /_/ __/
# /_/ /___/_/ Fuzzy finder for your shell # /_/ /___/_/ Fuzzy finder for your shell
# #
# Version: 0.8.6 (Jun 27, 2014) # Version: 0.8.6 (Jun 30, 2014)
# #
# Author: Junegunn Choi # Author: Junegunn Choi
# URL: https://github.com/junegunn/fzf # URL: https://github.com/junegunn/fzf
@ -50,8 +50,9 @@ end
class FZF class FZF
C = Curses C = Curses
attr_reader :rxflag, :sort, :nth, :color, :black, :ansi256, :reverse, attr_reader :rxflag, :sort, :nth, :color, :black, :ansi256, :reverse, :prompt,
:mouse, :multi, :query, :select1, :exit0, :filter, :extended :mouse, :multi, :query, :select1, :exit0, :filter, :extended,
:print_query
def sync def sync
@shr_mtx.synchronize { yield } @shr_mtx.synchronize { yield }
@ -91,7 +92,9 @@ class FZF
@nth = nil @nth = nil
@delim = nil @delim = nil
@reverse = false @reverse = false
@prompt = '> '
@shr_mtx = Mutex.new @shr_mtx = Mutex.new
@print_query = false
argv = argv =
if opts = ENV['FZF_DEFAULT_OPTS'] if opts = ENV['FZF_DEFAULT_OPTS']
@ -127,7 +130,7 @@ class FZF
when '+0', '--no-exit-0' then @exit0 = false when '+0', '--no-exit-0' then @exit0 = false
when '-q', '--query' when '-q', '--query'
usage 1, 'query string required' unless query = argv.shift usage 1, 'query string required' unless query = argv.shift
@query = query.dup @query = query
when /^-q(.*)$/, /^--query=(.*)$/ when /^-q(.*)$/, /^--query=(.*)$/
@query = $1 @query = $1
when '-f', '--filter' when '-f', '--filter'
@ -151,6 +154,13 @@ class FZF
@sort = sort.to_i @sort = sort.to_i
when /^-s([0-9]+)$/, /^--sort=([0-9]+)$/ when /^-s([0-9]+)$/, /^--sort=([0-9]+)$/
@sort = $1.to_i @sort = $1.to_i
when '--prompt'
usage 1, 'prompt string required' unless prompt = argv.shift
@prompt = prompt
when /^--prompt=(.*)$/
@prompt = $1
when '--print-query' then @print_query = true
when '--no-print-query' then @print_query = false
when '-e', '--extended-exact' then @extended = :exact when '-e', '--extended-exact' then @extended = :exact
when '+e', '--no-extended-exact' then @extended = nil when '+e', '--no-extended-exact' then @extended = nil
else else
@ -220,9 +230,11 @@ class FZF
len = empty ? get(:@count) : matches.length len = empty ? get(:@count) : matches.length
if loaded if loaded
if @select1 && len == 1 if @select1 && len == 1
puts @query if @print_query
puts empty ? matches.first : matches.first.first puts empty ? matches.first : matches.first.first
exit 0 exit 0
elsif @exit0 && len == 0 elsif @exit0 && len == 0
puts @query if @print_query
exit 0 exit 0
end end
end end
@ -243,6 +255,7 @@ class FZF
end end
def filter_list list def filter_list list
puts @filter if @print_query
matches = matcher.match(list, @filter, '', '') matches = matcher.match(list, @filter, '', '')
if @sort && matches.length <= @sort if @sort && matches.length <= @sort
matches = FZF.sort(matches) matches = FZF.sort(matches)
@ -314,12 +327,14 @@ class FZF
+2, --no-256 Disable 256-color +2, --no-256 Disable 256-color
--black Use black background --black Use black background
--reverse Reverse orientation --reverse Reverse orientation
--prompt=STR Input prompt (default: '> ')
Scripting Scripting
-q, --query=STR Start the finder with the given query -q, --query=STR Start the finder with the given query
-1, --select-1 Automatically select the only match -1, --select-1 Automatically select the only match
-0, --exit-0 Exit immediately when there's no match -0, --exit-0 Exit immediately when there's no match
-f, --filter=STR Filter mode. Do not start interactive finder. -f, --filter=STR Filter mode. Do not start interactive finder.
--print-query Print query as the first line
Environment variables Environment variables
FZF_DEFAULT_COMMAND Default command to use when input is tty FZF_DEFAULT_COMMAND Default command to use when input is tty
@ -352,7 +367,7 @@ class FZF
def print_input def print_input
C.setpos cursor_y, 0 C.setpos cursor_y, 0
C.clrtoeol C.clrtoeol
cprint '> ', color(:prompt, true) cprint @prompt, color(:prompt, true)
C.attron(C::A_BOLD) do C.attron(C::A_BOLD) do
C.addstr get(:@query) C.addstr get(:@query)
end end
@ -382,7 +397,7 @@ class FZF
def refresh def refresh
query, xcur = geta(:@query, :@xcur) query, xcur = geta(:@query, :@xcur)
C.setpos cursor_y, 2 + width(query[0, xcur]) C.setpos cursor_y, @prompt.length + width(query[0, xcur])
C.refresh C.refresh
end end
@ -1004,7 +1019,7 @@ class FZF
x, y, shift = val.values_at :x, :y, :shift x, y, shift = val.values_at :x, :y, :shift
y = @reverse ? (C.lines - 1 - y) : y y = @reverse ? (C.lines - 1 - y) : y
if y == C.lines - 1 if y == C.lines - 1
cursor = [0, [input.length, x - 2].min].max cursor = [0, [input.length, x - @prompt.length].min].max
elsif x > 1 && y <= max_items elsif x > 1 && y <= max_items
tv = get(:@yoff) + max_items - y - 1 tv = get(:@yoff) + max_items - y - 1
@ -1047,8 +1062,9 @@ class FZF
end end
ensure ensure
C.close_screen C.close_screen
q, selects = geta(:@query, :@selects)
@stdout.puts q if @print_query
if got if got
selects = call(:@selects, :dup)
if selects.empty? if selects.empty?
@stdout.puts got @stdout.puts got
else else

View File

@ -33,6 +33,8 @@ class TestFZF < MiniTest::Unit::TestCase
assert_equal nil, fzf.filter assert_equal nil, fzf.filter
assert_equal nil, fzf.extended assert_equal nil, fzf.extended
assert_equal false, fzf.reverse assert_equal false, fzf.reverse
assert_equal '> ', fzf.prompt
assert_equal false, fzf.print_query
end end
def test_environment_variables def test_environment_variables
@ -43,8 +45,8 @@ class TestFZF < MiniTest::Unit::TestCase
assert_equal nil, fzf.nth assert_equal nil, fzf.nth
ENV['FZF_DEFAULT_OPTS'] = ENV['FZF_DEFAULT_OPTS'] =
'-x -m -s 10000 -q " hello world " +c +2 --select-1 -0 ' + '-x -m -s 10000 -q " hello world " +c +2 --select-1 -0 ' <<
'--no-mouse -f "goodbye world" --black --nth=3,-1,2 --reverse' '--no-mouse -f "goodbye world" --black --nth=3,-1,2 --reverse --print-query'
fzf = FZF.new [] fzf = FZF.new []
assert_equal 10000, fzf.sort assert_equal 10000, fzf.sort
assert_equal ' hello world ', assert_equal ' hello world ',
@ -60,6 +62,7 @@ class TestFZF < MiniTest::Unit::TestCase
assert_equal true, fzf.select1 assert_equal true, fzf.select1
assert_equal true, fzf.exit0 assert_equal true, fzf.exit0
assert_equal true, fzf.reverse assert_equal true, fzf.reverse
assert_equal true, fzf.print_query
assert_equal [2..2, -1..-1, 1..1], fzf.nth assert_equal [2..2, -1..-1, 1..1], fzf.nth
end end
@ -67,7 +70,8 @@ class TestFZF < MiniTest::Unit::TestCase
# Long opts # Long opts
fzf = FZF.new %w[--sort=2000 --no-color --multi +i --query hello --select-1 fzf = FZF.new %w[--sort=2000 --no-color --multi +i --query hello --select-1
--exit-0 --filter=howdy --extended-exact --exit-0 --filter=howdy --extended-exact
--no-mouse --no-256 --nth=1 --reverse] --no-mouse --no-256 --nth=1 --reverse --prompt (hi)
--print-query]
assert_equal 2000, fzf.sort assert_equal 2000, fzf.sort
assert_equal true, fzf.multi assert_equal true, fzf.multi
assert_equal false, fzf.color assert_equal false, fzf.color
@ -82,13 +86,16 @@ class TestFZF < MiniTest::Unit::TestCase
assert_equal :exact, fzf.extended assert_equal :exact, fzf.extended
assert_equal [0..0], fzf.nth assert_equal [0..0], fzf.nth
assert_equal true, fzf.reverse assert_equal true, fzf.reverse
assert_equal '(hi)', fzf.prompt
assert_equal true, fzf.print_query
# Long opts (left-to-right) # Long opts (left-to-right)
fzf = FZF.new %w[--sort=2000 --no-color --multi +i --query=hello fzf = FZF.new %w[--sort=2000 --no-color --multi +i --query=hello
--filter a --filter b --no-256 --black --nth -1 --nth -2 --filter a --filter b --no-256 --black --nth -1 --nth -2
--select-1 --exit-0 --no-select-1 --no-exit-0 --select-1 --exit-0 --no-select-1 --no-exit-0
--no-sort -i --color --no-multi --256 --no-sort -i --color --no-multi --256
--reverse --no-reverse] --reverse --no-reverse --prompt (hi) --prompt=(HI)
--print-query --no-print-query]
assert_equal nil, fzf.sort assert_equal nil, fzf.sort
assert_equal false, fzf.multi assert_equal false, fzf.multi
assert_equal true, fzf.color assert_equal true, fzf.color
@ -103,6 +110,8 @@ class TestFZF < MiniTest::Unit::TestCase
assert_equal nil, fzf.extended assert_equal nil, fzf.extended
assert_equal [-2..-2], fzf.nth assert_equal [-2..-2], fzf.nth
assert_equal false, fzf.reverse assert_equal false, fzf.reverse
assert_equal '(HI)', fzf.prompt
assert_equal false, fzf.print_query
# Short opts # Short opts
fzf = FZF.new %w[-s2000 +c -m +i -qhello -x -fhowdy +2 -n3 -1 -0] fzf = FZF.new %w[-s2000 +c -m +i -qhello -x -fhowdy +2 -n3 -1 -0]
@ -565,36 +574,43 @@ class TestFZF < MiniTest::Unit::TestCase
end end
end end
def test_select_1 def assert_fzf_output opts, given, expected
stream = stream_for "Hello\nWorld" stream = stream_for given
output = StringIO.new output = StringIO.new
begin begin
$stdout = output $stdout = output
FZF.new(%w[--query=ol --select-1], stream).start FZF.new(opts, stream).start
rescue SystemExit => e rescue SystemExit => e
assert_equal 0, e.status assert_equal 0, e.status
assert_equal 'World', output.string.chomp assert_equal expected, output.string.chomp
ensure ensure
$stdout = STDOUT $stdout = STDOUT
end end
end end
def test_select_1_without_query def test_filter
stream = stream_for "Hello World" {
output = StringIO.new %w[--filter=ol] => 'World',
%w[--filter=ol --print-query] => "ol\nWorld",
begin }.each do |opts, expected|
$stdout = output assert_fzf_output opts, "Hello\nWorld", expected
FZF.new(%w[--select-1], stream).start
rescue SystemExit => e
assert_equal 0, e.status
assert_equal 'Hello World', output.string.chomp
ensure
$stdout = STDOUT
end end
end end
def test_select_1
{
%w[--query=ol --select-1] => 'World',
%w[--query=ol --select-1 --print-query] => "ol\nWorld",
}.each do |opts, expected|
assert_fzf_output opts, "Hello\nWorld", expected
end
end
def test_select_1_without_query
assert_fzf_output %w[--select-1], 'Hello World', 'Hello World'
end
def test_select_1_ambiguity def test_select_1_ambiguity
stream = stream_for "Hello\nWorld" stream = stream_for "Hello\nWorld"
begin begin
@ -609,33 +625,16 @@ class TestFZF < MiniTest::Unit::TestCase
end end
def test_exit_0 def test_exit_0
stream = stream_for "Hello\nWorld" {
output = StringIO.new %w[--query=zz --exit-0] => '',
%w[--query=zz --exit-0 --print-query] => 'zz',
begin }.each do |opts, expected|
$stdout = output assert_fzf_output opts, "Hello\nWorld", expected
FZF.new(%w[--query=zz --exit-0], stream).start
rescue SystemExit => e
assert_equal 0, e.status
assert_equal '', output.string
ensure
$stdout = STDOUT
end end
end end
def test_exit_0_without_query def test_exit_0_without_query
stream = stream_for "" assert_fzf_output %w[--exit-0], '', ''
output = StringIO.new
begin
$stdout = output
FZF.new(%w[--exit-0], stream).start
rescue SystemExit => e
assert_equal 0, e.status
assert_equal '', output.string
ensure
$stdout = STDOUT
end
end end
def test_ranking_overlap_match_regions def test_ranking_overlap_match_regions