Skip to content

Examples (completion)

Junegunn Choi edited this page Mar 8, 2019 · 8 revisions

Custom completion API is experimental and subject to change

Writing custom fuzzy completion

First define _fzf_complete_COMMAND function using _fzf_complete helper.

# Custom fuzzy completion for "doge" command
#   e.g. doge **<TAB>
_fzf_complete_doge() {
  _fzf_complete "--multi --reverse" "$@" < <(
    echo very
    echo wow
    echo such
    echo doge
  )
}

The first argument to _fzf_complete is the options to fzf. The second argument is the usual arguments passed to the completion function, you can simply pass "$@" here.

You can see that the output of some arbitrary commands (4 echos) are fed into the function using process substitution < <(...). The output lines of the enclosed commands become the completion candidates.

zsh will automatically pick up the command using the naming convention but in bash you have to connect the function to the command using complete command.

[ -n "$BASH" ] && complete -F _fzf_complete_doge -o default -o bashdefault doge

Post-processing

If you need to post-process the output from fzf, define _fzf_complete_COMMAND_post as follows.

_fzf_complete_foo() {
  _fzf_complete "--multi --reverse --header-lines=3" "$@" < <(
    ls -al
  )
}

_fzf_complete_foo_post() {
  awk '{print $NF}'
}

[ -n "$BASH" ] && complete -F _fzf_complete_foo -o default -o bashdefault foo

Examples

pass

# pass completion suggested by @d4ndo (#362)
_fzf_complete_pass() {
  _fzf_complete '+m' "$@" < <(
    pwdir=${PASSWORD_STORE_DIR-~/.password-store/}
    stringsize="${#pwdir}"
    find "$pwdir" -name "*.gpg" -print |
        cut -c "$((stringsize + 1))"-  |
        sed -e 's/\(.*\)\.gpg/\1/'
  )
}

[ -n "$BASH" ] && complete -F _fzf_complete_pass -o default -o bashdefault pass

[ZSH] Complete hg update/hg merge

If you need to add branch name completion for a subset of hg commands, e.g. hg up, hg merge, you can use technique as follows (zsh completion):

_fzf_complete_hg() {
  ARGS="$@"
  if [[ $ARGS == 'hg merge'* ]] || [[ $ARGS == 'hg up'* ]]; then
    _fzf_complete "--no-sort" "$@" < <(
      { hg branches & hg tags }
    )
  else
    eval "zle ${fzf_default_completion:-expand-or-complete}"
  fi
}

_fzf_complete_hg_post() {
  cut -f1 -d' '
}

[ZSH] Complete git co (for example)

You can use the same approach as above to complete any git command. In the example below, completion is triggered on git co (usual alias for git checkout):

_fzf_complete_git() {
    ARGS="$@"
    local branches
    branches=$(git branch -vv --all)
    if [[ $ARGS == 'git co'* ]]; then
        _fzf_complete "--reverse --multi" "$@" < <(
            echo $branches
        )
    else
        eval "zle ${fzf_default_completion:-expand-or-complete}"
    fi
}

_fzf_complete_git_post() {
    awk '{print $1}'
}

Custom trigger-less completion

If you want to remove the ** trigger just for certain completions, you can achieve this like so:

_fzf_complete_ssh_notrigger() {
    FZF_COMPLETION_TRIGGER='' _fzf_complete_ssh
}

complete -o bashdefault -o default -F _fzf_complete_ssh_notrigger ssh
complete -o bashdefault -o default -F _fzf_complete_ssh_notrigger mosh
complete -o bashdefault -o default -F _fzf_complete_ssh_notrigger ss
You can’t perform that action at this time.