[zsh-completion] Allow custom completion function

While in bash you can externally register custom completion functions
using `complete` command, it was not possible to do so in zsh without
changing completion.zsh as the name of the supported commands are
hard-coded within the code (See #362). With this commit, fzf-completion
of zsh will first look if `_fzf_COMMAND_completion` exists and calls the
function, so one can externally define completion functions for specific
commands.

This commit also tries to make the interface of (yet undocumented)
_fzf_list_completion helper function consistent across bash and zsh.

So the following code works both on bash and zsh.

    _fzf_pass_completion() {
      local pwdir=${PASSWORD_STORE_DIR-~/.password-store/}
      local stringsize="${#pwdir}"
      let "stringsize+=1"
      _fzf_list_completion '+m' "$@" << "EOF"
        find "$pwdir" -name "*.gpg" -print | cut -c "$stringsize"- | sed -e 's/\(.*\)\.gpg/\1/'
    EOF
    }

    # Only on bash
    complete -F _fzf_pass_completion -o default -o bashdefault pass

Note that the suggested convention and the interface are not yet final
and subject to change.

/cc @d4ndo
This commit is contained in:
Junegunn Choi 2015-10-05 01:10:00 +09:00
parent 92a75c9563
commit 8fa9e85980
2 changed files with 25 additions and 26 deletions

View File

@ -195,7 +195,7 @@ _fzf_kill_completion() {
_fzf_telnet_completion() { _fzf_telnet_completion() {
_fzf_list_completion '+m' "$@" << "EOF" _fzf_list_completion '+m' "$@" << "EOF"
\grep -v '^\s*\(#\|$\)' /etc/hosts | \grep -Fv '0.0.0.0' | awk '{if (length($2) > 0) {print $2}}' | sort -u \grep -v '^\s*\(#\|$\)' /etc/hosts | \grep -Fv '0.0.0.0' | awk '{if (length($2) > 0) {print $2}}' | sort -u
EOF EOF
} }
@ -207,13 +207,13 @@ EOF
_fzf_env_var_completion() { _fzf_env_var_completion() {
_fzf_list_completion '-m' "$@" << "EOF" _fzf_list_completion '-m' "$@" << "EOF"
declare -xp | sed 's/=.*//' | sed 's/.* //' declare -xp | sed 's/=.*//' | sed 's/.* //'
EOF EOF
} }
_fzf_alias_completion() { _fzf_alias_completion() {
_fzf_list_completion '-m' "$@" << "EOF" _fzf_list_completion '-m' "$@" << "EOF"
alias | sed 's/=.*//' | sed 's/.* //' alias | sed 's/=.*//' | sed 's/.* //'
EOF EOF
} }

View File

@ -60,10 +60,9 @@ _fzf_dir_completion() {
} }
_fzf_list_completion() { _fzf_list_completion() {
local prefix lbuf fzf_opts src fzf matches local fzf_opts lbuf src fzf matches
prefix=$1 fzf_opts=$1
lbuf=$2 lbuf=$2
fzf_opts=$3
read -r src read -r src
[ ${FZF_TMUX:-1} -eq 1 ] && fzf="fzf-tmux -d ${FZF_TMUX_HEIGHT:-40%}" || fzf="fzf" [ ${FZF_TMUX:-1} -eq 1 ] && fzf="fzf-tmux -d ${FZF_TMUX_HEIGHT:-40%}" || fzf="fzf"
@ -75,26 +74,32 @@ _fzf_list_completion() {
} }
_fzf_telnet_completion() { _fzf_telnet_completion() {
_fzf_list_completion "$1" "$2" '+m' << "EOF" _fzf_list_completion '+m' "$@" << "EOF"
\grep -v '^\s*\(#\|$\)' /etc/hosts | \grep -Fv '0.0.0.0' | awk '{if (length($2) > 0) {print $2}}' | sort -u \grep -v '^\s*\(#\|$\)' /etc/hosts | \grep -Fv '0.0.0.0' | awk '{if (length($2) > 0) {print $2}}' | sort -u
EOF EOF
} }
_fzf_ssh_completion() { _fzf_ssh_completion() {
_fzf_list_completion "$1" "$2" '+m' << "EOF" _fzf_list_completion '+m' "$@" << "EOF"
cat <(cat ~/.ssh/config /etc/ssh/ssh_config 2> /dev/null | \grep -i '^host' | \grep -v '*') <(\grep -v '^\s*\(#\|$\)' /etc/hosts | \grep -Fv '0.0.0.0') | awk '{if (length($2) > 0) {print $2}}' | sort -u cat <(cat ~/.ssh/config /etc/ssh/ssh_config 2> /dev/null | \grep -i '^host' | \grep -v '*') <(\grep -v '^\s*\(#\|$\)' /etc/hosts | \grep -Fv '0.0.0.0') | awk '{if (length($2) > 0) {print $2}}' | sort -u
EOF EOF
} }
_fzf_env_var_completion() { _fzf_export_completion() {
_fzf_list_completion "$1" "$2" '+m' << "EOF" _fzf_list_completion '+m' "$@" << "EOF"
declare -xp | sed 's/=.*//' | sed 's/.* //' declare -xp | sed 's/=.*//' | sed 's/.* //'
EOF EOF
} }
_fzf_alias_completion() { _fzf_unset_completion() {
_fzf_list_completion "$1" "$2" '+m' << "EOF" _fzf_list_completion '+m' "$@" << "EOF"
alias | sed 's/=.*//' declare -xp | sed 's/=.*//' | sed 's/.* //'
EOF
}
_fzf_unalias_completion() {
_fzf_list_completion '+m' "$@" << "EOF"
alias | sed 's/=.*//'
EOF EOF
} }
@ -135,18 +140,12 @@ fzf-completion() {
[ -z "$trigger" ] && prefix=${tokens[-1]} || prefix=${tokens[-1]:0:-${#trigger}} [ -z "$trigger" ] && prefix=${tokens[-1]} || prefix=${tokens[-1]:0:-${#trigger}}
[ -z "${tokens[-1]}" ] && lbuf=$LBUFFER || lbuf=${LBUFFER:0:-${#tokens[-1]}} [ -z "${tokens[-1]}" ] && lbuf=$LBUFFER || lbuf=${LBUFFER:0:-${#tokens[-1]}}
if [ ${d_cmds[(i)$cmd]} -le ${#d_cmds} ]; then if eval "type _fzf_${cmd}_completion > /dev/null"; then
_fzf_dir_completion "$prefix" $lbuf eval "prefix=\"$prefix\" _fzf_${cmd}_completion \"$lbuf\""
elif [ $cmd = telnet ]; then elif [ ${d_cmds[(i)$cmd]} -le ${#d_cmds} ]; then
_fzf_telnet_completion "$prefix" $lbuf _fzf_dir_completion "$prefix" "$lbuf"
elif [ $cmd = ssh ]; then
_fzf_ssh_completion "$prefix" $lbuf
elif [ $cmd = unset -o $cmd = export ]; then
_fzf_env_var_completion "$prefix" $lbuf
elif [ $cmd = unalias ]; then
_fzf_alias_completion "$prefix" $lbuf
else else
_fzf_all_completion "$prefix" $lbuf _fzf_all_completion "$prefix" "$lbuf"
fi fi
# Fall back to default completion # Fall back to default completion
else else