Skip to content

Commit

Permalink
history: work around possible dirty prefix * in the history output
Browse files Browse the repository at this point in the history
  • Loading branch information
akinomyoga committed Jun 9, 2022
1 parent 46f5c13 commit 64a740d
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 2 deletions.
3 changes: 2 additions & 1 deletion docs/ChangeLog.md
Expand Up @@ -257,6 +257,7 @@
- complete: do not attempt an independent rhs completion for arguments (reported by rsteube) `#D1787` f8bbe2c
- history: fix the unsaved history in the detached state `#D1795` 344168e
- edit: fix an unexpected leave from the command layout on `read` `#D1800` 4dbf16f
- history: work around possible dirty prefix `*` in the history output `#D1808` XXXXXXX

## Documentation

Expand Down Expand Up @@ -344,7 +345,7 @@
- global: work around bash-3.0 bug that single quotas remains for `"${v-$''}"` `#D1774` 9b96578
- util: work around old `vte` not supporting `DECSCUSR` yet setting `TERM=xterm` (reported by dongxi8) `#D1785` 70277d0
- progcomp: work around the cobra V2 description hack (reported by SuperSandro2000) `#D1803` 71d0736
- complete: work around blocking `_scp_remote_files` and `_dnf` (reported by iantra) `#D1807` a4a779e XXXXXXX
- complete: work around blocking `_scp_remote_files` and `_dnf` (reported by iantra) `#D1807` a4a779e 46f5c13

## Internal changes and fixes

Expand Down
166 changes: 166 additions & 0 deletions note.txt
Expand Up @@ -1809,6 +1809,62 @@ bash_tips
ToDo
-------------------------------------------------------------------------------

2022-06-09

* macOS の nawk の振る舞いが変だという事 (reported in killermoehre)
https://github.com/akinomyoga/ble.sh/issues/190

% workaround を追加できるのかどうかも定かではないが、取り敢えずおかしな振る舞
% いをするという事までは確かめていた。これについては改めて調べる事にする。特
% に binding の状態について確認する。
%
% 調べてみるとどうも "上下左右 home/end" などの unbind を正しく実行できていな
% い様である。
%
% a bind/unbind 用のスクリプトに問題がある可能性? → と思ったが別にこれらのファ
% イルはその場で awk によって生成されるのではなくて、昔作ったキャッシュによっ
% て生成された物を再利用しているだけに見える。なので今回は関係ないのではな
% いか。
%
% 逆に言うと報告されている問題は壊れた nawk によってキャッシュが生成される
% 事により被害が拡大している可能性もある。
%
% b TERM による bash の上書きを検出できていない可能性? これが怪しい気がする。
% これの検出を行っている部分のコードを確認する。うーん。先ず勝手に上書きさ
% れたという事が検出されたという訳でもない。或いは検出できないという事が問
% 題になっているのだろうか。然し、検出には awk は使っていないので awk の
% version で振る舞いが変わるのも変である。
%
% 正常に動作する awk の場合にも TERM/is-dirty で引っかかっている様子はない。
% やはりこれは本当に TERM が書き換わった時にだけ起こる問題なのではないか。
%
% c 改めて unbind のコードの部分で何が起こっているのかについて確認する。
%
% うーん。unbind 用のコードは
% ble/decode/bind/.generate-source-to-unbind-default で生成している。なので
% 別にキャッシュをしていた訳ではない。よく考えてみたら、ユーザーがその場で
% binding を変えているかもしれないので、毎回その場で unbind のコードを生成
% しなければならないのだった。
%
% →何と generate-source-to-unbind-default が何も出力していないのだった。うー
% ん。エラーメッセージは、標準エラー出力を使って記録している .save の方に記
% 録されていると思われる → と思ったが標準エラー出力ですら空であった。awk
% が途中で終了してしまっているのだろうか。
%
% うーん。然しこの箇所の awk は LC_ALL=C で動かしている様なので unicode サ
% ポート関係で失敗する訳もないと思われる。一方で報告を受けたエラーはどうも
% unicode サポート関係の様である。
%
% 実際に awk に読み取らせている内容をファイルにダンプして、自分で awk に入れ
% てみてどの様な問題が起こっているのか確認する。と思ったら何も表示されない。
% END まで到達していない。更に確かめていくとそもそもこの自前でコンパイルした
% awk は何を入力しても全く動作していないという事が判明した。つまり、この awk
% は全く動作していない。逆に何故これで今まで微妙にでも動いている様に見えたの
% かが謎である。改めてちゃんと動く apple awk を作る事が必要である。
%
% [結論] Linux 上でコンパイルした apple nawk は実はちゃんとコンパイルできてい
% なくてそもそも全く動作していなかった。

