From 44d9e1049cd79258ccb8de253d0d9307d577e8fc Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Thu, 26 Jan 2023 21:38:45 +0900 Subject: [PATCH] contrib: add "histdb" --- README-ja_JP.md | 1 + README.md | 1 + ble.pp | 98 ++++- contrib | 2 +- docs/ChangeLog.md | 4 +- lib/core-complete.sh | 2 +- lib/init-msleep.sh | 3 +- lib/vim-airline.sh | 2 +- make/debug.leakvar.exclude-list.txt | 2 +- make_command.sh | 2 + note.txt | 579 ++++++++++++++++++++++++++-- src/def.sh | 1 + src/edit.sh | 39 +- 13 files changed, 686 insertions(+), 50 deletions(-) diff --git a/README-ja_JP.md b/README-ja_JP.md index 39d05088..fc3a1e5c 100644 --- a/README-ja_JP.md +++ b/README-ja_JP.md @@ -341,6 +341,7 @@ make INSDIR="$HOME/.local/share/blesh" install - `blerc` 設定ファイル (`~/.blerc` または `~/.config/blesh/init.sh`) があれば削除します。 - `ble.sh` をインストールしたディレクトリを削除します。 - キャッシュディレクトリ `~/.cache/blesh` が生成されていればそれを削除します。 +- 状態ディレクトリ `~/.cache/blesh` が生成されていればそれを削除します。 - 一時ディレクトリ `/tmp/blesh` が生成されていればそれを削除します。これは `/tmp` の内容が自動的にクリアされないシステムで必要です。 # 2 基本設定 diff --git a/README.md b/README.md index 49ec27a7..e2e007a0 100644 --- a/README.md +++ b/README.md @@ -321,6 +321,7 @@ Basically you can simply delete the installed directory and the settings that th - Remove `blerc` files (`~/.blerc` or `~/.config/blesh/init.sh`) if any. - Remove the installed directory. - Remove the cache directory `~/.cache/blesh` if any. +- Remove the state directory `~/.local/state/blesh` if any. - Remove the temporary directory `/tmp/blesh` if any [ Only needed when your system does not automatically clears `/tmp` ]. # 2 Basic settings diff --git a/ble.pp b/ble.pp index ed1569aa..28023730 100644 --- a/ble.pp +++ b/ble.pp @@ -257,7 +257,7 @@ function ble/base/adjust-builtin-wrappers/.assign { if [[ ${_ble_util_assign_base-} ]]; then local _ble_local_tmpfile; ble/util/assign/.mktmp builtin eval -- "$1" >| "$_ble_local_tmpfile" - IFS= builtin read -r -d '' defs < "$_ble_local_tmpfile" + IFS= builtin read "${_ble_bash_tmout_wa[@]}" -r -d '' defs < "$_ble_local_tmpfile" ble/util/assign/.rmtmp else defs=$(builtin eval -- "$1") @@ -965,11 +965,21 @@ function ble/init/check-environment { if [[ ! $USER ]]; then ble/util/print "ble.sh: insane environment: \$USER is empty." >&2 - if type id &>/dev/null; then - export USER=$(id -un) + if USER=$(id -un) && [[ $USER ]]; then + export USER ble/util/print "ble.sh: modified USER=$USER" >&2 fi fi + _ble_base_env_USER=$USER + + if [[ ! $HOSTNAME ]]; then + ble/util/print "ble.sh: suspicious environment: \$HOSTNAME is empty." + if HOSTNAME=$(uname -n 2>/dev/null) && [[ $HOSTNAME ]]; then + export HOSTNAME + ble/util/print "ble.sh: fixed HOSTNAME=$HOSTNAME" >&2 + fi + fi + _ble_base_env_HOSTNAME=$HOSTNAME # 暫定的な ble/bin/$cmd 設定 ble/bin/.default-utility-path "${_ble_init_posix_command_list[@]}" @@ -1494,6 +1504,63 @@ function ble/base/migrate-cache-directory { fi ble/base/migrate-cache-directory +## +## @var _ble_base_state +## +## 環境毎の初期化ファイルを格納するディレクトリ。以下の手順で決定する。 +## +## 1. ${XDG_STATE_HOME:=$HOME/.state} (存在しなくても強制的に作成) の下に blesh を作成して使う。 +## 2. (1. に失敗した時) $_ble_base/state.d/$UID を使う。 +## +function ble/base/initialize-state-directory/.xdg { + local state_dir=${XDG_STATE_HOME:-$HOME/.local/state} + if [[ -e $state_dir || -L $state_dir ]]; then + if [[ ! -d $state_dir ]]; then + if [[ $XDG_STATE_HOME ]]; then + ble/util/print "ble.sh: XDG_STATE_HOME='$XDG_STATE_HOME' is not a directory." >&2 + else + ble/util/print "ble.sh: '$state_dir' is not a directory." >&2 + fi + return 1 + fi + if ! [[ -r $state_dir && -w $state_dir && -x $state_dir ]]; then + if [[ $XDG_STATE_HOME ]]; then + ble/util/print "ble.sh: XDG_STATE_HOME='$XDG_STATE_HOME' doesn't have a proper permission." >&2 + else + ble/util/print "ble.sh: '$state_dir' doesn't have a proper permission." >&2 + fi + return 1 + fi + fi + + ble/base/.create-user-directory _ble_base_state "$state_dir/blesh" +} +function ble/base/initialize-state-directory { + ble/base/initialize-state-directory/.xdg && return 0 + + # fallback + local state_dir=$_ble_base/state.d + if [[ ! -d $state_dir ]]; then + ble/bin/mkdir -p "$state_dir" || return 1 + ble/bin/chmod a+rwxt "$state_dir" || return 1 + + # relocate an old state directory if any + local old_state_dir=$_ble_base/state + if [[ -d $old_state_dir && ! -h $old_state_dir ]]; then + mv "$old_state_dir" "$state_dir/$UID" + ln -s "$state_dir/$UID" "$old_state_dir" + fi + fi + ble/util/print "ble.sh: using the non-standard position of the state directory: '$state_dir/$UID'" >&2 + ble/base/.create-user-directory _ble_base_state "$state_dir/$UID" +} +if ! ble/base/initialize-state-directory; then + ble/util/print "ble.sh: failed to initialize \$_ble_base_state." 1>&2 + builtin unset -v _ble_bash BLE_VERSION BLE_VERSINFO + ble/init/clean-up 2>/dev/null # set -x 対策 #D0930 + return 1 +fi + function ble/base/print-usage-for-no-argument-command { local name=${FUNCNAME[1]} desc=$1; shift @@ -1775,6 +1842,27 @@ function ble-update { ble/builtin/trap/install-hook ERR inactive ble/builtin/trap/install-hook RETURN inactive +# @var _ble_base_session +# @var BLE_SESSION_ID +function ble/base/initialize-session { + [[ $_ble_base_session == */"$$" ]] && return 0 + + local start_time= + if ((_ble_bash>=50000)); then + start_time=${EPOCHREALTIME//[!0-9]} + elif ((_ble_bash>=40200)); then + printf -v start_time '%(%s)T' + ((start_time*=1000000)) + else + ble/util/assign start_time 'ble/bin/date +%s' + fi + ((start_time-=SECONDS*1000000)) + + _ble_base_session=${start_time::${#start_time}-6}.${start_time:${#start_time}-6}/$$ + BLE_SESSION_ID=$_ble_base_session +} +ble/base/initialize-session + #%x inc.r|@|src/decode| #%x inc.r|@|src/color| #%x inc.r|@|src/canvas| @@ -1844,7 +1932,9 @@ function ble/dispatch { (version|--version) ble/util/print "ble.sh, version $BLE_VERSION (noarch)" ;; (check|--test) ble/base/sub:test "$@" ;; (*) - if ble/is-function ble/bin/ble; then + if ble/string#match "$cmd" '^[a-z0-9]+$' && ble/is-function "ble-$cmd"; then + "ble-$cmd" "$@" + elif ble/is-function ble/bin/ble; then ble/bin/ble "$cmd" "$@" else ble/util/print "ble (ble.sh): unrecognized subcommand '$cmd'." >&2 diff --git a/contrib b/contrib index d2c5eb3b..025590f5 160000 --- a/contrib +++ b/contrib @@ -1 +1 @@ -Subproject commit d2c5eb3b7a6ff24498567d80ea8e0b7ee9f1a1c8 +Subproject commit 025590f52167c4682fa5fd3d17a8a663cad442e1 diff --git a/docs/ChangeLog.md b/docs/ChangeLog.md index d6019695..4b003c39 100644 --- a/docs/ChangeLog.md +++ b/docs/ChangeLog.md @@ -116,7 +116,8 @@ - edit (`magic-space`): support `bleopt edit_magic_expand=...:alias` (requested by telometto) `#D1912` 63da2ac - auto-complete: cancel auto-complete for `magic-space` `#D1913` 01b4f67 - complete: support ambiguous completion for command paths `#D1922` 8a716ad -- complete: preserve original path segments as long as possible `#D1923` `#D1924` xxxxxxx +- complete: preserve original path segments as long as possible `#D1923` `#D1924` e3cdb9d +- main: support `BLE_SESSION_ID` and `BLE_COMMAND_ID` `#D1925` xxxxxxx ## Changes @@ -529,6 +530,7 @@ - colorglass: add color filter `#D1902` 88e74cc - colorglass: add `bleopt colorglass_{saturation,brightness}` (motivated by auwsom) `#D1906` 40625ac - fzf-key-bindings: fix a problem that `modifyOtherKeys` is not reflected (reported by SuperSandro2000) `#D1908` 486564a +- add `histdb` `#D1925` xxxxxxx # ble-0.4.0-devel2 diff --git a/lib/core-complete.sh b/lib/core-complete.sh index 4b8eafdc..e9f2ecfa 100644 --- a/lib/core-complete.sh +++ b/lib/core-complete.sh @@ -7955,7 +7955,7 @@ function ble/widget/auto_complete/self-insert/.is-magic-space { function ble/widget/auto_complete/self-insert { if ble/widget/auto_complete/self-insert/.is-magic-space; then ble/widget/auto_complete/cancel-default - return $? + return "$?" fi local code; ble/widget/self-insert/.get-code diff --git a/lib/init-msleep.sh b/lib/init-msleep.sh index 4d0049d3..4de4c7e4 100644 --- a/lib/init-msleep.sh +++ b/lib/init-msleep.sh @@ -18,7 +18,8 @@ function ble/util/msleep/.load-compiled-builtin { local basename=$_ble_edit_io_fname2 local fname_buff=$basename.buff - local builtin_path=$_ble_base_cache/init-msleep.$_ble_bash.$HOSTNAME.so + local hostname=${HOSTNAME:-$_ble_base_env_HOSTNAME} + local builtin_path=$_ble_base_cache/init-msleep.$_ble_bash.$hostname.so local builtin_runpath=$_ble_base_run/$$.init-msleep.so ble/util/msleep/.load-compiled-builtin/compile "$builtin_path" && ble/bin/cp "$builtin_path" "$builtin_runpath" || return 1 diff --git a/lib/vim-airline.sh b/lib/vim-airline.sh index ea53e807..0f1df972 100644 --- a/lib/vim-airline.sh +++ b/lib/vim-airline.sh @@ -133,7 +133,7 @@ function ble/lib/vim-airline/convert-theme/.setface { function ble/lib/vim-airline/convert-theme { local file=$1 sed -n 's/let s:airline_\([a-zA-Z_0-9]\{1,\}\)[^[:alnum:]]\{1,\}\(\#[0-9a-fA-F]\{6\}\)[^[:alnum:]]\{1,\}\(\#[0-9a-fA-F]\{6\}\).*/\1 \2 \3/p' "$file" | - while builtin read -r face fg bg; do + while builtin read "${_ble_bash_tmout_wa[@]}" -r face fg bg; do ble/lib/vim-airline/convert-theme/.setface "$face" "$fg" "$bg" done } diff --git a/make/debug.leakvar.exclude-list.txt b/make/debug.leakvar.exclude-list.txt index f88a48f0..db863324 100644 --- a/make/debug.leakvar.exclude-list.txt +++ b/make/debug.leakvar.exclude-list.txt @@ -124,7 +124,6 @@ ^TEXMFHOME= ^TIME_STYLE= ^USER= -^WINDOW= ^XDG_RUNTIME_DIR= ^XDG_SESSION_CLASS= ^XDG_SESSION_ID= @@ -155,6 +154,7 @@ ^SSH_CONNECTION= ^SSH_TTY= ^STY= +^WINDOW= -------------------------------------------------------------------------------- # bash-completion ^_xspecs= diff --git a/make_command.sh b/make_command.sh index c37e646f..793f49fe 100755 --- a/make_command.sh +++ b/make_command.sh @@ -1172,6 +1172,7 @@ function sub:scan/bash502-patsub_replacement { grc --color '\$\{[[:alnum:]_]+(\[[^][]*\])?//?([^{}]|\{[^{}]*\})+/[^{}"'\'']*([&$]|\\)' --exclude=./test | sed -E 'h;s/'"$esc"'//g;s/^[^:]*:[0-9]+:[[:space:]]*// \Z//?\$q/\$Q\}Zd + \Z//?\$q/\$qq\}Zd \Z//?\$__ble_q/\$__ble_Q\}Zd \Z//?\$_ble_local_q/\$_ble_local_Q\}Zd \Z/\$\(\([^()]+\)\)\}Zd @@ -1297,6 +1298,7 @@ function sub:scan/word-splitting-number { \Z\$\{#[a-zA-Z_0-9]+\}[<>?&]Zd \Z \$\{\#[a-zA-Z_0-9]+\[@\]\} -gt 0 \]\]Zd \Zcase \$\? inZd + \Zcase \$\(\(.*\)\) inZd g' } diff --git a/note.txt b/note.txt index 5895c49c..fa747cec 100644 --- a/note.txt +++ b/note.txt @@ -842,9 +842,39 @@ bash_tips Memo ------------------------------------------------------------------------------- +2023-01-31 + + * review: direnv [#M0023] + + direnv は .envrc を bash で評価して、環境変数の変更を調べて、それを各シェル + の変数に反映させるらしい。これにより使うシェルに依存せず一つの .envrc で同 + 時に対応できる。然し一方でこれが意味する所は、環境変数だけしか親シェルに反 + 映させる事ができないのだろうという事。ローカルな関数やエイリアスは引き継が + れない (或いはエイリアスであれば可能であろう)? また環境変数に制限する事によっ + てディレクトリに入る前の環境変数のセットをそのまま保存する事によって + push/pop を自前で実装しなくて済む様になっている。 + + .envrc は direnv allow しないと有効にならない。このallow/unallowedの情報は + どこに記録しているのだろうか。うーん。別の箇所にディレクトリを作成している + 様にも見える。うーん。 + + https://github.com/bbugyi200/funky これは各ディレクトリの中にデータベースファ + イルを作って local functions を保存する事によって動く。グローバルに使える関 + 数も定義できる (が .bashrc で定義するのと比べて何が違うのか謎)。 + + https://github.com/cxreg/smartcd これは機能的になかなか参考になる気がする。 + README の see also のまとめが参考になる。 + https://github.com/cxreg/smartcd#see-also + + https://github.com/Tarrasch/zsh-autoenv ... smartcd SEE ALSO による + と、~/.autoenv_authorized に実行して良い env ファイルが記録されているそうだ。 + + https://github.com/hyperupcall/autoenv ... これは bash にも対応している。記 + 録ファイル ~/.autoenv_authorized は zsh-autoenv と同じ様である。 + 2021-12-31 - * "function f {}" vs "f() {}" + * "function f {}" vs "f() {}" [#M0022] function f は元々は ksh functions で、POSIX functions f() とは局所変数の取 り扱いが異なる。ksh では f() の形式の関数では局所変数を定義できない。ksh @@ -1334,6 +1364,51 @@ bash_tips bug-bash, third-party bugs & reviews ------------------------------------------------------------------------------- +2023-01-31 + + * review: bash libraries + + https://blog.fascode.net/2022/05/05/fasbashlib/ + https://github.com/Hayao0819/FasBashLib ... これはライブラリ構成としてある + べき形を一通り備えている様に思える。具体的な関数としてどれだけ非自明なもの + が用意されているのかは余り確認していない。Common.sh を見ると悪しき set -Eeu + -o pipefail を前提としている。GNU toolchain を要求している。fork を減らすな + どの効率化については余り意識されていない気がする。結構 trivial なものまで関 + 数として定義されている。うーん。ForEach だとか Array.Length だとか、既に + bash に機能的に存在している物まで関数で wrap したり pipe 化したりと、syntax + sugar 的な関数が多く、実践志向ではない。或いは minimalism 的潔さはない。ラ + イブラリ構成としてメタ的な機能(naming convention 変換, etc)を揃えているので + 良さそうと思ったが、それも namespace の模倣のために整えられた枠組みの副産物 + と見るのが良い気がする。 + + FasCode project の一部? で、これは何かと検索すると Alter Linux という日本産 + Linux distribution を有志で作っている集まりだろうか? Arch based. Issues を + 見ると日本語メインのコミュニティーで 373 stars. 他に Serene Linux というの + も作っていて Ubuntu-based -> Fedora-based に変更したと書いている。作ってい + るのは学生の集団らしい。 + +2023-01-26 + + * review: コマンド履歴データベースの設計 + + fish はファイル名に一致する引数を覚えている。これにより autosuggestions で + は、コマンドライン中のファイル名が現在していない時にはそのコマンドはスキッ + プするという具合の振る舞いをする。 + + https://github.com/ellie/atuin ... 暗号化・ホスト間共有・C-r拡張・各種統計 + + https://github.com/jcsalterego/historian ... 単に .bash_history を検索するだけ + + https://github.com/ddworken/hishtory ... custom column として git_remote が + 紹介されている。git remote 単体が便利かどうかは分からない。sqlite3 だと + column を dynamical に追加するのは難しそう。一方で git の commit id を一緒 + に記録するというのは一つの可能性である。 + + https://github.com/larkery/zsh-histdb ... 実は同じ名前で zsh にもその様な + plugin が存在している様である。中を除いてみたら実装はかなり近い形になってい + る。履歴を表示するコマンドも用意しているが、余り細かい操作を実行できる訳で + もない様だ。 + 2022-06-26 * またもや tempenv=... builtin eval ':;echo $tempenv' のバグに引っ掛かった。 @@ -1503,7 +1578,7 @@ bash_tips 2021-09-01 - * review bash-raytracer + * review: bash-raytracer https://github.com/aneeshdurg/bash-raytracer 固定小数点で実装している。Issue 1 で遅いから inline 化して微妙に改善したと @@ -1861,6 +1936,102 @@ bash_tips - leakvars - keymap の移動 (これは別 commit にする?) +2023-01-26 + + * [保留] histdb: 形式を変更する時は形式自動アップグレードを実装する + + misc/version に基づき行う。ダウングレードが必要ならば代わりにファイル名にバー + ジョン番号を含めて (例: history@chatoyancy.v1.sqlite3) ファイルを開き直す。 + + * histdb: 現在の有効なファイル名をコマンドに紐づけて記録する可能性について + + ファイル名着色などの情報を参照したい。そうすればファイル名と偶々一致してい + る単語を誤って登録してしまうという事もなくなる。chroma を充実させる動機にも + なる。 + + 複数のファイル名が考えられるので別テーブルに記録する事も考えたが、それだと + データベースサイズが大きくなる気がする。或いは、別テーブルにファイル名だけ + 記録しておいて但し id リストを command_history の entry の中に保存するとい + う事にすれば良いのかもしれない。 + + * histdb: 今までに入力した単語を記録する機能 + + 当初は対応する session_id, exec_id と紐づけて管理する事を考えていたが、其処 + までする必要性はあるだろうか。そもそも何故単語を記録するのかというと、補完 + で使う為である。そう思ったら、最終使用日時及び使用回数だけ記録すれば良い気 + がする。 + + 既存の値から増やすという事を sqlite でするにはどうすればいいのか。と思って + 調べてみたら update で既存の値を使った計算式を指定できる様だ。 + https://stackoverflow.com/questions/744289/how-to-increase-value-by-a-certain-number + + 既に登録されていればそれを更新し、そうでなければ新しく挿入する方法は? と思っ + て調べたら色々あるようだ。 + https://stackoverflow.com/questions/3634984/insert-if-not-exists-else-update + https://stackoverflow.com/questions/418898/sqlite-upsert-not-insert-or-replace + + SQLite-3.24.0 [2018-06-04] で追加された UPSERT という機能が求める機能の気が + する。然し、これは比較的最近の機能なので使えるとは限らない。更に独自拡張な + ので別の sql db では使えない。色々読むと今回の場合は文字列以外は完全に置き + 換えるので単に insert or replace で十分の気がする。 + + coalesce((SELECT count FROM words WHERE str = '...'), 0) + 1 + + * histdb: history の中から情報を取り出してそれを使って何かする機能 + + これができなければそもそも実装する意味がない。例えば auto-complete で単語を + 表示する等。 + + * histdb: backup機能。sqlite3 データベースが破壊される事が実際起こるのか分か + らないが、消えるとショックなのでバックアップは時々したい。".backup ファイル + 名" でバックアップを作れる様だが、バックアップのファイル名は自分で決める必 + 要がある。またバックアップの頻度も考えたい。取り敢えず終了時に前回のバック + アップから時間が経っていたらバックアップするという形にするのが良い気がする。 + 前回のバックアップ時刻はデータベース内部に直接記録してしまって良いのでは。 + + 壊れたファイルで上書きしても駄目なので sqlite3 が壊れていないかのチェックも + 行う。チェックに失敗したら警告を発する。データサイズが大きくなってくると + "PRAGMA integrity_check;" は時間がかかるらしい。代わりに "PRAGMA + quick_check;" という物があるらしい。 + + https://sqlite.org/forum/forumpost/9d9e63a8d4 + https://serverfault.com/questions/8048/how-can-i-verify-that-a-sqlite-db3-file-is-valid-consistent + + .backup を実行するのと直接コピーするので何が違うのかと思ったが、直接コピー + すると中途半端な transaction のデータもコピーしたり、或いは書き換えながらコ + ピーされたりして壊れるという事。 + hourly, daily, weekly, monthly ぐらい backup しておけば十分の気がする。 + +2023-01-25 + + * complete: 英単語の曖昧補間やスペルミスの検出など + + この場合には一意確定だとしても挿入はしない方が良い。コマンド引数 + (source:argument) についてその他の候補生成が全て生成に失敗した時にこれを実 + 行するのが良い気がする。そしてその場合には勝手に挿入しない事を表す flag か + 何かを設定する事にすれば良い。 + + 英単語辞書は bash で処理すると遅いので awk か或いは外部コマンドを呼び出すべ + き。或いはこれまでに実行したコマンドから拾ってくる? これまでに実行したコマ + ンドに関しては変な切り取り方をしても仕方がないので、 + + a 予めコマンド実行時の文法解析結果を元に単語を抽出してファイルに記録してお + く。これは comps との一致対象。記録は state ディレクトリの中にファイルを + 作成すれば良い。~/.local/state/blesh/history.xword.txt 等。 + + b 同様に単語がファイル名に一致する場合にはそのファイル名を記録する + (history.filename)。現在ディレクトリとの組にして記録するとより良いかもし + れない。これは compv に対して一致を試みる。 + + c 更に、simple-word の時には展開結果を記録する (history.vword.txt)? + + d 更に c をスペース等で分割して単語を記録する (history.eword.txt)? 然しこ + れも変な物を記録しても仕方がないので bash special chars に関しては含めな + い様にする。もしくはそれらも分割子として取り扱う。これも compv に対して一 + 致を試みる (特にスペース等で分割した後の直近の文字列に対して判定する)。 + + history に関しては ToDo 2021-05-17 に関連項目がある。 + 2022-12-09 * edit,complete: alias expansion で alias sudo='sudo ' 等による引数の展開に対応? @@ -2012,6 +2183,45 @@ bash_tips * complete: - で始まるファイル名には ./ をつける? + * コマンドによっては + で始まるファイルについても ./ をつける必要がある事も + ある。そもそも + で始まるファイル名は普通ではないという事を考えると、+ で + 始まるファイル名についても - で始まるファイル名と同様に一律で ./ をつける + 様にしてしまって良い気がする。 + + * './' を前置するという事は遡って書き換えるという事を意味する。どの様に取り + 扱うべきか。 + + a うーん。INSERT 時に suffix を付加するのと同じ要領で ./ を挿入するという + 事にする? ./ は shell special characters を含んでいないので quote の状 + 態がどうであれ勝手に挿入してしまって良い。 + + b オプション名及びファイル名の両方の候補がある場合に menu-complete で両方 + 選択肢を表示したい時にどうするのか。という事を考えると CAND の時点で ./ + をつけてしまって独立な二つの候補にする必要がある。という事を考えると元 + より CAND の時点で ./ をつけるべきなのかもしれない。 + + 然しこれだと実は filter されてしまうのでは? + + c a と b の両方を行うのが良い気がする。曖昧補間 (部分一致) の場合には b + の方法だと filter されてしまって出て来ないので、最終段階で ./ を挿入す + る様にすれば良い。一方で、先頭一致の場合にはオプション名候補と区別する + 為に ./ は CAND の時点で付けておく事にする。 + + * --prefix=filename の様に生成した場合には --prefix の前に ./ を付加してし + まわない様に、ちゃんと prefix 部分を認識して戦闘の [-+] 判定を行うべき。 + + ble.sh builtin filename generation で ./ を付けるのは良いとして、progcomp + で生成された - で始まる単語で同名のファイルが存在する場合にどうするか? + progcomp で生成された物でファイル名に一致する物があった時に、それがオプショ + ンを意図した物なのか或いはファイル名を意図したものなのかを区別する手段はな + い。 + + a bash-completion の _filedir 等に介入して ./ を付加する? 一方で、これでは + もっと細かい補間関数で個別に生成している物や、bash-completion ではない設 + 定に関しては対応できない。 + + b 或いは同名のファイルがある場合には問答無用で ./ を付加する事にする? + * complete: 空白で終わる alias の対応? 空白で終わる alias は次の単語の alias 展開も引き起こす。然し一方でコマンド @@ -2584,6 +2794,9 @@ bash_tips →direnv が丁度同じ事を目的としたプロジェクトの様である。 + 2023-01-30 direnv が一体どういう事をしているのかについて調べる → #M0023 に + 纏める事にした。 + 2021-12-20 * git-prompt, git-status 等の機能の模倣? @@ -3566,27 +3779,6 @@ bash_tips $ exec {}>/dev/null $ exec {_ble_base_fd_null}>/dev/null - * history: 履歴が余りに消滅するので ble.sh の側で独立した履歴の仕組みを作りたい - - 然し何処に履歴ファイルを置くのかという問題がある。 - - a 今日日、~/.ble_history 的なファイルを置くのは憚られる。 - - b .cache には消えても良い物を置くべきだから置くなという話もあれば、 - - c .config はユーザー設定に纏わる物で dotfiles に入れている人もいるから勝手 - に書き込まないで欲しいという話もある。 - - d 結局、.local/share/blesh/xxxx に置く事になるのだろうか。まあ、 - .local/share/blesh/data 辺りに置いて置けば良いだろう。然しその為には更に - 新しいディレクトリを生成する必要がある。現在は _ble_base, cache, run の三 - 種類のディレクトリがある。 - - 履歴はどの様に記録するのが良いか。日付は unix time で記録するのが人間に分か - る様に記録するのか。カレントディレクトリも記録したいし、存在する相対パスも - 記録したい。所で存在する相対パスはどの様にして抽出するのが良いのだろうか。 - 単語着色の時に検知した物を何処かに記録しておく必要がある。 - * 色見本について探した 多くのサイトは微妙である。そもそも sRGB とかの概念があるのかないのか不明で @@ -6654,6 +6846,347 @@ bash_tips Done (実装ログ) ------------------------------------------------------------------------------- +2023-01-26 + + * 2021-05-17 histdb: 履歴が余りに消滅するので ble.sh の側で独立した履歴の仕組みを作りたい [#D1925] + + * 然し何処に履歴ファイルを置くのかという問題がある。 + + a 今日日、~/.ble_history 的なファイルを置くのは憚られる。 + + b .cache には消えても良い物を置くべきだから置くなという話もあれば、 + + c .config はユーザー設定に纏わる物で dotfiles に入れている人もいるから勝手 + に書き込まないで欲しいという話もある。 + + d 結局、.local/share/blesh/xxxx に置く事になるのだろうか。まあ、 + .local/share/blesh/data 辺りに置いて置けば良いだろう。然しその為には更に + 新しいディレクトリを生成する必要がある。現在は _ble_base, cache, run の三 + 種類のディレクトリがある。 + + →これは XDG_STATE_HOME (~/.local/state) 以下に保存する事にする。 + + 履歴はどの様に記録するのが良いか。日付は unix time で記録するのが人間に分か + る様に記録するのか。カレントディレクトリも記録したいし、存在する相対パスも + 記録したい。所で存在する相対パスはどの様にして抽出するのが良いのだろうか。 + 単語着色の時に検知した物を何処かに記録しておく必要がある。 + + 2023-01-25 同期等面倒だし、sqlite3 形式で記録する可能性について考える。既に + atuin 等、他の類似のフレームワークも sqlite を使っている。 + + * sqlite3 / SQL の使い方 + + 基本的な使い方は以下のページが分かりやすかった。ページが分割されていてペー + ジを移動しにくいが。 + + https://www.javadrive.jp/sqlite/ + + * sqlite3: 直前に挿入した項目の番号は last_insert_rowid() で取得できる。 + + * sqlite3: シェル側で処理できる様に複数の値を出力する方法は? + NUL-terminatedで出力できるのが望ましい。 + + 以下のページによると NUL separated でデータを読み取る事はできないらしい? + https://www.reddit.com/r/sqlite/comments/a9xort/help_please_cli_line_null_separated/ + + 以下のページはデータ自体に NUL が含まれている時にどうするかだがこれも微妙に難しいらしい。 + https://sqlite-users.sqlite.narkive.com/mMwpNBzZ/getting-text-data-w-embedded-nulls-from-shell + + sqlite3 --help |& grep output を実行すると色々使えそうなオプションはある。 + + * 然し、-newline '\000' 等とすると実際に '\000' という文字列が + separatorとして使われてしまう。或いは -newline __ble_sep__ 等としてそ + れを別のプログラムで置換すれば良い気もするが、大量のデータの場合に全 + てが一行に繋がった状態で読み込まれてそれを分割する事になり、効率が気 + になる。 + + * -newline '' も試してみたが、これだと単にデータが separator なしでくっつ + いてしまう。 + + * -ascii は RS か何かを分割文字として使ってくれるが、それでも RS 自体がデー + タに含まれる場合に困る。 + + * -quote は sqlite3 の文字リテラル方式で quote してくれる物である。今の + 所、これを用いて処理するのが現実的の気がする。-html, -json, -csv, + etc でも独自の方法で曖昧でない様に quote してくれると思われる + が、-quote の方式に比べると規則が複雑になる。 + + awk で行を読み込んだら 1) 先頭の ' を削除する 2) '' を先頭から順に ' + に置換して行って、一番最後に単独 ' が残っていれば OK. そうでなければ + LFを追加して次の行を読み込んで同様に '' を置換していく。最後に単独 ' + が残っているのをどの様に判定するのかはよく分からない。或いは置換する + 前に ' の数を数えて偶数か奇数かで判定する可能性。或いは、最初に末尾の + ' の数を数えて奇数か偶数かを判定する可能性。こちらの方が現実的の様な + 気がする。つまり、match(/'+$/, $0) で一致しておいて、RLENGTH が偶数か + 奇数かで判定する。以下の様に書けば NUL-separated に変換する事ができる + 気がする。 + + awk ' + { + if (line == "" && sub(/^'/, "") == 0) { + # NULL や数値など + printf("%s%c", $0, 0); + next; + } + + if (match(/'+$/, $0) && RLENGTH % 2 == 1) { + sub(/'$/, ""); + line = line $0; + gub(/''/, "'", line); + printf("%s%c", line, 0); + line = ""; + } else { + line = line $0 "\n"; + } + } + ' + + * 履歴項目として何を記録するか。 + + - done: session_id, exec_id, cmd, cwd, start_time, end_time, 各種時刻情報, + $?, $!, $_, PIPESTATUS + + - done: user, hostname 等の情報は session_id の方で登録するべきの気がする。 + + - 記録するべきか微妙な物: BASHOPTS/$- (before/after), ret (after), $@ + (before/after), 背景ジョブ情報 + + * 関連プロジェクトの情報も集める。これは review として note.txt の上部に残 + しておく事にする。 + + * hook point + + 素朴には PREEXEC 及び POSTEXEC にて項目を登録 & update すれば良い。一方で、 + 単語情報やファイル名情報も一緒に記録するのだとしたら、文法情報が消滅する + 前に登録しておく必要がある。 + + a ADDHISTORY を通して記録するのが良いだろうか。その為には + ble/widget/default/accept-line に於いて ble/history/add の位置を移動す + る必要がある。今は histexpand の結果を表示してから ble/history/add をし + ている。然し、histexpand の結果を表示するよりも前に newline を実行しな + ければならず、その時点で文法情報などは失われている。なので、newline を + 実行する前に ble/history/add を呼び出す様に変更した方が良いだろうか。 + + 然し、ble/history/add で更に何かを出力する可能性があるのであれば、やは + りそれより前に newline を実行しておく必要があるので使えない。現在の所は + ble/history/add で直接何かを出力するという事はない様である。一方で、 + ADDHISTORY を呼び出したら失敗があるという事。@@@@ + + そもそもよく考えてみたら ADDHISTORY は文法情報等とは関係ない気がする。然 + し、一方で history の一環として登録するという意味においてやはり history + とは切り離せない。 history.sh を拡張する形で実装するのだとしたらやはり + ADDHISTORYを通して介入するのは自然である。 + + そうは言っても新しい history の枠組みは既存の history とは全く異なる物で + あって、現在の entry point だけでは不十分である。寧ろ様々な箇所で介入が必 + 要な気がする。という事を考えると、やはり ADDHISTORY とは別に hook を作成 + するべきなのだろうか。 + + →改めて考えてみたが単に ble/history/add を newline の前に移動しても問題 + ない気がしてきた。ADDHISTORY から何かメッセージを標準出力に出す可能性につ + いては、特に有効な使い道も思い浮かばない (とは言いつつ、現状では未だ + ADDHISTORY のタイミングで呼び出しておく必要のある情報など記録していないの + で気にしなくて良い気がする)。 + + * 速度について + + もう一つの懸念点は、この設計だと最低でも ADDHISTORY, PREEXEC, POSTEXEC の + 三回の sqlite3 呼び出しが必要になる。 + + 或いは ADDHISTORY の時点で sqlite3 に渡す sql 文を部分的に生成して置いて + その時点では sqlite3 は呼び出さない。sql 文を exec の枠組みの中で保持して + おいて、更に PREEXEC で sql 文を追加した後に呼び出すという形の方が良いか + もしれない。 + + 因みにどういった種類の情報を記録するのかについては現在の文法言語 (現在は + 基本的に "bash" しかないが) に依存している。文法言語ごとに指定できる様に + するのが良い気がする。table 名として syntax_bash_filename だとか + syntax_bash_word 等が良い気がする。 + + 長いコマンドの実行中に bash (もしくはコンピュータ全体) がクラッシュする場 + 合等を考えたら PREEXEC と POSTEXEC は両方とも sqlite3 を呼び出しておくべ + きだろう。 + + →実際に実装してみた所、PREEXEC, POSTEXEC だけでも結構遅くなる。時間を計 + 測してみるとそれぞれの呼び出しで 0.070 程度の時間がかかっている。合計で + 0.140 である。0.140 ならば短い様な気がしたが実際に sleep 0.140 を実行して + みると確かに遅い。 + + という事を考えると coproc (bash-4.0) もしくは procsubst を用いて bg で + sqlite3 を実行する必要があるのではないか。以下で coproc で sqlite3 を実行 + する事について書かれている。一応技術的には可能の様である。 + https://hackerpublicradio.org/eps/hpr3413/full_shownotes.html + + もしこれを実装するのだとしたら ADDHISTORY, PREEXEC, POSTEXEC の全てで実行 + するというのは別に大変という訳でもない。 + + →取り敢えず名前付きパイプを用いて実装してみた。どうやら期待どおりに動い + ている様な気がする。stdbuf を使わなくてもその場で応答してくれている。速度 + は挿入時に 0.060s ぐらいかかっているが使っている感じだと余り意識しなくて + 済む。この 0.060 かかっているのは恐らく rowid の読み取りの為。 + + うーん。既に非同期にしてしまったので rowid を読み取らなくても直接 + (session_id, exec_id) で指定して挿入してしまって良いのではないか→その様 + にしたら待ち時間は全くなくなった。rowid は再配置等が途中で起こった時に変 + な事になる可能性があるので、今回の様にちゃんと一意のIDで指定できる様にす + るのは大切な事である。 + + * done: BLE_SESSION_ID などを公開する。これらは contrib/histdb 側ではなくて + ble.sh の方で設定するべきではないか。 + + コマンド番号については BLE_COMMAND_ID で公開する。BLE_COMMAND_ID は + _ble_edit_CMD を公開する形にし、また reload で減少しない様に対処する。 + + * done: start_time -> issue_time in TABLE command_history + + * done: exec_id と command_id は役割が重複していないか? + + _ble_edit_CMD は gexec prologue で increment されている。一方で exec_id + も同様に PREEXEC で increment されている。 + + * done: また、万が一 command_id が重複した時に何が起こるのかについて考えて + おく必要がある。うーん。以前のコマンドの情報が上書きされて消えてしまうと + いう事の気がする。消えない様に調整などは可能だろうか。 + + a 例えば session 名を変更する等? 然し、その必要があったという事を外側に伝 + える必要がある。或いは、上書きされてしまっても仕方がないと諦める事にす + るか。或いは、既に存在する場合には元々あった方を無難な session に変更す + る等? + + b 或いは command_id を何か中途半端な値に書き換える。順番が分からなくなる + と思ったが何れにしても時刻は記録しているので必要があれば時刻を用いて並 + び替えるしかない。例えば既存の項目に対して command_id を使われていない + 最小の負の値に書き換えるなど。 + + 取り敢えず b の方法を実装してみた。実際にそれを起こすのは大変の気がする。 + 手で直接 db を弄れば行ける → 実際に重複が起こる様にして試してみたところ + ちゃんと期待通りに動いている。 + + * done: 将来の history の形式の変更に備えて history_format_version を埋め込 + む。misc table でも作って置けば良い。TABLE misc(key, value) に version と + いう項目を入れて整数値で version を指定する事にした。 + + 将来的に形式を変更する暁には version を増やして、また初期化時に version + が小さい場合にはアップグレードし、version が大きい場合には明示的に + version をファイル名に入れてファイルを開き直す。これはその時になってから + また考えれば良い。 + + * done: sqlite3 を nfs の上で使うと何が起こるのか? + + やはり駄目な事になってしまう様である。NFS の設定によってはちゃんと動くけ + れども、恐らくパフォーマンス上の問題から、普通は安全側に倒した設定にはなっ + ていないと考えるべきである。 + + https://techblog.raccoon.ne.jp/archives/1635140633.html + + となるとホスト毎に history を保持するべきの気がする。流石にホスト名に関し + ては重複している場合は考えなくて良いだろう。 + + NFSv4 は AFS (Andrew file system) の影響を受けてよりファイルロックに関し + て良い振る舞いをするらしいがよく分からない。 + + →ホスト名を履歴ファイル名に含める事にした。 + + ? done: HISTIGNORE に一致するコマンドは履歴に登録するべきなのだろうか? + + a 登録するべきでない気がする。やはり既存の bash_history の拡張という考え + 方だとしたら HISTIGNORE 等の取り扱いにちゃんと従っていて欲しい。そう考 + えると preexec ではなく ADDHISTORY で全て追加するべきだろうか。然し、 + ADDHISTORY に介入するとしても、別の ADDHISTORY hook によって追加がキャ + ンセルされたという場合も考えられる。また、加工した物を history -s で追 + 加している場合等も考えると単純にはキャンセルされたかどうか判定できない。 + + b reject: うーん。ADDHISTORY によるキャンセルは考慮せず、ADDHISTORY に到 + 達したら問答無用で追加するという事で良い様な気がする。また、現在は + start_time と exec_time_beg を別々に管理しているので start_time は + ADDHISTORY の段階で設定してしまって問題ないのである。一方で、issue のタ + イミングと exec のタイミングがちゃんと交互になっていない場合にどうする + のかについては注意が必要。 + + c これについては bleopt histdb_ignore で独立な設定として管理して貰うのが + 良い気がしてきた。HISTCONTROL の影響も受けない (例えば ignoredups 等に + よって最近のコマンドと同じコマンドだったら履歴には追加しないという振る + 舞いも、様々な情報を記録する場合には余り望ましい物ではない)。 + + うーん。変更の方針としては ble/history/add の時点で histdb の更新も行う。 + 但し、複数の履歴が絡んでいる事が考えられるので gexec に登録すると分かって + いる時にだけこれを実行する。その時点で _ble_edit_CMD の更新も行う。実行は + ADDHISTORY 経由ではなくて必ず呼び出す事にして、独自に bleopt + histdb_ignore 等の処理を行う。exec の枠組みに対しては exec_id を渡す事に + する。 + + * done: sqlite3 のプロセスが死んだ時にどうするのか? + + 毎回 kill で生存確認するのが良い気がする。何れにしても sqlite3 がクラッシュ + すればその親の subshell の bash はすぐに終了するはずなので $! で取ったプ + ロセス ID で生存確認すれば良い。或いは、exec を実行してしまえば $! が直接 + sqlite3 になる筈。 + + * done: last_wd を session に記録する。後でフィルタするのに役立つ。通常は最 + 初は home で始まって、最後のディレクトリが実際の作業ディレクトリだから。 + last_time も記録する。 + + * reject: coproc による実装 + + * うーん。coproc は同時に複数起動できないという説が出回っている。 + https://lists.gnu.org/archive/html/help-bash/2023-01/msg00181.html + + それならば何故変数名を指定できるのか + + →うーん。どうもジョブ管理 or exit status の追跡という意味で同時に複数 + 管理できないというだけであって、同時に複数起動する事自体ができない訳で + はない様な気がする。しかし、そもそも coproc で起動したプロセスをどの様 + に管理するのか、どの範囲まで成業できるのかというのが不明である。そもそ + も、現在裏で走っている coproc を閉じる方法はあるのだろうか。 + + うーん。どうも fd を開放してしまえば coproc が生きている等のエラーは表 + 示されない様である。勿論、ちゃんと fd を (親プロセス内で) dup して他の + fd として保持しておく必要があるが、その為には coproc は親プロセスで実行 + する必要があって、そうすると bash の foreground dead job の振る舞いによっ + て sqlite の項目が表示されてしまう事になる。或いは + __ble_suppress_joblist__ さえ含めておけば問題なく行けるのだろうか。 + + 技術的には可能の様に思われる。 + + * Cygwin 上では (もしくは bash-5.0 以降では) coproc を使った実装に切り替 + える? disown しておけば問題は起こらないだろうか? その場合には親シェルで + coproc を実行する必要がある。fd を取得する為に。或いは coproc で生成し + たジョブの中で更に & を開始して、ジョブ自体は即終了するという手もある。 + + % 取り敢えず cygwin 上で試してみる事にする。動いている。named pipe は動 + % かないけれども coproc は動くという事? 或いは named pipe も実は今は動 + % く様になっている可能性? + % + % →今 cygwin を試してみたら実は named pipe でも動く様になっていた。つ + % まり、coproc が動くからと言って昔の bash/cygwin でも coproc が動いた + % かどうかというのは保証がない。他の cygwin/mingw も動作を確認する。 + % MinGW 64bit で試してみてもちゃんと動く。cygwin 32bit でも動く。もしか + % すると動かないのは process substitution の時だけだろうか? うーん。 + % process substitution でも動く。 + % + % 改めて Qiita の記事を確認してみたら動かないのは exec 9<> fifo; read + % -t <&9 をした時である。先に書き出しの側のプロセスを起動しておけば問題 + % ない。つまり、今回は先に必ず sqlite3 のプロセスを起動しているので問題 + % は起こらない筈なのである。 + + つまり fifo による実装は Cygwin でも問題なく動く筈なので敢えて Cygwin + で除外する理由もない。msys2 では動くが msys1 では動かないという問題に関 + しては、msys1 では mkfifo の時点で失敗するのでそれを以て判定する事がで + きる。 + + よく考えたら既にユーザーが coproc を作成している時に coproc を開いてしま + うとユーザーが作成した coproc が閉じられてしまって大変な事になる。かと言っ + てサブシェルで coproc を作ってもその fd を親シェルに渡す方法がない。と考 + えると fifo に頼らざるを得ない。 + + * done: 途中でデータベースファイルを切り替えられる様にする。 + + 処理中の exec がある時に切り替えると変な事になるので全て完了した時点で切 + り替えを完了させる。通常は複数の exec が設定される事はないので実際上の問 + 題が生じるかは分からないが。 + + 対応した。 + 2023-01-24 * [自然解消] 2022-02-03 complete: 補完している時に勝手に変数の中身が展開されてしまう事がある [#D1924] diff --git a/src/def.sh b/src/def.sh index c7469953..e9259232 100644 --- a/src/def.sh +++ b/src/def.sh @@ -61,6 +61,7 @@ blehook/declare ERREXEC blehook/declare widget_bell blehook/declare textarea_render_defer blehook/declare info_reveal +blehook/declare exec_end # deprecated function function ble-edit/prompt/print { ble/prompt/print "$@"; } diff --git a/src/edit.sh b/src/edit.sh index 1024e4fa..12d8495a 100644 --- a/src/edit.sh +++ b/src/edit.sh @@ -529,9 +529,9 @@ function ble/prompt/initialize { local ret # hostname - ble/prompt/.initialize-constant '\H' 'ret=$HOSTNAME' escape + ble/prompt/.initialize-constant '\H' 'ret=${HOSTNAME:-$_ble_base_env_HOSTNAME}' escape _ble_prompt_const_H=$ret - if local rex='^[0-9]+(\.[0-9]){3}$'; [[ $HOSTNAME =~ $rex ]]; then + if local rex='^[0-9]+(\.[0-9]){3}$'; [[ $_ble_prompt_const_H =~ $rex ]]; then # IPv4 の形式の場合には省略しない _ble_prompt_const_h=$_ble_prompt_const_H else @@ -547,7 +547,7 @@ function ble/prompt/initialize { _ble_prompt_const_s=$ret # user - ble/prompt/.initialize-constant '\s' 'ret=$USER' escape + ble/prompt/.initialize-constant '\s' 'ret=${USER:-$_ble_base_env_USER}' escape _ble_prompt_const_u=$ret # bash versions @@ -2579,7 +2579,9 @@ function ble-edit/attach/.attach { if [[ ! ${_ble_edit_LINENO+set} ]]; then _ble_edit_LINENO=${BASH_LINENO[${#BASH_LINENO[@]}-1]} ((_ble_edit_LINENO<0)) && _ble_edit_LINENO=0 - _ble_edit_CMD=$_ble_edit_LINENO + + # When _ble_edit_CMD is empty or less than _ble_edit_LINENO, we update it. + ((_ble_edit_CMD<=_ble_edit_LINENO)) && _ble_edit_CMD=$_ble_edit_LINENO fi ble/builtin/trap/install-hook WINCH readline @@ -5702,7 +5704,7 @@ function ble-edit/exec/register { ble/edit/leave-command-layout return 1 fi - ble/array#push _ble_edit_exec_lines "$1" + ble/array#push _ble_edit_exec_lines "$((++_ble_edit_CMD)):$1" } function ble-edit/exec/has-pending-commands { ((${#_ble_edit_exec_lines[@]})) @@ -5937,7 +5939,7 @@ function ble/exec/time#restore-TIMEFORMAT { builtin unset -v 'TIMEFORMAT[0]' fi local tot usr sys dummy - IFS=' ' builtin read -r tot usr sys dummy < "$_ble_exec_time_TIMEFILE" + IFS=' ' builtin read "${_ble_bash_tmout_wa[@]}" -r tot usr sys dummy < "$_ble_exec_time_TIMEFILE" ((_ble_exec_time_tot=10#0${tot//[!0-9]})) ((_ble_exec_time_usr=10#0${usr//[!0-9]})) ((_ble_exec_time_sys=10#0${sys//[!0-9]})) @@ -6102,9 +6104,9 @@ function ble/exec/time#start { (printf) ;; (uptime|SECONDS) # これらの原点は unix epoch でないので補正する。 - ble/util/assign _ble_exec_time_SECONDS_base 'ble/bin/date +%s000000' + ble/util/assign _ble_exec_time_CLOCK_base 'ble/bin/date +%s000000' local ret; ble/util/clock - ((_ble_exec_time_SECONDS_base-=ret*1000)) ;; + ((_ble_exec_time_CLOCK_base-=ret*1000)) ;; (date) # どうせファイルコマンドを使うのであればより精度の良い物を使う。 if ble/util/assign ret 'ble/bin/date +%6N' 2>/dev/null && [[ $ret ]]; then @@ -6510,6 +6512,7 @@ function ble-edit/exec:gexec/.end { ble-edit/exec:gexec/.TRAPINT/reset builtin trap -- - DEBUG + blehook/invoke exec_end [[ $PWD != "$_ble_edit_exec_PWD" ]] && blehook/invoke CHPWD ble/util/joblist.flush >&2 ble-edit/bind/.check-detach && return 0 @@ -6521,13 +6524,15 @@ function ble-edit/exec:gexec/.end { ble-edit/bind/.tail # flush will be called here } -## @fn ble-edit/exec:gexec/.prologue command +## @fn ble-edit/exec:gexec/.prologue command command_id ## @param[in] command ## 次に実行するコマンド。_ble_edit_exec_BASH_COMMAND に記録する。 function ble-edit/exec:gexec/.prologue { _ble_edit_exec_inside_prologue=1 local IFS=$_ble_term_IFS _ble_edit_exec_BASH_COMMAND=$1 + _ble_edit_exec_command_id=$2 + BLE_COMMAND_ID=$2 ble-edit/restore-PS1 ble-edit/restore-READLINE ble-edit/restore-IGNOREEOF @@ -6537,7 +6542,6 @@ function ble-edit/exec:gexec/.prologue { ble/util/joblist.clear ble-edit/exec:gexec/invoke-hook-with-setexit PREEXEC "$_ble_edit_exec_BASH_COMMAND" ble-edit/exec/print-PS0 >&"$_ble_util_fd_stdout" 2>&"$_ble_util_fd_stderr" - ((++_ble_edit_CMD)) ble/exec/time#start ble/base/restore-BASH_REMATCH @@ -6691,10 +6695,11 @@ function ble-edit/exec:gexec/.setup { if ((count)); then ble/util/buffer.flush >&2 - local q=\' Q="'\''" cmd + local q=\' Q="'\''" line cmd cmd_id buff[ibuff++]=ble-edit/exec:gexec/.begin - for cmd in "${_ble_edit_exec_lines[@]}"; do - buff[ibuff++]="ble-edit/exec:gexec/.prologue '${cmd//$q/$Q}'" + for line in "${_ble_edit_exec_lines[@]}"; do + cmd=${line#*:} cmd_id=${line%%:*} + buff[ibuff++]="ble-edit/exec:gexec/.prologue '${cmd//$q/$Q}' $cmd_id" # Note #D1823: LINENO を unset せずに上書きする為に tempenv を用いる。 # Note #D1823: Bash に "builtin eval" で tempenv が消滅するバグがあるので # builtin を付けずに eval を直接呼び出す。adjust-builtin-wrappers して @@ -6746,7 +6751,7 @@ function ble-edit/exec:gexec/restore-state { # **** accept-line **** @edit.accept -: ${_ble_edit_lineno:=0} +: "${_ble_edit_lineno:=0}" _ble_prompt_trim_opwd= ## @fn ble/widget/.insert-newline/trim-prompt @@ -6948,13 +6953,13 @@ function ble/widget/default/accept-line { hist_is_expanded=1 fi + # 編集文字列を履歴に追加 + ble/history/add "$command" + ble/widget/.newline # #D1800 register [[ $hist_is_expanded ]] && ble/util/buffer.print "${_ble_term_setaf[12]}[ble: expand]$_ble_term_sgr0 $command" - # 編集文字列を履歴に追加 - ble/history/add "$command" - # 実行を登録 ble-edit/exec/register "$command" }