Skip to content

Commit

Permalink
prompt: adjust behavior of "LINENO" and prompt sequence "\#"
Browse files Browse the repository at this point in the history
  • Loading branch information
akinomyoga committed May 11, 2021
1 parent 24a88ce commit 8b0257e
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 10 deletions.
3 changes: 2 additions & 1 deletion memo/ChangeLog.md
Expand Up @@ -58,7 +58,8 @@
- util (`ble/util/type`): fix a bug that aliases are not properly highlighted (reported by 3ximus) `#D1526` 45b30a7
- syntax (`ble/syntax:bash/simple-word/eval`): optimize large array passing (motivated by timjrd) `#D1522` c89aa23
- main: accept non-regular files as `blerc` and add option `--norc` `#D1530` 7244e2f
- promopt: let `stderr` pass through to tty in evaluating `PS0` (reported by tycho-kirchner) `#D1531` 0000000
- prompt: let `stderr` pass through to tty in evaluating `PS0` (reported by tycho-kirchner) `#D1541` 24a88ce
- prompt: adjust behavior of `LINENO` and prompt sequence `\#` (reported by tycho-kirchner) `#D1542` 0000000

## Fixes

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

2021-05-11

* PS0 の中での \# の展開結果が異なるという話 (reported by tycho-kirchner) [#D1542]
https://github.com/akinomyoga/ble.sh/issues/107

これはそもそも ble.sh ではコマンドの受付と実行を分離しているからである。こ
の様に疎結合にしたのに逆にその場で実行する様に書き換えるのは設計として許容
できない。それに実際にその様に実装しようとすると色々と複雑になってしまう。
なので、現在の枠組みの範囲内でそれを再現する様に実装しなければならない。

もう一つの問題は ble.sh では同時に複数のコマンドを実行する可能性があるとい
う事。そして、PS0 は各コマンド実行の直前に実行する物であって、PS1 はプロン
プト表示の前に実行する物であるという事。という事を考えると、

[PS0]
COMMAND1
[PS0]
COMMAND2
[PS1]
PROMPT

という形になる可能性もあるのである。

[修正]

* fixed: うーん。時々 Cygwin でプロンプトが表示されてからコマンドが実行され
たりする原因が分かった気がする。これは queue に何かあるのにも拘らず直ぐに
ユーザー入力が来て、それによって再度プロンプトが表示されて、その上でコマ
ンドを実行するから起こることである。

今となっては複数行入力の検出や bracketed paste mode など色々とユーザーの
誤貼り付けに対する対策が整ってきているので、この様な遅延の対策は不要であ
る。という事を考えると、queue に何かある時にはコマンドを実行する様に変更
するというので良い。


* OK: ble-edit/exec:gexec/process は誰も使っていない気がする。これは削除で
良いのではないか。と思ったら勘違いだった。ちゃんと呼び出されている。

x fixed: 改行が含まれる空コマンドの時に ble.sh は実行している気がする。但し、
履歴には登録していない。少なくとも CMD が一個増えてしまっている。何が起こっ
ているのだろうか。

→空かどうかのチェックで空白とタブしか判定していなかった。一方で history
に登録されていなかったのはまた別のフィルタが働いていたという事だろう。

? 履歴展開の展開結果が空の時には何が起こるのだろうか。と思ったが有限の文
字列から空の履歴展開になる事もない様な気がする。いや !:5 等としたら空に
なるのだろう→と思ったら bad word specifier というエラーになる。やはり
空に展開する事はないという事なのだろうか。

普通に history -s '' としたら空の履歴を登録する事ができて、!履歴番号で
空に展開させる事ができる。空に展開される時にはコマンド実行としては取り
扱われないが、改行はカウントされる。但しカウントされる改行は展開後では
なくて展開前の行数になっている様子である。

x done: 改行が含まれるコマンドの時に LINENO を増加させる。

* done: \# 及び LINENO の振る舞いについて調べる

