diff --git a/docs/ChangeLog.md b/docs/ChangeLog.md index a5df7875..ef4fe598 100644 --- a/docs/ChangeLog.md +++ b/docs/ChangeLog.md @@ -251,6 +251,7 @@ - util (`ble/util/import`): work around filenames with bash special characters `#D1763` b27f758 - edit: fix the restore failure of `PS1` and `PROMPT_COMMAND` on `ble-detach` `#D1784` b9fdaab - complete: do not attempt an independent rhs completion for arguments (reported by rsteube) `#D1787` 0000000 +- history: fix the unsaved history in the detached state `#D1795` 0000000 ## Documentation diff --git a/note.txt b/note.txt index fdfb6d5f..5341c031 100644 --- a/note.txt +++ b/note.txt @@ -1806,11 +1806,6 @@ bash_tips ToDo ------------------------------------------------------------------------------- -2022-02-23 - - * detach 状態で終了した時、また detach している間の履歴が記録されなくなってい - る気がする。EXIT が呼び出されていないのだろうか。また後で確認する。 - 2022-02-20 * より一般の補完 framework に向けたインターフェイスについて @@ -6148,6 +6143,31 @@ bash_tips 2022-03-02 + * history: detach 状態で終了すると履歴に記録されない [#D1795] + + detach 状態で終了した時、また detach している間の履歴が記録されなくなってい + る気がする。EXIT が呼び出されていないのだろうか。また後で確認する。 + + どうも ble/builtin/history/option:a 迄はちゃんと呼び出して実行しているが、 + rskip, wskip の更新が思う様に振る舞っていない様だ。rskip は現在のファイル内 + の読み取り位置で、wskip は現在の Bash プロセス内の履歴の書き込み開始位置 + (次にファイルに書き込むべき項目の位置) を管理している。history/option:a の + 中で呼び出した check-uncontrolled-changes で wskip が先端位置に移動して、そ + の為に何も書き込まれないという状態になっている様に思われる。 + + そもそも detach 状態で終了した場合、detach 前に実行していたコマンドですら書 + き込まれずに終了してしまっている。 + + * そもそも prevmax!=max だからと言って wskip..prevmax 迄はちゃんと履歴に残 + すべきなのではないか。と思ったがそれを記録する手段がない様な気がする。否、 + subshell で適当に -r してそれから書き込めば良いのだろうか。 + + 取り敢えず対応した。 + + * 履歴が倍加する問題が新しく発生していないか確認する。 + 一応 "history -a;history -c;history -r" に対しては問題は起こっていない。 + bashrc で history -r をしても変な事は起こっていない。恐らく大丈夫。 + * complete: BUG cygwin$ pdflatex [TAB] で /usr/bin/cat: '': No such file or directory というエラー [#D1794] Ref #D1637 diff --git a/src/history.sh b/src/history.sh index 07479786..c51ec8ff 100644 --- a/src/history.sh +++ b/src/history.sh @@ -953,12 +953,33 @@ function ble/builtin/history/.initialize { ble/builtin/history/.set-rskip "$histfile" "$rskip" return 0 } -## @fn ble/builtin/history/.check-uncontrolled-change +## @fn ble/builtin/history/.delete-range beg end +function ble/builtin/history/.delete-range { + local beg=$1 end=${2:-$1} + if ((_ble_bash>=50000&&beg=beg;i--)); do + builtin history -d "$i" + done + fi +} +## @fn ble/builtin/history/.check-uncontrolled-change [filename opts] ## ble/builtin/history の管理外で履歴が読み込まれた時、 ## それを history -a の対象から除外する為に wskip を更新する。 function ble/builtin/history/.check-uncontrolled-change { + [[ $_ble_decode_bind_state == none ]] && return 0 + local filename=${1-} opts=${2-} prevmax=$_ble_builtin_history_prevmax local max; ble/builtin/history/.get-max - if ((max!=_ble_builtin_history_prevmax)); then + if ((max!=prevmax)); then + if [[ $filename && :$opts: == *:append:* ]] && ((_ble_builtin_history_wskipmax&&(end=max)))) ((beg<=end)) || return 0 - if ((_ble_bash>=50000&&beg=beg;i--)); do - builtin history -d "$i" - done - fi + ble/builtin/history/.delete-range "$beg" "$end" if ((_ble_builtin_history_wskip>=end)); then ((_ble_builtin_history_wskip-=end-beg+1)) elif ((_ble_builtin_history_wskip>beg-1)); then @@ -1241,7 +1255,7 @@ function ble/builtin/history/option:a { ble/builtin/history/.initialize skip0 || return "$?" local histfile=${HISTFILE:-$HOME/.bash_history} local filename=${1:-$histfile} - ble/builtin/history/.check-uncontrolled-change + ble/builtin/history/.check-uncontrolled-change "$filename" append local rskip; ble/builtin/history/.get-rskip "$filename" ble/builtin/history/.write "$filename" "$_ble_builtin_history_wskip" append:fetch [[ -r $filename ]] && ble/builtin/history/.read "$filename" "$rskip" fetch