diff options
Diffstat (limited to 'dotfiles/system/.zsh/lib/ftb-tmux-popup')
| -rwxr-xr-x | dotfiles/system/.zsh/lib/ftb-tmux-popup | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/dotfiles/system/.zsh/lib/ftb-tmux-popup b/dotfiles/system/.zsh/lib/ftb-tmux-popup new file mode 100755 index 0000000..7e74d3c --- /dev/null +++ b/dotfiles/system/.zsh/lib/ftb-tmux-popup @@ -0,0 +1,83 @@ +#!/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 min +autoload -Uz zmathfunc +zmathfunc + +: ${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}")) +local cursor_y=$((tmp[1] + tmp[2])) cursor_x=$((tmp[3] + tmp[4])) window_height=$tmp[5] window_width=$tmp[6] + +# 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 + +zstyle -a ":fzf-tab:$_ftb_curcontext" popup-pad popup_pad || popup_pad=(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 sed 's/\x1b\[[0-9;]*m//g;s/\x00//g' $tmp_dir/completions.$$ | command awk 'length > max_length { max_length = length; } END { print max_length }') +fi +comp_length=$(( comp_length + $popup_pad[1] )) + +local popup_height popup_y popup_width popup_x + +# calculate the popup height and y position +if (( cursor_y * 2 > window_height )); then + # show above the cursor + popup_height=$(( min(comp_lines + 4, cursor_y) )) + popup_y=$cursor_y +else + # show below the cursor + popup_height=$(( min(comp_lines + 4, window_height - cursor_y) )) + popup_y=$(( cursor_y + popup_height + 1 )) + fzf_opts+=(--layout=reverse) +fi + +# calculate the popup width and x position +popup_width=$(( min(comp_length + 5, window_width) )) +popup_x=$(( cursor_x + popup_width > window_width ? window_width - popup_width : cursor_x )) + +echo -E "$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 |
