Skip to content

Commit

Permalink
decode: consume incomplete keyseq in macros
Browse files Browse the repository at this point in the history
  • Loading branch information
akinomyoga committed Feb 5, 2024
1 parent 82bfa66 commit 27e6309
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
- syntax: save stat after command name for consistent completion-context `#D2126` 50d6f1bb
- term: fix control sequences for hiding cursor (reported by n87) `#D2130` f9b9aea8
- highlight: fix inconsistent tab width in plain layer (reported by dgudim) `#D2132` xxxxxxxx
- decode: consume incomplete keyseq in macros `#D2137` xxxxxxxx

## Compatibility

Expand Down
15 changes: 15 additions & 0 deletions memo/D2137.bashrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# 2024-02-04

source out/ble.sh --norc
ble/function#advice \
after ble/decode/cmap/decode-chars \
'[[ ${keyseq-} ]] && ble/debug/print-variables keyseq chars keys'
bind '"\e[A": "\C-x\xC0\x96\C-x\xC0\x8F\C-x\xC0\x8D"'
bind '"\C-x\xC0\x96": ""'
bind '"\C-x\xC0\x8F": ""'
bind '"\C-x\xC0\x8D": ""'
bind '"\e": ""'
bind '"\e\e": ""'
bind '"\e[123": ""'
ble/function#advice \
clear ble/decode/cmap/decode-chars
112 changes: 112 additions & 0 deletions note.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7094,6 +7094,118 @@ bash_tips

2024-02-04

