mirror of
https://github.com/junegunn/fzf.git
synced 2025-07-31 20:22:01 -07:00
Compare commits
25 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
fccc93176b | ||
|
6439a138fe | ||
|
a9a29dff4f | ||
|
6a52f8b8dd | ||
|
a1049328d6 | ||
|
5c2b96bd00 | ||
|
c36413fdf6 | ||
|
52cf5af91c | ||
|
3a4e053af7 | ||
|
049bc9ec68 | ||
|
b461a555b8 | ||
|
0f87b2d1e1 | ||
|
0fb5b76c0d | ||
|
0c918dd87a | ||
|
05299a0fee | ||
|
b36b0a91f5 | ||
|
6081eac58a | ||
|
942ba749c7 | ||
|
f941012687 | ||
|
fed5e5d5af | ||
|
b864885753 | ||
|
64747c2324 | ||
|
34965edcda | ||
|
bd4377084d | ||
|
38a2076b89 |
@@ -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
|
||||
|
80
bin/fzf-tmux
80
bin/fzf-tmux
@@ -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
59
install
@@ -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
54
man/man1/fzf-tmux.1
Normal 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
|
@@ -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
|
||||
|
120
plugin/fzf.vim
120
plugin/fzf.vim
@@ -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 = {
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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})
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
||||
|
@@ -8,7 +8,7 @@ import (
|
||||
|
||||
const (
|
||||
// Current version
|
||||
version = "0.13.2"
|
||||
version = "0.13.3"
|
||||
|
||||
// Core
|
||||
coordinatorDelayMax time.Duration = 100 * time.Millisecond
|
||||
|
@@ -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()
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user