2015-01-17 04:55:29 +09:00
#!/usr/bin/env ruby
# encoding: utf-8
2017-08-04 23:29:02 +09:00
# frozen_string_literal: true
# rubocop:disable Metrics/LineLength
# rubocop:disable Metrics/MethodLength
2015-01-17 04:55:29 +09:00
require 'minitest/autorun'
2015-03-01 03:00:36 +09:00
require 'fileutils'
2017-08-04 23:29:02 +09:00
require 'English'
require 'shellwords'
2020-02-28 15:38:39 +09:00
require 'erb'
require 'tempfile'
2015-01-17 04:55:29 +09:00
2020-02-28 15:38:39 +09:00
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 10:39:04 +09:00
DEFAULT_TIMEOUT = 20
2015-11-30 17:32:16 +09:00
FILE = File . expand_path ( __FILE__ )
2020-02-28 15:38:39 +09:00
BASE = File . expand_path ( '..' , __dir__ )
Dir . chdir ( BASE )
FZF = "FZF_DEFAULT_OPTS= FZF_DEFAULT_COMMAND= #{ BASE } /bin/fzf"
2015-03-28 21:37:37 +09:00
2015-01-17 12:37:24 +09:00
class NilClass
2017-08-04 23:29:02 +09:00
def include? ( _str )
2015-01-17 12:37:24 +09:00
false
end
2015-03-01 03:00:36 +09:00
2017-08-04 23:29:02 +09:00
def start_with? ( _str )
2015-03-01 03:00:36 +09:00
false
end
2017-08-04 23:29:02 +09:00
def end_with? ( _str )
2015-03-01 03:00:36 +09:00
false
end
2015-01-17 12:37:24 +09:00
end
2015-04-25 10:39:04 +09:00
def wait
since = Time . now
while Time . now - since < DEFAULT_TIMEOUT
return if yield
sleep 0 . 05
2015-01-24 13:25:11 +09:00
end
2016-04-24 04:52:01 +09:00
raise 'timeout'
2015-01-24 13:25:11 +09:00
end
2015-03-01 03:00:36 +09:00
class Shell
class << self
def bash
2020-02-28 15:38:39 +09: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-03-01 03:00:36 +09:00
end
def zsh
2020-02-28 15:38:39 +09: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-03-01 03:00:36 +09:00
end
2016-08-13 19:26:36 +09:00
def fish
2020-02-28 15:38:39 +09:00
UNSETS . map { | v | v + '= ' } . join + 'fish'
2016-08-13 19:26:36 +09:00
end
2015-03-01 03:00:36 +09:00
end
end
2015-01-17 04:55:29 +09:00
class Tmux
attr_reader :win
2017-08-04 23:29:02 +09:00
def initialize ( shell = :bash )
2020-02-28 04:06:38 -07: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 23:29:02 +09:00
return unless shell == :fish
2020-02-28 15:38:39 +09:00
2017-08-04 23:29:02 +09:00
send_keys ( 'function fish_prompt; end; clear' , :Enter )
self . until ( & :empty? )
2015-01-17 04:55:29 +09:00
end
def kill
2020-02-28 04:06:38 -07:00
go ( %W[kill-window -t #{ win } ] )
2015-01-17 04:55:29 +09:00
end
2017-08-04 23:29:02 +09:00
def send_keys ( * args )
2015-03-01 03:00:36 +09:00
target =
if args . last . is_a? ( Hash )
hash = args . pop
2020-02-28 04:06:38 -07:00
go ( %W[select-window -t #{ win } ] )
2015-03-01 03:00:36 +09:00
" #{ win } . #{ hash [ :pane ] } "
else
win
end
2020-02-28 04:06:38 -07:00
go ( %W[send-keys -t #{ target } ] + args . map ( & :to_s ))
2015-01-17 04:55:29 +09:00
end
2017-08-04 23:29:02 +09:00
def paste ( str )
2020-02-20 17:51:34 -07:00
system ( 'tmux' , 'setb' , str , ';' , 'pasteb' , '-t' , win , ';' , 'send-keys' , '-t' , win , 'Enter' )
2016-07-10 12:27:01 +09:00
end
2017-08-04 23:29:02 +09:00
def capture ( pane = 0 )
2020-02-28 04:06:38 -07:00
go ( %W[capture-pane -p -t #{ win } . #{ pane } ] ) . reverse . drop_while ( & :empty? ) . reverse
2015-01-17 04:55:29 +09:00
end
2017-08-04 23:29:02 +09:00
def until ( refresh = false , pane = 0 )
2015-03-01 03:00:36 +09:00
lines = nil
2015-05-10 03:25:14 +09:00
begin
wait do
lines = capture ( pane )
class << lines
2017-01-08 01:30:31 +09:00
def counts
2017-08-04 23:29:02 +09:00
lazy
. map { | l | l . scan %r{^. ([0-9]+)\/([0-9]+)( \(([0-9]+)\))?} }
2017-01-08 01:30:31 +09: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-10 03:25:14 +09:00
def item_count
2017-01-08 01:30:31 +09:00
counts [ 1 ]
end
def select_count
counts [ 2 ]
end
2017-08-04 23:29:02 +09:00
def any_include? ( val )
2017-01-08 01:30:31 +09:00
method = val . is_a? ( Regexp ) ? :match : :include?
2017-08-04 23:29:02 +09:00
select { | line | line . send method , val } . first
2015-05-10 03:25:14 +09:00
end
2015-04-25 01:09:05 +09:00
end
2017-01-21 04:17:51 +09:00
yield ( lines ) . tap do | ok |
send_keys 'C-l' if refresh && ! ok
end
2015-04-25 01:09:05 +09:00
end
2017-08-04 23:29:02 +09:00
rescue StandardError
puts $ERROR_INFO . backtrace
2015-05-10 03:25:14 +09:00
puts '>' * 80
puts lines
puts '<' * 80
raise
2015-03-01 03:00:36 +09:00
end
lines
2015-01-17 04:55:29 +09:00
end
2015-03-01 03:00:36 +09:00
def prepare
2015-04-25 01:09:05 +09:00
tries = 0
begin
2016-10-22 00:01:21 +09:00
self . until do | lines |
2020-02-28 14:46:08 +09:00
send_keys ' ' , 'C-u' , 'hello' , :Left , :Right
2016-10-22 00:01:21 +09:00
lines [- 1 ]. end_with? ( 'hello' )
end
2017-08-04 23:29:02 +09:00
rescue StandardError
2015-04-25 01:09:05 +09:00
( tries += 1 ) < 5 ? retry : raise
end
2017-08-04 23:29:02 +09:00
send_keys 'C-u'
2015-03-01 03:00:36 +09:00
end
2017-08-04 23:29:02 +09:00
private
2020-02-28 04:06:38 -07:00
def go ( args )
IO . popen ( [ 'tmux' ] + args ) { | io | io . readlines ( chomp : true ) }
2015-01-17 04:55:29 +09:00
end
end
2015-03-01 03:00:36 +09:00
class TestBase < Minitest :: Test
2015-01-24 13:25:11 +09:00
TEMPNAME = '/tmp/output'
2015-01-17 04:55:29 +09:00
attr_reader :tmux
2015-06-14 02:44:22 +09:00
def tempname
2016-01-14 00:41:02 +09:00
@temp_suffix ||= 0
2015-06-14 02:44:22 +09:00
[ TEMPNAME ,
2016-01-14 00:41:02 +09:00
caller_locations . map ( & :label ) . find { | l | l =~ /^test_/ },
@temp_suffix ]. join '-'
2015-06-14 02:44:22 +09:00
end
2017-08-04 23:29:02 +09: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-08 01:30:31 +09:00
end
2015-04-25 10:39:04 +09:00
def readonce
2017-08-04 23:29:02 +09:00
wait { File . exist? ( tempname ) }
2015-06-14 02:44:22 +09:00
File . read ( tempname )
2015-04-25 10:39:04 +09:00
ensure
2017-08-04 23:29:02 +09:00
File . unlink tempname while File . exist? ( tempname )
2016-01-14 00:41:02 +09:00
@temp_suffix += 1
2015-06-18 02:09:03 +09:00
tmux . prepare
2015-01-17 04:55:29 +09:00
end
2015-01-29 17:37:35 +09:00
def fzf ( * opts )
2015-06-14 02:44:22 +09:00
fzf! ( * opts ) + " > #{ tempname } .tmp; mv #{ tempname } .tmp #{ tempname } "
2015-02-18 12:07:54 +09:00
end
def fzf! ( * opts )
2017-08-04 23:29:02 +09:00
opts = opts . map do | o |
2015-01-29 17:37:35 +09:00
case o
when Symbol
o = o . to_s
2017-08-04 23:29:02 +09:00
o . length > 1 ? "-- #{ o . tr ( '_' , '-' ) } " : "- #{ o } "
2015-01-29 17:37:35 +09:00
when String , Numeric
o . to_s
end
2017-08-04 23:29:02 +09:00
end . compact
2015-04-14 22:23:11 +09:00
" #{ FZF } #{ opts . join ' ' } "
2015-01-29 17:37:35 +09:00
end
2015-03-01 03:00:36 +09:00
end
class TestGoFZF < TestBase
def setup
super
@tmux = Tmux . new
end
def teardown
@tmux . kill
end
2015-01-29 17:37:35 +09:00
2015-01-17 04:55:29 +09:00
def test_vanilla
2015-01-29 17:37:35 +09:00
tmux . send_keys "seq 1 100000 | #{ fzf } " , :Enter
2015-04-25 10:39:04 +09:00
tmux . until { | lines | lines . last =~ /^>/ && lines [- 2 ] =~ /^ 100000/ }
2015-01-17 04:55:29 +09: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 14:55:13 +09:00
tmux . until do | lines |
'> 3910' == lines [- 4 ] &&
' 391' == lines [- 3 ] &&
' 856/100000' == lines [- 2 ] &&
'> 391' == lines [- 1 ]
end
2015-01-17 04:55:29 +09:00
tmux . send_keys :Enter
2016-04-16 14:02:43 +09:00
assert_equal '3910' , readonce . chomp
2015-01-17 04:55:29 +09:00
end
def test_fzf_default_command
2015-11-03 22:49:32 +09:00
tmux . send_keys fzf . sub ( 'FZF_DEFAULT_COMMAND=' , "FZF_DEFAULT_COMMAND='echo hello'" ), :Enter
2015-01-17 04:55:29 +09:00
tmux . until { | lines | lines . last =~ /^>/ }
tmux . send_keys :Enter
2015-01-24 13:25:11 +09:00
assert_equal 'hello' , readonce . chomp
2015-01-17 04:55:29 +09:00
end
2017-07-01 01:13:15 +09:00
def test_fzf_default_command_failure
tmux . send_keys fzf . sub ( 'FZF_DEFAULT_COMMAND=' , 'FZF_DEFAULT_COMMAND=false' ), :Enter
2019-11-10 13:13:45 +09:00
tmux . until { | lines | lines [- 2 ]. include? ( 'Command failed: false' ) }
2017-07-01 01:13:15 +09:00
tmux . send_keys :Enter
end
2015-01-17 11:20:00 +09:00
def test_key_bindings
2015-04-14 22:23:11 +09:00
tmux . send_keys " #{ FZF } -q 'foo bar foo-bar'" , :Enter
2015-01-17 06:12:57 +09:00
tmux . until { | lines | lines . last =~ /^>/ }
2015-01-17 04:55:29 +09:00
# CTRL-A
2017-08-04 23:29:02 +09:00
tmux . send_keys 'C-A' , '('
2015-01-17 04:55:29 +09:00
tmux . until { | lines | lines . last == '> (foo bar foo-bar' }
# META-F
2017-08-04 23:29:02 +09:00
tmux . send_keys :Escape , :f , ')'
2015-01-17 04:55:29 +09:00
tmux . until { | lines | lines . last == '> (foo) bar foo-bar' }
# CTRL-B
2017-08-04 23:29:02 +09:00
tmux . send_keys 'C-B' , 'var'
2015-01-17 04:55:29 +09:00
tmux . until { | lines | lines . last == '> (foovar) bar foo-bar' }
# Left, CTRL-D
2017-08-04 23:29:02 +09:00
tmux . send_keys :Left , :Left , 'C-D'
2015-01-17 04:55:29 +09: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 23:29:02 +09:00
tmux . send_keys 'C-Y' , 'C-Y'
2015-01-17 04:55:29 +09: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 23:29:02 +09:00
tmux . send_keys 'C-E' , 'baz'
2015-01-17 04:55:29 +09:00
tmux . until { | lines | lines . last == '> ( fovfoovr) bar foo-barbaz' }
# CTRL-U
2017-08-04 23:29:02 +09:00
tmux . send_keys 'C-U'
2015-01-17 04:55:29 +09:00
tmux . until { | lines | lines . last == '>' }
# CTRL-Y
2017-08-04 23:29:02 +09:00
tmux . send_keys 'C-Y'
2015-01-17 04:55:29 +09:00
tmux . until { | lines | lines . last == '> ( fovfoovr) bar foo-barbaz' }
# CTRL-W
2017-08-04 23:29:02 +09:00
tmux . send_keys 'C-W' , 'bar-foo'
2015-01-17 04:55:29 +09:00
tmux . until { | lines | lines . last == '> ( fovfoovr) bar bar-foo' }
# META-D
2017-08-04 23:29:02 +09:00
tmux . send_keys :Escape , :b , :Escape , :b , :Escape , :d , 'C-A' , 'C-Y'
2015-01-17 04:55:29 +09:00
tmux . until { | lines | lines . last == '> bar( fovfoovr) bar -foo' }
# CTRL-M
2017-08-04 23:29:02 +09:00
tmux . send_keys 'C-M'
2015-01-17 04:55:29 +09:00
tmux . until { | lines | lines . last !~ /^>/ }
end
2015-01-17 11:07:04 +09:00
2017-01-15 19:42:28 +09: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 11:20:00 +09:00
def test_multi_order
2015-01-29 17:37:35 +09:00
tmux . send_keys "seq 1 10 | #{ fzf :multi } " , :Enter
2015-01-17 11:07:04 +09: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 23:29:02 +09:00
tmux . send_keys 'C-M'
assert_equal %w[3 2 5 6 8 7] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-01-17 11:07:04 +09:00
end
2015-01-17 11:20:00 +09:00
2019-11-02 12:55:26 +09: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 11:20:00 +09:00
def test_with_nth
[ true , false ]. each do | multi |
tmux . send_keys "(echo ' 1st 2nd 3rd/';
echo ' first second third/') |
2015-01-29 17:37:35 +09:00
#{ fzf multi && :multi , :x , :nth , 2 , :with_nth , '2,-1,1' } " ,
2017-08-04 23:29:02 +09:00
:Enter
2015-01-17 12:37:24 +09:00
tmux . until { | lines | lines [- 2 ]. include? ( '2/2' ) }
2015-01-17 11:20:00 +09: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 19:24:22 +09:00
tmux . send_keys :BTab , :BTab
tmux . until { | lines | lines [- 2 ]. include? ( '(2)' ) }
tmux . send_keys :Enter
2017-08-04 23:29:02 +09:00
assert_equal [ ' 1st 2nd 3rd/' , ' first second third/' ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-01-17 11:20:00 +09:00
else
tmux . send_keys '^' , '3'
tmux . until { | lines | lines [- 2 ]. include? ( '1/2' ) }
tmux . send_keys :Enter
2017-08-04 23:29:02 +09:00
assert_equal [ ' 1st 2nd 3rd/' ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-01-17 11:20:00 +09:00
end
end
end
2015-01-17 12:21:38 +09:00
def test_scroll
[ true , false ]. each do | rev |
2015-01-29 17:37:35 +09:00
tmux . send_keys "seq 1 100 | #{ fzf rev && :reverse } " , :Enter
2015-01-24 13:25:11 +09:00
tmux . until { | lines | lines . include? ' 100/100' }
2017-08-04 23:29:02 +09:00
tmux . send_keys ( * Array . new ( 110 ) { rev ? :Down : :Up })
2015-01-17 13:38:42 +09:00
tmux . until { | lines | lines . include? '> 100' }
2015-01-17 12:21:38 +09:00
tmux . send_keys :Enter
2015-01-24 13:25:11 +09:00
assert_equal '100' , readonce . chomp
2015-01-17 12:21:38 +09:00
end
end
2015-01-17 12:37:24 +09:00
def test_select_1
2015-01-29 17:37:35 +09:00
tmux . send_keys "seq 1 100 | #{ fzf :with_nth , '..,..' , :print_query , :q , 5555 , :'1' } " , :Enter
2017-08-04 23:29:02 +09:00
assert_equal %w[5555 55] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-01-17 12:37:24 +09:00
end
def test_exit_0
2017-08-04 23:29:02 +09: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 12:37:24 +09:00
end
2015-01-24 13:26:33 +09:00
2015-02-18 00:51:44 +09:00
def test_select_1_exit_0_fail
2017-08-04 23:29:02 +09:00
[ :'0' , :'1' , % i [ 1 0 ]]. each do | opt |
2015-02-18 00:51:44 +09:00
tmux . send_keys "seq 1 100 | #{ fzf :print_query , :multi , :q , 5 , * opt } " , :Enter
tmux . until { | lines | lines . last =~ /^> 5/ }
2015-07-13 19:24:22 +09:00
tmux . send_keys :BTab , :BTab , :BTab
tmux . until { | lines | lines [- 2 ]. include? ( '(3)' ) }
tmux . send_keys :Enter
2017-08-04 23:29:02 +09:00
assert_equal %w[5 5 50 51] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-02-18 00:51:44 +09:00
end
end
2015-01-24 13:26:33 +09:00
def test_query_unicode
2020-02-20 17:51:34 -07: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-25 01:09:05 +09:00
tmux . until { | lines | lines [- 2 ]. include? '1/2' }
2015-01-24 13:26:33 +09:00
tmux . send_keys :Enter
2017-08-04 23:29:02 +09:00
assert_equal [ '가나다' ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-01-24 13:26:33 +09:00
end
2015-02-18 12:07:54 +09:00
def test_sync
2020-02-28 04:06:38 -07:00
tmux . send_keys "seq 1 100 | #{ fzf! :multi } | awk '{print $1 $1}' | #{ fzf :sync } " , :Enter
2015-02-18 12:07:54 +09:00
tmux . until { | lines | lines [- 1 ] == '>' }
tmux . send_keys 9
tmux . until { | lines | lines [- 2 ] == ' 19/100' }
2015-07-13 19:24:22 +09:00
tmux . send_keys :BTab , :BTab , :BTab
tmux . until { | lines | lines [- 2 ]. include? ( '(3)' ) }
tmux . send_keys :Enter
2015-02-18 12:07:54 +09:00
tmux . until { | lines | lines [- 1 ] == '>' }
tmux . send_keys 'C-K' , :Enter
2017-08-04 23:29:02 +09:00
assert_equal [ '9090' ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-02-18 12:07:54 +09:00
end
2015-02-26 01:42:15 +09: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 19:24:22 +09:00
tmux . send_keys :BTab , :BTab , :BTab
tmux . until { | lines | lines [- 2 ]. include? ( '(3)' ) }
tmux . send_keys :Enter
2017-08-04 23:29:02 +09:00
assert_equal %w[1000 999 998] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-02-26 01:42:15 +09: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 12:46:28 +09:00
tmux . until { | lines | lines [- 2 ]. include? '28/1000' }
2015-07-13 19:24:22 +09:00
tmux . send_keys :BTab , :BTab , :BTab
tmux . until { | lines | lines [- 2 ]. include? ( '(3)' ) }
tmux . send_keys :Enter
2017-08-04 23:29:02 +09:00
assert_equal %w[99 999 998] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-02-26 01:42:15 +09: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 10:54:47 +09:00
tmux . until { | lines | lines [- 2 ]. include? '10/1000' }
2015-07-13 19:24:22 +09:00
tmux . send_keys :BTab , :BTab , :BTab
tmux . until { | lines | lines [- 2 ]. include? ( '(3)' ) }
tmux . send_keys :Enter
2017-08-04 23:29:02 +09:00
assert_equal %w[1000 900 800] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-02-26 01:42:15 +09:00
end
2015-03-29 02:59:32 +09:00
def test_expect
test = lambda do | key , feed , expected = key |
2016-04-15 12:57:38 +09:00
tmux . send_keys "seq 1 100 | #{ fzf :expect , key } ; sync" , :Enter
2015-03-29 02:59:32 +09:00
tmux . until { | lines | lines [- 2 ]. include? '100/100' }
tmux . send_keys '55'
2015-04-25 10:54:47 +09:00
tmux . until { | lines | lines [- 2 ]. include? '1/100' }
2017-08-04 23:29:02 +09:00
tmux . send_keys ( * feed )
2016-04-15 12:57:38 +09:00
tmux . prepare
2017-08-04 23:29:02 +09:00
assert_equal [ expected , '55' ] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-03-29 02:59:32 +09:00
end
test . call 'ctrl-t' , 'C-T'
test . call 'ctrl-t' , 'Enter' , ''
2017-08-04 23:29:02 +09:00
test . call 'alt-c' , % i [ Escape c ]
2015-03-29 02:59:32 +09: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 23:29:02 +09:00
test . call 'alt-/' , % i [ Escape /]
2016-05-18 22:25:09 +09:00
%w[f5 f6 f7 f8 f9 f10].each do |key|
test.call 'f5,f6,f7,f8,f9,f10', key, key
end
2015-03-29 02:59:32 +09: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 10:54:47 +09:00
tmux.until { |lines| lines[-2].include? ' 1 / 100 ' }
2015-03-29 02:59:32 +09:00
tmux.send_keys :Escape, :z
2017-08-04 23:29:02 +09:00
assert_equal [' 55 ', ' alt - z ', ' 55 '], readonce.split($INPUT_RECORD_SEPARATOR)
2015-03-29 02:59:32 +09:00
end
2015-03-31 20:52:16 +09:00
2016-09-18 04:45:21 +09: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 23:29:02 +09:00
assert_equal %w[55 z 55], readonce.split($INPUT_RECORD_SEPARATOR)
2016-09-18 04:45:21 +09:00
end
2015-03-31 20:52:16 +09: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 23:29:02 +09:00
assert_equal [' 55 ', '', ' 55 '], readonce.split($INPUT_RECORD_SEPARATOR)
2015-03-31 20:52:16 +09:00
end
2015-03-31 22:05:02 +09:00
def test_toggle_sort
2015-05-21 21:06:52 +09: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-03 02:26:30 +09:00
tmux.until { |lines| lines[-2].include? ' 4 / 111 - S ( 1 ) ' }
2015-05-21 21:06:52 +09:00
tmux.send_keys ' C - R '
tmux.until { |lines| lines[-3].include? ' > 11 ' }
tmux.send_keys :Tab
2017-03-03 02:26:30 +09:00
tmux.until { |lines| lines[-2].include? ' 4 / 111 + S ( 2 ) ' }
2015-05-21 21:06:52 +09:00
tmux.send_keys :Enter
2017-08-04 23:29:02 +09:00
assert_equal %w[111 11], readonce.split($INPUT_RECORD_SEPARATOR)
2015-05-21 21:06:52 +09:00
end
2015-03-31 22:05:02 +09:00
end
2015-04-14 21:45:37 +09:00
def test_unicode_case
2015-04-16 14:19:28 +09:00
writelines tempname, %w[строКА1 СТРОКА2 строка3 Строка4]
2017-08-04 23:29:02 +09: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-14 21:45:37 +09:00
end
2015-04-16 14:19:28 +09:00
def test_tiebreak
input = %w[
--foobar--------
-----foobar---
----foobar--
-------foobar-
]
writelines tempname, input
2017-08-04 23:29:02 +09:00
assert_equal input, `#{FZF} -ffoobar --tiebreak=index < #{tempname}`.split($INPUT_RECORD_SEPARATOR)
2015-04-16 14:19:28 +09:00
by_length = %w[
----foobar--
-----foobar---
-------foobar-
--foobar--------
]
2017-08-04 23:29:02 +09: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 14:19:28 +09:00
by_begin = %w[
--foobar--------
----foobar--
-----foobar---
-------foobar-
]
2017-08-04 23:29:02 +09: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 14:19:28 +09:00
assert_equal %w[
-------foobar-
----foobar--
-----foobar---
--foobar--------
2017-08-04 23:29:02 +09:00
], `#{FZF} -ffoobar --tiebreak end < #{tempname}`.split($INPUT_RECORD_SEPARATOR)
2015-04-16 14:19:28 +09:00
2017-08-04 23:29:02 +09:00
assert_equal input, `#{FZF} -f"!z" -x --tiebreak end < #{tempname}`.split($INPUT_RECORD_SEPARATOR)
2016-01-13 03:07:42 +09:00
end
2016-09-07 09:58:18 +09:00
def test_tiebreak_index_begin
writelines tempname, [
' xoxxxxxoxx ',
' xoxxxxxox ',
' xxoxxxoxx ',
' xxxoxoxxx ',
' xxxxoxox ',
2017-08-04 23:29:02 +09:00
' xxoxoxxx '
2016-01-13 03:07:42 +09:00
]
2016-09-07 09:58:18 +09:00
assert_equal [
' xxxxoxox ',
' xxoxoxxx ',
' xxxoxoxxx ',
' xxoxxxoxx ',
' xoxxxxxox ',
2017-08-04 23:29:02 +09:00
' xoxxxxxoxx '
], `#{FZF} -foo < #{tempname}`.split($INPUT_RECORD_SEPARATOR)
2016-01-13 03:07:42 +09:00
2016-09-07 09:58:18 +09:00
assert_equal [
' xxxoxoxxx ',
' xxxxoxox ',
' xxoxoxxx ',
' xxoxxxoxx ',
' xoxxxxxoxx ',
2017-08-04 23:29:02 +09:00
' xoxxxxxox '
], `#{FZF} -foo --tiebreak=index < #{tempname}`.split($INPUT_RECORD_SEPARATOR)
2016-01-13 03:07:42 +09:00
2016-09-07 09:58:18 +09: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 23:29:02 +09:00
' xoxxxxxox '
], `#{FZF} -foo --tiebreak=begin < #{tempname}`.split($INPUT_RECORD_SEPARATOR)
2016-01-13 03:07:42 +09:00
2016-09-07 09:58:18 +09:00
assert_equal [
' xxoxoxxx ',
' xxxoxoxxx ',
' xxxxoxox ',
' xxoxxxoxx ',
' xoxxxxxox ',
2017-08-04 23:29:02 +09:00
' xoxxxxxoxx '
], `#{FZF} -foo --tiebreak=begin,length < #{tempname}`.split($INPUT_RECORD_SEPARATOR)
2015-04-16 14:19:28 +09:00
end
2017-02-03 02:14:14 +09:00
def test_tiebreak_begin_algo_v2
writelines tempname, [
' baz foo bar ',
2017-08-04 23:29:02 +09:00
' foo bar baz '
2017-02-03 02:14:14 +09:00
]
assert_equal [
' foo bar baz ',
2017-08-04 23:29:02 +09:00
' baz foo bar '
], `#{FZF} -fbar --tiebreak=begin --algo=v2 < #{tempname}`.split($INPUT_RECORD_SEPARATOR)
2017-02-03 02:14:14 +09:00
end
2016-09-07 09:58:18 +09:00
def test_tiebreak_end
2016-01-14 01:32:03 +09:00
writelines tempname, [
2016-09-07 09:58:18 +09:00
' xoxxxxxxxx ',
' xxoxxxxxxx ',
' xxxoxxxxxx ',
' xxxxoxxxx ',
' xxxxxoxxx ',
2017-08-04 23:29:02 +09:00
' xxxxoxxx '
2016-01-14 01:32:03 +09:00
]
assert_equal [
2016-09-07 09:58:18 +09:00
' xxxxoxxx ',
' xxxxoxxxx ',
' xxxxxoxxx ',
' xoxxxxxxxx ',
' xxoxxxxxxx ',
2017-08-04 23:29:02 +09:00
' xxxoxxxxxx '
], `#{FZF} -fo < #{tempname}`.split($INPUT_RECORD_SEPARATOR)
2016-01-14 01:32:03 +09:00
assert_equal [
2016-09-07 09:58:18 +09:00
' xxxxxoxxx ',
' xxxxoxxx ',
' xxxxoxxxx ',
' xxxoxxxxxx ',
' xxoxxxxxxx ',
2017-08-04 23:29:02 +09:00
' xoxxxxxxxx '
], `#{FZF} -fo --tiebreak=end < #{tempname}`.split($INPUT_RECORD_SEPARATOR)
2016-01-14 01:32:03 +09:00
assert_equal [
2016-09-07 09:58:18 +09:00
' xxxxxoxxx ',
2016-10-18 01:11:04 +09:00
' xxxxoxxx ',
2016-09-07 09:58:18 +09:00
' xxxxoxxxx ',
' xxxoxxxxxx ',
' xxoxxxxxxx ',
2017-08-04 23:29:02 +09:00
' xoxxxxxxxx '
], `#{FZF} -fo --tiebreak=end,length,begin < #{tempname}`.split($INPUT_RECORD_SEPARATOR)
2016-01-14 01:32:03 +09:00
end
2015-08-01 23:13:24 +09: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 23:29:02 +09:00
assert_equal output, `#{FZF} -fh < #{tempname}`.split($INPUT_RECORD_SEPARATOR)
2015-08-01 23:13:24 +09:00
2017-06-02 13:25:35 +09:00
# Since 0.16.8, --nth doesn' t affect -- tiebreak
2017-08-04 23:29:02 +09:00
assert_equal output , ` #{ FZF } -fh -n2 -d: < #{ tempname } ` . split ( $INPUT_RECORD_SEPARATOR )
2015-10-02 18:40:20 +09:00
end
2015-04-21 22:10:14 +09: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 13:22:30 +09:00
def test_invalid_cache_query_type
2020-02-28 04:06:38 -07:00
command = %[(echo 'foo$bar'; echo 'barfoo'; echo 'foo^bar'; echo "foo'1-2"; seq 100) | #{ fzf } ]
2017-08-08 13:22:30 +09: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 22:18:05 +09: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 21:25:15 +09:00
def test_bind
2017-08-04 23:29:02 +09:00
tmux . send_keys "seq 1 1000 | #{ fzf '-m --bind=ctrl-j:accept,u:up,T:toggle-up,t:toggle' } " , :Enter
2015-05-20 21:25:15 +09:00
tmux . until { | lines | lines [- 2 ]. end_with? '/1000' }
2015-05-21 21:06:52 +09:00
tmux . send_keys 'uuu' , 'TTT' , 'tt' , 'uu' , 'ttt' , 'C-j'
2017-08-04 23:29:02 +09:00
assert_equal %w[4 5 6 9] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-05-20 21:25:15 +09:00
end
2015-06-03 01:48:02 +09:00
2016-05-13 00:51:15 +09: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 23:29:02 +09:00
assert_equal %w[print-my-query] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2016-05-13 00:51:15 +09:00
end
2017-12-01 13:08:55 +09: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-03 01:48:02 +09:00
def test_long_line
data = '.' * 256 * 1024
File . open ( tempname , 'w' ) do | f |
f << data
end
2016-01-13 03:07:42 +09:00
assert_equal data , ` #{ FZF } -f . < #{ tempname } ` . chomp
2015-06-03 01:48:02 +09:00
end
2015-06-08 23:27:50 +09:00
2015-06-21 17:29:58 +09:00
def test_read0
2017-08-04 23:29:02 +09:00
lines = `find .` . split ( $INPUT_RECORD_SEPARATOR )
2015-06-08 23:27:50 +09:00
assert_equal lines . last , `find . | #{ FZF } -e -f "^ #{ lines . last } $"` . chomp
2017-08-04 23:29:02 +09:00
assert_equal (
lines . last ,
`find . -print0 | #{ FZF } --read0 -e -f "^ #{ lines . last } $"` . chomp
)
2015-06-08 23:27:50 +09:00
end
2015-06-09 23:44:54 +09: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 19:41:59 +09: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 23:44:54 +09:00
tmux . send_keys 'C-d'
tmux . until { | lines | ! lines [- 2 ]. include? '(' }
2019-11-02 19:41:59 +09:00
tmux . send_keys :BTab , :BTab
2015-06-09 23:44:54 +09: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 19:41:59 +09:00
assert_equal %w[1 2 10 20 30 40 50 60 70 80 90 100] ,
2017-08-04 23:29:02 +09:00
readonce . split ( $INPUT_RECORD_SEPARATOR )
2015-06-09 23:44:54 +09:00
end
2015-06-14 00:43:44 +09:00
def test_history
history_file = '/tmp/fzf-test-history'
# History with limited number of entries
2017-08-04 23:29:02 +09:00
begin
File . unlink history_file
rescue
nil
end
2015-06-19 01:03:25 +09:00
opts = "--history= #{ history_file } --history-size=4"
2017-08-04 23:29:02 +09:00
input = %w[00 11 22 33 44] . map { | e | e + $INPUT_RECORD_SEPARATOR }
2015-06-14 00:43:44 +09: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-14 02:51:36 +09:00
readonce
2015-06-14 00:43:44 +09: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-14 02:13:02 +09:00
readonce
2017-08-04 23:29:02 +09:00
assert_equal %w[22 33 44 310] . map { | e | e + $INPUT_RECORD_SEPARATOR }, File . readlines ( history_file )
2015-06-14 00:43:44 +09: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 12:25:08 +09:00
def test_execute
output = '/tmp/fzf-test-execute'
2020-02-28 04:06:38 -07:00
opts = %[--bind "alt-a:execute(echo /{}/ >> #{ output } ),alt-b:execute[echo /{}{}/ >> #{ output } ],C:execute:echo /{}{}{}/ >> #{ output } "]
2017-08-04 23:29:02 +09:00
wait = -> ( exp ) { tmux . until { | lines | lines [- 2 ]. include? exp } }
2016-06-08 02:04:40 +09:00
writelines tempname , %w[foo'bar foo"bar foo$bar]
tmux . send_keys "cat #{ tempname } | #{ fzf opts } ; sync" , :Enter
wait [ '3/3' ]
2016-05-11 01:40:49 +09:00
tmux . send_keys :Escape , :a
2016-06-08 02:04:40 +09:00
wait [ '/3' ]
2016-05-11 01:40:49 +09:00
tmux . send_keys :Escape , :a
2016-06-08 02:04:40 +09:00
wait [ '/3' ]
2015-06-14 12:25:08 +09:00
tmux . send_keys :Up
2016-05-11 01:40:49 +09:00
tmux . send_keys :Escape , :b
2016-06-08 02:04:40 +09:00
wait [ '/3' ]
2016-05-11 01:40:49 +09:00
tmux . send_keys :Escape , :b
2016-06-08 02:04:40 +09:00
wait [ '/3' ]
2015-06-14 12:25:08 +09:00
tmux . send_keys :Up
tmux . send_keys :C
2016-06-08 02:04:40 +09:00
wait [ '3/3' ]
tmux . send_keys 'barfoo'
wait [ '0/3' ]
2016-05-11 01:40:49 +09:00
tmux . send_keys :Escape , :a
2016-06-08 02:04:40 +09:00
wait [ '/3' ]
2016-05-11 01:40:49 +09:00
tmux . send_keys :Escape , :b
2016-06-08 02:04:40 +09:00
wait [ '/3' ]
2015-06-14 12:25:08 +09:00
tmux . send_keys :Enter
readonce
2019-11-02 13:14:47 +09:00
assert_equal %w[/foo'bar/ /foo'bar/
2016-06-08 02:04:40 +09:00
/foo"barfoo"bar/ /foo"barfoo"bar/
/foo$barfoo$barfoo$bar/] ,
2017-08-04 23:29:02 +09:00
File . readlines ( output ) . map ( & :chomp )
2015-06-14 12:25:08 +09:00
ensure
2017-08-04 23:29:02 +09:00
begin
File . unlink output
rescue
nil
end
2015-06-14 12:25:08 +09:00
end
2015-11-09 01:42:01 +09:00
def test_execute_multi
output = '/tmp/fzf-test-execute-multi'
2020-02-28 04:06:38 -07:00
opts = %[--multi --bind "alt-a:execute-multi(echo {}/{+} >> #{ output } ; sync)"]
2016-06-08 02:15:12 +09: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-09 01:42:01 +09:00
tmux . send_keys :Escape , :a
2016-06-08 02:15:12 +09:00
tmux . until { | lines | lines [- 2 ]. include? '/4' }
2015-11-09 01:42:01 +09:00
tmux . send_keys :BTab , :BTab , :BTab
tmux . send_keys :Escape , :a
2016-06-08 02:15:12 +09:00
tmux . until { | lines | lines [- 2 ]. include? '/4' }
2015-11-09 01:42:01 +09:00
tmux . send_keys :Tab , :Tab
tmux . send_keys :Escape , :a
2016-06-08 02:15:12 +09:00
tmux . until { | lines | lines [- 2 ]. include? '/4' }
2015-11-09 01:42:01 +09:00
tmux . send_keys :Enter
2016-03-06 12:46:28 +09:00
tmux . prepare
2015-11-09 01:42:01 +09:00
readonce
2017-08-04 23:29:02 +09: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-09 01:42:01 +09:00
ensure
2017-08-04 23:29:02 +09:00
begin
File . unlink output
rescue
nil
end
2015-11-09 01:42:01 +09:00
end
2017-01-27 16:38:42 +09:00
def test_execute_plus_flag
2017-08-04 23:29:02 +09:00
output = tempname + '.tmp'
begin
File . unlink output
rescue
nil
end
writelines tempname , [ 'foo bar' , '123 456' ]
2017-01-27 16:38:42 +09:00
2017-08-04 23:29:02 +09:00
tmux . send_keys "cat #{ tempname } | #{ FZF } --multi --bind 'x:execute-silent(echo {+}/{}/{+2}/{2} >> #{ output } )'" , :Enter
2017-01-27 16:38:42 +09: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 23:29:02 +09: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 16:38:42 +09:00
] , File . readlines ( output ) . map ( & :chomp )
rescue
2017-08-04 23:29:02 +09:00
begin
File . unlink output
rescue
nil
end
2017-01-27 16:38:42 +09:00
end
2016-02-03 04:46:02 +09:00
def test_execute_shell
# Custom script to use as $SHELL
output = tempname + '.out'
2017-08-04 23:29:02 +09:00
begin
File . unlink output
rescue
nil
end
writelines tempname ,
[ '#!/usr/bin/env bash' , "echo $1 / $2 > #{ output } " , 'sync' ]
2016-02-03 04:46:02 +09: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-02 03:23:32 +09:00
tmux . until { | lines | lines [- 2 ]. include? '1/1' }
2016-02-03 04:46:02 +09:00
tmux . send_keys 'C-c'
2016-03-02 03:23:32 +09:00
tmux . prepare
2016-06-08 02:16:07 +09:00
assert_equal [ "-c / 'foo'bar" ] , File . readlines ( output ) . map ( & :chomp )
2016-02-03 04:46:02 +09:00
ensure
2017-08-04 23:29:02 +09:00
begin
File . unlink output
rescue
nil
end
2016-02-03 04:46:02 +09:00
end
2015-06-16 23:14:57 +09: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 13:20:13 +09:00
tmux . send_keys :Up
2015-06-16 23:14:57 +09:00
tmux . until { | lines | lines [- 10 ]. start_with? '>' }
tmux . send_keys :PgUp
2017-05-24 13:20:13 +09:00
tmux . until { | lines | lines [- 10 ]. start_with? '>' }
2015-06-16 23:14:57 +09:00
tmux . send_keys :Up
tmux . until { | lines | lines [- 3 ]. start_with? '>' }
tmux . send_keys :PgDn
2017-05-24 13:20:13 +09:00
tmux . until { | lines | lines [- 3 ]. start_with? '>' }
tmux . send_keys :Down
2015-06-16 23:14:57 +09:00
tmux . until { | lines | lines [- 10 ]. start_with? '>' }
end
2015-07-22 13:45:38 +09: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 23:29:02 +09:00
lines [- 3 ] == ' 1' &&
lines [- 4 ] == ' 2' &&
lines [- 13 ] == '> 50'
2015-07-22 13:45:38 +09:00
end
tmux . send_keys :Down
end
tmux . send_keys :Enter
2016-04-16 14:02:43 +09:00
assert_equal '50' , readonce . chomp
2015-07-22 13:45:38 +09: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 23:29:02 +09:00
lines [ 2 ] == ' 1' &&
lines [ 3 ] == ' 2' &&
lines [ 12 ] == '> 50'
2015-07-22 13:45:38 +09:00
end
tmux . send_keys :Up
end
tmux . send_keys :Enter
2016-04-16 14:02:43 +09:00
assert_equal '50' , readonce . chomp
2015-07-22 13:45:38 +09:00
end
2018-06-10 01:41:50 +09: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 13:45:38 +09:00
def test_header_lines_overflow
tmux . send_keys "seq 100 | #{ fzf '--header-lines=200' } " , :Enter
2015-07-22 21:22:59 +09:00
tmux . until do | lines |
lines [- 2 ]. include? ( '0/0' ) &&
2017-08-04 23:29:02 +09:00
lines [- 3 ]. include? ( ' 1' )
2015-07-22 21:22:59 +09:00
end
2015-07-22 13:45:38 +09:00
tmux . send_keys :Enter
assert_equal '' , readonce . chomp
end
2015-07-22 21:24:02 +09:00
def test_header_lines_with_nth
2017-08-04 23:29:02 +09:00
tmux . send_keys "seq 100 | #{ fzf '--header-lines 5 --with-nth 1,1,1,1,1' } " , :Enter
2015-07-22 21:24:02 +09:00
tmux . until do | lines |
lines [- 2 ]. include? ( '95/95' ) &&
2017-08-04 23:29:02 +09:00
lines [- 3 ] == ' 11111' &&
lines [- 7 ] == ' 55555' &&
lines [- 8 ] == '> 66666'
2015-07-22 21:24:02 +09:00
end
tmux . send_keys :Enter
assert_equal '6' , readonce . chomp
end
2015-09-15 19:04:53 +09:00
def test_header
2020-02-28 04:06:38 -07:00
tmux . send_keys "seq 100 | #{ fzf "--header \" $(head -5 #{ FILE } ) \" " } " , :Enter
2015-11-30 17:32:16 +09:00
header = File . readlines ( FILE ) . take ( 5 ) . map ( & :strip )
2015-07-22 13:45:38 +09:00
tmux . until do | lines |
lines [- 2 ]. include? ( '100/100' ) &&
2018-06-10 01:41:50 +09:00
lines [- 7 ..- 3 ]. map ( & :strip ) == header &&
lines [- 8 ] == '> 1'
2015-07-22 13:45:38 +09:00
end
end
2015-09-15 19:04:53 +09:00
def test_header_reverse
2020-02-28 04:06:38 -07:00
tmux . send_keys "seq 100 | #{ fzf "--header \" $(head -5 #{ FILE } ) \" --reverse" } " , :Enter
2015-11-30 17:32:16 +09:00
header = File . readlines ( FILE ) . take ( 5 ) . map ( & :strip )
2015-07-22 13:45:38 +09:00
tmux . until do | lines |
lines [ 1 ]. include? ( '100/100' ) &&
2018-06-10 01:41:50 +09:00
lines [ 2 .. 6 ]. map ( & :strip ) == header &&
lines [ 7 ] == '> 1'
end
end
def test_header_reverse_list
2020-02-28 04:06:38 -07:00
tmux . send_keys "seq 100 | #{ fzf "--header \" $(head -5 #{ FILE } ) \" --layout=reverse-list" } " , :Enter
2018-06-10 01:41:50 +09: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 13:45:38 +09:00
end
end
2015-09-15 19:04:53 +09:00
def test_header_and_header_lines
2020-02-28 04:06:38 -07:00
tmux . send_keys "seq 100 | #{ fzf "--header-lines 10 --header \" $(head -5 #{ FILE } ) \" " } " , :Enter
2015-11-30 17:32:16 +09:00
header = File . readlines ( FILE ) . take ( 5 ) . map ( & :strip )
2015-09-15 19:04:53 +09:00
tmux . until do | lines |
lines [- 2 ]. include? ( '90/90' ) &&
2017-08-04 23:29:02 +09:00
lines [- 7 ...- 2 ]. map ( & :strip ) == header &&
lines [- 17 ...- 7 ]. map ( & :strip ) == ( 1 .. 10 ) . map ( & :to_s ) . reverse
2015-09-15 19:04:53 +09:00
end
end
def test_header_and_header_lines_reverse
2020-02-28 04:06:38 -07:00
tmux . send_keys "seq 100 | #{ fzf "--reverse --header-lines 10 --header \" $(head -5 #{ FILE } ) \" " } " , :Enter
2015-11-30 17:32:16 +09:00
header = File . readlines ( FILE ) . take ( 5 ) . map ( & :strip )
2015-09-15 19:04:53 +09:00
tmux . until do | lines |
lines [ 1 ]. include? ( '90/90' ) &&
2017-08-04 23:29:02 +09:00
lines [ 2 ... 7 ]. map ( & :strip ) == header &&
lines [ 7 ... 17 ]. map ( & :strip ) == ( 1 .. 10 ) . map ( & :to_s )
2015-09-15 19:04:53 +09:00
end
end
2018-06-10 01:41:50 +09:00
def test_header_and_header_lines_reverse_list
2020-02-28 04:06:38 -07:00
tmux . send_keys "seq 100 | #{ fzf "--layout=reverse-list --header-lines 10 --header \" $(head -5 #{ FILE } ) \" " } " , :Enter
2018-06-10 01:41:50 +09: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-13 00:44:27 +09:00
def test_cancel
2017-08-04 23:29:02 +09:00
tmux . send_keys "seq 10 | #{ fzf '--bind 2:cancel' } " , :Enter
2015-07-23 21:05:33 +09:00
tmux . until { | lines | lines [- 2 ]. include? ( '10/10' ) }
2015-07-22 22:56:53 +09:00
tmux . send_keys '123'
2015-07-23 21:05:33 +09: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 22:56:53 +09:00
tmux . until { | lines | lines [- 1 ] == '>' }
tmux . send_keys 2
tmux . prepare
end
2015-07-26 23:02:04 +09:00
def test_margin
2017-08-04 23:29:02 +09:00
tmux . send_keys "yes | head -1000 | #{ fzf '--margin 5,3' } " , :Enter
2015-07-26 23:02:04 +09:00
tmux . until { | lines | lines [ 4 ] == '' && lines [ 5 ] == ' y' }
tmux . send_keys :Enter
end
def test_margin_reverse
2017-08-04 23:29:02 +09:00
tmux . send_keys "seq 1000 | #{ fzf '--margin 7,5 --reverse' } " , :Enter
2015-07-26 23:02:04 +09:00
tmux . until { | lines | lines [ 1 + 7 ] == ' 1000/1000' }
tmux . send_keys :Enter
end
2018-06-10 01:41:50 +09: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 17:35:03 +09: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 23:29:02 +09:00
9 => '> f oo ba r baz barfooq ux'
2015-11-30 17:35:03 +09:00
} . each do | ts , exp |
tmux . prepare
2017-08-04 23:29:02 +09: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 17:35:03 +09:00
tmux . send_keys :Enter
end
end
2017-08-04 23:29:02 +09:00
def test_with_nth_basic
2015-08-26 23:35:31 +09:00
writelines tempname , [ 'hello world ' , 'byebye' ]
2017-08-04 23:29:02 +09:00
assert_equal (
'hello world ' ,
` #{ FZF } -f"^he hehe" -x -n 2.. --with-nth 2,1,1 < #{ tempname } ` . chomp
)
2015-08-26 23:35:31 +09:00
end
def test_with_nth_ansi
writelines tempname , [ " \x1b [33mhello \x1b [34;1mworld \x1b [m " , 'byebye' ]
2017-08-04 23:29:02 +09:00
assert_equal (
'hello world ' ,
` #{ FZF } -f"^he hehe" -x -n 2.. --with-nth 2,1,1 --ansi < #{ tempname } ` . chomp
)
2015-08-26 23:35:31 +09:00
end
2015-08-28 21:23:10 +09:00
def test_with_nth_no_ansi
src = " \x1b [33mhello \x1b [34;1mworld \x1b [m "
writelines tempname , [ src , 'byebye' ]
2017-08-04 23:29:02 +09:00
assert_equal (
src ,
` #{ FZF } -fhehe -x -n 2.. --with-nth 2,1,1 --no-ansi < #{ tempname } ` . chomp
)
2015-08-28 21:23:10 +09:00
end
2015-09-15 13:21:51 +09:00
def test_exit_0_exit_code
`echo foo | #{ FZF } -q bar -0`
2017-08-04 23:29:02 +09:00
assert_equal 1 , $CHILD_STATUS . exitstatus
2015-09-15 13:21:51 +09:00
end
def test_invalid_option
lines = ` #{ FZF } --foobar 2>&1`
2017-08-04 23:29:02 +09:00
assert_equal 2 , $CHILD_STATUS . exitstatus
2015-09-15 13:21:51 +09:00
assert lines . include? ( 'unknown option: --foobar' ), lines
end
def test_filter_exitstatus
# filter / streaming filter
2017-08-04 23:29:02 +09:00
[ '' , '--no-sort' ]. each do | opts |
2015-09-15 13:21:51 +09:00
assert `echo foo | #{ FZF } -f foo #{ opts } ` . include? ( 'foo' )
2017-08-04 23:29:02 +09:00
assert_equal 0 , $CHILD_STATUS . exitstatus
2015-09-15 13:21:51 +09:00
assert `echo foo | #{ FZF } -f bar #{ opts } ` . empty?
2017-08-04 23:29:02 +09:00
assert_equal 1 , $CHILD_STATUS . exitstatus
2015-09-15 13:21:51 +09:00
end
end
def test_exitstatus_empty
{ '99' => '0' , '999' => '1' } . each do | query , status |
2020-02-28 04:06:38 -07:00
tmux . send_keys "seq 100 | #{ FZF } -q #{ query } ; echo --$?--" , :Enter
2015-09-15 13:21:51 +09: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 22:49:32 +09: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-10 01:50:41 +09: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 23:29:02 +09:00
`seq 10 | #{ FZF } -f '1 | !1'` . lines . map ( & :chomp )
2015-11-10 01:50:41 +09:00
end
2016-03-02 03:06:21 +09:00
def test_hscroll_off
2017-08-04 23:29:02 +09:00
writelines tempname , [ '=' * 10_000 + '0123456789' ]
2016-03-02 03:06:21 +09: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-24 03:30:51 +09: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-18 02:06:52 +09: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 23:29:02 +09:00
assert_equal %w[5 2 1] , readonce . split ( $INPUT_RECORD_SEPARATOR )
2016-05-18 02:06:52 +09: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 10:19:03 +09: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 19:59:12 +09:00
def test_preview
2017-08-04 23:29:02 +09:00
tmux . send_keys %(seq 1000 | sed s/^2$// | #{ FZF } -m --preview 'sleep 0.2; echo {{}-{+}}' --bind ?:toggle-preview) , :Enter
2016-06-11 19:59:12 +09:00
tmux . until { | lines | lines [ 1 ]. include? ( ' {1-1}' ) }
2016-06-15 13:03:42 +09:00
tmux . send_keys :Up
tmux . until { | lines | lines [ 1 ]. include? ( ' {-}' ) }
2016-06-11 19:59:12 +09: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 13:03:42 +09: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 16:38:42 +09: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 19:59:12 +09:00
end
def test_preview_hidden
2020-02-28 04:06:38 -07: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 19:59:12 +09:00
tmux . until { | lines | lines [- 1 ] == '>' }
tmux . send_keys '?'
2017-12-01 12:04:01 +09:00
tmux . until { | lines | lines [- 2 ] =~ / {1-1-1-[0-9]+}/ }
2016-06-11 19:59:12 +09:00
tmux . send_keys '555'
2017-12-01 12:04:01 +09:00
tmux . until { | lines | lines [- 2 ] =~ / {555-555-1-[0-9]+}/ }
2016-06-11 19:59:12 +09:00
tmux . send_keys '?'
tmux . until { | lines | lines [- 1 ] == '> 555' }
end
2017-01-24 00:23:16 +09:00
def test_preview_size_0
2017-08-04 23:29:02 +09: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-24 00:23:16 +09:00
tmux . until { | lines | lines . item_count == 100 && lines [ 1 ] == ' 100/100' && lines [ 2 ] == '> 1' }
2017-08-04 23:29:02 +09:00
tmux . until { | _ | %w[1] == File . readlines ( tempname ) . map ( & :chomp ) }
2017-01-24 00:23:16 +09:00
tmux . send_keys :Down
tmux . until { | lines | lines [ 3 ] == '> 2' }
2017-08-04 23:29:02 +09:00
tmux . until { | _ | %w[1 2] == File . readlines ( tempname ) . map ( & :chomp ) }
2017-01-24 00:23:16 +09:00
tmux . send_keys :Down
tmux . until { | lines | lines [ 4 ] == '> 3' }
2017-08-04 23:29:02 +09:00
tmux . until { | _ | %w[1 2 3] == File . readlines ( tempname ) . map ( & :chomp ) }
2017-01-24 00:23:16 +09:00
end
2017-03-04 14:26:47 +09:00
2018-06-10 01:40:22 +09:00
def test_preview_flags
tmux . send_keys %(seq 10 | sed 's/^/:: /; s/$/ /' |
2019-02-19 01:12:57 +09: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-10 01:40:22 +09:00
tmux . send_keys '123'
2019-02-19 01:12:57 +09:00
tmux . until { | lines | lines [ 1 ]. include? ( '{////123//}' ) }
2018-06-10 01:40:22 +09:00
tmux . send_keys 'C-u' , '1'
tmux . until { | lines | lines . match_count == 2 }
2019-02-19 01:12:57 +09:00
tmux . until { | lines | lines [ 1 ]. include? ( '{1/1 /1/1 /1/0/0}' ) }
2018-06-10 01:40:22 +09:00
tmux . send_keys :BTab
2019-02-19 01:12:57 +09:00
tmux . until { | lines | lines [ 1 ]. include? ( '{10/10 /1/1 /1/9/0}' ) }
2018-06-10 01:40:22 +09:00
tmux . send_keys :BTab
2019-02-19 01:12:57 +09:00
tmux . until { | lines | lines [ 1 ]. include? ( '{10/10 /1 10/1 10 /1/9/0 9}' ) }
2018-06-10 01:40:22 +09:00
tmux . send_keys '2'
2019-02-19 01:12:57 +09:00
tmux . until { | lines | lines [ 1 ]. include? ( '{//1 10/1 10 /12//0 9}' ) }
2018-06-10 01:40:22 +09:00
tmux . send_keys '3'
2019-02-19 01:12:57 +09:00
tmux . until { | lines | lines [ 1 ]. include? ( '{//1 10/1 10 /123//0 9}' ) }
2018-06-10 01:40:22 +09: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-10 01:40:22 +09: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 18:45:55 +09: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 14:26:47 +09:00
def test_no_clear
2017-07-18 20:50:38 +09:00
tmux . send_keys "seq 10 | fzf --no-clear --inline-info --height 5 > #{ tempname } " , :Enter
prompt = '> < 10/10'
2017-03-04 14:26:47 +09:00
tmux . until { | lines | lines [- 1 ] == prompt }
tmux . send_keys :Enter
2017-07-18 20:50:38 +09:00
tmux . until { | _ | %w[1] == File . readlines ( tempname ) . map ( & :chomp ) }
tmux . until { | lines | lines [- 1 ] == prompt }
2017-03-04 14:26:47 +09:00
end
2017-05-22 17:07:05 +09:00
2019-11-15 00:39:29 +09:00
def test_info_hidden
tmux . send_keys 'seq 10 | fzf --info=hidden' , :Enter
tmux . until { | lines | lines [- 2 ] == '> 1' }
end
2017-05-22 17:07:05 +09:00
def test_change_top
2017-08-04 23:29:02 +09:00
tmux . send_keys %(seq 1000 | #{ FZF } --bind change:top) , :Enter
2017-05-22 17:07:05 +09: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-28 01:39:25 +09:00
2017-12-02 02:27:02 +09: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-28 01:39:25 +09: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 23:29:02 +09:00
tmux . until { | lines | lines . none? { | line | line . include? '1 2 3 4 5' } }
2017-07-28 01:39:25 +09:00
end
2017-08-09 23:25:32 +09: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 13:09:33 +09:00
assert_equal input.lines.count - 1, `#{FZF} -f' ^ foo bar $' < #{tempname}`.lines.count
2017-08-09 23:25:32 +09: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 13:09:33 +09:00
assert_equal input . lines . count - 1 , ` #{ FZF } -f'!^foo \\ bar$' < #{ tempname } ` . lines . count
2017-08-10 12:40:53 +09:00
end
2018-12-19 23:05:29 +09: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 11:52:18 +09: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 13:13:45 +09: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-12 00:57:19 +09: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-12 00:10:24 +09:00
tmux . until { | lines | lines . match_count == 998 }
2019-11-10 13:13:45 +09:00
tmux . send_keys 'a'
2019-11-12 00:10:24 +09:00
tmux . until { | lines | lines . item_count == 98 && lines . match_count == 98 }
2019-11-10 13:13:45 +09:00
tmux . send_keys 'b'
2019-11-12 00:10:24 +09:00
tmux . until { | lines | lines . item_count == 198 && lines . match_count == 198 }
2019-11-12 00:57:19 +09:00
tmux . send_keys :Tab
tmux . until { | lines | lines [- 2 ]. include? ( '(1/2)' ) }
2019-11-10 13:13:45 +09:00
tmux . send_keys '555'
2019-11-12 00:10:24 +09:00
tmux . until { | lines | lines . item_count == 553 && lines . match_count == 1 }
2019-11-12 00:57:19 +09:00
tmux . until { | lines | ! lines [- 2 ]. include? ( '(1/2)' ) }
2019-11-10 13:13:45 +09:00
end
2019-12-06 22:34:30 +09: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 22:34:45 +09: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 14:44:24 +09: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 10:38:32 -07: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 20:55:29 +09: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-17 04:55:29 +09:00
end
2015-03-01 03:00:36 +09:00
module TestShell
def setup
2020-02-28 02:47:13 -07:00
@tmux = Tmux . new shell
tmux . prepare
2015-03-01 03:00:36 +09:00
end
def teardown
@tmux . kill
end
2017-08-04 23:29:02 +09:00
def set_var ( name , val )
2015-06-26 01:00:58 +09:00
tmux . prepare
tmux . send_keys "export #{ name } =' #{ val } '" , :Enter
tmux . prepare
end
2017-08-04 23:29:02 +09:00
def unset_var ( name )
2017-01-08 01:30:31 +09:00
tmux . prepare
tmux . send_keys "unset #{ name } " , :Enter
2015-03-01 03:00:36 +09:00
tmux . prepare
end
2017-01-08 01:30:31 +09:00
def test_ctrl_t
2017-08-04 23:29:02 +09:00
set_var 'FZF_CTRL_T_COMMAND' , 'seq 100'
2017-01-08 01:30:31 +09:00
2017-08-04 23:29:02 +09:00
retries do
2017-01-09 13:22:24 +09:00
tmux . prepare
tmux . send_keys 'C-t'
tmux . until { | lines | lines . item_count == 100 }
end
2017-01-08 01:30:31 +09: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-26 01:00:58 +09:00
end
2016-04-25 00:53:11 +09:00
def test_ctrl_t_unicode
2017-01-08 01:30:31 +09:00
writelines tempname , [ 'fzf-unicode 테스트1' , 'fzf-unicode 테스트2' ]
2017-08-04 23:29:02 +09:00
set_var 'FZF_CTRL_T_COMMAND' , "cat #{ tempname } "
2017-01-08 01:30:31 +09:00
2017-01-09 13:22:24 +09:00
retries do
tmux . prepare
tmux . send_keys 'echo ' , 'C-t'
tmux . until { | lines | lines . item_count == 2 }
end
2017-01-08 01:30:31 +09:00
tmux . send_keys 'fzf-unicode'
tmux . until { | lines | lines . match_count == 2 }
2016-07-10 15:44:44 +09:00
2017-01-08 01:30:31 +09: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 15:44:44 +09:00
2017-01-08 01:30:31 +09:00
tmux . send_keys :BSpace
tmux . until { | lines | lines . match_count == 2 }
2016-07-10 15:44:44 +09:00
2017-01-08 01:30:31 +09:00
tmux . send_keys '2'
tmux . until { | lines | lines . match_count == 1 }
tmux . send_keys :Tab
tmux . until { | lines | lines . select_count == 2 }
2016-07-10 15:44:44 +09:00
2016-04-25 00:53:11 +09:00
tmux . send_keys :Enter
2020-02-20 17:51:34 -07:00
tmux . until { | lines | lines . join . match ( /echo.*fzf-unicode.*1.*fzf-unicode.*2/ ) }
2017-01-08 01:30:31 +09:00
tmux . send_keys :Enter
2017-08-04 23:29:02 +09:00
tmux . until { | lines | lines . any_include? ( /^fzf-unicode.*1.*fzf-unicode.*2/ ) }
2016-04-25 00:53:11 +09:00
end
2015-03-01 03:00:36 +09:00
def test_alt_c
2017-01-09 13:22:24 +09:00
lines = retries do
tmux . prepare
tmux . send_keys :Escape , :c
2018-06-01 18:21:34 +09:00
tmux . until { | lines | lines . match_count . positive? }
2017-01-09 13:22:24 +09:00
end
2017-01-08 01:30:31 +09:00
expected = lines . reverse . select { | l | l . start_with? '>' } . first [ 2 ..- 1 ]
tmux . send_keys :Enter
2015-03-01 03:00:36 +09:00
tmux . prepare
tmux . send_keys :pwd , :Enter
2015-04-25 10:54:47 +09:00
tmux . until { | lines | lines [- 1 ]. end_with? ( expected ) }
2015-03-01 03:00:36 +09:00
end
2015-11-08 00:11:46 +09:00
def test_alt_c_command
set_var 'FZF_ALT_C_COMMAND' , 'echo /tmp'
tmux . prepare
tmux . send_keys 'cd /' , :Enter
2017-01-09 13:22:24 +09:00
retries do
tmux . prepare
tmux . send_keys :Escape , :c
2017-08-04 23:29:02 +09:00
tmux . until { | lines | lines . item_count == 1 }
2017-01-09 13:22:24 +09:00
end
2017-01-08 01:30:31 +09:00
tmux . send_keys :Enter
2015-11-08 00:11:46 +09:00
tmux . prepare
tmux . send_keys :pwd , :Enter
tmux . until { | lines | lines [- 1 ]. end_with? '/tmp' }
end
2015-03-01 03:00:36 +09: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 13:22:24 +09:00
tmux . send_keys 'echo 4th' , :Enter
retries do
tmux . prepare
tmux . send_keys 'C-r'
2018-06-01 18:21:34 +09:00
tmux . until { | lines | lines . match_count . positive? }
2017-01-09 13:22:24 +09:00
end
2017-03-03 12:20:01 +09:00
tmux . send_keys 'C-r'
2017-01-08 01:30:31 +09:00
tmux . send_keys '3d'
tmux . until { | lines | lines [- 3 ]. end_with? 'echo 3rd' }
tmux . send_keys :Enter
2015-03-01 03:00:36 +09:00
tmux . until { | lines | lines [- 1 ] == 'echo 3rd' }
tmux . send_keys :Enter
tmux . until { | lines | lines [- 1 ] == '3rd' }
end
2017-01-09 13:22:24 +09:00
2020-02-28 04:06:38 -07: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 19:56:06 +09:00
retries do
tmux . prepare
tmux . send_keys 'C-r'
tmux . until { | lines | lines [- 1 ] == '>' }
end
2020-02-28 04:06:38 -07: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 02:47:13 -07: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 11:54:05 +09:00
%w[foo ' "] . each do | query |
2020-03-07 19:56:06 +09: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 11:54:05 +09:00
tmux . send_keys 'C-g'
tmux . until { | lines | lines [- 1 ]. start_with? query }
end
2020-02-28 02:47:13 -07:00
end
2017-08-04 23:29:02 +09:00
def retries ( times = 3 )
( times - 1 ) . times do
2017-01-09 13:22:24 +09:00
begin
2017-08-04 23:29:02 +09:00
return yield
2017-01-09 13:22:24 +09:00
rescue RuntimeError
end
end
2017-08-04 23:29:02 +09:00
yield
2017-01-09 13:22:24 +09:00
end
2015-03-01 03:00:36 +09:00
end
2015-05-09 20:15:14 +09:00
module CompletionTest
2015-03-01 03:00:36 +09:00
def test_file_completion
2015-05-12 01:40:44 +09: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 19:47:48 +09:00
[ 'no~such~user' , '/tmp/fzf test/foobar' , '~/.fzf-home' ]. each do | f |
2015-05-12 01:40:44 +09:00
FileUtils . touch File . expand_path ( f )
end
2015-03-01 03:00:36 +09:00
tmux . prepare
2017-01-08 01:30:31 +09:00
tmux . send_keys 'cat /tmp/fzf-test/10**' , :Tab
2018-06-01 18:21:34 +09:00
tmux . until { | lines | lines . match_count . positive? }
2015-12-29 00:00:20 +09:00
tmux . send_keys ' !d'
2017-01-08 01:30:31 +09:00
tmux . until { | lines | lines . match_count == 2 }
tmux . send_keys :Tab , :Tab
tmux . until { | lines | lines . select_count == 2 }
2015-07-13 19:24:22 +09:00
tmux . send_keys :Enter
2017-01-21 04:17:51 +09:00
tmux . until ( true ) do | lines |
2015-03-01 03:00:36 +09:00
lines [- 1 ]. include? ( '/tmp/fzf-test/10' ) &&
2017-08-04 23:29:02 +09:00
lines [- 1 ]. include? ( '/tmp/fzf-test/100' )
2015-04-14 02:00:50 +09:00
end
2015-05-10 02:35:00 +09:00
# ~USERNAME**<TAB>
tmux . send_keys 'C-u'
2017-01-08 01:30:31 +09:00
tmux . send_keys "cat ~ #{ ENV [ 'USER' ] } **" , :Tab
2018-06-01 18:21:34 +09:00
tmux . until { | lines | lines . match_count . positive? }
2017-01-08 01:30:31 +09:00
tmux . send_keys "'.fzf-home"
tmux . until { | lines | lines . select { | l | l . include? '.fzf-home' } . count > 1 }
2015-05-10 02:35:00 +09:00
tmux . send_keys :Enter
2017-01-21 04:17:51 +09:00
tmux . until ( true ) do | lines |
2015-05-20 19:47:48 +09:00
lines [- 1 ]. end_with? ( '.fzf-home' )
2015-05-10 02:54:22 +09:00
end
# ~INVALID_USERNAME**<TAB>
tmux . send_keys 'C-u'
2017-08-04 23:29:02 +09:00
tmux . send_keys 'cat ~such**' , :Tab
2017-01-21 04:17:51 +09:00
tmux . until ( true ) { | lines | lines . any_include? 'no~such~user' }
2015-05-10 02:54:22 +09:00
tmux . send_keys :Enter
2017-01-21 04:17:51 +09:00
tmux . until ( true ) { | lines | lines [- 1 ]. end_with? ( 'no~such~user' ) }
2015-05-12 01:40:44 +09:00
# /tmp/fzf\ test**<TAB>
tmux . send_keys 'C-u'
2017-01-08 01:30:31 +09:00
tmux . send_keys 'cat /tmp/fzf\ test/**' , :Tab
2018-06-01 18:21:34 +09:00
tmux . until { | lines | lines . match_count . positive? }
2017-01-08 01:30:31 +09:00
tmux . send_keys 'foobar$'
tmux . until { | lines | lines . match_count == 1 }
tmux . send_keys :Enter
2017-01-21 04:17:51 +09:00
tmux . until ( true ) { | lines | lines [- 1 ]. end_with? ( '/tmp/fzf\ test/foobar' ) }
2015-12-29 00:00:20 +09:00
# Should include hidden files
( 1 .. 100 ) . each { | i | FileUtils . touch "/tmp/fzf-test/.hidden- #{ i } " }
tmux . send_keys 'C-u'
2017-01-08 01:30:31 +09:00
tmux . send_keys 'cat /tmp/fzf-test/hidden**' , :Tab
2017-01-21 04:17:51 +09:00
tmux . until ( true ) { | lines | lines . match_count == 100 && lines . any_include? ( '/tmp/fzf-test/.hidden-' ) }
2016-03-06 12:46:28 +09:00
tmux . send_keys :Enter
2015-05-10 05:01:52 +09:00
ensure
2015-05-20 19:47:48 +09:00
[ '/tmp/fzf-test' , '/tmp/fzf test' , '~/.fzf-home' , 'no~such~user' ]. each do | f |
2015-05-12 01:40:44 +09:00
FileUtils . rm_rf File . expand_path ( f )
end
2015-03-01 03:00:36 +09:00
end
2015-12-29 13:02:16 +09:00
def test_file_completion_root
2017-01-08 01:30:31 +09:00
tmux . send_keys 'ls /**' , :Tab
2018-06-01 18:21:34 +09:00
tmux . until { | lines | lines . match_count . positive? }
2015-12-29 13:02:16 +09:00
tmux . send_keys :Enter
end
2015-03-01 03:00:36 +09:00
def test_dir_completion
2017-01-08 01:30:31 +09:00
( 1 .. 100 ) . each do | idx |
FileUtils . mkdir_p "/tmp/fzf-test/d #{ idx } "
end
FileUtils . touch '/tmp/fzf-test/d55/xxx'
2015-03-01 03:00:36 +09:00
tmux . prepare
2017-01-08 01:30:31 +09:00
tmux . send_keys 'cd /tmp/fzf-test/**' , :Tab
2018-06-01 18:21:34 +09:00
tmux . until { | lines | lines . match_count . positive? }
2017-01-08 01:30:31 +09:00
tmux . send_keys :Tab , :Tab # Tab does not work here
2015-03-01 03:00:36 +09:00
tmux . send_keys 55
2017-01-08 01:30:31 +09:00
tmux . until { | lines | lines . match_count == 1 }
2015-03-01 03:00:36 +09:00
tmux . send_keys :Enter
2017-01-21 04:17:51 +09:00
tmux . until ( true ) { | lines | lines [- 1 ] == 'cd /tmp/fzf-test/d55/' }
2015-03-04 12:59:23 +09:00
tmux . send_keys :xx
tmux . until { | lines | lines [- 1 ] == 'cd /tmp/fzf-test/d55/xx' }
2015-03-04 13:13:11 +09:00
2015-05-09 20:15:14 +09: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 13:13:11 +09: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-03-01 03:00:36 +09: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-08 01:30:31 +09:00
tmux . send_keys 'C-L'
tmux . send_keys 'kill ' , :Tab
2018-06-01 18:21:34 +09:00
tmux . until { | lines | lines . match_count . positive? }
2015-03-01 03:00:36 +09:00
tmux . send_keys 'sleep12345'
2017-01-08 01:30:31 +09:00
tmux . until { | lines | lines . any_include? 'sleep 12345' }
2015-03-01 03:00:36 +09:00
tmux . send_keys :Enter
2017-01-21 04:17:51 +09:00
tmux . until ( true ) { | lines | lines [- 1 ]. include? "kill #{ pid } " }
2015-05-10 11:21:21 +09:00
ensure
2017-08-04 23:29:02 +09:00
if pid
begin
Process . kill 'KILL' , pid . to_i
rescue
nil
end
end
2015-03-01 03:00:36 +09:00
end
2016-02-16 12:32:05 +09:00
def test_custom_completion
2020-02-28 04:06:38 -07:00
tmux . send_keys '_fzf_compgen_path() { echo "$1"; seq 10; }' , :Enter
2016-02-16 12:32:05 +09:00
tmux . prepare
2017-01-08 01:30:31 +09:00
tmux . send_keys 'ls /tmp/**' , :Tab
2018-06-01 18:21:34 +09:00
tmux . until { | lines | lines . match_count == 11 }
2017-01-08 01:30:31 +09:00
tmux . send_keys :Tab , :Tab , :Tab
tmux . until { | lines | lines . select_count == 3 }
2016-02-16 12:32:05 +09:00
tmux . send_keys :Enter
2017-08-04 23:29:02 +09:00
tmux . until ( true ) { | lines | lines [- 1 ] == 'ls /tmp 1 2' }
2016-02-16 12:32:05 +09:00
end
def test_unset_completion
2017-01-08 01:30:31 +09:00
tmux . send_keys 'export FZFFOOBAR=BAZ' , :Enter
2016-02-16 12:32:05 +09:00
tmux . prepare
# Using tmux
2017-02-04 22:49:17 +09:00
tmux . send_keys 'unset FZFFOOBR**' , :Tab
2017-01-08 01:30:31 +09:00
tmux . until { | lines | lines . match_count == 1 }
2016-02-16 12:32:05 +09:00
tmux . send_keys :Enter
2017-01-08 01:30:31 +09:00
tmux . until { | lines | lines [- 1 ]. include? 'unset FZFFOOBAR' }
2016-02-16 12:32:05 +09:00
tmux . send_keys 'C-c'
2017-01-08 01:30:31 +09:00
# FZF_TMUX=1
2016-02-16 12:32:05 +09:00
new_shell
2017-02-04 22:49:17 +09:00
tmux . send_keys 'unset FZFFOOBR**' , :Tab , pane : 0
2017-01-21 04:17:51 +09:00
tmux . until ( false , 1 ) { | lines | lines . match_count == 1 }
2016-02-16 12:32:05 +09:00
tmux . send_keys :Enter
2017-01-08 01:30:31 +09:00
tmux . until { | lines | lines [- 1 ]. include? 'unset FZFFOOBAR' }
2016-02-16 12:32:05 +09:00
end
2016-04-25 00:53:11 +09:00
def test_file_completion_unicode
FileUtils . mkdir_p '/tmp/fzf-test'
2020-02-20 17:51:34 -07: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-25 00:53:11 +09:00
tmux . prepare
2017-01-08 01:30:31 +09:00
tmux . send_keys 'cat fzf-unicode**' , :Tab
tmux . until { | lines | lines . match_count == 2 }
2016-07-10 15:44:44 +09:00
2017-01-08 01:30:31 +09: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 15:44:44 +09:00
2017-01-08 01:30:31 +09:00
tmux . send_keys :BSpace
tmux . until { | lines | lines . match_count == 2 }
2016-07-10 15:44:44 +09:00
2017-01-08 01:30:31 +09: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 15:44:44 +09:00
2017-01-08 01:30:31 +09:00
tmux . send_keys :Enter
2017-01-21 04:17:51 +09:00
tmux . until ( true ) { | lines | lines . any_include? 'cat' }
2016-04-25 00:53:11 +09:00
tmux . send_keys :Enter
tmux . until { | lines | lines [- 1 ]. include? 'test3test4' }
end
2020-03-11 18:29:39 +09:00
def test_custom_completion_api
%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
end
2015-03-01 03:00:36 +09:00
end
2015-05-09 20:15:14 +09:00
class TestBash < TestBase
include TestShell
include CompletionTest
2020-02-28 02:47:13 -07:00
def shell
:bash
end
2015-05-09 20:15:14 +09:00
def new_shell
2015-06-14 23:44:42 +09:00
tmux . prepare
2017-01-08 01:30:31 +09:00
tmux . send_keys "FZF_TMUX=1 #{ Shell . bash } " , :Enter
2015-05-09 20:15:14 +09:00
tmux . prepare
end
2017-12-03 03:06:10 +09: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 18:21:34 +09:00
tmux . until { | lines | lines . match_count . positive? }
2017-12-03 03:06:10 +09: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 18:21:34 +09:00
tmux . until { | lines | lines . match_count . positive? }
2017-12-03 03:06:10 +09:00
end
2015-05-09 20:15:14 +09:00
end
2015-03-01 03:00:36 +09:00
class TestZsh < TestBase
include TestShell
2015-05-09 20:15:14 +09:00
include CompletionTest
2015-03-01 03:00:36 +09:00
2020-02-28 02:47:13 -07:00
def shell
:zsh
end
2015-03-01 03:00:36 +09:00
def new_shell
2017-01-08 01:30:31 +09:00
tmux . send_keys "FZF_TMUX=1 #{ Shell . zsh } " , :Enter
2015-03-01 03:00:36 +09:00
tmux . prepare
end
end
class TestFish < TestBase
include TestShell
2020-02-28 02:47:13 -07:00
def shell
:fish
end
2015-03-01 03:00:36 +09:00
def new_shell
2017-01-08 01:30:31 +09:00
tmux . send_keys 'env FZF_TMUX=1 fish' , :Enter
2015-03-01 03:00:36 +09:00
tmux . send_keys 'function fish_prompt; end; clear' , :Enter
2017-08-04 23:29:02 +09:00
tmux . until ( & :empty? )
2015-03-01 03:00:36 +09:00
end
2017-08-04 23:29:02 +09:00
def set_var ( name , val )
2015-06-26 01:00:58 +09:00
tmux . prepare
2015-07-13 19:24:22 +09:00
tmux . send_keys "set -g #{ name } ' #{ val } '" , :Enter
2015-06-26 01:00:58 +09:00
tmux . prepare
end
2015-03-01 03:00:36 +09:00
end
2020-02-28 15:38:39 +09: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/null
# Key bindings
# ------------
source "<%= BASE %>/shell/key-bindings.<%= __method__ %>"
PS1= PROMPT_COMMAND= HISTFILE= HISTSIZE=100
unset <%= UNSETS.join(' ') %>
2020-03-11 18:29:39 +09: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
_fzf_comprun() {
local command=$1
shift
case "$command" in
f) fzf "$@" --preview 'echo preview-f-{}' ;;
g) fzf "$@" --preview 'echo preview-g-{}' ;;
*) fzf "$@" ;;
esac
}