Skip to content

Commit

Permalink
[bash-completion] Optimize __fzf_orig_completion_filter
Browse files Browse the repository at this point in the history
Commit d4ad4a2 slowed loading of completion.bash significantly (on my
laptop from 10 ms to 30 ms), then 54891d1 improved that (to 20 ms) but
it still stands out as the heavy part of my .bashrc.

Rewriting __fzf_orig_completion_filter to pure bash without forking to
sed/awk brings this back under 10 ms.

before:

    $ HISTFILE=/tmp/bashhist hyperfine 'bash --rcfile shell/completion.bash -i'
    Benchmark #1: bash --rcfile shell/completion.bash -i
      Time (mean ± σ):      21.2 ms ±   0.3 ms    [User: 24.9 ms, System: 6.4 ms]
      Range (min … max):    20.7 ms …  23.3 ms    132 runs

after:

    $ HISTFILE=/tmp/bashhist hyperfine 'bash --rcfile shell/completion.bash -i'
    Benchmark #1: bash --rcfile shell/completion.bash -i
      Time (mean ± σ):       9.6 ms ±   0.3 ms    [User: 8.0 ms, System: 2.2 ms]
      Range (min … max):     9.3 ms …  11.4 ms    298 runs

Fixes: d4ad4a2 ("[bash-completion] Fix default alias/variable completion")
Fixes: 54891d1 ("[bash-completion] Minor optimization")
  • Loading branch information
liskin authored and junegunn committed Nov 12, 2020
1 parent 218b3c8 commit ef2c29d
Showing 1 changed file with 16 additions and 8 deletions.
24 changes: 16 additions & 8 deletions shell/completion.bash
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,19 @@ __fzf_comprun() {
fi
}

__fzf_orig_completion_filter() {
sed '/ -F/!d; / _fzf/d; s/^\(.*-F\) *\([^ ]*\).* \([^ ]*\)$/export _fzf_orig_completion_\3="\1 %s \3 #\2"; [[ "\1" = *" -o nospace "* ]] \&\& [[ ! "$__fzf_nospace_commands" = *" \3 "* ]] \&\& __fzf_nospace_commands="$__fzf_nospace_commands \3 ";/' |
awk -F= '{OFS = FS} {gsub(/[^A-Za-z0-9_= ;]/, "_", $1);}1'
__fzf_orig_completion() {
local l comp f cmd
while read -r l; do
if [[ "$l" =~ ^(.*\ -F)\ *([^ ]*).*\ ([^ ]*)$ ]]; then
comp="${BASH_REMATCH[1]}"
f="${BASH_REMATCH[2]}"
cmd="${BASH_REMATCH[3]}"
export "_fzf_orig_completion_${cmd//[^A-Za-z0-9_]/_}=${comp} %s ${cmd} #${f}"
if [[ "$l" = *" -o nospace "* ]] && [[ ! "$__fzf_nospace_commands" = *" $cmd "* ]]; then
__fzf_nospace_commands="$__fzf_nospace_commands $cmd "
fi
fi
done
}

_fzf_opts_completion() {
Expand Down Expand Up @@ -137,7 +147,7 @@ _fzf_handle_dynamic_completion() {
ret=$?
# _completion_loader may not have updated completion for the command
if [ "$(complete -p "$orig_cmd" 2> /dev/null)" != "$orig_complete" ]; then
eval "$(complete | command grep " -F.* $orig_cmd$" | __fzf_orig_completion_filter)"
__fzf_orig_completion < <(complete -p "$orig_cmd" 2> /dev/null)
if [[ "$__fzf_nospace_commands" = *" $orig_cmd "* ]]; then
eval "${orig_complete/ -F / -o nospace -F }"
else
Expand Down Expand Up @@ -306,9 +316,7 @@ a_cmds="
svn tar unzip zip"
# Preserve existing completion
eval "$(complete |
sed -E "/ ($(echo $d_cmds $a_cmds | sed 's/ /|/g; s/+/\\+/g'))$/"'!d' |
__fzf_orig_completion_filter)"
__fzf_orig_completion < <(complete -p $d_cmds $a_cmds 2> /dev/null)
if type _completion_loader > /dev/null 2>&1; then
_fzf_completion_loader=1
Expand Down Expand Up @@ -353,7 +361,7 @@ _fzf_setup_completion() {
return 1
fi
shift
eval "$(complete -p "$@" 2> /dev/null | __fzf_orig_completion_filter)"
__fzf_orig_completion < <(complete -p "$@" 2> /dev/null)
for cmd in "$@"; do
case "$kind" in
dir) __fzf_defc "$cmd" "$fn" "-o nospace -o dirnames" ;;
Expand Down

0 comments on commit ef2c29d

Please sign in to comment.