2022-06-02

* bash-4.4 crash (reported by notmike-5)
Expand Down Expand Up @@ -6346,6 +6402,116 @@ bash_tips
Done (実装ログ)
-------------------------------------------------------------------------------

2022-06-09

* compat: Oh My Posh と組み合わせると動かないという質問が reddit にある (reported by abyss6166) [#D1809]
https://www.reddit.com/r/linuxquestions/comments/v43hek/oh_my_posh_theme_and_blesh_not_playing_well/

* 保留: oh-my-posh の設定で vertical-offset -1 を指定すると表示位置をずらす事
ができる。これによって ble.sh の内部でプロンプト領域が上に1行拡張されるのは
仕方がない。これは意図した動作であるし説明すれば分かってくれるのだろうと考
えている。

* oh-my-posh の right prompt の位置計算がうまく行っていない。これの原因は分かっ
た。oh-my-posh は全てのシーケンス毎に \[\] で囲んでいる。ここで rprompt の
幅が分かっている場合に以下の様にしている。

\[\e[1000C\]\[\e[10D\]

一方で ble.sh では \[\] はカーソル位置を変えないという想定をしつつ、また、
各シーケンスを現在のカーソル位置情報に基づいて再構築している。結果として、
例えば幅 80 の端末では上記は

(初期位置0,0)
\e[1000C → 右に 79 列進む (位置0,89)
\] → (位置0,0)
\e[10D → 何もしない (これ以上左に行けないので)

と解釈されて "\e[79C" に翻訳されてしまう。もっと簡単に言うと \[\e[1000C\]
はカーソル位置を変えないので \e[10D は位置(0,0)で実行されると解釈される。本
来は rprompt の為に出力しているシーケンスの全て(文字列も含めて)を \[\] で囲
んで欲しいのである。

? rprompt (vertical shift なし) ではどの様に描画されるのだろうか。

うーん。この時点で既に変な振る舞いをしている left の newline: true を削除す
るとちゃんと表示できない 。。

と思ったが、どうやらユーザー設定において rprompt の後には必ず left が来て
newline を指定しなければならないようだ。themes の中の設定は全てその様になっ
ている。なので、設計がおかしいとはいえ、これをバグとして報告しても仕方がな
い。

また、端末によって右端での動作が異なるのだという事を考えれば、rprompt で右
端に1文字余裕を持たせて、更に改行を強制的に実行するというのは妥当な選択肢で
ある。但し、その場合には rprompt の側で改行を入れるのが自然な実装だと思われ
るが。

テストをする上では取り敢えず newline: true は入れる事にするのである。

? bash の \[\] の説明はどうなっているのかというのを見たら単に non-printing
characters を囲むのに使うとしか書かれていなくて、確かにその観点からすると
omp の実装は正しい事になる。なのでこの方面から "正しくないから修正してくれ"
と要請するのは難しい。

* うーん。変更してくれないかと依頼するよりは自分で修正でも出した方が良いので
はないか。と思ってソースコードを確認してみたらどうやら \[\] はハードコード
されている様だ。

https://github.com/JanDeDobbeleer/oh-my-posh/blob/main/src/color/ansi.go#L77-L78

そもそも a.right 自体を \[\] で囲むという発想が誤っている様な気がしないでも
ないが、然し一方で実際にカーソル移動を誘起する場合には \[\] で囲もうが囲ま
まいが何れにしてもカーソル位置のずれは発生するのである。

a ちゃんとした修正を行うにはシーケンス毎に \[\] で囲むのではなくて、最終的
に戻ってくる前提の一連の移動全体を囲むという事になる。然し、そもそも現在
の omp の設計からして right は元に戻ってこない設計になっていて、次の left
で newline: true する事によって問題を解決する仕組みになっている。そして、
それはユーザーの設定項目として公開されているので下手に仕様を修正する訳に
も行かない。

b うーん。一つの workaround は \]\[ のペアを出力時に削除するという事。

\]\[ を置換するには? 出力する箇所で置換するべきという気がする。

Engine.console (strings.Builder) に書き込んで後で Engine.string() で中身
を取り出している様だ。この取り出す時に修正を行えば良いのではないかという
気がする。更にこれは e.print() 経由で文字列に変換して返されている。他に
PrintTooltip 及び PrintDebug でも利用されている。という事を考えると、
e.string() で処理するべきの気がする。

取り敢えず PR を出した。この PR だと完全に問題は解決していなくて、依然とし
て OMP は \[\] の中でカーソル移動を行っているが、これはこれで仕方がないのだ
ろうという気がする。

* history: 終了時の履歴保存の際にエラーメッセージが発生する [#D1808]

これは apple nawk による問題のテスト中に発見した問題である。

| 正しくコンパイルできていない apple awk で起動した際に、↑カーソルキーを3回押
| して C-d で抜けると以下のメッセージが発生する。↓だと発生しない。つまり、履歴
| を遡っていて、その履歴に含まれる項目が処理に混入している可能性もある。
|
| bash: ((: 1*: 構文エラー: オペランドが予期されます (エラーのあるトークンは "*")
| bash: ((: 1*: 構文エラー: オペランドが予期されます (エラーのあるトークンは "*")
| bash: ((: 1*: 構文エラー: オペランドが予期されます (エラーのあるトークンは "*")
|
| ここで何が起こっているのかについては上の事は置いておいても不思議である。
|
| →うーん。どうもこれは↑を3回押すと履歴項目の一番上の内容が消去されてしまう様
| だ。これによって history の結果の履歴番号に dirty mark として * が付加されて、
| 最終的に履歴番号を算術式で処理する時にエラーが発生するという事の様だ。
|
| 実はこれはもっと一般的な問題なのではないか。history の結果を解析する時にこの
| * の可能性を考慮に入れて処理する必要がある → 改めて確認した所、殆どの箇所で
| は既にちゃんと履歴番号の後に "*" が来る場合を考慮に入れていた。今回問題になっ
| たのとは別に1箇所だけ問題が見つかった。

結局原因は history の出力結果の履歴番号の後ろに * という文字が付く場合がある
という事を考慮に入れていない箇所があったということだった。既に殆どのコードで
はちゃんとこの事が考慮に入っていたが、一部のコードで見落としていた。

2022-05-13

* complete: scp の補完で固まる (reported by iantra) [#D1807]
Expand Down
4 changes: 3 additions & 1 deletion src/history.sh
Expand Up @@ -44,10 +44,12 @@ function ble/builtin/history/is-empty {
}
function ble/builtin/history/.get-min {
ble/util/assign min 'builtin history | head -1'
min=${min/'*'}
ble/string#split-words min "$min"
}
function ble/builtin/history/.get-max {
ble/util/assign max 'builtin history 1'
max=${max/'*'}
ble/string#split-words max "$max"
}

Expand Down Expand Up @@ -1316,7 +1318,7 @@ function ble/builtin/history/option:p {
builtin history -p -- '' &>/dev/null
ble/util/assign line2 'HISTTIMEFORMAT= builtin history 1'
if [[ $line1 != "$line2" ]]; then
local rex_head='^[[:space:]]*[0-9]+[[:space:]]*'
local rex_head='^[[:space:]]*[0-9]+\*?[[:space:]]*'
[[ $line1 =~ $rex_head ]] &&
line1=${line1:${#BASH_REMATCH}}

Expand Down

0 comments on commit 64a740d

Please sign in to comment.