summaryrefslogtreecommitdiffstats
path: root/shell
diff options
context:
space:
mode:
authorJunegunn Choi <junegunn.c@gmail.com>2020-03-11 18:29:39 +0900
committerJunegunn Choi <junegunn.c@gmail.com>2020-03-11 18:32:35 +0900
commit50b7608f9d27c09093846e172f230d92b401f956 (patch)
treec3257ce2128ee0329c161f2e2b1da2191abb0ccd /shell
parent7085e5b629dcc6eaef4205802f07979f535c8d5f (diff)
Change custom fuzzy completion API
To make it easier to write more complex fzf options. Although this does not break backward compatibility, users are encouraged to update their code accordingly. # Before _fzf_complete "FZF_ARG1 FZF_ARG2..." "$@" < <( # Print candidates ) # After _fzf_complete FZF_ARG1 FZF_ARG2... -- "$@" < <( # Print candidates )
Diffstat (limited to 'shell')
-rw-r--r--shell/completion.bash32
-rw-r--r--shell/completion.zsh42
2 files changed, 58 insertions, 16 deletions
diff --git a/shell/completion.bash b/shell/completion.bash
index bd94c51a..b1f7ac97 100644
--- a/shell/completion.bash
+++ b/shell/completion.bash
@@ -190,6 +190,27 @@ __fzf_generic_path_completion() {
}
_fzf_complete() {
+ # Split arguments around --
+ local args rest str_arg i sep
+ args=("$@")
+ sep=
+ for i in "${!args[@]}"; do
+ if [[ "${args[$i]}" = -- ]]; then
+ sep=$i
+ break
+ fi
+ done
+ if [[ -n "$sep" ]]; then
+ str_arg=
+ rest=("${args[@]:$((sep + 1)):${#args[@]}}")
+ args=("${args[@]:0:$sep}")
+ else
+ str_arg=$1
+ args=()
+ shift
+ rest=("$@")
+ fi
+
local cur selected trigger cmd post
post="$(caller 0 | awk '{print $2}')_post"
type -t "$post" > /dev/null 2>&1 || post=cat
@@ -200,7 +221,7 @@ _fzf_complete() {
if [[ "$cur" == *"$trigger" ]]; then
cur=${cur:0:${#cur}-${#trigger}}
- selected=$(FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS $1" __fzf_comprun "$2" -q "$cur" | $post | tr '\n' ' ')
+ selected=$(FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS $str_arg" __fzf_comprun "${rest[0]}" "${args[@]}" -q "$cur" | $post | tr '\n' ' ')
selected=${selected% } # Strip trailing space not to repeat "-o nospace"
if [ -n "$selected" ]; then
COMPREPLY=("$selected")
@@ -210,8 +231,7 @@ _fzf_complete() {
printf '\e[5n'
return 0
else
- shift
- _fzf_handle_dynamic_completion "$cmd" "$@"
+ _fzf_handle_dynamic_completion "$cmd" "${rest[@]}"
fi
}
@@ -243,7 +263,7 @@ _fzf_complete_kill() {
}
_fzf_host_completion() {
- _fzf_complete '+m' "$@" < <(
+ _fzf_complete +m -- "$@" < <(
cat <(cat ~/.ssh/config ~/.ssh/config.d/* /etc/ssh/ssh_config 2> /dev/null | command grep -i '^\s*host\(name\)\? ' | awk '{for (i = 2; i <= NF; i++) print $1 " " $i}' | command grep -v '[*?]') \
<(command grep -oE '^[[a-z0-9.,:-]+' ~/.ssh/known_hosts | tr ',' '\n' | tr -d '[' | awk '{ print $1 " " $1 }') \
<(command grep -v '^\s*\(#\|$\)' /etc/hosts | command grep -Fv '0.0.0.0') |
@@ -252,13 +272,13 @@ _fzf_host_completion() {
}
_fzf_var_completion() {
- _fzf_complete '-m' "$@" < <(
+ _fzf_complete -m -- "$@" < <(
declare -xp | sed 's/=.*//' | sed 's/.* //'
)
}
_fzf_alias_completion() {
- _fzf_complete '-m' "$@" < <(
+ _fzf_complete -m -- "$@" < <(
alias | sed 's/=.*//' | sed 's/.* //'
)
}
diff --git a/shell/completion.zsh b/shell/completion.zsh
index 95f6d685..e82de4c9 100644
--- a/shell/completion.zsh
+++ b/shell/completion.zsh
@@ -107,16 +107,38 @@ _fzf_feed_fifo() (
)
_fzf_complete() {
- local fifo fzf_opts lbuf cmd matches post
+ setopt localoptions ksh_arrays
+ # Split arguments around --
+ local args rest str_arg i sep
+ args=("$@")
+ sep=
+ for i in {0..$#args}; do
+ if [[ "${args[$i]}" = -- ]]; then
+ sep=$i
+ break
+ fi
+ done
+ if [[ -n "$sep" ]]; then
+ str_arg=
+ rest=("${args[@]:$((sep + 1)):${#args[@]}}")
+ args=("${args[@]:0:$sep}")
+ else
+ str_arg=$1
+ args=()
+ shift
+ rest=("$@")
+ fi
+
+ local fifo lbuf cmd matches post
fifo="${TMPDIR:-/tmp}/fzf-complete-fifo-$$"
- fzf_opts=$1
- lbuf=$2
+ lbuf=${rest[0]}
cmd=$(__fzf_extract_command "$lbuf")
- post="${funcstack[2]}_post"
+ post="${funcstack[1]}_post"
+ echo "$post"
type $post > /dev/null 2>&1 || post=cat
_fzf_feed_fifo "$fifo"
- matches=$(FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS" __fzf_comprun "$cmd" ${(Q)${(Z+n+)fzf_opts}} -q "${(Q)prefix}" < "$fifo" | $post | tr '\n' ' ')
+ matches=$(FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS $str_arg" __fzf_comprun "$cmd" "${args[@]}" -q "${(Q)prefix}" < "$fifo" | $post | tr '\n' ' ')
if [ -n "$matches" ]; then
LBUFFER="$lbuf$matches"
fi
@@ -125,14 +147,14 @@ _fzf_complete() {
}
_fzf_complete_telnet() {
- _fzf_complete '+m' "$@" < <(
+ _fzf_complete +m -- "$@" < <(
command grep -v '^\s*\(#\|$\)' /etc/hosts | command grep -Fv '0.0.0.0' |
awk '{if (length($2) > 0) {print $2}}' | sort -u
)
}
_fzf_complete_ssh() {
- _fzf_complete '+m' "$@" < <(
+ _fzf_complete +m -- "$@" < <(
setopt localoptions nonomatch
command cat <(cat ~/.ssh/config ~/.ssh/config.d/* /etc/ssh/ssh_config 2> /dev/null | command grep -i '^\s*host\(name\)\? ' | awk '{for (i = 2; i <= NF; i++) print $1 " " $i}' | command grep -v '[*?]') \
<(command grep -oE '^[[a-z0-9.,:-]+' ~/.ssh/known_hosts | tr ',' '\n' | tr -d '[' | awk '{ print $1 " " $1 }') \
@@ -142,19 +164,19 @@ _fzf_complete_ssh() {
}
_fzf_complete_export() {
- _fzf_complete '-m' "$@" < <(
+ _fzf_complete -m -- "$@" < <(
declare -xp | sed 's/=.*//' | sed 's/.* //'
)
}
_fzf_complete_unset() {
- _fzf_complete '-m' "$@" < <(
+ _fzf_complete -m -- "$@" < <(
declare -xp | sed 's/=.*//' | sed 's/.* //'
)
}
_fzf_complete_unalias() {
- _fzf_complete '+m' "$@" < <(
+ _fzf_complete +m -- "$@" < <(
alias | sed 's/=.*//'
)
}