101 lines
3.4 KiB
Plaintext
101 lines
3.4 KiB
Plaintext
|
#!/hint/zsh
|
||
|
# Show results with tmux popup
|
||
|
# Example usage:
|
||
|
# zstyle ':fzf-tab:*' fzf-command ftb-tmux-popup
|
||
|
# zstyle ':fzf-tab:*' popup-pad 0 0
|
||
|
# It can also be used as a standalone tool, like:
|
||
|
# ls | ftb-tmux-popup
|
||
|
emulate -L zsh -o extended_glob
|
||
|
|
||
|
# import math functions (only if they're not already defined)
|
||
|
if (( ! $+functions[zsh_math_func_min] )); then
|
||
|
autoload -Uz zmathfunc
|
||
|
zmathfunc
|
||
|
fi
|
||
|
|
||
|
: ${tmp_dir:=${TMPPREFIX:-/tmp/zsh}-fzf-tab-$USER}
|
||
|
|
||
|
# fallback to fzf if it is not running in tmux
|
||
|
if (( ! $+TMUX_PANE )); then
|
||
|
fzf $@
|
||
|
return
|
||
|
fi
|
||
|
|
||
|
local ret=0
|
||
|
|
||
|
local -a fzf_opts=($@)
|
||
|
fzf_opts=(${${fzf_opts/--height*}/--layout*})
|
||
|
|
||
|
# get position of cursor and size of window
|
||
|
local -a tmp=($(command tmux display-message -p "#{pane_top} #{cursor_y} #{pane_left} #{cursor_x} #{window_height} #{window_width} #{status} #{status-position}"))
|
||
|
local cursor_y=$((tmp[1] + tmp[2])) cursor_x=$((tmp[3] + tmp[4])) window_height=$tmp[5] window_width=$tmp[6] window_top=0
|
||
|
|
||
|
if [[ $tmp[8] == 'top' ]]; then
|
||
|
window_top=$tmp[7]
|
||
|
cursor_y=$((cursor_y + window_top))
|
||
|
fi
|
||
|
|
||
|
# if not called by fzf-tab
|
||
|
if (( ! $+IN_FZF_TAB )); then
|
||
|
[[ -d $tmp_dir ]] || mkdir -p $tmp_dir
|
||
|
cat > $tmp_dir/completions.$$
|
||
|
fi
|
||
|
|
||
|
local text REPLY comp_lines comp_length length popup_pad popup_min_size
|
||
|
|
||
|
zstyle -a ":fzf-tab:$_ftb_curcontext" popup-pad popup_pad || popup_pad=(0 0)
|
||
|
zstyle -a ":fzf-tab:$_ftb_curcontext" popup-min-size popup_min_size || popup_min_size=(0 0)
|
||
|
|
||
|
# get the size of content, note we should remove all ANSI color code
|
||
|
comp_lines=$(( ${#${(f)mapfile[$tmp_dir/completions.$$]}} + $popup_pad[2] ))
|
||
|
if (( comp_lines <= 500 )); then
|
||
|
comp_length=0
|
||
|
for line in ${(f)mapfile[$tmp_dir/completions.$$]}; do
|
||
|
length=${(m)#${(S)line//$'\x1b['[0-9]#*m}}
|
||
|
(( length >= comp_length )) && comp_length=$length
|
||
|
done
|
||
|
else
|
||
|
# FIXME: can't get the correct width of CJK characters.
|
||
|
comp_length=$( command perl -ne 's/\x1b\[[0-9;]*m//g;s/\x00//g; $m= length() if $m < length(); END { print $m }' < $tmp_dir/completions.$$ )
|
||
|
fi
|
||
|
comp_length=$(( comp_length + $popup_pad[1] ))
|
||
|
|
||
|
local popup_height popup_y popup_width popup_x adjust_height
|
||
|
|
||
|
# adjust the popup height if the fzf finder info style is not default
|
||
|
if (( $fzf_opts[(I)--info=*(hidden|inline)*] > 0 )); then
|
||
|
adjust_height=-1
|
||
|
fi
|
||
|
|
||
|
# calculate the popup height and y position
|
||
|
if (( cursor_y * 2 > window_height )); then
|
||
|
# show above the cursor
|
||
|
popup_height=$(( min(max(comp_lines + 4, popup_min_size[2]), cursor_y - window_top) + adjust_height ))
|
||
|
popup_y=$cursor_y
|
||
|
if zstyle -T ":fzf-tab:$_ftb_curcontext" popup-smart-tab; then
|
||
|
fzf_opts+=(--bind=tab:up,btab:down)
|
||
|
fi
|
||
|
fzf_opts+=(--layout=default)
|
||
|
else
|
||
|
# show below the cursor
|
||
|
popup_height=$(( min(max(comp_lines + 4, popup_min_size[2]), window_height - cursor_y + window_top - 1) + adjust_height ))
|
||
|
popup_y=$(( cursor_y + popup_height + 1 ))
|
||
|
fzf_opts+=(--layout=reverse)
|
||
|
fi
|
||
|
|
||
|
# calculate the popup width and x position
|
||
|
popup_width=$(( min(max(comp_length + 5, popup_min_size[1]), window_width) ))
|
||
|
popup_x=$(( cursor_x + popup_width > window_width ? window_width - popup_width : cursor_x ))
|
||
|
|
||
|
echo -E "env SHELL=$ZSH_NAME $commands[fzf] ${(qq)fzf_opts[@]} < $tmp_dir/completions.$$ > $tmp_dir/result-$$" > $tmp_dir/fzf-$$
|
||
|
{
|
||
|
tmux popup -x $popup_x -y $popup_y \
|
||
|
-w $popup_width -h $popup_height \
|
||
|
-d $PWD -E ". $tmp_dir/fzf-$$" || ret=$?
|
||
|
echo -E "$(<$tmp_dir/result-$$)"
|
||
|
} always {
|
||
|
command rm $tmp_dir/*-$$
|
||
|
(( $+IN_FZF_TAB )) || command rm $tmp_dir/completions.$$
|
||
|
}
|
||
|
return $ret
|