From 51215a3b94876830fdac0a9f14521e5c97a6786d Mon Sep 17 00:00:00 2001 From: Aloxaf Date: Thu, 22 Feb 2024 11:20:13 +0800 Subject: [PATCH 01/10] feat: complete prefix --- fzf-tab.zsh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/fzf-tab.zsh b/fzf-tab.zsh index 377f88d..8395d38 100644 --- a/fzf-tab.zsh +++ b/fzf-tab.zsh @@ -88,7 +88,7 @@ builtin unalias -m '[^+]*' fi # tell zsh that the match is successful - builtin compadd -U -qS '' -R -ftb-remove-space '' + builtin compadd "$@" } # when insert multi results, a whitespace will be added to each result @@ -131,6 +131,13 @@ builtin unalias -m '[^+]*' fi ;; *) + + if [[ "$compstate[unambiguous]" != "$PREFIX" ]]; then + compstate[list]= + compstate[insert]=unambiguous + 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 From 143e4f41000dcfb4ddc574a4340cc1f75686a090 Mon Sep 17 00:00:00 2001 From: Aloxaf Date: Thu, 22 Feb 2024 13:36:19 +0800 Subject: [PATCH 02/10] fix: normal completion --- fzf-tab.zsh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fzf-tab.zsh b/fzf-tab.zsh index 8395d38..a0f260d 100644 --- a/fzf-tab.zsh +++ b/fzf-tab.zsh @@ -132,7 +132,7 @@ builtin unalias -m '[^+]*' ;; *) - if [[ "$compstate[unambiguous]" != "$PREFIX" ]]; then + if -ftb-zstyle -T insert-unambiguous insert_unambiguous && [[ "$compstate[unambiguous]" != "$PREFIX" ]]; then compstate[list]= compstate[insert]=unambiguous return 0 @@ -193,7 +193,7 @@ builtin unalias -m '[^+]*' compstate[list]= compstate[insert]= if (( $#choices == 1 )); then - compstate[insert]='2' + compstate[insert]='1' [[ $RBUFFER == ' '* ]] || compstate[insert]+=' ' elif (( $#choices > 1 )); then compstate[insert]='all' From f4cc7e23683ac9a8eea4b2d7b5ae06244d7d86a3 Mon Sep 17 00:00:00 2001 From: Aloxaf Date: Thu, 22 Feb 2024 15:01:34 +0800 Subject: [PATCH 03/10] fix: follow zsh menu setting --- fzf-tab.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fzf-tab.zsh b/fzf-tab.zsh index a0f260d..4bdf387 100644 --- a/fzf-tab.zsh +++ b/fzf-tab.zsh @@ -132,7 +132,7 @@ builtin unalias -m '[^+]*' ;; *) - if -ftb-zstyle -T insert-unambiguous insert_unambiguous && [[ "$compstate[unambiguous]" != "$PREFIX" ]]; then + if [[ $compstate[insert] == *"unambiguous" ]] && [[ "$compstate[unambiguous]" != "$PREFIX" ]]; then compstate[list]= compstate[insert]=unambiguous return 0 From 3c33c17045132119014c577a10617397beb8a4ed Mon Sep 17 00:00:00 2001 From: Aloxaf Date: Thu, 22 Feb 2024 15:35:48 +0800 Subject: [PATCH 04/10] fix: tests --- fzf-tab.zsh | 2 +- test/fzftab.ztst | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/fzf-tab.zsh b/fzf-tab.zsh index 4bdf387..1d34990 100644 --- a/fzf-tab.zsh +++ b/fzf-tab.zsh @@ -159,7 +159,7 @@ builtin unalias -m '[^+]*' compstate[list]= compstate[insert]= if (( $#choices[1] > 0 )); then - compstate[insert]='2' + compstate[insert]='1' [[ $RBUFFER == ' '* ]] || compstate[insert]+=' ' fi return $ret diff --git a/test/fzftab.ztst b/test/fzftab.ztst index 98028f3..e162610 100644 --- a/test/fzftab.ztst +++ b/test/fzftab.ztst @@ -60,6 +60,11 @@ >C1:{file1} >C1:{file2} + comptest $': d\t' +0:unambiguous prefix +>line: {: dir}{} + + comptesteval 'zstyle ":completion:*" menu true' comptest $': d\t' 0:prefix >line: {: dir1/}{} From 9c02598cd8e89ab7e7249c7ba116728c2ca78895 Mon Sep 17 00:00:00 2001 From: Aloxaf Date: Sun, 25 Feb 2024 00:42:40 +0800 Subject: [PATCH 05/10] fix: multiple selection --- fzf-tab.zsh | 33 ++++++++++++++++++++++++--------- test/fzftab.ztst | 2 -- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/fzf-tab.zsh b/fzf-tab.zsh index 1921c9d..90f92b7 100644 --- a/fzf-tab.zsh +++ b/fzf-tab.zsh @@ -103,7 +103,6 @@ builtin unalias -m '[^+]*' } -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 @@ -135,6 +134,7 @@ builtin unalias -m '[^+]*' if [[ $compstate[insert] == *"unambiguous" ]] && [[ "$compstate[unambiguous]" != "$PREFIX" ]]; then compstate[list]= compstate[insert]=unambiguous + _ftb_finish=1 return 0 fi @@ -162,6 +162,7 @@ builtin unalias -m '[^+]*' compstate[insert]='1' [[ $RBUFFER == ' '* ]] || compstate[insert]+=' ' fi + _ftb_finish=1 return $ret fi choices[1]=() @@ -182,7 +183,17 @@ builtin unalias -m '[^+]*' fi choices[1]=() - for choice in "$choices[@]"; do + _ftb_choices=("${(@)choices}") + + compstate[list]= + compstate[insert]= + + return $ret +} + +-ftb-complete-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 @@ -191,14 +202,12 @@ builtin unalias -m '[^+]*' done compstate[list]= - compstate[insert]= - if (( $#choices == 1 )); then + 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() { @@ -223,7 +232,8 @@ fzf-tab-debug() { fzf-tab-complete() { # this name must be ugly to avoid clashes - local -i _ftb_continue=1 _ftb_continue_last=0 _ftb_accept=0 ret=0 + local -a _ftb_choices _ftb_compcap + local -i _ftb_continue=1 _ftb_continue_last=0 _ftb_accept=0 ret=0 _ftb_finish=0 # hide the cursor until finishing completion, so that users won't see cursor up and down # NOTE: MacOS Terminal doesn't support civis & cnorm echoti civis >/dev/tty 2>/dev/null @@ -231,8 +241,10 @@ fzf-tab-complete() { _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 -- -ftb-complete-apply || ret=$? + fi } always { IN_FZF_TAB=0 } @@ -256,6 +268,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 -- -ftb-complete-apply complete-word -ftb-complete-apply disable-fzf-tab() { emulate -L zsh -o extended_glob diff --git a/test/fzftab.ztst b/test/fzftab.ztst index e162610..9efc611 100644 --- a/test/fzftab.ztst +++ b/test/fzftab.ztst @@ -113,8 +113,6 @@ 0:warnings >line: {: asd}{} >WARN:{`file'} ->WARN:{`file'} -# FIXME:why two warnings? comptesteval "touch 'abc def'" comptest $': ./a\t' From 094903525d589c3c6cf3609521426fba1e287fa7 Mon Sep 17 00:00:00 2001 From: Aloxaf Date: Sun, 25 Feb 2024 01:01:41 +0800 Subject: [PATCH 06/10] test: force list --- test/fzftab.ztst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/fzftab.ztst b/test/fzftab.ztst index 9efc611..1ffc3a5 100644 --- a/test/fzftab.ztst +++ b/test/fzftab.ztst @@ -64,6 +64,15 @@ 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 From 7b1e083f112d3741ae7cbdc166ca98f50edf4b82 Mon Sep 17 00:00:00 2001 From: Aloxaf Date: Sun, 25 Feb 2024 14:03:53 +0800 Subject: [PATCH 07/10] fix: don't complete unambiguous prefix in continous completion --- fzf-tab.zsh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fzf-tab.zsh b/fzf-tab.zsh index 90f92b7..7801289 100644 --- a/fzf-tab.zsh +++ b/fzf-tab.zsh @@ -131,7 +131,9 @@ builtin unalias -m '[^+]*' ;; *) - if [[ $compstate[insert] == *"unambiguous" ]] && [[ "$compstate[unambiguous]" != "$PREFIX" ]]; then + if (( ! _ftb_continue_last )) \ + && [[ $compstate[insert] == *"unambiguous" ]] \ + && [[ "$compstate[unambiguous]" != "$PREFIX" ]]; then compstate[list]= compstate[insert]=unambiguous _ftb_finish=1 From 08309fea09f43c1bcd7171655fedcc87fb8921c3 Mon Sep 17 00:00:00 2001 From: Aloxaf Date: Mon, 26 Feb 2024 00:55:30 +0800 Subject: [PATCH 08/10] fix: clear intermediate variables --- fzf-tab.zsh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fzf-tab.zsh b/fzf-tab.zsh index edf60bc..9094cc9 100644 --- a/fzf-tab.zsh +++ b/fzf-tab.zsh @@ -234,12 +234,12 @@ fzf-tab-debug() { fzf-tab-complete() { # this name must be ugly to avoid clashes - local -a _ftb_choices _ftb_compcap - local -i _ftb_continue=1 _ftb_continue_last=0 _ftb_accept=0 ret=0 _ftb_finish=0 + local -i _ftb_continue=1 _ftb_continue_last=0 _ftb_accept=0 ret=0 # hide the cursor until finishing completion, so that users won't see cursor up and down # 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 { From 5c09df8fd867843f467ba59f38c5d7da2937ccc9 Mon Sep 17 00:00:00 2001 From: Aloxaf Date: Mon, 26 Feb 2024 09:05:27 +0800 Subject: [PATCH 09/10] fix: -ftb-complete-apply -> _fzf-tab-apply --- fzf-tab.zsh | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/fzf-tab.zsh b/fzf-tab.zsh index 9094cc9..5f3b3c4 100644 --- a/fzf-tab.zsh +++ b/fzf-tab.zsh @@ -91,13 +91,6 @@ builtin unalias -m '[^+]*' builtin compadd "$@" } -# 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]='' -} - -ftb-zstyle() { zstyle $1 ":fzf-tab:$_ftb_curcontext" ${@:2} } @@ -193,7 +186,7 @@ builtin unalias -m '[^+]*' return $ret } --ftb-complete-apply() { +_fzf-tab-apply() { local choice bs=$'\2' for choice in "$_ftb_choices[@]"; do local -A v=("${(@0)${_ftb_compcap[(r)${(b)choice}$bs*]#*$bs}}") @@ -245,7 +238,7 @@ fzf-tab-complete() { { zle .fzf-tab-orig-$_ftb_orig_widget || ret=$? if (( ! ret && ! _ftb_finish )); then - zle -- -ftb-complete-apply || ret=$? + zle _fzf-tab-apply || ret=$? fi } always { IN_FZF_TAB=0 @@ -272,7 +265,7 @@ 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 -- -ftb-complete-apply complete-word -ftb-complete-apply +zle -C _fzf-tab-apply complete-word _fzf-tab-apply disable-fzf-tab() { emulate -L zsh -o extended_glob From 0b396f78d1e1cc15bea9ad9b03842d515ce44e08 Mon Sep 17 00:00:00 2001 From: Aloxaf Date: Mon, 26 Feb 2024 10:56:40 +0800 Subject: [PATCH 10/10] test: docs --- test/fzftab.ztst | 3 ++- test/select | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/test/fzftab.ztst b/test/fzftab.ztst index 1ffc3a5..b4aad4e 100644 --- a/test/fzftab.ztst +++ b/test/fzftab.ztst @@ -123,6 +123,8 @@ >line: {: asd}{} >WARN:{`file'} +# enclose ' for syntax highlight + comptesteval "touch 'abc def'" comptest $': ./a\t' 0:filename with space @@ -160,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" diff --git a/test/select b/test/select index d06d4e9..60c88b6 100755 --- a/test/select +++ b/test/select @@ -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//\"/}"