Skip to content

Commit

Permalink
decode: support decode_abort_char for modifyOtherKeys
Browse files Browse the repository at this point in the history
  • Loading branch information
akinomyoga committed Mar 11, 2020
1 parent da6cc47 commit ad98416
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 11 deletions.
1 change: 1 addition & 0 deletions memo/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
- decode: fix error messages of BSD `sed` rejecting unencoded bytes from `bind -p` (reported by dylankb) `#D1277` 0cc9160
- edit: provide proper `$BASH_COMMAND` and `$_` for PS1, PROMPT_COMMAND, PRECMD, etc. `#D1276` 7db48dc
- edit (quoted-insert): insert literal key sequence `#D1291` 0000000
- decode: support `decode_abort_char` for `modifyOtherKeys` `#D1293` 0000000

## Compatibility

Expand Down
35 changes: 35 additions & 0 deletions note.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2667,6 +2667,41 @@ bash_tips
Done (実装ログ)
-------------------------------------------------------------------------------

2020-03-12

* decode: modifyOtherKeys の時の abort [#D1293]
C-\ で abort するという話を書いたが。
よく考えてみると modifyOtherKeys にしている時には動かないのでは。

さて、modifyOtherKeys にしていると C-c を押しても 3 は決して入って来ない。
ble-decode-key の直前で待ち伏せしなければならない。
然し、現在の実装だと ble-decode-key の結果はキャッシュされていないので、
其処で待ち伏せする事にするとそれより前の処理は全て実行された後になる。
それだとキャンセルした事にならない。
或いは key の計算と実行を切り離して key を検査してから実行を行うべきか。

然し、確認してみて思ったが検査はやはり byte のレベルで実行しなければならない。
実際に char のキャッシュも byte のレベルでしかキャンセルしない様になっている
(唯、制御文字に関しては decode を通しても変化しないという前提はある気がする)。

その様に考えると、decode_abort_char に複数のバイトから為るシーケンスを
登録できる様にしなければ動く様にはならないという気がする。

うーん。decode_abort_seq なる物を定義して byte を受け取った時に判定する。
然し、それだとユーザが端末ごとに正しい値を設定しなければならない。
更に modifyOtherKeys なので理解するのが難しい。
やはり自動的に検出する様にしなければならない。

うーん。可能なシーケンスは実は有限個しかない。
と思ったが本当だろうか。chars と bytes に跨って記録される事もあるのでは。
然し、シーケンスの到着のタイミング等を考えるとそれが起こるとは考えにくい。
取り敢えずは bytes に全て含まれている場合を考える事にする。

CSI の表現で 2 種類ある。> の有無で 2 種類ある。CSI >? 27 ; 5 ; code
27~ 形式 と u 形式で 2 種類ある。

→これについては実装した。

2020-03-08

* vi: vi-commandn/nth-column の算術式がおかしい (reported by andychu) [#D1292]
Expand Down
94 changes: 83 additions & 11 deletions src/decode.sh
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,81 @@ function ble-decode/.hook/erase-progress {
fi
}

## 関数 ble-decode/.check-abort byte
## bleopt_decode_abort_char による decode abort を検出します。
##
## @remarks modifyOtherKeys も考慮に入れると実は C-x の形式のキーは
## "CSI 27;5; code ~" や "CSI code ;5u" の形式で送られてくる。
## _ble_decode_input_buffer に記録されている受信済みバイトも検査して
## これらのシーケンスを構成していないか確認する必要がある。
##
function ble-decode/.check-abort {
if (($1==bleopt_decode_abort_char)); then
local nbytes=${#_ble_decode_input_buffer[@]}
local nchars=${#_ble_decode_char_buffer[@]}
((nbytes||nchars)); return
fi

(($1==0x7e||$1==0x75)) || return 1

local i=$((${#_ble_decode_input_buffer[@]}-1))
local n
((n=bleopt_decode_abort_char,
n+=(1<=n&&n<=26?96:64)))

if (($1==0x7e)); then
# Check "CSI >? 27 ; 5 ; XXX ~"

# Check code
for ((;n;n/=10)); do
((i>=0&&_ble_decode_input_buffer[i--]==n%10+48)) || return 1
done

# Check "27;5;"
((i>=4)) || return 1
((_ble_decode_input_buffer[i--]==59)) || return 1
((_ble_decode_input_buffer[i--]==53)) || return 1
((_ble_decode_input_buffer[i--]==59)) || return 1
((_ble_decode_input_buffer[i--]==55)) || return 1
((_ble_decode_input_buffer[i--]==50)) || return 1

elif (($1==0x75)); then
# Check "CSI >? XXX ; 5 u"

# Check ";5"
((i>=1)) || return 1
((_ble_decode_input_buffer[i--]==53)) || return 1
((_ble_decode_input_buffer[i--]==59)) || return 1

# Check code
for ((;n;n/=10)); do
((i>=0&&_ble_decode_input_buffer[i--]==n%10+48)) || return 1
done
fi

# Skip ">"
((i>=0&&_ble_decode_input_buffer[i]==62&&i--))

# Check CSI ("\e[", "\xC0\x9B[" or "\xC2\x9B")
# ENCODING: UTF-8 (\xC0\x9B)
((i>=0)) || return 1
if ((_ble_decode_input_buffer[i]==0x5B)); then
if ((i>=1&&_ble_decode_input_buffer[i-1]==0x1B)); then
((i-=2))
elif ((i>=2&&_ble_decode_input_buffer[i-1]==0x9B&&_ble_decode_input_buffer[i-2]==0xC0)); then
((i-=3))
else
return 1
fi
elif ((_ble_decode_input_buffer[i]==0x9B)); then
((--i>=0&&_ble_decode_input_buffer[i--]==0xC2)) || return 1
else
return 1
fi
(((i>=0||${#_ble_decode_char_buffer[@]}))); return
return 0
}

function ble-decode/.hook {
if ble/util/is-stdin-ready; then
ble/array#push _ble_decode_input_buffer "$@"
Expand All @@ -481,17 +556,14 @@ function ble-decode/.hook {
ble-decode/PROLOGUE

# abort #D0998
if (($1==bleopt_decode_abort_char)); then
local nbytes=${#_ble_decode_input_buffer[@]}
local nchars=${#_ble_decode_char_buffer[@]}
if ((nbytes||nchars)); then
_ble_decode_input_buffer=()
_ble_decode_char_buffer=()
ble/term/visible-bell "Abort by 'bleopt decode_abort_char=$bleopt_decode_abort_char'"
shift
# 何れにしても EPILOGUE を実行する必要があるので下に流れる。
# ble/term/visible-bell を表示する為には PROLOGUE の後でなければならない事にも注意する。
fi
if ble-decode/.check-abort "$1"; then
_ble_decode_char__hook=
_ble_decode_input_buffer=()
_ble_decode_char_buffer=()
ble/term/visible-bell "Abort by 'bleopt decode_abort_char=$bleopt_decode_abort_char'"
shift
# 何れにしても EPILOGUE を実行する必要があるので下に流れる。
# ble/term/visible-bell を表示する為には PROLOGUE の後でなければならない事にも注意する。
fi

local chars
Expand Down

0 comments on commit ad98416

Please sign in to comment.