[completion] Allow users to customize fzf options via _fzf_comprun

Related #1809 #1850
This commit is contained in:
Junegunn Choi 2020-02-20 00:28:16 +09:00
parent 54891d11e0
commit 5215415315
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627
3 changed files with 63 additions and 26 deletions

View File

@ -403,6 +403,21 @@ _fzf_compgen_path() {
_fzf_compgen_dir() {
fd --type d --hidden --follow --exclude ".git" . "$1"
}
# (EXPERIMENTAL) Advanced customization of fzf options via _fzf_comprun function
# - The first argument to the function is the name of the command.
# - You should make sure to pass the rest of the arguments to fzf.
_fzf_comprun() {
local command=$1
shift
case "$command" in
cd) fzf "$@" --preview 'tree -C {} | head -200' ;;
export|unset) fzf "$@" --preview "eval 'echo \$'{}" "$@" ;;
ssh) fzf "$@" --preview 'dig {}' ;;
*) fzf "$@" ;;
esac
}
```
#### Supported commands

View File

@ -34,9 +34,16 @@ fi
# To redraw line after fzf closes (printf '\e[5n')
bind '"\e[0n": redraw-current-line'
__fzfcmd_complete() {
[ -n "$TMUX_PANE" ] && [ "${FZF_TMUX:-0}" != 0 ] && [ ${LINES:-40} -gt 15 ] &&
echo "fzf-tmux -d${FZF_TMUX_HEIGHT:-40%}" || echo "fzf"
__fzf_comprun() {
if [ "$(type -t _fzf_comprun 2>&1)" = function ]; then
_fzf_comprun "$@"
elif [ -n "$TMUX_PANE" ] && [ "${FZF_TMUX:-0}" != 0 ] && [ ${LINES:-40} -gt 15 ]; then
shift
fzf-tmux -d "${FZF_TMUX_HEIGHT:-40%}" "$@"
else
shift
fzf "$@"
fi
}
__fzf_orig_completion_filter() {
@ -142,8 +149,7 @@ _fzf_handle_dynamic_completion() {
}
__fzf_generic_path_completion() {
local cur base dir leftover matches trigger cmd fzf
fzf="$(__fzfcmd_complete)"
local cur base dir leftover matches trigger cmd
cmd="${COMP_WORDS[0]//[^A-Za-z0-9_=]/_}"
COMPREPLY=()
trigger=${FZF_COMPLETION_TRIGGER-'**'}
@ -159,7 +165,7 @@ __fzf_generic_path_completion() {
leftover=${leftover/#\/}
[ -z "$dir" ] && dir='.'
[ "$dir" != "/" ] && dir="${dir/%\//}"
matches=$(eval "$1 $(printf %q "$dir")" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS" $fzf $2 -q "$leftover" | while read -r item; do
matches=$(eval "$1 $(printf %q "$dir")" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS $2" __fzf_comprun "$4" -q "$leftover" | while read -r item; do
printf "%q$3 " "$item"
done)
matches=${matches% }
@ -184,10 +190,9 @@ __fzf_generic_path_completion() {
}
_fzf_complete() {
local cur selected trigger cmd fzf post
local cur selected trigger cmd post
post="$(caller 0 | awk '{print $2}')_post"
type -t "$post" > /dev/null 2>&1 || post=cat
fzf="$(__fzfcmd_complete)"
cmd="${COMP_WORDS[0]//[^A-Za-z0-9_=]/_}"
trigger=${FZF_COMPLETION_TRIGGER-'**'}
@ -195,7 +200,7 @@ _fzf_complete() {
if [[ "$cur" == *"$trigger" ]]; then
cur=${cur:0:${#cur}-${#trigger}}
selected=$(cat | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS" $fzf $1 -q "$cur" | $post | tr '\n' ' ')
selected=$(cat | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS $1" __fzf_comprun "$2" -q "$cur" | $post | tr '\n' ' ')
selected=${selected% } # Strip trailing space not to repeat "-o nospace"
if [ -n "$selected" ]; then
COMPREPLY=("$selected")
@ -226,9 +231,8 @@ _fzf_dir_completion() {
_fzf_complete_kill() {
[ -n "${COMP_WORDS[COMP_CWORD]}" ] && return 1
local selected fzf
fzf="$(__fzfcmd_complete)"
selected=$(command ps -ef | sed 1d | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-50%} --min-height 15 --reverse $FZF_DEFAULT_OPTS --preview 'echo {}' --preview-window down:3:wrap $FZF_COMPLETION_OPTS" $fzf -m | awk '{print $2}' | tr '\n' ' ')
local selected
selected=$(command ps -ef | sed 1d | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-50%} --min-height 15 --reverse $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS --preview 'echo {}' --preview-window down:3:wrap" __fzf_comprun "kill" -m | awk '{print $2}' | tr '\n' ' ')
printf '\e[5n'
if [ -n "$selected" ]; then

View File

@ -31,20 +31,40 @@ fi
###########################################################
__fzfcmd_complete() {
[ -n "$TMUX_PANE" ] && [ "${FZF_TMUX:-0}" != 0 ] && [ ${LINES:-40} -gt 15 ] &&
echo "fzf-tmux -d${FZF_TMUX_HEIGHT:-40%}" || echo "fzf"
__fzf_comprun() {
if [[ "$(type _fzf_comprun 2>&1)" =~ function ]]; then
_fzf_comprun "$@"
elif [ -n "$TMUX_PANE" ] && [ "${FZF_TMUX:-0}" != 0 ] && [ ${LINES:-40} -gt 15 ]; then
shift
fzf-tmux -d "${FZF_TMUX_HEIGHT:-40%}" "$@"
else
shift
fzf "$@"
fi
}
# Extract the name of the command. e.g. foo=1 bar baz**<tab>
__fzf_extract_command() {
local token tokens
tokens=(${(z)1})
for token in $tokens; do
if [[ "$token" =~ [[:alnum:]] && ! "$token" =~ "=" ]]; then
echo "$token"
return
fi
done
echo "${tokens[1]}"
}
__fzf_generic_path_completion() {
local base lbuf compgen fzf_opts suffix tail fzf dir leftover matches
local base lbuf cmd compgen fzf_opts suffix tail dir leftover matches
base=$1
lbuf=$2
cmd=$(__fzf_extract_command "$lbuf")
compgen=$3
fzf_opts=$4
suffix=$5
tail=$6
fzf="$(__fzfcmd_complete)"
setopt localoptions nonomatch
eval "base=$base"
@ -55,7 +75,7 @@ __fzf_generic_path_completion() {
leftover=${leftover/#\/}
[ -z "$dir" ] && dir='.'
[ "$dir" != "/" ] && dir="${dir/%\//}"
matches=$(eval "$compgen $(printf %q "$dir")" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS" ${(Q)${(Z+n+)fzf}} ${(Q)${(Z+n+)fzf_opts}} -q "$leftover" | while read item; do
matches=$(eval "$compgen $(printf %q "$dir")" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS" __fzf_comprun "$cmd" ${(Q)${(Z+n+)fzf_opts}} -q "$leftover" | while read item; do
echo -n "${(q)item}$suffix "
done)
matches=${matches% }
@ -87,17 +107,16 @@ _fzf_feed_fifo() (
)
_fzf_complete() {
local fifo fzf_opts lbuf fzf matches post
local fifo fzf_opts lbuf cmd matches post
fifo="${TMPDIR:-/tmp}/fzf-complete-fifo-$$"
fzf_opts=$1
lbuf=$2
cmd=$(__fzf_extract_command "$lbuf")
post="${funcstack[2]}_post"
type $post > /dev/null 2>&1 || post=cat
fzf="$(__fzfcmd_complete)"
_fzf_feed_fifo "$fifo"
matches=$(cat "$fifo" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS" ${(Q)${(Z+n+)fzf}} ${(Q)${(Z+n+)fzf_opts}} -q "${(Q)prefix}" | $post | tr '\n' ' ')
matches=$(cat "$fifo" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS" __fzf_comprun "$cmd" ${(Q)${(Z+n+)fzf_opts}} -q "${(Q)prefix}" | $post | tr '\n' ' ')
if [ -n "$matches" ]; then
LBUFFER="$lbuf$matches"
fi
@ -141,7 +160,7 @@ _fzf_complete_unalias() {
}
fzf-completion() {
local tokens cmd prefix trigger tail fzf matches lbuf d_cmds
local tokens cmd prefix trigger tail matches lbuf d_cmds
setopt localoptions noshwordsplit noksh_arrays noposixbuiltins
# http://zsh.sourceforge.net/FAQ/zshfaq03.html
@ -152,7 +171,7 @@ fzf-completion() {
return
fi
cmd=${tokens[1]}
cmd=$(__fzf_extract_command "$LBUFFER")
# Explicitly allow for empty trigger.
trigger=${FZF_COMPLETION_TRIGGER-'**'}
@ -167,8 +186,7 @@ fzf-completion() {
tail=${LBUFFER:$(( ${#LBUFFER} - ${#trigger} ))}
# Kill completion (do not require trigger sequence)
if [ $cmd = kill -a ${LBUFFER[-1]} = ' ' ]; then
fzf="$(__fzfcmd_complete)"
matches=$(command ps -ef | sed 1d | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-50%} --min-height 15 --reverse $FZF_DEFAULT_OPTS --preview 'echo {}' --preview-window down:3:wrap $FZF_COMPLETION_OPTS" ${(Q)${(Z+n+)fzf}} -m | awk '{print $2}' | tr '\n' ' ')
matches=$(command ps -ef | sed 1d | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-50%} --min-height 15 --reverse $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS --preview 'echo {}' --preview-window down:3:wrap" __fzf_comprun "$cmd" -m | awk '{print $2}' | tr '\n' ' ')
if [ -n "$matches" ]; then
LBUFFER="$LBUFFER$matches"
fi