diff --git a/GNUmakefile b/GNUmakefile index 67762fd6..23dbac7b 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -71,6 +71,7 @@ outfiles += $(OUTDIR)/lib/init-msys1.sh outfiles += $(OUTDIR)/lib/core-complete.sh outfiles += $(OUTDIR)/lib/core-syntax.sh outfiles += $(OUTDIR)/lib/core-test.sh +outfiles += $(OUTDIR)/lib/core-cmdspec.sh outfiles += $(OUTDIR)/lib/core-edit.ignoreeof-messages.txt outfiles += $(OUTDIR)/lib/core-decode.emacs-rlfunc.txt outfiles += $(OUTDIR)/lib/core-decode.vi_imap-rlfunc.txt diff --git a/README-ja_JP.md b/README-ja_JP.md index 305585c2..9b81bdc5 100644 --- a/README-ja_JP.md +++ b/README-ja_JP.md @@ -441,6 +441,8 @@ ble-face -s varname_number fg=64 ble-face -s varname_readonly fg=200 ble-face -s varname_transform fg=29,bold ble-face -s varname_unset fg=124 +ble-face -s argument_option fg=teal +ble-face -s argument_error fg=black,bg=225 ``` 現在の描画設定の一覧は以下のコマンドでも確認できます (`ble-face` を無引数で呼び出す)。 diff --git a/README.md b/README.md index 01e5d563..547a0df2 100644 --- a/README.md +++ b/README.md @@ -411,6 +411,9 @@ ble-face -s varname_number fg=64 ble-face -s varname_readonly fg=200 ble-face -s varname_transform fg=29,bold ble-face -s varname_unset fg=124 +ble-face -s argument_option fg=teal +ble-face -s argument_error fg=black,bg=225 + ``` The current list of faces can be obtained by the following command (`ble-face` without arguments): diff --git a/ble.pp b/ble.pp index 7db5adb3..3bfccdfc 100644 --- a/ble.pp +++ b/ble.pp @@ -1214,6 +1214,7 @@ function ble-update { #%x inc.r|@|src/edit| #%x inc.r|@|lib/core-syntax-def| #%x inc.r|@|lib/core-complete-def| +#%x inc.r|@|lib/core-cmdspec-def| bleopt -I #------------------------------------------------------------------------------ diff --git a/blerc b/blerc index 7f0ccd78..74d7cd3b 100644 --- a/blerc +++ b/blerc @@ -663,6 +663,7 @@ #ble-face -s command_jobs fg=red,bold #ble-face -s command_directory fg=navy,underline #ble-face -s argument_option fg=teal +#ble-face -s argument_option fg=black,bg=225 #ble-face -s filename_directory underline,fg=26 #ble-face -s filename_directory_sticky underline,fg=white,bg=26 #ble-face -s filename_link underline,fg=teal diff --git a/docs/ChangeLog.md b/docs/ChangeLog.md index e0c28817..5057e9da 100644 --- a/docs/ChangeLog.md +++ b/docs/ChangeLog.md @@ -83,6 +83,7 @@ - term: let DECSCUSR pass through terminal multiplexers (motivated by cmplstofB) `#D1697` 0000000 - complete: requote for more compact representations on full completions `#D1700` 0000000 - complete: improve support for `declare` and `[[ ... ]]` `#D1701` 0000000 + - syntax: fix completion and highlighting of `declare` with assignment arguments `#D1704` `#D1705` 0000000 ## Changes diff --git a/lib/core-cmdspec-def.sh b/lib/core-cmdspec-def.sh new file mode 100644 index 00000000..70c8500e --- /dev/null +++ b/lib/core-cmdspec-def.sh @@ -0,0 +1,4 @@ +# -*- mode: sh; mode: sh-bash -*- + +function ble/cmdspec/initialize { ble-import "$_ble_base/lib/core-cmdspec.sh"; } +ble/is-function ble/util/idle.push && ble-import -d "$_ble_base/lib/core-cmdspec.sh" diff --git a/lib/core-cmdspec.sh b/lib/core-cmdspec.sh new file mode 100644 index 00000000..b5fe4c4a --- /dev/null +++ b/lib/core-cmdspec.sh @@ -0,0 +1,46 @@ +# -*- mode: sh; mode: sh-bash -*- + +function ble/cmdspec/initialize { return 0; } +ble-import core-complete + +function ble/cmdinfo/cmd:declare/chroma.wattr { + local ret + if ((wtype==_ble_attr_VAR)); then + ble/syntax:bash/find-rhs "$wtype" "$wbeg" "$wlen" element-assignment && + ble/progcolor/highlight-filename.wattr "$ret" "$wend" + else + ble/progcolor/eval-word || return "$?" + + local wval=$ret + if ble/string#match "$wval" '^([_a-zA-Z][_a-zA-Z0-9]*)(\[.+\])?$'; then + # ToDo: properly support quoted case + local varname=${BASH_REMATCH[1]} + ble/syntax/highlight/vartype "$varname" + ble/progcolor/wattr#setattr "$wbeg" "$ret" + ble/progcolor/wattr#setattr $((wbeg+${#varname})) d + elif ble/string#match "$wval" '^[-+]' && ble/progcolor/is-option-context; then + # ToDo: validate available options + local ret; ble/color/face2g argument_option + ble/progcolor/wattr#setg "$wbeg" "$ret" + else + local ret; ble/color/face2g argument_error + ble/progcolor/wattr#setg "$wbeg" "$ret" + fi + fi + return 0 +} + +function ble/cmdinfo/cmd:declare/chroma { + local i "${_ble_syntax_progcolor_vars[@]/%/=}" # WA #D1570 checked + for ((i=1;i<${#comp_words[@]};i++)); do + local ref=${tree_words[i]} + [[ $ref ]] || continue + local progcolor_iword=$i + ble/progcolor/load-word-data "$ref" + ble/progcolor/@wattr ble/cmdinfo/cmd:declare/chroma.wattr + done +} +function ble/cmdinfo/cmd:typeset/chroma { ble/cmdinfo/cmd:declare/chroma "$@"; } +function ble/cmdinfo/cmd:local/chroma { ble/cmdinfo/cmd:declare/chroma "$@"; } +function ble/cmdinfo/cmd:readonly/chroma { ble/cmdinfo/cmd:declare/chroma "$@"; } +function ble/cmdinfo/cmd:export/chroma { ble/cmdinfo/cmd:declare/chroma "$@"; } diff --git a/lib/core-complete.sh b/lib/core-complete.sh index 4e731c37..aaea113e 100644 --- a/lib/core-complete.sh +++ b/lib/core-complete.sh @@ -4089,23 +4089,24 @@ function ble/complete/mandb/initialize-mandb-opts { -ge (NUM1 -ge NUM2) Arithmetic comparison >=. -nt (FILE1 -nt FILE2) True if file1 is newer than file2 (according to modification date). -ot (FILE1 -ot FILE2) True if file1 is older than file2. - -ef (FILE1 -ef FILE2) True if file1 is a hard link to file2. - ' - ble/complete/mandb/opt help=%'help test':help=@"$conditional_operators" '[[' + -ef (FILE1 -ef FILE2) True if file1 is a hard link to file2.' + ble/complete/mandb/opt ignore-double-hyphen:help=%'help test':help=@"$conditional_operators" '[[' + local test_operators=$conditional_operators' -a (EXPR1 -a EXPR2) True if both expr1 AND expr2 are true. - -a (EXPR1 -o EXPR2) True if either expr1 OR expr2 is true. - ' - ble/complete/mandb/opt help=%'help test':help=@"$test_operators" 'test' '[' + -a (EXPR1 -o EXPR2) True if either expr1 OR expr2 is true.' + ble/complete/mandb/opt ignore-double-hyphen:help=%'help test':help=@"$test_operators" 'test' '[' ble/complete/mandb/opt no-man:help:stop-after-argument:plus-option=aAilnrtux declare typeset local ble/complete/mandb/opt no-man:help:stop-after-argument local export readonly + ble/complete/mandb/opt no-man:help:stop-after-argument alias } ble/complete/mandb/initialize-mandb-opts -## @fn ble/complete/mandb/get-opts command +## @fn ble/complete/mandb/get-opts command [default_value] ## @var[out] mandb_opts function ble/complete/mandb/get-opts { + mandb_opts=$2 local ret= if ble/gdict#get _ble_complete_mandb_opts "$1" || { [[ $1 == */*[!/] ]] && ble/gdict#get _ble_complete_mandb_opts "${1##*/}"; } @@ -4242,26 +4243,21 @@ function ble/complete/mandb/load-cache { function ble/complete/source:option/.stops-option { (($#)) || return 1 - local reject= rex_req= + local reject= rexreq= [[ :$mandb_opts: != *:ignore-double-hyphen:* ]] && reject=-- if [[ :$mandb_opts: == *:stop-after-argument:* ]]; then - rex_req='^-.+' - if ble/string#match ":$mandb_opts:" ':plus-option(=[^:]+)?:'; then - if [[ ${BASH_REMATCH[1]} ]]; then - [[ ${BASH_REMATCH[1]:1} ]] && - rex_req='^-.+|^\+['${BASH_REMATCH[1]:1}']' - else - rex_req='^[-+].+' - fi + rexreq='^-.+' + if ble/string#match ":$mandb_opts:" ':plus-option(=[^:]*)?:'; then + rexreq='^[-+].+' fi fi - [[ $reject$rex_req ]] || return 1 + [[ $reject$rexreq ]] || return 1 local word ret for word; do ble/syntax:bash/simple-word/is-simple "$word" && ble/syntax:bash/simple-word/eval "$word" noglob && - [[ $reject && $ret == $reject || $rex_req && ! ( $ret =~ $rex_req ) ]] && + [[ $reject && $ret == $reject || $rexreq && ! ( $ret =~ $rexreq ) ]] && return 0 done return 1 @@ -4286,7 +4282,7 @@ function ble/complete/source:option { local alias_checked=' ' while local ret; ! ble/complete/mandb/load-cache "$cmd"; do alias_checked=$alias_checked$cmd' ' - ble/util/expand-alias "$cmd" + ble/util/expand-alias "$cmd" || return 1 local words; ble/string#split-words ret "$ret"; words=("${ret[@]}") # 変数代入は読み飛ばし @@ -4549,6 +4545,7 @@ function ble/complete/context/overwrite-sources { function ble/complete/context:syntax/generate-sources { ble/syntax/import ble-edit/content/update-syntax + ble/cmdspec/initialize # load user configruation ble/syntax/completion-context/generate "$comp_text" "$comp_index" ((${#sources[@]})) } diff --git a/lib/core-syntax-def.sh b/lib/core-syntax-def.sh index d692da7d..74784ab1 100644 --- a/lib/core-syntax-def.sh +++ b/lib/core-syntax-def.sh @@ -177,5 +177,6 @@ function ble/syntax/defface.onload { ble/color/defface varname_transform fg=29,bold ble/color/defface varname_export fg=200,bold ble/color/defface argument_option fg=teal + ble/color/defface argument_error fg=black,bg=225 } blehook/eval-after-load color_defface ble/syntax/defface.onload diff --git a/lib/core-syntax.sh b/lib/core-syntax.sh index 1ec9fd6d..20a24757 100644 --- a/lib/core-syntax.sh +++ b/lib/core-syntax.sh @@ -3139,13 +3139,8 @@ function ble/syntax:bash/check-variable-assignment { [[ ${_ble_syntax_bash_command_CtxAssign[ctx]} ]] || return 1 # パターン一致 (var= var+= arr[ のどれか) - local suffix='=|\+=?' - ((_ble_bash<30100)) && suffix='=' - if ((ctx==CTX_ARGVI||ctx==CTX_ARGEI)); then - suffix="$suffix|\[?" - else - suffix="$suffix|\[" - fi + local suffix='[=[]' + ((_ble_bash>=30100)) && suffix=$suffix'|\+=?' local rex_assign="^([a-zA-Z_][a-zA-Z_0-9]*)($suffix)" [[ $tail =~ $rex_assign ]] || return 1 local rematch=$BASH_REMATCH @@ -3492,102 +3487,100 @@ function ble/syntax:bash/ctx-command/check-word-end { ble/syntax/parse/word-pop if ((ctx==CTX_CMDI)); then - if ((wt==CTX_CMDXV)); then - ((ctx=CTX_ARGX)) - return 0 - fi - local ret ble/util/expand-alias "$word"; local word_expanded=$ret - local processed= - case "$word_expanded" in - ('[[') - # 条件コマンド開始 - ble/syntax/parse/touch-updated-attr "$wbeg" - ((_ble_syntax_attr[wbeg]=ATTR_DEL, - ctx=CTX_ARGX0)) - - ble/syntax/parse/word-cancel # 単語 "[[" (とその内部のノード全て) を削除 - if [[ $word == '[[' ]]; then - # "[[" は一度角括弧式として読み取られるので、その情報を削除する。 - _ble_syntax_attr[wbeg+1]= # 角括弧式として着色されているのを消去 - fi + # キーワードの処理 + if ((wt!=CTX_CMDXV)); then # Note: 変数代入の直後はキーワードは処理しない + local processed= + case "$word_expanded" in + ('[[') + # 条件コマンド開始 + ble/syntax/parse/touch-updated-attr "$wbeg" + ((_ble_syntax_attr[wbeg]=ATTR_DEL, + ctx=CTX_ARGX0)) - i=$wbeg ble/syntax/parse/nest-push "$CTX_CONDX" + ble/syntax/parse/word-cancel # 単語 "[[" (とその内部のノード全て) を削除 + if [[ $word == '[[' ]]; then + # "[[" は一度角括弧式として読み取られるので、その情報を削除する。 + _ble_syntax_attr[wbeg+1]= # 角括弧式として着色されているのを消去 + fi - # workaround: word "[[" を nest 内部に設置し直す - i=$wbeg ble/syntax/parse/word-push "$CTX_CMDI" "$wbeg" - ble/syntax/parse/word-pop - return 0 ;; - ('time') ((ctx=CTX_TARGX1)); processed=keyword ;; - ('!') ((ctx=CTX_CMDXT)) ; processed=keyword ;; - ('if'|'while'|'until') ((ctx=CTX_CMDX1)) ; processed=begin ;; - ('for') ((ctx=CTX_FARGX1)); processed=begin ;; - ('select') ((ctx=CTX_SARGX1)); processed=begin ;; - ('case') ((ctx=CTX_CARGX1)); processed=begin ;; - ('{') - ((ctx=CTX_CMDX1)) - if ((wt==CTX_CMDXD||wt==CTX_CMDXD0)); then - processed=middle # "for ...; {" などの時 - else - processed=begin - fi ;; - ('then'|'elif'|'else'|'do') ((ctx=CTX_CMDX1)) ; processed=middle ;; - ('}'|'done'|'fi'|'esac') ((ctx=CTX_CMDXE)) ; processed=end ;; - ('coproc') - if ((_ble_bash>=40000)); then - if ble/syntax:bash/ctx-coproc/.is-next-compound; then - ((ctx=CTX_CMDXC)) + i=$wbeg ble/syntax/parse/nest-push "$CTX_CONDX" + + # workaround: word "[[" を nest 内部に設置し直す + i=$wbeg ble/syntax/parse/word-push "$CTX_CMDI" "$wbeg" + ble/syntax/parse/word-pop + return 0 ;; + ('time') ((ctx=CTX_TARGX1)); processed=keyword ;; + ('!') ((ctx=CTX_CMDXT)) ; processed=keyword ;; + ('if'|'while'|'until') ((ctx=CTX_CMDX1)) ; processed=begin ;; + ('for') ((ctx=CTX_FARGX1)); processed=begin ;; + ('select') ((ctx=CTX_SARGX1)); processed=begin ;; + ('case') ((ctx=CTX_CARGX1)); processed=begin ;; + ('{') + ((ctx=CTX_CMDX1)) + if ((wt==CTX_CMDXD||wt==CTX_CMDXD0)); then + processed=middle # "for ...; {" などの時 else - ((ctx=CTX_COARGX)) - fi - processed=keyword - fi ;; - ('function') - ((ctx=CTX_ARGX)) - local isfuncsymx=$'\t\n'' "$&'\''();<>\`|' rex_space=$'[ \t]' rex - if rex="^$rex_space+" && [[ ${text:i} =~ $rex ]]; then - ((_ble_syntax_attr[i]=CTX_ARGX,i+=${#BASH_REMATCH},ctx=CTX_ARGX)) - if rex="^([^#$isfuncsymx][^$isfuncsymx]*)($rex_space*)(\(\(|\($rex_space*\)?)?" && [[ ${text:i} =~ $rex ]]; then - local rematch1=${BASH_REMATCH[1]} - local rematch2=${BASH_REMATCH[2]} - local rematch3=${BASH_REMATCH[3]} - ((_ble_syntax_attr[i]=ATTR_FUNCDEF,i+=${#rematch1}, - ${#rematch2}&&(_ble_syntax_attr[i]=CTX_CMDX1,i+=${#rematch2}))) - - if [[ $rematch3 == '('*')' ]]; then - ((_ble_syntax_attr[i]=ATTR_DEL,i+=${#rematch3},ctx=CTX_CMDXC)) - elif ((_ble_bash>=40200)) && [[ $rematch3 == '((' ]]; then - ble/syntax/parse/set-lookahead 2 + processed=begin + fi ;; + ('then'|'elif'|'else'|'do') ((ctx=CTX_CMDX1)) ; processed=middle ;; + ('}'|'done'|'fi'|'esac') ((ctx=CTX_CMDXE)) ; processed=end ;; + ('coproc') + if ((_ble_bash>=40000)); then + if ble/syntax:bash/ctx-coproc/.is-next-compound; then ((ctx=CTX_CMDXC)) - elif [[ $rematch3 == '('* ]]; then - ((_ble_syntax_attr[i]=ATTR_ERR,ctx=CTX_ARGX0)) - ble/syntax/parse/nest-push "$CTX_CMDX1" '(' - ((${#rematch3}>=2&&(_ble_syntax_attr[i+1]=CTX_CMDX1),i+=${#rematch3})) else - ((ctx=CTX_CMDXC)) + ((ctx=CTX_COARGX)) fi processed=keyword + fi ;; + ('function') + ((ctx=CTX_ARGX)) + local isfuncsymx=$'\t\n'' "$&'\''();<>\`|' rex_space=$'[ \t]' rex + if rex="^$rex_space+" && [[ ${text:i} =~ $rex ]]; then + ((_ble_syntax_attr[i]=CTX_ARGX,i+=${#BASH_REMATCH},ctx=CTX_ARGX)) + if rex="^([^#$isfuncsymx][^$isfuncsymx]*)($rex_space*)(\(\(|\($rex_space*\)?)?" && [[ ${text:i} =~ $rex ]]; then + local rematch1=${BASH_REMATCH[1]} + local rematch2=${BASH_REMATCH[2]} + local rematch3=${BASH_REMATCH[3]} + ((_ble_syntax_attr[i]=ATTR_FUNCDEF,i+=${#rematch1}, + ${#rematch2}&&(_ble_syntax_attr[i]=CTX_CMDX1,i+=${#rematch2}))) + + if [[ $rematch3 == '('*')' ]]; then + ((_ble_syntax_attr[i]=ATTR_DEL,i+=${#rematch3},ctx=CTX_CMDXC)) + elif ((_ble_bash>=40200)) && [[ $rematch3 == '((' ]]; then + ble/syntax/parse/set-lookahead 2 + ((ctx=CTX_CMDXC)) + elif [[ $rematch3 == '('* ]]; then + ((_ble_syntax_attr[i]=ATTR_ERR,ctx=CTX_ARGX0)) + ble/syntax/parse/nest-push "$CTX_CMDX1" '(' + ((${#rematch3}>=2&&(_ble_syntax_attr[i+1]=CTX_CMDX1),i+=${#rematch3})) + else + ((ctx=CTX_CMDXC)) + fi + processed=keyword + fi fi - fi - [[ $processed ]] || ((_ble_syntax_attr[i-1]=ATTR_ERR)) ;; - esac - - if [[ $processed ]]; then - local attr= - case $processed in - (keyword) attr=$ATTR_KEYWORD ;; - (begin) attr=$ATTR_KEYWORD_BEGIN ;; - (end) attr=$ATTR_KEYWORD_END ;; - (middle) attr=$ATTR_KEYWORD_MID ;; + [[ $processed ]] || ((_ble_syntax_attr[i-1]=ATTR_ERR)) ;; esac - if [[ $attr ]]; then - ble/syntax/parse/touch-updated-attr "$wbeg" - ((_ble_syntax_attr[wbeg]=attr)) - fi - return 0 + if [[ $processed ]]; then + local attr= + case $processed in + (keyword) attr=$ATTR_KEYWORD ;; + (begin) attr=$ATTR_KEYWORD_BEGIN ;; + (end) attr=$ATTR_KEYWORD_END ;; + (middle) attr=$ATTR_KEYWORD_MID ;; + esac + if [[ $attr ]]; then + ble/syntax/parse/touch-updated-attr "$wbeg" + ((_ble_syntax_attr[wbeg]=attr)) + fi + + return 0 + fi fi # 関数定義である可能性を考え stat を置かず読み取る @@ -5825,7 +5818,7 @@ function ble/syntax:bash/extract-command/.construct-proc { EC_found=1 return 0 fi - elif ((wtype==CTX_ARGI||wtype==CTX_ARGVI||wtype==CTX_ARGEI)); then + elif ((wtype==CTX_ARGI||wtype==CTX_ARGVI||wtype==CTX_ARGEI||wtype==ATTR_VAR)); then ble/syntax:bash/extract-command/.register-word comp_line=" $comp_line" fi @@ -5995,11 +5988,13 @@ function ble/syntax:bash/extract-command-by-noderef { comp_cword=0 comp_point=0 + local ExprIsArgument='wtype==CTX_ARGI||wtype==CTX_ARGVI||wtype==CTX_ARGEI||wtype==ATTR_VAR' + # 自ノードの追加 local ret node wtype wlen wbeg wend wattr ble/string#split-words node "${_ble_syntax_tree[i-1]}" wtype=${node[nofs]} wlen=${node[nofs+1]} - [[ ! ${wtype//[0-9]} ]] && ((wtype==CTX_CMDI||wtype==CTX_ARGI||wtype==CTX_ARGVI||wtype==CTX_ARGEI)) || return 1 + [[ ! ${wtype//[0-9]} ]] && ((wtype==CTX_CMDI||ExprIsArgument)) || return 1 ble/array#push comp_words "${_ble_syntax_text:i-wlen:wlen}" [[ $opts == *:treeinfo:* ]] && ble/array#push tree_words "$i:$nofs" @@ -6011,7 +6006,7 @@ function ble/syntax:bash/extract-command-by-noderef { ble/syntax/tree#previous-sibling "$ret" wvars do [[ ! ${wtype//[0-9]} ]] || continue - if ((wtype==CTX_CMDI||wtype==CTX_ARGI||wtype==CTX_ARGVI||wtype==CTX_ARGEI)); then + if ((wtype==CTX_CMDI||ExprIsArgument)); then ble/array#push comp_words "${_ble_syntax_text:wbeg:wlen}" [[ $opts == *:treeinfo:* ]] && ble/array#push tree_words "$ret" @@ -6029,7 +6024,7 @@ function ble/syntax:bash/extract-command-by-noderef { while ble/syntax/tree#next-sibling "$ret" wvars; do [[ ! ${wtype//[0-9]} ]] || continue ((wtype==CTX_CMDI)) && break - if ((wtype==CTX_ARGI||wtype==CTX_ARGVI||wtype==CTX_ARGEI)); then + if ((ExprIsArgument)); then ble/array#push comp_words "${_ble_syntax_text:wbeg:wlen}" [[ $opts == *:treeinfo:* ]] && ble/array#push tree_words "$ret" @@ -6470,17 +6465,17 @@ function bleopt/check:filename_ls_colors { bleopt -I filename_ls_colors #------------------------------------------------------------------------------ -# ble/syntax/progcolor +# ble/progcolor _ble_syntax_progcolor_vars=( node TE_i TE_nofs wtype wlen wbeg wend wattr) _ble_syntax_progcolor_wattr_vars=( wattr_buff wattr_pos wattr_g) -## @fn ble/syntax/progcolor/load-word-data i:nofs +## @fn ble/progcolor/load-word-data i:nofs ## @var[out] TE_i TE_nofs node ## @var[out] wtype wlen wbeg wend wattr -function ble/syntax/progcolor/load-word-data { +function ble/progcolor/load-word-data { # TE_i TE_nofs TE_i=${1%%:*} TE_nofs=${1#*:} [[ $1 != *:* ]] && TE_nofs=0 @@ -6496,9 +6491,9 @@ function ble/syntax/progcolor/load-word-data { wend=$TE_i } -## @fn ble/syntax/progcolor/set-wattr value +## @fn ble/progcolor/set-wattr value ## @var[in] TE_i TE_nofs node -function ble/syntax/progcolor/set-wattr { +function ble/progcolor/set-wattr { ble/syntax/urange#update color_ "$wbeg" "$wend" ble/syntax/wrange#update _ble_syntax_word_ "$TE_i" node[TE_nofs+4]=$1 @@ -6506,7 +6501,7 @@ function ble/syntax/progcolor/set-wattr { _ble_syntax_tree[TE_i-1]="${node[*]}" } -## @fn ble/syntax/progcolor/eval-word [iword] [opts] +## @fn ble/progcolor/eval-word [iword] [opts] ## 現在のコマンドの iword 番目の単語を評価した値を返します。 ## iword を省略した場合には現在着色中の単語が使われます。 ## 単語が評価できない場合にはコマンドは失敗します。 @@ -6523,7 +6518,7 @@ function ble/syntax/progcolor/set-wattr { ## 単語の評価値のキャッシュです。 ## @var[out] ret ## -function ble/syntax/progcolor/eval-word { +function ble/progcolor/eval-word { local iword=${1:-progcolor_iword} opts=$2 if [[ ${progcolor_stats[iword]+set} ]]; then ret=${progcolor_wvals[iword]} @@ -6555,38 +6550,82 @@ function ble/syntax/progcolor/eval-word { return 0 } -## @fn ble/syntax/progcolor/wattr#initialize +function ble/progcolor/is-option-context { + # 既にオプション停止位置が計算済みの場合 + if [[ ${progcolor_optctx[1]} ]]; then + # Note: 等号は停止を引き起こした引数 -- 自体の時 (オプションとして有効) + ((progcolor_iword<=progcolor_optctx[1])) + return $? + fi + + local reject rexreq + if [[ ! ${progcolor_optctx[0]} ]]; then + progcolor_optctx[0]=1 + + reject=-- rexreq= + if ble/is-function ble/complete/mandb/get-opts; then + # copied from ble/complete/source:option/.stops-option + local mandb_opts; ble/complete/mandb/get-opts "${comp_words[0]}" + [[ :$mandb_opts: != *:ignore-double-hyphen:* ]] && reject=-- + if [[ :$mandb_opts: == *:stop-after-argument:* ]]; then + rexreq='^-.+' + if ble/string#match ":$mandb_opts:" ':plus-option(=[^:]*)?:'; then + rexreq='^[-+].+' + fi + fi + fi + progcolor_optctx[2]=$reject + progcolor_optctx[3]=$rexreq + else + reject=${progcolor_optctx[2]} + rexreq=${progcolor_optctx[3]} + fi + [[ $reject$rexreq ]] || return 0 + + local iword + for ((iword=progcolor_optctx[0];iword0)) && ble/array#push wattr_buff "$len:$wattr_g" wattr_pos=$pos wattr_g=$g } -function ble/syntax/progcolor/wattr#setattr { +function ble/progcolor/wattr#setattr { local pos=$1 attr=$2 g ble/syntax/attr2g "$attr" - ble/syntax/progcolor/wattr#setg "$pos" "$g" + ble/progcolor/wattr#setg "$pos" "$g" } -## @fn ble/syntax/progcolor/wattr#finalize +## @fn ble/progcolor/wattr#finalize ## @var[in,out] wattr_buff ## @var[in,out] wattr_pos ## @var[in,out] wattr_g -function ble/syntax/progcolor/wattr#finalize { +function ble/progcolor/wattr#finalize { local wattr if ((${#wattr_buff[@]})); then local len=$((wend-wattr_pos)) @@ -6597,17 +6636,17 @@ function ble/syntax/progcolor/wattr#finalize { else wattr=$wattr_g fi - ble/syntax/progcolor/set-wattr "$wattr" + ble/progcolor/set-wattr "$wattr" } -## @fn ble/syntax/progcolor/word:default/.detect-separated-path word +## @fn ble/progcolor/highlight-filename/.detect-separated-path word ## @param[in] word ## @var[in] wtype p0 ## @var[in] _ble_syntax_attr ## @var[out] ret ## 有効な区切り文字の集合を返します。 -function ble/syntax/progcolor/word:default/.detect-separated-path { +function ble/progcolor/highlight-filename/.detect-separated-path { local word=$1 ((wtype==CTX_ARGI||wtype==CTX_ARGEI||wtype==CTX_VALI||wtype==ATTR_VAR||wtype==CTX_RDRS)) || return 1 @@ -6617,12 +6656,12 @@ function ble/syntax/progcolor/word:default/.detect-separated-path { ble/syntax:bash/simple-word/detect-separated-path "$word" :, "$detect_opts" } -## @fn ble/syntax/progcolor/word:default/.highlight-pathspec g [opts] +## @fn ble/progcolor/highlight-filename/.pathspec.wattr g [opts] ## @param[in] g ## @param[in,opt] opts ## @var[in] wtype p0 p1 ## @var[in] path spec -function ble/syntax/progcolor/word:default/.highlight-pathspec { +function ble/progcolor/highlight-filename/.pathspec.wattr { local p=$p0 opts=$2 if [[ :$opts: != *:no-path-color:* ]]; then @@ -6643,31 +6682,31 @@ function ble/syntax/progcolor/word:default/.highlight-pathspec { # コマンド名の時は下線は引かない様にする ((wtype==CTX_CMDI&&(g&=~_ble_color_gflags_Underline))) - ble/syntax/progcolor/wattr#setg "$p" "$g" + ble/progcolor/wattr#setg "$p" "$g" ((p=p0+${#espec})) done fi - ble/syntax/progcolor/wattr#setg "$p" "$1" + ble/progcolor/wattr#setg "$p" "$1" [[ $1 != d ]] && - ble/syntax/progcolor/wattr#setg "$p1" d + ble/progcolor/wattr#setg "$p1" d return 0 } -## @fn ble/syntax/progcolor/word:default/.highlight-pathspec-with-attr attr +## @fn ble/progcolor/highlight-filename/.pathspec-with-attr.wattr attr ## @param[in] attr ## @var[in] wtype p0 p1 ## @var[in] path spec -function ble/syntax/progcolor/word:default/.highlight-pathspec-with-attr { +function ble/progcolor/highlight-filename/.pathspec-with-attr.wattr { local g; ble/syntax/attr2g "$1" - ble/syntax/progcolor/word:default/.highlight-pathspec "$g" + ble/progcolor/highlight-filename/.pathspec.wattr "$g" return 0 } -## @fn ble/syntax/progcolor/word:default/.highlight-pathspec-by-name value +## @fn ble/progcolor/highlight-filename/.pathspec-by-name.wattr value ## @param[in] value ## @var[in] wtype p0 p1 ## @var[in] path spec -function ble/syntax/progcolor/word:default/.highlight-pathspec-by-name { +function ble/progcolor/highlight-filename/.pathspec-by-name.wattr { local value=$1 local highlight_opts= @@ -6721,15 +6760,15 @@ function ble/syntax/progcolor/word:default/.highlight-pathspec-by-name { fi [[ $type && ! $g ]] && ble/syntax/attr2g "$type" - ble/syntax/progcolor/word:default/.highlight-pathspec "${g:-d}" "$highlight_opts" + ble/progcolor/highlight-filename/.pathspec.wattr "${g:-d}" "$highlight_opts" return 0 } -## @fn ble/syntax/progcolor/word:default/.highlight-filename p0:p1 +## @fn ble/progcolor/highlight-filename/.single.wattr p0:p1 ## @param[in] p0 p1 ## ファイル名の (コマンドライン内部における) 範囲を指定します。 ## @param[in] wtype -function ble/syntax/progcolor/word:default/.highlight-filename { +function ble/progcolor/highlight-filename/.single.wattr { local p0=${1%%:*} p1=${1#*:} local wtxt=${text:p0:p1-p0} @@ -6744,65 +6783,98 @@ function ble/syntax/progcolor/word:default/.highlight-filename { if ((ext==142)); then if [[ $ble_textarea_render_defer_running ]]; then # background で timeout した時はこのファイル名の着色は諦める - ble/syntax/progcolor/wattr#setg "$p0" d + ble/progcolor/wattr#setg "$p0" d else # foreground で timeout した時は後で background で着色する為に取り敢えず抜ける return 148 fi elif ((ext&&(wtype==CTX_CMDI||wtype==CTX_ARGI||wtype==CTX_ARGEI||wtype==CTX_RDRF||wtype==CTX_RDRS||wtype==CTX_RDRD||wtype==CTX_RDRD2||wtype==CTX_VALI))); then # failglob 等の理由で展開に失敗した場合 - ble/syntax/progcolor/word:default/.highlight-pathspec-with-attr "$ATTR_ERR" + ble/progcolor/highlight-filename/.pathspec-with-attr.wattr "$ATTR_ERR" elif (((wtype==CTX_RDRF||wtype==CTX_RDRD||wtype==CTX_RDRD2)&&count>=2)); then # 複数語に展開されたら駄目 - ble/syntax/progcolor/wattr#setattr "$p0" "$ATTR_ERR" + ble/progcolor/wattr#setattr "$p0" "$ATTR_ERR" elif ((wtype==CTX_CMDI)); then local attr=${_ble_syntax_attr[wbeg]} if ((attr!=ATTR_KEYWORD&&attr!=ATTR_KEYWORD_BEGIN&&attr!=ATTR_KEYWORD_END&&attr!=ATTR_KEYWORD_MID&&attr!=ATTR_DEL)); then local type=; ble/syntax/highlight/cmdtype "$value" "$wtxt" if ((type==ATTR_CMD_FILE||type==ATTR_CMD_FILE||type==ATTR_ERR)); then - ble/syntax/progcolor/word:default/.highlight-pathspec-with-attr "$type" + ble/progcolor/highlight-filename/.pathspec-with-attr.wattr "$type" elif [[ $type ]]; then - ble/syntax/progcolor/wattr#setattr "$p0" "$type" + ble/progcolor/wattr#setattr "$p0" "$type" fi fi elif ((wtype==CTX_RDRD||wtype==CTX_RDRD2)); then if local rex='^[0-9]+-?$|^-$'; [[ $value =~ $rex ]]; then - ble/syntax/progcolor/wattr#setattr "$p0" "$ATTR_DEL" + ble/progcolor/wattr#setattr "$p0" "$ATTR_DEL" elif ((wtype==CTX_RDRD2)); then - ble/syntax/progcolor/word:default/.highlight-pathspec-by-name "$value" + ble/progcolor/highlight-filename/.pathspec-by-name.wattr "$value" else - ble/syntax/progcolor/wattr#setattr "$p0" "$ATTR_ERR" + ble/progcolor/wattr#setattr "$p0" "$ATTR_ERR" fi elif ((wtype==CTX_ARGI||wtype==CTX_ARGEI||wtype==CTX_VALI||wtype==ATTR_VAR||wtype==CTX_RDRS||wtype==CTX_RDRF)); then - ble/syntax/progcolor/word:default/.highlight-pathspec-by-name "$value" + ble/progcolor/highlight-filename/.pathspec-by-name.wattr "$value" fi } -## @fn ble/syntax/progcolor/word:default/.is-option-context -## @var[in] wtype -function ble/syntax/progcolor/word:default/.is-option-context { - ((wtype==CTX_ARGI||wtype==CTX_ARGEI||wtype==CTX_ARGVI)) || return 1 +function ble/progcolor/highlight-filename.wattr { + local p0=$1 p1=$2 + if ((p0=2)) || return 1 local IFS=$_ble_term_IFS @@ -6894,27 +6944,31 @@ function ble/syntax/progcolor/.compline-rewrite-command { ble/array#reserve-prototype $# tree_words=("${tree_words[0]}" "${_ble_array_prototype[@]::$#-1}" "${tree_words[@]:1}") } -## @fn ble/syntax/progcolor cmd opts +## @fn ble/progcolor cmd opts ## @var[in] comp_words comp_cword comp_line comp_point ## @var[in] tree_words ## @var[in,out] color_umin color_umax -function ble/syntax/progcolor { +function ble/progcolor { local cmd=$1 opts=$2 + # cache used by "eval-word" local -a progcolor_stats=() local -a progcolor_wvals=() + # cache used by "is-option-context" + local -a progcolor_optctx=() + local -a alias_args=() local checked=" " processed= while :; do - if ble/is-function "ble/cmdinfo/color:$cmd"; then - ble/syntax/progcolor/.compline-rewrite-command "$cmd" "${alias_args[@]}" - "ble/cmdinfo/color:$cmd" "$opts" + if ble/is-function ble/cmdinfo/cmd:"$cmd"/chroma; then + ble/progcolor/.compline-rewrite-command "$cmd" "${alias_args[@]}" + ble/cmdinfo/cmd:"$cmd"/chroma "$opts" processed=1 break - elif [[ $cmd == */?* ]] && ble/is-function "ble/cmdinfo/color:${cmd##*/}"; then - ble/syntax/progcolor/.compline-rewrite-command "${cmd##*/}" "${alias_args[@]}" - "ble/cmdinfo/color:${cmd##*/}" "$opts" + elif [[ $cmd == */?* ]] && ble/is-function ble/cmdinfo/cmd:"${cmd##*/}"/chroma; then + ble/progcolor/.compline-rewrite-command "${cmd##*/}" "${alias_args[@]}" + ble/cmdinfo/cmd:"${cmd##*/}"/chroma "$opts" processed=1 break fi @@ -6929,13 +6983,13 @@ function ble/syntax/progcolor { alias_args=("${ret[@]:1}" "${alias_args[@]}") done [[ $processed ]] || - ble/syntax/progcolor/default + ble/progcolor/default # コマンド名に対しては既定の着色を実行 if [[ ${tree_words[0]} ]]; then local "${_ble_syntax_progcolor_vars[@]/%/=}" # WA #D1570 checked - ble/syntax/progcolor/load-word-data "${tree_words[0]}" - [[ $wattr == - ]] && ble/syntax/progcolor/word:default + ble/progcolor/load-word-data "${tree_words[0]}" + [[ $wattr == - ]] && ble/progcolor/word:default fi } @@ -6997,13 +7051,13 @@ function ble/highlight/layer:syntax/word/.update-attributes/.proc { local comp_line comp_point comp_words comp_cword tree_words if ble/syntax:bash/extract-command-by-noderef "$TE_i:$TE_nofs" treeinfo; then local cmd=${comp_words[0]} - ble/syntax/progcolor "$cmd" + ble/progcolor "$cmd" return 0 fi fi # コマンドラインを復元できなければ単一単語の着色 - ble/syntax/progcolor/word:default + ble/progcolor/word:default } ## @fn ble/highlight/layer:syntax/word/.update-attributes @@ -7220,6 +7274,7 @@ function ble/highlight/layer:syntax/update { fi #%end + ble/cmdspec/initialize # load chroma ble/highlight/layer:syntax/update-attribute-table ble/highlight/layer:syntax/update-word-table ble/highlight/layer:syntax/update-error-table diff --git a/note.txt b/note.txt index d2751baa..7db4640c 100644 --- a/note.txt +++ b/note.txt @@ -1275,6 +1275,12 @@ bash_tips bug-bash, third-party bugs & reviews ------------------------------------------------------------------------------- +2021-12-11 + + * bash-completion: curl --http0, --http1, --proxy1 等存在しないオプションが生成されている + * bash-completion: printf -v varname + * bash-completion: test, [ の引数の文法に従った補完 + 2021-12-08 * space @@ -1618,17 +1624,65 @@ bash_tips 2021-12-11 + * declare の引数チェックをもっと真面目に実装する。chroma のインターフェイス + 設計の足がかりにする。 + + * refactor: mandb_opts をキャッシュする様にする。progcolor_optctx と同様に。 + これは declare のより詳細な実装で mandb_opts を参照したいから。 + + * wattr=- (未着色) の時にのみ着色しているが、実際には一つでも未着色があった + らそれ以降の引数に対して与える影響を考慮に入れなければならない。但し、これ + を実行すると毎回ファイル名着色が全て計算されるなどの様な形になりとても遅く + なると思われるので、未だ実装しない。 + + これは一般の問題なので別項目で議論するべき気がする。mandb_opts 等を用いて + 指定する可能性。 + + * declare: -f, -F が含まれる場合には関数名として任意の名前を含む事ができる。 + というかオプション名も含む事ができる? (declare -F -f とした時の解釈はどちら + になるのだろうか?) + + * refactor: mandb_opts はコマンド一般用に転化しても良いのではないか。その時 + には cmdspec に移動して、更にそれを core-complete から読み込む様にすれば + 良い。と思ったが help, help-usage 等は名前的には mandb_opts 専用の物である。 + 名前を変更する必要があるかもしれない。 + + 或いは、help:help-usage 等 mandb 専用のオプションはそれ専用の配列に格納する? + + 取り敢えず現在使われているオプションについて整理する。また、将来的に使い + そうなオプションについても考える。 + + no-man + help + help-usage + ignore-double-hyphen + stop-after-argument + plus-option=aAilnrtux + + うーん。これは別項目で対応するべき事の気がする。 + + * refactor: highlight-variable というインターフェイスを作る。 + + と、思ったが quote 等も考えるとそういった関数を提供する事に意味があるのか + 分からなくなってくる。先に quote 除去した時の対応関係について解決する枠組 + みが必要になるのではないかという気もする。 + + * cmdspec: cd 関連の cmdinfo は core-cmdspec ではなくて contrib/cmdspec/* 辺 + りに移動する? + + * [BUG} mandb: declare で空の completion が生成されている。 + + * [BUG] wget の man page 抽出で short option の desc が空になっている。 + * PROMPT_COMMAND / trap DEBUG で問題が起こる? (found by rashad-moves) https://github.com/rashad-moves/HomeConfigurationFiles/commit/efbac4153fd5021f1bc00d42c618fd9d6f4090b9 - * bash-completion: curl --http0, --http1, --proxy1 等存在しないオプションが生成されている - * complete (source:rhs): 変数名依存の補完に対応しても良いのでは。 * complete: ARGEX (eval 文脈) の補完 現在は "variable:=, command:D, file" で生成しているが、本来は一番先頭の引数 - を元にして argument (including progcomp, etc.) を呼び出すべきである。 + を元にして argument (including progcomp, etc.) を呼び出すべきなのではないか。 * complete: [[ の中の文法も考慮した補完。これは [[ の中の文法にちゃんと対応し た後で考える事の気がする。 @@ -1662,30 +1716,11 @@ bash_tips $ dnf -C repoquery --installed --whatprovides /usr/bin/\* --nvr $ LANG=C dnf -C provides -q /usr/bin/\* - * highlight: declare のオプション名…変数名よりも後にあるのはエラー着色にするべき。 + というか man -s 1:5:... -f command... を呼び出せばよいらしい。 * complete: 文字列引数の中にファイル名を含めたい事もあるのでは。つまり "add a.sh" の様な。特に complete -m '...' の編集で欲しくなる。 - * bash-completion: printf -v ... - https://github.com/akinomyoga/ble.sh/issues/155#issuecomment-984619516 - - これは bash-completion 側で対応するべき事の気がする。 - - 取り敢えず --help 対応が終われば、変数名の補完はできないにしても、オプショ - ンの表示ぐらいはできる様になる。printf の場合には最初の引数には '' を指定す - るのが良い気がする → 取り敢えずオプションは表示される様になった。 - - * bash-completion: better support for test, [ - https://github.com/akinomyoga/ble.sh/issues/158 - - これも bash-completion の側で対応するべき事の気がする。 - 但しオプションの説明についてはちゃんと生成しなければならない。 - progcomp の枠組みで説明も一緒に生成できる仕組みがあっても良いのではないか。 - - うーん。生成し切れていない物は別枠で指定する? うーん。getoptions 的仕様を確 - 定する必要がある気がする。 - * bash-completion: awk - で long option だけが生成される。調べてみると complete -F _longopt が割り当てられているコマンドについては全てこのパターン の様である。 @@ -5616,8 +5651,251 @@ bash_tips Done (実装ログ) ------------------------------------------------------------------------------- +2021-12-12 + + * highlight: declare のオプション名…変数名よりも後にあるのはエラー着色にするべき [#D1705] + これは #D1704 で一緒に対応した。 + + * complete: declare a -[TAB] でも候補が生成されてしまっている [#D1704] + + →調べてみた所、これは declare の引数 (変数形式) が extract-commands で抽出 + されていないのが原因であった。引数の種類を調べると ATTR_VAR である。然し色々 + と振る舞いを調べると ATTR_VAR はコマンドの前につく a=b の形の変数代入に使わ + れている単語の種類である。 + + もっと調べると declare a=b の場合には a=b の単語の種類はちゃんと ARGI になっ + ている。また、a=b declare hello の時にも hello の単語の種類はちゃんと ARGI + になっている。つまり、特定の条件で declare hello の変数名が変数代入であるか + の様に単語登録されてしまっているのが原因である。 + + wtype の決定経緯を調べる。ctx-command/check-word-end に入った時点で既に + wtype == ATTR_VAR になっている。従って、word-begin の段階で ATTR_VAR になっ + ているのが問題である気がする。然し、check-word-begin の段階では wtype = + CTX_ARGVX の様である。つまり、何処かで wtype が書き換わってしまっているのが + 原因という事になるのだろうか。 + + うーん。分かった。ble/syntax:bash/check-variable-assignment の中で ARGVI 及 + び ARGEI の時には = の有無に関係なく ATTR_VAR にしてしまっている。これは何 + 故だったろうか。経緯を調べる必要がある。 + + | 2f2f0eb6 + | @@ -2401,7 +2406,7 @@ function ble-syntax:bash/check-variable-assignment { + | # パターン一致 (var= var+= arr[ のどれか) + | local suffix='=|\+=?' + | ((_ble_bash<30100)) && suffix='=' + | - if ((ctx==CTX_ARGVI)); then + | + if ((ctx==CTX_ARGVI||ctx==CTX_ARGEI)); then + | suffix="$suffix|\[?" + | else + | suffix="$suffix|\[" + |---------------------------------------------------------------------- + | commit 1823c540cfe25c952fc96d8e50ae7dab712aacaf + | Author: Koichi Murase + | Date: Mon Nov 27 23:46:09 2017 +0900 + | + | syntax (tilde expansion): support ordinary words with variable assignment form + | + | @@ -2054,6 +2112,109 @@ function ble-syntax:bash/check-tilde-expansion { + | ((_ble_syntax_attr[i]=ctx,i+=${#BASH_REMATCH})) + | fi + | [中略] + | + + | +## 関数 ble-syntax:bash/check-variable-assignment + | +## @var[in] tail + | +function ble-syntax:bash/check-variable-assignment { + | + ((wbegin==i)) || return 1 + | + + | [中略] + | + + | + # パターン一致 (var= var+= arr[ のどれか) + | + local suffix='=|\+=?' + | + ((_ble_bash<30100)) && suffix='=' + | + if ((ctx==CTX_ARGVI)); then + | + suffix="$suffix|\[?" + | + else + | + suffix="$suffix|\[" + | + fi + | @@ -2577,51 +2760,6 @@ function ble-syntax:bash/ctx-command/.check-word-begin { + | return 0 + | } + | + | -## 関数 ble-syntax:bash/ctx-command/.check-assign + | -## @var[in] tail + | -function ble-syntax:bash/ctx-command/.check-assign { + | - ((wbegin==i)) || return 1 + | - ((ctx==CTX_CMDI||ctx==CTX_ARGVI)) || return 1 + | - + | - # パターン一致 (var= var+= arr[ のどれか) + | - local suffix='=|\+=?' + | - ((_ble_bash<30100)) && suffix='=' + | - if ((ctx==CTX_CMDI)); then + | - suffix="$suffix|\[" + | - elif ((ctx==CTX_ARGVI)); then + | - suffix="$suffix|" + | - fi + |---------------------------------------------------------------------- + | 7d862418 (Koichi Murase 2017-03-01 06:29:55 +0900 2580) ## 関数 ble-syntax:bash/ctx-command/.check-assign + | be5c4616 (Koichi Murase 2015-12-23 22:09:39 +0900 2581) ## @var[in] tail + | 7d862418 (Koichi Murase 2017-03-01 06:29:55 +0900 2582) function ble-syntax:bash/ctx-command/.check-assign { + | be5c4616 (Koichi Murase 2015-12-23 22:09:39 +0900 2583) ((wbegin==i)) || return 1 + | be5c4616 (Koichi Murase 2015-12-23 22:09:39 +0900 2584) ((ctx==CTX_CMDI||ctx==CTX_ARGVI)) || return 1 + | be5c4616 (Koichi Murase 2015-12-23 22:09:39 +0900 2585) + | be5c4616 (Koichi Murase 2015-12-23 22:09:39 +0900 2586) # パターン一致 (var= var+= arr[ のどれか) + | 69bac74a (Koichi Murase 2015-12-24 21:47:15 +0900 2587) local suffix='=|\+=?' + | be5c4616 (Koichi Murase 2015-12-23 22:09:39 +0900 2588) ((_ble_bash<30100)) && suffix='=' + | be5c4616 (Koichi Murase 2015-12-23 22:09:39 +0900 2589) if ((ctx==CTX_CMDI)); then + | be5c4616 (Koichi Murase 2015-12-23 22:09:39 +0900 2590) suffix="$suffix|\[" + | be5c4616 (Koichi Murase 2015-12-23 22:09:39 +0900 2591) elif ((ctx==CTX_ARGVI)); then + | be5c4616 (Koichi Murase 2015-12-23 22:09:39 +0900 2592) suffix="$suffix|" + | be5c4616 (Koichi Murase 2015-12-23 22:09:39 +0900 2593) fi + | + | commit be5c461693ddacd2acf581011c3decd1390641d5 + | Author: Koichi Murase + | Date: Wed Dec 23 22:09:39 2015 +0900 + | + | (ble-syntax:bash): special treatment of arguments of `declare'. + | + | * (ble-syntax:bash): declare, typeset, local, export, alias コマンドの引数を文法的に特別に扱う。特に配列構文 =() を許容する。 + | その為に新しい文脈値 CTX_ARGVX, CTX_ARGVI を追加する。 + | * (ble-syntax:bash): CTX_ARGVI に対する補完候補は変数名。等号 '=' 以降の部分についてはファイル名の補完候補を列挙する。 + | * (ble-syntax:bash): 通常の代入構文における配列構文の動作を変更。 + | [以下略] + | + | +2015-12-23 + | + + | + * ble-syntax:bash declare 配列初期化構文対応 + | + + | + > * [2015-02-16] ble-syntax.sh: local a=(arr) a+= + | + > これは declare や local typeset readonly 等を文法的に特別扱いしなければ対応できない + | + + | + 色々試してみた所、以下のコマンドの引数で =() を特別扱いする様である。 + | + declare readonly typeset local export alias + | + alias に関しては他のコマンドと全然性質が違う様な気がするし、 + | + export に関しては配列の初めの要素しか export されない気がするが、 + | + 文法的には両者とも =() の形式を許容する様である。 + | + 或いは、他にも同様の形式の引数を許容する組コマンドが存在するかもしれない。 + | + + | + (少なくとも echo などの組み込みコマンドや、外部コマンドに関しては + | + 引数に =() 等という物が含まれていると失敗する。) + + これを見る限りは特別扱いは ARGVX, ARGVI を導入した最初の瞬間からあった様で + ある。特に後付で ARGVI に対して特別扱いを実装したという訳ではなく、最初から。 + 実装の経緯を観察する限りはどうも補完で変数名を生成させる為に特別な単語の種 + 類を割り当てている様な気がする。一方で現在の実装に於いては、補完は特に + wtype を参照している訳ではないのでこの様に特別に取り扱う理由もない気がする。 + + * ARGVI, ARGEI の際の変数代入で = を要求しない振る舞いは修正する方向で考え + る。 + + x 然し、そうしたら単語着色が消えてしまった。うーん。ARGVI 及び ARGEI の時に + は単語着色はするべきだろうか。 + + 先ず文法レベルで。それから引数レベルで。 + + | うーん。先ず初めに、文法レベルでの着色については ARGVI だけで良い。 + | ARGEI の時には = 無しで単語が現れたとしたらそれは単語ではないので着色し + | なくて良い。 + | + | そもそも文法レベルの着色をするべきなのかという疑問も実は存在する。bash + | の文法的には実は declare hello= は変数代入になっているが、declare hello + | は変数代入になっていないと思われる。という事を考えると文法レベルの着色 + | はするべきでない。 + + 引数レベルの着色については declare 系列専用の着色を定義する必要がある。 + + うーん。ble/cmdinfo/color: という名前も何だか微妙な気がするが、これは後 + でいくらでも変更できるので取り敢えずは実装する。既存の実装は存在してい + ない様だ。ble/cmdinfo/chroma: に変更する。 + + うーん。ファイルを分離しようと思ったが名前はどうしたら良いだろうか + ... やはり cmdinfo は何だか名前として不自然な気がする。core-cmdinfo, + + | * core-help, core-man, core-mandb, core-info, core-whatis, core-which, + | これらは既存のマニュアル系のコマンドの名称を取ってきた物。 + | + | * core-catalogue, core-manual, core-dictionary, core-book, + | corer-guidebook, core-map, core-cmdmap, core-reference, + | core-commandreference, core-cmdref (reference 系は別の意味になるので + | 駄目), core-library, core-cmdlib, core-spelllib (library 系も別の意味), + | core-spellbook ... 或いはより現実的な物に例えてみる等の方針。 + | + | * core-getopt これは、実際に cmdinfo を定義する主要な形態として getopt + | 的な方法を考えている事から。然し、これだけが唯一の定義方法という訳で + | もないし、getopt は更にその上の階層の枠組みに名付けたい気がする。実際 + | には、cmdinfo の中に定義する形になるのではないかと考えている。 + | + | * core-cmddb, core-database (一般的過ぎる), core-commanddatabase, + | core-cmdspec, core-commandspec, core-cmdspec + + うーん。cmdspec の方が幾らかましの気がするので取り敢えず cmdspec という + 事にする。 + + 然し本当に cmdspec に定義するべきなのだろうかという疑問も残る。実は + bash-completion でやっている様に contrib/cmdspec/* の下に個別のファイル + として定義した方が良いのではないかという疑惑。うーん。然しそうだとして + も取り敢えずの実験的な実装として cmdspec の中に色々記述して API が落ち + 着いてからファイルに分割するというので良い気がする。そう。それがしたかっ + た事の気がする。 + + o ちゃんと引数レベルでの着色で変数名着色ができている。 + + o declare の通常引数の後のオプションをエラー着色する機能もOK + + * done: コマンドレベルで declare, etc. + alias の着色を行う。 + うーん。alias については今回は対応しなくて良い。 + + * done: 変数代入も extract-command で列挙する。但し、extract command に影響 + がない様にしなければならない。 + + x fixed: もう一つの謎は a=b declare a= の形式の時には変数代入が検出されない + という事。そもそも、変数名着色だって無効化されている。これは一体どういう + 事だろう + + 調べてみると "a=b declare@ " の時には @ の位置に stat ARGX が置かれている + 様である。一方で、 "declare@ " の場合には @ の位置には stat は置かれてい + なくて、代わりにその次の位置に ARGVX が置かれている。この振る舞いは他の通 + 常コマンド (echo など) でも同様であった。CMDXV の特別な振る舞いという事な + のだろうか。 + + →うーん。正にそれを実行するコードが check-word-end にある。これはどうい + う事だろうか。→分かった。どうもこれは変数代入の直後にはキーワードは来な + いという事を養成する為のコードの様だ。昔は単に ctx=ARGX を設定して抜けれ + ば良かったが、その後の複雑化で只単に ARGX を設定すれば良いという訳ではな + くなった。各文脈に応じた複雑な処理を CMDXV の時にも実行する必要がある。 + + o ok: declare a -[TAB] での候補生成の抑制は動いている。 + + 幾つか残っているのを修正する必要がある。 + + * ok: global -- が着色されていない。これは今確認したらちゃんと動いている。 + 勘違いだったか或いは別の物を修正した時に一緒に直ったか。 + + * done: blerc, wiki, 移動: argument_error + + * done: ble/syntax/progcolor は最早 ble/progcolor で良いのではないか。そも + そも純粋な文法解釈から離れてきていて、bash 特有の実装になっている。 + 2021-12-11 + * [External] bash-completion: printf -v ... [#D1703] + https://github.com/akinomyoga/ble.sh/issues/155#issuecomment-984619516 + + これは bash-completion 側で対応するべき事の気がする。 + + 取り敢えず --help 対応が終われば、変数名の補完はできないにしても、オプショ + ンの表示ぐらいはできる様になる。printf の場合には最初の引数には '' を指定す + るのが良い気がする → 取り敢えずオプションは表示される様になった。 + + * [External] bash-completion: better support for "test", "[" [#D1702] + https://github.com/akinomyoga/ble.sh/issues/158 + + これも bash-completion の側で対応するべき事の気がする。 + 但しオプションの説明についてはちゃんと生成しなければならない。 + progcomp の枠組みで説明も一緒に生成できる仕組みがあっても良いのではないか。 + + うーん。生成し切れていない物は別枠で指定する? うーん。getoptions 的仕様を確 + 定する必要がある気がする。 + * complete: [[ 及び declare の補完 (requested by EmilySeville7cfg) [#D1701] https://github.com/akinomyoga/ble.sh/issues/155 https://github.com/akinomyoga/ble.sh/issues/157 diff --git a/src/color.sh b/src/color.sh index 0ecf10de..83af739a 100644 --- a/src/color.sh +++ b/src/color.sh @@ -516,7 +516,7 @@ function ble/color/.name2color { (teal) ret=6 ;; (silver) ret=7 ;; - (gray) ret=8 ;; + (gr[ae]y) ret=8 ;; (red) ret=9 ;; (lime) ret=10 ;; (yellow) ret=11 ;; diff --git a/src/util.sh b/src/util.sh index 22f41f9d..9f289f19 100644 --- a/src/util.sh +++ b/src/util.sh @@ -1393,23 +1393,39 @@ function ble/path#contains { builtin eval "[[ :\${$1}: == *:\"\$2\":* ]]" } -## @fn ble/opts#extract-first-optarg key opts +## @fn ble/opts#extract-first-optarg key opts [default_value] function ble/opts#extract-first-optarg { ret=() local rex=':'$1'(=[^:]*)?:' [[ :$2: =~ $rex ]] || return 1 - [[ ${BASH_REMATCH[1]} ]] && ret=${BASH_REMATCH[1]:1} + if [[ ${BASH_REMATCH[1]} ]]; then + ret=${BASH_REMATCH[1]:1} + elif [[ ${3+set} ]]; then + ret=$3 + fi return 0 } -## @fn ble/opts#extract-last-optarg key opts +## @fn ble/opts#extract-last-optarg key opts [default_value] function ble/opts#extract-last-optarg { ret=() local rex='.*:'$1'(=[^:]*)?:' [[ :$2: =~ $rex ]] || return 1 - [[ ${BASH_REMATCH[1]} ]] && ret=${BASH_REMATCH[1]:1} + if [[ ${BASH_REMATCH[1]} ]]; then + ret=${BASH_REMATCH[1]:1} + elif [[ ${3+set} ]]; then + ret=$3 + fi return 0 } ## @fn ble/opts#extract-all-optargs key opts [default_value] +## extract all values from the string OPTS of the form +## "...:key=value1:...:key=value2:...:key:...". +## +## @param[in] key +## This should not include any special characters of regular +## expressions---preferably composed of [-_[:alnum:]]. +## +## @arr[out] ret function ble/opts#extract-all-optargs { ret=() local value=:$2: rex=':'$1'(=[^:]*)?(:.*)$' count=0 @@ -2882,13 +2898,14 @@ function ble/util/type { } ## @fn ble/util/expand-alias word ## @var[out] ret +## @exit +## エイリアス展開が実際に行われた時に成功します。 function ble/util/expand-alias { ret=$1 local type; ble/util/type type "$ret" - if [[ $type == alias ]]; then - local data; ble/util/assign data 'LC_ALL=C alias "$ret"' &>/dev/null - [[ $data == 'alias '*=* ]] && builtin eval "ret=${data#alias *=}" - fi + [[ $type != alias ]] && return 1 + local data; ble/util/assign data 'LC_ALL=C alias "$ret"' &>/dev/null + [[ $data == 'alias '*=* ]] && builtin eval "ret=${data#alias *=}" } if ((_ble_bash>=40000)); then