diff options
author | Tomas Janousek <tomi@nomi.cz> | 2020-11-11 14:44:47 +0000 |
---|---|---|
committer | Junegunn Choi <junegunn.c@gmail.com> | 2020-11-13 02:16:54 +0900 |
commit | ef2c29d5d4974cc773149d368488a6d8a0fcc1fc (patch) | |
tree | bb91ec675491d30e02823277ac53c3dc3f2d5bde | |
parent | 218b3c8274193c7ea128d164c7924fcb46c2db65 (diff) |
[bash-completion] Optimize __fzf_orig_completion_filter
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")
-rw-r--r-- | shell/completion.bash | 24 |
1 files 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" ;; |