\# は LINENO ではなくて _ble_edit_CMD を使わなければならない。というか、
LINENO 等の振る舞いに関しても bash の PS0, PS1 の振る舞いに従わなければな
らないのだろうか。両者の振る舞いについて確認する事にする。

うーん。どうやら LINENO の方がペアを特定するのには便利な気がするが何故
CMD の方を使っているのだろうか。

? どの様な時に LINENO と CMD がずれるのだろうか。normal bash で確かめてみ
ると、どうやら不完全なコマンドを入力して "> " (PS2) で続きを入力した時
にずれる様である。

他に LINENO はコマンドを実行せずに Enter を押した時にも増えるし、一まと
まりのコマンドの中に改行が含まれている時にも改行の数だけ余分に増える。

C-c でコマンドをキャンセルした時にも増える様である。これについては
ble.sh で試したらちゃんとその様になっていたので気にしなくて良い。

? Bash で \# に対応する変数はないのか。もしあるのであれば同様の名前で提供
するべきなのではないだろうか。

何処で \# の処理がされているのかと思ったが parse.y:6162
(decode_prompt_string) の中にあった。current_command_number という変数
を参照している。そしてこれは eval.c の中で incr されている。そも他の箇
所では全く使われていないので、これは別に Bash の内部の値を取り出そうな
どとはしなくて良い。

* fixed: \# の振る舞いを PS0 の評価後に変化する様に変える

% 取り敢えず \# はコマンドを登録する時に番号を保存する様にする。もし保存
% されていたら其処で振る舞いを書き換える事にする。

_ble_edit_CMD の increment を内部に移動する事にする? この変数は \# を通し
てしか定義されない物の様なので他の場所で影響が出てくる事はない様に思われ
る。なので PS0 の直後で increment する様に変更してしまって問題ない気がす
る。

* Note: どうやら normal bash でも PS0,PS0,PS1 という感じの組み合わせになる
事がある様である。C-v C-j として改行を挟んで独立したコマンドを複数入力し
た場合になる。この時には LINENO は PS0 前に inc されて CMD は PS0 直後に
inc されている様に見える。PS0 に関してはこの振る舞いに倣うのが適切だろう。

元々の報告では PS0 と PS1 が必ず pair になる事を期待しているのだろうか。そ
もそも PS0 はコマンド開始前に出力する物で、PS1 はプロンプト表示前に出力する
物なので必ずしも組になっているとは限らない。

組になっている事を期待するのであれば PREEXEC 及び POSTEXEC を利用するべきな
のである。但し、shournal が単に計測対象開始として PS0 を使って、計測対象終
了として PS1 を使っているというだけなのであれば、PS0 が重複していても特に問
題は生じないのである。

もし PREEXEC, POSTEXEC を使うというのであれば ble.sh が後からロードされた時
にもちゃんと有効化される様に記述する必要がある。。

2021-05-10

