Compare commits

..

25 Commits

Author SHA1 Message Date
Junegunn Choi
fccc93176b 0.13.3 2016-07-16 01:06:53 +09:00
Junegunn Choi
6439a138fe [install] Build fzf if prebuilt binary doesn't work
Close #617
2016-07-16 00:36:35 +09:00
Junegunn Choi
a9a29dff4f Fix duplicate rendering of the last line in preview window 2016-07-15 23:24:14 +09:00
Junegunn Choi
6a52f8b8dd [zsh-completion] setopt localoptions noksh_arrays
Close #607
2016-07-15 01:26:29 +09:00
Junegunn Choi
a1049328d6 [vim] Adjust split size when --header option is set
Close #622
2016-07-14 13:35:18 +09:00
Junegunn Choi
5c2b96bd00 [vim] Fix error with multi-line $FZF_DEFAULT_COMMAND
Close #620
2016-07-13 13:15:14 +09:00
Junegunn Choi
c36413fdf6 [zsh] Suppress error message when pipefail is not supported
Close #615
2016-07-11 17:47:41 +09:00
Junegunn Choi
52cf5af91c [test] Fix test failure on Travis CI
No guarantee in the order in which files are listed
2016-07-10 15:44:44 +09:00
Junegunn Choi
3a4e053af7 [bash] Fall back to send-keys if named paste buffer is not supported
Related: #616
2016-07-10 15:21:28 +09:00
Junegunn Choi
049bc9ec68 [fzf-tmux] Add man page 2016-07-10 14:44:00 +09:00
Junegunn Choi
b461a555b8 [fzf-tmux] Add --version and --help flags 2016-07-10 14:41:06 +09:00
Junegunn Choi
0f87b2d1e1 [fzf-tmux] Use double brackets
For consistency and (negligible) performance improvement
2016-07-10 14:34:29 +09:00
Junegunn Choi
0fb5b76c0d [fzf-tmux] Fail fast if fzf excutable is not found 2016-07-10 14:28:58 +09:00
Junegunn Choi
0c918dd87a Merge pull request #616 from seanlaguna/master
Use tmux buffers for sending output to preserve character encoding
2016-07-10 12:29:32 +09:00
Junegunn Choi
05299a0fee [test] Use tmux buffer in unicode test cases
Related #616
2016-07-10 12:27:01 +09:00
Sean
b36b0a91f5 use tmux buffers for sending output to preserve character encoding 2016-07-09 09:47:20 -05:00
Junegunn Choi
6081eac58a [shell] Suppress alias/function expansion
Close #611
2016-07-07 01:40:14 +09:00
Junegunn Choi
942ba749c7 [vim] Restore working directory even when new window is opened
Close #612
2016-07-06 13:31:04 +09:00
Junegunn Choi
f941012687 Merge pull request #610 from eigengrau/master
[zsh] Re-initialize zle when widgets finish
2016-07-05 21:50:43 +09:00
Sebastian Reuße
fed5e5d5af [zsh] Re-initialize zle when widgets finish
zle automatically calls zle-line-init when it starts to read a new line. Many
Zsh setups use this hook to set the terminal into application mode, since this
will then allow defining keybinds based on the $terminfo variable (the escape
codes in said variable are only valid in application mode).

However, fzf resets the terminal into raw mode, rendering $terminfo values
invalid once the widget has finished. Accordingly, keyboard bindings defined
via $terminfo won’t work anymore.

This fixes the issue by calling zle-line-init when widgets finish. Care is taken
to not call this widget when it is undefined.

