Skip to content

Commit

Permalink
highlight: add "bleopt highlight_eval_word_limit"
Browse files Browse the repository at this point in the history
  • Loading branch information
akinomyoga committed Aug 22, 2024
1 parent cbcce62 commit 6833bdf
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 14 deletions.
7 changes: 7 additions & 0 deletions blerc.template
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,13 @@
#bleopt syntax_eval_polling_interval=50


## The following setting limits the number of expanded words to process in
## highlighting a single grammatical word. When this setting is set to an
## empty string, the number of expanded words to process is unlimited.

#bleopt highlight_eval_word_limit=200


## If set to a non-empty value, the setting "color_scheme" specifies a preset
## graphic styles for basic faces. The supported schemes are found in the
## subdirectory "contrib/scheme". The default value is "default".
Expand Down
1 change: 1 addition & 0 deletions docs/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
- util(vbell): support `bleopt vbell_align=panel` (requested by bb010g) `#D2228` fe85e0dd
- highlight: reflect the top-level positional parameters `#D2246` f08e8f08
- color: adjust default fg values in faces and add `bleopt color_scheme` (requested by mattmc3) `#D2248`
- highlight: add `bleopt highlight_eval_word_limit` (motivated by orionalves) `#D2256` xxxxxxxx

## Changes

