Compare commits

...

16 Commits

Author SHA1 Message Date
Junegunn Choi
35a9aff8e1 0.12.1 2016-04-25 01:23:52 +09:00
Junegunn Choi
988c9bd9be [zsh] Fix issues with unicode characters 2016-04-25 01:04:35 +09:00
Junegunn Choi
095f31b316 [vim] Explicitly set source to FZF_DEFAULT_COMMAND
Helps when your `$SHELL` is slow.

Close #552.
2016-04-24 18:02:01 +09:00
Junegunn Choi
d86cee2a69 [bash] Export fzf-file-widget function for bash 4+ (#546)
e.g. Remapping fzf-file-widget to CTRL-X CTRL-T intead of CTRL-T

    bind -x '"\C-x\C-t": fzf-file-widget'
    bind '"\C-t": transpose-chars'
2016-04-24 14:04:15 +09:00
Junegunn Choi
e986f20a85 [fish] Use consistent function names for key bindings (#546)
- fzf-file-widget
- fzf-history-widget
- fzf-cd-widget
2016-04-24 13:56:50 +09:00
Junegunn Choi
c727ba1d99 [fzf-tmux] Do not split pane if the height is too small 2016-04-24 13:32:33 +09:00
Junegunn Choi
bb70923cd8 Fix flaky test cases 2016-04-24 04:52:01 +09:00
Junegunn Choi
772fa42dcb [fish] Fix intermittent errors on CTRL-T
Related: 23244bb
2016-04-24 04:51:35 +09:00
Junegunn Choi
85ef3263fc Fix incorrect cache reference in --exact mode (#547)
When we prepend a single quote to our query in --exact mode, we are not
supposed to limit the scope of the new search to the previous
exact-match result.
2016-04-24 03:43:24 +09:00
Junegunn Choi
4bde8de63f Apply new ranking algorithm to exact match as well 2016-04-23 19:48:06 +09:00
Junegunn Choi
654a7df9b0 [neovim] Set bufhidden and nobuflisted after opening terminal 2016-04-23 17:53:54 +09:00
Junegunn Choi
c3aa836ec0 [bash] Update completion.bash
[bash] Update completion.bash
2016-04-23 11:36:50 +09:00
Junegunn Choi
95764bef6f Merge pull request #550 from gene-pavlovsky/gene-pavlovsky-patch-2
[bash] Update key-bindings.bash
2016-04-23 11:35:27 +09:00
Gene Pavlovsky
63dbf48546 Update key-bindings.bash
Faster startup. Use internal bash globbing instead of external grep binary (adapter from Gentoo's `/etc/bash/bashrc` TERM checking). Insignificant on Linux, but on Cygwin this cuts startup time by 40 ms on my Core i7 laptop.
2016-04-23 03:44:41 +03:00
Gene Pavlovsky
e2401350a3 Update completion.bash
Fixes #548. Avoid using a subshell in _fzf_defc().
2016-04-23 03:12:15 +03:00
Junegunn Choi
e867355b2a [neovim] Restore winfixwidth and winfixheight
Fix https://github.com/junegunn/fzf.vim/issues/128
2016-04-21 00:33:30 +09:00
15 changed files with 199 additions and 123 deletions

View File

@@ -1,6 +1,13 @@
CHANGELOG
=========
0.12.1
------
- Ranking algorithm introduced in 0.12.0 is now universally applied
- Fixed invalid cache reference in exact mode
- Fixes and improvements in Vim plugin and shell extensions
0.12.0
------

View File

@@ -8,6 +8,7 @@ skip=""
swap=""
close=""
term=""
[ -n "$LINES" ] && lines=$LINES || lines=$(tput lines)
while [ $# -gt 0 ]; do
arg="$1"
case "$arg" in
@@ -60,7 +61,7 @@ while [ $# -gt 0 ]; do
if [[ "$arg" =~ ^.l ]]; then
[ -n "$COLUMNS" ] && max=$COLUMNS || max=$(tput cols)
else
[ -n "$LINES" ] && max=$LINES || max=$(tput lines)
max=$lines
fi
size=$(( max - size ))
[ $size -lt 0 ] && size=0
@@ -82,7 +83,7 @@ while [ $# -gt 0 ]; do
shift
done
if [ -z "$TMUX" ]; then
if ! [ -n "$TMUX_PANE" -a $lines -gt 15 ]; then
fzf "${args[@]}"
exit $?
fi

View File

@@ -2,8 +2,8 @@
set -u
[[ "$@" =~ --pre ]] && version=0.12.0 pre=1 ||
version=0.12.0 pre=0
[[ "$@" =~ --pre ]] && version=0.12.1 pre=1 ||
version=0.12.1 pre=0
auto_completion=
key_bindings=

View File

@@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
..
.TH fzf 1 "Apr 2016" "fzf 0.12.0" "fzf - a command-line fuzzy finder"
.TH fzf 1 "Apr 2016" "fzf 0.12.1" "fzf - a command-line fuzzy finder"
.SH NAME
fzf - a command-line fuzzy finder

View File

@@ -121,6 +121,10 @@ try
throw v:exception
endtry
if !has_key(dict, 'source') && !empty($FZF_DEFAULT_COMMAND)
let dict.source = $FZF_DEFAULT_COMMAND
endif
if has_key(dict, 'source')
let source = dict.source
let type = type(source)
@@ -307,7 +311,7 @@ function! s:split(dict)
endif
execute cmd sz.'new'
execute resz sz
return
return {}
endif
endfor
if s:present(a:dict, 'window')
@@ -315,20 +319,25 @@ function! s:split(dict)
else
execute (tabpagenr()-1).'tabnew'
endif
return { '&l:wfw': &l:wfw, '&l:wfh': &l:wfh }
finally
setlocal winfixwidth winfixheight buftype=nofile bufhidden=wipe nobuflisted
setlocal winfixwidth winfixheight
endtry
endfunction
function! s:execute_term(dict, command, temps) abort
call s:split(a:dict)
let winopts = s:split(a:dict)
let fzf = { 'buf': bufnr('%'), 'dict': a:dict, 'temps': a:temps, 'name': 'FZF' }
let fzf = { 'buf': bufnr('%'), 'dict': a:dict, 'temps': a:temps, 'name': 'FZF', 'winopts': winopts }
let s:command = a:command
function! fzf.on_exit(id, code)
let pos = s:getpos()
let inplace = pos == s:ppos " {'window': 'enew'}
if !inplace
if inplace
for [opt, val] in items(self.winopts)
execute 'let' opt '=' val
endfor
else
if bufnr('') == self.buf
" We use close instead of bd! since Vim does not close the split when
" there's no other listed buffer (nvim +'set nobuflisted')
@@ -363,7 +372,7 @@ function! s:execute_term(dict, command, temps) abort
call s:pushd(a:dict)
call termopen(a:command, fzf)
call s:popd(a:dict, [])
setlocal nospell
setlocal nospell bufhidden=wipe nobuflisted
setf fzf
startinsert
return []

View File

@@ -272,14 +272,15 @@ if type _completion_loader > /dev/null 2>&1; then
fi
_fzf_defc() {
local cmd func opts orig_var orig
local cmd func opts orig_var orig def
cmd="$1"
func="$2"
opts="$3"
orig_var="_fzf_orig_completion_$cmd"
orig="${!orig_var}"
if [ -n "$orig" ]; then
eval "$(printf "$orig" "$func")"
printf -v def "$orig" "$func"
eval "$def"
else
complete -F "$func" $opts "$cmd"
fi

View File

@@ -54,7 +54,7 @@ __fzf_generic_path_completion() {
[ "$dir" != "/" ] && dir="${dir/%\//}"
dir=${~dir}
matches=$(eval "$compgen $(printf %q "$dir")" | ${=fzf} ${=FZF_COMPLETION_OPTS} ${=fzf_opts} -q "$leftover" | while read item; do
printf "%q$suffix " "$item"
echo -n "${(q)item}$suffix "
done)
matches=${matches% }
if [ -n "$matches" ]; then

View File

@@ -29,11 +29,13 @@ __fzf_select_tmux__() {
tmux split-window $height "cd $(printf %q "$PWD"); FZF_DEFAULT_OPTS=$(printf %q "$FZF_DEFAULT_OPTS") PATH=$(printf %q "$PATH") FZF_CTRL_T_COMMAND=$(printf %q "$FZF_CTRL_T_COMMAND") bash -c 'source \"${BASH_SOURCE[0]}\"; tmux send-keys -t $TMUX_PANE \"\$(__fzf_select__)\"'"
}
__fzf_select_tmux_auto__() {
if [ "${FZF_TMUX:-1}" != 0 ] && [ ${LINES:-40} -gt 15 ]; then
fzf-file-widget() {
if __fzf_use_tmux__; then
__fzf_select_tmux__
else
tmux send-keys -t "$TMUX_PANE" "$(__fzf_select__)"
local selected="$(__fzf_select__)"
READLINE_LINE="${READLINE_LINE:0:$READLINE_POINT}$selected${READLINE_LINE:$READLINE_POINT}"
READLINE_POINT=$(( READLINE_POINT + ${#selected} ))
fi
}
@@ -58,21 +60,21 @@ __fzf_history__() (
fi
)
__use_tmux=0
__use_tmux_auto=0
if [ -n "$TMUX_PANE" ]; then
[ "${FZF_TMUX:-1}" != 0 ] && [ ${LINES:-40} -gt 15 ] && __use_tmux=1
[ $BASH_VERSINFO -gt 3 ] && __use_tmux_auto=1
fi
__fzf_use_tmux__() {
[ -n "$TMUX_PANE" ] && [ "${FZF_TMUX:-1}" != 0 ] && [ ${LINES:-40} -gt 15 ]
}
if [ -z "$(set -o | \grep '^vi.*on')" ]; then
[ $BASH_VERSINFO -gt 3 ] && __use_bind_x=1 || __use_bind_x=0
__fzf_use_tmux__ && __use_tmux=1 || __use_tmux=0
if [[ $'\n'$(set -o) != *$'\n'vi*on* ]]; then
# Required to refresh the prompt after fzf
bind '"\er": redraw-current-line'
bind '"\e^": history-expand-line'
# CTRL-T - Paste the selected file path into the command line
if [ $__use_tmux_auto -eq 1 ]; then
bind -x '"\C-t": "__fzf_select_tmux_auto__"'
if [ $__use_bind_x -eq 1 ]; then
bind -x '"\C-t": "fzf-file-widget"'
elif [ $__use_tmux -eq 1 ]; then
bind '"\C-t": " \C-u \C-a\C-k$(__fzf_select_tmux__)\e\C-e\C-y\C-a\C-d\C-y\ey\C-h"'
else
@@ -100,8 +102,8 @@ else
# CTRL-T - Paste the selected file path into the command line
# - FIXME: Selected items are attached to the end regardless of cursor position
if [ $__use_tmux_auto -eq 1 ]; then
bind -x '"\C-t": "__fzf_select_tmux_auto__"'
if [ $__use_bind_x -eq 1 ]; then
bind -x '"\C-t": "fzf-file-widget"'
elif [ $__use_tmux -eq 1 ]; then
bind '"\C-t": "\C-x\C-a$a \C-x\C-addi$(__fzf_select_tmux__)\C-x\C-e\C-x\C-a0P$xa"'
else
@@ -118,6 +120,6 @@ else
bind -m vi-command '"\ec": "ddi$(__fzf_cd__)\C-x\C-e\C-x\C-r\C-m"'
fi
unset -v __use_tmux __use_tmux_auto
unset -v __use_tmux __use_bind_x
fi

View File

@@ -13,27 +13,26 @@ function fzf_key_bindings
end
end
function __fzf_ctrl_t
function fzf-file-widget
set -q FZF_CTRL_T_COMMAND; or set -l FZF_CTRL_T_COMMAND "
command find -L . \\( -path '*/\\.*' -o -fstype 'dev' -o -fstype 'proc' \\) -prune \
-o -type f -print \
-o -type d -print \
-o -type l -print 2> /dev/null | sed 1d | cut -b3-"
eval "$FZF_CTRL_T_COMMAND | "(__fzfcmd)" -m > $TMPDIR/fzf.result"
and sleep 0
and commandline -i (cat $TMPDIR/fzf.result | __fzf_escape)
and for i in (seq 20); commandline -i (cat $TMPDIR/fzf.result | __fzf_escape) 2> /dev/null; and break; sleep 0.1; end
commandline -f repaint
rm -f $TMPDIR/fzf.result
end
function __fzf_ctrl_r
function fzf-history-widget
history | eval (__fzfcmd) +s +m --tiebreak=index --toggle-sort=ctrl-r $FZF_CTRL_R_OPTS > $TMPDIR/fzf.result
and commandline (cat $TMPDIR/fzf.result)
commandline -f repaint
rm -f $TMPDIR/fzf.result
end
function __fzf_alt_c
function fzf-cd-widget
set -q FZF_ALT_C_COMMAND; or set -l FZF_ALT_C_COMMAND "
command find -L . \\( -path '*/\\.*' -o -fstype 'dev' -o -fstype 'proc' \\) -prune \
-o -type d -print 2> /dev/null | sed 1d | cut -b3-"
@@ -59,14 +58,14 @@ function fzf_key_bindings
end
end
bind \ct '__fzf_ctrl_t'
bind \cr '__fzf_ctrl_r'
bind \ec '__fzf_alt_c'
bind \ct fzf-file-widget
bind \cr fzf-history-widget
bind \ec fzf-cd-widget
if bind -M insert > /dev/null 2>&1
bind -M insert \ct '__fzf_ctrl_t'
bind -M insert \cr '__fzf_ctrl_r'
bind -M insert \ec '__fzf_alt_c'
bind -M insert \ct fzf-file-widget
bind -M insert \cr fzf-history-widget
bind -M insert \ec fzf-cd-widget
end
end

View File

@@ -9,7 +9,7 @@ __fsel() {
-o -type d -print \
-o -type l -print 2> /dev/null | sed 1d | cut -b3-"}"
eval "$cmd" | $(__fzfcmd) -m | while read item; do
printf '%q ' "$item"
echo -n "${(q)item} "
done
echo
}

View File

@@ -42,6 +42,70 @@ const (
charNumber
)
func evaluateBonus(caseSensitive bool, runes []rune, pattern []rune, sidx int, eidx int) int32 {
var bonus int32
pidx := 0
lenPattern := len(pattern)
consecutive := false
prevClass := charNonWord
for index := 0; index < eidx; index++ {
char := runes[index]
var class charClass
if unicode.IsLower(char) {
class = charLower
} else if unicode.IsUpper(char) {
class = charUpper
} else if unicode.IsLetter(char) {
class = charLetter
} else if unicode.IsNumber(char) {
class = charNumber
} else {
class = charNonWord
}
var point int32
if prevClass == charNonWord && class != charNonWord {
// Word boundary
point = 2
} else if prevClass == charLower && class == charUpper ||
prevClass != charNumber && class == charNumber {
// camelCase letter123
point = 1
}
prevClass = class
if index >= sidx {
if !caseSensitive {
if char >= 'A' && char <= 'Z' {
char += 32
} else if char > unicode.MaxASCII {
char = unicode.To(unicode.LowerCase, char)
}
}
pchar := pattern[pidx]
if pchar == char {
// Boost bonus for the first character in the pattern
if pidx == 0 {
point *= 2
}
// Bonus to consecutive matching chars
if consecutive {
point++
}
bonus += point
if pidx++; pidx == lenPattern {
break
}
consecutive = true
} else {
consecutive = false
}
}
}
return bonus
}
// FuzzyMatch performs fuzzy-match
func FuzzyMatch(caseSensitive bool, forward bool, runes []rune, pattern []rune) Result {
if len(pattern) == 0 {
@@ -117,67 +181,8 @@ func FuzzyMatch(caseSensitive bool, forward bool, runes []rune, pattern []rune)
sidx, eidx = lenRunes-eidx, lenRunes-sidx
}
var bonus int32
pidx := 0
consecutive := false
prevClass := charNonWord
for index := 0; index < eidx; index++ {
char := runes[index]
var class charClass
if unicode.IsLower(char) {
class = charLower
} else if unicode.IsUpper(char) {
class = charUpper
} else if unicode.IsLetter(char) {
class = charLetter
} else if unicode.IsNumber(char) {
class = charNumber
} else {
class = charNonWord
}
var point int32
if prevClass == charNonWord && class != charNonWord {
// Word boundary
point = 2
} else if prevClass == charLower && class == charUpper ||
prevClass != charNumber && class == charNumber {
// camelCase letter123
point = 1
}
prevClass = class
if index >= sidx {
if !caseSensitive {
if char >= 'A' && char <= 'Z' {
char += 32
} else if char > unicode.MaxASCII {
char = unicode.To(unicode.LowerCase, char)
}
}
pchar := pattern[pidx]
if pchar == char {
// Boost bonus for the first character in the pattern
if pidx == 0 {
point *= 2
}
// Bonus to consecutive matching chars
if consecutive {
point++
}
bonus += point
if pidx++; pidx == lenPattern {
break
}
consecutive = true
} else {
consecutive = false
}
}
}
return Result{int32(sidx), int32(eidx), bonus}
return Result{int32(sidx), int32(eidx),
evaluateBonus(caseSensitive, runes, pattern, sidx, eidx)}
}
return Result{-1, -1, 0}
}
@@ -190,7 +195,6 @@ func FuzzyMatch(caseSensitive bool, forward bool, runes []rune, pattern []rune)
// We might try to implement better algorithms in the future:
// http://en.wikipedia.org/wiki/String_searching_algorithm
func ExactMatchNaive(caseSensitive bool, forward bool, runes []rune, pattern []rune) Result {
// Note: ExactMatchNaive always return a zero bonus.
if len(pattern) == 0 {
return Result{0, 0, 0}
}
@@ -216,10 +220,16 @@ func ExactMatchNaive(caseSensitive bool, forward bool, runes []rune, pattern []r
if pchar == char {
pidx++
if pidx == lenPattern {
var sidx, eidx int
if forward {
return Result{int32(index - lenPattern + 1), int32(index + 1), 0}
sidx = index - lenPattern + 1
eidx = index + 1
} else {
sidx = lenRunes - (index + 1)
eidx = lenRunes - (index - lenPattern + 1)
}
return Result{int32(lenRunes - (index + 1)), int32(lenRunes - (index - lenPattern + 1)), 0}
return Result{int32(sidx), int32(eidx),
evaluateBonus(caseSensitive, runes, pattern, sidx, eidx)}
}
} else {
index -= pidx
@@ -231,7 +241,6 @@ func ExactMatchNaive(caseSensitive bool, forward bool, runes []rune, pattern []r
// PrefixMatch performs prefix-match
func PrefixMatch(caseSensitive bool, forward bool, runes []rune, pattern []rune) Result {
// Note: PrefixMatch always return a zero bonus.
if len(runes) < len(pattern) {
return Result{-1, -1, 0}
}
@@ -245,12 +254,13 @@ func PrefixMatch(caseSensitive bool, forward bool, runes []rune, pattern []rune)
return Result{-1, -1, 0}
}
}
return Result{0, int32(len(pattern)), 0}
lenPattern := len(pattern)
return Result{0, int32(lenPattern),
evaluateBonus(caseSensitive, runes, pattern, 0, lenPattern)}
}
// SuffixMatch performs suffix-match
func SuffixMatch(caseSensitive bool, forward bool, input []rune, pattern []rune) Result {
// Note: SuffixMatch always return a zero bonus.
runes := util.TrimRight(input)
trimmedLen := len(runes)
diff := trimmedLen - len(pattern)
@@ -267,7 +277,11 @@ func SuffixMatch(caseSensitive bool, forward bool, input []rune, pattern []rune)
return Result{-1, -1, 0}
}
}
return Result{int32(trimmedLen - len(pattern)), int32(trimmedLen), 0}
lenPattern := len(pattern)
sidx := trimmedLen - lenPattern
eidx := trimmedLen
return Result{int32(sidx), int32(eidx),
evaluateBonus(caseSensitive, runes, pattern, sidx, eidx)}
}
// EqualMatch performs equal-match

View File

@@ -51,29 +51,36 @@ func TestFuzzyMatchBackward(t *testing.T) {
func TestExactMatchNaive(t *testing.T) {
for _, dir := range []bool{true, false} {
assertMatch(t, ExactMatchNaive, false, dir, "fooBarbaz", "oBA", 2, 5, 0)
assertMatch(t, ExactMatchNaive, false, dir, "fooBarbaz", "oBA", 2, 5, 3)
assertMatch(t, ExactMatchNaive, true, dir, "fooBarbaz", "oBA", -1, -1, 0)
assertMatch(t, ExactMatchNaive, true, dir, "fooBarbaz", "fooBarbazz", -1, -1, 0)
assertMatch(t, ExactMatchNaive, false, dir, "/AutomatorDocument.icns", "rdoc", 9, 13, 4)
assertMatch(t, ExactMatchNaive, false, dir, "/man1/zshcompctl.1", "zshc", 6, 10, 7)
assertMatch(t, ExactMatchNaive, false, dir, "/.oh-my-zsh/cache", "zsh/c", 8, 13, 10)
}
}
func TestExactMatchNaiveBackward(t *testing.T) {
assertMatch(t, ExactMatchNaive, false, true, "foobar foob", "oo", 1, 3, 0)
assertMatch(t, ExactMatchNaive, false, false, "foobar foob", "oo", 8, 10, 0)
assertMatch(t, ExactMatchNaive, false, true, "foobar foob", "oo", 1, 3, 1)
assertMatch(t, ExactMatchNaive, false, false, "foobar foob", "oo", 8, 10, 1)
}
func TestPrefixMatch(t *testing.T) {
for _, dir := range []bool{true, false} {
assertMatch(t, PrefixMatch, false, dir, "fooBarbaz", "Foo", 0, 3, 0)
assertMatch(t, PrefixMatch, true, dir, "fooBarbaz", "Foo", -1, -1, 0)
assertMatch(t, PrefixMatch, false, dir, "fooBarbaz", "baz", -1, -1, 0)
assertMatch(t, PrefixMatch, false, dir, "fooBarBaz", "baz", -1, -1, 0)
assertMatch(t, PrefixMatch, false, dir, "fooBarbaz", "Foo", 0, 3, 6)
assertMatch(t, PrefixMatch, false, dir, "foOBarBaZ", "foo", 0, 3, 7)
assertMatch(t, PrefixMatch, false, dir, "f-oBarbaz", "f-o", 0, 3, 8)
}
}
func TestSuffixMatch(t *testing.T) {
for _, dir := range []bool{true, false} {
assertMatch(t, SuffixMatch, false, dir, "fooBarbaz", "Foo", -1, -1, 0)
assertMatch(t, SuffixMatch, false, dir, "fooBarbaz", "baz", 6, 9, 0)
assertMatch(t, SuffixMatch, false, dir, "fooBarbaz", "baz", 6, 9, 2)
assertMatch(t, SuffixMatch, false, dir, "fooBarBaZ", "baz", 6, 9, 5)
assertMatch(t, SuffixMatch, true, dir, "fooBarbaz", "Baz", -1, -1, 0)
}
}

View File

@@ -8,7 +8,7 @@ import (
const (
// Current version
version = "0.12.0"
version = "0.12.1"
// Core
coordinatorDelayMax time.Duration = 100 * time.Millisecond

View File

@@ -227,7 +227,7 @@ func (p *Pattern) CacheKey() string {
}
cacheableTerms := []string{}
for _, termSet := range p.termSets {
if len(termSet) == 1 && !termSet[0].inv {
if len(termSet) == 1 && !termSet[0].inv && (p.fuzzy || termSet[0].typ == termExact) {
cacheableTerms = append(cacheableTerms, string(termSet[0].origText))
}
}

View File

@@ -31,7 +31,7 @@ def wait
return if yield
sleep 0.05
end
throw 'timeout'
raise 'timeout'
end
class Shell
@@ -1117,13 +1117,9 @@ class TestGoFZF < TestBase
def test_exitstatus_empty
{ '99' => '0', '999' => '1' }.each do |query, status|
tmux.send_keys "seq 100 | #{FZF} -q #{query}", :Enter
tmux.send_keys "seq 100 | #{FZF} -q #{query}; echo --\\$?--", :Enter
tmux.until { |lines| lines[-2] =~ %r{ [10]/100} }
tmux.send_keys :Enter
tmux.send_keys 'echo --\$?--'
tmux.until { |lines| lines.last.include? "echo --$?--" }
tmux.send_keys :Enter
tmux.until { |lines| lines.last.include? "--#{status}--" }
end
end
@@ -1157,6 +1153,16 @@ class TestGoFZF < TestBase
end
end
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
private
def writelines path, lines
File.unlink path while File.exists? path
@@ -1212,6 +1218,22 @@ module TestShell
tmux.until(0) { |lines| lines[-1].include? '1 2 3' }
end
def test_ctrl_t_unicode
FileUtils.mkdir_p '/tmp/fzf-test'
tmux.send_keys 'cd /tmp/fzf-test; echo -n test1 > "fzf-unicode 테스트1"; echo -n test2 > "fzf-unicode 테스트2"', :Enter
tmux.prepare
tmux.send_keys 'cat ', 'C-t', pane: 0
tmux.until(1) { |lines| lines.item_count >= 1 }
tmux.send_keys 'fzf-unicode', pane: 1
tmux.until(1) { |lines| lines[-2].start_with? ' 2/' }
tmux.send_keys :BTab, :BTab, pane: 1
tmux.until(1) { |lines| lines[-2].include? '(2)' }
tmux.send_keys :Enter, pane: 1
tmux.until { |lines| lines[-1].include? 'cat' }
tmux.send_keys :Enter
tmux.until { |lines| lines[-1].include? 'test1test2' }
end
def test_alt_c
tmux.prepare
tmux.send_keys :Escape, :c, pane: 0
@@ -1412,6 +1434,20 @@ module CompletionTest
tmux.send_keys :Enter
tmux.until { |lines| lines[-1] == 'unset FOO' }
end
def test_file_completion_unicode
FileUtils.mkdir_p '/tmp/fzf-test'
tmux.send_keys 'cd /tmp/fzf-test; echo -n test3 > "fzf-unicode 테스트1"; echo -n test4 > "fzf-unicode 테스트2"', :Enter
tmux.prepare
tmux.send_keys 'cat fzf-unicode**', :Tab, pane: 0
tmux.until(1) { |lines| lines[-2].start_with? ' 2/' }
tmux.send_keys :BTab, :BTab, pane: 1
tmux.until(1) { |lines| lines[-2].include? '(2)' }
tmux.send_keys :Enter, pane: 1
tmux.until { |lines| lines[-1].include? 'cat' }
tmux.send_keys :Enter
tmux.until { |lines| lines[-1].include? 'test3test4' }
end
end
class TestBash < TestBase