diff --git a/archive/layer/adapter.sh b/archive/layer/adapter.sh index ee77f158..1e7cc68c 100755 --- a/archive/layer/adapter.sh +++ b/archive/layer/adapter.sh @@ -47,7 +47,7 @@ function ble/highlight/layer:adapter/update { ble/highlight/layer/update/shift _ble_highlight_layer_adapter_buff local i g gprev=0 ctx=0 ret ((i1>0)) && { ble/highlight/layer/getg $((i1-1)); gprev=$g; } - # ble-edit/info/show text "layer:adapter u = $i1-$i2" + # ble/edit/info/show text "layer:adapter u = $i1-$i2" for ((i=i1;i<=i2;i++)); do local ch if [[ ${_ble_region_highlight_table[i]} ]]; then diff --git a/ble.pp b/ble.pp index 607efe2c..d8c3a902 100644 --- a/ble.pp +++ b/ble.pp @@ -809,7 +809,7 @@ function ble-attach { # Note: ble-decode/{initialize,reset-default-keymap} 内で # info を設定する事があるので表示する。 - ble-edit/info/default + ble/edit/info/default ble-edit/bind/.tail } @@ -835,7 +835,7 @@ function ble-detach/impl { function ble-detach/message { ble/util/buffer.flush >&2 printf '%s\n' "$@" 1>&2 - ble-edit/info/hide + ble/edit/info/hide ble/textarea#render ble/util/buffer.flush >&2 } diff --git a/blerc b/blerc index d68087ff..61d06765 100644 --- a/blerc +++ b/blerc @@ -111,6 +111,15 @@ #bleopt edit_line_type=graphical +## The following option controls the position of the info pane where completion +## menu, mode names, and other information are shown. When the value "top" is +## specified, the info pane is shown just below the command line. When the +## value "bottom" is specified, the info pane is shown at the bottom of the +## terminal. The default is "top". + +#bleopt info_display=top + + ## The following settings controls the prompt after the cursor left the command ## line. "prompt_ps1_final" contains a prompt string. "prompt_ps1_transient" ## is a colon-separated list of fields "always", "same-dir" and "trim". The diff --git a/keymap/emacs.sh b/keymap/emacs.sh index 6861cb19..20dfd06e 100644 --- a/keymap/emacs.sh +++ b/keymap/emacs.sh @@ -94,7 +94,7 @@ function ble/keymap:emacs/update-mode-name { [[ $name ]] || info=${info#' '} name=$name$info - ble-edit/info/default ansi "$name" + ble/edit/info/default ansi "$name" } function ble/widget/emacs/__after_widget__ { @@ -209,7 +209,7 @@ function ble-decode/keymap:emacs/initialize { source "$fname_keymap_cache" && return 0 fi - ble-edit/info/immediate-show text "ble.sh: updating cache/keymap.emacs..." + ble/edit/info/immediate-show text "ble.sh: updating cache/keymap.emacs..." { ble-decode/keymap/load isearch dump @@ -217,7 +217,7 @@ function ble-decode/keymap:emacs/initialize { ble-decode/keymap/load emacs dump } 3>| "$fname_keymap_cache" - ble-edit/info/immediate-show text "ble.sh: updating cache/keymap.emacs... done" + ble/edit/info/immediate-show text "ble.sh: updating cache/keymap.emacs... done" } ble-decode/keymap:emacs/initialize diff --git a/keymap/vi.sh b/keymap/vi.sh index 075e0c23..c6cc9ad8 100644 --- a/keymap/vi.sh +++ b/keymap/vi.sh @@ -360,7 +360,7 @@ function ble/keymap:vi/update-mode-name { ble/util/buffer "$bleopt_term_vi_omap" ble/term/cursor-state/set-internal "$bleopt_keymap_vi_omap_cursor" elif [[ $kmap == vi_cmap ]]; then - ble-edit/info/default text '' + ble/edit/info/default text '' ble/util/buffer "$bleopt_term_vi_cmap" ble/term/cursor-state/set-internal "$bleopt_keymap_vi_cmap_cursor" return 0 @@ -423,7 +423,7 @@ function ble/keymap:vi/update-mode-name { elif [[ $_ble_edit_kbdmacro_record ]]; then name=$name${name:+' '}$'\e[1;31mREC\e[m' fi - ble-edit/info/default ansi "$name" # 6ms + ble/edit/info/default ansi "$name" # 6ms } function ble/widget/vi_imap/normal-mode.impl { @@ -913,7 +913,7 @@ function ble/keymap:vi/register#dump { out=$out'"'$k' ('$type') '$content$'\n' done - ble-edit/info/show ansi "$out" + ble/edit/info/show ansi "$out" return 0 } function ble/widget/vi-command:reg { ble/keymap:vi/register#dump; } @@ -4982,7 +4982,7 @@ function ble/widget/vi-command:w { local wc ble/util/assign wc 'ble/bin/wc "$file"' ble/string#split-words wc "$wc" - ble-edit/info/show text "\"$file\" ${wc[0]}L, ${wc[2]}C written" + ble/edit/info/show text "\"$file\" ${wc[0]}L, ${wc[2]}C written" ble/keymap:vi/adjust-command-mode return 0 } @@ -5158,7 +5158,7 @@ function ble/widget/vi-command/search.core { else ble/history/isearch-forward regex:progress fi; local r=$? - ble-edit/info/default + ble/edit/info/default if ((r==0)); then local new_index; ble/history/get-index -v new_index @@ -5598,7 +5598,7 @@ function ble/widget/vi-command/show-line-info { local line_ratio=$(((100*iline+nline-1)/nline))% local line_stat=$'line \e[34m'$iline$'\e[m / \e[34m'$nline$'\e[m --\e[34m'$line_ratio$'\e[m--' - ble-edit/info/show ansi "\"$hist_stat\" $line_stat" + ble/edit/info/show ansi "\"$hist_stat\" $line_stat" ble/keymap:vi/adjust-command-mode return 0 } @@ -5613,9 +5613,9 @@ function ble/widget/vi-command/cancel { local joblist; ble/util/joblist if ((${#joblist[*]})); then ble/array#push joblist $'Type \e[35m:q!\e[m and press \e[35m\e[m to abandon all \e[31mjobs\e[m and exit Bash' - IFS=$'\n' builtin eval 'ble-edit/info/show ansi "${joblist[*]}"' + IFS=$'\n' builtin eval 'ble/edit/info/show ansi "${joblist[*]}"' else - ble-edit/info/show ansi $'Type \e[35m:q\e[m and press \e[35m\e[m to exit Bash' + ble/edit/info/show ansi $'Type \e[35m:q\e[m and press \e[35m\e[m to exit Bash' fi fi ble/widget/vi-command/bell @@ -7894,6 +7894,7 @@ function ble/keymap:vi/async-commandline-mode { # 記録 ble/textarea#render ble/textarea#save-state _ble_keymap_vi_cmap + ble/util/save-vars _ble_keymap_vi_cmap _ble_canvas_panel_focus _ble_keymap_vi_cmap_history_prefix=$_ble_history_prefix # 初期化 @@ -7902,6 +7903,7 @@ function ble/keymap:vi/async-commandline-mode { # textarea _ble_textarea_panel=1 + _ble_canvas_panel_focus=1 ble/textarea#invalidate # edit/prompt @@ -7943,6 +7945,7 @@ function ble/widget/vi_cmap/accept { # 復元 ble/textarea#restore-state _ble_keymap_vi_cmap ble/textarea#clear-state _ble_keymap_vi_cmap + ble/util/restore-vars _ble_keymap_vi_cmap _ble_canvas_panel_focus [[ $_ble_edit_overwrite_mode ]] && ble/util/buffer "$_ble_term_civis" _ble_history_prefix=$_ble_keymap_vi_cmap_history_prefix @@ -8026,7 +8029,7 @@ function ble-decode/keymap:vi/initialize { source "$fname_keymap_cache" && return 0 fi - ble-edit/info/immediate-show text "ble.sh: updating cache/keymap.vi..." + ble/edit/info/immediate-show text "ble.sh: updating cache/keymap.vi..." { ble-decode/keymap/load isearch dump @@ -8038,7 +8041,7 @@ function ble-decode/keymap:vi/initialize { ble-decode/keymap/load vi_cmap dump } 3>| "$fname_keymap_cache" - ble-edit/info/immediate-show text "ble.sh: updating cache/keymap.vi... done" + ble/edit/info/immediate-show text "ble.sh: updating cache/keymap.vi... done" } ble-decode/keymap:vi/initialize diff --git a/keymap/vi_digraph.sh b/keymap/vi_digraph.sh index 4241c7b4..3dca4184 100644 --- a/keymap/vi_digraph.sh +++ b/keymap/vi_digraph.sh @@ -54,12 +54,12 @@ function ble-decode/keymap:vi_digraph/initialize { return 0 fi - ble-edit/info/immediate-show text "ble.sh: updating cache/keymap.vi_digraph..." + ble/edit/info/immediate-show text "ble.sh: updating cache/keymap.vi_digraph..." : >| "$fname_keymap_cache" ble-decode/keymap/load vi_digraph dump 3>> "$fname_keymap_cache" - ble-edit/info/immediate-show text "ble.sh: updating cache/keymap.vi_digraph... done" + ble/edit/info/immediate-show text "ble.sh: updating cache/keymap.vi_digraph... done" } ble-decode/keymap:vi_digraph/initialize diff --git a/lib/core-complete.sh b/lib/core-complete.sh index 51010b1d..00adf637 100644 --- a/lib/core-complete.sh +++ b/lib/core-complete.sh @@ -424,7 +424,7 @@ function ble/complete/menu-style:desc-raw/guess { ## @fn ble/complete/menu#construct/.initialize-size ## @var[out] cols lines function ble/complete/menu#construct/.initialize-size { - ble-edit/info/.initialize-size + ble/edit/info/.initialize-size local maxlines=$((bleopt_complete_menu_maxlines)) ((maxlines>0&&lines>maxlines)) && lines=$maxlines } @@ -535,10 +535,10 @@ function ble/complete/menu#construct { } function ble/complete/menu#show { - ble-edit/info/immediate-show "${_ble_complete_menu_info_data[@]}" + ble/edit/info/immediate-show "${_ble_complete_menu_info_data[@]}" } function ble/complete/menu#clear { - ble-edit/info/clear + ble/edit/info/clear } @@ -583,7 +583,7 @@ function ble/complete/menu#select { fi local -a DRAW_BUFF=() - local x0=$_ble_canvas_x y0=$_ble_canvas_y + local ret; ble/canvas/panel/save-position; local pos0=$ret if ((osel>=0)); then # 消去 local entry=${_ble_complete_menu_icons[osel-visible_beg]} @@ -629,7 +629,7 @@ function ble/complete/menu#select { _ble_complete_menu_selected=-1 value=$_ble_complete_menu_original fi - ble/canvas/goto.draw "$x0" "$y0" + ble/canvas/panel/load-position.draw "$pos0" ble/canvas/bflush.draw ble/function#try "$menu_class"/onselect "$nsel" "$osel" @@ -4896,7 +4896,7 @@ function ble/widget/complete { if ((ext!=0||cand_count==0)); then [[ :$opts: != *:no-bell:* && ! $cand_limit_reached ]] && ble/widget/.bell 'complete: no completions' - ble-edit/info/clear + ble/edit/info/clear return 1 fi fi @@ -6070,14 +6070,14 @@ function ble/complete/dabbrev/.show-status.fib { ((fib_ntask)) && text="$text *$fib_ntask" - ble-edit/info/show text "$text" + ble/edit/info/show text "$text" } function ble/complete/dabbrev/show-status { local fib_ntask=${#_ble_util_fiberchain[@]} ble/complete/dabbrev/.show-status.fib } function ble/complete/dabbrev/erase-status { - ble-edit/info/default + ble/edit/info/default } ## @fn ble/complete/dabbrev/initialize-variables diff --git a/lib/core-syntax.sh b/lib/core-syntax.sh index f796aa35..aecf2aae 100644 --- a/lib/core-syntax.sh +++ b/lib/core-syntax.sh @@ -7095,7 +7095,7 @@ function ble/highlight/layer:syntax/update { local ret; ble/canvas/sflush.draw status=$status$ret #ble/util/assign buff 'declare -p _ble_textarea_bufferName $_ble_textarea_bufferName | cat -A'; status="$status$buff" - ble-edit/info/show ansi "$status" + ble/edit/info/show ansi "$status" fi #%end @@ -7113,7 +7113,7 @@ function ble/highlight/layer:syntax/update { # ble/array#push words "[$value ${word[*]}]" # fi # done - # ble-edit/info/show text "${words[*]}" + # ble/edit/info/show text "${words[*]}" } function ble/highlight/layer:syntax/getg { diff --git a/lib/init-bind.sh b/lib/init-bind.sh index 2557a4cb..f128215c 100644 --- a/lib/init-bind.sh +++ b/lib/init-bind.sh @@ -30,7 +30,7 @@ function ble/init:bind/generate-binder { local fbind1=$_ble_base_cache/ble-decode-bind.$_ble_bash.$bleopt_input_encoding.bind local fbind2=$_ble_base_cache/ble-decode-bind.$_ble_bash.$bleopt_input_encoding.unbind - ble-edit/info/show text "ble.sh: updating binders..." + ble/edit/info/show text "ble.sh: updating binders..." : >| "$fbind1" : >| "$fbind2" @@ -216,7 +216,7 @@ function ble/init:bind/generate-binder { ble/function#try ble/encoding:"$bleopt_input_encoding"/generate-binder - ble-edit/info/immediate-show text "ble.sh: updating binders... done" + ble/edit/info/immediate-show text "ble.sh: updating binders... done" } ble/init:bind/generate-binder diff --git a/lib/init-cmap.sh b/lib/init-cmap.sh index 1299324c..d88a864a 100644 --- a/lib/init-cmap.sh +++ b/lib/init-cmap.sh @@ -76,7 +76,7 @@ function ble/init:cmap/initialize { # print = f16 [xterm] # deleteline = A-delete - ble-edit/info/immediate-show text "ble/lib/init-cmap.sh: updating key sequences..." + ble/edit/info/immediate-show text "ble/lib/init-cmap.sh: updating key sequences..." # pc-style keys # # vt52, xterm, rxvt @@ -255,7 +255,7 @@ function ble/init:cmap/initialize { # ble-bind -k "CAN @ m" meta # ble-bind -k "CAN @ s" super - ble-edit/info/immediate-show text "ble/lib/init-cmap.sh: updating key sequences... done" + ble/edit/info/immediate-show text "ble/lib/init-cmap.sh: updating key sequences... done" } ble/init:cmap/initialize diff --git a/memo/ChangeLog.md b/memo/ChangeLog.md index c4fbe6d0..24fea655 100644 --- a/memo/ChangeLog.md +++ b/memo/ChangeLog.md @@ -12,6 +12,7 @@ - edit (kill/copy): combine multiple kills and copies (suggested by 3ximus) `#D1443` 66564e1 - edit (`{kill,copy}-region-or`): fix unconditionally combined kills/copies (reported by 3ximus) `#D1447` 1631751 - canvas: update emoji database and support `bleopt emoji_version` (motivated by endorfina) `#D1454` d1f8c27 +- canvas, edit: support `bleopt info_display` (suggested by 0neGuyDev) `#D1458` 0000000 ## Changes @@ -21,7 +22,7 @@ - edit: change default behavior of C-w and M-w to operate on backward words `#D1448` 47a3301 - syntax (`layer:syntax/word`): perform pathname expansions in background subshells (motivated by 3ximus) `#D1449` 13e7bdd - complete: perform pathname expansions in subshells (motivated by 3ximus) `#D1450` d511896 -- complete: support `bleopt complete_timeout_compvar` to time out pathname expansions for `COMP_WORDS` / `COMP_LINE` `#D1457` 0000000 +- complete: support `bleopt complete_timeout_compvar` to time out pathname expansions for `COMP_WORDS` / `COMP_LINE` `#D1457` cc2881a ## Fixes diff --git a/note.txt b/note.txt index 417bdeea..7baf8b17 100644 --- a/note.txt +++ b/note.txt @@ -3811,6 +3811,166 @@ bash_tips 全て 40300 に書き換えた。まあ、これで何も起こらないだろう。 +2021-02-03 + + * canvas: status line を最終行に表示する可能性 (suggested by 0neGuyDev) [#D1458] + https://github.com/akinomyoga/ble.sh/issues/85 + + 元々の提案は vim の mode 名という事だったが、vim の mode 名だけを最終行に表 + 示するのか、或いは補完候補等の情報も全て最終行付近に表示するのかという可能 + 性がある。Emacs 等を考えると補完候補も最終行に表示するのが自然な気がする。 + なので、実装としては info を丸ごと一番最後に表示する可能性について考えて良 + い気がする。 + + 最終行に表示する為に必要な事。 + + a 一つの方法は \e7 \e8 で現在位置を記録するという事。これは visible-bell で + 既にやっている事。問題になるのは info の内容を構築する時に \e7 \e8 を使え + ないという事。trace に明示的に禁止・代替するオプションを付ける必要がある + かもしれない。 + + b もう一つの方法は DSR(6)/CPR で問い合わせるという方法。実はこの方法は未だ + ble.sh には積極的に取り入れた事はない。とはいいつつも歴史的な端末でも軒並 + みこれに対応しているので、全ての端末で使えると思って良い。問題になるのは + 応答に時間がかかるので頻繁に問い合わせる訳には行かないという事。どのタイ + ミングで問い合わせるのが良いのか非自明であるという点。 + + 取り敢えず実装としては a の方針を試すのが自然な気がする。実は canvas の + panel を調整するだけで、他の部分は触れずに実装できてしまうのではないだろう + か。前にも似た様な事を考えた事があるような気がしないでもない。 + + 自身の高さ変更だけでなく他の panel の高さ変更の時にも注意が必要。 + 特に高さを増やす時。 + + * ok: bell を表示する為の行が canvas origin の一つ上に確保されている事に注 + 意する。と思ったが、\e7\e8 で移動するのであれば実は余り関係ないという気が + する。 + + ? reject: 間に適当な高さの空 panel を設置すれば良いのではないか、と思ったが + 間の高さが不明なので関係ない。 + + * vfill 以降の高さが 0 の時に変な事が起こらないか + →これについてはちゃんと意識して実装する事にした。 + + うーん。取り敢えず実装した。canvas.sh に対する修正だけで大体動いているが細 + かい所で変な事が起こっている。 + + x fixed: C-l をしても画面の一番上に移動しなくなってしまう。何故だろうか。 + →これは clear-screen する時に下部に excursion している状態で行っていたので、 + その後 textarea を描画する時に _ble_term_rc で位置が復元されるのが原因だった。 + + x 空コマンドを実行した時に info が押し出されて消える。実装を見ると + ble/widget/.insert-newline の *:keep-info:* が該当する部分だがちゃんと動 + きそうな気がする。と思ったら canvas.sh の panel#increase-total-height が + 未実装だったのを思い出した。 + + % と思ったがよく見たらちゃんと実装できている気がする。然し整理した。それで + % も動かない。そもそも普通に C-q C-j で改行を入力した時も info が消えてしまっ + % ている。うーん。increase-height に失敗している? + + やっぱり実装できていなかった。端末の高さが十分に高い時は、全体の高さは増 + えない。うーん。制御機能を工夫してこれを何とかする方法は実際に存在するの + だろうか。勿論 CPR や他の機能を使えば可能なのだろうと思うが基本的な移動と + IND RI の組み合わせでできない物だろうか。 + + うーん。無理の気がする。CUU&CUD の累積でできるのではないかと考えたが、累 + 積させる方法が存在しない。 + + + やはり DECSTBM 等に依存するしかないのだろうか。或いは CPR を利用する。も + しくは、再描画する。再描画が現実的な気がする、と思ったがサイズが変化する + 可能性がある場合全般に問題が発生するので、やはり現実的ではないように思わ + れる。うーん。CPR を毎回発行して現在位置を記録する様にした方が良いのだろ + うか。 + + a reject: CPR の可能性について→余り現実的でない気がする + + ble/term/enter の辺りで CPR を発行する様にする事を考えたが。或いは + ble/textarea#invalidate を発行する度に実行した方が良いのではないか。うー + ん。然し、描画しようとしている時に即座に返答が帰ってくる訳でもない。と + いって CPR が帰って来るまでブロックするというのも変だし、続きを async + に処理するとういのも変である。やはり CPR は飽くまで補助的に使うべきなの + だという気がする。或いは、画面の大きさが変わる時に初めて CPR 要求を出す + という考え方もある。然し、そうすると async に処理しなければならなくな + る…或いはその場で入力を待っても良いのかもしれないが…やはり駄目。別の + 入力を先に受信したりすると変な事になる。 + + b done: 再描画の可能性について→呼び出し元で再描画が必要化判定するのは困難なの + で event を発火するなどして対処する。 + + 実の所、再描画の為の関数を用意する筈だったので丁度良いのではないか。うー + ん。再描画というよりは invalidate して、後で再描画するという形にするの + が良い。invalidate については…。全体を invalidate するというのも考えら + れるが一部を invalidate するというのも考えられる。矩形で invalidate さ + れた領域を記録できる様にするのが良い気がする。 + + →invalidate を呼び出してそれからそれを記録して、更に次の render の時に + 改めて反映させるというコードを ble-edit/info について新しく書いた。 + ble/textarea に関しては既に実装した関数を適当に呼び出すだけで良いという + 事にする。 + + c done: DECSTBM を使う可能性について。取り敢えず最近の端末はこれに対応している + だろうと想像されるのでこれを使うというので良い気がする。ble.sh 起動時に + DECSTBM に対応しているかどうかを検出する。 + + * done: DECSTBM の判定コード + 取り敢えず判定コードを書いた。 + + →と思ったら行が消滅してしまう。うーん。→ IND の代わりに CUD を使って + DECSTBM をテストする事にした。動いている。OK + + x fixed: cursor-position (DECSTBM が使えない場合) が info の中になってしまっている + _ble_canvas_panel_focus という変数を用意した。 + 然し、それでも振る舞いが変である。 + + x fixed: (DECSTBM が使えない場合) 一番最後の行での描画が重複している。 + + DECSTBM の有無で振る舞いが逆になってしまっている。これは明らかに + set-height の振る舞いに (少なくとも片方は) 間違いがあるという事。 + + →これは単純にバグだった。 + + x fixed: DECSTBM を使っている時に一番最後から二行目が使われない。 + + DECSTBM を使わない場合にはちゃんと動いているのでここにも何が間違いがある。 + + * util (visible-bell) との干渉について + + x fixed: 実は visible-bell の実装にバグがある。 + + RI を使って現在編集のコマンドと被らない様にしているが、実は現在行と被らな + い様にしているだけであって、実際には編集文字列の2行目以降にいる時には + visible-bell が上書きしてしまう。 + + x fixed: 先頭行の visible-bell で info が消滅する。 + + * resolved: _ble_term_{sc,rc} ... util.sh で使っている箇所がある + + * ok: visible-bell の中の trace で sc rc を使えない様にするべきでは? と思っ + たが、visible-bell は純粋な text という事になっているので今は関係ない。 + 将来的には esc seq も指定できる様にする可能性もあるが今は考えない。 + + * resolved: ble/canvas 内で他にも _ble_term_{sc,rc} を使っている箇所がある。 + これは曖昧文字幅の問い合わせに使っていた。 + + * ok: _ble_term{sc,rc} は edit.sh でも使っている箇所がある。 + →adjust-eol で使っている。これは大丈夫の筈。 + + * ok: ble/canvas/panel#report-cursor-position 等については影響がないか確認 + が必要。ble/canvas/panel#get-origin についても。 + + get-origin に関しては core-complete.sh で menu の構築で使われている様だが、 + 絶対位置として他の panel の座標系と混ぜて使っている訳ではないので問題ない。 + + report-cursor-position に関してはパネルの局所座標を引数に指定しているので + 呼び出し元は気にしなくて良い。特に問題も無い様に思われる。 + + * done: trace で SC/RC を emulate する (with opts=noscrc) + + * done: bleopt で制御できる様にする + + * blerc に bleopt info_display を追記する。 + 2021-02-01 * complete: support "bleopt complete_timeout_compvar" (motivated by 3ximus) [#D1457] diff --git a/src/canvas.sh b/src/canvas.sh index a9cb96fd..708e33e6 100644 --- a/src/canvas.sh +++ b/src/canvas.sh @@ -319,6 +319,10 @@ function ble/util/c2w+auto { } function ble/util/c2w+auto/update.buff { local opts=$1 + local -a DRAW_BUFF=() + local ret + [[ $_ble_attached ]] && ble/canvas/panel/save-position goto-top-dock + ble/canvas/put.draw "$_ble_term_sc" if ble/util/is-unicode-output; then local achar='▽' if [[ :$opts: == *:first-line:* ]]; then @@ -327,22 +331,20 @@ function ble/util/c2w+auto/update.buff { local x0=$((cols-4)); ((x0<0)) && x0=0 _ble_util_c2w_auto_update_x0=$x0 - local -a DRAW_BUFF=() - ble/canvas/put.draw "$_ble_term_sc" ble/canvas/put-cup.draw 1 $((x0+1)) ble/canvas/put.draw "$achar" ble/term/CPR/request.draw ble/util/c2w+auto/update.hook ble/canvas/put-cup.draw 1 $((x0+1)) ble/canvas/put.draw "$_ble_term_el" - ble/canvas/put.draw "$_ble_term_rc" - ble/canvas/bflush.draw else _ble_util_c2w_auto_update_x0=0 - ble/util/buffer "$_ble_term_sc$_ble_term_cr$achar" - ble/term/CPR/request.buff ble/util/c2w+auto/update.hook - ble/util/buffer "$_ble_term_rc" + ble/canvas/put.draw "$_ble_term_cr$achar" + ble/term/CPR/request.draw ble/util/c2w+auto/update.hook fi fi + ble/canvas/put.draw "$_ble_term_rc" + [[ $_ble_attached ]] && ble/canvas/panel/load-position.draw "$ret" + ble/canvas/bflush.draw } function ble/util/c2w+auto/update.hook { local l=$1 c=$2 @@ -369,6 +371,11 @@ function ble/canvas/put-ind.draw { 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" + DRAW_BUFF[${#DRAW_BUFF[*]}]=$ret +} function ble/canvas/put-il.draw { local value=${1-1} ((value>0)) || return 0 @@ -597,28 +604,40 @@ function ble/canvas/trace/.process-overflow { function ble/canvas/trace/.decsc { trace_decsc=("$x" "$y" "$g" "$lc" "$lg") - ble/canvas/put.draw "$_ble_term_sc" + [[ :$opts: == *:noscrc:* ]] || + ble/canvas/put.draw "$_ble_term_sc" } function ble/canvas/trace/.decrc { + local ret; ble/color/g2sgr "${trace_decsc[2]}" # g を明示的に復元。 + ble/canvas/put.draw "$ret" + if [[ :$opts: == *:noscrc:* ]]; then + ble/canvas/put-move.draw $((trace_decsc[0]-x)) $((trace_decsc[1]-y)) + else + ble/canvas/put.draw "$_ble_term_rc" + fi x=${trace_decsc[0]} y=${trace_decsc[1]} g=${trace_decsc[2]} lc=${trace_decsc[3]} lg=${trace_decsc[4]} - local ret; ble/color/g2sgr "$g" # g を明示的に復元。 - ble/canvas/put.draw "$ret$_ble_term_rc" } function ble/canvas/trace/.scosc { trace_scosc=("$x" "$y" "$g" "$lc" "$lg") - ble/canvas/put.draw "$_ble_term_sc" + [[ :$opts: == *:noscrc:* ]] || + ble/canvas/put.draw "$_ble_term_sc" } function ble/canvas/trace/.scorc { + local ret; ble/color/g2sgr "$g" # g は変わらない様に。 + ble/canvas/put.draw "$ret" + if [[ :$opts: == *:noscrc:* ]]; then + ble/canvas/put-move.draw $((trace_scosc[0]-x)) $((trace_scosc[1]-y)) + else + ble/canvas/put.draw "$_ble_term_rc" + fi x=${trace_scosc[0]} y=${trace_scosc[1]} lc=${trace_scosc[3]} lg=${trace_scosc[4]} - local ret; ble/color/g2sgr "$g" # g は変わらない様に。 - ble/canvas/put.draw "$_ble_term_rc$ret" } function ble/canvas/trace/.ps1sc { trace_brack[${#trace_brack[*]}]="$x $y" @@ -1661,7 +1680,9 @@ function ble/textmap#hit { ## @var _ble_canvas_x ## @var _ble_canvas_y ## 現在の (描画の為に動き回る) カーソル位置を保持します。 -_ble_canvas_x=0 _ble_canvas_y=0 +_ble_canvas_x=0 +_ble_canvas_y=0 +_ble_canvas_excursion= ## @fn ble/canvas/goto.draw x y opts ## 現在位置を指定した座標へ移動する制御系列を生成します。 @@ -1694,10 +1715,27 @@ function ble/canvas/goto.draw { _ble_canvas_x=$x _ble_canvas_y=$y } +_ble_canvas_excursion_x= +_ble_canvas_excursion_y= +function ble/canvas/excursion-start.draw { + [[ $_ble_canvas_excursion ]] && return + _ble_canvas_excursion=1 + _ble_canvas_excursion_x=$_ble_canvas_x + _ble_canvas_excursion_y=$_ble_canvas_y + ble/canvas/put.draw "$_ble_term_sc" +} +function ble/canvas/excursion-end.draw { + [[ $_ble_canvas_excursion ]] || return + _ble_canvas_excursion= + ble/canvas/put.draw "$_ble_term_rc" + _ble_canvas_x=$_ble_canvas_excursion_x + _ble_canvas_y=$_ble_canvas_excursion_y +} + #------------------------------------------------------------------------------ # ble/canvas/panel -## @arr _ble_canvas_panel_type +## @arr _ble_canvas_panel_class ## 各パネルを管理する関数接頭辞を保持する。 ## ## @arr _ble_canvas_panel_height @@ -1706,16 +1744,28 @@ function ble/canvas/goto.draw { ## ## 開始した瞬間にキー入力をすると画面に echo されてしまうので、 ## それを削除するために最初の編集文字列の行数を 1 とする。 -_ble_canvas_panel_type=(ble/textarea/panel ble/textarea/panel ble-edit/info) +## +## @var _ble_canvas_panel_focus +## 現在 focus のあるパネルの番号を保持する。 +## 端末の現在位置はこのパネルの render が設定した位置に置かれる。 +## +## @var _ble_canvas_panel_vfill +## 下部に寄せて表示されるパネルの開始番号を保持する。 +## この変数が空文字列の時は全てのパネルは上部に表示される。 +_ble_canvas_panel_class=() _ble_canvas_panel_height=(1 0 0) +_ble_canvas_panel_focus= +_ble_canvas_panel_vfill= +_ble_canvas_panel_bottom= # 現在下部に居るかどうか +_ble_canvas_panel_tmargin=1 # for visible-bell ## @fn ble/canvas/panel/layout/.extract-heights ## @arr[out] mins maxs function ble/canvas/panel/layout/.extract-heights { - local i n=${#_ble_canvas_panel_type[@]} + local i n=${#_ble_canvas_panel_class[@]} for ((i=0;i=_ble_canvas_panel_vfill)) +} + ## @fn ble/canvas/panel#get-origin ## @var[out] x y function ble/canvas/panel#get-origin { @@ -1822,6 +1955,11 @@ function ble/canvas/panel#get-origin { } function ble/canvas/panel#goto.draw { local index=$1 x=${2-0} y=${3-0} opts=$4 ret + if ble/canvas/panel#is-bottom "$index"; then + ble/canvas/panel/goto-bottom-dock.draw + else + ble/canvas/panel/goto-top-dock.draw + fi ble/arithmetic/sum "${_ble_canvas_panel_height[@]::index}" ble/canvas/goto.draw "$x" $((ret+y)) "$opts" } @@ -1841,15 +1979,32 @@ function ble/canvas/panel#increase-total-height.draw { ((delta>0)) || return 1 local ret - ble/arithmetic/sum "${_ble_canvas_panel_height[@]}"; local old_total_height=$ret - # 下に余白を確保 - if ((old_total_height>0)); then - ble/canvas/goto.draw 0 $((old_total_height-1)) - ble/canvas/put-ind.draw "$delta"; ((_ble_canvas_y+=delta)) - else - ble/canvas/goto.draw 0 0 - ble/canvas/put-ind.draw $((delta-1)); ((_ble_canvas_y+=delta-1)) + ble/canvas/panel/top-dock#height; local top_height=$ret + ble/canvas/panel/bottom-dock#height; local bottom_height=$ret + if ((bottom_height)); then + ble/canvas/panel/goto-top-dock.draw + if [[ $_ble_term_DECSTBM ]]; then + ble/canvas/excursion-start.draw + ble/canvas/put.draw $'\e[1;'$((LINES-bottom_height))'r' + ble/canvas/excursion-end.draw + ble/canvas/goto.draw 0 $((top_height==0?0:top_height-1)) + ble/canvas/put-ind.draw $((top_height-1+delta-_ble_canvas_y)) + ((_ble_canvas_y=top_height-1+delta)) + ble/canvas/excursion-start.draw + ble/canvas/put.draw $'\e[;r' + ble/canvas/excursion-end.draw + return 0 + else + ble/canvas/panel/bottom-dock#invalidate + fi fi + + local old_height=$((top_height+bottom_height)) + local new_height=$((old_height+delta)) + ble/canvas/goto.draw 0 $((top_height==0?0:top_height-1)) + ble/canvas/put-ind.draw $((new_height-1-_ble_canvas_y)); ((_ble_canvas_y=new_height-1)) + ble/canvas/panel/goto-vfill.draw && + ble/canvas/put-il.draw "$delta" } ## @fn ble/canvas/panel#set-height.draw panel height opts @@ -1858,36 +2013,58 @@ function ble/canvas/panel#increase-total-height.draw { function ble/canvas/panel#set-height.draw { local index=$1 new_height=$2 opts=$3 ((new_height<0)) && new_height=0 - local delta=$((new_height-_ble_canvas_panel_height[index])) - ((delta)) || return 1 + local old_height=${_ble_canvas_panel_height[index]} + local delta=$((new_height-old_height)) - local ret - if ((delta>0)); then + if ((delta==0)); then + if [[ :$opts: == *:clear:* ]]; then + ble/canvas/panel#clear.draw "$index" + return $? + else + return 1 + fi + elif ((delta>0)); then # 新しく行を挿入 ble/canvas/panel#increase-total-height.draw "$delta" + ble/canvas/panel/goto-vfill.draw && + ble/canvas/put-dl.draw "$delta" + ((_ble_canvas_panel_height[index]=new_height)) + + case :$opts: in + (*:clear:*) + ble/canvas/panel#goto.draw "$index" + ble/canvas/put-dl.draw "$old_height" + ble/canvas/put-il.draw "$new_height" ;; + (*:shift:*) # 先頭に行挿入 + ble/canvas/panel#goto.draw "$index" + ble/canvas/put-il.draw "$delta" ;; + (*) # 末尾に行挿入 + ble/canvas/panel#goto.draw "$index" 0 "$old_height" + ble/canvas/put-il.draw "$delta" ;; + esac - if [[ :$opts: == *:shift:* ]]; then # 先頭に挿入 - ble/arithmetic/sum "${_ble_canvas_panel_height[@]::index}"; local ins_offset=$ret - ble/canvas/goto.draw 0 "$ins_offset" - else # 末尾に挿入 - ble/arithmetic/sum "${_ble_canvas_panel_height[@]::index+1}"; local ins_offset=$ret - ble/canvas/goto.draw 0 "$ins_offset" - fi - ble/canvas/put-il.draw "$delta" else - # 行を削除 - if [[ :$opts: == *:shift:* ]]; then # 先頭を削除 - ble/arithmetic/sum "${_ble_canvas_panel_height[@]::index}"; local ins_offset=$ret - ble/canvas/goto.draw 0 "$ins_offset" - else # 末尾を削除 - ble/arithmetic/sum "${_ble_canvas_panel_height[@]::index+1}"; local ins_offset=$ret - ble/canvas/goto.draw 0 $((ins_offset+delta)) - fi - ble/canvas/put-dl.draw $((-delta)) + ((delta=-delta)) + + case :$opts: in + (*:clear:*) + ble/canvas/panel#goto.draw "$index" + ble/canvas/put-dl.draw "$old_height" + ble/canvas/put-il.draw "$new_height" ;; + (*:shift:*) # 先頭を削除 + ble/canvas/panel#goto.draw "$index" 0 0 + ble/canvas/put-dl.draw "$delta" ;; + (*) # 末尾を削除 + ble/canvas/panel#goto.draw "$index" 0 "$new_height" + ble/canvas/put-dl.draw "$delta" ;; + esac + + ((_ble_canvas_panel_height[index]=new_height)) + ble/canvas/panel/goto-vfill.draw && + ble/canvas/put-il.draw "$delta" fi + ble/function#try "${_ble_canvas_panel_class[index]}#panel::onHeightChange" "$index" - ((_ble_canvas_panel_height[index]=new_height)) - ble/function#try "${_ble_canvas_panel_type[index]}#on-height-change" "$index" return 0 } function ble/canvas/panel#increase-height.draw { @@ -1897,26 +2074,14 @@ function ble/canvas/panel#increase-height.draw { function ble/canvas/panel#set-height-and-clear.draw { local index=$1 new_height=$2 - local old_height=${_ble_canvas_panel_height[index]} - ((old_height||new_height)) || return 1 - - local ret - ble/canvas/panel#increase-total-height.draw $((new_height-old_height)) - ble/arithmetic/sum "${_ble_canvas_panel_height[@]::index}"; local ins_offset=$ret - ble/canvas/goto.draw 0 "$ins_offset" - ((old_height)) && ble/canvas/put-dl.draw "$old_height" - ((new_height)) && ble/canvas/put-il.draw "$new_height" - - ((_ble_canvas_panel_height[index]=new_height)) + ble/canvas/panel#set-height.draw "$index" "$new_height" clear } function ble/canvas/panel#clear.draw { local index=$1 local height=${_ble_canvas_panel_height[index]} if ((height)); then - local ret - ble/arithmetic/sum "${_ble_canvas_panel_height[@]::index}"; local ins_offset=$ret - ble/canvas/goto.draw 0 "$ins_offset" sgr0 + ble/canvas/panel#goto.draw "$index" 0 0 sgr0 if ((height==1)); then ble/canvas/put.draw "$_ble_term_el2" else @@ -1940,3 +2105,77 @@ function ble/canvas/panel#clear-after.draw { ble/canvas/put.draw "$_ble_term_ri" fi } + +## @fn ble/canvas/panel/invalidate +## Invalidate all panels (with non-zero height) +function ble/canvas/panel/clear { + local -a DRAW_BUFF=() + local index n=${#_ble_canvas_panel_class[@]} + for ((index=0;indexLINES)) && tmargin=$LINES + ((tmargin>0)) || return 0 + + local ret + ble/canvas/panel/save-position; local pos=$ret + ble/canvas/panel/goto-top-dock.draw + + ble/canvas/panel/top-dock#height; local top_height=$ret + ble/canvas/panel/bottom-dock#height; local bottom_height=$ret + if ((bottom_height)); then + if [[ $_ble_term_DECSTBM ]]; then + ble/canvas/excursion-start.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" + ble/canvas/excursion-start.draw + ble/canvas/put.draw $'\e[;r' + ble/canvas/excursion-end.draw + ble/canvas/panel/load-position.draw "$pos" + return 0 + else + ble/canvas/panel/bottom-dock#invalidate + fi + fi + + ble/canvas/goto.draw 0 0 + ble/canvas/put-ri.draw "$tmargin" + ble/canvas/put-cud.draw "$tmargin" + ble/canvas/panel/load-position.draw "$pos" +} diff --git a/src/decode.sh b/src/decode.sh index 5568ffc2..98aca7b1 100644 --- a/src/decode.sh +++ b/src/decode.sh @@ -519,16 +519,16 @@ function ble-decode/.hook/show-progress { text=$sgr$ret$'\e[m '$text fi - ble-edit/info/show ansi "$text" + ble/edit/info/show ansi "$text" _ble_edit_info_scene=decode_input_progress } function ble-decode/.hook/erase-progress { [[ $_ble_edit_info_scene == decode_input_progress ]] || return 1 if ((${#_ble_decode_input_original_info[@]})); then - ble-edit/info/show store "${_ble_decode_input_original_info[@]}" + ble/edit/info/show store "${_ble_decode_input_original_info[@]}" else - ble-edit/info/default + ble/edit/info/default fi } @@ -2509,7 +2509,7 @@ function ble/decode/cmap/initialize { if [[ $dump -nt $init ]]; then source "$dump" else - ble-edit/info/immediate-show text 'ble.sh: generating "'"$dump"'"...' + ble/edit/info/immediate-show text 'ble.sh: generating "'"$dump"'"...' source "$init" ble-bind -D | ble/bin/awk ' { @@ -2528,11 +2528,11 @@ function ble/decode/cmap/initialize { local fbinder=$_ble_base_cache/cmap+default.binder-source _ble_decode_bind_fbinder=$fbinder if ! [[ $_ble_decode_bind_fbinder -nt $init ]]; then - ble-edit/info/immediate-show text 'ble.sh: initializing multichar sequence binders... ' + ble/edit/info/immediate-show text 'ble.sh: initializing multichar sequence binders... ' ble/decode/cmap/.generate-binder-template >| "$fbinder" binder=ble/decode/cmap/.emit-bindx source "$fbinder" >| "$fbinder.bind" binder=ble/decode/cmap/.emit-bindr source "$fbinder" >| "$fbinder.unbind" - ble-edit/info/immediate-show text 'ble.sh: initializing multichar sequence binders... done' + ble/edit/info/immediate-show text 'ble.sh: initializing multichar sequence binders... done' fi fi } diff --git a/src/edit.sh b/src/edit.sh index f9dfa86d..0e9a994e 100644 --- a/src/edit.sh +++ b/src/edit.sh @@ -25,6 +25,11 @@ # @comp # @bind # @bind.bind +# +# 現在の ble/canvas/panel 構成 +# 0 command-line +# 1 追加入力欄 +# 2 infobar ## @bleopt edit_vbell ## 編集時の visible bell の有効・無効を設定します。 @@ -118,6 +123,25 @@ function ble/edit/performs-on-graphical-line { return 0 } +bleopt/declare -n info_display top +function bleopt/check:info_display { + case $value in + (top) + [[ $_ble_canvas_panel_vfill == '' ]] && return 0 + _ble_canvas_panel_vfill= + ble/canvas/panel/clear + return 0 ;; + (bottom) + [[ $_ble_canvas_panel_vfill == 2 ]] && return 0 + _ble_canvas_panel_vfill=2 + ble/canvas/panel/clear + return 0 ;; + (*) + ble/util/print "bleopt: Invalid value for 'info_display': $value" + return 1 ;; + esac +} + ## プロンプトオプション bleopt/declare -v prompt_ps1_final '' bleopt/declare -v prompt_ps1_transient '' @@ -204,6 +228,11 @@ bleopt/declare -v line_limit_length 10000 ## 一括挿入で文字数を超過した時の動作を指定します。 bleopt/declare -v line_limit_type none +# canvas.sh 設定 + +_ble_canvas_panel_focus=0 +_ble_canvas_panel_class=(ble/textarea ble/textarea ble/edit/info) + # #------------------------------------------------------------------------------ # **** prompt **** @line.ps1 @@ -943,9 +972,9 @@ function ble/prompt/notify-readline-mode-change { #------------------------------------------------------------------------------ # **** information pane **** @line.info -## @fn ble-edit/info/.initialize-size +## @fn ble/edit/info/.initialize-size ## @var[out] cols lines -function ble-edit/info/.initialize-size { +function ble/edit/info/.initialize-size { local ret ble/canvas/panel/layout/.get-available-height "$_ble_edit_info_panel" cols=${COLUMNS-80} lines=$ret @@ -953,27 +982,49 @@ function ble-edit/info/.initialize-size { _ble_edit_info_panel=2 _ble_edit_info=(0 0 "") +_ble_edit_info_invalidated= -function ble-edit/info#get-height { +function ble/edit/info#panel::getHeight { + (($1!=_ble_edit_info_panel)) && return 0 if [[ ${_ble_edit_info[2]} ]]; then height=1:$((_ble_edit_info[1]+1)) else height=0:0 fi } +function ble/edit/info#panel::invalidate { + (($1!=_ble_edit_info_panel)) && return 0 + _ble_edit_info_invalidated=1 +} +function ble/edit/info#panel::render { + (($1!=_ble_edit_info_panel)) && return 0 + [[ $_ble_edit_info_invalidated ]] || return 0 + ((_ble_canvas_panel_height[$1])) || return 0 + + local -a DRAW_BUFF=() + ble/canvas/panel#clear.draw "$_ble_edit_info_panel" + if [[ ${_ble_edit_info[2]} ]]; then + ble/canvas/panel#goto.draw "$_ble_edit_info_panel" + ble/canvas/put.draw "${_ble_edit_info[2]}" + ((_ble_canvas_x=_ble_edit_info[0])) + ((_ble_canvas_y+=_ble_edit_info[1])) + fi + ble/canvas/bflush.draw +} -## @fn ble-edit/info/.construct-content type text +## @fn ble/edit/info/.construct-content type text ## @var[out] x y ## @var[out] content -function ble-edit/info/.construct-content { +function ble/edit/info/.construct-content { local cols lines - ble-edit/info/.initialize-size + ble/edit/info/.initialize-size x=0 y=0 content= local type=$1 text=$2 case "$1" in (ansi|esc) local trace_opts=truncate + [[ $bleopt_info_display == bottom ]] && trace_opts=$trace_opts:noscrc [[ $1 == esc ]] && trace_opts=$trace_opts:terminfo local ret= g=0 LINES=$lines ble/canvas/trace "$text" "$trace_opts" @@ -985,13 +1036,13 @@ function ble-edit/info/.construct-content { (store) x=$2 y=$3 content=$4 # 現在の高さに入らない時は計測し直す。 - ((y&2 ;; + ble/util/print "usage: ble/edit/info/.construct-content type text" >&2 ;; esac } -function ble-edit/info/.clear-content { +function ble/edit/info/.clear-content { [[ ${_ble_edit_info[2]} ]] || return 1 local -a DRAW_BUFF=() @@ -1001,16 +1052,16 @@ function ble-edit/info/.clear-content { _ble_edit_info=(0 0 "") } -## @fn ble-edit/info/.render-content x y content +## @fn ble/edit/info/.render-content x y content ## @param[in] x y content -function ble-edit/info/.render-content { +function ble/edit/info/.render-content { local x=$1 y=$2 content=$3 # 既に同じ内容で表示されているとき…。 [[ $content == "${_ble_edit_info[2]}" ]] && return 0 if [[ ! $content ]]; then - ble-edit/info/.clear-content; return "$?" + ble/edit/info/.clear-content; return "$?" fi _ble_edit_info=("$x" "$y" "$content") @@ -1027,7 +1078,7 @@ function ble-edit/info/.render-content { _ble_edit_info_default=(0 0 "") _ble_edit_info_scene=default -## @fn ble-edit/info/show type text +## @fn ble/edit/info/show type text ## ## @param[in] type ## @@ -1045,69 +1096,65 @@ _ble_edit_info_scene=default ## これらの文字列について ## 画面からはみ出る文字列に関しては自動で truncate される。 ## -function ble-edit/info/show { +function ble/edit/info/show { local type=$1 text=$2 if [[ $text ]]; then local x y content= - ble-edit/info/.construct-content "$@" - ble-edit/info/.render-content "$x" "$y" "$content" + ble/edit/info/.construct-content "$@" + ble/edit/info/.render-content "$x" "$y" "$content" ble/util/buffer.flush >&2 _ble_edit_info_scene=show else - ble-edit/info/default + ble/edit/info/default fi } -function ble-edit/info/set-default { +function ble/edit/info/set-default { local type=$1 text=$2 local x y content - ble-edit/info/.construct-content "$type" "$text" + ble/edit/info/.construct-content "$type" "$text" _ble_edit_info_default=("$x" "$y" "$content") } -function ble-edit/info/default { +function ble/edit/info/default { _ble_edit_info_scene=default - (($#)) && ble-edit/info/set-default "$@" + (($#)) && ble/edit/info/set-default "$@" return 0 } -function ble-edit/info/clear { - ble-edit/info/default +function ble/edit/info/clear { + ble/edit/info/default } -## @fn ble-edit/info/hide -## @fn ble-edit/info/reveal +## @fn ble/edit/info/hide +## @fn ble/edit/info/reveal ## ## これらの関数は .newline 前後に一時的に info の表示を抑制するための関数である。 ## この関数の呼び出しの後に flush が入ることを想定して ble/util/buffer.flush は実行しない。 ## -function ble-edit/info/hide { - ble-edit/info/.clear-content +function ble/edit/info/hide { + ble/edit/info/.clear-content } -function ble-edit/info/reveal { +function ble/edit/info/reveal { if [[ $_ble_edit_info_scene == default ]]; then - ble-edit/info/.render-content "${_ble_edit_info_default[@]}" + ble/edit/info/.render-content "${_ble_edit_info_default[@]}" fi } -function ble-edit/info/immediate-show { - local x=$_ble_canvas_x y=$_ble_canvas_y - ble-edit/info/show "$@" - local -a DRAW_BUFF=() - ble/canvas/goto.draw "$x" "$y" - ble/canvas/bflush.draw +function ble/edit/info/immediate-show { + local ret; ble/canvas/panel/save-position + ble/edit/info/show "$@" + ble/canvas/panel/load-position "$ret" ble/util/buffer.flush >&2 } -function ble-edit/info/immediate-clear { - local x=$_ble_canvas_x y=$_ble_canvas_y - ble-edit/info/clear - ble-edit/info/reveal - local -a DRAW_BUFF=() - ble/canvas/goto.draw "$x" "$y" - ble/canvas/bflush.draw +function ble/edit/info/immediate-clear { + local ret; ble/canvas/panel/save-position + ble/edit/info/clear + ble/edit/info/reveal + ble/canvas/panel/load-position "$ret" ble/util/buffer.flush >&2 } # #------------------------------------------------------------------------------ -# **** edit **** @edit +# **** edit **** @edit.content _ble_edit_VARNAMES=( _ble_edit_str @@ -1643,10 +1690,10 @@ function ble-edit/attach/TRAPWINCH { if [[ ! $_ble_textarea_invalidated && $_ble_term_state == internal ]]; then _ble_textmap_pos=() ble-edit/bind/stdout.on - ble-edit/info/hide + ble/edit/info/hide ble/util/buffer "$_ble_term_ed" - ble-edit/info/reveal - ble/textarea#redraw + ble/edit/info/reveal + ble/canvas/panel/render ble-edit/bind/stdout.off fi fi @@ -1707,9 +1754,9 @@ _ble_textarea_VARNAMES=( _ble_textarea_local_VARNAMES=() -## @fn ble/textarea/panel#get-height +## @fn ble/textarea#panel::getHeight ## @var[out] height -function ble/textarea/panel#get-height { +function ble/textarea#panel::getHeight { if [[ $1 == "$_ble_textarea_panel" ]]; then local min=$((_ble_edit_prompt[2]+1)) max=$((_ble_textmap_endy+1)) ((min&2 # Note: ble-decode-key が中断しない為の設定 #D0998 @@ -7301,8 +7365,8 @@ function ble/builtin/read/.loop { ble/util/is-stdin-ready && continue ble-edit/content/check-limit ble-decode/.hook/erase-progress - ble-edit/info/reveal - ble/textarea#render + ble/edit/info/reveal + ble/canvas/panel/render ble/util/buffer.flush >&2 done @@ -7310,7 +7374,7 @@ function ble/builtin/read/.loop { if [[ $_ble_edit_read_context == internal ]]; then local -a DRAW_BUFF=() ble/canvas/panel#set-height.draw "$_ble_textarea_panel" 0 - ble/canvas/goto.draw "$x0" "$y0" + ble/canvas/panel/load-position.draw "$pos0" ble/canvas/bflush.draw else if ((_ble_edit_read_accept==1)); then @@ -7877,17 +7941,17 @@ function ble-edit/bind/.tail-without-draw { if ((_ble_bash>=40000)); then function ble-edit/bind/.tail { - ble-edit/info/reveal - ble/textarea#render - ble/util/idle.do && ble/textarea#render + ble/edit/info/reveal + ble/canvas/panel/render + ble/util/idle.do && ble/canvas/panel/render ble/textarea#adjust-for-bash-bind # bash-4.0+ ble-edit/bind/stdout.off } else function ble-edit/bind/.tail { - ble-edit/info/reveal - ble/textarea#render # bash-3 では READLINE_LINE を設定する方法はないので常に 0 幅 - ble/util/idle.do && ble/textarea#render # bash-4.0+ + ble/edit/info/reveal + ble/canvas/panel/render # bash-3 では READLINE_LINE を設定する方法はないので常に 0 幅 + ble/util/idle.do && ble/canvas/panel/render # bash-4.0+ ble-edit/bind/stdout.off } fi @@ -7946,7 +8010,7 @@ function ble/widget/external-command { BASH_COMMAND=("$*") [[ ${BASH_COMMAND//[$_ble_term_IFS]} ]] || return 1 - ble-edit/info/hide + ble/edit/info/hide ble/textarea#invalidate local -a DRAW_BUFF=() ble/canvas/panel#set-height.draw "$_ble_textarea_panel" 0 diff --git a/src/util.sh b/src/util.sh index a64617ae..7834c72d 100644 --- a/src/util.sh +++ b/src/util.sh @@ -443,7 +443,13 @@ function ble/array#pop { } ## @fn ble/array#unshift arr value... function ble/array#unshift { - builtin eval "$1=(\"\${@:2}\" \"\${$1[@]}\")" + builtin eval -- "$1=(\"\${@:2}\" \"\${$1[@]}\")" +} +## @fn ble/array#shift arr count +function ble/array#shift { + # Note: Bash 4.3 以下では ${arr[@]:${2:-1}} が offset='${2' + # length='-1' に解釈されるので、先に算術式展開させる。 + builtin eval -- "$1=(\"\${$1[@]:$((${2:-1}))}\")" } ## @fn ble/array#reverse arr function ble/array#reverse { @@ -4110,21 +4116,25 @@ function ble/term/visible-bell/.show { 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/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$message$_ble_term_sgr0" ble/canvas/put-cud.draw 1 ble/canvas/put-hpa.draw $((1+_ble_canvas_x)) fi - ble/canvas/flush.draw + 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}" @@ -4141,21 +4151,25 @@ function ble/term/visible-bell/.update { 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/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$message$_ble_term_sgr0" ble/canvas/put-cud.draw 1 ble/canvas/put-hpa.draw $((1+_ble_canvas_x)) fi - ble/canvas/flush.draw + ble/canvas/bflush.draw + ble/util/buffer.flush >&2 else ble/util/put "${_ble_term_visible_bell_show//'%message%'/$sgr$message}" fi @@ -4171,6 +4185,8 @@ function ble/term/visible-bell/.clear { 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" @@ -4178,6 +4194,7 @@ function ble/term/visible-bell/.clear { #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 @@ -4474,23 +4491,38 @@ function ble/term/DA2/notify { blehook/invoke DA2R } +_ble_term_DECSTBM= +function ble/term/test-DECSTBM.hook { + (($1==2)) && _ble_term_DECSTBM=$'\e[%s;%sr' +} +function ble/term/test-DECSTBM { + local -a DRAW_BUFF=() + ble/canvas/panel/goto-top-dock.draw + ble/canvas/put.draw "$_ble_term_sc"$'\e[1;2r' + ble/canvas/put-cup.draw 2 1 + ble/canvas/put-cud.draw 1 + ble/term/CPR/request.draw ble/term/test-DECSTBM.hook + ble/canvas/put.draw $'\e[;r'"$_ble_term_rc" + ble/canvas/bflush.draw +} + #---- DSR(6) ------------------------------------------------------------------ # CPR (CURSOR POSITION REPORT) -_ble_term_CPR_hook= +_ble_term_CPR_hook=() function ble/term/CPR/request.buff { - _ble_term_CPR_hook=$1 + ble/array#push _ble_term_CPR_hook "$1" ble/util/buffer $'\e[6n' return 147 } function ble/term/CPR/request.draw { - _ble_term_CPR_hook=$1 + ble/array#push _ble_term_CPR_hook "$1" ble/canvas/put.draw $'\e[6n' return 147 } function ble/term/CPR/notify { - local hook=$_ble_term_CPR_hook - _ble_term_CPR_hook= + local hook=${_ble_term_CPR_hook[0]} + ble/array#shift _ble_term_CPR_hook [[ ! $hook ]] || "$hook" "$1" "$2" } @@ -4614,6 +4646,7 @@ function ble/term/finalize { } function ble/term/initialize { ble/term/stty/initialize + ble/term/test-DECSTBM ble/term/enter }