* syntax: PS0 から stderr に出力できないという報告を受けた (reported by tycho-kirchner) [#D1541]
Expand Down
34 changes: 25 additions & 9 deletions src/edit.sh
Expand Up @@ -1808,7 +1808,12 @@ function ble-edit/content/push-kill-ring {
#
# 内部使用変数
## @var _ble_edit_LINENO
## LINENO の値を保持します。
## コマンドラインで処理・キャンセルした行数の合計です。
## @var _ble_edit_CMD
## プロンプトで \# として参照される変数です。
## 実際のコマンド実行の回数を保持します。
## PS0 の評価後に増加します。
## @var _ble_edit_PS1
## @var _ble_edit_IFS
## @var _ble_edit_IGNOREEOF_adjusted
Expand Down Expand Up @@ -4590,6 +4595,9 @@ _ble_edit_exec_BASH_COMMAND=$BASH
function ble-edit/exec/register {
ble/array#push _ble_edit_exec_lines "$1"
}
function ble-edit/exec/has-pending-commands {
((${#_ble_edit_exec_lines[@]}))
}
function ble-edit/exec/.setexit {
# $? 変数の設定
return "$_ble_edit_exec_lastexit"
Expand Down Expand Up @@ -4995,10 +5003,13 @@ function ble-edit/exec:gexec/.prologue {
ble-edit/restore-READLINE
ble-edit/restore-IGNOREEOF
builtin unset -v HISTCMD; ble/history/get-count -v HISTCMD

_ble_edit_exec_INT=0
ble/util/joblist.clear
ble-edit/exec:gexec/invoke-hook-with-setexit PREEXEC "$_ble_edit_exec_BASH_COMMAND" &>/dev/tty
ble-edit/exec/print-PS0 >&31 2>&32
((++_ble_edit_CMD))

ble-edit/exec/restore-BASH_REMATCH
ble/base/restore-bash-options
ble/base/restore-POSIXLY_CORRECT
Expand Down Expand Up @@ -5205,7 +5216,11 @@ function ble/widget/.newline {
fi

_ble_complete_menu_active= ble/widget/.insert-newline "$opts"
((LINENO=++_ble_edit_LINENO))

# update LINENO
local ret; ble/string#count-char "$_ble_edit_str" $'\n'
((_ble_edit_LINENO+=1+ret))
((LINENO=_ble_edit_LINENO))

ble/history/onleave.fire
ble/widget/.newline/clear-content
Expand Down Expand Up @@ -5259,7 +5274,7 @@ function ble/widget/default/accept-line {
ble-edit/content/clear-arg
local command=$_ble_edit_str

if [[ ! ${command//[ ]} ]]; then
if [[ ! ${command//["$_ble_term_IFS"]} ]]; then
[[ $bleopt_history_share ]] &&
ble/builtin/history/option:n
ble/widget/.newline keep-info
Expand Down Expand Up @@ -5297,8 +5312,6 @@ function ble/widget/default/accept-line {

[[ $hist_is_expanded ]] && ble/util/buffer.print "${_ble_term_setaf[12]}[ble: expand]$_ble_term_sgr0 $command"

((++_ble_edit_CMD))

# 編集文字列を履歴に追加
ble/history/add "$command"

Expand Down Expand Up @@ -5407,14 +5420,13 @@ function ble/widget/edit-and-execute-command.impl {
local command=$ret

command=${command%$'\n'}
if [[ ! ${command//["$IFS"]} ]]; then
if [[ ! ${command//["$_ble_term_IFS"]} ]]; then
ble/widget/.bell
return 1
fi

# Note: accept-line を参考にした
ble/util/buffer.print "${_ble_term_setaf[12]}[ble: fc]$_ble_term_sgr0 $command"
((++_ble_edit_CMD))
ble/history/add "$command"
ble-edit/exec/register "$command"
}
Expand Down Expand Up @@ -8309,16 +8321,20 @@ function ble-decode/EPILOGUE {
# 大量の文字が入力された時に毎回再描画をすると滅茶苦茶遅い。
# 次の文字が既に来て居る場合には描画処理をせずに抜ける。
# (再描画は次の文字に対する bind 呼出でされる筈。)
if ble/decode/has-input; then
# 現在は ble-decode/.hook の段階で連続入力を縮約しているので
# この関数はそんなに沢山呼び出される事はない。
# bash 4.0 以降でないとユーザー入力検出できない事に注意。
if ble/decode/has-input && ! ble-edit/exec/has-pending-commands; then
ble-edit/bind/.tail-without-draw
return 0
fi
fi

ble-edit/content/check-limit

# _ble_decode_bind_hook で bind/,tail される。
"ble-edit/exec:$bleopt_internal_exec_type/process" && return 0
# コマンド実行が設定された時には _ble_decode_bind_hook の最後で bind/.tail
# が実行される。
ble-edit/exec:"$bleopt_internal_exec_type"/process && return 0

ble-edit/bind/.tail
return 0
Expand Down

0 comments on commit 8b0257e

Please sign in to comment.