From 6ca0b8c96f220472b661e6f163288e6005c87461 Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Sat, 20 Feb 2021 15:47:23 +0800 Subject: [PATCH] term: support Solaris console --- lib/init-cmap.sh | 25 +++- lib/init-term.sh | 17 ++- memo/ChangeLog.md | 5 + note.txt | 127 +++++++++++++++++++++ src/canvas.sh | 40 +++++-- src/decode.sh | 24 ++-- src/edit.sh | 12 +- src/util.sh | 282 ++++++++++++++++++++++++---------------------- 8 files changed, 370 insertions(+), 162 deletions(-) diff --git a/lib/init-cmap.sh b/lib/init-cmap.sh index d88a864a..8a6d27a3 100644 --- a/lib/init-cmap.sh +++ b/lib/init-cmap.sh @@ -133,7 +133,7 @@ function ble/init:cmap/initialize { ble-bind --csi '7~' home ble-bind --csi '8~' end local kdch1; ble/util/assign kdch1 'tput kD 2>/dev/null || tput kdch1 2>/dev/null' - [[ $kdch1 == $'\x7F' ]] && ble-bind -k 'DEL' delete + [[ $kdch1 == $'\x7F' || $TERM == sun* ]] && ble-bind -k 'DEL' delete # vt220, xterm, rxvt ble-bind --csi '11~' f1 @@ -240,6 +240,29 @@ function ble/init:cmap/initialize { ble/init:cmap/bind-single-csi '[ D' f4 ble/init:cmap/bind-single-csi '[ E' f5 + # sun specific (Solaris) + ble/init:cmap/bind-single-csi '2 4 7 z' insert + ble/init:cmap/bind-single-csi '2 1 4 z' home + ble/init:cmap/bind-single-csi '2 2 0 z' end + ble/init:cmap/bind-single-csi '2 2 2 z' prior + ble/init:cmap/bind-single-csi '2 1 6 z' next + ble/init:cmap/bind-single-csi '2 2 4 z' f1 + ble/init:cmap/bind-single-csi '2 2 5 z' f2 + ble/init:cmap/bind-single-csi '2 2 6 z' f3 + ble/init:cmap/bind-single-csi '2 2 7 z' f4 + ble/init:cmap/bind-single-csi '2 2 8 z' f5 + ble/init:cmap/bind-single-csi '2 2 9 z' f6 + ble/init:cmap/bind-single-csi '2 3 0 z' f7 + ble/init:cmap/bind-single-csi '2 3 1 z' f8 + ble/init:cmap/bind-single-csi '2 3 2 z' f9 + ble/init:cmap/bind-single-csi '2 3 3 z' f10 + ble/init:cmap/bind-single-csi '2 3 4 z' f11 + ble/init:cmap/bind-single-csi '2 3 5 z' f12 + # ble/init:cmap/bind-single-csi '2 z' insert # terminfo + # ble/init:cmap/bind-single-csi '3 z' delete # terminfo + # ble/init:cmap/bind-single-csi '1 9 2 z' f11 + # ble/init:cmap/bind-single-csi '1 9 3 z' f12 + # 修飾キー 'CAN @ ?' # # 取り敢えず CAN で始まる修飾キーは無効にしておく。何故なら、 diff --git a/lib/init-term.sh b/lib/init-term.sh index e86ee604..17ff4297 100644 --- a/lib/init-term.sh +++ b/lib/init-term.sh @@ -77,7 +77,8 @@ function ble/init:term/initialize { _ble_term_xenl=1 [[ $_ble_term_tput ]] && ! ble/init:term/tput xenl:xn &>/dev/null && - _ble_term_xenl=0 + _ble_term_xenl= + [[ $TERM == sun* ]] && _ble_term_xenl= ble/init:term/register-varname _ble_term_xenl # bce (background color erase) @@ -96,9 +97,9 @@ function ble/init:term/initialize { ble/init:term/register-varname _ble_term_it # IND/RI, CR, LF, FS - ble/init:term/define-cap.2 _ble_term_ind $'\eD' ind:sf - ble/init:term/define-cap _ble_term_ri $'\eM' ri:sr - ble/init:term/define-cap _ble_term_cr $'\r' cr:cr + ble/init:term/define-cap.2 _ble_term_ind $'\n' ind:sf # $'\eD' + ble/init:term/define-cap _ble_term_ri '' ri:sr # $'\eM' + ble/init:term/define-cap _ble_term_cr $'\r' cr:cr if [[ $OSTYPE == msys && ! $_ble_term_CR ]]; then # msys-1.0 [[ $_ble_term_cr ]] || _ble_term_cr=$'\e[G' if [[ $TERM == cygwin ]]; then @@ -118,6 +119,9 @@ function ble/init:term/initialize { _ble_term_cub=${_ble_term_cub//123/%d} # ※もし 122 だとか 124 だとかになると上記では駄目 + _ble_term_ri_or_cuu1=${_ble_term_ri:-${_ble_term_cuu//'%d'/1}} + ble/init:term/register-varname _ble_term_ri_or_cuu1 + # CUP ble/init:term/define-cap _ble_term_cup $'\e[13;35H' cup:cm 12 34 _ble_term_cup=${_ble_term_cup//13/%l} @@ -165,9 +169,10 @@ function ble/init:term/initialize { _ble_term_ech=${_ble_term_ech//123/%d} # DECSC/DECRC or SCOSC/SCORC - ble/init:term/define-cap _ble_term_sc $'\e[s' sc:sc - ble/init:term/define-cap _ble_term_rc $'\e[u' rc:rc + ble/init:term/define-cap _ble_term_sc $'\e7' sc:sc # \e[s + ble/init:term/define-cap _ble_term_rc $'\e8' rc:rc # \e[u [[ $TERM == minix ]] && _ble_term_sc= _ble_term_rc= + # Note: TERM=sun{,-color}: terminfo にはないが \e7 \e8 が使える。 # Cursors ble/init:term/define-cap _ble_term_Ss '' Ss:Ss 123 # DECSCUSR diff --git a/memo/ChangeLog.md b/memo/ChangeLog.md index 6299df22..717bac50 100644 --- a/memo/ChangeLog.md +++ b/memo/ChangeLog.md @@ -56,6 +56,11 @@ - mandb: improve extraction and cache for each locale `#D1480` 3588158 - decode (rlfunc): work around incomplete bytes in keyseq (reported by onelittlehope) `#D1483` 3559658 beb0383 0000000 +## Compatibility + +- term: work around quirks of Solaris xpg4 awk `#D1481` 0000000 +- term: support key sequences and control sequences of Solaris console `#D1481` 0000000 + ## Internal changes and fixes - main: include hostname in local runtime directory `#D1444` 6494836 diff --git a/note.txt b/note.txt index cc7e51e6..77ab315f 100644 --- a/note.txt +++ b/note.txt @@ -3811,6 +3811,133 @@ bash_tips 2021-02-20 + * term: sum (Solaris console) IND/RI が使えない。他色々動いていない [#D1481] + + * RI が使えない時にどの様にすれば良いか。 + + * 使っている箇所の一つは vbell である。 + + 例えば prompt の上の行に一行 IL するという方針だと…。vbell を表示する度 + にずれてしまう。今ここで欲しいのは "上に一行も余裕がない時限定で一行確保 + する" という機能である。 + + * ble/canvas/put-ri.draw + + これは2箇所から使われている。両方とも + ble/canvas/panel/ensure-tmargin.draw という関数の中から使われていて、この + 関数は vbell から使う為の物である。 + + * ble/canvas/panel#clear-after.draw + これは単に cuu に置き換えれば良い気がする→置き換えた。 + + 結局 vbell が問題になる。_ble_term_ri が空の時に別の手法で vbell を表示す + る? + + a 例えば xterm_title を使って表示するか。 + + 元から設定されている値を保存・復元したりするのが面倒である。push/pop の + エスケープシーケンスも存在するかもしれないが、それに対応しているかどう + かの判定も面倒である。というより RI を対応していない端末が xterm title + 等に対応しているとは思えない。この手法は追求しても余り意味がない。 + + b 或いは、一番下の行に表示するというのは可能だろうか。 + + この方法を取る場合には現在の canvas の tmargin の取り扱いを工夫しなけれ + ばならない。というか RI が使えない場合には canvas の tmargin も振る舞い + が微妙な気がする。 + + c もしくは _ble_term_ri を使わずに被っても良いので先頭行を使う。 + + 然し、やはり内容が上書きされてしまうというのは都合が悪い様に思われる。 + + d もしくは毎回一番上に行を挿入する。 + + この方法だと bell が表示される度に行がどんどん下の方に移動してしまって + 余り嬉しい事にはならない。一応 IND を使って下に行きすぎない様に調整する + 事はできる。top/bottom dock に分かれている場合には制御が面倒である。 + + 現在の ble/canvas/panel/ensure-tmargin.draw の実装について確認する。 + DECSTBM が存在する場合には、スクロール領域を設定して bottom dock を固定する。 + その上で RI を実行して canvas 原点の上に tmargin 行だけスペースを確保する。 + + それ以外の場合には即座に RI で canvas 原点の上にスペースを確保する。 + bottom に関しては破壊されてしまうのは我慢して invalidate する。 + + さて、RI が使えない場合にどの様に内容をシフトするのか。場合分けして考え + る。DECSTBM が使える場合にはやはり bottom dock を固定して於いて、その上 + で、top_height+tmargin だけ IND を実行する。これで少なくとも top dock + の下に tmargin だけのスペースができる。その後で IL を一番上で実行すれば + 良い。 + + うーん。完全ではないが d の方針で何とか誤魔化す事にした。 + + * done: modifyOtherkeys がそのまま出力される。 + + これは linux や minix と同様に出力しない様に変更。 + + * done: home csi 214 z / end csi 210 z + + これは contra の escseq.html にまとめてある物に一致する気がするので確認する。 + + * done: OSC がそのまま出力されている + + 面倒なので xterm_title の所で直接 term の判定を行って切り替える。 + OSC を無視できるかどうかを各 OS のコンソールで確認する。 + freebsd, linux, haiku ではちゃんと無視できている。 + minix 及び sun は失敗している。 + + * prompt_eol_mark 関連のカーソル移動に使われているシーケンスにも問題のある + 物がある。_ble_term_sc, _ble_term_rc の既定値が \e[s, \e[u になっていたが、 + これらは寧ろ少数派なので \e7, \e8 に切り替える事にした。Solaris では + terminfo に \e7, \e8 は載っていないが実際には使える。 + + また _ble_term_xenl に関しても terminfo になかった事から既定で 1 になって + いたが、Solaris では 0 にする必要がある。修正した。序でに xenl がない時に + は 0 ではなくて空文字列にする事にする。 + + x ok: RI がない時の vbell の振る舞いが駄目。再度実装を確認する。 + うーん。幾らか修正して、更に必要な時にだけ高さを確保する様に変更した。 + + そもそも sun console は下から出ていくと上に戻るという変な振る舞いをするの + でまともに対応するのが難しい。適当な所で良しとするのが良い。 + + * done: delete キーで ^? (DEL) が送信される。これについては TERM=sun* の時 + に ^? を delete に変換して対策する事にした。実は既に infocmp kdch1 が ^? + の時にはこの対策が実施されていたが、sun* の terminfo に kdch1 が登録され + ていなかったのが原因だった。 + + x 文字 x が入力できない。emacs にするとちゃんと入力できる。.blerc を別名に + すると入力できる。と思ったがこれは set -o vi が実行されなくなるからだった。 + 更に時々 segfault もする。またランダムな文字列を実行しようともする。 + + これは恐らく "x?" で bind が形成されてその後でそれが削除される事により、 + x 単体の入力に対して出鱈目な文字列が実行されているという事なのだろう。 + では誰が x に bind しているのだろうか。。不思議である。 + + うーん。inputrc は存在していないし、bind は特に直接呼び出されてはいない様 + だし、という事を考えると ble.sh で呼び出している builtin bind が問題を起 + こしているという事なのだろうか。 + + generate-source-to-unbind-default の出力を保存してそれを読ませてみたら + 問題が発生するという事が分かった。特に問題のある行もない…と思いきや、 + + builtin bind -r 'x1c' (bash-4.1) + + という変な行が混入している。これは一体何処から出てきた物だろうか。普通に + 動いている環境で実行してみると + + builtin bind -r '\x1c' (bash-4.4) + + という結果になっている。つまり、これは bash-4.1 特有の処置ではなくて一般 + に行われている処置である。 + + 問題の箇所を確認してみると awk で sub(/.../, "\"\\x1c\"") としている。 + つまり Solaris awk はこの \\ を消してしまうという事。と思っていたら、 + 既にその問題点についてコメントに書かれていた。'\'' に対しては対策されていたが、 + 直接 \ が現れる場合については対策されていなかったのが原因。 + 特に \x の組み合わせが x に変換されてしまうという問題の様である。 + \x についても対応すると共にコードの整理を行った。 + * complete/mabdb: man awk の内容を抽出しきれていない [#D1480] 先ず .PD という行が挿入されている事が原因の様である。 diff --git a/src/canvas.sh b/src/canvas.sh index 63f9f22e..b7a3280b 100644 --- a/src/canvas.sh +++ b/src/canvas.sh @@ -368,12 +368,12 @@ function ble/canvas/put.draw { } function ble/canvas/put-ind.draw { local count=${1-1} - local ret; ble/string#repeat "${_ble_term_ind}" "$count" + local ret; ble/string#repeat "$_ble_term_ind" "$count" DRAW_BUFF[${#DRAW_BUFF[*]}]=$ret } function ble/canvas/put-ri.draw { local count=${1-1} - local ret; ble/string#repeat "${_ble_term_ri}" "$count" + local ret; ble/string#repeat "$_ble_term_ri" "$count" DRAW_BUFF[${#DRAW_BUFF[*]}]=$ret } function ble/canvas/put-il.draw { @@ -2119,7 +2119,7 @@ function ble/canvas/panel#clear-after.draw { ble/canvas/put.draw "$_ble_term_ind" ble/canvas/put-dl.draw "$rest_lines" ble/canvas/put-il.draw "$rest_lines" - ble/canvas/put.draw "$_ble_term_ri" + ble/canvas/put-cuu.draw 1 fi } @@ -2180,8 +2180,18 @@ function ble/canvas/panel/ensure-tmargin.draw { ble/canvas/put.draw $'\e[1;'$((LINES-bottom_height))'r' ble/canvas/excursion-end.draw ble/canvas/goto.draw 0 0 - ble/canvas/put-ri.draw "$tmargin" - ble/canvas/put-cud.draw "$tmargin" + if [[ $_ble_term_ri ]]; then + ble/canvas/put-ri.draw "$tmargin" + ble/canvas/put-cud.draw "$tmargin" + else + # RI がない時 + ble/canvas/put-ind.draw $((top_height-1+tmargin)) + ble/canvas/put-cuu.draw $((top_height-1+tmargin)) + ble/canvas/excursion-start.draw + ble/canvas/put-cup.draw 1 1 + ble/canvas/put-il.draw "$tmargin" + ble/canvas/excursion-end.draw + fi ble/canvas/excursion-start.draw ble/canvas/put.draw $'\e[;r' ble/canvas/excursion-end.draw @@ -2193,7 +2203,23 @@ function ble/canvas/panel/ensure-tmargin.draw { fi ble/canvas/goto.draw 0 0 - ble/canvas/put-ri.draw "$tmargin" - ble/canvas/put-cud.draw "$tmargin" + if [[ $_ble_term_ri ]]; then + ble/canvas/put-ri.draw "$tmargin" + ble/canvas/put-cud.draw "$tmargin" + else + # RI がない時 + local total_height=$((top_height+bottom_height)) + ble/canvas/put-ind.draw $((total_height-1+tmargin)) + ble/canvas/put-cuu.draw $((total_height-1+tmargin)) + if [[ $_ble_term_rc ]]; then + ble/canvas/excursion-start.draw + ble/canvas/put-cup.draw 1 1 + ble/canvas/put-il.draw "$tmargin" + ble/canvas/excursion-end.draw + else + ble/canvas/put-il.draw "$tmargin" + fi + ble/canvas/put-cud.draw "$tmargin" + fi ble/canvas/panel/load-position.draw "$pos" } diff --git a/src/decode.sh b/src/decode.sh index 1566d414..42262995 100644 --- a/src/decode.sh +++ b/src/decode.sh @@ -2638,18 +2638,24 @@ function ble/decode/bind/.generate-source-to-unbind-default { } 2>/dev/null function ble/decode/bind/.generate-source-to-unbind-default/.process { # Note: #D1355 LC_ALL 切り替えに伴うエラーメッセージは呼び出し元で /dev/null に繋いでいる。 - local q=\' b=\\ Q="'\''" + local q=\' Q="'\''" is_xpg4=0 # Note: Solaris xpg4 awk では gsub の置換後のエスケープシーケンスも処理される - [[ $_ble_bin_awk_solaris_xpg4 == yes ]] && Q="'$b$b''" - local QUOT_Q=\"${Q//"$b"/$b$b}\" - LC_ALL=C ble/bin/awk -v q="$q" ' + [[ $_ble_bin_awk_solaris_xpg4 == yes ]] && is_xpg4=1 + LC_ALL=C ble/bin/awk -v q="$q" -v is_xpg4="$is_xpg4" ' + function str2rep(str) { + if (is_xpg4) sub(/\\/, "\\\\\\\\", str); + return str; + } BEGIN { - Q = '"$QUOT_Q"'; + rep_Q = str2rep(q "\\" q q); + rep_bslash = str2rep("\\"); + rep_kseq_1c5c = str2rep("\"\\x1c\\x5c\""); + rep_kseq_1c = str2rep("\"\\x1c\""); mode = 1; } function quote(text) { - gsub(q, Q, text); + gsub(q, rep_Q, text); return q text q; } @@ -2673,7 +2679,7 @@ function ble/decode/bind/.generate-source-to-unbind-default/.process { str = unescape_control_modifier(str); gsub(/\\e/, sprintf("%c", 27), str); gsub(/\\"/, "\"", str); - gsub(/\\\\/, "\\", str); + gsub(/\\\\/, rep_bslash, str); return str; } @@ -2694,8 +2700,8 @@ function ble/decode/bind/.generate-source-to-unbind-default/.process { mode == 1 && $0 ~ /^"/ { # Workaround Bash-5.0 bug (cf #D1078) - sub(/^"\\C-\\\\\\"/, "\"\\x1c\\x5c\""); - sub(/^"\\C-\\\\?"/, "\"\\x1c\""); + sub(/^"\\C-\\\\\\"/, rep_kseq_1c5c); + sub(/^"\\C-\\\\?"/, rep_kseq_1c); output_bindr($0); diff --git a/src/edit.sh b/src/edit.sh index 18b8fe00..e8eb09d3 100644 --- a/src/edit.sh +++ b/src/edit.sh @@ -1061,10 +1061,14 @@ function ble/prompt/update { fi # bleopt prompt_xterm_title - local ret - ble/prompt/.instantiate-control-string _ble_prompt_xterm_title "$bleopt_prompt_xterm_title" - [[ $ret ]] && ret=$'\e]0;'$ret$'\a' - _ble_prompt_xterm_title[6]=$ret + case ${_ble_term_TERM:-$TERM} in + (sun*|minix) ;; # black list + (*) + local ret + ble/prompt/.instantiate-control-string _ble_prompt_xterm_title "$bleopt_prompt_xterm_title" + [[ $ret ]] && ret=$'\e]0;'$ret$'\a' + _ble_prompt_xterm_title[6]=$ret ;; + esac # bleopt prompt_screen_title case ${_ble_term_TERM:-$TERM} in diff --git a/src/util.sh b/src/util.sh index cacc71fc..877e7c58 100644 --- a/src/util.sh +++ b/src/util.sh @@ -4158,25 +4158,131 @@ function ble/term/audible-bell { # # 前回の表示内容は以下の配列に格納する。 # -# @arr _ble_term_visible_bell_prev=(message [x0 y0 x y]) +# @arr _ble_term_visible_bell_prev=(vbell_type message [x0 y0 x y]) +_ble_term_visible_bell_prev=() _ble_term_visible_bell_ftime=$_ble_base_run/$$.visible-bell.time + _ble_term_visible_bell_show='%message%' _ble_term_visible_bell_clear= -function ble/term/visible-bell/.initialize { - local -a BUFF=() - ble/term/put "$_ble_term_ri$_ble_term_sc$_ble_term_sgr0" - ble/term/cup 0 0 - ble/term/put "$_ble_term_el%message%$_ble_term_sgr0$_ble_term_rc${_ble_term_cud//'%d'/1}" - IFS= builtin eval '_ble_term_visible_bell_show="${BUFF[*]}"' +function ble/term/visible-bell:term/init { + if [[ ! $_ble_term_visible_bell_clear ]]; then + local -a BUFF=() + ble/term/put "$_ble_term_ri_or_cuu1$_ble_term_sc$_ble_term_sgr0" + ble/term/cup 0 0 + ble/term/put "$_ble_term_el%message%$_ble_term_sgr0$_ble_term_rc${_ble_term_cud//'%d'/1}" + IFS= builtin eval '_ble_term_visible_bell_show="${BUFF[*]}"' + + BUFF=() + ble/term/put "$_ble_term_sc$_ble_term_sgr0" + ble/term/cup 0 0 + ble/term/put "$_ble_term_el2$_ble_term_rc" + IFS= builtin eval '_ble_term_visible_bell_clear="${BUFF[*]}"' + fi - BUFF=() - ble/term/put "$_ble_term_sc$_ble_term_sgr0" - ble/term/cup 0 0 - ble/term/put "$_ble_term_el2$_ble_term_rc" - IFS= builtin eval '_ble_term_visible_bell_clear="${BUFF[*]}"' + # 一行に収まる様に切り詰める + local cols=${COLUMNS:-80} + ((_ble_term_xenl||cols--)) + local message=${1::cols} + _ble_term_visible_bell_prev=(term "$message") +} +function ble/term/visible-bell:term/show { + local sgr=$1 message=${_ble_term_visible_bell_prev[1]} + ble/util/put "${_ble_term_visible_bell_show//'%message%'/$sgr$message}" >&2 +} +function ble/term/visible-bell:term/update { + ble/term/visible-bell:term/show "$@" +} +function ble/term/visible-bell:term/clear { + local sgr=$1 + ble/util/put "$_ble_term_visible_bell_clear" >&2 +} + +function ble/term/visible-bell:canvas/init { + local message=$1 + + local lines=1 cols=${COLUMNS:-80} + ((_ble_term_xenl||cols--)) + local x= y= + local ret sgr0= sgr1= + ble/canvas/trace-text "$message" nonewline:external-sgr + message=$ret + + local x0=0 y0=0 + if [[ $bleopt_vbell_align == right ]]; then + ((x0=COLUMNS-1-x,x0<0&&(x0=0))) + elif [[ $bleopt_vbell_align == center ]]; then + ((x0=(COLUMNS-1-x)/2,x0<0&&(x0=0))) + fi + + _ble_term_visible_bell_prev=(canvas "$message" "$x0" "$y0" "$x" "$y") +} +function ble/term/visible-bell:canvas/show { + local sgr=$1 opts=$2 + local message=${_ble_term_visible_bell_prev[1]} + local x0=${_ble_term_visible_bell_prev[2]} + local y0=${_ble_term_visible_bell_prev[3]} + local x=${_ble_term_visible_bell_prev[4]} + local y=${_ble_term_visible_bell_prev[5]} + + local -a DRAW_BUFF=() + [[ $_ble_attached ]] && + [[ $_ble_term_ri || :$opts: != *:erased:* && :$opts: != *:update:* ]] && + ble/canvas/panel/ensure-tmargin.draw + if [[ $_ble_term_rc ]]; then + local ret= + [[ $_ble_attached ]] && ble/canvas/panel/save-position goto-top-dock + ble/canvas/put.draw "$_ble_term_ri_or_cuu1$_ble_term_sc$_ble_term_sgr0" + ble/canvas/put-cup.draw $((y0+1)) $((x0+1)) + ble/canvas/put.draw "$sgr$message$_ble_term_sgr0" + ble/canvas/put.draw "$_ble_term_rc" + ble/canvas/put-cud.draw 1 + [[ $_ble_attached ]] && ble/canvas/panel/load-position.draw "$ret" + else + ble/canvas/put.draw "$_ble_term_ri_or_cuu1$_ble_term_sgr0" + ble/canvas/put-hpa.draw $((1+x0)) + ble/canvas/put.draw "$sgr$message$_ble_term_sgr0" + ble/canvas/put-cud.draw 1 + ble/canvas/put-hpa.draw $((1+_ble_canvas_x)) + fi + ble/canvas/bflush.draw + ble/util/buffer.flush >&2 +} +function ble/term/visible-bell:canvas/update { + ble/term/visible-bell:canvas/show "$@" +} +function ble/term/visible-bell:canvas/clear { + local sgr=$1 + local x0=${_ble_term_visible_bell_prev[2]} + local y0=${_ble_term_visible_bell_prev[3]} + local x=${_ble_term_visible_bell_prev[4]} + local y=${_ble_term_visible_bell_prev[5]} + + local -a DRAW_BUFF=() + if [[ $_ble_term_rc ]]; then + local ret= + [[ $_ble_attached ]] && ble/canvas/panel/save-position goto-top-dock + ble/canvas/put.draw "$_ble_term_sc$_ble_term_sgr0" + ble/canvas/put-cup.draw $((y0+1)) $((x0+1)) + ble/canvas/put.draw "$sgr" + ble/canvas/put-spaces.draw "$x" + #ble/canvas/put-ech.draw "$x" + #ble/canvas/put.draw "$_ble_term_el" + ble/canvas/put.draw "$_ble_term_sgr0$_ble_term_rc" + [[ $_ble_attached ]] && ble/canvas/panel/load-position.draw "$ret" + else + : # 親プロセスの _ble_canvas_x が分からないので座標がずれる + # ble/util/buffer.flush >&2 + # ble/canvas/put.draw "$_ble_term_ri_or_cuu1$_ble_term_sgr0" + # ble/canvas/put-hpa.draw $((1+x0)) + # ble/canvas/put.draw "$sgr" + # ble/canvas/put-spaces.draw "$x" + # ble/canvas/put.draw "$_ble_term_sgr0" + # ble/canvas/put-cud.draw 1 + # ble/canvas/put-hpa.draw $((1+_ble_canvas_x)) # 親プロセスの _ble_canvas_x? + fi + ble/canvas/flush.draw >&2 } -ble/term/visible-bell/.initialize function ble/term/visible-bell/defface.hook { ble/color/defface vbell reverse @@ -4185,114 +4291,20 @@ function ble/term/visible-bell/defface.hook { } blehook color_init_defface+=ble/term/visible-bell/defface.hook -_ble_term_visible_bell_prev=() function ble/term/visible-bell/.show { - local message=$1 sgr=$2 x=$3 y=$4 - if [[ $opt_canvas ]]; then - local x0=0 y0=0 - if [[ $bleopt_vbell_align == right ]]; then - ((x0=COLUMNS-1-x,x0<0&&(x0=0))) - elif [[ $bleopt_vbell_align == center ]]; then - ((x0=(COLUMNS-1-x)/2,x0<0&&(x0=0))) - fi - - local -a DRAW_BUFF=() - [[ $_ble_attached ]] && ble/canvas/panel/ensure-tmargin.draw - if [[ $_ble_term_rc ]]; then - local ret= - [[ $_ble_attached ]] && ble/canvas/panel/save-position goto-top-dock - ble/canvas/put.draw "$_ble_term_ri$_ble_term_sc$_ble_term_sgr0" - ble/canvas/put-cup.draw $((y0+1)) $((x0+1)) - ble/canvas/put.draw "$sgr$message$_ble_term_sgr0" - ble/canvas/put.draw "$_ble_term_rc" - ble/canvas/put-cud.draw 1 - [[ $_ble_attached ]] && ble/canvas/panel/load-position.draw "$ret" - else - ble/canvas/put.draw "$_ble_term_ri$_ble_term_sgr0" - ble/canvas/put-hpa.draw $((1+x0)) - ble/canvas/put.draw "$sgr$message$_ble_term_sgr0" - ble/canvas/put-cud.draw 1 - ble/canvas/put-hpa.draw $((1+_ble_canvas_x)) - fi - ble/canvas/bflush.draw - ble/util/buffer.flush >&2 - _ble_term_visible_bell_prev=("$message" "$x0" "$y0" "$x" "$y") - else - ble/util/put "${_ble_term_visible_bell_show//'%message%'/$message}" - _ble_term_visible_bell_prev=("$message") - fi -} >&2 + local bell_type=${_ble_term_visible_bell_prev[0]} + ble/term/visible-bell:"$bell_type"/show "$@" +} function ble/term/visible-bell/.update { - local sgr=$1 - local message=${_ble_term_visible_bell_prev[0]} - if ((${#_ble_term_visible_bell_prev[@]}==5)); then - local x0=${_ble_term_visible_bell_prev[1]} - local y0=${_ble_term_visible_bell_prev[2]} - local x=${_ble_term_visible_bell_prev[3]} - local y=${_ble_term_visible_bell_prev[4]} - - local -a DRAW_BUFF=() - [[ $_ble_attached ]] && ble/canvas/panel/ensure-tmargin.draw - if [[ $_ble_term_rc ]]; then - local ret= - [[ $_ble_attached ]] && ble/canvas/panel/save-position goto-top-dock - ble/canvas/put.draw "$_ble_term_ri$_ble_term_sc$_ble_term_sgr0" - ble/canvas/put-cup.draw $((y0+1)) $((x0+1)) - ble/canvas/put.draw "$sgr$message$_ble_term_sgr0" - ble/canvas/put.draw "$_ble_term_rc" - ble/canvas/put-cud.draw 1 - [[ $_ble_attached ]] && ble/canvas/panel/load-position.draw "$ret" - else - ble/canvas/put.draw "$_ble_term_ri$_ble_term_sgr0" - ble/canvas/put-hpa.draw $((1+x0)) - ble/canvas/put.draw "$sgr$message$_ble_term_sgr0" - ble/canvas/put-cud.draw 1 - ble/canvas/put-hpa.draw $((1+_ble_canvas_x)) - fi - ble/canvas/bflush.draw - ble/util/buffer.flush >&2 - else - ble/util/put "${_ble_term_visible_bell_show//'%message%'/$sgr$message}" - fi -} >&2 + local bell_type=${_ble_term_visible_bell_prev[0]} + ble/term/visible-bell:"$bell_type"/update "$1" "$2:update" +} function ble/term/visible-bell/.clear { - if ((${#_ble_term_visible_bell_prev[@]}==5)); then - local x0=${_ble_term_visible_bell_prev[1]} - local y0=${_ble_term_visible_bell_prev[2]} - local x=${_ble_term_visible_bell_prev[3]} - local y=${_ble_term_visible_bell_prev[4]} - - local ret; ble/color/face2sgr vbell_erase; local sgr=$ret - - local -a DRAW_BUFF=() - if [[ $_ble_term_rc ]]; then - local ret= - [[ $_ble_attached ]] && ble/canvas/panel/save-position goto-top-dock - ble/canvas/put.draw "$_ble_term_sc$_ble_term_sgr0" - ble/canvas/put-cup.draw $((y0+1)) $((x0+1)) - ble/canvas/put.draw "$sgr" - ble/canvas/put-spaces.draw "$x" - #ble/canvas/put-ech.draw "$x" - #ble/canvas/put.draw "$_ble_term_el" - ble/canvas/put.draw "$_ble_term_sgr0$_ble_term_rc" - [[ $_ble_attached ]] && ble/canvas/panel/load-position.draw "$ret" - else - : # 親プロセスの _ble_canvas_x が分からないので座標がずれる - # ble/util/buffer.flush >&2 - # ble/canvas/put.draw "$_ble_term_ri$_ble_term_sgr0" - # ble/canvas/put-hpa.draw $((1+x0)) - # ble/canvas/put.draw "$sgr" - # ble/canvas/put-spaces.draw "$x" - # ble/canvas/put.draw "$_ble_term_sgr0" - # ble/canvas/put-cud.draw 1 - # ble/canvas/put-hpa.draw $((1+_ble_canvas_x)) # 親プロセスの _ble_canvas_x? - fi - ble/canvas/flush.draw - else - ble/util/put "$_ble_term_visible_bell_clear" - fi + local bell_type=${_ble_term_visible_bell_prev[0]} + ble/term/visible-bell:"$bell_type"/clear "$@" >| "$_ble_term_visible_bell_ftime" -} >&2 +} + function ble/term/visible-bell/.erase-previous-visible-bell { local -a workers=() builtin eval 'workers=("$_ble_base_run/$$.visible-bell."*)' &>/dev/null # failglob 対策 @@ -4300,10 +4312,11 @@ function ble/term/visible-bell/.erase-previous-visible-bell { local workerfile for workerfile in "${workers[@]}"; do if [[ -s $workerfile && ! ( $workerfile -ot $_ble_term_visible_bell_ftime ) ]]; then - ble/term/visible-bell/.clear - break + ble/term/visible-bell/.clear "$sgr0" + return 0 fi done + return 1 } function ble/term/visible-bell/.create-workerfile { @@ -4336,37 +4349,35 @@ function ble/term/visible-bell/.worker { [[ $workerfile -ot $_ble_term_visible_bell_ftime ]] && return 0 >| "$workerfile" # check and clear - ble/term/visible-bell/.clear + ble/term/visible-bell/.clear "$sgr0" >| "$workerfile" } ## @fn ble/term/visible-bell message [opts] function ble/term/visible-bell { - local cols=${COLUMNS:-80} local message=$1 opts=$2 message=${message:-$bleopt_vbell_default_message} - # 一行に収まる様に切り詰める - local opt_canvas= x= y= if ble/is-function ble/canvas/trace-text; then - opt_canvas=1 - local ret lines=1 sgr0= sgr1= - ble/canvas/trace-text "$message" nonewline:external-sgr - message=$ret + ble/term/visible-bell:canvas/init "$message" else - message=${message::cols} + ble/term/visible-bell:term/init "$message" fi local sgr0=$_ble_term_sgr0 local sgr1=${_ble_term_setaf[2]}$_ble_term_rev local sgr2=$_ble_term_rev - local ret - ble/color/face2sgr vbell_flash; sgr1=$ret - ble/color/face2sgr vbell; sgr2=$ret + if ble/is-function ble/color/face2sgr; then + local ret + ble/color/face2sgr vbell_flash; sgr1=$ret + ble/color/face2sgr vbell; sgr2=$ret + ble/color/face2sgr vbell_erase; sgr0=$ret + fi - ble/term/visible-bell/.erase-previous-visible-bell - ble/term/visible-bell/.show "$message" "$sgr1" "$x" "$y" + local show_opts= + ble/term/visible-bell/.erase-previous-visible-bell && show_opts=erased + ble/term/visible-bell/.show "$sgr1" "$show_opts" local workerfile; ble/term/visible-bell/.create-workerfile # Note: __ble_suppress_joblist__ を指定する事によって、 @@ -4640,7 +4651,7 @@ function ble/term/modifyOtherKeys/.update { _ble_term_modifyOtherKeys_current=$1 } function ble/term/modifyOtherKeys/.supported { - # libvte は SGR(>4) を直接画面に表示してしまう + # libvte は SGR(>4) を直接画面に表示してしまう。 [[ $_ble_term_TERM == vte ]] && return 1 # 改造版 Poderosa は通知でウィンドウサイズを毎回変更するので表示が乱れてしまう @@ -4648,7 +4659,8 @@ function ble/term/modifyOtherKeys/.supported { # Note #D1213: linux (kernel 5.0.0) は "\e[>" でエスケープシーケンスを閉じてしまう。 # 5.4.8 は大丈夫だがそれでも modifyOtherKeys に対応していない。 - [[ $TERM == linux || $TERM == minix ]] && return 1 + # Solaris のコンソールもそのまま出力してしまう。 + [[ $TERM == linux || $TERM == minix || $TERM == sun* ]] && return 1 return 0 }