Skip to content

Commit

Permalink
stty: do not remove keydefs for "C-u", "C-v", "C-w", and "C-?"
Browse files Browse the repository at this point in the history
  • Loading branch information
akinomyoga committed Nov 28, 2021
1 parent b1be640 commit 82f74f0
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 13 deletions.
1 change: 1 addition & 0 deletions docs/ChangeLog.md
Expand Up @@ -233,6 +233,7 @@
- decode: work around openSUSE broken `/etc/inputrc` `#D1662` e5b0c86
- decode: work around the overwritten builtin `set` (reported by eadmaster) `#D1680` a6b4e2c
- complete: work around the variable leaks by `virsh` completion from `libvirt` (reported by telometto) `#D1682` 0000000
- stty: do not remove keydefs for <kbd>C-u</kbd>, <kbd>C-v</kbd>, <kbd>C-w</kbd>, and <kbd>C-?</kbd> (reported by laoshaw) `#D1683` 0000000

## Internal changes and fixes

Expand Down
2 changes: 1 addition & 1 deletion memo/done.txt
Expand Up @@ -55939,7 +55939,7 @@
やはり C-v は stty に食われて bash にシグナルとして伝達する。
問題が生じなければ stty lnext undef で放置という事で良い気がする。

然し C-z に bind 擦る為に結局 stty susp undef をして、
然し C-z に bind する為に結局 stty susp undef をして、
コマンド実行直前に復元して、コマンド実行後にまた undef するという事をしたくなりそうだから、
その際には lnext も復元させる事にすればよい。

Expand Down
132 changes: 132 additions & 0 deletions note.txt
Expand Up @@ -5448,6 +5448,138 @@ bash_tips
Done (実装ログ)
-------------------------------------------------------------------------------

2021-11-28

