2015-01-16 19:55:29 +00:00
#!/usr/bin/env ruby
# encoding: utf-8
2017-08-04 14:29:02 +00:00
# frozen_string_literal: true
# rubocop:disable Metrics/LineLength
# rubocop:disable Metrics/MethodLength
2015-01-16 19:55:29 +00:00
require 'minitest/autorun'
2015-02-28 18:00:36 +00:00
require 'fileutils'
2017-08-04 14:29:02 +00:00
require 'English'
require 'shellwords'
2020-02-28 06:38:39 +00:00
require 'erb'
require 'tempfile'
TEMPLATE = DATA . read
UNSETS = %w[
FZF_DEFAULT_COMMAND FZF_DEFAULT_OPTS
FZF_CTRL_T_COMMAND FZF_CTRL_T_OPTS
FZF_ALT_C_COMMAND
FZF_ALT_C_OPTS FZF_CTRL_R_OPTS
fish_history
] . freeze
2015-04-25 01:39:04 +00:00
DEFAULT_TIMEOUT = 20
2015-11-30 08:32:16 +00:00
FILE = File . expand_path ( __FILE__ )
2020-02-28 06:38:39 +00:00
BASE = File . expand_path ( '..' , __dir__ )
Dir . chdir ( BASE )
FZF = " FZF_DEFAULT_OPTS= FZF_DEFAULT_COMMAND= #{ BASE } /bin/fzf "
2015-03-28 12:37:37 +00:00
2015-01-17 03:37:24 +00:00
class NilClass
2017-08-04 14:29:02 +00:00
def include? ( _str )
2015-01-17 03:37:24 +00:00
false
end
2015-02-28 18:00:36 +00:00
2017-08-04 14:29:02 +00:00
def start_with? ( _str )
2015-02-28 18:00:36 +00:00
false
end
2017-08-04 14:29:02 +00:00
def end_with? ( _str )
2015-02-28 18:00:36 +00:00
false
end
2015-01-17 03:37:24 +00:00
end
2015-04-25 01:39:04 +00:00
def wait
since = Time . now
while Time . now - since < DEFAULT_TIMEOUT
return if yield
sleep 0 . 05
2015-01-24 04:25:11 +00:00
end
2016-04-23 19:52:01 +00:00
raise 'timeout'
2015-01-24 04:25:11 +00:00
end
2015-02-28 18:00:36 +00:00
class Shell
class << self
def bash
2020-02-28 06:38:39 +00:00
@bash || =
begin
bashrc = '/tmp/fzf.bash'
File . open ( bashrc , 'w' ) do | f |
f . puts ( ERB . new ( TEMPLATE ) . result ( binding ) )
end
" bash --rcfile #{ bashrc } "
end
2015-02-28 18:00:36 +00:00
end
def zsh
2020-02-28 06:38:39 +00:00
@zsh || =
begin
zdotdir = '/tmp/fzf-zsh'
FileUtils . rm_rf ( zdotdir )
FileUtils . mkdir_p ( zdotdir )
File . open ( " #{ zdotdir } /.zshrc " , 'w' ) do | f |
f . puts ( ERB . new ( TEMPLATE ) . result ( binding ) )
end
" ZDOTDIR= #{ zdotdir } zsh "
end
2015-02-28 18:00:36 +00:00
end
2016-08-13 10:26:36 +00:00
def fish
2020-02-28 06:38:39 +00:00
UNSETS . map { | v | v + '= ' } . join + 'fish'
2016-08-13 10:26:36 +00:00
end
2015-02-28 18:00:36 +00:00
end
end
2015-01-16 19:55:29 +00:00
class Tmux
attr_reader :win
2017-08-04 14:29:02 +00:00
def initialize ( shell = :bash )
2020-02-28 11:06:38 +00:00
@win = go ( %W[ new-window -d -P -F # I #{ Shell . send ( shell ) } ] ) . first
go ( %W[ set-window-option -t #{ @win } pane-base-index 0 ] )
2017-08-04 14:29:02 +00:00
return unless shell == :fish
2020-02-28 06:38:39 +00:00
2017-08-04 14:29:02 +00:00
send_keys ( 'function fish_prompt; end; clear' , :Enter )
self . until ( & :empty? )
2015-01-16 19:55:29 +00:00
end
def kill
2020-02-28 11:06:38 +00:00
go ( %W[ kill-window -t #{ win } ] )
2015-01-16 19:55:29 +00:00
end
2017-08-04 14:29:02 +00:00
def send_keys ( * args )
2015-02-28 18:00:36 +00:00
target =
if args . last . is_a? ( Hash )
hash = args . pop
2020-02-28 11:06:38 +00:00
go ( %W[ select-window -t #{ win } ] )
2015-02-28 18:00:36 +00:00
" #{ win } . #{ hash [ :pane ] } "
else
win
end
2020-02-28 11:06:38 +00:00
go ( %W[ send-keys -t #{ target } ] + args . map ( & :to_s ) )
2015-01-16 19:55:29 +00:00
end
2017-08-04 14:29:02 +00:00
def paste ( str )
2020-02-21 00:51:34 +00:00
system ( 'tmux' , 'setb' , str , ';' , 'pasteb' , '-t' , win , ';' , 'send-keys' , '-t' , win , 'Enter' )
2016-07-10 03:27:01 +00:00
end
2017-08-04 14:29:02 +00:00
def capture ( pane = 0 )
2020-02-28 11:06:38 +00:00
go ( %W[ capture-pane -p -t #{ win } . #{ pane } ] ) . reverse . drop_while ( & :empty? ) . reverse
2015-01-16 19:55:29 +00:00
end
2017-08-04 14:29:02 +00:00
def until ( refresh = false , pane = 0 )
2015-02-28 18:00:36 +00:00
lines = nil
2015-05-09 18:25:14 +00:00
begin
wait do
lines = capture ( pane )
class << lines
2017-01-07 16:30:31 +00:00
def counts
2017-08-04 14:29:02 +00:00
lazy
. map { | l | l . scan %r{ ^. ([0-9]+) \ /([0-9]+)( \ (([0-9]+) \ ))? } }
2017-01-07 16:30:31 +00:00
. reject ( & :empty? )
. first & . first & . map ( & :to_i ) & . values_at ( 0 , 1 , 3 ) || [ 0 , 0 , 0 ]
end
def match_count
counts [ 0 ]
end
2015-05-09 18:25:14 +00:00
def item_count
2017-01-07 16:30:31 +00:00
counts [ 1 ]
end
def select_count
counts [ 2 ]
end
2017-08-04 14:29:02 +00:00
def any_include? ( val )
2017-01-07 16:30:31 +00:00
method = val . is_a? ( Regexp ) ? :match : :include?
2017-08-04 14:29:02 +00:00
select { | line | line . send method , val } . first
2015-05-09 18:25:14 +00:00
end
2015-04-24 16:09:05 +00:00
end
2017-01-20 19:17:51 +00:00
yield ( lines ) . tap do | ok |
send_keys 'C-l' if refresh && ! ok
end
2015-04-24 16:09:05 +00:00
end
2017-08-04 14:29:02 +00:00
rescue StandardError
puts $ERROR_INFO . backtrace
2015-05-09 18:25:14 +00:00
puts '>' * 80
puts lines
puts '<' * 80
raise
2015-02-28 18:00:36 +00:00
end
lines
2015-01-16 19:55:29 +00:00
end
2015-02-28 18:00:36 +00:00
def prepare
2015-04-24 16:09:05 +00:00
tries = 0
begin
2016-10-21 15:01:21 +00:00
self . until do | lines |
2020-02-28 05:46:08 +00:00
send_keys ' ' , 'C-u' , 'hello' , :Left , :Right
2016-10-21 15:01:21 +00:00
lines [ - 1 ] . end_with? ( 'hello' )
end
2017-08-04 14:29:02 +00:00
rescue StandardError
2015-04-24 16:09:05 +00:00
( tries += 1 ) < 5 ? retry : raise
end
2017-08-04 14:29:02 +00:00
send_keys 'C-u'
2015-02-28 18:00:36 +00:00
end
2017-08-04 14:29:02 +00:00
private
2020-02-28 11:06:38 +00:00
def go ( args )
IO . popen ( [ 'tmux' ] + args ) { | io | io . readlines ( chomp : true ) }
2015-01-16 19:55:29 +00:00
end
end
2015-02-28 18:00:36 +00:00
class TestBase < Minitest :: Test
2015-01-24 04:25:11 +00:00
TEMPNAME = '/tmp/output'
2015-01-17 04:38:42 +00:00
2015-01-24 04:25:11 +00:00
attr_reader :tmux
2015-01-17 03:37:24 +00:00
2015-06-13 17:44:22 +00:00
def tempname
2016-01-13 15:41:02 +00:00
@temp_suffix || = 0
2015-06-13 17:44:22 +00:00
[ TEMPNAME ,
2016-01-13 15:41:02 +00:00
caller_locations . map ( & :label ) . find { | l | l =~ / ^test_ / } ,
@temp_suffix ] . join '-'
2015-06-13 17:44:22 +00:00
end
2017-08-04 14:29:02 +00:00
def writelines ( path , lines )
File . unlink path while File . exist? path
File . open ( path , 'w' ) { | f | f << lines . join ( $INPUT_RECORD_SEPARATOR ) + $INPUT_RECORD_SEPARATOR }
2017-01-07 16:30:31 +00:00
end
2015-04-25 01:39:04 +00:00
def readonce
2017-08-04 14:29:02 +00:00
wait { File . exist? ( tempname ) }
2015-06-13 17:44:22 +00:00
File . read ( tempname )
2015-04-25 01:39:04 +00:00
ensure
2017-08-04 14:29:02 +00:00
File . unlink tempname while File . exist? ( tempname )
2016-01-13 15:41:02 +00:00
@temp_suffix += 1
2015-06-17 17:09:03 +00:00
tmux . prepare
2015-01-16 19:55:29 +00:00
end
2015-01-29 08:37:35 +00:00
def fzf ( * opts )
2015-06-13 17:44:22 +00:00
fzf! ( * opts ) + " > #{ tempname } .tmp; mv #{ tempname } .tmp #{ tempname } "
2015-02-18 03:07:54 +00:00
end
def fzf! ( * opts )
2017-08-04 14:29:02 +00:00
opts = opts . map do | o |
2015-01-29 08:37:35 +00:00
case o
when Symbol
o = o . to_s
2017-08-04 14:29:02 +00:00
o . length > 1 ? " -- #{ o . tr ( '_' , '-' ) } " : " - #{ o } "
2015-01-29 08:37:35 +00:00
when String , Numeric
o . to_s
end
2017-08-04 14:29:02 +00:00
end . compact
2015-04-14 13:23:11 +00:00
" #{ FZF } #{ opts . join ' ' } "
2015-01-29 08:37:35 +00:00
end
2015-02-28 18:00:36 +00:00
end
class TestGoFZF < TestBase
def setup
super
@tmux = Tmux . new
end
def teardown
@tmux . kill
end
2015-01-29 08:37:35 +00:00
2015-01-16 19:55:29 +00:00
def test_vanilla
2015-01-29 08:37:35 +00:00
tmux . send_keys " seq 1 100000 | #{ fzf } " , :Enter
2015-04-25 01:39:04 +00:00
tmux . until { | lines | lines . last =~ / ^> / && lines [ - 2 ] =~ / ^ 100000 / }
2015-01-16 19:55:29 +00:00
lines = tmux . capture
assert_equal ' 2' , lines [ - 4 ]
assert_equal '> 1' , lines [ - 3 ]
assert_equal ' 100000/100000' , lines [ - 2 ]
assert_equal '>' , lines [ - 1 ]
# Testing basic key bindings
tmux . send_keys '99' , 'C-a' , '1' , 'C-f' , '3' , 'C-b' , 'C-h' , 'C-u' , 'C-e' , 'C-y' , 'C-k' , 'Tab' , 'BTab'
2019-11-02 05:55:13 +00:00
tmux . until do | lines |
'> 3910' == lines [ - 4 ] &&
' 391' == lines [ - 3 ] &&
' 856/100000' == lines [ - 2 ] &&
'> 391' == lines [ - 1 ]
end
2015-01-16 19:55:29 +00:00
tmux . send_keys :Enter
2016-04-16 05:02:43 +00:00
assert_equal '3910' , readonce . chomp
2015-01-16 19:55:29 +00:00
end
def test_fzf_default_command
2015-11-03 13:49:32 +00:00
tmux . send_keys fzf . sub ( 'FZF_DEFAULT_COMMAND=' , " FZF_DEFAULT_COMMAND='echo hello' " ) , :Enter
2015-01-16 19:55:29 +00:00
tmux . until { | lines | lines . last =~ / ^> / }
tmux . send_keys :Enter
2015-01-24 04:25:11 +00:00
assert_equal 'hello' , readonce . chomp
2015-01-16 19:55:29 +00:00
end
2017-06-30 16:13:15 +00:00
def test_fzf_default_command_failure
tmux . send_keys fzf . sub ( 'FZF_DEFAULT_COMMAND=' , 'FZF_DEFAULT_COMMAND=false' ) , :Enter
2019-11-10 04:13:45 +00:00
tmux . until { | lines | lines [ - 2 ] . include? ( 'Command failed: false' ) }
2017-06-30 16:13:15 +00:00
tmux . send_keys :Enter
end
2015-01-17 02:20:00 +00:00
def test_key_bindings
2015-04-14 13:23:11 +00:00
tmux . send_keys " #{ FZF } -q 'foo bar foo-bar' " , :Enter
2015-01-16 21:12:57 +00:00
tmux . until { | lines | lines . last =~ / ^> / }
2015-01-16 19:55:29 +00:00
# CTRL-A
2017-08-04 14:29:02 +00:00
tmux . send_keys 'C-A' , '('
2015-01-16 19:55:29 +00:00
tmux . until { | lines | lines . last == '> (foo bar foo-bar' }
# META-F
2017-08-04 14:29:02 +00:00
tmux . send_keys :Escape , :f , ')'
2015-01-16 19:55:29 +00:00
tmux . until { | lines | lines . last == '> (foo) bar foo-bar' }
# CTRL-B
2017-08-04 14:29:02 +00:00
tmux . send_keys 'C-B' , 'var'
2015-01-16 19:55:29 +00:00
tmux . until { | lines | lines . last == '> (foovar) bar foo-bar' }
# Left, CTRL-D
2017-08-04 14:29:02 +00:00
tmux . send_keys :Left , :Left , 'C-D'
2015-01-16 19:55:29 +00:00
tmux . until { | lines | lines . last == '> (foovr) bar foo-bar' }
# META-BS
tmux . send_keys :Escape , :BSpace
tmux . until { | lines | lines . last == '> (r) bar foo-bar' }
# CTRL-Y
2017-08-04 14:29:02 +00:00
tmux . send_keys 'C-Y' , 'C-Y'
2015-01-16 19:55:29 +00:00
tmux . until { | lines | lines . last == '> (foovfoovr) bar foo-bar' }
# META-B
tmux . send_keys :Escape , :b , :Space , :Space
tmux . until { | lines | lines . last == '> ( foovfoovr) bar foo-bar' }
# CTRL-F / Right
tmux . send_keys 'C-F' , :Right , '/'
tmux . until { | lines | lines . last == '> ( fo/ovfoovr) bar foo-bar' }
# CTRL-H / BS
tmux . send_keys 'C-H' , :BSpace
tmux . until { | lines | lines . last == '> ( fovfoovr) bar foo-bar' }
# CTRL-E
2017-08-04 14:29:02 +00:00
tmux . send_keys 'C-E' , 'baz'
2015-01-16 19:55:29 +00:00
tmux . until { | lines | lines . last == '> ( fovfoovr) bar foo-barbaz' }
# CTRL-U
2017-08-04 14:29:02 +00:00
tmux . send_keys 'C-U'
2015-01-16 19:55:29 +00:00
tmux . until { | lines | lines . last == '>' }
# CTRL-Y
2017-08-04 14:29:02 +00:00
tmux . send_keys 'C-Y'
2015-01-16 19:55:29 +00:00
tmux . until { | lines | lines . last == '> ( fovfoovr) bar foo-barbaz' }
# CTRL-W
2017-08-04 14:29:02 +00:00
tmux . send_keys 'C-W' , 'bar-foo'
2015-01-16 19:55:29 +00:00
tmux . until { | lines | lines . last == '> ( fovfoovr) bar bar-foo' }
# META-D
2017-08-04 14:29:02 +00:00
tmux . send_keys :Escape , :b , :Escape , :b , :Escape , :d , 'C-A' , 'C-Y'
2015-01-16 19:55:29 +00:00
tmux . until { | lines | lines . last == '> bar( fovfoovr) bar -foo' }
# CTRL-M
2017-08-04 14:29:02 +00:00
tmux . send_keys 'C-M'
2015-01-16 19:55:29 +00:00
tmux . until { | lines | lines . last !~ / ^> / }
end
2015-01-17 02:07:04 +00:00
2017-01-15 10:42:28 +00:00
def test_file_word
tmux . send_keys " #{ FZF } -q '--/foo bar/foo-bar/baz' --filepath-word " , :Enter
tmux . until { | lines | lines . last =~ / ^> / }
tmux . send_keys :Escape , :b
tmux . send_keys :Escape , :b
tmux . send_keys :Escape , :b
tmux . send_keys :Escape , :d
tmux . send_keys :Escape , :f
tmux . send_keys :Escape , :BSpace
tmux . until { | lines | lines . last == '> --///baz' }
end
2015-01-17 02:20:00 +00:00
def test_multi_order
2015-01-29 08:37:35 +00:00
tmux . send_keys " seq 1 10 | #{ fzf :multi } " , :Enter
2015-01-17 02:07:04 +00:00
tmux . until { | lines | lines . last =~ / ^> / }
tmux . send_keys :Tab , :Up , :Up , :Tab , :Tab , :Tab , # 3, 2
'C-K' , 'C-K' , 'C-K' , 'C-K' , :BTab , :BTab , # 5, 6
:PgUp , 'C-J' , :Down , :Tab , :Tab # 8, 7
tmux . until { | lines | lines [ - 2 ] . include? '(6)' }
2017-08-04 14:29:02 +00:00
tmux . send_keys 'C-M'
assert_equal %w[ 3 2 5 6 8 7 ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-01-17 02:07:04 +00:00
end
2015-01-17 02:20:00 +00:00
2019-11-02 03:55:26 +00:00
def test_multi_max
tmux . send_keys " seq 1 10 | #{ FZF } -m 3 --bind A:select-all,T:toggle-all --preview 'echo [{+}]/{}' " , :Enter
tmux . until { | lines | lines . item_count == 10 }
tmux . send_keys '1'
tmux . until do | lines |
lines [ 1 ] . include? ( '[1]/1' ) && lines [ - 2 ] . include? ( '2/10' )
end
tmux . send_keys 'A'
tmux . until do | lines |
lines [ 1 ] . include? ( '[1 10]/1' ) && lines [ - 2 ] . include? ( '2/10 (2/3)' )
end
tmux . send_keys :BSpace
tmux . until { | lines | lines [ - 2 ] . include? ( '10/10 (2/3)' ) }
tmux . send_keys 'T'
tmux . until do | lines |
lines [ 1 ] . include? ( '[2 3 4]/1' ) && lines [ - 2 ] . include? ( '10/10 (3/3)' )
end
%w[ T A ] . each do | key |
tmux . send_keys key
tmux . until do | lines |
lines [ 1 ] . include? ( '[1 5 6]/1' ) && lines [ - 2 ] . include? ( '10/10 (3/3)' )
end
end
tmux . send_keys :BTab
tmux . until do | lines |
lines [ 1 ] . include? ( '[5 6]/2' ) && lines [ - 2 ] . include? ( '10/10 (2/3)' )
end
[ :BTab , :BTab , 'A' ] . each do | key |
tmux . send_keys key
tmux . until do | lines |
lines [ 1 ] . include? ( '[5 6 2]/3' ) && lines [ - 2 ] . include? ( '10/10 (3/3)' )
end
end
tmux . send_keys '2'
tmux . until { | lines | lines [ - 2 ] . include? ( '1/10 (3/3)' ) }
tmux . send_keys 'T'
tmux . until do | lines |
lines [ 1 ] . include? ( '[5 6]/2' ) && lines [ - 2 ] . include? ( '1/10 (2/3)' )
end
tmux . send_keys :BSpace
tmux . until { | lines | lines [ - 2 ] . include? ( '10/10 (2/3)' ) }
tmux . send_keys 'A'
tmux . until do | lines |
lines [ 1 ] . include? ( '[5 6 1]/1' ) && lines [ - 2 ] . include? ( '10/10 (3/3)' )
end
end
2015-01-17 02:20:00 +00:00
def test_with_nth
[ true , false ] . each do | multi |
tmux . send_keys " (echo ' 1st 2nd 3rd/';
echo ' first second third/' ) |
2015-01-29 08:37:35 +00:00
#{fzf multi && :multi, :x, :nth, 2, :with_nth, '2,-1,1'}",
2017-08-04 14:29:02 +00:00
:Enter
2015-01-17 03:37:24 +00:00
tmux . until { | lines | lines [ - 2 ] . include? ( '2/2' ) }
2015-01-17 02:20:00 +00:00
# Transformed list
lines = tmux . capture
assert_equal ' second third/first' , lines [ - 4 ]
assert_equal '> 2nd 3rd/1st' , lines [ - 3 ]
# However, the output must not be transformed
if multi
2015-07-13 10:24:22 +00:00
tmux . send_keys :BTab , :BTab
tmux . until { | lines | lines [ - 2 ] . include? ( '(2)' ) }
tmux . send_keys :Enter
2017-08-04 14:29:02 +00:00
assert_equal [ ' 1st 2nd 3rd/' , ' first second third/' ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-01-17 02:20:00 +00:00
else
tmux . send_keys '^' , '3'
tmux . until { | lines | lines [ - 2 ] . include? ( '1/2' ) }
tmux . send_keys :Enter
2017-08-04 14:29:02 +00:00
assert_equal [ ' 1st 2nd 3rd/' ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-01-17 02:20:00 +00:00
end
end
end
2015-01-17 03:21:38 +00:00
def test_scroll
[ true , false ] . each do | rev |
2015-01-29 08:37:35 +00:00
tmux . send_keys " seq 1 100 | #{ fzf rev && :reverse } " , :Enter
2015-01-24 04:25:11 +00:00
tmux . until { | lines | lines . include? ' 100/100' }
2017-08-04 14:29:02 +00:00
tmux . send_keys ( * Array . new ( 110 ) { rev ? :Down : :Up } )
2015-01-17 04:38:42 +00:00
tmux . until { | lines | lines . include? '> 100' }
2015-01-17 03:21:38 +00:00
tmux . send_keys :Enter
2015-01-24 04:25:11 +00:00
assert_equal '100' , readonce . chomp
2015-01-17 03:21:38 +00:00
end
end
2015-01-17 03:37:24 +00:00
def test_select_1
2015-01-29 08:37:35 +00:00
tmux . send_keys " seq 1 100 | #{ fzf :with_nth , '..,..' , :print_query , :q , 5555 , :'1' } " , :Enter
2017-08-04 14:29:02 +00:00
assert_equal %w[ 5555 55 ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-01-17 03:37:24 +00:00
end
def test_exit_0
2017-08-04 14:29:02 +00:00
tmux . send_keys " seq 1 100 | #{ fzf :with_nth , '..,..' , :print_query , :q , 555_555 , :'0' } " , :Enter
assert_equal [ '555555' ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-01-17 03:37:24 +00:00
end
2015-01-24 04:26:33 +00:00
2015-02-17 15:51:44 +00:00
def test_select_1_exit_0_fail
2017-08-04 14:29:02 +00:00
[ :'0' , :'1' , % i [ 1 0 ] ] . each do | opt |
2015-02-17 15:51:44 +00:00
tmux . send_keys " seq 1 100 | #{ fzf :print_query , :multi , :q , 5 , * opt } " , :Enter
tmux . until { | lines | lines . last =~ / ^> 5 / }
2015-07-13 10:24:22 +00:00
tmux . send_keys :BTab , :BTab , :BTab
tmux . until { | lines | lines [ - 2 ] . include? ( '(3)' ) }
tmux . send_keys :Enter
2017-08-04 14:29:02 +00:00
assert_equal %w[ 5 5 50 51 ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-02-17 15:51:44 +00:00
end
end
2015-01-24 04:26:33 +00:00
def test_query_unicode
2020-02-21 00:51:34 +00:00
tmux . paste " (echo abc; echo $' \\ 352 \\ 260 \\ 200 \\ 353 \\ 202 \\ 230 \\ 353 \\ 213 \\ 244') | #{ fzf :query , " $' \\ 352 \\ 260 \\ 200 \\ 353 \\ 213 \\ 244' " } "
2015-04-24 16:09:05 +00:00
tmux . until { | lines | lines [ - 2 ] . include? '1/2' }
2015-01-24 04:26:33 +00:00
tmux . send_keys :Enter
2017-08-04 14:29:02 +00:00
assert_equal [ '가나다' ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-01-24 04:26:33 +00:00
end
2015-02-18 03:07:54 +00:00
def test_sync
2020-02-28 11:06:38 +00:00
tmux . send_keys " seq 1 100 | #{ fzf! :multi } | awk '{print $1 $1}' | #{ fzf :sync } " , :Enter
2015-02-18 03:07:54 +00:00
tmux . until { | lines | lines [ - 1 ] == '>' }
tmux . send_keys 9
tmux . until { | lines | lines [ - 2 ] == ' 19/100' }
2015-07-13 10:24:22 +00:00
tmux . send_keys :BTab , :BTab , :BTab
tmux . until { | lines | lines [ - 2 ] . include? ( '(3)' ) }
tmux . send_keys :Enter
2015-02-18 03:07:54 +00:00
tmux . until { | lines | lines [ - 1 ] == '>' }
tmux . send_keys 'C-K' , :Enter
2017-08-04 14:29:02 +00:00
assert_equal [ '9090' ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-02-18 03:07:54 +00:00
end
2015-02-25 16:42:15 +00:00
def test_tac
tmux . send_keys " seq 1 1000 | #{ fzf :tac , :multi } " , :Enter
tmux . until { | lines | lines [ - 2 ] . include? '1000/1000' }
2015-07-13 10:24:22 +00:00
tmux . send_keys :BTab , :BTab , :BTab
tmux . until { | lines | lines [ - 2 ] . include? ( '(3)' ) }
tmux . send_keys :Enter
2017-08-04 14:29:02 +00:00
assert_equal %w[ 1000 999 998 ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-02-25 16:42:15 +00:00
end
def test_tac_sort
tmux . send_keys " seq 1 1000 | #{ fzf :tac , :multi } " , :Enter
tmux . until { | lines | lines [ - 2 ] . include? '1000/1000' }
tmux . send_keys '99'
2016-03-06 03:46:28 +00:00
tmux . until { | lines | lines [ - 2 ] . include? '28/1000' }
2015-07-13 10:24:22 +00:00
tmux . send_keys :BTab , :BTab , :BTab
tmux . until { | lines | lines [ - 2 ] . include? ( '(3)' ) }
tmux . send_keys :Enter
2017-08-04 14:29:02 +00:00
assert_equal %w[ 99 999 998 ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-02-25 16:42:15 +00:00
end
def test_tac_nosort
tmux . send_keys " seq 1 1000 | #{ fzf :tac , :no_sort , :multi } " , :Enter
tmux . until { | lines | lines [ - 2 ] . include? '1000/1000' }
tmux . send_keys '00'
2015-04-25 01:54:47 +00:00
tmux . until { | lines | lines [ - 2 ] . include? '10/1000' }
2015-07-13 10:24:22 +00:00
tmux . send_keys :BTab , :BTab , :BTab
tmux . until { | lines | lines [ - 2 ] . include? ( '(3)' ) }
tmux . send_keys :Enter
2017-08-04 14:29:02 +00:00
assert_equal %w[ 1000 900 800 ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-02-25 16:42:15 +00:00
end
2015-03-28 17:59:32 +00:00
def test_expect
test = lambda do | key , feed , expected = key |
2016-04-15 03:57:38 +00:00
tmux . send_keys " seq 1 100 | #{ fzf :expect , key } ; sync " , :Enter
2015-03-28 17:59:32 +00:00
tmux . until { | lines | lines [ - 2 ] . include? '100/100' }
tmux . send_keys '55'
2015-04-25 01:54:47 +00:00
tmux . until { | lines | lines [ - 2 ] . include? '1/100' }
2017-08-04 14:29:02 +00:00
tmux . send_keys ( * feed )
2016-04-15 03:57:38 +00:00
tmux . prepare
2017-08-04 14:29:02 +00:00
assert_equal [ expected , '55' ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-03-28 17:59:32 +00:00
end
test . call 'ctrl-t' , 'C-T'
test . call 'ctrl-t' , 'Enter' , ''
2017-08-04 14:29:02 +00:00
test . call 'alt-c' , % i [ Escape c ]
2015-03-28 17:59:32 +00:00
test . call 'f1' , 'f1'
test . call 'f2' , 'f2'
test . call 'f3' , 'f3'
test . call 'f2,f4' , 'f2' , 'f2'
test . call 'f2,f4' , 'f4' , 'f4'
2017-08-04 14:29:02 +00:00
test . call 'alt-/' , % i [ Escape / ]
2016-05-18 13:25:09 +00:00
%w[ f5 f6 f7 f8 f9 f10 ] . each do | key |
test . call 'f5,f6,f7,f8,f9,f10' , key , key
end
2015-03-28 17:59:32 +00:00
test . call '@' , '@'
end
def test_expect_print_query
tmux . send_keys " seq 1 100 | #{ fzf '--expect=alt-z' , :print_query } " , :Enter
tmux . until { | lines | lines [ - 2 ] . include? '100/100' }
tmux . send_keys '55'
2015-04-25 01:54:47 +00:00
tmux . until { | lines | lines [ - 2 ] . include? '1/100' }
2015-03-28 17:59:32 +00:00
tmux . send_keys :Escape , :z
2017-08-04 14:29:02 +00:00
assert_equal [ '55' , 'alt-z' , '55' ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-03-28 17:59:32 +00:00
end
2015-03-31 11:52:16 +00:00
2016-09-17 19:45:21 +00:00
def test_expect_printable_character_print_query
tmux . send_keys " seq 1 100 | #{ fzf '--expect=z --print-query' } " , :Enter
tmux . until { | lines | lines [ - 2 ] . include? '100/100' }
tmux . send_keys '55'
tmux . until { | lines | lines [ - 2 ] . include? '1/100' }
tmux . send_keys 'z'
2017-08-04 14:29:02 +00:00
assert_equal %w[ 55 z 55 ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2016-09-17 19:45:21 +00:00
end
2015-03-31 11:52:16 +00:00
def test_expect_print_query_select_1
tmux . send_keys " seq 1 100 | #{ fzf '-q55 -1 --expect=alt-z --print-query' } " , :Enter
2017-08-04 14:29:02 +00:00
assert_equal [ '55' , '' , '55' ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-03-31 11:52:16 +00:00
end
2015-03-31 13:05:02 +00:00
def test_toggle_sort
2015-05-21 12:06:52 +00:00
[ '--toggle-sort=ctrl-r' , '--bind=ctrl-r:toggle-sort' ] . each do | opt |
tmux . send_keys " seq 1 111 | #{ fzf " -m +s --tac #{ opt } -q11 " } " , :Enter
tmux . until { | lines | lines [ - 3 ] . include? '> 111' }
tmux . send_keys :Tab
2017-03-02 17:26:30 +00:00
tmux . until { | lines | lines [ - 2 ] . include? '4/111 -S (1)' }
2015-05-21 12:06:52 +00:00
tmux . send_keys 'C-R'
tmux . until { | lines | lines [ - 3 ] . include? '> 11' }
tmux . send_keys :Tab
2017-03-02 17:26:30 +00:00
tmux . until { | lines | lines [ - 2 ] . include? '4/111 +S (2)' }
2015-05-21 12:06:52 +00:00
tmux . send_keys :Enter
2017-08-04 14:29:02 +00:00
assert_equal %w[ 111 11 ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-05-21 12:06:52 +00:00
end
2015-03-31 13:05:02 +00:00
end
2015-04-14 12:45:37 +00:00
def test_unicode_case
2015-04-16 05:19:28 +00:00
writelines tempname , %w[ с тр о К А 1 С Т Р О К А 2 с тр о ка 3 С тр о ка 4]
2017-08-04 14:29:02 +00:00
assert_equal %w[ С Т Р О К А 2 С тр о ка 4] , ` #{ FZF } -fС < #{ tempname } ` . split ( $INPUT_RECORD_SEPARATOR )
assert_equal %w[ с тр о К А 1 С Т Р О К А 2 с тр о ка 3 С тр о ка 4] , ` #{ FZF } -fс < #{ tempname } ` . split ( $INPUT_RECORD_SEPARATOR )
2015-04-16 05:19:28 +00:00
end
def test_tiebreak
input = %w[
- - foobar - - - - - - - -
- - - - - foobar - - -
- - - - foobar - -
- - - - - - - foobar -
]
writelines tempname , input
2017-08-04 14:29:02 +00:00
assert_equal input , ` #{ FZF } -ffoobar --tiebreak=index < #{ tempname } ` . split ( $INPUT_RECORD_SEPARATOR )
2015-04-16 05:19:28 +00:00
by_length = %w[
- - - - foobar - -
- - - - - foobar - - -
- - - - - - - foobar -
- - foobar - - - - - - - -
]
2017-08-04 14:29:02 +00:00
assert_equal by_length , ` #{ FZF } -ffoobar < #{ tempname } ` . split ( $INPUT_RECORD_SEPARATOR )
assert_equal by_length , ` #{ FZF } -ffoobar --tiebreak=length < #{ tempname } ` . split ( $INPUT_RECORD_SEPARATOR )
2015-04-16 05:19:28 +00:00
by_begin = %w[
- - foobar - - - - - - - -
- - - - foobar - -
- - - - - foobar - - -
- - - - - - - foobar -
]
2017-08-04 14:29:02 +00:00
assert_equal by_begin , ` #{ FZF } -ffoobar --tiebreak=begin < #{ tempname } ` . split ( $INPUT_RECORD_SEPARATOR )
assert_equal by_begin , ` #{ FZF } -f"!z foobar" -x --tiebreak begin < #{ tempname } ` . split ( $INPUT_RECORD_SEPARATOR )
2015-04-16 05:19:28 +00:00
assert_equal %w[
- - - - - - - foobar -
- - - - foobar - -
- - - - - foobar - - -
- - foobar - - - - - - - -
2017-08-04 14:29:02 +00:00
] , ` #{ FZF } -ffoobar --tiebreak end < #{ tempname } ` . split ( $INPUT_RECORD_SEPARATOR )
2015-04-16 05:19:28 +00:00
2017-08-04 14:29:02 +00:00
assert_equal input , ` #{ FZF } -f"!z" -x --tiebreak end < #{ tempname } ` . split ( $INPUT_RECORD_SEPARATOR )
2016-01-12 18:07:42 +00:00
end
2016-09-07 00:58:18 +00:00
def test_tiebreak_index_begin
writelines tempname , [
'xoxxxxxoxx' ,
'xoxxxxxox' ,
'xxoxxxoxx' ,
'xxxoxoxxx' ,
'xxxxoxox' ,
2017-08-04 14:29:02 +00:00
' xxoxoxxx'
2016-01-12 18:07:42 +00:00
]
2016-09-07 00:58:18 +00:00
assert_equal [
'xxxxoxox' ,
' xxoxoxxx' ,
'xxxoxoxxx' ,
'xxoxxxoxx' ,
'xoxxxxxox' ,
2017-08-04 14:29:02 +00:00
'xoxxxxxoxx'
] , ` #{ FZF } -foo < #{ tempname } ` . split ( $INPUT_RECORD_SEPARATOR )
2016-01-12 18:07:42 +00:00
2016-09-07 00:58:18 +00:00
assert_equal [
'xxxoxoxxx' ,
'xxxxoxox' ,
' xxoxoxxx' ,
'xxoxxxoxx' ,
'xoxxxxxoxx' ,
2017-08-04 14:29:02 +00:00
'xoxxxxxox'
] , ` #{ FZF } -foo --tiebreak=index < #{ tempname } ` . split ( $INPUT_RECORD_SEPARATOR )
2016-09-07 00:58:18 +00:00
# Note that --tiebreak=begin is now based on the first occurrence of the
# first character on the pattern
assert_equal [
' xxoxoxxx' ,
'xxxoxoxxx' ,
'xxxxoxox' ,
'xxoxxxoxx' ,
'xoxxxxxoxx' ,
2017-08-04 14:29:02 +00:00
'xoxxxxxox'
] , ` #{ FZF } -foo --tiebreak=begin < #{ tempname } ` . split ( $INPUT_RECORD_SEPARATOR )
2016-01-12 18:07:42 +00:00
2016-09-07 00:58:18 +00:00
assert_equal [
' xxoxoxxx' ,
'xxxoxoxxx' ,
'xxxxoxox' ,
'xxoxxxoxx' ,
'xoxxxxxox' ,
2017-08-04 14:29:02 +00:00
'xoxxxxxoxx'
] , ` #{ FZF } -foo --tiebreak=begin,length < #{ tempname } ` . split ( $INPUT_RECORD_SEPARATOR )
2015-04-16 05:19:28 +00:00
end
2017-02-02 17:14:14 +00:00
def test_tiebreak_begin_algo_v2
writelines tempname , [
'baz foo bar' ,
2017-08-04 14:29:02 +00:00
'foo bar baz'
2017-02-02 17:14:14 +00:00
]
assert_equal [
'foo bar baz' ,
2017-08-04 14:29:02 +00:00
'baz foo bar'
] , ` #{ FZF } -fbar --tiebreak=begin --algo=v2 < #{ tempname } ` . split ( $INPUT_RECORD_SEPARATOR )
2017-02-02 17:14:14 +00:00
end
2016-09-07 00:58:18 +00:00
def test_tiebreak_end
2016-01-13 16:32:03 +00:00
writelines tempname , [
2016-09-07 00:58:18 +00:00
'xoxxxxxxxx' ,
'xxoxxxxxxx' ,
'xxxoxxxxxx' ,
'xxxxoxxxx' ,
'xxxxxoxxx' ,
2017-08-04 14:29:02 +00:00
' xxxxoxxx'
2016-01-13 16:32:03 +00:00
]
assert_equal [
2016-09-07 00:58:18 +00:00
' xxxxoxxx' ,
'xxxxoxxxx' ,
'xxxxxoxxx' ,
'xoxxxxxxxx' ,
'xxoxxxxxxx' ,
2017-08-04 14:29:02 +00:00
'xxxoxxxxxx'
] , ` #{ FZF } -fo < #{ tempname } ` . split ( $INPUT_RECORD_SEPARATOR )
2016-01-13 16:32:03 +00:00
assert_equal [
2016-09-07 00:58:18 +00:00
'xxxxxoxxx' ,
' xxxxoxxx' ,
'xxxxoxxxx' ,
'xxxoxxxxxx' ,
'xxoxxxxxxx' ,
2017-08-04 14:29:02 +00:00
'xoxxxxxxxx'
] , ` #{ FZF } -fo --tiebreak=end < #{ tempname } ` . split ( $INPUT_RECORD_SEPARATOR )
2016-01-13 16:32:03 +00:00
assert_equal [
2016-09-07 00:58:18 +00:00
'xxxxxoxxx' ,
2016-10-17 16:11:04 +00:00
' xxxxoxxx' ,
2016-09-07 00:58:18 +00:00
'xxxxoxxxx' ,
'xxxoxxxxxx' ,
'xxoxxxxxxx' ,
2017-08-04 14:29:02 +00:00
'xoxxxxxxxx'
] , ` #{ FZF } -fo --tiebreak=end,length,begin < #{ tempname } ` . split ( $INPUT_RECORD_SEPARATOR )
2016-01-13 16:32:03 +00:00
end
2015-08-01 14:13:24 +00:00
def test_tiebreak_length_with_nth
input = %w[
1 :hell
123 :hello
12345 :he
1234567 :h
]
writelines tempname , input
output = %w[
1 :hell
12345 :he
123 :hello
1234567 :h
]
2017-08-04 14:29:02 +00:00
assert_equal output , ` #{ FZF } -fh < #{ tempname } ` . split ( $INPUT_RECORD_SEPARATOR )
2015-08-01 14:13:24 +00:00
2017-06-02 04:25:35 +00:00
# Since 0.16.8, --nth doesn't affect --tiebreak
2017-08-04 14:29:02 +00:00
assert_equal output , ` #{ FZF } -fh -n2 -d: < #{ tempname } ` . split ( $INPUT_RECORD_SEPARATOR )
2015-10-02 09:40:20 +00:00
end
2015-04-21 13:10:14 +00:00
def test_invalid_cache
tmux . send_keys " (echo d; echo D; echo x) | #{ fzf '-q d' } " , :Enter
tmux . until { | lines | lines [ - 2 ] . include? '2/3' }
tmux . send_keys :BSpace
tmux . until { | lines | lines [ - 2 ] . include? '3/3' }
tmux . send_keys :D
tmux . until { | lines | lines [ - 2 ] . include? '1/3' }
tmux . send_keys :Enter
end
2017-08-08 04:22:30 +00:00
def test_invalid_cache_query_type
2020-02-28 11:06:38 +00:00
command = %[ (echo 'foo$bar'; echo 'barfoo'; echo 'foo^bar'; echo "foo'1-2"; seq 100) | #{ fzf } ]
2017-08-08 04:22:30 +00:00
# Suffix match
tmux . send_keys command , :Enter
tmux . until { | lines | lines . match_count == 104 }
tmux . send_keys 'foo$'
tmux . until { | lines | lines . match_count == 1 }
tmux . send_keys 'bar'
tmux . until { | lines | lines . match_count == 1 }
tmux . send_keys :Enter
# Prefix match
tmux . prepare
tmux . send_keys command , :Enter
tmux . until { | lines | lines . match_count == 104 }
tmux . send_keys '^bar'
tmux . until { | lines | lines . match_count == 1 }
tmux . send_keys 'C-a' , 'foo'
tmux . until { | lines | lines . match_count == 1 }
tmux . send_keys :Enter
# Exact match
tmux . prepare
tmux . send_keys command , :Enter
tmux . until { | lines | lines . match_count == 104 }
tmux . send_keys " '12 "
tmux . until { | lines | lines . match_count == 1 }
tmux . send_keys 'C-a' , 'foo'
tmux . until { | lines | lines . match_count == 1 }
end
2015-04-21 13:18:05 +00:00
def test_smart_case_for_each_term
assert_equal 1 , ` echo Foo bar | #{ FZF } -x -f "foo Fbar" | wc -l ` . to_i
end
2015-05-20 12:25:15 +00:00
def test_bind
2017-08-04 14:29:02 +00:00
tmux . send_keys " seq 1 1000 | #{ fzf '-m --bind=ctrl-j:accept,u:up,T:toggle-up,t:toggle' } " , :Enter
2015-05-20 12:25:15 +00:00
tmux . until { | lines | lines [ - 2 ] . end_with? '/1000' }
2015-05-21 12:06:52 +00:00
tmux . send_keys 'uuu' , 'TTT' , 'tt' , 'uu' , 'ttt' , 'C-j'
2017-08-04 14:29:02 +00:00
assert_equal %w[ 4 5 6 9 ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-05-20 12:25:15 +00:00
end
2015-06-02 16:48:02 +00:00
2016-05-12 15:51:15 +00:00
def test_bind_print_query
tmux . send_keys " seq 1 1000 | #{ fzf '-m --bind=ctrl-j:print-query' } " , :Enter
tmux . until { | lines | lines [ - 2 ] . end_with? '/1000' }
tmux . send_keys 'print-my-query' , 'C-j'
2017-08-04 14:29:02 +00:00
assert_equal %w[ print-my-query ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2016-05-12 15:51:15 +00:00
end
2017-12-01 04:08:55 +00:00
def test_bind_replace_query
tmux . send_keys " seq 1 1000 | #{ fzf '--print-query --bind=ctrl-j:replace-query' } " , :Enter
tmux . send_keys '1'
tmux . until { | lines | lines [ - 2 ] . end_with? '272/1000' }
tmux . send_keys 'C-k' , 'C-j'
tmux . until { | lines | lines [ - 2 ] . end_with? '29/1000' }
tmux . until { | lines | lines [ - 1 ] . end_with? '> 10' }
end
2015-06-02 16:48:02 +00:00
def test_long_line
data = '.' * 256 * 1024
File . open ( tempname , 'w' ) do | f |
f << data
end
2016-01-12 18:07:42 +00:00
assert_equal data , ` #{ FZF } -f . < #{ tempname } ` . chomp
2015-06-02 16:48:02 +00:00
end
2015-06-08 14:27:50 +00:00
2015-06-21 08:29:58 +00:00
def test_read0
2017-08-04 14:29:02 +00:00
lines = ` find . ` . split ( $INPUT_RECORD_SEPARATOR )
2015-06-08 14:27:50 +00:00
assert_equal lines . last , ` find . | #{ FZF } -e -f "^ #{ lines . last } $" ` . chomp
2017-08-04 14:29:02 +00:00
assert_equal (
lines . last ,
` find . -print0 | #{ FZF } --read0 -e -f "^ #{ lines . last } $" ` . chomp
)
2015-06-08 14:27:50 +00:00
end
2015-06-09 14:44:54 +00:00
def test_select_all_deselect_all_toggle_all
tmux . send_keys " seq 100 | #{ fzf '--bind ctrl-a:select-all,ctrl-d:deselect-all,ctrl-t:toggle-all --multi' } " , :Enter
tmux . until { | lines | lines [ - 2 ] . include? '100/100' }
tmux . send_keys :BTab , :BTab , :BTab
tmux . until { | lines | lines [ - 2 ] . include? '(3)' }
tmux . send_keys 'C-t'
tmux . until { | lines | lines [ - 2 ] . include? '(97)' }
tmux . send_keys 'C-a'
tmux . until { | lines | lines [ - 2 ] . include? '(100)' }
tmux . send_keys :Tab , :Tab
tmux . until { | lines | lines [ - 2 ] . include? '(98)' }
2019-11-02 10:41:59 +00:00
tmux . send_keys '100'
tmux . until { | lines | lines . match_count == 1 }
tmux . send_keys 'C-d'
tmux . until { | lines | lines [ - 2 ] . include? '(97)' }
tmux . send_keys 'C-u'
tmux . until { | lines | lines . match_count == 100 }
2015-06-09 14:44:54 +00:00
tmux . send_keys 'C-d'
tmux . until { | lines | ! lines [ - 2 ] . include? '(' }
2019-11-02 10:41:59 +00:00
tmux . send_keys :BTab , :BTab
2015-06-09 14:44:54 +00:00
tmux . until { | lines | lines [ - 2 ] . include? '(2)' }
tmux . send_keys 0
tmux . until { | lines | lines [ - 2 ] . include? '10/100' }
tmux . send_keys 'C-a'
tmux . until { | lines | lines [ - 2 ] . include? '(12)' }
tmux . send_keys :Enter
2019-11-02 10:41:59 +00:00
assert_equal %w[ 1 2 10 20 30 40 50 60 70 80 90 100 ] ,
2017-08-04 14:29:02 +00:00
readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-06-09 14:44:54 +00:00
end
2015-06-13 15:43:44 +00:00
def test_history
history_file = '/tmp/fzf-test-history'
# History with limited number of entries
2017-08-04 14:29:02 +00:00
begin
File . unlink history_file
rescue
nil
end
2015-06-18 16:03:25 +00:00
opts = " --history= #{ history_file } --history-size=4 "
2017-08-04 14:29:02 +00:00
input = %w[ 00 11 22 33 44 ] . map { | e | e + $INPUT_RECORD_SEPARATOR }
2015-06-13 15:43:44 +00:00
input . each do | keys |
tmux . send_keys " seq 100 | #{ fzf opts } " , :Enter
tmux . until { | lines | lines [ - 2 ] . include? '100/100' }
tmux . send_keys keys
tmux . until { | lines | lines [ - 2 ] . include? '1/100' }
tmux . send_keys :Enter
2015-06-13 17:51:36 +00:00
readonce
2015-06-13 15:43:44 +00:00
end
assert_equal input [ 1 .. - 1 ] , File . readlines ( history_file )
# Update history entries (not changed on disk)
tmux . send_keys " seq 100 | #{ fzf opts } " , :Enter
tmux . until { | lines | lines [ - 2 ] . include? '100/100' }
tmux . send_keys 'C-p'
tmux . until { | lines | lines [ - 1 ] . end_with? '> 44' }
tmux . send_keys 'C-p'
tmux . until { | lines | lines [ - 1 ] . end_with? '> 33' }
tmux . send_keys :BSpace
tmux . until { | lines | lines [ - 1 ] . end_with? '> 3' }
tmux . send_keys 1
tmux . until { | lines | lines [ - 1 ] . end_with? '> 31' }
tmux . send_keys 'C-p'
tmux . until { | lines | lines [ - 1 ] . end_with? '> 22' }
tmux . send_keys 'C-n'
tmux . until { | lines | lines [ - 1 ] . end_with? '> 31' }
tmux . send_keys 0
tmux . until { | lines | lines [ - 1 ] . end_with? '> 310' }
tmux . send_keys :Enter
2015-06-13 17:13:02 +00:00
readonce
2017-08-04 14:29:02 +00:00
assert_equal %w[ 22 33 44 310 ] . map { | e | e + $INPUT_RECORD_SEPARATOR } , File . readlines ( history_file )
2015-06-13 15:43:44 +00:00
# Respect --bind option
tmux . send_keys " seq 100 | #{ fzf opts + ' --bind ctrl-p:next-history,ctrl-n:previous-history' } " , :Enter
tmux . until { | lines | lines [ - 2 ] . include? '100/100' }
tmux . send_keys 'C-n' , 'C-n' , 'C-n' , 'C-n' , 'C-p'
tmux . until { | lines | lines [ - 1 ] . end_with? ( '33' ) }
tmux . send_keys :Enter
ensure
File . unlink history_file
end
2015-06-14 03:25:08 +00:00
def test_execute
output = '/tmp/fzf-test-execute'
2020-02-28 11:06:38 +00:00
opts = %[ --bind "alt-a:execute(echo /{}/ >> #{ output } ),alt-b:execute [ echo /{}{}/ >> #{ output } ] ,C:execute:echo /{}{}{}/ >> #{ output } " ]
2017-08-04 14:29:02 +00:00
wait = - > ( exp ) { tmux . until { | lines | lines [ - 2 ] . include? exp } }
2016-06-07 17:04:40 +00:00
writelines tempname , %w[ foo'bar foo"bar foo$bar ]
tmux . send_keys " cat #{ tempname } | #{ fzf opts } ; sync " , :Enter
wait [ '3/3' ]
2016-05-10 16:40:49 +00:00
tmux . send_keys :Escape , :a
2016-06-07 17:04:40 +00:00
wait [ '/3' ]
2016-05-10 16:40:49 +00:00
tmux . send_keys :Escape , :a
2016-06-07 17:04:40 +00:00
wait [ '/3' ]
2015-06-14 03:25:08 +00:00
tmux . send_keys :Up
2016-05-10 16:40:49 +00:00
tmux . send_keys :Escape , :b
2016-06-07 17:04:40 +00:00
wait [ '/3' ]
2016-05-10 16:40:49 +00:00
tmux . send_keys :Escape , :b
2016-06-07 17:04:40 +00:00
wait [ '/3' ]
2015-06-14 03:25:08 +00:00
tmux . send_keys :Up
tmux . send_keys :C
2016-06-07 17:04:40 +00:00
wait [ '3/3' ]
tmux . send_keys 'barfoo'
wait [ '0/3' ]
2016-05-10 16:40:49 +00:00
tmux . send_keys :Escape , :a
2016-06-07 17:04:40 +00:00
wait [ '/3' ]
2016-05-10 16:40:49 +00:00
tmux . send_keys :Escape , :b
2016-06-07 17:04:40 +00:00
wait [ '/3' ]
2015-06-14 03:25:08 +00:00
tmux . send_keys :Enter
readonce
2019-11-02 04:14:47 +00:00
assert_equal %w[ /foo'bar/ /foo'bar/
2016-06-07 17:04:40 +00:00
/ foo"barfoo"bar / / foo"barfoo"bar /
/ foo$barfoo$barfoo$bar / ] ,
2017-08-04 14:29:02 +00:00
File . readlines ( output ) . map ( & :chomp )
2015-06-14 03:25:08 +00:00
ensure
2017-08-04 14:29:02 +00:00
begin
File . unlink output
rescue
nil
end
2015-06-14 03:25:08 +00:00
end
2015-11-08 16:42:01 +00:00
def test_execute_multi
output = '/tmp/fzf-test-execute-multi'
2020-02-28 11:06:38 +00:00
opts = %[ --multi --bind "alt-a:execute-multi(echo {}/{+} >> #{ output } ; sync)" ]
2016-06-07 17:15:12 +00:00
writelines tempname , %w[ foo'bar foo"bar foo$bar foobar ]
tmux . send_keys " cat #{ tempname } | #{ fzf opts } " , :Enter
tmux . until { | lines | lines [ - 2 ] . include? '4/4' }
2015-11-08 16:42:01 +00:00
tmux . send_keys :Escape , :a
2016-06-07 17:15:12 +00:00
tmux . until { | lines | lines [ - 2 ] . include? '/4' }
2015-11-08 16:42:01 +00:00
tmux . send_keys :BTab , :BTab , :BTab
tmux . send_keys :Escape , :a
2016-06-07 17:15:12 +00:00
tmux . until { | lines | lines [ - 2 ] . include? '/4' }
2015-11-08 16:42:01 +00:00
tmux . send_keys :Tab , :Tab
tmux . send_keys :Escape , :a
2016-06-07 17:15:12 +00:00
tmux . until { | lines | lines [ - 2 ] . include? '/4' }
2015-11-08 16:42:01 +00:00
tmux . send_keys :Enter
2016-03-06 03:46:28 +00:00
tmux . prepare
2015-11-08 16:42:01 +00:00
readonce
2017-08-04 14:29:02 +00:00
assert_equal [ %( foo'bar/foo'bar ) ,
%( foo'bar foo"bar foo$bar/foo'bar foo"bar foo$bar ) ,
%( foo'bar foo"bar foobar/foo'bar foo"bar foobar ) ] ,
File . readlines ( output ) . map ( & :chomp )
2015-11-08 16:42:01 +00:00
ensure
2017-08-04 14:29:02 +00:00
begin
File . unlink output
rescue
nil
end
2015-11-08 16:42:01 +00:00
end
2017-01-27 07:38:42 +00:00
def test_execute_plus_flag
2017-08-04 14:29:02 +00:00
output = tempname + '.tmp'
begin
File . unlink output
rescue
nil
end
writelines tempname , [ 'foo bar' , '123 456' ]
2017-01-27 07:38:42 +00:00
2017-08-04 14:29:02 +00:00
tmux . send_keys " cat #{ tempname } | #{ FZF } --multi --bind 'x:execute-silent(echo {+}/{}/{+2}/{2} >> #{ output } )' " , :Enter
2017-01-27 07:38:42 +00:00
execute = lambda do
tmux . send_keys 'x' , 'y'
tmux . until { | lines | lines [ - 2 ] . include? '0/2' }
tmux . send_keys :BSpace
tmux . until { | lines | lines [ - 2 ] . include? '2/2' }
end
tmux . until { | lines | lines [ - 2 ] . include? '2/2' }
execute . call
tmux . send_keys :Up
tmux . send_keys :Tab
execute . call
tmux . send_keys :Tab
execute . call
tmux . send_keys :Enter
tmux . prepare
readonce
assert_equal [
2017-08-04 14:29:02 +00:00
%( foo bar/foo bar/bar/bar ) ,
%( 123 456/foo bar/456/bar ) ,
%( 123 456 foo bar/foo bar/456 bar/bar )
2017-01-27 07:38:42 +00:00
] , File . readlines ( output ) . map ( & :chomp )
rescue
2017-08-04 14:29:02 +00:00
begin
File . unlink output
rescue
nil
end
2017-01-27 07:38:42 +00:00
end
2016-02-02 19:46:02 +00:00
def test_execute_shell
# Custom script to use as $SHELL
output = tempname + '.out'
2017-08-04 14:29:02 +00:00
begin
File . unlink output
rescue
nil
end
writelines tempname ,
[ '#!/usr/bin/env bash' , " echo $1 / $2 > #{ output } " , 'sync' ]
2016-02-02 19:46:02 +00:00
system " chmod +x #{ tempname } "
tmux . send_keys " echo foo | SHELL= #{ tempname } fzf --bind 'enter:execute:{}bar' " , :Enter
tmux . until { | lines | lines [ - 2 ] . include? '1/1' }
tmux . send_keys :Enter
2016-03-01 18:23:32 +00:00
tmux . until { | lines | lines [ - 2 ] . include? '1/1' }
2016-02-02 19:46:02 +00:00
tmux . send_keys 'C-c'
2016-03-01 18:23:32 +00:00
tmux . prepare
2016-06-07 17:16:07 +00:00
assert_equal [ " -c / 'foo'bar " ] , File . readlines ( output ) . map ( & :chomp )
2016-02-02 19:46:02 +00:00
ensure
2017-08-04 14:29:02 +00:00
begin
File . unlink output
rescue
nil
end
2016-02-02 19:46:02 +00:00
end
2015-06-16 14:14:57 +00:00
def test_cycle
tmux . send_keys " seq 8 | #{ fzf :cycle } " , :Enter
tmux . until { | lines | lines [ - 2 ] . include? '8/8' }
tmux . send_keys :Down
tmux . until { | lines | lines [ - 10 ] . start_with? '>' }
tmux . send_keys :Down
tmux . until { | lines | lines [ - 9 ] . start_with? '>' }
2017-05-24 04:20:13 +00:00
tmux . send_keys :Up
2015-06-16 14:14:57 +00:00
tmux . until { | lines | lines [ - 10 ] . start_with? '>' }
tmux . send_keys :PgUp
2017-05-24 04:20:13 +00:00
tmux . until { | lines | lines [ - 10 ] . start_with? '>' }
2015-06-16 14:14:57 +00:00
tmux . send_keys :Up
tmux . until { | lines | lines [ - 3 ] . start_with? '>' }
tmux . send_keys :PgDn
2017-05-24 04:20:13 +00:00
tmux . until { | lines | lines [ - 3 ] . start_with? '>' }
tmux . send_keys :Down
2015-06-16 14:14:57 +00:00
tmux . until { | lines | lines [ - 10 ] . start_with? '>' }
end
2015-07-22 04:45:38 +00:00
def test_header_lines
tmux . send_keys " seq 100 | #{ fzf '--header-lines=10 -q 5' } " , :Enter
2 . times do
tmux . until do | lines |
lines [ - 2 ] . include? ( '/90' ) &&
2017-08-04 14:29:02 +00:00
lines [ - 3 ] == ' 1' &&
lines [ - 4 ] == ' 2' &&
lines [ - 13 ] == '> 50'
2015-07-22 04:45:38 +00:00
end
tmux . send_keys :Down
end
tmux . send_keys :Enter
2016-04-16 05:02:43 +00:00
assert_equal '50' , readonce . chomp
2015-07-22 04:45:38 +00:00
end
def test_header_lines_reverse
tmux . send_keys " seq 100 | #{ fzf '--header-lines=10 -q 5 --reverse' } " , :Enter
2 . times do
tmux . until do | lines |
lines [ 1 ] . include? ( '/90' ) &&
2017-08-04 14:29:02 +00:00
lines [ 2 ] == ' 1' &&
lines [ 3 ] == ' 2' &&
lines [ 12 ] == '> 50'
2015-07-22 04:45:38 +00:00
end
tmux . send_keys :Up
end
tmux . send_keys :Enter
2016-04-16 05:02:43 +00:00
assert_equal '50' , readonce . chomp
2015-07-22 04:45:38 +00:00
end
2018-06-09 16:41:50 +00:00
def test_header_lines_reverse_list
tmux . send_keys " seq 100 | #{ fzf '--header-lines=10 -q 5 --layout=reverse-list' } " , :Enter
2 . times do
tmux . until do | lines |
lines [ 0 ] == '> 50' &&
lines [ - 4 ] == ' 2' &&
lines [ - 3 ] == ' 1' &&
lines [ - 2 ] . include? ( '/90' )
end
tmux . send_keys :Up
end
tmux . send_keys :Enter
assert_equal '50' , readonce . chomp
end
2015-07-22 04:45:38 +00:00
def test_header_lines_overflow
tmux . send_keys " seq 100 | #{ fzf '--header-lines=200' } " , :Enter
2015-07-22 12:22:59 +00:00
tmux . until do | lines |
lines [ - 2 ] . include? ( '0/0' ) &&
2017-08-04 14:29:02 +00:00
lines [ - 3 ] . include? ( ' 1' )
2015-07-22 12:22:59 +00:00
end
2015-07-22 04:45:38 +00:00
tmux . send_keys :Enter
assert_equal '' , readonce . chomp
end
2015-07-22 12:24:02 +00:00
def test_header_lines_with_nth
2017-08-04 14:29:02 +00:00
tmux . send_keys " seq 100 | #{ fzf '--header-lines 5 --with-nth 1,1,1,1,1' } " , :Enter
2015-07-22 12:24:02 +00:00
tmux . until do | lines |
lines [ - 2 ] . include? ( '95/95' ) &&
2017-08-04 14:29:02 +00:00
lines [ - 3 ] == ' 11111' &&
lines [ - 7 ] == ' 55555' &&
lines [ - 8 ] == '> 66666'
2015-07-22 12:24:02 +00:00
end
tmux . send_keys :Enter
assert_equal '6' , readonce . chomp
end
2015-09-15 10:04:53 +00:00
def test_header
2020-02-28 11:06:38 +00:00
tmux . send_keys " seq 100 | #{ fzf " --header \" $(head -5 #{ FILE } ) \" " } " , :Enter
2015-11-30 08:32:16 +00:00
header = File . readlines ( FILE ) . take ( 5 ) . map ( & :strip )
2015-07-22 04:45:38 +00:00
tmux . until do | lines |
lines [ - 2 ] . include? ( '100/100' ) &&
2018-06-09 16:41:50 +00:00
lines [ - 7 .. - 3 ] . map ( & :strip ) == header &&
lines [ - 8 ] == '> 1'
2015-07-22 04:45:38 +00:00
end
end
2015-09-15 10:04:53 +00:00
def test_header_reverse
2020-02-28 11:06:38 +00:00
tmux . send_keys " seq 100 | #{ fzf " --header \" $(head -5 #{ FILE } ) \" --reverse " } " , :Enter
2015-11-30 08:32:16 +00:00
header = File . readlines ( FILE ) . take ( 5 ) . map ( & :strip )
2015-07-22 04:45:38 +00:00
tmux . until do | lines |
lines [ 1 ] . include? ( '100/100' ) &&
2018-06-09 16:41:50 +00:00
lines [ 2 .. 6 ] . map ( & :strip ) == header &&
lines [ 7 ] == '> 1'
end
end
def test_header_reverse_list
2020-02-28 11:06:38 +00:00
tmux . send_keys " seq 100 | #{ fzf " --header \" $(head -5 #{ FILE } ) \" --layout=reverse-list " } " , :Enter
2018-06-09 16:41:50 +00:00
header = File . readlines ( FILE ) . take ( 5 ) . map ( & :strip )
tmux . until do | lines |
lines [ - 2 ] . include? ( '100/100' ) &&
lines [ - 7 .. - 3 ] . map ( & :strip ) == header &&
lines [ 0 ] == '> 1'
2015-07-22 04:45:38 +00:00
end
end
2015-09-15 10:04:53 +00:00
def test_header_and_header_lines
2020-02-28 11:06:38 +00:00
tmux . send_keys " seq 100 | #{ fzf " --header-lines 10 --header \" $(head -5 #{ FILE } ) \" " } " , :Enter
2015-11-30 08:32:16 +00:00
header = File . readlines ( FILE ) . take ( 5 ) . map ( & :strip )
2015-09-15 10:04:53 +00:00
tmux . until do | lines |
lines [ - 2 ] . include? ( '90/90' ) &&
2017-08-04 14:29:02 +00:00
lines [ - 7 ... - 2 ] . map ( & :strip ) == header &&
lines [ - 17 ... - 7 ] . map ( & :strip ) == ( 1 .. 10 ) . map ( & :to_s ) . reverse
2015-09-15 10:04:53 +00:00
end
end
def test_header_and_header_lines_reverse
2020-02-28 11:06:38 +00:00
tmux . send_keys " seq 100 | #{ fzf " --reverse --header-lines 10 --header \" $(head -5 #{ FILE } ) \" " } " , :Enter
2015-11-30 08:32:16 +00:00
header = File . readlines ( FILE ) . take ( 5 ) . map ( & :strip )
2015-09-15 10:04:53 +00:00
tmux . until do | lines |
lines [ 1 ] . include? ( '90/90' ) &&
2017-08-04 14:29:02 +00:00
lines [ 2 ... 7 ] . map ( & :strip ) == header &&
lines [ 7 ... 17 ] . map ( & :strip ) == ( 1 .. 10 ) . map ( & :to_s )
2015-09-15 10:04:53 +00:00
end
end
2018-06-09 16:41:50 +00:00
def test_header_and_header_lines_reverse_list
2020-02-28 11:06:38 +00:00
tmux . send_keys " seq 100 | #{ fzf " --layout=reverse-list --header-lines 10 --header \" $(head -5 #{ FILE } ) \" " } " , :Enter
2018-06-09 16:41:50 +00:00
header = File . readlines ( FILE ) . take ( 5 ) . map ( & :strip )
tmux . until do | lines |
lines [ - 2 ] . include? ( '90/90' ) &&
lines [ - 7 ... - 2 ] . map ( & :strip ) == header &&
lines [ - 17 ... - 7 ] . map ( & :strip ) == ( 1 .. 10 ) . map ( & :to_s ) . reverse
end
end
2016-05-12 15:44:27 +00:00
def test_cancel
2017-08-04 14:29:02 +00:00
tmux . send_keys " seq 10 | #{ fzf '--bind 2:cancel' } " , :Enter
2015-07-23 12:05:33 +00:00
tmux . until { | lines | lines [ - 2 ] . include? ( '10/10' ) }
2015-07-22 13:56:53 +00:00
tmux . send_keys '123'
2015-07-23 12:05:33 +00:00
tmux . until { | lines | lines [ - 1 ] == '> 3' && lines [ - 2 ] . include? ( '1/10' ) }
tmux . send_keys 'C-y' , 'C-y'
tmux . until { | lines | lines [ - 1 ] == '> 311' }
tmux . send_keys 2
2015-07-22 13:56:53 +00:00
tmux . until { | lines | lines [ - 1 ] == '>' }
tmux . send_keys 2
tmux . prepare
end
2015-07-26 14:02:04 +00:00
def test_margin
2017-08-04 14:29:02 +00:00
tmux . send_keys " yes | head -1000 | #{ fzf '--margin 5,3' } " , :Enter
2015-07-26 14:02:04 +00:00
tmux . until { | lines | lines [ 4 ] == '' && lines [ 5 ] == ' y' }
tmux . send_keys :Enter
end
def test_margin_reverse
2017-08-04 14:29:02 +00:00
tmux . send_keys " seq 1000 | #{ fzf '--margin 7,5 --reverse' } " , :Enter
2015-07-26 14:02:04 +00:00
tmux . until { | lines | lines [ 1 + 7 ] == ' 1000/1000' }
tmux . send_keys :Enter
end
2018-06-09 16:41:50 +00:00
def test_margin_reverse_list
tmux . send_keys " yes | head -1000 | #{ fzf '--margin 5,3 --layout=reverse-list' } " , :Enter
tmux . until { | lines | lines [ 4 ] == '' && lines [ 5 ] == ' > y' }
tmux . send_keys :Enter
end
2015-11-30 08:35:03 +00:00
def test_tabstop
writelines tempname , [ " f \t oo \t ba \t r \t baz \t barfooq \t ux " ]
{
1 = > '> f oo ba r baz barfooq ux' ,
2 = > '> f oo ba r baz barfooq ux' ,
3 = > '> f oo ba r baz barfooq ux' ,
4 = > '> f oo ba r baz barfooq ux' ,
5 = > '> f oo ba r baz barfooq ux' ,
6 = > '> f oo ba r baz barfooq ux' ,
7 = > '> f oo ba r baz barfooq ux' ,
8 = > '> f oo ba r baz barfooq ux' ,
2017-08-04 14:29:02 +00:00
9 = > '> f oo ba r baz barfooq ux'
2015-11-30 08:35:03 +00:00
} . each do | ts , exp |
tmux . prepare
2017-08-04 14:29:02 +00:00
tmux . send_keys %( cat #{ tempname } | fzf --tabstop= #{ ts } ) , :Enter
tmux . until ( true ) do | lines |
exp . start_with? lines [ - 3 ] . to_s . strip . sub ( / \ . \ .$ / , '' )
end
2015-11-30 08:35:03 +00:00
tmux . send_keys :Enter
end
end
2017-08-04 14:29:02 +00:00
def test_with_nth_basic
2015-08-26 14:35:31 +00:00
writelines tempname , [ 'hello world ' , 'byebye' ]
2017-08-04 14:29:02 +00:00
assert_equal (
'hello world ' ,
` #{ FZF } -f"^he hehe" -x -n 2.. --with-nth 2,1,1 < #{ tempname } ` . chomp
)
2015-08-26 14:35:31 +00:00
end
def test_with_nth_ansi
writelines tempname , [ " \x1b [33mhello \x1b [34;1mworld \x1b [m " , 'byebye' ]
2017-08-04 14:29:02 +00:00
assert_equal (
'hello world ' ,
` #{ FZF } -f"^he hehe" -x -n 2.. --with-nth 2,1,1 --ansi < #{ tempname } ` . chomp
)
2015-08-26 14:35:31 +00:00
end
2015-08-28 12:23:10 +00:00
def test_with_nth_no_ansi
src = " \x1b [33mhello \x1b [34;1mworld \x1b [m "
writelines tempname , [ src , 'byebye' ]
2017-08-04 14:29:02 +00:00
assert_equal (
src ,
` #{ FZF } -fhehe -x -n 2.. --with-nth 2,1,1 --no-ansi < #{ tempname } ` . chomp
)
2015-08-28 12:23:10 +00:00
end
2015-09-15 04:21:51 +00:00
def test_exit_0_exit_code
` echo foo | #{ FZF } -q bar -0 `
2017-08-04 14:29:02 +00:00
assert_equal 1 , $CHILD_STATUS . exitstatus
2015-09-15 04:21:51 +00:00
end
def test_invalid_option
lines = ` #{ FZF } --foobar 2>&1 `
2017-08-04 14:29:02 +00:00
assert_equal 2 , $CHILD_STATUS . exitstatus
2015-09-15 04:21:51 +00:00
assert lines . include? ( 'unknown option: --foobar' ) , lines
end
def test_filter_exitstatus
# filter / streaming filter
2017-08-04 14:29:02 +00:00
[ '' , '--no-sort' ] . each do | opts |
2015-09-15 04:21:51 +00:00
assert ` echo foo | #{ FZF } -f foo #{ opts } ` . include? ( 'foo' )
2017-08-04 14:29:02 +00:00
assert_equal 0 , $CHILD_STATUS . exitstatus
2015-09-15 04:21:51 +00:00
assert ` echo foo | #{ FZF } -f bar #{ opts } ` . empty?
2017-08-04 14:29:02 +00:00
assert_equal 1 , $CHILD_STATUS . exitstatus
2015-09-15 04:21:51 +00:00
end
end
def test_exitstatus_empty
{ '99' = > '0' , '999' = > '1' } . each do | query , status |
2020-02-28 11:06:38 +00:00
tmux . send_keys " seq 100 | #{ FZF } -q #{ query } ; echo --$?-- " , :Enter
2015-09-15 04:21:51 +00:00
tmux . until { | lines | lines [ - 2 ] =~ %r{ [10]/100 } }
tmux . send_keys :Enter
tmux . until { | lines | lines . last . include? " -- #{ status } -- " }
end
end
2015-11-03 13:49:32 +00:00
def test_default_extended
assert_equal '100' , ` seq 100 | #{ FZF } -f "1 00$" ` . chomp
assert_equal '' , ` seq 100 | #{ FZF } -f "1 00$" +x ` . chomp
end
def test_exact
assert_equal 4 , ` seq 123 | #{ FZF } -f 13 ` . lines . length
assert_equal 2 , ` seq 123 | #{ FZF } -f 13 -e ` . lines . length
assert_equal 4 , ` seq 123 | #{ FZF } -f 13 +e ` . lines . length
end
2015-11-09 16:50:41 +00:00
def test_or_operator
assert_equal %w[ 1 5 10 ] , ` seq 10 | #{ FZF } -f "1 | 5" ` . lines . map ( & :chomp )
assert_equal %w[ 1 10 2 3 4 5 6 7 8 9 ] ,
2017-08-04 14:29:02 +00:00
` seq 10 | #{ FZF } -f '1 | !1' ` . lines . map ( & :chomp )
2015-11-09 16:50:41 +00:00
end
2016-03-01 18:06:21 +00:00
def test_hscroll_off
2017-08-04 14:29:02 +00:00
writelines tempname , [ '=' * 10_000 + '0123456789' ]
2016-03-01 18:06:21 +00:00
[ 0 , 3 , 6 ] . each do | off |
tmux . prepare
tmux . send_keys " #{ FZF } --hscroll-off= #{ off } -q 0 < #{ tempname } " , :Enter
tmux . until { | lines | lines [ - 3 ] . end_with? ( ( 0 .. off ) . to_a . join + '..' ) }
tmux . send_keys '9'
tmux . until { | lines | lines [ - 3 ] . end_with? '789' }
tmux . send_keys :Enter
end
end
2016-04-23 18:30:51 +00:00
def test_partial_caching
tmux . send_keys 'seq 1000 | fzf -e' , :Enter
tmux . until { | lines | lines [ - 2 ] == ' 1000/1000' }
tmux . send_keys 11
tmux . until { | lines | lines [ - 2 ] == ' 19/1000' }
tmux . send_keys 'C-a' , " ' "
tmux . until { | lines | lines [ - 2 ] == ' 28/1000' }
tmux . send_keys :Enter
end
2016-05-17 17:06:52 +00:00
def test_jump
tmux . send_keys " seq 1000 | #{ fzf " --multi --jump-labels 12345 --bind 'ctrl-j:jump' " } " , :Enter
tmux . until { | lines | lines [ - 2 ] == ' 1000/1000' }
tmux . send_keys 'C-j'
tmux . until { | lines | lines [ - 7 ] == '5 5' }
tmux . until { | lines | lines [ - 8 ] == ' 6' }
tmux . send_keys '5'
tmux . until { | lines | lines [ - 7 ] == '> 5' }
tmux . send_keys :Tab
tmux . until { | lines | lines [ - 7 ] == ' >5' }
tmux . send_keys 'C-j'
tmux . until { | lines | lines [ - 7 ] == '5>5' }
tmux . send_keys '2'
tmux . until { | lines | lines [ - 4 ] == '> 2' }
tmux . send_keys :Tab
tmux . until { | lines | lines [ - 4 ] == ' >2' }
tmux . send_keys 'C-j'
tmux . until { | lines | lines [ - 7 ] == '5>5' }
# Press any key other than jump labels to cancel jump
tmux . send_keys '6'
tmux . until { | lines | lines [ - 3 ] == '> 1' }
tmux . send_keys :Tab
tmux . until { | lines | lines [ - 3 ] == '>>1' }
tmux . send_keys :Enter
2017-08-04 14:29:02 +00:00
assert_equal %w[ 5 2 1 ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2016-05-17 17:06:52 +00:00
end
def test_jump_accept
tmux . send_keys " seq 1000 | #{ fzf " --multi --jump-labels 12345 --bind 'ctrl-j:jump-accept' " } " , :Enter
tmux . until { | lines | lines [ - 2 ] == ' 1000/1000' }
tmux . send_keys 'C-j'
tmux . until { | lines | lines [ - 7 ] == '5 5' }
tmux . send_keys '3'
assert_equal '3' , readonce . chomp
end
2020-02-17 01:19:03 +00:00
def test_pointer
pointer = '>>'
tmux . send_keys " seq 10 | #{ fzf " --pointer ' #{ pointer } ' " } " , :Enter
tmux . until { | lines | lines [ - 2 ] == ' 10/10' }
lines = tmux . capture
# Assert that specified pointer is displayed
assert_equal " #{ pointer } 1 " , lines [ - 3 ]
end
def test_pointer_with_jump
pointer = '>>'
tmux . send_keys " seq 10 | #{ fzf " --multi --jump-labels 12345 --bind 'ctrl-j:jump' --pointer ' #{ pointer } ' " } " , :Enter
tmux . until { | lines | lines [ - 2 ] == ' 10/10' }
tmux . send_keys 'C-j'
# Correctly padded jump label should appear
tmux . until { | lines | lines [ - 7 ] == '5 5' }
tmux . until { | lines | lines [ - 8 ] == ' 6' }
tmux . send_keys '5'
lines = tmux . capture
# Assert that specified pointer is displayed
assert_equal " #{ pointer } 5 " , lines [ - 7 ]
end
def test_marker
marker = '>>'
tmux . send_keys " seq 10 | #{ fzf " --multi --marker ' #{ marker } ' " } " , :Enter
tmux . until { | lines | lines [ - 2 ] == ' 10/10' }
tmux . send_keys :BTab
lines = tmux . capture
# Assert that specified marker is displayed
assert_equal " #{ marker } 1 " , lines [ - 3 ]
end
2016-06-11 10:59:12 +00:00
def test_preview
2017-08-04 14:29:02 +00:00
tmux . send_keys %( seq 1000 | sed s/^2$// | #{ FZF } -m --preview 'sleep 0.2; echo {{}-{+}}' --bind ?:toggle-preview ) , :Enter
2016-06-11 10:59:12 +00:00
tmux . until { | lines | lines [ 1 ] . include? ( ' {1-1}' ) }
2016-06-15 04:03:42 +00:00
tmux . send_keys :Up
tmux . until { | lines | lines [ 1 ] . include? ( ' {-}' ) }
2016-06-11 10:59:12 +00:00
tmux . send_keys '555'
tmux . until { | lines | lines [ 1 ] . include? ( ' {555-555}' ) }
tmux . send_keys '?'
tmux . until { | lines | ! lines [ 1 ] . include? ( ' {555-555}' ) }
tmux . send_keys '?'
tmux . until { | lines | lines [ 1 ] . include? ( ' {555-555}' ) }
2016-06-15 04:03:42 +00:00
tmux . send_keys :BSpace
tmux . until { | lines | lines [ - 2 ] . start_with? ' 28/1000' }
tmux . send_keys 'foobar'
tmux . until { | lines | ! lines [ 1 ] . include? ( '{' ) }
2017-01-27 07:38:42 +00:00
tmux . send_keys 'C-u'
tmux . until { | lines | lines . match_count == 1000 }
tmux . until { | lines | lines [ 1 ] . include? ( ' {1-1}' ) }
tmux . send_keys :BTab
tmux . until { | lines | lines [ 1 ] . include? ( ' {-1}' ) }
tmux . send_keys :BTab
tmux . until { | lines | lines [ 1 ] . include? ( ' {3-1 }' ) }
tmux . send_keys :BTab
tmux . until { | lines | lines [ 1 ] . include? ( ' {4-1 3}' ) }
tmux . send_keys :BTab
tmux . until { | lines | lines [ 1 ] . include? ( ' {5-1 3 4}' ) }
2016-06-11 10:59:12 +00:00
end
def test_preview_hidden
2020-02-28 11:06:38 +00:00
tmux . send_keys %( seq 1000 | #{ FZF } --preview 'echo {{}-{}-$FZF_PREVIEW_LINES-$FZF_PREVIEW_COLUMNS}' --preview-window down:1:hidden --bind ?:toggle-preview ) , :Enter
2016-06-11 10:59:12 +00:00
tmux . until { | lines | lines [ - 1 ] == '>' }
tmux . send_keys '?'
2017-12-01 03:04:01 +00:00
tmux . until { | lines | lines [ - 2 ] =~ / {1-1-1-[0-9]+} / }
2016-06-11 10:59:12 +00:00
tmux . send_keys '555'
2017-12-01 03:04:01 +00:00
tmux . until { | lines | lines [ - 2 ] =~ / {555-555-1-[0-9]+} / }
2016-06-11 10:59:12 +00:00
tmux . send_keys '?'
tmux . until { | lines | lines [ - 1 ] == '> 555' }
end
2017-01-23 15:23:16 +00:00
def test_preview_size_0
2017-08-04 14:29:02 +00:00
begin
File . unlink tempname
rescue
nil
end
tmux . send_keys %( seq 100 | #{ FZF } --reverse --preview 'echo {} >> #{ tempname } ; echo ' --preview-window 0 ) , :Enter
2017-01-23 15:23:16 +00:00
tmux . until { | lines | lines . item_count == 100 && lines [ 1 ] == ' 100/100' && lines [ 2 ] == '> 1' }
2017-08-04 14:29:02 +00:00
tmux . until { | _ | %w[ 1 ] == File . readlines ( tempname ) . map ( & :chomp ) }
2017-01-23 15:23:16 +00:00
tmux . send_keys :Down
tmux . until { | lines | lines [ 3 ] == '> 2' }
2017-08-04 14:29:02 +00:00
tmux . until { | _ | %w[ 1 2 ] == File . readlines ( tempname ) . map ( & :chomp ) }
2017-01-23 15:23:16 +00:00
tmux . send_keys :Down
tmux . until { | lines | lines [ 4 ] == '> 3' }
2017-08-04 14:29:02 +00:00
tmux . until { | _ | %w[ 1 2 3 ] == File . readlines ( tempname ) . map ( & :chomp ) }
2017-01-23 15:23:16 +00:00
end
2017-03-04 05:26:47 +00:00
2018-06-09 16:40:22 +00:00
def test_preview_flags
tmux . send_keys %( seq 10 | sed 's/^/:: /; s/$/ /' |
2019-02-18 16:12:57 +00:00
#{FZF} --multi --preview 'echo {{2}/{s2}/{+2}/{+s2}/{q}/{n}/{+n}}'), :Enter
tmux . until { | lines | lines [ 1 ] . include? ( '{1/1 /1/1 //0/0}' ) }
2018-06-09 16:40:22 +00:00
tmux . send_keys '123'
2019-02-18 16:12:57 +00:00
tmux . until { | lines | lines [ 1 ] . include? ( '{////123//}' ) }
2018-06-09 16:40:22 +00:00
tmux . send_keys 'C-u' , '1'
tmux . until { | lines | lines . match_count == 2 }
2019-02-18 16:12:57 +00:00
tmux . until { | lines | lines [ 1 ] . include? ( '{1/1 /1/1 /1/0/0}' ) }
2018-06-09 16:40:22 +00:00
tmux . send_keys :BTab
2019-02-18 16:12:57 +00:00
tmux . until { | lines | lines [ 1 ] . include? ( '{10/10 /1/1 /1/9/0}' ) }
2018-06-09 16:40:22 +00:00
tmux . send_keys :BTab
2019-02-18 16:12:57 +00:00
tmux . until { | lines | lines [ 1 ] . include? ( '{10/10 /1 10/1 10 /1/9/0 9}' ) }
2018-06-09 16:40:22 +00:00
tmux . send_keys '2'
2019-02-18 16:12:57 +00:00
tmux . until { | lines | lines [ 1 ] . include? ( '{//1 10/1 10 /12//0 9}' ) }
2018-06-09 16:40:22 +00:00
tmux . send_keys '3'
2019-02-18 16:12:57 +00:00
tmux . until { | lines | lines [ 1 ] . include? ( '{//1 10/1 10 /123//0 9}' ) }
2018-06-09 16:40:22 +00:00
end
2019-10-27 14:50:12 +00:00
def test_preview_file
tmux . send_keys %[ (echo foo bar; echo bar foo) | #{ FZF } --multi --preview 'cat {+f} {+f2} {+nf} {+fn}' --print0 ] , :Enter
tmux . until { | lines | lines [ 1 ] . include? ( 'foo barbar00' ) }
tmux . send_keys :BTab
tmux . until { | lines | lines [ 1 ] . include? ( 'foo barbar00' ) }
tmux . send_keys :BTab
tmux . until { | lines | lines [ 1 ] . include? ( 'foo barbar foobarfoo0101' ) }
end
2018-06-09 16:40:22 +00:00
def test_preview_q_no_match
tmux . send_keys %( : | #{ FZF } --preview 'echo foo {q}' ) , :Enter
tmux . until { | lines | lines . match_count == 0 }
tmux . until { | lines | ! lines [ 1 ] . include? ( 'foo' ) }
tmux . send_keys 'bar'
tmux . until { | lines | lines [ 1 ] . include? ( 'foo bar' ) }
tmux . send_keys 'C-u'
tmux . until { | lines | ! lines [ 1 ] . include? ( 'foo' ) }
end
2018-12-05 09:45:55 +00:00
def test_preview_q_no_match_with_initial_query
tmux . send_keys %( : | #{ FZF } --preview 'echo foo {q}{q}' --query foo ) , :Enter
tmux . until { | lines | lines . match_count == 0 }
tmux . until { | lines | lines [ 1 ] . include? ( 'foofoo' ) }
end
2017-03-04 05:26:47 +00:00
def test_no_clear
2017-07-18 11:50:38 +00:00
tmux . send_keys " seq 10 | fzf --no-clear --inline-info --height 5 > #{ tempname } " , :Enter
prompt = '> < 10/10'
2017-03-04 05:26:47 +00:00
tmux . until { | lines | lines [ - 1 ] == prompt }
tmux . send_keys :Enter
2017-07-18 11:50:38 +00:00
tmux . until { | _ | %w[ 1 ] == File . readlines ( tempname ) . map ( & :chomp ) }
tmux . until { | lines | lines [ - 1 ] == prompt }
2017-03-04 05:26:47 +00:00
end
2017-05-22 08:07:05 +00:00
2019-11-14 15:39:29 +00:00
def test_info_hidden
tmux . send_keys 'seq 10 | fzf --info=hidden' , :Enter
tmux . until { | lines | lines [ - 2 ] == '> 1' }
end
2017-05-22 08:07:05 +00:00
def test_change_top
2017-08-04 14:29:02 +00:00
tmux . send_keys %( seq 1000 | #{ FZF } --bind change:top ) , :Enter
2017-05-22 08:07:05 +00:00
tmux . until { | lines | lines . match_count == 1000 }
tmux . send_keys :Up
tmux . until { | lines | lines [ - 4 ] == '> 2' }
tmux . send_keys 1
tmux . until { | lines | lines [ - 3 ] == '> 1' }
tmux . send_keys :Up
tmux . until { | lines | lines [ - 4 ] == '> 10' }
tmux . send_keys 1
tmux . until { | lines | lines [ - 3 ] == '> 11' }
tmux . send_keys :Enter
end
2017-07-27 16:39:25 +00:00
2017-12-01 17:27:02 +00:00
def test_accept_non_empty
tmux . send_keys %( seq 1000 | #{ fzf '--print-query --bind enter:accept-non-empty' } ) , :Enter
tmux . until { | lines | lines . match_count == 1000 }
tmux . send_keys 'foo'
tmux . until { | lines | lines [ - 2 ] . include? '0/1000' }
# fzf doesn't exit since there's no selection
tmux . send_keys :Enter
tmux . until { | lines | lines [ - 2 ] . include? '0/1000' }
tmux . send_keys 'C-u'
tmux . until { | lines | lines [ - 2 ] . include? '1000/1000' }
tmux . send_keys '999'
tmux . until { | lines | lines [ - 2 ] . include? '1/1000' }
tmux . send_keys :Enter
assert_equal %w[ 999 999 ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
end
def test_accept_non_empty_with_multi_selection
tmux . send_keys %( seq 1000 | #{ fzf '-m --print-query --bind enter:accept-non-empty' } ) , :Enter
tmux . until { | lines | lines . match_count == 1000 }
tmux . send_keys :Tab
tmux . until { | lines | lines [ - 2 ] . include? '1000/1000 (1)' }
tmux . send_keys 'foo'
tmux . until { | lines | lines [ - 2 ] . include? '0/1000' }
# fzf will exit in this case even though there's no match for the current query
tmux . send_keys :Enter
assert_equal %w[ foo 1 ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
end
def test_accept_non_empty_with_empty_list
tmux . send_keys %( : | #{ fzf '-q foo --print-query --bind enter:accept-non-empty' } ) , :Enter
tmux . until { | lines | lines [ - 2 ] . strip == '0/0' }
tmux . send_keys :Enter
# fzf will exit anyway since input list is empty
assert_equal %w[ foo ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
end
2017-07-27 16:39:25 +00:00
def test_preview_update_on_select
tmux . send_keys ( %( seq 10 | fzf -m --preview 'echo {+}' --bind a:toggle-all ) ,
:Enter )
tmux . until { | lines | lines . item_count == 10 }
tmux . send_keys 'a'
tmux . until { | lines | lines . any? { | line | line . include? '1 2 3 4 5' } }
tmux . send_keys 'a'
2017-08-04 14:29:02 +00:00
tmux . until { | lines | lines . none? { | line | line . include? '1 2 3 4 5' } }
2017-07-27 16:39:25 +00:00
end
2017-08-09 14:25:32 +00:00
def test_escaped_meta_characters
input = << ~ EOF
foo ^ bar
foo $bar
foo! bar
foo ' bar
foo bar
bar foo
EOF
writelines tempname , input . lines . map ( & :chomp )
assert_equal input . lines . count , ` #{ FZF } -f'foo bar' < #{ tempname } ` . lines . count
2017-08-11 04:09:33 +00:00
assert_equal input . lines . count - 1 , ` #{ FZF } -f'^foo bar$' < #{ tempname } ` . lines . count
2017-08-09 14:25:32 +00:00
assert_equal [ 'foo bar' ] , ` #{ FZF } -f'foo \\ bar' < #{ tempname } ` . lines . map ( & :chomp )
assert_equal [ 'foo bar' ] , ` #{ FZF } -f'^foo \\ bar$' < #{ tempname } ` . lines . map ( & :chomp )
2017-08-11 04:09:33 +00:00
assert_equal input . lines . count - 1 , ` #{ FZF } -f'!^foo \\ bar$' < #{ tempname } ` . lines . count
2017-08-10 03:40:53 +00:00
end
2018-12-19 14:05:29 +00:00
def test_inverse_only_search_should_not_sort_the_result
# Filter
assert_equal ( %w[ aaaaa b ccc ] ,
` printf '%s \n ' aaaaa b ccc BAD | #{ FZF } -f '!bad' ` . lines . map ( & :chomp ) )
# Interactive
tmux . send_keys ( %[ printf '%s \n ' aaaaa b ccc BAD | #{ FZF } -q '!bad' ] , :Enter )
tmux . until { | lines | lines . item_count == 4 && lines . match_count == 3 }
tmux . until { | lines | lines [ - 3 ] == '> aaaaa' }
tmux . until { | lines | lines [ - 4 ] == ' b' }
tmux . until { | lines | lines [ - 5 ] == ' ccc' }
end
2018-12-22 02:52:18 +00:00
def test_preview_correct_tab_width_after_ansi_reset_code
writelines tempname , [ " \x1b [31m+ \x1b [m \t \x1b [32mgreen " ]
tmux . send_keys " #{ FZF } --preview 'cat #{ tempname } ' " , :Enter
tmux . until { | lines | lines [ 1 ] . include? ( '+ green' ) }
end
2019-11-10 04:13:45 +00:00
def test_phony
tmux . send_keys %( seq 1000 | #{ FZF } --query 333 --phony --preview 'echo {} {q}' ) , :Enter
tmux . until { | lines | lines . match_count == 1000 }
tmux . until { | lines | lines [ 1 ] . include? ( '1 333' ) }
tmux . send_keys 'foo'
tmux . until { | lines | lines . match_count == 1000 }
tmux . until { | lines | lines [ 1 ] . include? ( '1 333foo' ) }
end
def test_reload
2019-11-11 15:57:19 +00:00
tmux . send_keys %( seq 1000 | #{ FZF } --bind 'change:reload ( seq {q} ) ,a:reload ( seq 100 ) ,b:reload:seq 200' --header-lines 2 --multi 2 ) , :Enter
2019-11-11 15:10:24 +00:00
tmux . until { | lines | lines . match_count == 998 }
2019-11-10 04:13:45 +00:00
tmux . send_keys 'a'
2019-11-11 15:10:24 +00:00
tmux . until { | lines | lines . item_count == 98 && lines . match_count == 98 }
2019-11-10 04:13:45 +00:00
tmux . send_keys 'b'
2019-11-11 15:10:24 +00:00
tmux . until { | lines | lines . item_count == 198 && lines . match_count == 198 }
2019-11-11 15:57:19 +00:00
tmux . send_keys :Tab
tmux . until { | lines | lines [ - 2 ] . include? ( '(1/2)' ) }
2019-11-10 04:13:45 +00:00
tmux . send_keys '555'
2019-11-11 15:10:24 +00:00
tmux . until { | lines | lines . item_count == 553 && lines . match_count == 1 }
2019-11-11 15:57:19 +00:00
tmux . until { | lines | ! lines [ - 2 ] . include? ( '(1/2)' ) }
2019-11-10 04:13:45 +00:00
end
2019-12-06 13:34:30 +00:00
def test_reload_even_when_theres_no_match
tmux . send_keys %( : | #{ FZF } --bind 'space:reload ( seq 10 ) ' ) , :Enter
tmux . until { | lines | lines . item_count . zero? }
tmux . send_keys :Space
tmux . until { | lines | lines . item_count == 10 }
end
2019-12-06 13:34:45 +00:00
def test_clear_list_when_header_lines_changed_due_to_reload
tmux . send_keys %( seq 10 | #{ FZF } --header 0 --header-lines 3 --bind 'space:reload ( seq 1 ) ' ) , :Enter
tmux . until { | lines | lines . any? { | line | line . include? ( '9' ) } }
tmux . send_keys :Space
tmux . until { | lines | lines . none? { | line | line . include? ( '9' ) } }
end
2019-12-07 05:44:24 +00:00
def test_clear_query
tmux . send_keys %( : | #{ FZF } --query foo --bind space:clear-query ) , :Enter
tmux . until { | lines | lines . item_count . zero? }
tmux . until { | lines | lines . last . include? ( '> foo' ) }
tmux . send_keys 'C-a' , 'bar'
tmux . until { | lines | lines . last . include? ( '> barfoo' ) }
tmux . send_keys :Space
tmux . until { | lines | lines . last == '>' }
end
def test_clear_selection
tmux . send_keys %( seq 100 | #{ FZF } --multi --bind space:clear-selection ) , :Enter
tmux . until { | lines | lines . match_count == 100 }
tmux . send_keys :Tab
tmux . until { | lines | lines [ - 2 ] . include? ( '(1)' ) }
tmux . send_keys 'foo'
tmux . until { | lines | lines . match_count . zero? }
tmux . until { | lines | lines [ - 2 ] . include? ( '(1)' ) }
tmux . send_keys :Space
tmux . until { | lines | lines . match_count . zero? }
tmux . until { | lines | ! lines [ - 2 ] . include? ( '(1)' ) }
end
2020-02-27 17:38:32 +00:00
def test_backward_delete_char_eof
tmux . send_keys " seq 1000 | #{ fzf " --bind 'bs:backward-delete-char/eof' " } " , :Enter
tmux . until { | lines | lines [ - 2 ] == ' 1000/1000' }
tmux . send_keys '11'
tmux . until { | lines | lines [ - 1 ] == '> 11' }
tmux . send_keys :BSpace
tmux . until { | lines | lines [ - 1 ] == '> 1' }
tmux . send_keys :BSpace
tmux . until { | lines | lines [ - 1 ] == '>' }
tmux . send_keys :BSpace
tmux . prepare
end
2020-03-03 11:55:29 +00:00
def test_strip_xterm_osc_sequence
%W[ \x07 \x1b \\ ] . each do | esc |
writelines tempname , [ %( printf $1" \e ]4;3;rgb:aa/bb/cc #{ esc } "$2 ) ]
File . chmod ( 0 o755 , tempname )
tmux . prepare
tmux . send_keys (
%( echo foo bar | #{ FZF } --preview ' #{ tempname } {2} {1}' ) , :Enter
)
tmux . until { | lines | lines . any_include? ( 'bar foo' ) }
tmux . send_keys :Enter
end
end
2015-01-16 19:55:29 +00:00
end
2015-02-28 18:00:36 +00:00
module TestShell
def setup
2020-02-28 09:47:13 +00:00
@tmux = Tmux . new shell
tmux . prepare
2015-02-28 18:00:36 +00:00
end
def teardown
@tmux . kill
end
2017-08-04 14:29:02 +00:00
def set_var ( name , val )
2015-06-25 16:00:58 +00:00
tmux . prepare
tmux . send_keys " export #{ name } =' #{ val } ' " , :Enter
tmux . prepare
end
2017-08-04 14:29:02 +00:00
def unset_var ( name )
2017-01-07 16:30:31 +00:00
tmux . prepare
tmux . send_keys " unset #{ name } " , :Enter
2015-02-28 18:00:36 +00:00
tmux . prepare
end
2017-01-07 16:30:31 +00:00
def test_ctrl_t
2017-08-04 14:29:02 +00:00
set_var 'FZF_CTRL_T_COMMAND' , 'seq 100'
2017-01-07 16:30:31 +00:00
2017-08-04 14:29:02 +00:00
retries do
2017-01-09 04:22:24 +00:00
tmux . prepare
tmux . send_keys 'C-t'
tmux . until { | lines | lines . item_count == 100 }
end
2017-01-07 16:30:31 +00:00
tmux . send_keys :Tab , :Tab , :Tab
tmux . until { | lines | lines . any_include? ' (3)' }
tmux . send_keys :Enter
tmux . until { | lines | lines . any_include? '1 2 3' }
tmux . send_keys 'C-c'
2015-06-25 16:00:58 +00:00
end
2016-04-24 15:53:11 +00:00
def test_ctrl_t_unicode
2017-01-07 16:30:31 +00:00
writelines tempname , [ 'fzf-unicode 테스트1' , 'fzf-unicode 테스트2' ]
2017-08-04 14:29:02 +00:00
set_var 'FZF_CTRL_T_COMMAND' , " cat #{ tempname } "
2017-01-07 16:30:31 +00:00
2017-01-09 04:22:24 +00:00
retries do
tmux . prepare
tmux . send_keys 'echo ' , 'C-t'
tmux . until { | lines | lines . item_count == 2 }
end
2017-01-07 16:30:31 +00:00
tmux . send_keys 'fzf-unicode'
tmux . until { | lines | lines . match_count == 2 }
tmux . send_keys '1'
tmux . until { | lines | lines . match_count == 1 }
tmux . send_keys :Tab
tmux . until { | lines | lines . select_count == 1 }
tmux . send_keys :BSpace
tmux . until { | lines | lines . match_count == 2 }
tmux . send_keys '2'
tmux . until { | lines | lines . match_count == 1 }
tmux . send_keys :Tab
tmux . until { | lines | lines . select_count == 2 }
tmux . send_keys :Enter
2020-02-21 00:51:34 +00:00
tmux . until { | lines | lines . join . match ( / echo.*fzf-unicode.*1.*fzf-unicode.*2 / ) }
2016-04-24 15:53:11 +00:00
tmux . send_keys :Enter
2017-08-04 14:29:02 +00:00
tmux . until { | lines | lines . any_include? ( / ^fzf-unicode.*1.*fzf-unicode.*2 / ) }
2016-04-24 15:53:11 +00:00
end
2015-02-28 18:00:36 +00:00
def test_alt_c
2017-01-09 04:22:24 +00:00
lines = retries do
tmux . prepare
tmux . send_keys :Escape , :c
2018-06-01 09:21:34 +00:00
tmux . until { | lines | lines . match_count . positive? }
2017-01-09 04:22:24 +00:00
end
2017-01-07 16:30:31 +00:00
expected = lines . reverse . select { | l | l . start_with? '>' } . first [ 2 .. - 1 ]
tmux . send_keys :Enter
2015-02-28 18:00:36 +00:00
tmux . prepare
tmux . send_keys :pwd , :Enter
2015-04-25 01:54:47 +00:00
tmux . until { | lines | lines [ - 1 ] . end_with? ( expected ) }
2015-02-28 18:00:36 +00:00
end
2015-11-07 15:11:46 +00:00
def test_alt_c_command
set_var 'FZF_ALT_C_COMMAND' , 'echo /tmp'
tmux . prepare
tmux . send_keys 'cd /' , :Enter
2017-01-09 04:22:24 +00:00
retries do
tmux . prepare
tmux . send_keys :Escape , :c
2017-08-04 14:29:02 +00:00
tmux . until { | lines | lines . item_count == 1 }
2017-01-09 04:22:24 +00:00
end
2017-01-07 16:30:31 +00:00
tmux . send_keys :Enter
2015-11-07 15:11:46 +00:00
tmux . prepare
tmux . send_keys :pwd , :Enter
tmux . until { | lines | lines [ - 1 ] . end_with? '/tmp' }
end
2015-02-28 18:00:36 +00:00
def test_ctrl_r
tmux . prepare
tmux . send_keys 'echo 1st' , :Enter ; tmux . prepare
tmux . send_keys 'echo 2nd' , :Enter ; tmux . prepare
tmux . send_keys 'echo 3d' , :Enter ; tmux . prepare
tmux . send_keys 'echo 3rd' , :Enter ; tmux . prepare
2017-01-09 04:22:24 +00:00
tmux . send_keys 'echo 4th' , :Enter
retries do
tmux . prepare
tmux . send_keys 'C-r'
2018-06-01 09:21:34 +00:00
tmux . until { | lines | lines . match_count . positive? }
2017-01-09 04:22:24 +00:00
end
2017-03-03 03:20:01 +00:00
tmux . send_keys 'C-r'
2017-01-07 16:30:31 +00:00
tmux . send_keys '3d'
tmux . until { | lines | lines [ - 3 ] . end_with? 'echo 3rd' }
tmux . send_keys :Enter
2015-02-28 18:00:36 +00:00
tmux . until { | lines | lines [ - 1 ] == 'echo 3rd' }
tmux . send_keys :Enter
tmux . until { | lines | lines [ - 1 ] == '3rd' }
end
2017-01-09 04:22:24 +00:00
2020-02-28 11:06:38 +00:00
def test_ctrl_r_multiline
tmux . send_keys 'echo "foo' , :Enter , 'bar"' , :Enter
tmux . until { | lines | lines [ - 2 .. - 1 ] == [ 'foo' , 'bar' ] }
2020-03-07 10:56:06 +00:00
retries do
tmux . prepare
tmux . send_keys 'C-r'
tmux . until { | lines | lines [ - 1 ] == '>' }
end
2020-02-28 11:06:38 +00:00
tmux . send_keys 'foo bar'
tmux . until { | lines | lines [ - 3 ] . end_with? 'bar"' }
tmux . send_keys :Enter
tmux . until { | lines | lines [ - 1 ] . end_with? 'bar"' }
tmux . send_keys :Enter
tmux . until { | lines | lines [ - 2 .. - 1 ] == [ 'foo' , 'bar' ] }
end
2020-02-28 09:47:13 +00:00
def test_ctrl_r_abort
skip " doesn't restore the original line when search is aborted pre Bash 4 " if shell == :bash && / (?<= version ) \ d+ / . match ( ` #{ Shell . bash } --version ` ) . to_s . to_i < 4
2020-02-29 02:54:05 +00:00
%w[ foo ' " ] . each do | query |
2020-03-07 10:56:06 +00:00
retries do
tmux . prepare
tmux . send_keys ( :Space , 'C-e' , 'C-u' , query )
tmux . until { | lines | lines [ - 1 ] . start_with? query }
tmux . send_keys 'C-r'
tmux . until { | lines | lines [ - 1 ] == " > #{ query } " }
end
2020-02-29 02:54:05 +00:00
tmux . send_keys 'C-g'
tmux . until { | lines | lines [ - 1 ] . start_with? query }
end
2020-02-28 09:47:13 +00:00
end
2017-08-04 14:29:02 +00:00
def retries ( times = 3 )
( times - 1 ) . times do
2017-01-09 04:22:24 +00:00
begin
2017-08-04 14:29:02 +00:00
return yield
2017-01-09 04:22:24 +00:00
rescue RuntimeError
end
end
2017-08-04 14:29:02 +00:00
yield
2017-01-09 04:22:24 +00:00
end
2015-02-28 18:00:36 +00:00
end
2015-05-09 11:15:14 +00:00
module CompletionTest
2015-02-28 18:00:36 +00:00
def test_file_completion
2015-05-11 16:40:44 +00:00
FileUtils . mkdir_p '/tmp/fzf-test'
FileUtils . mkdir_p '/tmp/fzf test'
( 1 .. 100 ) . each { | i | FileUtils . touch " /tmp/fzf-test/ #{ i } " }
2015-05-20 10:47:48 +00:00
[ 'no~such~user' , '/tmp/fzf test/foobar' , '~/.fzf-home' ] . each do | f |
2015-05-11 16:40:44 +00:00
FileUtils . touch File . expand_path ( f )
end
2015-02-28 18:00:36 +00:00
tmux . prepare
2017-01-07 16:30:31 +00:00
tmux . send_keys 'cat /tmp/fzf-test/10**' , :Tab
2018-06-01 09:21:34 +00:00
tmux . until { | lines | lines . match_count . positive? }
2015-12-28 15:00:20 +00:00
tmux . send_keys ' !d'
2017-01-07 16:30:31 +00:00
tmux . until { | lines | lines . match_count == 2 }
tmux . send_keys :Tab , :Tab
tmux . until { | lines | lines . select_count == 2 }
2015-07-13 10:24:22 +00:00
tmux . send_keys :Enter
2017-01-20 19:17:51 +00:00
tmux . until ( true ) do | lines |
2015-02-28 18:00:36 +00:00
lines [ - 1 ] . include? ( '/tmp/fzf-test/10' ) &&
2017-08-04 14:29:02 +00:00
lines [ - 1 ] . include? ( '/tmp/fzf-test/100' )
2015-04-13 17:00:50 +00:00
end
2015-05-09 17:35:00 +00:00
# ~USERNAME**<TAB>
tmux . send_keys 'C-u'
2017-01-07 16:30:31 +00:00
tmux . send_keys " cat ~ #{ ENV [ 'USER' ] } ** " , :Tab
2018-06-01 09:21:34 +00:00
tmux . until { | lines | lines . match_count . positive? }
2017-01-07 16:30:31 +00:00
tmux . send_keys " '.fzf-home "
tmux . until { | lines | lines . select { | l | l . include? '.fzf-home' } . count > 1 }
2015-05-09 17:35:00 +00:00
tmux . send_keys :Enter
2017-01-20 19:17:51 +00:00
tmux . until ( true ) do | lines |
2015-05-20 10:47:48 +00:00
lines [ - 1 ] . end_with? ( '.fzf-home' )
2015-05-09 17:54:22 +00:00
end
# ~INVALID_USERNAME**<TAB>
tmux . send_keys 'C-u'
2017-08-04 14:29:02 +00:00
tmux . send_keys 'cat ~such**' , :Tab
2017-01-20 19:17:51 +00:00
tmux . until ( true ) { | lines | lines . any_include? 'no~such~user' }
2015-05-09 17:54:22 +00:00
tmux . send_keys :Enter
2017-01-20 19:17:51 +00:00
tmux . until ( true ) { | lines | lines [ - 1 ] . end_with? ( 'no~such~user' ) }
2015-05-11 16:40:44 +00:00
# /tmp/fzf\ test**<TAB>
tmux . send_keys 'C-u'
2017-01-07 16:30:31 +00:00
tmux . send_keys 'cat /tmp/fzf\ test/**' , :Tab
2018-06-01 09:21:34 +00:00
tmux . until { | lines | lines . match_count . positive? }
2017-01-07 16:30:31 +00:00
tmux . send_keys 'foobar$'
tmux . until { | lines | lines . match_count == 1 }
tmux . send_keys :Enter
2017-01-20 19:17:51 +00:00
tmux . until ( true ) { | lines | lines [ - 1 ] . end_with? ( '/tmp/fzf\ test/foobar' ) }
2015-12-28 15:00:20 +00:00
# Should include hidden files
( 1 .. 100 ) . each { | i | FileUtils . touch " /tmp/fzf-test/.hidden- #{ i } " }
tmux . send_keys 'C-u'
2017-01-07 16:30:31 +00:00
tmux . send_keys 'cat /tmp/fzf-test/hidden**' , :Tab
2017-01-20 19:17:51 +00:00
tmux . until ( true ) { | lines | lines . match_count == 100 && lines . any_include? ( '/tmp/fzf-test/.hidden-' ) }
2016-03-06 03:46:28 +00:00
tmux . send_keys :Enter
2015-05-09 20:01:52 +00:00
ensure
2015-05-20 10:47:48 +00:00
[ '/tmp/fzf-test' , '/tmp/fzf test' , '~/.fzf-home' , 'no~such~user' ] . each do | f |
2015-05-11 16:40:44 +00:00
FileUtils . rm_rf File . expand_path ( f )
end
2015-02-28 18:00:36 +00:00
end
2015-12-29 04:02:16 +00:00
def test_file_completion_root
2017-01-07 16:30:31 +00:00
tmux . send_keys 'ls /**' , :Tab
2018-06-01 09:21:34 +00:00
tmux . until { | lines | lines . match_count . positive? }
2015-12-29 04:02:16 +00:00
tmux . send_keys :Enter
end
2015-02-28 18:00:36 +00:00
def test_dir_completion
2017-01-07 16:30:31 +00:00
( 1 .. 100 ) . each do | idx |
FileUtils . mkdir_p " /tmp/fzf-test/d #{ idx } "
end
FileUtils . touch '/tmp/fzf-test/d55/xxx'
2015-02-28 18:00:36 +00:00
tmux . prepare
2017-01-07 16:30:31 +00:00
tmux . send_keys 'cd /tmp/fzf-test/**' , :Tab
2018-06-01 09:21:34 +00:00
tmux . until { | lines | lines . match_count . positive? }
2017-01-07 16:30:31 +00:00
tmux . send_keys :Tab , :Tab # Tab does not work here
2015-02-28 18:00:36 +00:00
tmux . send_keys 55
2017-01-07 16:30:31 +00:00
tmux . until { | lines | lines . match_count == 1 }
2015-02-28 18:00:36 +00:00
tmux . send_keys :Enter
2017-01-20 19:17:51 +00:00
tmux . until ( true ) { | lines | lines [ - 1 ] == 'cd /tmp/fzf-test/d55/' }
2015-03-04 03:59:23 +00:00
tmux . send_keys :xx
tmux . until { | lines | lines [ - 1 ] == 'cd /tmp/fzf-test/d55/xx' }
2015-03-04 04:13:11 +00:00
2015-05-09 11:15:14 +00:00
# Should not match regular files (bash-only)
if self . class == TestBash
tmux . send_keys :Tab
tmux . until { | lines | lines [ - 1 ] == 'cd /tmp/fzf-test/d55/xx' }
end
2015-03-04 04:13:11 +00:00
# Fail back to plusdirs
tmux . send_keys :BSpace , :BSpace , :BSpace
tmux . until { | lines | lines [ - 1 ] == 'cd /tmp/fzf-test/d55' }
tmux . send_keys :Tab
tmux . until { | lines | lines [ - 1 ] == 'cd /tmp/fzf-test/d55/' }
2015-02-28 18:00:36 +00:00
end
def test_process_completion
tmux . send_keys 'sleep 12345 &' , :Enter
lines = tmux . until { | lines | lines [ - 1 ] . start_with? '[1]' }
pid = lines [ - 1 ] . split . last
tmux . prepare
2017-01-07 16:30:31 +00:00
tmux . send_keys 'C-L'
tmux . send_keys 'kill ' , :Tab
2018-06-01 09:21:34 +00:00
tmux . until { | lines | lines . match_count . positive? }
2015-02-28 18:00:36 +00:00
tmux . send_keys 'sleep12345'
2017-01-07 16:30:31 +00:00
tmux . until { | lines | lines . any_include? 'sleep 12345' }
2015-02-28 18:00:36 +00:00
tmux . send_keys :Enter
2017-01-20 19:17:51 +00:00
tmux . until ( true ) { | lines | lines [ - 1 ] . include? " kill #{ pid } " }
2015-05-10 02:21:21 +00:00
ensure
2017-08-04 14:29:02 +00:00
if pid
begin
Process . kill 'KILL' , pid . to_i
rescue
nil
end
end
2015-02-28 18:00:36 +00:00
end
2016-02-16 03:32:05 +00:00
def test_custom_completion
2020-02-28 11:06:38 +00:00
tmux . send_keys '_fzf_compgen_path() { echo "$1"; seq 10; }' , :Enter
2016-02-16 03:32:05 +00:00
tmux . prepare
2017-01-07 16:30:31 +00:00
tmux . send_keys 'ls /tmp/**' , :Tab
2018-06-01 09:21:34 +00:00
tmux . until { | lines | lines . match_count == 11 }
2017-01-07 16:30:31 +00:00
tmux . send_keys :Tab , :Tab , :Tab
tmux . until { | lines | lines . select_count == 3 }
2016-02-16 03:32:05 +00:00
tmux . send_keys :Enter
2017-08-04 14:29:02 +00:00
tmux . until ( true ) { | lines | lines [ - 1 ] == 'ls /tmp 1 2' }
2016-02-16 03:32:05 +00:00
end
def test_unset_completion
2017-01-07 16:30:31 +00:00
tmux . send_keys 'export FZFFOOBAR=BAZ' , :Enter
2016-02-16 03:32:05 +00:00
tmux . prepare
# Using tmux
2017-02-04 13:49:17 +00:00
tmux . send_keys 'unset FZFFOOBR**' , :Tab
2017-01-07 16:30:31 +00:00
tmux . until { | lines | lines . match_count == 1 }
2016-02-16 03:32:05 +00:00
tmux . send_keys :Enter
2017-01-07 16:30:31 +00:00
tmux . until { | lines | lines [ - 1 ] . include? 'unset FZFFOOBAR' }
2016-02-16 03:32:05 +00:00
tmux . send_keys 'C-c'
2017-01-07 16:30:31 +00:00
# FZF_TMUX=1
2016-02-16 03:32:05 +00:00
new_shell
2017-02-04 13:49:17 +00:00
tmux . send_keys 'unset FZFFOOBR**' , :Tab , pane : 0
2017-01-20 19:17:51 +00:00
tmux . until ( false , 1 ) { | lines | lines . match_count == 1 }
2016-02-16 03:32:05 +00:00
tmux . send_keys :Enter
2017-01-07 16:30:31 +00:00
tmux . until { | lines | lines [ - 1 ] . include? 'unset FZFFOOBAR' }
2016-02-16 03:32:05 +00:00
end
2016-04-24 15:53:11 +00:00
def test_file_completion_unicode
FileUtils . mkdir_p '/tmp/fzf-test'
2020-02-21 00:51:34 +00:00
tmux . paste " cd /tmp/fzf-test; echo -n test3 > $'fzf-unicode \\ 355 \\ 205 \\ 214 \\ 354 \\ 212 \\ 244 \\ 355 \\ 212 \\ 2701'; echo -n test4 > $'fzf-unicode \\ 355 \\ 205 \\ 214 \\ 354 \\ 212 \\ 244 \\ 355 \\ 212 \\ 2702' "
2016-04-24 15:53:11 +00:00
tmux . prepare
2017-01-07 16:30:31 +00:00
tmux . send_keys 'cat fzf-unicode**' , :Tab
tmux . until { | lines | lines . match_count == 2 }
2016-07-10 06:44:44 +00:00
2017-01-07 16:30:31 +00:00
tmux . send_keys '1'
tmux . until { | lines | lines . match_count == 1 }
tmux . send_keys :Tab
tmux . until { | lines | lines . select_count == 1 }
2016-07-10 06:44:44 +00:00
2017-01-07 16:30:31 +00:00
tmux . send_keys :BSpace
tmux . until { | lines | lines . match_count == 2 }
2016-07-10 06:44:44 +00:00
2017-01-07 16:30:31 +00:00
tmux . send_keys '2'
tmux . until { | lines | lines . select_count == 1 }
tmux . send_keys :Tab
tmux . until { | lines | lines . select_count == 2 }
2016-07-10 06:44:44 +00:00
2017-01-07 16:30:31 +00:00
tmux . send_keys :Enter
2017-01-20 19:17:51 +00:00
tmux . until ( true ) { | lines | lines . any_include? 'cat' }
2016-04-24 15:53:11 +00:00
tmux . send_keys :Enter
tmux . until { | lines | lines [ - 1 ] . include? 'test3test4' }
end
2020-03-11 09:29:39 +00:00
def test_custom_completion_api
2020-03-11 10:42:17 +00:00
tmux . send_keys 'eval "_fzf$(declare -f _comprun)"' , :Enter
2020-03-11 09:29:39 +00:00
%w[ f g ] . each do | command |
tmux . prepare
tmux . send_keys " #{ command } b** " , :Tab
tmux . until do | lines |
lines . item_count == 2 && lines . match_count == 1 &&
lines . any_include? ( " prompt- #{ command } " ) &&
lines . any_include? ( " preview- #{ command } -bar " )
end
tmux . send_keys :Enter
tmux . until { | lines | lines [ - 1 ] . include? ( " #{ command } #{ command } barbar " ) }
tmux . send_keys 'C-u'
end
2020-03-11 10:42:17 +00:00
ensure
tmux . prepare
tmux . send_keys 'unset -f _fzf_comprun' , :Enter
2020-03-11 09:29:39 +00:00
end
2015-02-28 18:00:36 +00:00
end
2015-05-09 11:15:14 +00:00
class TestBash < TestBase
include TestShell
include CompletionTest
2020-02-28 09:47:13 +00:00
def shell
:bash
end
2015-05-09 11:15:14 +00:00
def new_shell
2015-06-14 14:44:42 +00:00
tmux . prepare
2017-01-07 16:30:31 +00:00
tmux . send_keys " FZF_TMUX=1 #{ Shell . bash } " , :Enter
2015-05-09 11:15:14 +00:00
tmux . prepare
end
2017-12-02 18:06:10 +00:00
def test_dynamic_completion_loader
tmux . paste 'touch /tmp/foo; _fzf_completion_loader=1'
tmux . paste '_completion_loader() { complete -o default fake; }'
tmux . paste 'complete -F _fzf_path_completion -o default -o bashdefault fake'
tmux . send_keys 'fake /tmp/foo**' , :Tab
2018-06-01 09:21:34 +00:00
tmux . until { | lines | lines . match_count . positive? }
2017-12-02 18:06:10 +00:00
tmux . send_keys 'C-c'
tmux . prepare
tmux . send_keys 'fake /tmp/foo'
tmux . send_keys :Tab , 'C-u'
tmux . prepare
tmux . send_keys 'fake /tmp/foo**' , :Tab
2018-06-01 09:21:34 +00:00
tmux . until { | lines | lines . match_count . positive? }
2017-12-02 18:06:10 +00:00
end
2015-05-09 11:15:14 +00:00
end
2015-02-28 18:00:36 +00:00
class TestZsh < TestBase
include TestShell
2015-05-09 11:15:14 +00:00
include CompletionTest
2015-02-28 18:00:36 +00:00
2020-02-28 09:47:13 +00:00
def shell
:zsh
end
2015-02-28 18:00:36 +00:00
def new_shell
2017-01-07 16:30:31 +00:00
tmux . send_keys " FZF_TMUX=1 #{ Shell . zsh } " , :Enter
2015-02-28 18:00:36 +00:00
tmux . prepare
end
end
class TestFish < TestBase
include TestShell
2020-02-28 09:47:13 +00:00
def shell
:fish
end
2015-02-28 18:00:36 +00:00
def new_shell
2017-01-07 16:30:31 +00:00
tmux . send_keys 'env FZF_TMUX=1 fish' , :Enter
2015-02-28 18:00:36 +00:00
tmux . send_keys 'function fish_prompt; end; clear' , :Enter
2017-08-04 14:29:02 +00:00
tmux . until ( & :empty? )
2015-02-28 18:00:36 +00:00
end
2017-08-04 14:29:02 +00:00
def set_var ( name , val )
2015-06-25 16:00:58 +00:00
tmux . prepare
2015-07-13 10:24:22 +00:00
tmux . send_keys " set -g #{ name } ' #{ val } ' " , :Enter
2015-06-25 16:00:58 +00:00
tmux . prepare
end
2015-02-28 18:00:36 +00:00
end
2020-02-28 06:38:39 +00:00
__END__
# Setup fzf
# ---------
if [ [ ! " $PATH " == * < %= BASE % > / bin* ]]; then
export PATH = " ${PATH:+${PATH}:}<%= BASE %>/bin "
fi
# Auto-completion
# ---------------
[ [ $- == * i * ] ] && source " <%= BASE %>/shell/completion.<%= __method__ %> " 2 > / dev /nu ll
# Key bindings
# ------------
source " <%= BASE %>/shell/key-bindings.<%= __method__ %> "
PS1 = PROMPT_COMMAND = HISTFILE = HISTSIZE = 100
unset < %= UNSETS . join ( ' ' ) % >
2020-03-11 09:29:39 +00:00
# Old API
_fzf_complete_f ( ) {
_fzf_complete " --multi --prompt \" prompt-f> \" " " $@ " < < (
echo foo
echo bar
)
}
# New API
_fzf_complete_g ( ) {
_fzf_complete - - multi - - prompt " prompt-g> " - - " $@ " < < (
echo foo
echo bar
)
}
_fzf_complete_f_post ( ) {
awk '{print "f" $0 $0}'
}
_fzf_complete_g_post ( ) {
awk '{print "g" $0 $0}'
}
[ - n " $BASH " ] && complete - F _fzf_complete_f - o default - o bashdefault f
[ - n " $BASH " ] && complete - F _fzf_complete_g - o default - o bashdefault g
2020-03-11 10:42:17 +00:00
_comprun ( ) {
2020-03-11 09:29:39 +00:00
local command = $1
shift
case " $command " in
f ) fzf " $@ " - - preview 'echo preview-f-{}' ; ;
g ) fzf " $@ " - - preview 'echo preview-g-{}' ; ;
* ) fzf " $@ " ; ;
esac
}