Skip to content

Commit

Permalink
syntax (ble/syntax:bash/simple-word/eval): cache
Browse files Browse the repository at this point in the history
  • Loading branch information
akinomyoga committed Feb 20, 2021
1 parent d4d718a commit 6d8311e
Show file tree
Hide file tree
Showing 8 changed files with 306 additions and 48 deletions.
4 changes: 2 additions & 2 deletions lib/core-complete.sh
Expand Up @@ -1332,7 +1332,7 @@ function ble/complete/source/test-limit {
function ble/complete/source/eval-simple-word {
local word=$1 opts=$2
if [[ :$comp_type: != *:sync:* && :$opts: != *:noglob:* ]]; then
opts=$opts:stopcheck
opts=$opts:stopcheck:cached
[[ :$comp_type: == *:auto:* && $bleopt_complete_auto_timeout ]] &&
opts=$opts:timeout=$((bleopt_complete_auto_timeout))
fi
Expand All @@ -1343,7 +1343,7 @@ function ble/complete/source/eval-simple-word {
function ble/complete/source/evaluate-path-spec {
local word=$1 sep=$2 opts=$3
if [[ :$comp_type: != *:sync:* && :$opts: != *:noglob:* ]]; then
opts=$opts:stopcheck
opts=$opts:stopcheck:cached
[[ :$comp_type: == *:auto:* && $bleopt_complete_auto_timeout ]] &&
opts=$opts:timeout=$((bleopt_complete_auto_timeout))
fi
Expand Down
2 changes: 2 additions & 0 deletions lib/core-syntax-def.sh
Expand Up @@ -111,3 +111,5 @@ if ((_ble_bash>=40300||_ble_bash>=40000&&!_ble_bash_loaded_in_function)); then
declare -A _ble_syntax_highlight_lscolors_ext=()
fi
fi

builtin eval -- "${_ble_util_gdict_declare//NAME/_ble_syntax_bash_simple_eval}"
83 changes: 59 additions & 24 deletions lib/core-syntax.sh
Expand Up @@ -1406,23 +1406,65 @@ function ble/syntax:bash/simple-word/eval/.impl {
[[ $__ble_flags == *f* ]] && set +f
return "$ext"
}

_ble_syntax_bash_simple_eval_hash=
## @fn ble/syntax:bash/simple-word/eval/.cache-clear
## @var[in,out] _ble_syntax_bash_simple_eval
function ble/syntax:bash/simple-word/eval/.cache-clear {
ble/gdict#clear _ble_syntax_bash_simple_eval
}
## @fn ble/syntax:bash/simple-word/eval/.cache-update
## @var[in,out] _ble_syntax_bash_simple_eval
## @var[in,out] _ble_syntax_bash_simple_eval_hash
function ble/syntax:bash/simple-word/eval/.cache-update {
local hash=$-:$BASHOPTS:$_ble_edit_lineno:$_ble_textarea_version:$PWD
if [[ $hash != "$_ble_syntax_bash_simple_eval_hash" ]]; then
_ble_syntax_bash_simple_eval_hash=$hash
ble/syntax:bash/simple-word/eval/.cache-clear
fi
}
## @fn ble/syntax:bash/simple-word/eval/.save word ext ret...
## @var[in,out] _ble_syntax_bash_simple_eval
function ble/syntax:bash/simple-word/eval/.cache-save {
((ext==148||ext==142)) && return 0
local ret; ble/string#quote-words "${@:3}"
ble/gdict#set _ble_syntax_bash_simple_eval "$1" "ext=$2 ret=($ret)"
}
function ble/syntax:bash/simple-word/eval/.cache-load {
ext= ret=
ble/gdict#get _ble_syntax_bash_simple_eval "$1" || return 1
builtin eval -- "$ret"
return 0
}

## @fn ble/syntax:bash/simple-word/eval word opts
## @param[in] word
## @param[in,opt] opts
## stopcheck
## timeout-highlight
## timeout=NUM
## stopcheck を指定している時に有効です。timeout を指定します。
## cached
## noglob
##
## @var[out] ret
## @exit
## shopt -q failglob の時、パス名展開に失敗すると
## 0 以外の終了ステータスを返します。
##
function ble/syntax:bash/simple-word/eval {
if [[ :$2: == *:cached:* && :$2: != *:noglob:* ]]; then
ble/syntax:bash/simple-word/eval/.cache-update
local ext; ble/syntax:bash/simple-word/eval/.cache-load "$1" && return "$ext"
fi

local __ble_ret
ble/syntax:bash/simple-word/eval/.impl "$1" "$2"; local ext=$?
ret=("${__ble_ret[@]}")

if [[ :$2: == *:cached:* && :$2: != *:noglob:* ]]; then
ble/syntax:bash/simple-word/eval/.cache-save "$1" "$ext" "${ret[@]}"
fi
return "$ext"
}

Expand All @@ -1442,10 +1484,13 @@ function ble/syntax:bash/simple-word/.get-rex_element {
## @param[in] path_spec
## @param[in,opt] sep (default: '/:=')
## @param[in,opt] opts
## noglob notilde after-sep
## noglob
## stopcheck
## timeout-highlight
## timeout=*
## cached
## notilde
## after-sep
## @arr[out] spec
## @arr[out] path
## @arr[out] ret
Expand All @@ -1466,12 +1511,7 @@ function ble/syntax:bash/simple-word/evaluate-path-spec {
[[ $word ]] || return 0

# read options
local eval_opts= rex_timeout=':(timeout=[^:]*):'
[[ :$opts: == *:stopcheck:* ]] && eval_opts=stopcheck
[[ :$opts: == *:timeout-highlight:* ]] && eval_opts=$eval_opts:timeout-highlight
[[ :$opts: =~ $rex_timeout ]] && eval_opts=$eval_opts:${BASH_REMATCH[1]}
[[ :$opts: == *:noglob:* ]] && eval_opts=$eval_opts:noglob
local notilde=
local eval_opts=$opts notilde=
[[ :$opts: == *:notilde:* ]] && notilde=\'\' # チルダ展開の抑制

# compose regular expressions
Expand Down Expand Up @@ -1501,12 +1541,13 @@ function ble/syntax:bash/simple-word/evaluate-path-spec {
## @param[in] word
## @param[in,opt] sep
## @param[in] opts
## url
## noglob
## notilde
## stopcheck
## timeout-highlight
## timeout=*
## cached
## url
## notilde
## @var[out] ret
## 有効な区切り文字の集合を返します。
function ble/syntax:bash/simple-word/detect-separated-path {
Expand All @@ -1517,12 +1558,7 @@ function ble/syntax:bash/simple-word/detect-separated-path {
[[ :$opts: == *:url:* && $word =~ $rex_url ]] && return 1

# read eval options
local eval_opts= rex_timeout=':(timeout=[^:]*):'
[[ :$opts: == *:stopcheck:* ]] && eval_opts=stopcheck
[[ :$opts: == *:timeout-highlight:* ]] && eval_opts=$eval_opts:timeout-highlight
[[ :$opts: =~ $rex_timeout ]] && eval_opts=$eval_opts:${BASH_REMATCH[1]}
[[ :$opts: == *:noglob:* ]] && eval_opts=$eval_opts:noglob
local notilde=
local eval_opts=$opts notilde=
[[ :$opts: == *:notilde:* ]] && notilde=\'\' # チルダ展開の抑制

# compose regular expressions
Expand Down Expand Up @@ -1584,6 +1620,9 @@ function ble/syntax:bash/simple-word/locate-filename/.exists {
## stopcheck に際して timeout として highlight 用の設定を使用します。
## timeout=*
## stopcheck に際して timeout を指定します。
## cached
## 展開内容をキャッシュします。
##
## @arr[out] ret
## 偶数個の要素を含みます。偶数 index (0, 2, 4, ...) が範囲の開始で、
## 奇数 index (1, 3, 5, ...) が範囲の終了です。
Expand All @@ -1594,11 +1633,7 @@ function ble/syntax:bash/simple-word/locate-filename {
[[ $word ]] || return 0

# prepare evaluator
local eval_opts= rex_timeout=':(timeout=[^:]*):'
[[ :$opts: == *:stopcheck:* ]] && eval_opts=stopcheck
[[ :$opts: == *:timeout-highlight:* ]] && eval_opts=$eval_opts:timeout-highlight
[[ :$opts: =~ $rex_timeout ]] && eval_opts=$eval_opts:${BASH_REMATCH[1]}
[[ :$opts: == *:noglob:* ]] && eval_opts=$eval_opts:noglob
local eval_opts=$opts

# compose regular expressions
local rex_element; ble/syntax:bash/simple-word/.get-rex_element "$sep"
Expand Down Expand Up @@ -6406,7 +6441,7 @@ function ble/syntax/progcolor/word:default/.detect-separated-path {
local word=$1
((wtype==CTX_ARGI||wtype==CTX_ARGEI||wtype==CTX_VALI||wtype==ATTR_VAR||wtype==CTX_RDRS)) || return 1

local detect_opts=stopcheck:timeout-highlight:url
local detect_opts=stopcheck:timeout-highlight:cached:url
((wtype==CTX_RDRS)) && detect_opts=$detect_opts:noglob
[[ $word == '~'* ]] && ((_ble_syntax_attr[p0]!=ATTR_TILDE)) && detect_opts=$detect_opts:notilde
ble/syntax:bash/simple-word/detect-separated-path "$word" :, "$detect_opts"
Expand Down Expand Up @@ -6528,7 +6563,7 @@ function ble/syntax/progcolor/word:default/.highlight-filename {
local p0=${1%%:*} p1=${1#*:}
local wtxt=${text:p0:p1-p0}

local path_opts=stopcheck:timeout-highlight:after-sep
local path_opts=stopcheck:timeout-highlight:cached:after-sep
# チルダ展開の文脈でない時には抑制
[[ $wtxt == '~'* ]] && ((_ble_syntax_attr[p0]!=ATTR_TILDE)) && path_opts=$path_opts:notilde
((wtype==CTX_RDRS||wtype==ATTR_VAR||wtype==CTX_VALI&&wbeg<p0)) && path_opts=$path_opts:noglob
Expand Down Expand Up @@ -6572,7 +6607,7 @@ function ble/syntax/progcolor/word:default/.is-option-context {

local iword ret
for ((iword=1;iword<progcolor_iword;iword++)); do
ble/syntax/progcolor/eval-word "$iword" stopcheck:timeout-highlight
ble/syntax/progcolor/eval-word "$iword" stopcheck:timeout-highlight:cached
[[ $ret == -- ]] && return 1
done
return 0
Expand Down Expand Up @@ -6622,7 +6657,7 @@ function ble/syntax/progcolor/word:default/.impl {
((ext==148)) && return 148
if ((ext==0)); then
local sep=$ret ranges i
ble/syntax:bash/simple-word/locate-filename "$wtxt" "$sep" stopcheck:timeout-highlight:url
ble/syntax:bash/simple-word/locate-filename "$wtxt" "$sep" stopcheck:timeout-highlight:cached:url
(($?==148)) && return 148; ranges=("${ret[@]}")
for ((i=0;i<${#ranges[@]};i+=2)); do
ble/syntax/progcolor/word:default/.highlight-filename $((p0+ranges[i])):$((p0+ranges[i+1]))
Expand Down
100 changes: 97 additions & 3 deletions lib/test-util.sh
Expand Up @@ -2,7 +2,7 @@

ble-import lib/core-test

ble/test/start-section 'util' 1047
ble/test/start-section 'util' 1191

# bleopt

Expand Down Expand Up @@ -938,6 +938,97 @@ function is-global() (readonly "$1"; ! local "$1" 2>/dev/null)
ble/test code:'ret=xyz; ! ble/path#contains ret "???"'
)

# ble/dict#set
(
builtin eval -- "${_ble_util_dict_declare//NAME/dict1}"
builtin eval -- "${_ble_util_gdict_declare//NAME/dict2}"
builtin eval -- "${_ble_util_adict_declare//NAME/dict3}"
index=1
for Dict in ble/{,g,a}dict; do
dict=dict$((index++))

ret=unchanged
ble/test '! '$Dict'#has '$dict' banana' ret=unchanged
ble/test '! '$Dict'#has '$dict' ""' ret=unchanged

$Dict#set $dict apple red
$Dict#set $dict banana yellow
$Dict#set $dict orange orange
$Dict#set $dict melon green

ret=unchanged
ble/test $Dict'#has '$dict' banana' ret=unchanged # 先頭
ble/test $Dict'#has '$dict' apple' ret=unchanged #
ble/test $Dict'#has '$dict' melon' ret=unchanged # 末尾
ble/test '! '$Dict'#has '$dict' pear' ret=unchanged # 存在しない項目
ble/test $Dict'#get '$dict' banana' ret=yellow # 先頭
ble/test $Dict'#get '$dict' apple' ret=red #
ble/test $Dict'#get '$dict' melon' ret=green # 末尾
ble/test '! '$Dict'#get '$dict' pear' ret= # 存在しない項目

# 空白類
ble/test '! '$Dict'#has '$dict' ""' # 末尾空要素で引けるか
ble/test '! '$Dict'#get '$dict' ""' # 末尾空要素で引けるか
$Dict#set $dict '' transparent
ble/test $Dict'#has '$dict' ""' # 末尾空要素で引けるか
ble/test $Dict'#get '$dict' ""' ret=transparent # 末尾空要素で引けるか
$Dict#set $dict 'alpha beta' pink
ble/test $Dict'#has '$dict' ""' # 中央空要素で引けるか
ble/test $Dict'#has '$dict' "alpha beta"' # 空白を含む見出し
ble/test $Dict'#get '$dict' ""' ret=transparent # 中央空要素で引けるか
ble/test $Dict'#get '$dict' "alpha beta"' ret=pink # 空白を含む見出し
$Dict#set $dict ' apple ' ' red '
ble/test $Dict'#has '$dict' " apple "' # 空白で trim されないか
ble/test $Dict'#has '$dict' apple' # 既存項目を破壊していないか
ble/test $Dict'#get '$dict' " apple "' ret=' red ' # 空白で trim されないか
ble/test $Dict'#get '$dict' apple' ret=red # 既存項目を破壊していないか

# FS, colon
ble/test '! '$Dict'#has '$dict' "${_ble_term_FS}"' # 単一FS
ble/test '! '$Dict'#has '$dict' ":"' # 単一コロン
ble/test '! '$Dict'#has '$dict' "apple${_ble_term_FS}banana"' # FSを含む見出し
ble/test '! '$Dict'#has '$dict' apple:banana' # コロンを含む見出し
ble/test '! '$Dict'#get '$dict' "${_ble_term_FS}"' ret= # 単一FS
ble/test '! '$Dict'#get '$dict' ":"' ret= # 単一コロン
ble/test '! '$Dict'#get '$dict' "apple${_ble_term_FS}banana"' ret= # FSを含む見出し
ble/test '! '$Dict'#get '$dict' apple:banana' ret= # コロンを含む見出し
$Dict#set $dict "${_ble_term_FS}" Empty
$Dict#set $dict ":" Colon
$Dict#set $dict "apple${_ble_term_FS}banana" RedYellow
$Dict#set $dict "apple:banana" __red_yellow__
ble/test $Dict'#has '$dict' "${_ble_term_FS}"' # 単一FS
ble/test $Dict'#has '$dict' ":"' # 単一コロン
ble/test $Dict'#has '$dict' "apple${_ble_term_FS}banana"' # FSを含む見出し
ble/test $Dict'#has '$dict' apple:banana' # コロンを含む見出し
ble/test $Dict'#get '$dict' "${_ble_term_FS}"' ret=Empty # 単一FS
ble/test $Dict'#get '$dict' ":"' ret=Colon # 単一コロン
ble/test $Dict'#get '$dict' "apple${_ble_term_FS}banana"' ret=RedYellow # FSを含む見出し
ble/test $Dict'#get '$dict' apple:banana' ret=__red_yellow__ # コロンを含む見出し

# unset
$Dict#unset $dict banana
$Dict#unset $dict apple
$Dict#unset $dict melon
ble/test '! '$Dict'#has '$dict' banana'
ble/test '! '$Dict'#has '$dict' apple'
ble/test '! '$Dict'#has '$dict' melon'
$Dict#unset $dict ""
$Dict#unset $dict "alpha beta"
$Dict#unset $dict " apple "
ble/test '! '$Dict'#has '$dict' ""' # 中央空要素で引けるか
ble/test '! '$Dict'#has '$dict' "alpha beta"' # 空白を含む見出し
ble/test '! '$Dict'#has '$dict' " apple "' # 空白で trim されないか
$Dict#unset $dict "${_ble_term_FS}"
$Dict#unset $dict ":"
$Dict#unset $dict "apple${_ble_term_FS}banana"
$Dict#unset $dict apple:banana
ble/test '! '$Dict'#has '$dict' "${_ble_term_FS}"' # 単一FS
ble/test '! '$Dict'#has '$dict' ":"' # 単一コロン
ble/test '! '$Dict'#has '$dict' "apple${_ble_term_FS}banana"' # FSを含む見出し
ble/test '! '$Dict'#has '$dict' apple:banana' # コロンを含む見出し
done
)

# blehook
(
# declare hook
Expand Down Expand Up @@ -1436,9 +1527,12 @@ ble/test ble/util/is-running-in-subshell exit=1
# ble/util/strftime

# ble/util/{msleep,sleep}
ble/util/msleep/.calibrate-loop &>/dev/null
ble/util/msleep/.calibrate-loop &>/dev/null
ble/util/msleep/.calibrate-loop &>/dev/null
(
ble/test 'ble-measure -q "ble/util/msleep 100"; echo "$ret usec" >&2; ((msec=ret/1000,95<=msec&&msec<=105))'
ble/test 'ble-measure -q "ble/util/sleep 0.1"; echo "$ret usec" >&2; ((msec=ret/1000,95<=msec&&msec<=105))'
ble/test 'ble-measure -q "ble/util/msleep 100"; echo "$ret usec" >&2; ((msec=ret/1000,90<=msec&&msec<=110))'
ble/test 'ble-measure -q "ble/util/sleep 0.1"; echo "$ret usec" >&2; ((msec=ret/1000,90<=msec&&msec<=110))'
)

# ble/util/conditional-sync
Expand Down
2 changes: 1 addition & 1 deletion make_command.sh
Expand Up @@ -242,7 +242,7 @@ function sub:scan/list-command {
[[ $flag_error ]] && return 1

[[ $flag_exclude_this ]] && ble/array#push options --exclude=./make_command.sh
grc "${options[@]}" "(^|[^-./\${}=])\b$command"'\b([[:space:]|&;<>()`"'\'']|$)'
grc "${options[@]}" "(^|[^-./\${}=#])\b$command"'\b([[:space:]|&;<>()`"'\'']|$)'
}

function sub:scan/builtin {
Expand Down
3 changes: 2 additions & 1 deletion memo/ChangeLog.md
Expand Up @@ -33,7 +33,7 @@
- edit (sword): fix definition of `sword` (shell words) `#D1441` f923388
- edit (`kill-forward-logical-line`): fix a bug not deleting newline at the end of the line `#D1443` 09cf7f1
- complete (mandb): fix an encoding prpblem of utf8 manuals `#D1446` 7a4a480
- util (`ble/util/msleep`): fix hang in Cygwin by swithing from `/dev/udp/0.0.0.0/80` to `/dev/zero` `#D1452` 0000000
- util (`ble/util/msleep`): fix hang in Cygwin by swithing from `/dev/udp/0.0.0.0/80` to `/dev/zero` `#D1452` d4d718a
- global:work around bash-4.2 bug of `declare -gA` (reported by 0xC0ncord) `#D1470` 8856a04
- global: fix declaration of associative arrays for `ble-reload` `#D1471` 3cae6e4

Expand All @@ -42,6 +42,7 @@
- main: include hostname in local runtime directory `#D1444` 6494836
- 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` 0000000

<!---------------------------------------------------------------------------->
# ble-0.4.0-devel2
Expand Down

0 comments on commit 6d8311e

Please sign in to comment.