Skip to content

Commit

Permalink
prompt: invalidate prompt and textarea on prompt setting changes
Browse files Browse the repository at this point in the history
  • Loading branch information
akinomyoga committed Feb 22, 2021
1 parent 5f9adfe commit 1f55913
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 4 deletions.
2 changes: 1 addition & 1 deletion ble.pp
Expand Up @@ -790,7 +790,7 @@ function ble-attach {
ble/term/enter # 3ms (起動時のずれ防止の為 stty)
ble-edit/initialize # 3ms
ble-edit/attach # 0ms (_ble_edit_PS1 他の初期化)
ble/textarea#redraw # 37ms
ble/canvas/panel/render # 37ms
ble/util/buffer.flush >&2

# keymap 初期化
Expand Down
1 change: 0 additions & 1 deletion keymap/vi.sh
Expand Up @@ -408,7 +408,6 @@ function ble/keymap:vi/update-mode-name {

if [[ $bleopt_keymap_vi_mode_update_prompt ]] || ble/util/test-rl-variable show-mode-in-prompt; then
ble/prompt/clear
ble/textarea#invalidate
fi

local name=
Expand Down
3 changes: 2 additions & 1 deletion memo/ChangeLog.md
Expand Up @@ -35,6 +35,7 @@
- edit (`ble/builtin/read`): cancel by <kbd>C-d</kbd> on an empty line `#D1473` ecb8888
- syntax: change syntax context after `time ;` and `! ;` for Bash 4.4 `#D1477` 4628370
- decode (rlfunc): update mapping `vi-replace` in `imap` and `vi-editing-mode` in `nmap` (reported by onelittlehope) `#D1484` f2ca811
- prompt: invalidate prompt and textarea on prompt setting changes `#D1492` 0000000

## Fixes

Expand All @@ -57,7 +58,7 @@
- edit: clear graphic rendition on newlines and external commands `#D1479` 18bb2d5
- mandb: improve extraction and cache for each locale `#D1480` 3588158
- decode (rlfunc): work around incomplete bytes in keyseq (reported by onelittlehope) `#D1483` 3559658 beb0383 37363be
- main: fix a bug that unset `IFS` is not correctly restored `#D1489` 0000000
- main: fix a bug that unset `IFS` is not correctly restored `#D1489` 808f6f7

## Compatibility

Expand Down
112 changes: 112 additions & 0 deletions note.txt
Expand Up @@ -1206,6 +1206,18 @@ bash_tips

2021-02-22

* global: IFS 対策

多くの関数は IFS が普通の値になっているという事を前提にして書かれている。
ble.sh の中では一時的に IFS を設定して動作する様になっているが、
ユーザーから使用された時に IFS に変な値が設定されている可能性は排除でいない。

* 引数を $* で渡された時の対策は取り敢えず grc -F で ${* もしくは $* に一致させて確認した。
* 配列に対する単語分割 =($...) に関してもチェックは行った。

他に配列を結合する処理に関しても注意が必要になる可能性がある。
つまり、aa="${arr[*]}" の形の処理である。

* cavnas: 描画の最中で status が高さを取得する時に textarea の内容を削り取る可能性がある

現在の render 中に配置を決定する仕組みは問題があるので再考する必要がある。
Expand Down Expand Up @@ -3746,6 +3758,106 @@ bash_tips

2021-02-22

* prompt: status line が最初の起動時に表示されていない [#D1492]

| 何故だろうか。。。うーん。プロンプトが初期化される前だから? でもプロンプト
| が初期化されたら…うーん?
|
| screen の中だと遅れて statusline が表示されるが、contra の中にいると次に何
| か新しく表示されるまで何も表示されない。そもそもこの違いは何処から来るのだ
| ろうか。screen の場合には誰かが invalidate しないと再描画がなされない筈なの
| である。
|
| * screen で何故再描画が実施されるのか。調べてみると何らかのデータを受信した
| 折に screen の中での再描画が走っている。
|
| DA2R を受信した時に再描画が走っているのだろうと思ったがそうでもない様だ。
| contra でも DA2R は受信している。また、DA2R を受信してから一拍置いてから
| 再描画が走っている様に見える。
|
| もう少し詳しく受信しているバイト列を確認する事にする。
|
| % うーん。分かった気がする。screen が CPR に応答した時に char_width_mode
| % が変わって invalidate が起こっているのではないかという気がする。contra
| % については CPR に応答していないが為に char_width_mode による invalidate
| % が起こっていない、という事なのだろう。
| %
| % →と思ったがやはり CPR ではない様である。先ず contra は一切 CPR に返事を
| % しないのは予想通り。一方で、screen はそもそも char_width_mode についての
| % CPR 要求はしていない。何故なら char_width_mode に emacs を指定しているか
| % ら自動判定にはなっていないのである。代わりに DECSTBM の判定に使っている
| % CPR を受信している。然し、その受信した CPR を完全に無視する様に書き換えて
| % もやはり再描画は発生しているのである。
|
| 再描画が起こっている理由について調べる。$caret_state が変化している事によ
| る再描画の様子である。
|
| ? yes: というより本当にこの dirty の判定の所まで到達しているのだろうか。
| もっと前の段階て撥ねられていないだろうか。と思ったが、大丈夫の様だ。こ
| の判定の部分までは到達している。
|
| caret_state の値について出力して確認してみる。
|
| contra 内部 screen 内部
| ---------------- ------------------
| old=0:0:0::: old=0:0:0:::
| new=0:0:0::: new=0:0:0:::
| dirty:2 dirty:2
| old=0:0:0::: old=0:0:0:::
| new=0:0:0::: new=0:0:0:::
| dirty:clean dirty:clean
| old=0:0:0:::
| new=1:0:0:::
| dirty:3
| chars=(DA2R...) chars=(DA2R CPR)
| CPR ble/term/t
| old=1:0:0::: old=0:0:0:::
| new=1:0:0::: new=0:0:0:::
| dirty:clean dirty:clean
| old=1:0:0::: old=0:0:0:::
| new=1:0:0::: new=1:0:0:::
| dirty:clean dirty:3
|
| 起動の振る舞いを見ると contra の場合には、CPR DA2R の応答を貰うよりも前に
| 再描画の機会がある様だ。うーん。
|
| ? 不思議な事に keymap_vi_load の実行は比較的最初に済んでいるという事であ
| る。もう一つの不思議な事は contra の内部でも dirty:3 が発生しているのに
| も拘らず prompt update が実行されていないという点。prompt の update の
| 条件についても確認するべき気がする。
|
| どうやらプロンプトが更新されたりされなかったりするのは history を読み込
| んだり読み込まなかったりする事による物のようである。何故端末が異なると
| history の読み込みに影響が出るのかは謎である。しかも、確率的にではなく
| て確実にそれぞれの端末で異なる一貫した動作になっているのも不思議な事で
| ある。

[状況]

最初に描画する瞬間は未だ keymap も読み込んでいない状態なので keymap_vi_load
を経由して設定される prompt_status_line も表示されない。その後で
keymap_vi_load が実行され、更にその後で再描画がかかる。

違いは再描画がかかるタイミングが contra の中と screen の中で何故か異なる事
によって出てくる様に見える。

* keymap_vi_load との前後関係は実は関係ない。再描画がかかるのは何れにしても
既に prompt_status_line が初期化された後の話なので、もしプロンプトの更新
がかかるのであればどちらの場合でもちゃんとステータスラインが表示される筈
である。

* 代わりにコマンド履歴の読み込みのタイミングとの前後関係が問題になっている。
screen の中では DA2R, CPR を受信した後に再描画が起こるが、この段階でコマ
ンド履歴が読み込み済み状態になっている。これにより再描画に際してプロンプ
トの再計算が実施される。一方で contra の場合には DA2R を受信する前に再描
画がかかって、この時には未だコマンド履歴が読み込まれていない。この為に、
プロンプトの更新の必要がないと判定されてプロンプトの更新無しで再描画だけ
が行われている。

何れにしても設計としてはプロンプトの設定を変更したら ble/prompt/clear を実
行するべきで、更に、ble/prompt/clear を実行する時には
ble/textarea#invalidate も実行するべきという事。

* global: IFS 対策 [#D1491]

多くの関数は IFS が普通の値になっているという事を前提にして書かれている。
Expand Down
12 changes: 11 additions & 1 deletion src/edit.sh
Expand Up @@ -155,16 +155,25 @@ bleopt/declare -v prompt_term_status ''
bleopt/declare -o rps1 prompt_rps1
bleopt/declare -o rps1_transient prompt_rps1_transient

function bleopt/check:prompt_rps1 { ble/prompt/clear; return 0; }
function bleopt/check:prompt_xterm_title { ble/prompt/clear; return 0; }
function bleopt/check:prompt_screen_title { ble/prompt/clear; return 0; }
function bleopt/check:prompt_term_status { ble/prompt/clear; return 0; }

## @bleopt prompt_eol_mark
bleopt/declare -v prompt_eol_mark $'\e[94m[ble: EOF]\e[m'

bleopt/declare -v prompt_status_line ''
bleopt/declare -n prompt_status_align left
ble/color/defface prompt_status_line fg=231,bg=240

function bleopt/check:prompt_status_line { ble/prompt/clear; return 0; }
function bleopt/check:prompt_status_align {
case $value in
(left|right|center) return 0 ;;
(left|right|center)
[[ $bleopt_prompt_status_line ]] &&
ble/prompt/clear
return 0 ;;
(*)
ble/util/print "bleopt prompt_status_align: unsupported value: '$value'" >&2
return 1 ;;
Expand Down Expand Up @@ -1109,6 +1118,7 @@ function ble/prompt/update {
}
function ble/prompt/clear {
_ble_edit_prompt[0]=
ble/textarea#invalidate
}
function ble/prompt/notify-readline-mode-change {
if ble/util/test-rl-variable show-mode-in-prompt; then
Expand Down

0 comments on commit 1f55913

Please sign in to comment.