Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: prefix completion #413

Merged
merged 13 commits into from
Feb 26, 2024
53 changes: 35 additions & 18 deletions fzf-tab.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -88,22 +88,14 @@ builtin unalias -m '[^+]*'
fi

# tell zsh that the match is successful
builtin compadd -U -qS '' -R -ftb-remove-space ''
}

# when insert multi results, a whitespace will be added to each result
# remove left space of our fake result because I can't remove right space
# FIXME: what if the left char is not whitespace: `echo $widgets[\t`
-ftb-remove-space() {
[[ $LBUFFER[-1] == ' ' ]] && LBUFFER[-1]=''
builtin compadd "$@"
}

-ftb-zstyle() {
zstyle $1 ":fzf-tab:$_ftb_curcontext" ${@:2}
}

-ftb-complete() {
local -a _ftb_compcap
local -Ua _ftb_groups
local choice choices _ftb_curcontext continuous_trigger print_query accept_line bs=$'\2' nul=$'\0'
local ret=0
Expand Down Expand Up @@ -131,6 +123,16 @@ builtin unalias -m '[^+]*'
fi
;;
*)

if (( ! _ftb_continue_last )) \
&& [[ $compstate[insert] == *"unambiguous" ]] \
&& [[ "$compstate[unambiguous]" != "$PREFIX" ]]; then
compstate[list]=
compstate[insert]=unambiguous
_ftb_finish=1
return 0
fi

-ftb-generate-query # sets `_ftb_query`
-ftb-generate-header # sets `_ftb_headers`
-ftb-zstyle -s print-query print_query || print_query=alt-enter
Expand All @@ -152,9 +154,10 @@ builtin unalias -m '[^+]*'
compstate[list]=
compstate[insert]=
if (( $#choices[1] > 0 )); then
compstate[insert]='2'
compstate[insert]='1'
[[ $RBUFFER == ' '* ]] || compstate[insert]+=' '
fi
_ftb_finish=1
return $ret
fi
choices[1]=()
Expand All @@ -175,7 +178,17 @@ builtin unalias -m '[^+]*'
fi
choices[1]=()

for choice in "$choices[@]"; do
_ftb_choices=("${(@)choices}")

compstate[list]=
compstate[insert]=

return $ret
}

_fzf-tab-apply() {
local choice bs=$'\2'
for choice in "$_ftb_choices[@]"; do
local -A v=("${(@0)${_ftb_compcap[(r)${(b)choice}$bs*]#*$bs}}")
local -a args=("${(@ps:\1:)v[args]}")
[[ -z $args[1] ]] && args=() # don't pass an empty string
Expand All @@ -184,14 +197,12 @@ builtin unalias -m '[^+]*'
done

compstate[list]=
compstate[insert]=
if (( $#choices == 1 )); then
compstate[insert]='2'
if (( $#_ftb_choices == 1 )); then
compstate[insert]='1'
[[ $RBUFFER == ' '* ]] || compstate[insert]+=' '
elif (( $#choices > 1 )); then
elif (( $#_ftb_choices > 1 )); then
compstate[insert]='all'
fi
return $ret
}

fzf-tab-debug() {
Expand Down Expand Up @@ -221,11 +232,14 @@ fzf-tab-complete() {
# NOTE: MacOS Terminal doesn't support civis & cnorm
echoti civis >/dev/tty 2>/dev/null
while (( _ftb_continue )); do
local _ftb_choices=() _ftb_compcap=() _ftb_finish=0
_ftb_continue=0
local IN_FZF_TAB=1
{
zle .fzf-tab-orig-$_ftb_orig_widget
ret=$?
zle .fzf-tab-orig-$_ftb_orig_widget || ret=$?
if (( ! ret && ! _ftb_finish )); then
zle _fzf-tab-apply || ret=$?
fi
} always {
IN_FZF_TAB=0
}
Expand All @@ -249,6 +263,9 @@ fzf-tab-dummy() { }
zle -N fzf-tab-debug
zle -N fzf-tab-complete
zle -N fzf-tab-dummy
# this is registered as a completion widget
# so that we can have a clean completion list to only insert the results user selected
zle -C _fzf-tab-apply complete-word _fzf-tab-apply

disable-fzf-tab() {
emulate -L zsh -o extended_glob
Expand Down
19 changes: 16 additions & 3 deletions test/fzftab.ztst
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,20 @@
>C1:{file1}
>C1:{file2}

comptest $': d\t'
0:unambiguous prefix
>line: {: dir}{}

comptesteval '_tst() { compadd /home /usr /lib; compstate[insert]=menu }'
comptest $'tst \t'
0:force list
>line: {tst /home }{}
>QUERY:{/}
>C0:{/home}
>C0:{/lib}
>C0:{/usr}

comptesteval 'zstyle ":completion:*" menu true'
comptest $': d\t'
0:prefix
>line: {: dir1/}{}
Expand Down Expand Up @@ -108,8 +122,8 @@
0:warnings
>line: {: asd}{}
>WARN:{`file'}
>WARN:{`file'}
# FIXME:why two warnings?

# enclose ' for syntax highlight

comptesteval "touch 'abc def'"
comptest $': ./a\t'
Expand Down Expand Up @@ -148,7 +162,6 @@
comptest $'git add dir1\t'
0:add empty word
>line: {git add dir1/}{}
# FIXME:why two warnings?

comptesteval "zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|=*' 'l:|=* r:|=*'"
comptesteval "touch vim.coc"
Expand Down
6 changes: 5 additions & 1 deletion test/select
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

zmodload zsh/zutil

local -A headers range query
local -A headers range query expect

# -h: lines of headers
# -n: selection index, if it is QUERY, query string will be used
# -q: query string
# -e: expect key
zparseopts -E h:=headers n:=range q:=query e:=expect

print -r -- "${query//\"/}"
Expand Down