* decode: bind '"keyseq": ""' で keyseq が正しく解析されていない [#D2137]

atuin の macro chain の実験中に ble.sh が変な挙動をする

結構無理な事をしているから仕方がないとは言え何故この様な振る舞いをするのか
については確認しておきたい。keylog を見ると C-x が重複して受信されて それか
ら SS3 が重複した形になっている何故だろうか。

.MACRO は ble-decode-char に対してデータを送っている様だ。ble-decode-char
が受け取っているシーケンスを見る限りは何も問題ない気がする。但し、macro
chain の為に中で新しい keyseq を解析しているのでその解析が途中で入っている。

? reject: 或いはその途中の解析が状態を破壊している可能性?

ble-decode-key が受け取っているシーケンスも問題ない気がする、と思ったがよ
く見ると 143 (\M-\C-o) を重複して受け取っている。これは内部で解析を行った
直後である。そう言えば最近 ble-decode-key の解析を修正して新しい状態変数
を導入したのだった。ちゃんとその状態変数は localize できているのか? blame
で確認するとその変数は _ble_decode_char2_modseq である。bind の為の呼び出
しは以下の経路で行われている。

'ble-decode-char'
'ble/decode/cmap/decode-chars'
'ble/builtin/bind/.initialize-keys-and-value'
'ble/builtin/bind/option:-'
'ble/builtin/bind/.process'
'ble/builtin/bind'
'bind'

然し _ble_decode_char2_modseq を localize しても問題は直らない。他にも途
中状態が破壊されている箇所があるという事の気がする。decode-chars の呼び出
し元で確認する必要がある気がする → 呼び出し元で declare で全変数を dump
して前後比較してみたが _ と keys しか変わっていない。前者は元々変わる物で
後者は今回目的の変更対象なので期待している通りである。他の状態は何も変更
されていない。

或いは全く bind を実行しなくても問題が発生するのだろうか? 試してみる →
再現した。つまり ble/decode/cmap/decode-chars は関係ない。

実は以下の設定だけで問題が再現した。不思議なのは何故最後から二番目だけ問題
が発生しているのかという事。うーん。keyseq の一致に失敗しているという事だと
思われるが?

bind '"\e[A": "\C-x\xC0\x96\C-x\xC0\x8F\C-x\xC0\x8D"'
bind '"\C-x\xC0\x96": ""'
bind '"\C-x\xC0\x8F": ""'
bind '"\C-x\xC0\x8D": ""'

うーん。keyseq の一致を確認してみると、そもそも \C-x\xC0 の時点で
keybinding が見つかっている。そして \C-x\xC0\x8F に対応する keybinding が存
在しない事になっている。何故? つまり、bind を実行した時点での問題の気がする。

改めて .initialize-keys-and-value の結果を確認する。

keyseq='"\C-x\xC0\x96"' chars=('24' '192' '150') keys=('67108984' '192' '150')
keyseq='"\C-x\xC0\x8F"' chars=('24' '192' '143') keys=('67108984' '192')
keyseq='"\C-x\xC0\x8D"' chars=('24' '192' '141') keys=('67108984' '192' '141')

分かった。つまり、最後の C-o が処理されずに中途半端な状態になっているので、
keys の中に反映されていないという事。decode-chars では中途半端に pending に
なっている物を flush する機能が必要なのではないか?

うーん。読んだがよく分からない。ent を取得する部分で何の sequence にも属さ
ない文字を無理やり入れたらいい感じに残留している物がなくなるまで吐き出され
る様な気がする。丁度 __ignore__ というのがあるのでそれを入れて、その上で
__ignore__ を削除すれば良いのでは? と思って試してみたら動く。しかも
__ignore__ は結果に混入していない。

? ok: 然し __ignore__ が消えるのは今回は好ましい振る舞いだが何故だろう? 通
常文字として挿入されたりしないのか? と思ったが元より __ignore__ は
csistat の処理の途中で無視するべき (or 処理済み) のキーが発生した時にそれ
にお着替えているのだから、今回の場合も M-__ignore__ みたいな物が生成され
ない限りは __ignore__ も生成されないのである。

? fixed: だとすると、"\e" を正しく処理する事はできるのだろうか? meta
modifier は未だ flush されずに残留する様な気がする。

keyseq='"\e"' chars=('27') keys=()

やっぱり駄目だ。ちゃんと処理できていない。修正が必要である。

% コードを読む限りは未だ処理されていない modifier の key 列は
% _ble_decode_char2_modseq に記録されている。特に失敗した時には全てこれを
% 直接 ble-decode-key に流し込んでいるので、_ble_decode_char2_modseq の中
% 身をそのまま keys に追加すれば問題ない気がする。
%
% keyseq='"\e"' chars=('27') keys=('27')
%
% 動いている。と、思ったが C-[ に変換しなくて良いのだろうか? うーん。然し
% 最終的に同じ key 列を出力している限りは特に問題はないのでは? 問題は
% __ignore__ が発生しない状況で本当に同じキー列が生成されるのかという事。
% うーん。そもそも 27 に関しては失敗する事がないから、中途半端な 27 があ
% る keybinding はそもそも意味がない? 改めてコードを見る。

うーん。別に _ble_decode_char2_modseq を直接 ble-decode-key に渡している
訳では無い様だ。寧ろ _ble_decode_char2_modkcode の方を渡していて、その時
にその key を生成するのに使った char の列として _ble_decode_char2_modseq
が使われているのに過ぎない。

keyseq='"\e"' chars=('27') keys=('67108955')

改めてそれに倣って見た所、元よりちゃんと C-[ への変換は実施されていた様だ。
OK。取り敢えずこれでOK \e\e の時の振る舞いもチェックしておく。

keyseq='"\e\e"' chars=('27' '27') keys=('201326683')

問題なさそうだ。

? ok: 閉じていない CSI シーケンスはちゃんと分解されてから処理される?

keyseq='"\e[123"' chars=('27' '91' '49' '50' '51') keys=('134217819' '49' '50' '51')

* contrib: execmark が colorglass に対応していない [#D2136]

確認してみた所、これは元々 trace を使って一気に error と elapsed を処理して
Expand Down
6 changes: 5 additions & 1 deletion src/decode.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2873,6 +2873,7 @@ function ble/decode/cmap/decode-chars {
local _ble_decode_char2_reach_seq=
local _ble_decode_char2_modifier=
local _ble_decode_char2_modkcode=
local -a _ble_decode_char2_modseq=()

# suppress unrelated triggers
local _ble_decode_char__hook=
Expand All @@ -2893,9 +2894,12 @@ function ble/decode/cmap/decode-chars {
local -a ble_decode_bind_keys=()
local _ble_decode_key__hook=ble/decode/cmap/decode-chars.hook
local ble_decode_char_sync=1 # ユーザ入力があっても中断しない
ble-decode-char "$@"
ble-decode-char "$@" "$_ble_decode_KCODE_IGNORE"

keys=("${ble_decode_bind_keys[@]}")
if [[ $_ble_decode_char2_modkcode ]]; then
ble/array#push keys "$_ble_decode_char2_modkcode"
fi
}

#------------------------------------------------------------------------------
Expand Down

0 comments on commit 27e6309

Please sign in to comment.