From ef2c29d5d4974cc773149d368488a6d8a0fcc1fc Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Wed, 11 Nov 2020 14:44:47 +0000 Subject: [PATCH] [bash-completion] Optimize __fzf_orig_completion_filter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit d4ad4a25 slowed loading of completion.bash significantly (on my laptop from 10 ms to 30 ms), then 54891d11 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: d4ad4a25db5f ("[bash-completion] Fix default alias/variable completion") Fixes: 54891d11e09d ("[bash-completion] Minor optimization") --- shell/completion.bash | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/shell/completion.bash b/shell/completion.bash index 1af17698..b8c32abe 100644 --- a/shell/completion.bash +++ b/shell/completion.bash @@ -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() { @@ -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 @@ -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 @@ -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" ;;