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

Support FZF custom completion API #41

Merged
merged 1 commit into from
Feb 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,25 @@ Key Bindings:

For example <kbd>Ctrl</kdb>+<kdb>T</kbd> `bindkey '^T' toggle-fzf-tab`

### Custom completions

There exists mechanism for overwriting completion action for particular command
[similar to fzf](https://github.com/junegunn/fzf/wiki/Examples-(completion)).
If function named `_fzf_complete_foo` is found, it will be used for handling completions
of `foo` command.

If you also have [fzf's completions](https://github.com/junegunn/fzf#fuzzy-completion-for-bash-and-zsh)
enabled (`completion.zsh` is sourced), you can use it's `_fzf_complete` helper function, for example:
```
_fzf_complete_foo() {
_fzf_complete "--multi --reverse" "$@" < <(
echo foo
echo bar
echo bazz
)
}
```

### Configure

Here are some variables which can be used to control the behavior of fzf-tab.
Expand Down Expand Up @@ -178,6 +197,16 @@ printc() {

The key trigger continuous completion. Default value: `/`

#### FZF_TAB_CUSTOM_COMPLETIONS

Whether to search for custom completion functions. Default value: `1`

#### FZF_TAB_CUSTOM_COMPLETIONS_PREFIX

Default value: `"_fzf_complete_"`

note: The default value matches fzf name convention so that the same functions can be used both by fzf and fzf-tab.

## Difference from other plugins

fzf-tab doesn't do "complete", it just shows your results of the default completion system.
Expand Down
21 changes: 20 additions & 1 deletion fzf-tab.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ _fzf_tab_remove_space() {
: ${FZF_TAB_SHOW_GROUP:=full}
: ${FZF_TAB_NO_GROUP_COLOR:=$'\033[37m'}
: ${FZF_TAB_CONTINUOUS_TRIGGER:='/'}
: ${FZF_TAB_CUSTOM_COMPLETIONS:='1'}
: ${FZF_TAB_CUSTOM_COMPLETIONS_PREFIX:='_fzf_complete_'}
: ${(A)=FZF_TAB_QUERY=prefix input first}
: ${(A)=FZF_TAB_SINGLE_GROUP=color header}
: ${(A)=FZF_TAB_GROUP_COLORS=\
Expand All @@ -95,7 +97,7 @@ _fzf_tab_remove_space() {

(( $+FZF_TAB_OPTS )) || FZF_TAB_OPTS=(
--ansi # Enable ANSI color support, necessary for showing groups
--expect='$FZF_TAB_CONTINUOUS_TRIGGER' # For continuous completion
--expect='$FZF_TAB_CONTINUOUS_TRIGGER' # For continuous completion
'--color=hl:$(( $#headers == 0 ? 108 : 255 ))'
--nth=2,3 --delimiter='\x00' # Don't search FZF_TAB_PREFIX
--layout=reverse --height=75%
Expand Down Expand Up @@ -306,7 +308,24 @@ _fzf_tab_complete() {

zle -C _fzf_tab_complete complete-word _fzf_tab_complete

_fzf_tab_try_custom_completion() {
# do not steal fzf's completions
[[ $LBUFFER =~ ${(q)FZF_COMPLETION_TRIGGER-'**'}$ ]] && return 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I set FZF_COMPLETION_TRIGGER="" and bind fzf-completion to a separate key (Ctrl-T). This way I can use TAB for normal completions and Ctrl-T to complete file arguments with fzf. I find that pressing Ctrl-T to complete file arguments with fzf is more convenient than pressing *-*-TAB.

With this setup _fzf_tab_try_custom_completion always bails out early.

Does the check on the first line of _fzf_tab_try_custom_completion presuppose that _fzf_tab_orig_widget is fzf-completion (or some other widget that respects FZF_COMPLETION_TRIGGER)? I set _fzf_tab_orig_widget to expand-or-complete, so this check doesn't make much sense.

FWIW, I don't know what's the right thing to do here. I'm unsure how exactly I want completions to work. Just wanted to share that the current code is a bit odd and likely incorrect.

Copy link
Contributor Author

@doubleloop doubleloop Feb 28, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just checked for this configuration:

export FZF_COMPLETION_TRIGGER=""
bindkey '^T' fzf-completion
bindkey '^I' fzf-tab-complete

export fzf_default_completion=expand-or-complete
export _fzf_tab_orig_widget=expand-or-complete

If no custom completion function is defined, TAB triggers fzf-tab, ctrl-t triggers fzf.
If some custom completion function is defined, both TAB and ctrl-t triggers it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean it return 1 on the first if?

Yes.

If some custom completion function is defined, both TAB and ctrl-t triggers it.

Are you sure TAB triggers it? It doesn't for me. When I press TAB, _fzf_tab_try_custom_completion returns on the first line, so _fzf_complete_* is never called. Can you verify that _fzf_tab_orig_widget is indeed expand-or-complete in your setup?

local tokens=(${(z)LBUFFER})
[[ ${LBUFFER[-1]} = ' ' ]] && tokens+=("")
local cmd=${tokens[1]}
if (( $+functions[${FZF_TAB_CUSTOM_COMPLETIONS_PREFIX}${cmd}] )); then
local prefix=${tokens[-1]}
local lbuf
[ -z "${tokens[-1]}" ] && lbuf=$LBUFFER || lbuf=${LBUFFER:0:-${#tokens[-1]}}
prefix="$prefix" eval _fzf_complete_${cmd} ${(q)lbuf}
return 0
fi
return 1
}

fzf-tab-complete() {
(( FZF_TAB_CUSTOM_COMPLETIONS )) && _fzf_tab_try_custom_completion && return
# complete or not complete, this is a question
# this name must be ugly to avoid clashes
local -i _fzf_tab_continue=1 _fzf_tab_should_complete=0
Expand Down