* 2021-11-05 vim の :term 内部で backspace が効かない (reported by laoshaw) [#D1683]

C-q に続けて backspace を入力しても何も反応はない。auto-complete が表示さ
れている状態で backspace を入力すると auto-complete がキャンセルされる事
から何かしらは受信している。

modifyOtherKeys を off にしても問題は発生する。

ble/debug/keylog#start で確かめてみた所、何と backspace に対して NUL が受
信されている。bash 本体はちゃんと受信できているという事を見ると bind の問
題だろうか。

| * うーん。然し端末 (host to terminal) では DEL と NUL が同じ効果というの
| もある。それに関連して vim terminal が何か勝手に変化させている可能性?
| でもそうだとしたら他の application でもっと問題になる筈である。何より
| readline がちゃんと動いている。
|
| * 最新版の bash でも同様に問題が発生する。なので version 依存のバグという
| 訳でもない様に思われる。
|
| * 単に以下を bind しただけでは問題は再現しない。
|
| $ bind -x '"\C-@": echo NUL'
| $ bind -x '"\C-?": echo DEL'
| $ bind -x '"\C-h": echo BS'
|
| * vim :term の中の ble.sh で builtin bind -Xs の結果を見てもちゃんと \C-?
| に対して 127 が割り当てられている。逆に 0 が割り当てられている hook も
| \C-@ しかない。不思議だ。
|
| * 実際に本当に .hook 経由で NUL が混入しているのか確認した。確かに .hook
| が 0 を引数として受け取っている。これはどういう事なのだろうか。FUNCNAME
| 配列を出力してみたが問題の .hook は top level から呼び出されている。こ
| れも異常はない。だとすると、bind の組み合わせによって変な振る舞いになる
| 可能性があるという事だろうか。
|
| * stty を潰してみたがそうすると端末ハンドラの行エディタらしき物が有効になっ
| てしまってテストできない。
|
| * stty の設定を確認してみた。vim の中では brkint ignpar imaxbel が欠けて
| いる。然し、それらの設定を一致させてみてもやはり問題は振る舞いは治らな
| い。stty の設定によって引き起こされているという訳でもない様だ。
|
| 不思議なのは :term の中では発生して他の端末では発生しないという事である。
| bash の振る舞いがおかしいという事なのだろうか。取り敢えず bash の
| bash_execute_unix_command がどう実行されているかについて確認したほうが良
| い様に思われる。
|
| * bash_execute_unix_command の時点で \C-@ になっているという事を確認した。
| また vim の外側では \C-? である。然し不思議なのは自分で手動で bind した
| 時には特に問題も起こっていないという事なのである。
|
| うーん。この bind -s の設定によって問題が起こっている気がする。それ以外に
| は考えにくいのである。然しそうだとしても :term だけで発生するのは不思議で
| ある。
|
| うーん。bash が受信しているバイト列について追跡する事にする。うーん。何と
| rl_getc の中の read(fd) の段階で 00 を受信している。ble.sh を有効にしてい
| ない時には問題は生じない。ble-detach している時には問題は生じない。うーん。
| 此処まで来ると bind -s の問題ではなくてやはり vim の :term の側の問題の様
| な気がする。
|
| stty 関連の設定を変更して試してみるとどうなるだろうか。と思ったがそれは既
| に試している。端末ハンドラの行エディタが有効になってしまってちゃんと処理
| できない。
|
| うーん。bash の内部状態における端末状態と ble.sh の内部状態における端末状
| 態が異なるというのが原因だろうか。通常の readline における rl_getc の瞬間
| の端末状態を出力する事は可能だろうか。stty を実行すれば良い?
|
| これによる結果はどうも各種 key を undef している事だけが違いである。うー
| ん。undef になっていると勝手に 0x7F が 0x80 になってしまうという事なのだ
| ろうか。
|
| -intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
| eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt
| = ^R; werase = ^W; lnext = <undef>; discard = <undef>; min = 1; time =
| 0;
| +intr = <undef>; quit = <undef>; erase = <undef>; kill = <undef>; eof =
| ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop =
| ^S; susp = <undef>; rprnt = ^R; werase = <undef>; lnext = <undef>;
| discard = <undef>; min = 1; time = 0;
|
| ここで erase undef をしない様にしたらちゃんと vim :term の中でも動く様に
| なった。他に ^C ^U ^\ ^Z (+ あれば ^W ^V ^R) について stty で変更している
| 様だが、
|
| - ^C, ^U, ^Z, ^V, ^R については普通に受信できている。
| - ^W については vim で使われている。
| - ^\ については寧ろ ble.sh の内部ではちゃんと受信できているが、外では受信
| できていない。というか vim :term の外側にいる時でも受信できていない?

[原因] stty erase undef としていたのが原因になっている様である。

一方で、この設定がなくてもちゃんと動作する様に思われる。そもそもこの設定は
何故あるのだろうか。どの様な場合に必要になるのだろうか。

| 然しもし erase undef しなくても受信できるのだとしたらそもそも何の為にそう
| していたのか。昔は icanon 等をしていなかった為に受信できなかったという事
| だろうか。
|
| ? 何処かにコードコメントは残っていないか? → 残っていない。
|
| icanon がない時の対策なのだとしたら、実際に icanon に対する対策を落として振
| る舞いを確認すれば本当にそうか確認できる。うーん。icanon に対する対策を外し
| たとしても ^? は有効である様に見える。逆に icanon があったとしても ^Z は効
| かなくなる。
|
| それぞれの key について改めてちゃんと振る舞うかどうかを確認する事にする。
|
| - ^Z, ^\, ^C ... icanon があっても対策が必要。
|
| - ^U, ^? ... 別に問題は起こらない様に見える。icanon は恐らく関係ない。
| - ^V, ^W, ^R ... これらも問題は起こらない様に見える。icanon を対策していな
| くても振る舞いは変わらない。うーん。これらは単に
|
| うーん。分かった。adjust-uvw で ^U^V^W^? が対策の対象になっている。つまり、
| 初期の実装に於いて ^U^V^W^? が bash の内部的な rebinding によって無効になっ
| ているのを、stty の設定の問題であると誤認して追加した対策コードなのではない
| かという事。そして、実際の所、これらの対策コードは役割を果たしていなかった
| という事なのではないか。

[まとめ] ^U^V^W^? について stty で undef にしていたのは、これらのキーに
bind できない事に対する誤った対策だったと考えられる。これに対する対策は
ble/decode/bind/adjust-uvw で行われている。昔は原因が不明だった為に、念の為
で stty でも undef する様にしていたのだと考えられる。

* 一応古い bash version でもちゃんと動くか確認する。→ bash-3.0, 3.1, 3.2,
4.0, 4.1, 4.2, 4.3, 5.1 でも試した特に問題は起こっていない様である。

2021-11-23

* progcomp: libvirt virsh completion に対する防御 (reported by telometto) [#D1682]
Expand Down
33 changes: 21 additions & 12 deletions src/util.sh
Expand Up @@ -5372,20 +5372,29 @@ function ble/term/visible-bell/cancel-erasure {
_ble_term_stty_state=
_ble_term_stty_flags_enter=()
_ble_term_stty_flags_leave=()
ble/array#push _ble_term_stty_flags_enter kill undef erase undef intr undef quit undef susp undef
ble/array#push _ble_term_stty_flags_leave kill '' erase '' intr '' quit '' susp ''
ble/array#push _ble_term_stty_flags_enter intr undef quit undef susp undef
ble/array#push _ble_term_stty_flags_leave intr '' quit '' susp ''
function ble/term/stty/.initialize-flags {
local stty; ble/util/assign stty 'stty -a'
# lnext, werase は POSIX にはないのでチェックする
if [[ $stty == *' lnext '* ]]; then
ble/array#push _ble_term_stty_flags_enter lnext undef
ble/array#push _ble_term_stty_flags_leave lnext ''
fi
if [[ $stty == *' werase '* ]]; then
ble/array#push _ble_term_stty_flags_enter werase undef
ble/array#push _ble_term_stty_flags_leave werase ''
fi
# # ^U, ^V, ^W, ^?
# # Note: lnext, werase は POSIX にはないので stty の項目に存在する
# # かチェックする。
# # Note (#D1683): ble/decode/bind/adjust-uvw が正しい対策。以下の対
# # 策の効果は不明。寧ろ vim :term 内部で ^? が効かなくなるなど問
# # 題を起こす様なので取り敢えず無効化する。
# ble/array#push _ble_term_stty_flags_enter kill undef erase undef
# ble/array#push _ble_term_stty_flags_leave kill '' erase ''
# local stty; ble/util/assign stty 'stty -a'
# if [[ $stty == *' lnext '* ]]; then
# ble/array#push _ble_term_stty_flags_enter lnext undef
# ble/array#push _ble_term_stty_flags_leave lnext ''
# fi
# if [[ $stty == *' werase '* ]]; then
# ble/array#push _ble_term_stty_flags_enter werase undef
# ble/array#push _ble_term_stty_flags_leave werase ''
# fi

if [[ $TERM == minix ]]; then
local stty; ble/util/assign stty 'stty -a'
if [[ $stty == *' rprnt '* ]]; then
ble/array#push _ble_term_stty_flags_enter rprnt undef
ble/array#push _ble_term_stty_flags_leave rprnt ''
Expand Down

0 comments on commit 82f74f0

Please sign in to comment.