Expand Down
2 changes: 1 addition & 1 deletion lib/core-complete.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1769,7 +1769,7 @@ function ble/complete/action/requote-final-insert {
if [[ $insert == "$comps_prefix"* && $comps_prefix != *[!':/={,'] ]]; then
local ret ins=${insert:${#comps_prefix}}
if ! ble/syntax:bash/simple-word/is-literal "$ins" &&
ble/syntax:bash/simple-word/safe-eval "$ins" &&
ble/syntax:bash/simple-word/safe-eval "$ins" limit=2 &&
((${#ret[@]}==1))
then
ble/string#quote-word "$ret" quote-empty
Expand Down
11 changes: 10 additions & 1 deletion lib/core-debug.sh
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,16 @@ function ble/debug/profiler/stop {
ble/util/assign-words nline 'ble/bin/wc -l "$f1" 2>/dev/null'
ble/util/print $'\e[A\rble/debug/profiler: counting lines... '"$nline" >&2

ble/bin/awk -v magic="$_ble_debug_profiler_magic" -v nline="$nline" '
# nawk becomes unacceptably slow when there is a long line. It seems to scale
# as O(N^2). If mawk/gawk is available, we prefer mawk/gawk to nawk.
local awk=ble/bin/awk
if ble/is-function ble/bin/mawk; then
awk=ble/bin/mawk
elif ble/is-function ble/bin/gawk; then
awk=ble/bin/gawk
fi

"$awk" -v magic="$_ble_debug_profiler_magic" -v nline="$nline" '
BEGIN {
xtrace_debug_enabled = 1;
print "ble/debug/profiler: collecting information..." >"/dev/stderr";
Expand Down
1 change: 1 addition & 0 deletions lib/core-syntax-def.sh
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ bleopt/declare -v highlight_filename 1
bleopt/declare -v highlight_variable 1
bleopt/declare -v highlight_timeout_sync 50
bleopt/declare -v highlight_timeout_async 5000
bleopt/declare -v highlight_eval_word_limit 200
bleopt/declare -v syntax_eval_polling_interval 50

builtin eval -- "${_ble_util_gdict_declare//NAME/_ble_syntax_highlight_filetype}"
Expand Down
52 changes: 40 additions & 12 deletions lib/core-syntax.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1337,8 +1337,16 @@ function ble/syntax:bash/simple-word/extract-parameter-names/.process-dquot {
done
}

function ble/syntax:bash/simple-word/eval/.set-result { __ble_ret=("$@"); }
function ble/syntax:bash/simple-word/eval/.set-result {
if [[ $__ble_word_limit ]] && (($#>__ble_word_limit)); then
set -- "${@::__ble_word_limit}"
fi
__ble_ret=("$@")
}
function ble/syntax:bash/simple-word/eval/.print-result {
if [[ $__ble_word_limit ]] && (($#>__ble_word_limit)); then
set -- "${@::__ble_word_limit}"
fi
if (($#>=1000)) && [[ $OSTYPE != cygwin ]]; then
# ファイル数が少ない場合は fork コストを避ける為に多少遅くても quote&eval
# でデータを親シェルに転送する。Cygwin では mapfile/read が unbuffered で遅
Expand Down Expand Up @@ -1406,6 +1414,10 @@ function ble/syntax:bash/simple-word/eval/.impl {
builtin eval -- "$__ble_defs" &>/dev/null # 読み取り専用の変数のこともある
fi

local __ble_word_limit=
ble/string#match ":$__ble_opts:" ':limit=([^:]*):' &&
((__ble_word_limit=BASH_REMATCH[1]))

# glob パターンを含む可能性がある時の処理 (Note: is-simple-noglob の
# 判定で変数を参照するので、グローバル変数の復元よりも後で処理する必
# 要がある)
Expand Down Expand Up @@ -1523,6 +1535,9 @@ function ble/syntax:bash/simple-word/eval/.cache-load {
##
## single
## 最初の展開結果のみを ret に設定します。
## limit=COUNT
## 評価後の単語数を COUNT 以下に制限します。これは count によって設定さ
## れる展開結果の単語数にも影響を与えます。
## count
## 変数 count に展開結果の単語数を返します。
## cached
Expand All @@ -1543,8 +1558,8 @@ function ble/syntax:bash/simple-word/eval/.cache-load {
## パス名展開のタイムアウトの既定値を指定します。空文字列が指定さ
## れている時、既定でタイムアウトは起こりません。
## @var[in,out] _ble_syntax_bash_simple_eval_timeout_carry
## この値が設定されている時、パス名展開に対して強制的にタイムアウ
## トが起こります。opts に timeout-carry が指定されている時に値が設定されます。
## この値が設定されている時、パス名展開に対して強制的にタイムアウトが起こり
## ます。opts に timeout-carry が指定されている時に値が設定されます。
##
## @arr[out] ret
## 展開結果を返します。複数の単語に評価される場合にはそれを全て返します。
Expand Down Expand Up @@ -1586,9 +1601,12 @@ function ble/syntax:bash/simple-word/eval {
}

## @fn ble/syntax:bash/simple-word/eval word [opts]
## Evaluate the specified word only when the word is safe and take the first
## word when the word is expanded to multiple words.
##
## @param[in,opt] opts
## A colon-separated list of options. In addition to the values supported
## by ble/syntax:bash/simple-word/eval, the following value is available:
## by ble/syntax:bash/simple-word/eval, the following values are available:
##
## @opt reconstruct
## Try to reconstruct the full word using
Expand All @@ -1600,18 +1618,26 @@ function ble/syntax:bash/simple-word/eval {
## expansion an empty array "${arr[@]}" or unmatching glob pattern with
## nullglob.
##
## The other options are processed by "ble/syntax:bash/simple-word/eval",
## but if "limit=COUNT" is not specified, the option "limit=1" is added to
## suppress the number of generated words.
##
## @arr[out] ret
##
function ble/syntax:bash/simple-word/safe-eval {
if [[ :$2: == *:reconstruct:* ]]; then
local __ble_opts=$2
if [[ :$__ble_opts: == *:reconstruct:* ]]; then
local simple_flags simple_ibrace
ble/syntax:bash/simple-word/reconstruct-incomplete-word "$1" || return 1
ble/util/unlocal simple_flags simple_ibrace
else
ble/syntax:bash/simple-word/is-simple "$1" || return 1
fi
ble/syntax:bash/simple-word/eval "$1" &&
{ [[ :$2: != *:nonull:* ]] || ((${#ret[@]})); }
[[ :$__ble_opts: == *:limit=*:* ]] ||
__ble_opts=$__ble_opts:limit=1

ble/syntax:bash/simple-word/eval "$1" "$__ble_opts" &&
{ [[ :$__ble_opts: != *:nonull:* ]] || ((${#ret[@]})); }
}

## @fn ble/syntax:bash/simple-word/get-rex_element sep
Expand Down Expand Up @@ -7558,14 +7584,16 @@ function ble/highlight/layer:syntax/word/.update-attributes/.proc {
function ble/highlight/layer:syntax/word/.update-attributes {
((_ble_syntax_word_umin>=0)) || return 1

local _ble_syntax_bash_simple_eval_timeout=$bleopt_highlight_timeout_sync
local highlight_eval_opts=cached:single:stopcheck

[[ $bleopt_highlight_eval_word_limit ]] &&
highlight_eval_opts=$highlight_eval_opts:limit=$((bleopt_highlight_eval_word_limit))

# Timeout setting for simple-word/eval
if [[ ! $ble_textarea_render_defer_running ]]; then
local _ble_syntax_bash_simple_eval_timeout=$bleopt_highlight_timeout_sync
local _ble_syntax_bash_simple_eval_timeout_carry=
local highlight_eval_opts=cached:single:stopcheck:timeout-carry
else
local _ble_syntax_bash_simple_eval_timeout=$bleopt_highlight_timeout_async
local highlight_eval_opts=cached:single:stopcheck
highlight_eval_opts=$highlight_eval_opts:timeout-carry
fi

ble/syntax/tree-enumerate-in-range "$_ble_syntax_word_umin" "$_ble_syntax_word_umax" \
Expand Down
23 changes: 23 additions & 0 deletions note.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7394,6 +7394,29 @@ bash_tips

2024-08-22

* simple-word: limit the number of expanded words (motivated by orionalves) [#D2256]
https://github.com/akinomyoga/ble.sh/issues/482

ブレース展開で巨大な数を入力するとシステムがクラッシュするという報告。正直
そんな非現実的な物を入力するのが悪いとしか言いようがない。

ble/syntax:bash/simple-word/eval について limit=COUNT opts を追加して、構文
着色の際に実施される単語の展開および補完の為の展開について上限を設ける事に
した。

但し、単語数の制限は展開の後に行われるので、必ず一回は大量の単語を生成する
ことになる。単にその後の処理をできるだけ軽くするだけの事であるが、単語着色
に関しては response はかなり改善したように思う。取り敢えず単語数の上限は既
定では 200 という事にする。

テストに使ったコード:

| if ((${#__ble_ret[@]}>200)); then
| echo "count=${#__ble_ret[@]} opts=($__ble_opts)" >/dev/tty
| printf -- '- %s\n' "${FUNCNAME[@]}" >/dev/tty
| __ble_ret=("${__ble_ret[@]::200}")
| fi

* mandb: sudo などから呼び出されたコマンドオプションに説明がつかない [#D2255]
https://github.com/akinomyoga/ble.sh/issues/480#issuecomment-2298976015

Expand Down

0 comments on commit 6833bdf

Please sign in to comment.