From c87fd045cd1e28a3fac5e912c0b6c9272cdebc5f Mon Sep 17 00:00:00 2001 From: Jochen Wierum Date: Fri, 28 Jul 2023 10:20:05 +0200 Subject: [PATCH 1/5] Add 'complete-common-prefix' option. This option automatically completes to a common prefix of all options instead of starting fzf if such a prefix exists. --- fzf-tab.zsh | 59 +++++++++++++++++++++++++++-------------- lib/-ftb-generate-query | 3 +++ 2 files changed, 42 insertions(+), 20 deletions(-) diff --git a/fzf-tab.zsh b/fzf-tab.zsh index b81716d..a6516b8 100644 --- a/fzf-tab.zsh +++ b/fzf-tab.zsh @@ -111,7 +111,7 @@ emulate -L zsh -o extended_glob - local _ftb_query _ftb_complist=() _ftb_headers=() command opts + local _ftb_query _ftb_complist=() _ftb_headers=() _ftb_query_prefix command opts -ftb-generate-complist # sets `_ftb_complist` -ftb-zstyle -s continuous-trigger continuous_trigger || { @@ -127,37 +127,56 @@ fi ;; *) - -ftb-generate-query # sets `_ftb_query` - -ftb-generate-header # sets `_ftb_headers` - -ftb-zstyle -s print-query print_query || print_query=alt-enter - -ftb-zstyle -s accept-line accept_line + -ftb-zstyle -s complete-common-prefix complete_common_prefix || complete_common_prefix=true - choices=("${(@f)"$(builtin print -rl -- $_ftb_headers $_ftb_complist | -ftb-fzf)"}") - ret=$? - # choices=(query_string expect_key returned_word) + -ftb-generate-query # sets `_ftb_query` and `_ftb_query_prefix` - # insert query string directly - if [[ $choices[2] == $print_query ]] || [[ -n $choices[1] && $#choices == 1 ]] ; then + if [[ "$complete_common_prefix" == true && $_ftb_query_prefix == 1 && "$PREFIX" != "$_ftb_query" ]]; then local -A v=("${(@0)${_ftb_compcap[1]}}") local -a args=("${(@ps:\1:)v[args]}") [[ -z $args[1] ]] && args=() # don't pass an empty string IPREFIX=$v[IPREFIX] PREFIX=$v[PREFIX] SUFFIX=$v[SUFFIX] ISUFFIX=$v[ISUFFIX] - # NOTE: should I use `-U` here?, ../f\tabcd -> ../abcd - builtin compadd "${args[@]:--Q}" -Q -- $choices[1] + builtin compadd "${args[@]:--Q}" -Q -- $_ftb_query compstate[list]= compstate[insert]= - if (( $#choices[1] > 0 )); then - compstate[insert]='2' - [[ $RBUFFER == ' '* ]] || compstate[insert]+=' ' + if (( $#_ftb_query > 0 )); then + compstate[insert]='2' + [[ $RBUFFER == ' '* ]] || compstate[insert]+=' ' fi - return $ret - fi - choices[1]=() + return 0 + else + -ftb-generate-header # sets `_ftb_headers` + -ftb-zstyle -s print-query print_query || print_query=alt-enter + -ftb-zstyle -s accept-line accept_line + + choices=("${(@f)"$(builtin print -rl -- $_ftb_headers $_ftb_complist | -ftb-fzf)"}") + ret=$? + # choices=(query_string expect_key returned_word) + + # insert query string directly + if [[ $choices[2] == $print_query ]] || [[ -n $choices[1] && $#choices == 1 ]] ; then + local -A v=("${(@0)${_ftb_compcap[1]}}") + local -a args=("${(@ps:\1:)v[args]}") + [[ -z $args[1] ]] && args=() # don't pass an empty string + IPREFIX=$v[IPREFIX] PREFIX=$v[PREFIX] SUFFIX=$v[SUFFIX] ISUFFIX=$v[ISUFFIX] + # NOTE: should I use `-U` here?, ../f\tabcd -> ../abcd + builtin compadd "${args[@]:--Q}" -Q -- $choices[1] + + compstate[list]= + compstate[insert]= + if (( $#choices[1] > 0 )); then + compstate[insert]='2' + [[ $RBUFFER == ' '* ]] || compstate[insert]+=' ' + fi + return $ret + fi + choices[1]=() - choices=("${(@)${(@)choices%$nul*}#*$nul}") + choices=("${(@)${(@)choices%$nul*}#*$nul}") - unset CTXT + unset CTXT + fi ;; esac diff --git a/lib/-ftb-generate-query b/lib/-ftb-generate-query index 4f54604..0675dac 100644 --- a/lib/-ftb-generate-query +++ b/lib/-ftb-generate-query @@ -6,6 +6,7 @@ fi local key qtype tmp query_string typeset -g _ftb_query= +typeset -g _ftb_query_prefix=0 -ftb-zstyle -a query-string query_string || query_string=(prefix input first) for qtype in $query_string; do if [[ $qtype == prefix ]]; then @@ -23,6 +24,7 @@ for qtype in $query_string; do tmp[$#MATCH/2+1,-1]="" prefix[$#MATCH/2+1,-1]=() done + _ftb_query_prefix=1 elif [[ $qtype == input ]]; then local fv=${_ftb_compcap[1]#*$'\2'} local -A v=("${(@0)fv}") @@ -31,6 +33,7 @@ for qtype in $query_string; do tmp=${tmp/%$v[SUFFIX]} fi tmp=${${tmp#$v[hpre]}#$v[apre]} + _ftb_query_prefix=0 fi if (( $query_string[(I)longest] )); then (( $#tmp > $#_ftb_query )) && _ftb_query=$tmp From 30f2aad6e287d5b7b0f821e741853fb66b6569e5 Mon Sep 17 00:00:00 2001 From: Jochen Wierum Date: Mon, 31 Jul 2023 12:09:34 +0200 Subject: [PATCH 2/5] Fix problem with complete-common-prefix if the prefix is part of a path --- fzf-tab.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fzf-tab.zsh b/fzf-tab.zsh index a6516b8..e164624 100644 --- a/fzf-tab.zsh +++ b/fzf-tab.zsh @@ -131,7 +131,7 @@ -ftb-generate-query # sets `_ftb_query` and `_ftb_query_prefix` - if [[ "$complete_common_prefix" == true && $_ftb_query_prefix == 1 && "$PREFIX" != "$_ftb_query" ]]; then + if [[ "$complete_common_prefix" == true && $_ftb_query_prefix == 1 && "${PREFIX##*/}" != "$_ftb_query" ]]; then local -A v=("${(@0)${_ftb_compcap[1]}}") local -a args=("${(@ps:\1:)v[args]}") [[ -z $args[1] ]] && args=() # don't pass an empty string From 9d8cc1684f37f0bdc6de5f93298f759b9ac0e00e Mon Sep 17 00:00:00 2001 From: Jochen Wierum Date: Mon, 31 Jul 2023 15:35:12 +0200 Subject: [PATCH 3/5] Fix problem if the prefix is shorter than the input. This happens if the user types 'ab' while there exists files like 'abc' and 'aBC'. In that case, the prefix shrinks to 'a'. --- fzf-tab.zsh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fzf-tab.zsh b/fzf-tab.zsh index e164624..4c86776 100644 --- a/fzf-tab.zsh +++ b/fzf-tab.zsh @@ -131,7 +131,8 @@ -ftb-generate-query # sets `_ftb_query` and `_ftb_query_prefix` - if [[ "$complete_common_prefix" == true && $_ftb_query_prefix == 1 && "${PREFIX##*/}" != "$_ftb_query" ]]; then + local curr_prefix="${PREFIX##*/}" + if [[ "$complete_common_prefix" == true && $_ftb_query_prefix == 1 && "$curr_prefix" != "$_ftb_query"* ]]; then local -A v=("${(@0)${_ftb_compcap[1]}}") local -a args=("${(@ps:\1:)v[args]}") [[ -z $args[1] ]] && args=() # don't pass an empty string @@ -142,7 +143,7 @@ compstate[insert]= if (( $#_ftb_query > 0 )); then compstate[insert]='2' - [[ $RBUFFER == ' '* ]] || compstate[insert]+=' ' + [[ $RBUFFER == ' '* ]] && compstate[insert]+=' ' fi return 0 else From 4b37ea7bae8714c718dc4502f880191f3777199c Mon Sep 17 00:00:00 2001 From: Jochen Wierum Date: Tue, 20 Feb 2024 19:36:25 +0100 Subject: [PATCH 4/5] fix: Do not append slashes when completing to a common prefix --- fzf-tab.zsh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fzf-tab.zsh b/fzf-tab.zsh index 4c86776..a644047 100644 --- a/fzf-tab.zsh +++ b/fzf-tab.zsh @@ -132,12 +132,12 @@ -ftb-generate-query # sets `_ftb_query` and `_ftb_query_prefix` local curr_prefix="${PREFIX##*/}" - if [[ "$complete_common_prefix" == true && $_ftb_query_prefix == 1 && "$curr_prefix" != "$_ftb_query"* ]]; then + if [[ "$complete_common_prefix" == true && $_ftb_query_prefix == 1 && "$curr_prefix" != "$_ftb_query"* ]]; then local -A v=("${(@0)${_ftb_compcap[1]}}") local -a args=("${(@ps:\1:)v[args]}") [[ -z $args[1] ]] && args=() # don't pass an empty string IPREFIX=$v[IPREFIX] PREFIX=$v[PREFIX] SUFFIX=$v[SUFFIX] ISUFFIX=$v[ISUFFIX] - builtin compadd "${args[@]:--Q}" -Q -- $_ftb_query + builtin compadd "${${(@)${(@)args:#-f}:#-W}[@]}" -- $_ftb_query compstate[list]= compstate[insert]= From 8bb76ac5c8e5f12ef8179f44cf7e4599688ad597 Mon Sep 17 00:00:00 2001 From: Jochen Wierum Date: Wed, 21 Feb 2024 16:17:11 +0100 Subject: [PATCH 5/5] fix: Don't remove the '-W' flag when completing a common prefix --- fzf-tab.zsh | 2 +- test/fzftab.ztst | 30 ++++++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/fzf-tab.zsh b/fzf-tab.zsh index a644047..ae2b603 100644 --- a/fzf-tab.zsh +++ b/fzf-tab.zsh @@ -137,7 +137,7 @@ local -a args=("${(@ps:\1:)v[args]}") [[ -z $args[1] ]] && args=() # don't pass an empty string IPREFIX=$v[IPREFIX] PREFIX=$v[PREFIX] SUFFIX=$v[SUFFIX] ISUFFIX=$v[ISUFFIX] - builtin compadd "${${(@)${(@)args:#-f}:#-W}[@]}" -- $_ftb_query + builtin compadd "${${(@)args:#-f}[@]}" -- $_ftb_query compstate[list]= compstate[insert]= diff --git a/test/fzftab.ztst b/test/fzftab.ztst index 98028f3..d7d5657 100644 --- a/test/fzftab.ztst +++ b/test/fzftab.ztst @@ -60,14 +60,20 @@ >C1:{file1} >C1:{file2} + comptesteval "zstyle ':fzf-tab:*' complete-common-prefix false" comptest $': d\t' -0:prefix +0:prefix (complete-common disabled) >line: {: dir1/}{} >QUERY:{dir} >DESCRIPTION:{file} >C1:{dir1/} >C1:{dir2/} + comptesteval "zstyle ':fzf-tab:*' complete-common-prefix true" + comptest $': d\t' +0:prefix (complete-common enabled) +>line: {: dir}{} + comptesteval '_tst () { compadd d c b a }' comptest $'tst \t' 0:normal @@ -125,14 +131,34 @@ 0:complete in word(with known bug) >line: {: ./abc\ def}{ def} + comptesteval "zstyle ':fzf-tab:*' complete-common-prefix false" comptesteval 'mkdir -p abc/def/hij abc/dfe/hij' comptest $': ./a/d/h\t' comptesteval 'rm -rd abc' -0:nested directory +0:nested directory (common prefix disabled) >line: {: ./abc/def/h}{} >QUERY:{d} >DESCRIPTION:{file} >C1:{def/} +>C1:{dfe/} + + comptesteval "zstyle ':fzf-tab:*' complete-common-prefix true" + comptesteval 'mkdir -p abc/def/hij abc/dfe/hij' + comptest $': ./a/d/h\t' + comptesteval 'rm -rd abc' +0:nested directory, 1 tab (common prefix enabled) +>line: {: ./abc/d}{/h} + + comptesteval "zstyle ':fzf-tab:*' complete-common-prefix true" + comptesteval 'mkdir -p abc/def/hij abc/dfe/hij' + comptest $': ./a/d/h\t\t' + comptesteval 'rm -rd abc' +0:nested directory, 2 tabs (common prefix enabled) +>line: {: ./abc/d}{/h} +>line: {: ./abc/d}{/h} +>QUERY:{d} +>DESCRIPTION:{file} +>C1:{def/} >C1:{dfe/} comptesteval '_tst() { a=(a); _describe "group1" a; a=(b); _describe "group2" a }'