Fixes #279
2016-07-05 08:57:11 +02:00
Junegunn Choi
b864885753 [install] Make sure to unset pipefail 2016-07-04 13:05:26 +09:00
Junegunn Choi
64747c2324 [install] Fix error in install script
Close #608
2016-07-04 13:00:30 +09:00
Junegunn Choi
34965edcda [install] Fall back to wget if curl failed
Close #605
2016-07-04 01:41:43 +09:00
Junegunn Choi
bd4377084d Merge pull request #601 from blueyed/zsh-ret-for-fzf-file-widget
zsh: pass through exit code from fzf with fzf-file-widget
2016-06-18 23:17:10 +09:00
Daniel Hahler
38a2076b89 zsh: pass through exit code from widgets
This allows to have a custom widget like the following, which would
additionally accept the line, but only in case of entries being
selected:

    fzf-file-widget-with-accept() {
      zle fzf-file-widget
      if [[ "$?" == 0 ]] && (( $#BUFFER )); then
        zle accept-line
      fi
    }
    zle     -N   fzf-file-widget-with-accept
    bindkey '\e^T' fzf-file-widget-with-accept

With this `<C-a>t` will launch fzf, and simulate the pressing of "Enter"
afterwards.
2016-06-16 20:20:29 +02:00
14 changed files with 293 additions and 132 deletions

View File

@@ -1,6 +1,10 @@
CHANGELOG
=========
0.13.3
------
- Fixed duplicate rendering of the last line in preview window
0.13.2
------
- Fixed race condition where preview window is not properly cleared

View File

@@ -2,25 +2,51 @@
# fzf-tmux: starts fzf in a tmux pane
# usage: fzf-tmux [-u|-d [HEIGHT[%]]] [-l|-r [WIDTH[%]]] [--] [FZF OPTIONS]
fail() {
>&2 echo "$1"
exit 2
}
fzf="$(command -v fzf 2> /dev/null)" || fzf="$(dirname "$0")/fzf"
[[ -x "$fzf" ]] || fail 'fzf executable not found'
args=()
opt=""
skip=""
swap=""
close=""
term=""
[ -n "$LINES" ] && lines=$LINES || lines=$(tput lines)
while [ $# -gt 0 ]; do
[[ -n "$LINES" ]] && lines=$LINES || lines=$(tput lines)
help() {
>&2 echo 'usage: fzf-tmux [-u|-d [HEIGHT[%]]] [-l|-r [WIDTH[%]]] [--] [FZF OPTIONS]
Layout
-u [HEIGHT[%]] Split above (up)
-d [HEIGHT[%]] Split below (down)
-l [WIDTH[%]] Split left
-r [WIDTH[%]] Split right
(default: -d 50%)
'
exit
}
while [[ $# -gt 0 ]]; do
arg="$1"
case "$arg" in
shift
[[ -z "$skip" ]] && case "$arg" in
-)
term=1
;;
--help)
help
;;
--version)
echo "fzf-tmux (with fzf $("$fzf" --version))"
exit
;;
-w*|-h*|-d*|-u*|-r*|-l*)
if [ -n "$skip" ]; then
args+=("$1")
shift
continue
fi
if [[ "$arg" =~ ^.[lrw] ]]; then
opt="-h"
if [[ "$arg" =~ ^.l ]]; then
@@ -36,35 +62,33 @@ while [ $# -gt 0 ]; do
close="; tmux swap-pane -D"
fi
fi
if [ ${#arg} -gt 2 ]; then
if [[ ${#arg} -gt 2 ]]; then
size="${arg:2}"
else
shift
if [[ "$1" =~ ^[0-9]+%?$ ]]; then
size="$1"
else
[ -n "$1" -a "$1" != "--" ] && args+=("$1")
shift
else
continue
fi
fi
if [[ "$size" =~ %$ ]]; then
size=${size:0:((${#size}-1))}
if [ -n "$swap" ]; then
if [[ -n "$swap" ]]; then
opt="$opt -p $(( 100 - size ))"
else
opt="$opt -p $size"
fi
else
if [ -n "$swap" ]; then
if [[ -n "$swap" ]]; then
if [[ "$arg" =~ ^.l ]]; then
[ -n "$COLUMNS" ] && max=$COLUMNS || max=$(tput cols)
[[ -n "$COLUMNS" ]] && max=$COLUMNS || max=$(tput cols)
else
max=$lines
fi
size=$(( max - size ))
[ $size -lt 0 ] && size=0
[[ $size -lt 0 ]] && size=0
opt="$opt -l $size"
else
opt="$opt -l $size"
@@ -75,16 +99,17 @@ while [ $# -gt 0 ]; do
# "--" can be used to separate fzf-tmux options from fzf options to
# avoid conflicts
skip=1
continue
;;
*)
args+=("$1")
args+=("$arg")
;;
esac
shift
[[ -n "$skip" ]] && args+=("$arg")
done
if ! [ -n "$TMUX" -a "$lines" -gt 15 ]; then
fzf "${args[@]}"
if [[ -z "$TMUX" ]] || [[ "$lines" -le 15 ]]; then
"$fzf" "${args[@]}"
exit $?
fi
@@ -108,7 +133,7 @@ cleanup() {
rm -f $argsf $fifo1 $fifo2 $fifo3
# Remove temp window if we were zoomed
if [ -n "$zoomed" ]; then
if [[ -n "$zoomed" ]]; then
tmux swap-pane -t $original_window \; \
select-window -t $original_window \; \
kill-window -t $tmp_window \; \
@@ -117,16 +142,9 @@ cleanup() {
}
trap cleanup EXIT SIGINT SIGTERM
fail() {
>&2 echo "$1"
exit 2
}
fzf="$(which fzf 2> /dev/null)" || fzf="$(dirname "$0")/fzf"
[ -x "$fzf" ] || fail "fzf executable not found"
envs="env TERM=$TERM "
[ -n "$FZF_DEFAULT_OPTS" ] && envs="$envs FZF_DEFAULT_OPTS=$(printf %q "$FZF_DEFAULT_OPTS")"
[ -n "$FZF_DEFAULT_COMMAND" ] && envs="$envs FZF_DEFAULT_COMMAND=$(printf %q "$FZF_DEFAULT_COMMAND")"
[[ -n "$FZF_DEFAULT_OPTS" ]] && envs="$envs FZF_DEFAULT_OPTS=$(printf %q "$FZF_DEFAULT_OPTS")"
[[ -n "$FZF_DEFAULT_COMMAND" ]] && envs="$envs FZF_DEFAULT_COMMAND=$(printf %q "$FZF_DEFAULT_COMMAND")"
mkfifo -m o+w $fifo2
mkfifo -m o+w $fifo3
@@ -141,7 +159,7 @@ for arg in "${args[@]}"; do
opts="$opts \"$arg\""
done
if [ -n "$term" -o -t 0 ]; then
if [[ -n "$term" ]] || [[ -t 0 ]]; then
cat <<< "\"$fzf\" $opts > $fifo2; echo \$? > $fifo3 $close" > $argsf
tmux set-window-option synchronize-panes off \;\
set-window-option remain-on-exit off \;\

59
install
View File

@@ -2,13 +2,14 @@
set -u
[[ "$@" =~ --pre ]] && version=0.13.2 pre=1 ||
version=0.13.2 pre=0
[[ "$@" =~ --pre ]] && version=0.13.3 pre=1 ||
version=0.13.3 pre=0
auto_completion=
key_bindings=
update_config=2
binary_arch=
allow_legacy=
help() {
cat << EOF
@@ -37,6 +38,7 @@ for opt in "$@"; do
auto_completion=1
key_bindings=1
update_config=1
allow_legacy=1
;;
--key-bindings) key_bindings=1 ;;
--no-key-bindings) key_bindings=0 ;;
@@ -109,6 +111,14 @@ link_fzf_in_path() {
return 1
}
try_curl() {
command -v curl > /dev/null && curl -fL $1 | tar -xz
}
try_wget() {
command -v wget > /dev/null && wget -O - $1 | tar -xz
}
download() {
echo "Downloading bin/fzf ..."
if [ $pre = 0 ]; then
@@ -128,14 +138,13 @@ download() {
fi
local url=https://github.com/junegunn/fzf-bin/releases/download/$version/${1}.tgz
if command -v curl > /dev/null; then
curl -fL $url | tar -xz
elif command -v wget > /dev/null; then
wget -O - $url | tar -xz
else
binary_error="curl or wget not found"
set -o pipefail
if ! (try_curl $url || try_wget $url); then
set +o pipefail
binary_error="Failed to download with curl and wget"
return
fi
set +o pipefail
if [ ! -f $1 ]; then
binary_error="Failed to download ${1}"
@@ -158,6 +167,9 @@ case "$archi" in
esac
install_ruby_fzf() {
if [ -z "$allow_legacy" ]; then
ask "Do you want to install legacy Ruby version instead?" && exit 1
fi
echo "Installing legacy Ruby version ..."
# ruby executable
@@ -229,26 +241,25 @@ cd "$fzf_base"
if [ -n "$binary_error" ]; then
if [ $binary_available -eq 0 ]; then
echo "No prebuilt binary for $archi ..."
if command -v go > /dev/null; then
echo -n "Building binary (go get -u github.com/junegunn/fzf/src/fzf) ... "
if [ -z "${GOPATH-}" ]; then
export GOPATH="${TMPDIR:-/tmp}/fzf-gopath"
mkdir -p "$GOPATH"
fi
if go get -u github.com/junegunn/fzf/src/fzf; then
echo "OK"
cp "$GOPATH/bin/fzf" "$fzf_base/bin/"
else
echo "Failed to build binary ..."
install_ruby_fzf
fi
else
echo " - $binary_error !!!"
fi
if command -v go > /dev/null; then
echo -n "Building binary (go get -u github.com/junegunn/fzf/src/fzf) ... "
if [ -z "${GOPATH-}" ]; then
export GOPATH="${TMPDIR:-/tmp}/fzf-gopath"
mkdir -p "$GOPATH"
fi
if go get -u github.com/junegunn/fzf/src/fzf; then
echo "OK"
cp "$GOPATH/bin/fzf" "$fzf_base/bin/"
else
echo "go executable not found. Cannot build binary ..."
echo "Failed to build binary ..."
install_ruby_fzf
fi
else
echo " - $binary_error !!!"
exit 1
echo "go executable not found. Cannot build binary ..."
install_ruby_fzf
fi
fi

54
man/man1/fzf-tmux.1 Normal file
View File

@@ -0,0 +1,54 @@
.ig
The MIT License (MIT)
Copyright (c) 2016 Junegunn Choi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
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-tmux 1 "Jul 2016" "fzf 0.13.3" "fzf-tmux - open fzf in tmux split pane"
.SH NAME
fzf-tmux - open fzf in tmux split pane
.SH SYNOPSIS
.B fzf-tmux [-u|-d [HEIGHT[%]]] [-l|-r [WIDTH[%]]] [--] [FZF OPTIONS]
.SH DESCRIPTION
fzf-tmux is a wrapper script for fzf that opens fzf in a tmux split pane. It is
designed to work just like fzf except that it does not take up the whole
screen. You can safely use fzf-tmux instead of fzf in your scripts as the extra
options will be silently ignored if you're not on tmux.
.SH OPTIONS
.SS Layout
(default: \fB-d 50%\fR)
.TP
.B "-u [height[%]]"
Split above (up)
.TP
.B "-d [height[%]]"
Split below (down)
.TP
.B "-l [width[%]]"
Split left
.TP
.B "-r [width[%]]"
Split right

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 "Jun 2016" "fzf 0.13.2" "fzf - a command-line fuzzy finder"
.TH fzf 1 "Jul 2016" "fzf 0.13.3" "fzf - a command-line fuzzy finder"
.SH NAME
fzf - a command-line fuzzy finder

View File

@@ -122,7 +122,9 @@ try
endtry
if !has_key(dict, 'source') && !empty($FZF_DEFAULT_COMMAND)
let dict.source = $FZF_DEFAULT_COMMAND
let temps.source = tempname()
call writefile(split($FZF_DEFAULT_COMMAND, "\n"), temps.source)
let dict.source = (empty($SHELL) ? 'sh' : $SHELL) . ' ' . s:shellesc(temps.source)
endif
if has_key(dict, 'source')
@@ -147,9 +149,9 @@ try
return s:execute_term(dict, command, temps)
endif
let ret = tmux ? s:execute_tmux(dict, command, temps) : s:execute(dict, command, temps)
call s:popd(dict, ret)
return ret
let lines = tmux ? s:execute_tmux(dict, command, temps) : s:execute(dict, command, temps)
call s:callback(dict, lines)
return lines
finally
let &shell = oshell
endtry
@@ -200,22 +202,17 @@ function! s:pushd(dict)
return 0
endfunction
function! s:popd(dict, lines)
" Since anything can be done in the sink function, there is no telling that
" the change of the working directory was made by &autochdir setting.
"
" We use the following heuristic to determine whether to restore CWD:
" - Always restore the current directory when &autochdir is disabled.
" FIXME This makes it impossible to change directory from inside the sink
" function when &autochdir is not used.
" - In case of an error or an interrupt, a:lines will be empty.
" And it will be an array of a single empty string when fzf was finished
" without a match. In these cases, we presume that the change of the
" directory is not expected and should be undone.
if has_key(a:dict, 'prev_dir') &&
\ (!&autochdir || (empty(a:lines) || len(a:lines) == 1 && empty(a:lines[0])))
execute 'lcd' s:escape(remove(a:dict, 'prev_dir'))
augroup fzf_popd
autocmd!
autocmd WinEnter * call s:dopopd()
augroup END
function! s:dopopd()
if !exists('w:fzf_prev_dir') || exists('*haslocaldir') && !haslocaldir()
return
endif
execute 'lcd' s:escape(w:fzf_prev_dir)
unlet w:fzf_prev_dir
endfunction
function! s:xterm_launcher()
@@ -256,7 +253,7 @@ function! s:execute(dict, command, temps) abort
endif
execute 'silent !'.command
redraw!
return s:exit_handler(v:shell_error, command) ? s:callback(a:dict, a:temps) : []
return s:exit_handler(v:shell_error, command) ? s:collect(a:temps) : []
endfunction
function! s:execute_tmux(dict, command, temps) abort
@@ -268,7 +265,7 @@ function! s:execute_tmux(dict, command, temps) abort
call system(command)
redraw!
return s:exit_handler(v:shell_error, command) ? s:callback(a:dict, a:temps) : []
return s:exit_handler(v:shell_error, command) ? s:collect(a:temps) : []
endfunction
function! s:calc_size(max, val, dict)
@@ -285,6 +282,7 @@ function! s:calc_size(max, val, dict)
let opts = get(a:dict, 'options', '').$FZF_DEFAULT_OPTS
let margin = stridx(opts, '--inline-info') > stridx(opts, '--no-inline-info') ? 1 : 2
let margin += stridx(opts, '--header') > stridx(opts, '--no-header')
return srcsz >= 0 ? min([srcsz + margin, size]) : size
endfunction
@@ -361,31 +359,58 @@ function! s:execute_term(dict, command, temps) abort
endif
call s:pushd(self.dict)
let ret = []
try
let ret = s:callback(self.dict, self.temps)
call self.switch_back(s:getpos() == self.ppos)
finally
call s:popd(self.dict, ret)
endtry
let lines = s:collect(self.temps)
call s:callback(self.dict, lines)
call self.switch_back(s:getpos() == self.ppos)
endfunction
call s:pushd(a:dict)
call termopen(a:command, fzf)
call s:popd(a:dict, [])
try
if s:present(a:dict, 'dir')
execute 'lcd' s:escape(a:dict.dir)
endif
call termopen(a:command, fzf)
finally
if s:present(a:dict, 'dir')
lcd -
endif
endtry
setlocal nospell bufhidden=wipe nobuflisted
setf fzf
startinsert
return []
endfunction
function! s:callback(dict, temps) abort
let lines = []
try
if filereadable(a:temps.result)
let lines = readfile(a:temps.result)
function! s:collect(temps) abort
try
return filereadable(a:temps.result) ? readfile(a:temps.result) : []
finally
for tf in values(a:temps)
silent! call delete(tf)
endfor
endtry
endfunction
function! s:callback(dict, lines) abort
" Since anything can be done in the sink function, there is no telling that
" the change of the working directory was made by &autochdir setting.
"
" We use the following heuristic to determine whether to restore CWD:
" - Always restore the current directory when &autochdir is disabled.
" FIXME This makes it impossible to change directory from inside the sink
" function when &autochdir is not used.
" - In case of an error or an interrupt, a:lines will be empty.
" And it will be an array of a single empty string when fzf was finished
" without a match. In these cases, we presume that the change of the
" directory is not expected and should be undone.
let popd = has_key(a:dict, 'prev_dir') &&
\ (!&autochdir || (empty(a:lines) || len(a:lines) == 1 && empty(a:lines[0])))
if popd
let w:fzf_prev_dir = a:dict.prev_dir
endif
try
if has_key(a:dict, 'sink')
for line in lines
for line in a:lines
if type(a:dict.sink) == 2
call a:dict.sink(line)
else
@@ -394,20 +419,19 @@ try
endfor
endif
if has_key(a:dict, 'sink*')
call a:dict['sink*'](lines)
call a:dict['sink*'](a:lines)
endif
endif
catch
if stridx(v:exception, ':E325:') < 0
echoerr v:exception
endif
endtry
for tf in values(a:temps)
silent! call delete(tf)
endfor
catch
if stridx(v:exception, ':E325:') < 0
echoerr v:exception
" We may have opened a new window or tab
if popd
let w:fzf_prev_dir = a:dict.prev_dir
call s:dopopd()
endif
finally
return lines
endtry
endfunction
let s:default_action = {

View File

@@ -14,7 +14,7 @@
if ! declare -f _fzf_compgen_path > /dev/null; then
_fzf_compgen_path() {
echo "$1"
\find -L "$1" \
command find -L "$1" \
-name .git -prune -o -name .svn -prune -o \( -type d -o -type f -o -type l \) \
-a -not -path "$1" -print 2> /dev/null | sed 's@^\./@@'
}
@@ -22,7 +22,7 @@ fi
if ! declare -f _fzf_compgen_dir > /dev/null; then
_fzf_compgen_dir() {
\find -L "$1" \
command find -L "$1" \
-name .git -prune -o -name .svn -prune -o -type d \
-a -not -path "$1" -print 2> /dev/null | sed 's@^\./@@'
}
@@ -108,7 +108,7 @@ _fzf_handle_dynamic_completion() {
elif [ -n "$_fzf_completion_loader" ]; then
_completion_loader "$@"
ret=$?
eval "$(complete | \grep "\-F.* $orig_cmd$" | _fzf_orig_completion_filter)"
eval "$(complete | command grep "\-F.* $orig_cmd$" | _fzf_orig_completion_filter)"
source "${BASH_SOURCE[0]}"
return $ret
fi
@@ -213,16 +213,16 @@ _fzf_complete_kill() {
_fzf_complete_telnet() {
_fzf_complete '+m' "$@" < <(
\grep -v '^\s*\(#\|$\)' /etc/hosts | \grep -Fv '0.0.0.0' |
command grep -v '^\s*\(#\|$\)' /etc/hosts | command grep -Fv '0.0.0.0' |
awk '{if (length($2) > 0) {print $2}}' | sort -u
)
}
_fzf_complete_ssh() {
_fzf_complete '+m' "$@" < <(
cat <(cat ~/.ssh/config /etc/ssh/ssh_config 2> /dev/null | \grep -i '^host' | \grep -v '*') \
<(\grep -oE '^[^ ]+' ~/.ssh/known_hosts | tr ',' '\n' | awk '{ print $1 " " $1 }') \
<(\grep -v '^\s*\(#\|$\)' /etc/hosts | \grep -Fv '0.0.0.0') |
cat <(cat ~/.ssh/config /etc/ssh/ssh_config 2> /dev/null | command grep -i '^host' | command grep -v '*') \
<(command grep -oE '^[^ ]+' ~/.ssh/known_hosts | tr ',' '\n' | awk '{ print $1 " " $1 }') \
<(command grep -v '^\s*\(#\|$\)' /etc/hosts | command grep -Fv '0.0.0.0') |
awk '{if (length($2) > 0) {print $2}}' | sort -u
)
}
@@ -263,8 +263,8 @@ x_cmds="kill ssh telnet unset unalias export"
# Preserve existing completion
if [ "$_fzf_completion_loaded" != '0.11.3' ]; then
# Really wish I could use associative array but OSX comes with bash 3.2 :(
eval $(complete | \grep '\-F' | \grep -v _fzf_ |
\grep -E " ($(echo $d_cmds $a_cmds $x_cmds | sed 's/ /|/g' | sed 's/+/\\+/g'))$" | _fzf_orig_completion_filter)
eval $(complete | command grep '\-F' | command grep -v _fzf_ |
command grep -E " ($(echo $d_cmds $a_cmds $x_cmds | sed 's/ /|/g' | sed 's/+/\\+/g'))$" | _fzf_orig_completion_filter)
export _fzf_completion_loaded=0.11.3
fi

View File

@@ -14,7 +14,7 @@
if ! declare -f _fzf_compgen_path > /dev/null; then
_fzf_compgen_path() {
echo "$1"
\find -L "$1" \
command find -L "$1" \
-name .git -prune -o -name .svn -prune -o \( -type d -o -type f -o -type l \) \
-a -not -path "$1" -print 2> /dev/null | sed 's@^\./@@'
}
@@ -22,7 +22,7 @@ fi
if ! declare -f _fzf_compgen_dir > /dev/null; then
_fzf_compgen_dir() {
\find -L "$1" \
command find -L "$1" \
-name .git -prune -o -name .svn -prune -o -type d \
-a -not -path "$1" -print 2> /dev/null | sed 's@^\./@@'
}
@@ -58,6 +58,7 @@ __fzf_generic_path_completion() {
LBUFFER="$lbuf$matches$tail"
fi
zle redisplay
typeset -f zle-line-init >/dev/null && zle zle-line-init
break
fi
dir=$(dirname "$dir")
@@ -76,7 +77,7 @@ _fzf_dir_completion() {
}
_fzf_feed_fifo() (
rm -f "$1"
command rm -f "$1"
mkfifo "$1"
cat <&0 > "$1" &
)
@@ -97,21 +98,22 @@ _fzf_complete() {
LBUFFER="$lbuf$matches"
fi
zle redisplay
rm -f "$fifo"
typeset -f zle-line-init >/dev/null && zle zle-line-init
command rm -f "$fifo"
}
_fzf_complete_telnet() {
_fzf_complete '+m' "$@" < <(
\grep -v '^\s*\(#\|$\)' /etc/hosts | \grep -Fv '0.0.0.0' |
command grep -v '^\s*\(#\|$\)' /etc/hosts | command grep -Fv '0.0.0.0' |
awk '{if (length($2) > 0) {print $2}}' | sort -u
)
}
_fzf_complete_ssh() {
_fzf_complete '+m' "$@" < <(
cat <(cat ~/.ssh/config /etc/ssh/ssh_config 2> /dev/null | \grep -i '^host' | \grep -v '*') \
<(\grep -oE '^[^ ]+' ~/.ssh/known_hosts | tr ',' '\n' | awk '{ print $1 " " $1 }') \
<(\grep -v '^\s*\(#\|$\)' /etc/hosts | \grep -Fv '0.0.0.0') |
cat <(cat ~/.ssh/config /etc/ssh/ssh_config 2> /dev/null | command grep -i '^host' | command grep -v '*') \
<(command grep -oE '^[^ ]+' ~/.ssh/known_hosts | tr ',' '\n' | awk '{ print $1 " " $1 }') \
<(command grep -v '^\s*\(#\|$\)' /etc/hosts | command grep -Fv '0.0.0.0') |
awk '{if (length($2) > 0) {print $2}}' | sort -u
)
}
@@ -136,7 +138,7 @@ _fzf_complete_unalias() {
fzf-completion() {
local tokens cmd prefix trigger tail fzf matches lbuf d_cmds
setopt localoptions noshwordsplit
setopt localoptions noshwordsplit noksh_arrays
# http://zsh.sourceforge.net/FAQ/zshfaq03.html
# http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion-Flags
@@ -161,6 +163,7 @@ fzf-completion() {
LBUFFER="$LBUFFER$matches"
fi
zle redisplay
typeset -f zle-line-init >/dev/null && zle zle-line-init
# Trigger sequence given
elif [ ${#tokens} -gt 1 -a "$tail" = "$trigger" ]; then
d_cmds=(${=FZF_COMPLETION_DIR_COMMANDS:-cd pushd rmdir})

View File

@@ -26,7 +26,7 @@ __fzf_select_tmux__() {
height="-l $height"
fi
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") FZF_CTRL_T_OPTS=$(printf %q "$FZF_CTRL_T_OPTS") bash -c 'source \"${BASH_SOURCE[0]}\"; tmux send-keys -t $TMUX_PANE \"\$(__fzf_select__)\"'"
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") FZF_CTRL_T_OPTS=$(printf %q "$FZF_CTRL_T_OPTS") bash -c 'source \"${BASH_SOURCE[0]}\"; RESULT=\"\$(__fzf_select__)\"; tmux setb -b fzf \"\$RESULT\" \\; pasteb -b fzf -t $TMUX_PANE \\; deleteb -b fzf || tmux send-keys -t $TMUX_PANE \"\$RESULT\"'"
}
fzf-file-widget() {
@@ -52,7 +52,7 @@ __fzf_history__() (
line=$(
HISTTIMEFORMAT= history |
eval "$(__fzfcmd) +s --tac +m -n2..,.. --tiebreak=index --toggle-sort=ctrl-r $FZF_CTRL_R_OPTS" |
\grep '^ *[0-9]') &&
command grep '^ *[0-9]') &&
if [[ $- =~ H ]]; then
sed 's/^ *\([0-9]*\)\** .*/!\1/' <<< "$line"
else

View File

@@ -8,10 +8,13 @@ __fsel() {
-o -type f -print \
-o -type d -print \
-o -type l -print 2> /dev/null | sed 1d | cut -b3-"}"
setopt localoptions pipefail 2> /dev/null
eval "$cmd | $(__fzfcmd) -m $FZF_CTRL_T_OPTS" | while read item; do
echo -n "${(q)item} "
done
local ret=$?
echo
return $ret
}
__fzfcmd() {
@@ -20,7 +23,10 @@ __fzfcmd() {
fzf-file-widget() {
LBUFFER="${LBUFFER}$(__fsel)"
local ret=$?
zle redisplay
typeset -f zle-line-init >/dev/null && zle zle-line-init
return $ret
}
zle -N fzf-file-widget
bindkey '^T' fzf-file-widget
@@ -29,8 +35,12 @@ bindkey '^T' fzf-file-widget
fzf-cd-widget() {
local cmd="${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-"}"
setopt localoptions pipefail 2> /dev/null
cd "${$(eval "$cmd | $(__fzfcmd) +m $FZF_ALT_C_OPTS"):-.}"
local ret=$?
zle reset-prompt
typeset -f zle-line-init >/dev/null && zle zle-line-init
return $ret
}
zle -N fzf-cd-widget
bindkey '\ec' fzf-cd-widget
@@ -38,8 +48,9 @@ bindkey '\ec' fzf-cd-widget
# CTRL-R - Paste the selected command from history into the command line
fzf-history-widget() {
local selected num
setopt localoptions noglobsubst
setopt localoptions noglobsubst pipefail 2> /dev/null
selected=( $(fc -l 1 | eval "$(__fzfcmd) +s --tac +m -n2..,.. --tiebreak=index --toggle-sort=ctrl-r $FZF_CTRL_R_OPTS -q ${(q)LBUFFER}") )
local ret=$?
if [ -n "$selected" ]; then
num=$selected[1]
if [ -n "$num" ]; then
@@ -47,6 +58,8 @@ fzf-history-widget() {
fi
fi
zle redisplay
typeset -f zle-line-init >/dev/null && zle zle-line-init
return $ret
}
zle -N fzf-history-widget
bindkey '^R' fzf-history-widget

View File

@@ -49,7 +49,7 @@ func extractColor(str string, state *ansiState, proc func(string, *ansiState) bo
prev := str[idx:offset[0]]
output.WriteString(prev)
if proc != nil && !proc(prev, state) {
break
return "", nil, nil
}
newState := interpretCode(str[offset[0]:offset[1]], state)

View File

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

View File

@@ -43,6 +43,11 @@ Execute (fzf#run with dir option and noautochdir):
" No change in working directory
AssertEqual cwd, getcwd()
call fzf#run({'source': ['/foobar'], 'sink': 'tabe', 'dir': '/tmp', 'options': '-1'})
AssertEqual cwd, getcwd()
tabclose
AssertEqual cwd, getcwd()
Execute (Incomplete fzf#run with dir option and autochdir):
set acd
let cwd = getcwd()

View File

@@ -90,6 +90,10 @@ class Tmux
go("send-keys -t #{target} #{args}")
end
def paste str
%x[tmux setb '#{str.gsub("'", "'\\''")}' \\; pasteb -t #{win} \\; send-keys -t #{win} Enter]
end
def capture pane = 0
File.unlink TEMPNAME while File.exists? TEMPNAME
wait do
@@ -362,7 +366,7 @@ class TestGoFZF < TestBase
end
def test_query_unicode
tmux.send_keys "(echo abc; echo 가나다) | #{fzf :query, '가다'}", :Enter
tmux.paste "(echo abc; echo 가나다) | #{fzf :query, '가다'}"
tmux.until { |lines| lines[-2].include? '1/2' }
tmux.send_keys :Enter
assert_equal ['가나다'], readonce.split($/)
@@ -1313,16 +1317,29 @@ module TestShell
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.paste 'cd /tmp/fzf-test; echo -n test1 > "fzf-unicode 테스트1"; echo -n test2 > "fzf-unicode 테스트2"'
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.send_keys '1', pane: 1
tmux.until(1) { |lines| lines[-2].start_with? ' 1/' }
tmux.send_keys :BTab, pane: 1
tmux.until(1) { |lines| lines[-2].include? '(1)' }
tmux.send_keys :BSpace, pane: 1
tmux.until(1) { |lines| lines[-2].start_with? ' 2/' }
tmux.send_keys '2', pane: 1
tmux.until(1) { |lines| lines[-2].start_with? ' 1/' }
tmux.send_keys :BTab, pane: 1
tmux.until(1) { |lines| lines[-2].include? '(2)' }
tmux.send_keys :Enter, pane: 1
tmux.until { |lines| lines[-1].include?('cat') || lines[-2].include?('cat') }
tmux.until { |lines| lines[-1].include?('fzf-unicode') || lines[-2].include?('fzf-unicode') }
tmux.send_keys :Enter
tmux.until { |lines| lines[-1].include? 'test1test2' }
end
@@ -1530,12 +1547,24 @@ module CompletionTest
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.paste 'cd /tmp/fzf-test; echo -n test3 > "fzf-unicode 테스트1"; echo -n test4 > "fzf-unicode 테스트2"'
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.send_keys '1', pane: 1
tmux.until(1) { |lines| lines[-2].start_with? ' 1/' }
tmux.send_keys :BTab, pane: 1
tmux.until(1) { |lines| lines[-2].include? '(1)' }
tmux.send_keys :BSpace, pane: 1
tmux.until(1) { |lines| lines[-2].start_with? ' 2/' }
tmux.send_keys '2', pane: 1
tmux.until(1) { |lines| lines[-2].start_with? ' 1/' }
tmux.send_keys :BTab, pane: 1
tmux.until(1) { |lines| lines[-2].include? '(2)' }
tmux.send_keys :Enter, pane: 1
tmux.until { |lines| lines[-1].include?('cat') || lines[-2].include?('cat') }
tmux.send_keys :Enter