From cc2881a5729b5da8d0f79b260d92a08fb3e86028 Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Mon, 1 Feb 2021 22:24:54 +0800 Subject: [PATCH] complete: support "bleopt complete_timeout_compvar" --- blerc | 12 ++++++++++- lib/core-complete-def.sh | 3 ++- lib/core-complete.sh | 34 ++++++++++++++++++++----------- lib/core-syntax.sh | 16 ++++++++++++--- memo/ChangeLog.md | 3 ++- note.txt | 43 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 93 insertions(+), 18 deletions(-) diff --git a/blerc b/blerc index c682dd07..d68087ff 100644 --- a/blerc +++ b/blerc @@ -417,7 +417,17 @@ ## the timeout duration in milliseconds. When the value is empty, the ## timeout is disabled. -# bleopt complete_auto_timeout=5000 +# bleopt complete_timeout_auto=5000 + + +## The following setting controls the timeout for the pathname expansions to +## prepare COMP_WORDS and COMP_LINE for progcomp. When the word contains a +## glob pattern that takes a long time to evaluate, the pathname expansion is +## canceled, and a noglob expansion is used to construct COMP_WORDS and +## COMP_LINE. The value specifies ## the timeout duration in milliseconds. +## When the value is empty, the timeout is disabled. + +# bleopt complete_timeout_compvar=200 ## The following setting specifies the style of the menu to show completion diff --git a/lib/core-complete-def.sh b/lib/core-complete-def.sh index d3d23aa3..0c62f00f 100644 --- a/lib/core-complete-def.sh +++ b/lib/core-complete-def.sh @@ -34,7 +34,8 @@ bleopt/declare -o complete_stdin_frequency complete_polling_cycle bleopt/declare -v complete_limit 500 bleopt/declare -v complete_limit_auto 200 -bleopt/declare -v complete_auto_timeout 5000 +bleopt/declare -v complete_timeout_auto 5000 +bleopt/declare -v complete_timeout_compvar 200 bleopt/declare -v complete_ambiguous 1 bleopt/declare -v complete_contract_function_names 1 diff --git a/lib/core-complete.sh b/lib/core-complete.sh index b8661524..51010b1d 100644 --- a/lib/core-complete.sh +++ b/lib/core-complete.sh @@ -1333,8 +1333,8 @@ function ble/complete/source/eval-simple-word { local word=$1 opts=$2 if [[ :$comp_type: != *:sync:* && :$opts: != *:noglob:* ]]; then opts=$opts:stopcheck:cached - [[ :$comp_type: == *:auto:* && $bleopt_complete_auto_timeout ]] && - opts=$opts:timeout=$((bleopt_complete_auto_timeout)) + [[ :$comp_type: == *:auto:* && $bleopt_complete_timeout_auto ]] && + opts=$opts:timeout=$((bleopt_complete_timeout_auto)) fi ble/syntax:bash/simple-word/eval "$word" "$opts"; local ext=$? ((ext==142)) && return 148 @@ -1344,8 +1344,8 @@ function ble/complete/source/evaluate-path-spec { local word=$1 sep=$2 opts=$3 if [[ :$comp_type: != *:sync:* && :$opts: != *:noglob:* ]]; then opts=$opts:stopcheck:cached - [[ :$comp_type: == *:auto:* && $bleopt_complete_auto_timeout ]] && - opts=$opts:timeout=$((bleopt_complete_auto_timeout)) + [[ :$comp_type: == *:auto:* && $bleopt_complete_timeout_auto ]] && + opts=$opts:timeout=$((bleopt_complete_timeout_auto)) fi ble/syntax:bash/simple-word/evaluate-path-spec "$word" "$sep" "$opts"; local ext=$? ((ext==142)) && return 148 @@ -1751,8 +1751,8 @@ function ble/complete/util/eval-pathname-expansion { else local sync_command='ble/complete/util/eval-pathname-expansion/.print-def "$pattern"' local sync_opts=progressive-weight - [[ :$comp_type: == *:auto:* && $bleopt_complete_auto_timeout ]] && - sync_opts=$sync_opts:timeout=$((bleopt_complete_auto_timeout)) + [[ :$comp_type: == *:auto:* && $bleopt_complete_timeout_auto ]] && + sync_opts=$sync_opts:timeout=$((bleopt_complete_timeout_auto)) local def ble/util/assign def 'ble/util/conditional-sync "$sync_command" "" "" "$sync_opts"' &>/dev/null; local ext=$? ((ext==148)) && return 148 @@ -1975,6 +1975,16 @@ function ble/complete/progcomp/.compvar-perform-wordbreaks { # その場合には wordbreaks の次に新しい単語を開始していると考える。 ble/array#push ret "$word" } +function ble/complete/progcomp/.compvar-eval-word { + local opts=$2 + if [[ :$opts: == *:noglob:* ]]; then + ble/syntax:bash/simple-word/eval "$1" "$opts" + else + [[ $bleopt_complete_timeout_compvar ]] && + opts=timeout=$((bleopt_complete_timeout_compvar)):retry-noglob-on-timeout:$opts + ble/complete/source/eval-simple-word "$1" "$opts" + fi +} ## @fn ble/complete/progcomp/.compvar-generate-subwords/impl1 word ## $wordbreaks で分割してから評価する戦略。 @@ -2018,7 +2028,7 @@ function ble/complete/progcomp/.compvar-generate-subwords/impl1 { ble/syntax:bash/simple-word#break-word "$left" local subword for subword in "${ret[@]}"; do - ble/syntax:bash/simple-word/eval "$subword" "$eval_opts" + ble/complete/progcomp/.compvar-eval-word "$subword" "$eval_opts" ble/array#push words "$ret" ((point+=${#ret})) done @@ -2028,7 +2038,7 @@ function ble/complete/progcomp/.compvar-generate-subwords/impl1 { ble/syntax:bash/simple-word#break-word "$right" local subword isfirst=1 for subword in "${ret[@]}"; do - ble/syntax:bash/simple-word/eval "$subword" noglob + ble/complete/progcomp/.compvar-eval-word "$subword" noglob if [[ $isfirst ]]; then isfirst= local iword=${#words[@]}; ((iword&&iword--)) @@ -2054,12 +2064,12 @@ function ble/complete/progcomp/.compvar-generate-subwords/impl2 { local word=$1 ble/syntax:bash/simple-word/reconstruct-incomplete-word "$word" || return 1 - ble/complete/source/eval-simple-word "$ret"; (($?==148)) && return 148; local value1=$ret + ble/complete/progcomp/.compvar-eval-word "$ret"; (($?==148)) && return 148; local value1=$ret if [[ $point ]]; then if ((point==${#word})); then point=${#value1} elif ble/syntax:bash/simple-word/reconstruct-incomplete-word "${word::point}"; then - ble/complete/source/eval-simple-word "$ret"; (($?==148)) && return 148 + ble/complete/progcomp/.compvar-eval-word "$ret"; (($?==148)) && return 148 point=${#ret} fi fi @@ -2120,7 +2130,7 @@ function ble/complete/progcomp/.compvar-quote-subword { [[ $subword_flags == *E* ]] && to_quote=1 elif ble/syntax:bash/simple-word/reconstruct-incomplete-word "$word"; then is_evaluated=1 - ble/complete/source/eval-simple-word "$ret"; (($?==148)) && return 148; word=$ret + ble/complete/progcomp/.compvar-eval-word "$ret"; (($?==148)) && return 148; word=$ret to_quote=1 fi @@ -2141,7 +2151,7 @@ function ble/complete/progcomp/.compvar-quote-subword { local left=${word::p} if [[ $is_evaluated ]]; then if ble/syntax:bash/simple-word/reconstruct-incomplete-word "$left"; then - ble/complete/source/eval-simple-word "$ret"; (($?==148)) && return 148; left=$ret + ble/complete/progcomp/.compvar-eval-word "$ret"; (($?==148)) && return 148; left=$ret fi fi if [[ $is_quoted ]]; then diff --git a/lib/core-syntax.sh b/lib/core-syntax.sh index 3a1e5945..f796aa35 100644 --- a/lib/core-syntax.sh +++ b/lib/core-syntax.sh @@ -1425,6 +1425,7 @@ function ble/syntax:bash/simple-word/eval/.cache-update { fi } ## @fn ble/syntax:bash/simple-word/eval/.save word ext ret... +## @var[in] ext ## @var[in,out] _ble_syntax_bash_simple_eval function ble/syntax:bash/simple-word/eval/.cache-save { ((ext==148||ext==142)) && return 0 @@ -1441,12 +1442,17 @@ function ble/syntax:bash/simple-word/eval/.cache-load { ## @fn ble/syntax:bash/simple-word/eval word opts ## @param[in] word ## @param[in,opt] opts +## noglob +## +## cached ## stopcheck -## timeout-highlight +## ## timeout=NUM ## stopcheck を指定している時に有効です。timeout を指定します。 -## cached -## noglob +## timeout-highlight +## bleopt highlight_timeout_{sync,async} を参照して timeout します。 +## retry-noglob-on-timeout +## timeout した時に noglob で改めて展開を試行します。 ## ## @var[out] ret ## @exit @@ -1466,6 +1472,10 @@ function ble/syntax:bash/simple-word/eval { if [[ :$2: == *:cached:* && :$2: != *:noglob:* ]]; then ble/syntax:bash/simple-word/eval/.cache-save "$1" "$ext" "${ret[@]}" fi + if ((ext==142)) && [[ :$2: == *:retry-noglob-on-timeout:* ]]; then + ble/syntax:bash/simple-word/eval "$1" "$2:noglob" + return "$?" + fi return "$ext" } diff --git a/memo/ChangeLog.md b/memo/ChangeLog.md index ea7baca7..c4fbe6d0 100644 --- a/memo/ChangeLog.md +++ b/memo/ChangeLog.md @@ -21,6 +21,7 @@ - edit: change default behavior of C-w and M-w to operate on backward words `#D1448` 47a3301 - syntax (`layer:syntax/word`): perform pathname expansions in background subshells (motivated by 3ximus) `#D1449` 13e7bdd - complete: perform pathname expansions in subshells (motivated by 3ximus) `#D1450` d511896 +- complete: support `bleopt complete_timeout_compvar` to time out pathname expansions for `COMP_WORDS` / `COMP_LINE` `#D1457` 0000000 ## Fixes @@ -44,7 +45,7 @@ - global: update the style of document comments ff4c4e7 - util: add function `ble/string#quote-words` `#D1451` f03b87b - syntax (`ble/syntax:bash/simple-word/eval`): cache `#D1453` 6d8311e -- global: refactor `setup => set up / set-up` `#D1456` 0000000 +- global: refactor `setup => set up / set-up` `#D1456` c37a9dd # ble-0.4.0-devel2 diff --git a/note.txt b/note.txt index 800be053..417bdeea 100644 --- a/note.txt +++ b/note.txt @@ -3813,6 +3813,49 @@ bash_tips 2021-02-01 + * complete: support "bleopt complete_timeout_compvar" (motivated by 3ximus) [#D1457] + https://github.com/akinomyoga/ble.sh/issues/82#issuecomment-770390986 + + これは progcomp の関数を呼び出す時にパス名展開を実行しているからである。 + 一応、応答がなくなるという事はないが補完に不自然に時間がかかるのは避けたい。 + progcomp の為に展開する時は noglob で展開する事も考えたが、 + 展開した文字列を quote しているので、noglob で呼び出すと例えば *.txt + が '*.txt' 等になってしまって意図しない結果になってしまう。 + + どの様にするのが良いのかは不明である。或いは timeout したら '*.txt' にして + しまうというのでも良いのかもしれない。 + + bleopt complete_timeout_progcomp_glob=200 等の設定にして、timeout したら + noglob で呼び出すというので良い気がする。 + + retry-noglob-on-timeout という opts を追加する事にする。 + + 新しい bleopt の変数名は何が良いだろうか。 + + complete_timeout_progcomp_glob だと長い。 + それに似たような変数が沢山あって気になる。 + そもそも単に timeout としていると何の timeout か分からない。 + + ちゃんとした名前にするなら glob_timeout が良いが長い。 + 一単語でこれを表現できないか。fsys_timeout, path_timeout, ... + やはり専用の単語は存在しない以上は一単語にするのは難しい。 + また、似たような設定をまとめるという立場からすると以下の様な + 変数名で良いのではないかという気もしないでもないが、微妙。 + + glob_timeout_progcomp + glob_timeout_sync_highilght + glob_timeout_async_highilght + glob_timeout_auto_complete + + やはり highlight_*, complete_* という名前にしたい。 + + highlight_timeout_sync + highlight_timeout_async + complete_timeout_auto + complete_timeout_compvar + + →これは実際に試してみたが改善していない。 + * setup を動詞の様に使っている箇所が多くて気になるので修正する [#D1456] set up に代わる動詞を探しても余り良いのが見つからない。文脈に応じて全く違う