From 4603d540c3ae648c9e2ef84f33433b275290aa7c Mon Sep 17 00:00:00 2001 From: John Fred Fadrigalan Date: Sun, 16 Oct 2022 16:15:19 +0800 Subject: [PATCH] [shell] Make bash/zsh completion and bindings work with 'set -u' (#2999) Co-authored-by: Junegunn Choi --- shell/completion.bash | 22 ++++++++++++---------- shell/completion.zsh | 14 +++++++------- shell/key-bindings.bash | 8 ++++---- shell/key-bindings.zsh | 8 ++++---- test/test_go.rb | 5 +++-- 5 files changed, 30 insertions(+), 27 deletions(-) diff --git a/shell/completion.bash b/shell/completion.bash index 4b1e0dba..51687a08 100644 --- a/shell/completion.bash +++ b/shell/completion.bash @@ -37,7 +37,7 @@ bind '"\e[0n": redraw-current-line' 2> /dev/null __fzf_comprun() { if [[ "$(type -t _fzf_comprun 2>&1)" = function ]]; then _fzf_comprun "$@" - elif [[ -n "$TMUX_PANE" ]] && { [[ "${FZF_TMUX:-0}" != 0 ]] || [[ -n "$FZF_TMUX_OPTS" ]]; }; then + elif [[ -n "${TMUX_PANE-}" ]] && { [[ "${FZF_TMUX:-0}" != 0 ]] || [[ -n "${FZF_TMUX_OPTS-}" ]]; }; then shift fzf-tmux ${FZF_TMUX_OPTS:--d${FZF_TMUX_HEIGHT:-40%}} -- "$@" else @@ -55,8 +55,8 @@ __fzf_orig_completion() { cmd="${BASH_REMATCH[3]}" [[ "$f" = _fzf_* ]] && continue printf -v "_fzf_orig_completion_${cmd//[^A-Za-z0-9_]/_}" "%s" "${comp} %s ${cmd} #${f}" - if [[ "$l" = *" -o nospace "* ]] && [[ ! "$__fzf_nospace_commands" = *" $cmd "* ]]; then - __fzf_nospace_commands="$__fzf_nospace_commands $cmd " + if [[ "$l" = *" -o nospace "* ]] && [[ ! "${__fzf_nospace_commands-}" = *" $cmd "* ]]; then + __fzf_nospace_commands="${__fzf_nospace_commands-} $cmd " fi fi done @@ -139,17 +139,18 @@ _fzf_handle_dynamic_completion() { shift orig_cmd="$1" orig_var="_fzf_orig_completion_$cmd" - orig="${!orig_var##*#}" + orig="${!orig_var-}" + orig="${orig##*#}" if [[ -n "$orig" ]] && type "$orig" > /dev/null 2>&1; then $orig "$@" - elif [[ -n "$_fzf_completion_loader" ]]; then + elif [[ -n "${_fzf_completion_loader-}" ]]; then orig_complete=$(complete -p "$orig_cmd" 2> /dev/null) _completion_loader "$@" ret=$? # _completion_loader may not have updated completion for the command if [[ "$(complete -p "$orig_cmd" 2> /dev/null)" != "$orig_complete" ]]; then __fzf_orig_completion < <(complete -p "$orig_cmd" 2> /dev/null) - if [[ "$__fzf_nospace_commands" = *" $orig_cmd "* ]]; then + if [[ "${__fzf_nospace_commands-}" = *" $orig_cmd "* ]]; then eval "${orig_complete/ -F / -o nospace -F }" else eval "$orig_complete" @@ -173,6 +174,7 @@ __fzf_generic_path_completion() { base=${cur:0:${#cur}-${#trigger}} eval "base=$base" + dir= [[ $base = *"/"* ]] && dir="$base" while true; do if [[ -z "$dir" ]] || [[ -d "$dir" ]]; then @@ -180,11 +182,11 @@ __fzf_generic_path_completion() { leftover=${leftover/#\/} [[ -z "$dir" ]] && dir='.' [[ "$dir" != "/" ]] && dir="${dir/%\//}" - matches=$(eval "$1 $(printf %q "$dir")" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS $2" __fzf_comprun "$4" -q "$leftover" | while read -r item; do + matches=$(eval "$1 $(printf %q "$dir")" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore ${FZF_DEFAULT_OPTS-} ${FZF_COMPLETION_OPTS-} $2" __fzf_comprun "$4" -q "$leftover" | while read -r item; do printf "%q " "${item%$3}$3" done) matches=${matches% } - [[ -z "$3" ]] && [[ "$__fzf_nospace_commands" = *" ${COMP_WORDS[0]} "* ]] && matches="$matches " + [[ -z "$3" ]] && [[ "${__fzf_nospace_commands-}" = *" ${COMP_WORDS[0]} "* ]] && matches="$matches " if [[ -n "$matches" ]]; then COMPREPLY=( "$matches" ) else @@ -236,7 +238,7 @@ _fzf_complete() { if [[ "$cur" == *"$trigger" ]]; then cur=${cur:0:${#cur}-${#trigger}} - selected=$(FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS $str_arg" __fzf_comprun "${rest[0]}" "${args[@]}" -q "$cur" | $post | tr '\n' ' ') + selected=$(FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore ${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") @@ -329,7 +331,7 @@ __fzf_defc() { func="$2" opts="$3" orig_var="_fzf_orig_completion_${cmd//[^A-Za-z0-9_]/_}" - orig="${!orig_var}" + orig="${!orig_var-}" if [[ -n "$orig" ]]; then printf -v def "$orig" "$func" eval "$def" diff --git a/shell/completion.zsh b/shell/completion.zsh index 417d03c0..807d7b3a 100644 --- a/shell/completion.zsh +++ b/shell/completion.zsh @@ -99,9 +99,9 @@ fi __fzf_comprun() { if [[ "$(type _fzf_comprun 2>&1)" =~ function ]]; then _fzf_comprun "$@" - elif [ -n "$TMUX_PANE" ] && { [ "${FZF_TMUX:-0}" != 0 ] || [ -n "$FZF_TMUX_OPTS" ]; }; then + elif [ -n "${TMUX_PANE-}" ] && { [ "${FZF_TMUX:-0}" != 0 ] || [ -n "${FZF_TMUX_OPTS-}" ]; }; then shift - if [ -n "$FZF_TMUX_OPTS" ]; then + if [ -n "${FZF_TMUX_OPTS-}" ]; then fzf-tmux ${(Q)${(Z+n+)FZF_TMUX_OPTS}} -- "$@" else fzf-tmux -d ${FZF_TMUX_HEIGHT:-40%} -- "$@" @@ -145,7 +145,7 @@ __fzf_generic_path_completion() { leftover=${leftover/#\/} [ -z "$dir" ] && dir='.' [ "$dir" != "/" ] && dir="${dir/%\//}" - matches=$(eval "$compgen $(printf %q "$dir")" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS" __fzf_comprun "$cmd" ${(Q)${(Z+n+)fzf_opts}} -q "$leftover" | while read item; do + matches=$(eval "$compgen $(printf %q "$dir")" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore ${FZF_DEFAULT_OPTS-} ${FZF_COMPLETION_OPTS-}" __fzf_comprun "$cmd" ${(Q)${(Z+n+)fzf_opts}} -q "$leftover" | while read item; do item="${item%$suffix}$suffix" echo -n "${(q)item} " done) @@ -184,7 +184,7 @@ _fzf_complete() { args=("$@") sep= for i in {0..${#args[@]}}; do - if [[ "${args[$i]}" = -- ]]; then + if [[ "${args[$i]-}" = -- ]]; then sep=$i break fi @@ -208,7 +208,7 @@ _fzf_complete() { type $post > /dev/null 2>&1 || post=cat _fzf_feed_fifo "$fifo" - matches=$(FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS $str_arg" __fzf_comprun "$cmd" "${args[@]}" -q "${(Q)prefix}" < "$fifo" | $post | tr '\n' ' ') + matches=$(FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore ${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 @@ -279,8 +279,8 @@ fzf-completion() { [ -z "$trigger" -a ${LBUFFER[-1]} = ' ' ] && tokens+=("") # When the trigger starts with ';', it becomes a separate token - if [[ ${LBUFFER} = *"${tokens[-2]}${tokens[-1]}" ]]; then - tokens[-2]="${tokens[-2]}${tokens[-1]}" + if [[ ${LBUFFER} = *"${tokens[-2]-}${tokens[-1]}" ]]; then + tokens[-2]="${tokens[-2]-}${tokens[-1]}" tokens=(${tokens[0,-2]}) fi diff --git a/shell/key-bindings.bash b/shell/key-bindings.bash index f6797d49..d83f9d3e 100644 --- a/shell/key-bindings.bash +++ b/shell/key-bindings.bash @@ -19,7 +19,7 @@ __fzf_select__() { -o -type f -print \ -o -type d -print \ -o -type l -print 2> /dev/null | cut -b3-"}" - opts="--height ${FZF_TMUX_HEIGHT:-40%} --bind=ctrl-z:ignore --reverse $FZF_DEFAULT_OPTS $FZF_CTRL_T_OPTS -m" + opts="--height ${FZF_TMUX_HEIGHT:-40%} --bind=ctrl-z:ignore --reverse ${FZF_DEFAULT_OPTS-} ${FZF_CTRL_T_OPTS-} -m" eval "$cmd" | FZF_DEFAULT_OPTS="$opts" $(__fzfcmd) "$@" | while read -r item; do @@ -30,7 +30,7 @@ __fzf_select__() { if [[ $- =~ i ]]; then __fzfcmd() { - [[ -n "$TMUX_PANE" ]] && { [[ "${FZF_TMUX:-0}" != 0 ]] || [[ -n "$FZF_TMUX_OPTS" ]]; } && + [[ -n "${TMUX_PANE-}" ]] && { [[ "${FZF_TMUX:-0}" != 0 ]] || [[ -n "${FZF_TMUX_OPTS-}" ]]; } && echo "fzf-tmux ${FZF_TMUX_OPTS:--d${FZF_TMUX_HEIGHT:-40%}} -- " || echo "fzf" } @@ -44,13 +44,13 @@ __fzf_cd__() { local cmd opts dir cmd="${FZF_ALT_C_COMMAND:-"command find -L . -mindepth 1 \\( -path '*/\\.*' -o -fstype 'sysfs' -o -fstype 'devfs' -o -fstype 'devtmpfs' -o -fstype 'proc' \\) -prune \ -o -type d -print 2> /dev/null | cut -b3-"}" - opts="--height ${FZF_TMUX_HEIGHT:-40%} --bind=ctrl-z:ignore --reverse $FZF_DEFAULT_OPTS $FZF_ALT_C_OPTS +m" + opts="--height ${FZF_TMUX_HEIGHT:-40%} --bind=ctrl-z:ignore --reverse ${FZF_DEFAULT_OPTS-} ${FZF_ALT_C_OPTS-} +m" dir=$(eval "$cmd" | FZF_DEFAULT_OPTS="$opts" $(__fzfcmd)) && printf 'builtin cd -- %q' "$dir" } __fzf_history__() { local output opts script - opts="--height ${FZF_TMUX_HEIGHT:-40%} --bind=ctrl-z:ignore $FZF_DEFAULT_OPTS -n2..,.. --scheme=history --bind=ctrl-r:toggle-sort $FZF_CTRL_R_OPTS +m --read0" + opts="--height ${FZF_TMUX_HEIGHT:-40%} --bind=ctrl-z:ignore ${FZF_DEFAULT_OPTS-} -n2..,.. --scheme=history --bind=ctrl-r:toggle-sort ${FZF_CTRL_R_OPTS-} +m --read0" script='BEGIN { getc; $/ = "\n\t"; $HISTCOUNT = $ENV{last_hist} + 1 } s/^[ *]//; print $HISTCOUNT - $. . "\t$_" if !$seen{$_}++' output=$( builtin fc -lnr -2147483648 | diff --git a/shell/key-bindings.zsh b/shell/key-bindings.zsh index 47ef17a7..dfb473cc 100644 --- a/shell/key-bindings.zsh +++ b/shell/key-bindings.zsh @@ -46,7 +46,7 @@ __fsel() { -o -type l -print 2> /dev/null | cut -b3-"}" setopt localoptions pipefail no_aliases 2> /dev/null local item - eval "$cmd" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore $FZF_DEFAULT_OPTS $FZF_CTRL_T_OPTS" $(__fzfcmd) -m "$@" | while read item; do + eval "$cmd" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore ${FZF_DEFAULT_OPTS-} ${FZF_CTRL_T_OPTS-}" $(__fzfcmd) -m "$@" | while read item; do echo -n "${(q)item} " done local ret=$? @@ -55,7 +55,7 @@ __fsel() { } __fzfcmd() { - [ -n "$TMUX_PANE" ] && { [ "${FZF_TMUX:-0}" != 0 ] || [ -n "$FZF_TMUX_OPTS" ]; } && + [ -n "${TMUX_PANE-}" ] && { [ "${FZF_TMUX:-0}" != 0 ] || [ -n "${FZF_TMUX_OPTS-}" ]; } && echo "fzf-tmux ${FZF_TMUX_OPTS:--d${FZF_TMUX_HEIGHT:-40%}} -- " || echo "fzf" } @@ -75,7 +75,7 @@ fzf-cd-widget() { local cmd="${FZF_ALT_C_COMMAND:-"command find -L . -mindepth 1 \\( -path '*/\\.*' -o -fstype 'sysfs' -o -fstype 'devfs' -o -fstype 'devtmpfs' -o -fstype 'proc' \\) -prune \ -o -type d -print 2> /dev/null | cut -b3-"}" setopt localoptions pipefail no_aliases 2> /dev/null - local dir="$(eval "$cmd" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore $FZF_DEFAULT_OPTS $FZF_ALT_C_OPTS" $(__fzfcmd) +m)" + local dir="$(eval "$cmd" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore ${FZF_DEFAULT_OPTS-} ${FZF_ALT_C_OPTS-}" $(__fzfcmd) +m)" if [[ -z "$dir" ]]; then zle redisplay return 0 @@ -98,7 +98,7 @@ fzf-history-widget() { local selected num setopt localoptions noglobsubst noposixbuiltins pipefail no_aliases 2> /dev/null selected=( $(fc -rl 1 | awk '{ cmd=$0; sub(/^[ \t]*[0-9]+\**[ \t]+/, "", cmd); if (!seen[cmd]++) print $0 }' | - FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} $FZF_DEFAULT_OPTS -n2..,.. --scheme=history --bind=ctrl-r:toggle-sort,ctrl-z:ignore $FZF_CTRL_R_OPTS --query=${(qqq)LBUFFER} +m" $(__fzfcmd)) ) + FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} ${FZF_DEFAULT_OPTS-} -n2..,.. --scheme=history --bind=ctrl-r:toggle-sort,ctrl-z:ignore ${FZF_CTRL_R_OPTS-} --query=${(qqq)LBUFFER} +m" $(__fzfcmd)) ) local ret=$? if [ -n "$selected" ]; then num=$selected[1] diff --git a/test/test_go.rb b/test/test_go.rb index bb6a4c8d..ab5a4ae6 100755 --- a/test/test_go.rb +++ b/test/test_go.rb @@ -2758,6 +2758,7 @@ class TestFish < TestBase end __END__ +set -u PS1= PROMPT_COMMAND= HISTFILE= HISTSIZE=100 unset <%= UNSETS.join(' ') %> unset $(env | sed -n /^_fzf_orig/s/=.*//p) @@ -2801,8 +2802,8 @@ _fzf_complete_g_post() { awk '{print "g" $0 $0}' } -[ -n "$BASH" ] && complete -F _fzf_complete_f -o default -o bashdefault f -[ -n "$BASH" ] && complete -F _fzf_complete_g -o default -o bashdefault g +[ -n "${BASH-}" ] && complete -F _fzf_complete_f -o default -o bashdefault f +[ -n "${BASH-}" ] && complete -F _fzf_complete_g -o default -o bashdefault g _comprun() { local command=$1