summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomas Janousek <tomi@nomi.cz>2020-11-11 14:44:47 +0000
committerJunegunn Choi <junegunn.c@gmail.com>2020-11-13 02:16:54 +0900
commitef2c29d5d4974cc773149d368488a6d8a0fcc1fc (patch)
treebb91ec675491d30e02823277ac53c3dc3f2d5bde
parent218b3c8274193c7ea128d164c7924fcb46c2db65 (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.bash24
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" ;;