# -*- coding:utf-8 -*-

拡張

  * compopt -o ble/filter-by-prefix
    プログラム補完に於いて補完関数内で指定した場合、
    生成される候補を接頭辞が一致するものだけに絞り込む。

  * compopt -o ble/syntax-raw
  * compopt -o ble/no-mark-directories
  * compopt -o ble/prog-trim
  * compopt -o ble/no-default
  * HISTCONTROL=strip

制限

  * ble.sh を attach しているとき builtin read -e は動かない。
    代わりに ble.sh が定義したシェル関数 read (組み込みコマンドを上書き)
    を用いて read -e を呼び出す必要がある。

  * bash-3 C-d について

    今は何とか C-d を処理する事に成功しているが完全ではない。

    1 C-d を押した時に bash が出力するエラーメッセージを使って捕捉している。
      このエラーメッセージは言語や設定によって異なると思われる。
      現在は以下のメッセージを調べている。
      - 'Use "exit" to leave the shell.'
      - 'ログアウトする為には exit を入力して下さい'
      - 'シェルから脱出するには "exit" を使用してください。'
      自分の bash が異なるメッセージを出力する時は
      それを bleopt_ignoreeof_message に設定する。
    2 連続で沢山 C-d を押すと "^D" が echo されて表示が乱れるかもしれない。
      最悪の場合 C-d によって bash プロセスが落ちる可能性もあるかもしれない。
      (未だ落ちた事はないが)。
    3 C-d を処理する為に SIGUSR1 を使用している。
      その為 SIGUSR1 を別の目的で使用する事は出来ない。

  * 文字コードについて

    現在は基本的に UTF-8 を想定している。
    それ以外の環境のためには少なくとも以下の修正が必要になる。

    - ble.sh 自体を iconv で変換する事。或いは日本語を完全に排除する事。

      現在のところは日本語はコメント中にしか含まれていないはずである。
      コメントさえ削除すれば何処でも動くようになっていると良い。

    - 使いたい文字コード → unicode のデコーダを自分でかく事:
      これは "function ble-decode-byte+文字コード" を実装すれば良い。

    - Unicode → 文字のコードが正しく動作する様にする事:
      これは .ble-text.c2s (ble-core.sh) の辺りを直せばよい。
      "ble-text-c2b+文字コード"
      "ble-text-b2c+文字コード"
      も実装する必要がある。

    - ble/encoding:$bleopt_input_encoding/generate-binder

      現在 "C-@", "ESC" 及び "ESC *" を bind する為に、
      その符号化形式の非正規な符号に変換している。
      この変換はシェル関数 ble/encoding:$bleopt_input_encoding/generate-binder
      において文字符号化方式毎に (UTF-8 前提の設定を上書きする形で) 定義する。

      また bind を記録したキャッシュは $bleopt_input_encoding 毎に保持するが、
      このキャッシュの更新は bind.sh のタイムスタンプしか見ていない (ble-decode/bind 内)。
      新しい符号化方式を定義する時には、タイムスタンプを参照するファイル
      (ble/encoding:$bleopt_input_encoding/generate-binder を定義するファイル) を決める必要がある。


    他の文字コードは未だ一回も実装していないので上記以外にも必要な作業が出て来る可能性がある。

    + 2015-11-30 Note: ble-decode.sh (generate-source-to-unbind-default)

      文字コード実装時に問題があるかも。

      現在、bind -sp が出力する中途半端なバイトを解釈する為に、LANG=C で awk を起動している。
      UTF-8 の場合には複数バイト文字を構成するバイトは ASCII 文字と被らないので問題ないが、
      Shift_JIS 等の場合には ASCII 文字、特に \ や " を含む可能性がある。
      この場合には LANG=C にしていると問題が生じる。
      というか、bind -sp の出力する中途半端な文字と、複数バイト文字の一部を本質的に区別する方法はない様に思われる。

      ただし、救いは、もし ble.sh を plain な bash の上で起動するとすれば
      日本語で bind -sp に登録がなされていることはないだろうということである。
      つまり、ユーザが手で (或いは .inputrc に) bind '"日本語":"にほんご"' などとしない限りは問題は生じない。

  * bash-4.0, 4.1 において特殊シェル変数 FUNCNAME をユーザが unset した上で、
    関数内から ble.sh を source すると ble の使う連想配列がローカルに定義され問題になる。

    - bash-4.0 以降では連想配列を用いるが bash-4.2 未満では、
      連想配列を明示的にグローバルに配置することができない。

    - FUNCNAME がユーザによって削除されていなければ、
      この変数を用いて関数内から source されたことを検知できるので、
      その時には配列実装に fallback する。
      FUNCNAME が削除されていると fallback に正しく切り替わらずに問題になる。

  * bash-4.3 では C-x は、次の文字が来るまでは受信できない。
    bash-4.0 - 4.4 の他の version では遅延はないのでこれは bash-4.3 特有の問題である。

  * 構文に従った着色の中には bash の不自然な振る舞いや、
    複雑な振る舞いのために正確さを諦めた物がある。

    - bash の最初の [@()] の構文解析とパス名展開時の解析の齟齬

      echo [@(echo|[...])]

      恐らく bash は最初の単語の切り出しで @() を一単位として読み取り、
      ["@(echo|[...])"] の様に読み取る。その上で、改めてパス名展開を適用するが、
      その時には ["@(echo|[.."]")]" の様に解釈する。
      つまり、初めの構文解析とパス名展開の適用の間に齟齬がある。

      ble.sh では構文解析に従った解析・着色をすることにしたので、
      実際のパス名展開の適用結果が着色と異なることがあることに注意する。

    - bash echo {@(,)}

      これについても上と同様のことが起こる。
      単語の切り出しは {"@(,)"} となり、構文エラーは発生しない。
      後のブレース展開では {"@(",")"} と解釈されて分割される。
      単語が分断されてしまうのでパス名展開は起こらない。

    - bash のブレース展開時の ${var:-...}{,} の解析とパラメータ展開時の解析の齟齬

      echo ${var:-{a,b}{a,b}

      恐らく bash は最初にブレース展開を試みる時に、
      ${} の中については {} の入れ子を数えてスキップする。
      従って、上のコマンドの時は ${} が終端しないのでブレース展開は試みられない。
      しかし、パラメータ展開が実施される時には {} の入れ子は考慮に入れられず、
      最初に現れた "}" で終端するので、${var:-"{a,b"}"{a,b}" という解釈になる。

      [予定]
      ble.sh ではどの様に着色するか微妙である。
      理想的には最終的な解釈の ${var:-"{a,b"}"{a,b}" に応じた着色にしたいが、
      後半の {a,b} の部分が {} の入れ子のアンバランスによって
      無効化されている事を検出するのは困難である。
      仕方がないので、ブレース展開の {} の入れ子の勘定はバグとして無視する事にする。
      つまり、echo ${var:-"{a,b"}{a,b} という解釈で着色する。

    - bash のチルダ展開の時の echo a[]b]=~ の解析と、パス名展開の時の解析

      チルダ展開の時には a["]b"]=~ とはならず a[]"b]="~ という解釈になるので、チルダ展開は起こらない。
      一方で、パス名展開のときには a["]b"]"=~" という解釈になり、'ab=~' などのファイル名に一致する。
      ble.sh ではパス名展開の規則の方を優先させる。

    - ble.sh では [[ @({a,b}) ]] のブレース展開が有効であるかの様に着色される。

      実際には、条件コマンドの中ではブレース展開は無効になる。
      これに正確に対応する為には "条件コマンドの中の extglob"
      に対応する文脈値を定義する必要があるが、煩雑になるので対応していない。

    - ble.sh では echo [{@(a|b),[abc]}] の内部の extglob や [...] が有効であるかの様に着色される。

      しかし、実際にはブレース展開を実行したとしても [] の内部なので、
      extglob や [...] は不活性化しているはずである。
      しかし、これも解析が無意味に複雑になるので対応はしない。

    - ble.sh では echo {~user,~user} の内部のチルダ展開に反応しない。

      bash ではブレース展開された後にチルダ展開が実行されるので有効。

    - ble.sh はブレース展開が含まれる変数代入形式単語でも、
      ブレース展開より前のチルダ展開は有効である。

      bash では変数代入形式の単語の右辺でチルダ展開が起こる。
      しかし、ブレース展開が含まれている場合には例外としてチルダ展開が起こらない様だ。

      $ a=~:{a,b}:~:echo      → ブレース展開は起こらず、チルダ展開は起こる。
      $ echo a=~:{a,b}:~:echo → ブレース展開が起こり、チルダ展開は起こらない
                                 ble.sh では一つ目のチルダ展開の解析時点では、
                                 次にブレース展開が来ることを知らないので、
                                 一つ目の ~ はチルダ展開として着色する。

      規則がよく分からないが、取り敢えず ble.sh ではブレース展開が現れたら、
      それ以降はチルダ展開が無効になるようにしている。
      具体的には _ble_syntax_bash_command_IsAssign[ctx] の設定されている文脈は、
      ブレース展開が現れたときに、変数代入形式前の文脈値に戻すようにしている。

    - echo [a[!b

      echo [! の組み合わせは履歴展開にはならない。
      echo [a[!b] の場合にも履歴展開にはならない。
      しかし、echo [!a[!b の場合には履歴展開になる。
      違いは bracket expressions が閉じているか閉じていないかである。
      然し、それを判定する為には先読みをして単語の最後まで見ないといけない。
      それは実装上困難なのでこれは諦める。

      (bash の parser がここでどう動作しているのかは不思議ではある。
      例えば echo [a[!echo""] は無効で [a[!echo"" は有効である。)

    - echo $((echo)>/dev/null)
      よく考えたらこの有名なパターンに対応するのを忘れていた。

    - echo $(case A in A) echo B;; esac)
      実はこのパターン。Bash-4.0 以降では大丈夫だが、
      Bash-3.2 以降では構文エラーになる。ble.sh は bash-4.0 以降の振る舞いしかしない。

    - ${#var[...]修飾}
      この形式は Bash 的には構文エラーになるが、[...] の中身を相当先読みしないと
      修飾があるかないかを見る事ができないので諦めている。

    - set +H; echo ${!!修飾}
      これは Bash では構文エラーだが何故かが分からない。

    - {$v,$w}xxx これは $vxxx $wxxx に展開される。
      つまり、v と xxx がくっついて新しい変数名になる。
      これは分かりにくい動作だが、これを逆に使う人もあるのかもしれない。
      実の所、ブレース展開も文法レベルで実施されるべきなのかもしれない。

  * 2019-02-04 プログラム補完関数の中で標準入力は使えない。
    どうしてもユーザからの入力を得たい場合には、
    現在の補完が自動補完でない事を確認してから /dev/tty から直接取る事。

bash 実装上で注意するべき事

  * 3.0以上 [Note: これは regcomp の問題かもしれない]:
    正規表現 '.^' や $'\n^' は文字列の先頭ではなく行頭に一致する。

    その他の場合 (.*^ など) にはちゃんと文字列の先頭にしか一致しない様だ。

    Ref. #D1869

  * bash-5.2 以上の patsub_replacement に注意する。

    任意の文字列に置換する場合は & が勝手に解釈されない様に "${var/x/"$s"}" の
    様に quote すると良い。但し、bash-4.2 では "${var/x/"$s"}" の " は literal
    に解釈されてしまう事に注意する。一番安全なのは一旦変数に代入するという事。

  * 変数の代入は基本的に quote は必要ないが、

    1 チルダで始まる時はチルダ展開を防ぐ為に quote が必要。
      (変数展開の中にあるチルダは quote しなくても大丈夫)

    2 配列要素を空文字列で連結するときは quote が必要。
      つまり、IFS= eval 'declare var=${arr[*]}' とすると空白区切りになる。
      IFS= eval 'declare var="${arr[*]}"' とする必要がある。
      また IFS が中身のある場合には問題は起こらない。

      - bash-4.3 以降では IFS= eval 'var=${arr[*]}' なら OK

    関係あるか分からないが
    http://lists.gnu.org/archive/html/bug-bash/2017-04/msg00001.html
    において以下のような例が紹介されている。これは bash-4.5 で修正されるらしい。

    | bash-4.2$ unset IFS; set ' '; a=$*; printf '<%s>' "$a"
    | < >
    | bash-4.3$ unset IFS; set ' '; a=$*; printf '<%s>' "$a"
    | <>

  * コマンドをつなぐ && と || の優先順位は同じで左結合である
    但し、算術式や [[ ]] に登場する && と || はC言語と同じ優先順位である。

  * unset の引数は quote しないとパス名展開の対象である。
    特に配列要素を消す場合には [...] を quote する必要がある。

  * unset -v または unset -f と明示的に指定しないと、
    意図せず同名の関数または同名の変数を消去してしまう可能性がある。
    変数を消す場合でも unset -v と明示する必要がある (ref #D0893)。

  * コマンドの単語中のパラメータ展開は "" でクォートする必要がある
    (ref #D0943)

    特に値として以下の物が含まれている可能性がある時は絶対必要である。
    先ず始めに IFS に含まれる文字がある場合は意図しない単語分割を抑制する為に "" で囲む。
    次に、グロブの特殊文字 *?[ が含まれている場合にも注意する。
    shopt -s extglob の時には @( や !( の並びにも注意する必要がある。
    更に、'\' が含まれる場合もグロブ特殊文字のクォートに何故か影響を与える様なので注意する。
    これは例えば shopt -s failglob において、a='\'; echo $a'*' がエラーメッセージを出す事で分かる。

  [complete 仕様について]

  * compgen -f はクォート除去、チルダ展開を実行する
    理解できないのはクォート除去した後にチルダ展開をするという事。
    compgen -f "'~/'" としても '~' というディレクトリには決して一致しない。
    compgen -f "'\~/'" 等とクォートした上に backslash も指定しないと行けない。
    結局どういう規則なのか分からないので、寧ろ arr=('~/'*) 等の様にするべき。

    Note: ~ だとちゃんと現在のディレクトリ以下のファイルに一致するようだ?
    Note: compgen -W でも似たような quote 除去・ブレース展開などを行う様だが、
      それでも理解できる振る舞いになっている。
    Note: bash --norc で echo \~/ から補完を実際に実行してみると echo ~/... に書き換わってしまう。
      何処かで quote が消えてしまっている。これはバグと見做すべきであろう。

  * $ complete -F foo -C bar command と登録すると foo, bar の両方が foo bar の順に実行される。
    $ complete -C bar -F foo command と登録すると bar foo の順に実行される。
    しかし、complete -p とすると両者とも
    complete -C 'bar' -F foo
    と表示され登録順・実行順についての情報を取り出す事ができない。

    →今試すと必ず foo bar の順序でしか呼び出されない。compgen でも同様に見える。

  * $ complete -F hoge1 -F hoge2 command とすると、-F hoge2 だけ有効になる
    (complete -p による表示もそうだし、実際に実行されるのも hoge2 だけであった)。
    -F オプションは後からものによって上書きされるという事の様だ。

  * shopt -q は通常の出力はやめてもエラーメッセージは出す。
    つまり未実装のオプション (compat* や autocd) について
    shopt -q をするとエラーメッセージが出力されるので
    結局 &>/dev/null にリダイレクトしなければならない。

  * locale の環境変数 LC_*/LANG を設定する時は &>/dev/null する必要がある。
    ref #D1205 #D1341 #D1355

    元々入っていた値が不正な値である場合、
    元の値を復元した時にエラーメッセージが意図されず出力される。

    ローカル変数として設定する場合は、
    - 値の復元はどうやら関数の本体を完全に実行し終わった後に起こる様なので、
      関数の本体自体を &>/dev/null で囲んでも意味はない。
    - 関数の中で unset を行っても意味はない。
    - 関数の中でもとの値を設定しても意味はない。
      関数が抜ける時に改めて設定される様だ。

    IFS= LC_ALL=C read -t 0 &>/dev/null
    としても復元時のメッセージは何故か抑制できなかった。

    * #D1341 更に、bash-4.1 以下では LC_ALL= LC_COLLATE=C func 等の形式にしても
      効果が現れない。local LC_ALL= LC_COLLATE=C としないと効かない様である。

      外部コマンドを呼び出す時には問題は起こらない。関数経由でも大丈夫。
      逆に外部コマンドの時には "LC_ALL=C awk" の形式にする必要がある。
      もしくは "local -x LC_ALL= LC_COLLATE=C" とする。

      ng$ aaa() { echo ${#1}; }; LC_CTYPE=C aaa あいうえお
      ok$ echo あいうえお | LC_CTYPE=C awk '{print length($0)}'
      ok$ echo あいうえお | LC_CTYPE=C ble/bin/awk '{print length($0)}'

    * 2021-01-15 aaa() { local LC_ALL= LC_CTYPE=C; ... ; } 2>/dev/null の形式でも
      駄目だという事が判明した。ちゃんとする為には関数内で unlocal までする必要がある?

  * Bash 正規表現はシステムの <regex.h> を使用するので環境依存である。

    Linux においては bash 正規表現の POSIX 文字クラス ([[:alpha:]] など) は
    ロケールによって何にでも一致するので信用できない。
    例えば GNU/Linux (Fedora 25) では ja_JP.UTF-8 で [[:alpha:]] は漢字・仮名にも一致する。

  * bind 関数の中で set +o emacs などをして編集モードを無効にすると、

    編集関数の実行自体が中断されるようである。
    具体的には set +o emacs を含む行だけ実行されて、次の行以降は実行されない。
    set +o emacs が eval に含まれる場合は eval が終わると共に中断される。
    また関数内に set +o emacs がある場合は、その関数は最後まで実行されるようだ。

    従って set +o emacs が実行されたことを検知して適切な後処理を実行するのは難しい。
    更にその後で set -o emacs に戻ってくると変な状態になる。
    bind -p ではちゃんと hook された状態になっているが、
    実際に操作してみると keymap はリセットされているように見受けられる。
    この辺りはもう少し詳しく調べてみないと具体的に何が起こっているかはわからない。

    例: 以下の3行のコマンドを実行しようとすると途中で中断され元の状態には戻らなくなる。

    $ set +o emacs
    > echo hello
    > set -o emacs

    直接 readline で実行している場合にはこの問題は起こらない。

  * ble.sh では変数の -i は積極的には使用しないことにした ref #D0894

    関数引数に使用する場合は、そもそも -i の機能を使う機会の方が少ないので
    全ての関数の引数に適用するのは非効率であり、一部の関数の引数にだけ適用するのは
    関数の仕様として分かりにくくバグの元である。そもそも算術式展開が必要化どうかは
    呼び出し元が知っていることのはずなので呼び出し元で算術式展開をするべきである。

    関数内で使用する場合についても明示的に算術式展開を実行すれば良い。

  * bind 関数中の set +v は揮発性 ref #D0930 (Bash 3.0--5.0)

    bind 関数中で set +v 等としてもその状態は
    次の bind 関数の呼び出しの際には元に戻ってしまう。
    この振る舞いは試した全ての bash version で共通だった。

bashbug: 実装上で注意するべき事・バグ

  * bash-5.0 -- 4.4 (ref #D1334)
    trap handler が実行中に return を無引数で呼び出すと、
    無条件に trap handler 起動直前の $? が関数の終了ステータスになる。
    POSIX に要求されていると書かれているが解釈に難がある。
    特に trap handler を抜ける時の戻り値だけに影響を与えるのが自然に思われる。

  * bash-5.0 -- 3.0 (全 version) バグ (ref #D0943)

    $ shopt -s failglob
    $ a='\'; echo $a'*'

    これで failglob になる。\* に一致するファイルは存在しませんのエラーメッセージ。
    ファイルとして '*', '\*', '\a', 'a' 等があっても決して一致しない。
    これを防ぐ為には、パラメータ展開は必ず "" でクォートする様にすれば良い。

  * bash-5.0 -- 3.0 (全 version) バグ

    history -p をコマンド実行中に呼び出すと呼び出す度に履歴項目が減る。
    これは例えば f1() { history | tail -1; history -p '!!'; history | tail; } として、
    f1 を実行すると分かる。f1;f1;f1 等とすると一回で3件消える。
    更に bash-3.0 では bind -x の関数の中であっても history -p を呼び出す度に履歴項目が減る。

  * bash-4.4 -- 4.3 バグ

    \C-@ 関係に bind -x すると正しく動かない
    bash-4.4 での動作については未だ確認していない。
    → bash-4.4 でもやはり動かない。

    これは修正した http://lists.gnu.org/archive/html/bug-bash/2018-03/msg00165.html

  * bash-4.4 -- 3.2, etc

    rex="^([^\$]|\\'[^\\']*\\')+\$" && [[ 'i$' =~ $rex ]] && echo hello
    が一致する。\' の解釈が謎である。単に ' とすれば問題ない。

    rex=$'^([^$]|\\\'.\\\')+$' でも一致する。
    rex=$'^([^$]|\\\')+$' だと一致しない。
    \' は何らかのアンカーとして解釈されるという事だろうか。
    或いは単純に無視されているのか。

  * bash-4.2

    declare -g -r var とした時に、
    グローバル変数が定義されていなければローカルに新しく変数を作る様だ。
    bash-4.3 で直っている。

  * bash-4.2 以下
    bash-4.2 ～ bash-3.0

    \C-x 単体に bind -x して C-x に続けて何か打つと segfault する。
    $ bind -x '"\C-x":echo' → 続けて C-x a 等と入力

  * bash-4.1 以下: LC_CTYPE=C eval 'echo ${#var}' としても
    ${#var} が元のロケールで計算される。"変数代入 コマンド"
    の形式だとロケールの初期化が間に合わないのだろうか。

  * bash-4.0 segfault

    以下で segfault を起こすことが分かった。bash-4.1 以降では直っている。

    bash-4.0 -c 'function f1 { COMPREPLY=(alpha); }; compgen -F f1 2>/dev/null'

    但し、ble.sh の使用中に実際に compgen -F を通して segfault になることはなかった。
    もしかすると何らかの条件が整うと segfault するかもしれないので、
    念のためここに記録に残しておく。

  * bash-4.0 -- 3.0

    $'' 内に \' を入れていると履歴展開が '' の中で起こる?
    例えば rex='a'$'\'\'''!a' とすると !a の部分が展開される。

  * bash-3.2 以下ではプロセス置換に含まれるブレース展開は
    プロセス置換ごと複製してしまう。
    例えば echo <(echo {1..3}) は、
    echo <(echo 1 2 3) ではなくて、
    echo <(echo 1) <(echo 2) <(echo 3) に展開されてしまう。

  * bash-3.2 以下では declare a としただけで空の値で初期化される。
    unset 状態になるという事はないので注意を要する。

  * bash-3.2, bash-3.1 では source にプロセス置換を渡しても読み取ってくれない。
    つまり source <( ... ) としても何も起こらない。
    代わりに eval -- "$( ... )" すると良い。

  * bash-3.2 -- 3.1

    ref #D0857
    10 以上のファイルディスクリプタで使用されている物に対して
    リダイレクションで新しい出力先を設定しようとしても失敗する。
    これは fd>&- として一旦閉じてからリダイレクションすれば良い。

    bash-3.1 では一度開いた fd を改めて開き直したり、
    或いは閉じたりすることができない。
    exec 34>/dev/null とすると、exec 34>&- としても閉じれないし、
    exec 34>a.txt としても /dev/null に繋がったままになってしまう。

  * bash-3.1 では a=(""); echo "a${a[*]}b" | cat -A とすると
    a^?b となって謎の文字が入る。echo "a""${a[*]}""b" 等とすれば大丈夫。

  * bash-3.1 では declare -f funcname の funcname に + 等の文字を含める事ができない。
    一応 declare -F 等とすれば名前は列挙される様ではある。
    bash-3.2 未満では declare -f ではなく type -t で関数かどうかの確認を行う。

  * bash-3.1 での bind -r について
    bind -sp とすると "\M-[C" 等と表示されるがそれに従って bind -r '\M-[C'
    としても削除する事は出来ない。代わりに bind -r '\e[C' とすれば削除できる。

    eval -- "$(bind -sp | awk '/M-\[/{sub(/:$/,"",$1);gsub(/\\M-/,"\\e");print "bind -r " $1}')"

  * bash-3.1
    呼出先の関数で、呼出元で定義されているのと同名の配列を作っても、中が空になる。
    > $ function dbg/test2 { local -a hello=(1 2 3); echo "hello=(${hello[*]})";}
    > $ function dbg/test1 { local -a hello=(3 2 1); dbg/test2;}
    > $ dbg/test1
    > hello=()

    これは bash-3.1-patches/bash31-004 で修正されている様だ。

  * bash-3.1

    - ${#arr[n]} は文字数ではなくバイト数を返す様だ。

    - "${var//%d/123}" は動かない。"${var//'%d'/123}" 等とすればOK。

    - bash-3.0, bash-3.1: local GLOBIGNORE すると、
      関数を出てもパス名展開の時にその影響が残っている。
      (直接変数の中身を見ても何もない様に見えるが。)
      unset GLOBIGNORE などとすると直る。

  * bash-3.0

    - ${#param} は文字数ではなくバイト数を返す、という事になっているらしいが、
      実際に試してみると文字数になっている (bash-3.0.22)。
      何処かで patch が当たったのだろうか。まあいいか…。

      (※${param:ofs:len} は 3.0-beta1 以降であれば文字数でカウントされる)

    - declare -p A で改行を含む変数を出力すると改行が消える。
      例: 一見正しく出力されている様に錯覚するが "\ + 改行" は改行のエスケープではなく、
        長い文字列リテラルを二行に書く為の記法である。つまり、無視される。
      $ A=$'\n'; declare -p A
      | A="\
      | "

    - "${scalar[@]/xxxx}" は全て空になる。変数名が配列である事が保証されている
      必要がある。

    - "${...#$'...'}" という形を使うと $'...' の展開結果が ... ではなく '...'
      の様に、余分な引用符が入ってしまう。extquote を設定しても結果は変わらない。

  * msys1, msys2: var='^M' とすると CR が消えてなくなる。
    msys2 では var=$'\r' とすれば大丈夫。また変数に入っている物も大丈夫。
    例えば var=$_ble_term_CR はOKである。
    msys1 ではそれでも駄目。local var=$'\r' とすれば大丈夫。
    変数に入っている物でも local を付けないと消滅してしまう。

  * msys1 では named pipe が未対応。従ってプロセス置換も使えない。

bashbug 算術式周りのバグと注意点

  * bash-3.0 - 4.4.7 算術式:

    条件分岐で実行されない部分でも配列の添字は 0 以上でなければならない。
    例えば以下はエラーになる @ bash-3.0, 3.1, 3.2, 4.0, 4.2, 4.3
    ((a=-1,a>=0?b[a]:0))

    もっと調べてみると配列の添字に限らず分岐しない所で式が評価されている様だ:

    + 三項条件式で起こる。true/false branches のどちらでも起こる。&& や || では起こらない。

      $ echo 'x=a=1; ((a=0,0?x:0)); echo $a' | bash      1 (bash-3.0 - 4.3)
      $ echo 'x=a=1; ((a=0,1?0:x)); echo $a' | bash      1 (bash-3.0 - 4.3)
      $ echo 'x=a=1; ((a=0,0&&x)); echo $a' | bash       0 (bash-3.0 - 4.3)
      $ echo 'x=a=1; ((a=0,1||x)); echo $a' | bash       0 (bash-3.0 - 4.3)

      $ echo 'x=a=1; ((a=0,0?b[x]:0)); echo $a' | bash   1
      $ echo 'x=a=1; ((a=0,0&&b[x])); echo $a' | bash    0 (bash-3.0, 3.1, 4.2+ / bash-3.2, 4.0, 4.1 は別の bug で 1)

    + 括弧で囲めば何も起こらない様だ。

      $ echo 'x=a=1; ((a=0,0?(x):0)); echo $a' | bash    0 (bash-3.0 - 4.3)
      $ echo 'x=a=1; ((a=0,1?0:(x))); echo $a' | bash    0 (bash-3.0 - 4.3)

      $ echo 'x=a=1; ((a=0,0?(b[x]):0)); echo $a' | bash 0 (bash-3.0, 3.1, 4.2+ / bash-3.2, 4.0, 4.1 は別の bug で 1)

  * bash-4.2 算術式 seg fault

    https://lists.gnu.org/archive/html/bug-bash-gnu/2013-01/msg00036.html
    https://lists.gnu.org/archive/html/bug-bash-gnu/2013-01/msg00042.html
    https://lists.gnu.org/archive/html/bug-bash-gnu/2013-01/msg00043.html

    算術式の中で配列要素の参照に関係して特定の式構造になると segfault する。
    多分、配列要素の読み出しの次の token が整数または代入式の左辺だと落ちる。
    配列要素を参照したら一旦算術式を閉じるのが良い。
    $ ((a=b[0],c=0))

    以下でも segmentation fault が起こった。
    $ (((klen=node[nofs+k])<0||(kbeg=j-klen)>end0))
    $ (((a=node[1])<2||(b=3)))
    $ (((a=node[1])||(b=3)))
    $ (((a=node[1])<2||b)) # OK
    $ (((a=node[1])||b))   # OK
    $ (((node[1])||(b=3))) # OK
    やはり起こる条件が良く分からない。
    代入式の右辺に配列が来て、
    その後に代入式の左辺に token があると駄目なのか?

  * bash-4.1, 4.0, 3.2: 算術式分岐内配列参照

    bash-3.2.48 で以下の評価に失敗する。
    bash-3.1 以下は大丈夫。bash-4.2, bash-4.3 も大丈夫。bash-4.0 は駄目。

    dbg=()
    ((a=0,b=0,0&&(a=1,x=dbg[0],b=1))) # NG
    配列添字で値を参照 (代入はOK) すると、その部分以降が必ず実行される。
    複合代入であっても駄目である。

    bash-4.0 bash-4.1 でも以下の式で必ず _pos[1]++ が実行されていた。
    ((_eoc[2]&&(_pos[0]=0,_pos[1]++)))


    $ ((a=0,b=0,0&&(a=1,x=dbg[0],b=1))); echo $a $b               → 0 1
    $ expr="a=1,x=dbg[0],b=1"; ((a=0,b=0,0&&expr)); echo $a $b    → 0 1
    $ expr="a=1,x=dbg[0],b=1"; ((a=0,b=0,0&&(expr))); echo $a $b  → 0 1

    更に配列添字も必ず評価されてしまう。
    ((i>=0&&a[i])) は i が負であっても参照される。
    そして、((i>=0&&a[i--])) をすると更に副作用も起こる。

  * bash-4.1 以下 (bash-3.0 ～ bash-4.1)

    配列要素に対して修飾付きのパラメータ展開を実行すると、
    配列添字に指定した算術式が2回評価される。
    例えば "${arr[i++]#a}" を実行すると i が 2 増える。

  * bash-4.0 他 算術式を使って値を計算する時の注意

    算術式の中に初期化されていない変数…例えば ret 等がある場合、
    ret の中身に不正な数式的な物が入っていたりコマンド置換が入っていたりすると、
    文法エラーになったりこれが eval されてしまう。
    実際に 4.0 では 'あ' という文字列が入っているだけでエラーになる。
    (より上の version では識別子名と解釈されているからなのかエラーにはならない。
    しかし、今迄は毎回「あ」等という変数を探していたのだろう。

  * bash-3.1, 3.0

    ?: 演算子の中身は全てカッコで囲まないと構文エラーになる。例えば、
    $ bash-3.1 -c '((a?(b=123):c?(d=321):1))'
    bash-3.1: ((: a?(b=123):c?(d=321):1: syntax error in expression (error token is "?(d=321):1")

  * bash-3.0

    D1956: 関数定義の一番外側でリダイレクトしてもリダイレクトされない。例えば、
    function func { ls -l /proc/$BASHPID/fd/{0..2}; } <&"$fd0" >&"$fd1"

bash 配列の宣言に関する仕様・バグと注意点

  * arr=(1 2 3) func の形式で配列をシェル関数に渡そうとすると、
    export arr='(1 2 3)' で渡されてしまう。

  * 既に配列変数になっている物に対して
    export var=value や typeset -x var=value をしても、
    呼び出された別コマンドからは環境変数として見えない。

    $ a=(1 2 3)
    $ (export a=1; bash -c 'declare -p a')
    bash: 0 行: declare: a: 見つかりません

    新しい変数として導入すれば良い。
    例えば関数内で新しく local -x var=value とするか、
    var=value command の形式で呼び出すようにすれば良い。

    $ (a=1 bash -c 'declare -p a')
    declare -x a="1"

  * BUG bash-4.0, 4.1 (local), bash-3.0 ～ 3.2 (declare)

    a[${#a[*}]=value もしくは ble/array#push a value するとき、
    その配列を事前に宣言したければ local -a a のように -a を指定する必要がある。

    [問題]

    bash-4.1 以下で関数内で local arr しただけで ${#arr[*]} が 1 になる。
    その後、要素 #1 を設定しても ${#arr[*]} は 1 のままである。
    これの所為で以下のコードが破綻する:
      arr[${#arr[*]}]=...
    常に要素 #1 にしか代入されない事になる。

    bash-3.2 以下では関数内に限らず declare arr しただけで ${#arr[*]} が 1 になる。
    但し、要素[1] に設定をすると ${#arr[*]} は 2 に増加する。
    従って余分な空要素があるものの ble/array#push は失敗しない。

    [解決]

    local -a arr とすれば問題は起きない。
    ※local arr=() としても問題は起きないがこの記述だと
      今度は bash-3.0 で文字列 '()' が代入されて問題である。

  * BUG bash-3.0: local a=(...) や declare a=(...) とすると、a="(...)" と同じ事になる。
    a=() の形式ならば問題ない。

  * BUG bash-3.0: 今まで local -a a=() の形式ならば問題ないと信じてきたが、どうやら
    local -a a=('1 2') が local -a a=(1 2) と同じ意味になってしまうようだ。
    a="123 345"; declare -a arr=("$a"); このようにしても駄目だ。
    a="123 345"; declare -a arr; arr=("$a"); こうする必要がある。

  * BUG bash-3.0: "${var[@]/xxx/yyy}" はスカラー変数に対して空の結果を生む。
    ${var[@]//xxx/yyy}, ${var[@]/%/yyy}, ${var[@]/#/yyy} についても同様である。

  * 配列要素を連結する時

    動く例:
      IFS= eval 'value=${arr[*]}'
      IFS= eval 'value="${arr[*]}"'
      IFS= eval 'local value="${arr[*]}"'

    動かない例 (間に空白が入ってしまう):
      IFS= eval 'local value=${arr[*]}'

  * BUG bash-4.0..4.4: ローカルで local -a x; local -A x とすると segfault する。
    ref http://lists.gnu.org/archive/html/bug-bash/2019-02/msg00047.html, #D0924

    f() { local -a a; local -A a; }; f # これで segfault する

    - 別のスコープで定義された配列を -A とした場合には起こらない。
    - 同じスコープの場合でも unset a してから local -A a すれば大丈夫。
    - グローバルでは起こらない。

  * BUG bash-3.0..3.2: ^? や ^A の値が declare -p で ^A^? や ^A^A に変換されてしまう。

その他のバグ

  * BUG gawk-4.0.2 正規表現 [][:space:]] や [^][:space:]] に対して警告メッセー
    ジを出力する。実際には正しく解釈して正しく動作する様である。また、他の gawk
    version では問題はない。

    これは scan チェックに含める事にする。

bash_features

  * time -- について。
    bash-5.1 以降で time -- command が可能。
    bash-4.2 以降で time -p -- command が可能。
    (bash-4.1 以前では time には -- を指定できない)

  * bash-5.0 以降: EPOCHREALTIME, EPOCHSECONDS
    ref #D0925

  * Bash-5.0 では POSIX に倣ってパラメータ展開結果に \ が含まれる場合に
    グロブパターンと見做す様に変更されたが、
    これにより問題が起こり POSIX が記述に誤りがあることを認めて修正した。
    結局 Bash-5.1 で 4.4 と同じ動作に戻すつもりらしい。
    https://lists.gnu.org/archive/html/bug-bash/2020-03/msg00051.html

  * ${param@a} (attributes) 及び他の transformation は bash-4.4 より

  * read -t timeout

    * -t オプションの対応は 2.04 である。
    * TMOUT 変数の対応は 2.05b-alpha1 以降である。
    * 小数を指定できる様になったのは 4.0-alpha 以降である。
    * `-t 0' で次の文字を読み取り可能かどうかチェックできるのは 4.0 以降である。
    * 4.3 以下では timeout した時に読み取った入力は失われてしまう。
      4.4 以降では timeout するまでに読み取った内容が指定した変数に格納される。

  * グローバル変数に対する属性指定 declare -g は bash-4.2 から

    更に bash-4.3 には declare -gA を二度行うとクラッシュするバグがあったらしい。
    現在の最新版ではそのような振る舞いは見られない?

    2021-02-10 #D1470 どうも bash-4.2 の declare -g にはバグがある。declare -gA
    とすると属性は global まで適用されるが、代入された値は関数を抜けると共に消
    滅する。2021-05-20 追記。declare -gA a=() とすると関数を抜けると共に値が消
    滅するが、declare -gA a; a=() とすると特に問題は生じない。

  * 連想配列 declare -A は bash-4.0 から

  * BASHPID 何と Bash 4.0 以降の機能らしい ref #D1200

    ------------------------------------------------------------------------------
    This document details the changes between this version, bash-4.0-alpha,
    and the previous version, bash-3.2-release.

    c.  There is a new variable, $BASHPID, which always returns the process id of
        the current shell.
    ------------------------------------------------------------------------------

    と思ったら既にソースコードの一部にも Bash 4.0 以降であるとの注記があった。

  * command |& command は Bash 4.0 以降なので使えない。

  * printf -v var %s value

    bash-3.1 以降で使える。
    bash-4.1 以降で var として配列要素 (arr[123] 等) を指定できる。

  * printf %(...)T は bash-4.2 以降から。但し、bash-4.2 では -1 を明示的に指定
    しないと現在時刻になってくれずに 0 になってしまう。bash-4.3 以降では省略し
    た場合は現在時刻になる。

  * ${!arr[@]} は bash-3.0 より

bash_tips

  * swap の仕方
    local a=$b b=$a
    local や declare などは必要である。

  * [[ ]] の中で =~ で設定された BASH_REMATCH は直後の式で参照できる。
    つまり [[ $text =~ $rex && $BASH_REMATCH == ... ]] の様にできる。

    bash-3.0 から bash-4.4 までで以下のコマンドで確かめた。

    [[ "" =~ ^ ]]; [[ $BASH_REMATCH ]]; [[ a =~ a && $BASH_REMATCH ]]

  * 構文関係でマニュアルに載っていないものが色々ある。

    * }, fi, done, esac の直後に }, fi, done, esac, do, else, elif, then が来る場合はセミコロンは省略できる。

    * for ((expr1; expr2; expr3)) [ ; ] { list; } は比較的有名だが、
      for name [in name]; { list; }
      select name [in name]; { list; } も使える様だ。

    * select name [ [ in word ... ] ; ] do ...; done
      ※in word ... がない場合、do の前のセミコロンは省略可能である。

  * "$(case *) ;; esac)" に対応する可能性があるかと思ったが動きはない
    ref http://lists.gnu.org/archive/html/bug-bash/2017-11/msg00002.html, #D0928

  * function @() { ...; } は成功するが実際には関数は作られない
    ref http://lists.gnu.org/archive/html/bug-bash/2017-03/msg00220.html, #D0927

  * declare -c var という隠し属性がある。Capitalize する。Bash 4.0+
    変数の値の各単語について適用するのではなく本当に最初の文字にしか適用されない。
    この中途半端な機能の為に恐らくマニュアルに載っていないのだろう。

    ソースコードを確認すると他にも declare -G var という謎機能が存在する。
    同じ文脈に局所変数があればそれに設定してそれ以外ならば大局変数に設定する。
    これは丁度他の言語のレキシカルスコープを真似た物という事だろうか。

  * nameref & extra expansion
    気付いたのだが declare -n ref='arr[...]' の ... に任意の式を記述できる。
    これによって新しい乱数変数も定義できるのでは。例えば。

    declare -n var='var_[var_=RANDOM*RANDOM,0]'

    但し、算術式なので整数以外は代入できない。
    更に、$() でプログラムを実行することすらできる。
    然し、任意の文字列という訳には行かないのが問題。
    $() はサブシェルで実行されるので副作用を残す事ができない。

  * let & brace expansion
    これは算術式のページに既に書いた。

  * rcfile を処理している間は

    * 関数内で FUNCNAME, BASH_SOURCE, BASH_LINENO を確認するとFUNCNAME
      の最後の要素は "source" であり、BASH_LINENO の最後の要素は 0 に
      なっている。BASH_SOURCE の最後の要素がファイル名である。

    * bash-4.4 以降では $- に s (標準入力から読み取り中) が含まれない
      事で確かめられる。bashrc を抜けてPROMPT_COMMAND を実行する時には
      s が含まれる様になる。bash-4.4 未満では s は決して含まれない事に
      注意する。

    まとめると以下の様な関数で rcfile 中で走っているかどうかを判定できるのではないか。

    function ble/util/is-running-in-rcfile {
      [[ $- == *i* && ( _ble_bash -lt 40400 || $- != *s* ) ]] || return 1
      local nstack=${#BASH_LINENO}
      [[ ${BASH_LINENO[nstack-1]} == 0 && ${FUNCNAME[nstack-1]} == source ]]
    }


*******************************************************************************
    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 と同じ様である。

    https://github.com/jamesob/desk ... これも似たような事を実装しているが、恐
    らく予め設定した内容だけでなく現在のディレクトリやコマンド履歴などの動的な
    情報も「セッション」として記録している気がする。然しここまで来ると screen
    で良いのではないかという気がしてくる。

2021-12-31

  * "function f {}" vs "f() {}" [#M0022]

    function f は元々は ksh functions で、POSIX functions f() とは局所変数の取
    り扱いが異なる。ksh では f() の形式の関数では局所変数を定義できない。ksh
    functions ではその関数で宣言したローカル変数またはグローバル変数しか見えな
    い。この背景から function f() という両方を組み合わせた形で書くと鬼の首を撮っ
    たかの様に指摘してくる人がいる (Greg Wooledge だったか)。

    f() の形式の場合には f の部分は alias 展開の対象である。例えば alias
    die=std::die 等として名前空間を import している時に、関数を上書きしたい時に
    それが alias されているという事を意識せずに直接 die() { ... } 等として上書
    きする事ができる。

    function ... の場合には、f() の形式では定義できない、特別な文字を含んだ関数
    も定義する事ができる。POSIXLY_CORRECT の時には結局どちらの形式を使ったとし
    ても、識別子以外の名前で関数を定義する事はできないのであるが。

    Bash 5.0 以前では function hello の直後にはサブシェル () を本体とした定義は
    置けない。文法的にはこれが当たり前の様な気もするが、Bash 5.1 以降では直後に
    サブシェルを置ける様である。例えば function f(echo) など。

2021-05-16

  * Linux パッケージのチェック (by killermoehre) [#M0021]
    どの Linux にどのパッケージのどの version が入っているかを調べられるサイト
    https://pkgs.org/search/?q=groff

2021-05-15

  * PKGBUILD の説明は此処にある [#M0020]
    https://wiki.archlinux.org/title/VCS_package_guidelines
    https://wiki.archlinux.jp/index.php/PKGBUILD
    https://wiki.archlinux.jp/index.php/%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%81%AE%E4%BD%9C%E6%88%90#.E9.96.A2.E6.95.B0_pkgver.28.29

2021-05-03

  * awk の互換性に関する注意点 [#M0019]

    * 正規表現 {m,n} は gawk-4 以降でしか既定で使えない。gawk-3 も nawk も mawk
      も駄目。

      POSIXに反しているが過去の互換性の為という事らしく gawk-3 では
      POSIXLY_CORRECT またはオプション --posix または --re-interval を指定すれ
      ば利用できる様になるが、nawk/mawk はそういうオプションすらない。

    * 正規表現 A?A? は mawk では最初の A? しか一致しない。

      これは明らかにバグの気がするがどうなのだろうか。

    * 16進リテラル 0xHHHH は gawk でしか使えない。

2021-05-01

  * ble.sh 初期化時の Bash 設定に対する対策 [#M0018]

    ble.sh が set -euxv -o posix や FUNCNEST=0 等特殊な状況で呼び出される事がある。
    この様な環境ではまともに動作する事ができないので設定を適切な順序で解除してい
    く必要がある。

    set -eu に関しては適切な記述方法を取れば回避する事ができるので後回しにする。
    set -xv に関しても標準エラー出力を適当な物に繋いで置けば回避できる。set -o
    posix が設定されていると関数を定義できない。その他の振る舞いにも注意が必要だ
    ろう。alias も何が定義されているか分からないので出来るだけ expand_aliases を
    off にする方向で考えたい。

    現在の実装では以下の順にチェック・対策を行っている。

    1 最初の引数解析 (POSIX shell 準拠): この部分は別のシェルで起動した場合などで
      も引数解析の結果などを表示する為に対策よりも前に処理する。alias で { や if
      が書き換えられている事によって失敗しても、シェルが全く操作できなくなるとい
      う事はないだろうし、ユーザー側の責任とする。

    2 Bash のバージョンチェック。これをしないとそもそも対策コード自体動くか怪しく
      なってくるので先にチェックする必要がある。これもシェルが全く操作できなくな
      るという事はないだろうという事で、ユーザー側の責任とする。

    3 expand_aliases
    4 FUNCNEST
    5 set +o posix

      この三つを設定すれば取り敢えず安全に関数を定義して実行できる。

    6 reset-builtins

      builtin が上書きされてしまうのを防ぐ為。

    7 adjust-options (set +euxv; shopt -u nocaseglob; shopt -u expand_aliases)

2020-05-11

  * Bash の HISTTIMEFORMAT 振る舞いのまとめ [#M0017]

    ref #D1351

    * Bash は、HISTTIMEFORMAT の値に関係なく、コマンドの時刻を常に内部
      的に管理している (#0x10 の件を考えると文字列で記録している疑いが
      ある)。HISTTIMEFORMAT が設定されている時、history コマンドで出力
      されるコマンド履歴に時刻が出力される。

    * 変数 HISTTIMEFORMAT が存在する時 (空文字列や unset も含む)、Bash
      は履歴ファイルに #%s の形式で時刻を保存する。

    * 履歴ファイルからコマンドを読み取る時、直前に #%s があればそれを
      コマンドの時刻とする。それ以外の時はコマンドの時刻は bash の起動
      時刻とする。これは HISTTIMEFORMAT の状態に関係ない。

      履歴ファイルから読み取る時には単一行モードと複数行モードがある様
      だ。変数 HISTTIMEFORAMAT が存在 (空文字列や unset も含む) してか
      つファイルの先頭行が #%s の時に複数行モードになる。

      時刻行は "#数字" で始まっているかどうかで判定する。先頭または #
      と数字の間に余分な空白が含まれている場合は時刻行ではない。"#整数
      " の後に別の文字列があったとしてもそれは無視される。但し、"#0"
      で始まっている時だけは行全体を時刻と見做すようで、余分な文字列が
      あると history で出力する際にエラーになる。

    * history コマンドの出力は HISTTIMEFORMAT が非空文字列の時にタイム
      スタンプが出力される。

      HISTTIMEFORMAT が設定されていても空文字列の時には処理は行われな
      い。これは通常の見た目の振る舞いでは区別がつかない (処理していて
      も処理していなくても出力に違いは出ない) が、履歴ファイルに #0xxx
      の様な無効なタイムスタンプが含まれていた時の振る舞いで分かる。

    * shopt -s lithist は、for 等の文法的に複数行に跨るコマンドについ
      て、そのままの形でコマンド履歴に登録する。単にコマンドラインで複
      数行を入力して実行しても改行で分割してコマンド履歴に登録される。

      これはコマンドを実行した時に Bash プロセスの内部のコマンド履歴に
      登録する際に影響を与える物であって、履歴ファイルへの書出しや履歴
      ファイルからの読み出しには影響を与えない様である。

    現在の ble.sh サポートの制限について。

    * mlfix: bash-4.4 以降では複数行コマンドを history -r で読み出せるが、
      bash-4.3 以前では複数行コマンドは history -s で構築せざるを得ない。
      従って複数行コマンドに関しては正しくコマンド時刻を復元できない。

2020-05-06

  * trap: DEBUG/RETURN trap のまとめ [#M0016]

    DEBUG trap は設置した関数内で有効。set -o functrace (set -T) が設
    置されている時または呼び出される関数に declare -tf を設定している
    時にのみ呼び出される関数に継承される。trap -p の出力は現在処理して
    いる関数毎に異なる (継承しない場合は DEBUG/RETURN trap に対しては
    何も出力されない)。

    DEBUG: bash-4.3 以下では設置した関数の呼び出し元には影響はないが、
    bash-4.4 以降では呼び出し元の DEBUG trap も上書きする。DEBUG trap
    を削除した場合には、呼び出し元には影響は与えない。DEBUG trap の中
    では DEBUG trap は発火しない。

    RETURN:

    * BASH_COMMAND には最後に関数内で実行したコマンドが入っている。
      return を使った場合にはそれが、関数の末端で終わった場合には最後
      のコマンドが入っている。
    * RETURN trap は関数内部で実行されるので、return を呼び出して終了
      ステータスを変更する事ができる。但し、条件をつけないと、RETURN
      trap の return に対して再び RETURN trap が発火して無限ループにな
      るので注意する。
    * RETURN trap の中では RETURN trap は発火しない。それ以外の trap
      では発火する。

    BASH_LINENO, BASH_SOURCE, FUNCNAME についてはまだ詳しく調べていない。

2020-04-14

  * ${###} 等のパラメータ展開・変数展開について [#M0015]

    Bash のパラメータ展開 #D1330

    <param>

    - 位置パラメータ: 1 2 ...
    - 特殊パラメータ: * @ # ? - $ ! 0 _
    - 変数名: /_[[:alpha:]][[:alnum:]]*/ の形式
    - 配列名[添字]
      添字はシェル展開の対象で配列の時は算術式の対象
    - 配列名[@], 配列名[*]

    <modifier>

    - @A 変数の定義
    - @a 変数の属性
    - @Q @E @P 値を加工する
      これらの ops は展開の対象ではない。つまりvar=A として ${xxx@$var} とはできない。
    - #, ##, %, %%
    - /, //, /#, /% (クォートとの兼ね合い)
    - ^ ^^ , ,, ~ ~~
      Note: ~ については https://qiita.com/t_nakayama0714/items/80b4c94de43643f4be51 に書いてあった。
    - = + - ? := :+ :- :?
    - :offset, :offset:length

    * $<param>
      Note: 配列, 2桁以上の位置パラメータは使えない。

    * ${...} の例外規則

      * ${#<param>}
        ${#@}, ${#*}, ${#a[@]}, ${#a[*]} は要素の数。
        それ以外については文字の数。

      * ${!var@} ${!var*}

      * ${!arr[@]} ${!var[*]}

    * ${<param><modifier>}
    * ${!<param><modifier>}

      * ! で始まる物については ${<param>} を変数名とする。

        Note: <param> は !, $ 以外でなければならない様だ。

        $@ $* ${arr[@]} ${arr[*]} の時には "$*" などを変数名と見做す。
        つまり、普通に ${!arr[*]##} 等とすると要素が1個の時以外はエラーになる。
        (arr=(a b c); IFS=; abc=4321; echo "${!arr[*]##}") 等とすると動く。
        (arr=(a b c); IFS=; abc=4321; echo "${!arr[@]##}") は動かない。

    ★${!#} で最後の引数を取れる。${@:$#} でも行ける。
      但し、引数がない場合は $0 に展開される事に注意する。

2020-04-07

  * bashrc に於ける history の操作について [#M0014]
    初回の history -nrs の実行時に "未初期化" であれば初期化を行う。
    "未初期化" の判定は履歴がその時に空であるかどうかによる。

    * "未初期化" の時に history -awcd を呼び出した時は何も実行しない。
    * "未初期化" の時に history -nrs を呼び出した時は、
      履歴ファイル (HISTFILE) を読み取って初期化した後に要求された操作を実行する。
      これは bash の動作とは異なる。bash は履歴ファイルを読まずに操作を実行する。
      その後で何らかの条件で履歴ファイルの読み取りを最初のプロンプト表示の前に行う。
    * history -p に関しては "未初期化" かどうかに関係なく、そのまま実行する。

    bashrc の中で history -r を実行すると履歴の倍加が発生する。
    但し、実行時だけで記録される履歴ファイルは倍加しない。

2019-06-10

  * history -na の動作に就いて [#M0013]

    * どのコマンド以降を新しいものとして取り扱うのか。という事について。
      特に他の Bash が bash_history に書き込んだ新しいコマンドを読み取った時、
      次に自分が history -a する時にどの範囲のコマンドを追加するのだろうかという事など。

      まとめると Bash の動作は恐らく以下の様になっている。
      先ず Bash は2つの変数を使っている。ここでは read_index と write_index と呼ぶ事にする。
      read_index は history -n で HISTFILE から次に読み出すべきコマンドの行番号を保持する。
      write_index は history -a で次に HISTFILE に書き込むべき history 内のコマンドの番号を保持する。
      Bash の起動時には read_index も write_index も同じ値に初期化される。
      history -n を実行すると read_index は HISTFILE の行数に再設定される。
      write_index は読み取った行数だけ増加する。
      history -a を実行すると write_index は history の項目数に再設定される。
      read_index は書き込んだ行数だけ増加する。

      この動作に従うと history -n; history -a や
      history -a; history -n を実行すると問題が生じる事になる。
      書き込み済みのデータ・読み取り済みのデータが混ざった時に正しく範囲を表現できない。
      この事が理由で巷にある同期の設定では history -a; history -cr を実行しているのである。

    * HISTCONTROL=erasedups
      試してみたが erasedups が設定されていたとしても history -n で新しく読み取った
      コマンドと同じ名前のコマンドを削除するとかそういう事は別にしない様である。

2019-02-13

  * keymap: 以下のキーについては既定では同じ動作になる様に設定する事にする [#M0012]
    ref #D0929, #D0752

    - DEL C-? / BS C-h
    - NUL C-@ C-SP
    - RET C-m
    - TAB C-i
    - C-_ C-DEL C-BS

2019-01-01

  * vi: inclusive/exclusive motion の実装に関して [#M0011]

    exclusive な motion は exclusive-goto.impl を呼び出す。
    inclusive な motion は inclusive-goto.impl を呼び出す。
    何れの場合も範囲を修正の後に exclustive-range.impl に委譲する。

2018-08-31

  * decode: 端末の送信するキーシーケンスについて [#M0010]

    * back (BackSpace)
      xterm は back に対して BS (C-h) を送る。
      C-back に対して DEL (C-?) を送る。
      一方で、mintty, RLogin では back に対して DEL (C-?) を送る。
      C-back に対して C-_ を送る。

    * modifyOtherKeys(2)

2018-08-05

  * compgen に指定した単語のクォート除去に関して [#M0009]

    参考: #D0714

    生成するコマンドの種類と、バージョンによってクォート除去されたりされなかったりする。
    以下に、クォート除去されることを期待してクォートしても問題がないかをまとめる。

      compgen -A command   クォート不可
      compgen -A directory クォート不可 (Bash-4.3 以降でクォート除去されない※1)
      compgen -A file      クォート不可 (Bash-4.0, 4.1 でクォート除去されない※2)
      compgen -A function  クォート可
      compgen -A variable  クォート可
      compgen -A arrayvar  クォート可

    ※1 バグと思われる。ble をロードしていると何故かクォート除去されている。
      然し、--norc や ble ロードなしで実行するとクォート除去されない。
      クォート除去が実行されなくなってしまう条件が分からないのでこれは使わない。

    ※2 バグと思われる。

2017-10-31

  * ble 関数の典型的な終了ステータスについて [#M0008]

    127 適切な widget が見つからなかった:
      (由来: Bash でコマンドが見つからなかった時の値)

    126 処理をキャンセルするとき:

      install-hook した trap に関して、blehook internal_NAME 経由で trap の発火
      をキャンセルする時に返す値。

      廃止: widget を呼び出すことができなかった (未使用)

    125 widget を呼び出したが適切な処理が見つからなかった:

      __defchar__ に登録した widget がこれを返したとき
      次のハンドラを用いる。具体的には __default__ の呼び出しを試みる。

    147 ユーザの入力を非同期に待つ為に一時停止した:

      ble/util/idle の処理に於いて条件待ち状態に入る時や、widget に於いてユーザ
      の入力を待つ為に、自発的に一時中断した時に返す値。

    148 ble/util/idle や isearch や complete に於いて、ユーザ入力を処理する為に
      一旦現在の処理を中断する時に返す値。vi-mode のオペレータが 148 を返したと
      き後処理を実行せずにそのまま抜ける (由来: 128+SIGTSTP)

    124 プログラム補完において補完の再実行を要求する
      (由来: これは Bash の仕様に倣った)

    27 widget の動作がユーザによってキャンセルされた (由来: ESC = 27)

    6 ble-update で更新の必要がなかった時に内部的に使用 (由来: ACK = 6)

    2 コマンドの使い方が異なる

    3 ble/util/bgproc は named pipes がシステムでサポートされていない時に 3 を返す。

2017-10-18

  * ble-decode: widget に関して [#M0007]

    __defchar__ および __default__ に登録された widget が 125 を返した時、
    その入力に対する適切な処理が見つからなかったことを表します。
    この時、次のハンドラの探索が行われます。
    次のハンドラがない場合には対応するものが見つからなかったというエラーになります。

2017-09-24

  * vi-mode 以下は現在のところ対応しない予定である [#M0006]

    * 2017-09-24 vi-mode: % で用いる matchpairs には現在対応しない

    * 2017-09-17 vi-mode (insert mode/newline):
      インデントを挿入するが何もしなかった時にそれを削除することには対応していない。

      これは実際の所、挿入モードにおける移動と抜ける時の処理において、
      細工を行えば対応できる。現在の挿入モードの操作の繰り返しの記録の仕組みも使えるが、
      もっと別の仕組みを用意しても良い気がする。

    * 2017-09-12 vi-mode: タブ文字上にカーソルがある時のカーソルの表示位置

      後、気付いたことはタブ文字に居る時のカーソル位置は、
      ノーマルモードにいるときはタブ文字の最後の位置である。
      要するに p で挿入される位置を示しているとも言える。
      でも全角文字の場合にはちゃんと全角文字の先頭にカーソルが来る。
      この動作は分かりにくいし更に言うと現状の ble.sh の描画コードでは対応していない。
      これには取り敢えず対応しないことにする。

    以下は積極的に対応する予定はない。
    将来的に対応する場合の注意点がある場合も含む。

    * 2017-10-11 M ( ) [[ ]] { } :s :tag
      これらのコマンドは "ジャンプ" なので、$flag なしで実際にジャンプに成功する場合には
      set-local-mark 96 をする必要がある。

    * done: 2017-10-09 取り敢えず今の所はスクロール (C-b C-d C-e C-u C-y など) には対応しない
      →これは #D0886 で対応した。

2017-09-08

  * vi-mode: 以下のリンクで重要そうなコマンドの一覧が見られる [#M0005]

    http://qiita.com/sfuta/items/0de4ead865c15e9e9b68 ?
    http://qiita.com/sfuta/items/2d646396a6117c8e53e5 g? z?
    http://qiita.com/sfuta/items/fd78f3ece8861f8142ee C-w? [? ]?
    http://vim-jp.org/vimdoc-ja/vimindex.html
    http://vim-jp.org/vimdoc-en/vimindex.html

2015-11-28

  * デモ画像の作り方 [#M0004]

    * ble-0.2 のデモ画像はキャプチャソフトを使った (ref #D0926)

      - Cygwin の mintty を用いた。
        画面の幅は56列にし文字の大きさは14程度が良い。
      - キャプチャソフトには LICEcap というソフトウェアを使った。
      - キー入力を表示するソフトには KeyCastOW を改造した物を用いた
        https://github.com/akinomyoga/KeyCastOW

      ble-0.1 の時に行った基本的な操作に加えて、
      ble をダウンロード・展開して試してみるところも含めた。

    * ble-0.1 のデモ画像は ttyrec & seq2gif を用いて作成した

      準備
      $ # PS1=$'[\e[4;38;5;202mfoo@bar\e[m \\j \\W]\\$ '
      $ TTYREC=1
      $ ttyrec demo.tty

      echo hello, world
      printf hello
      [[ a == b ]]
      echo "hello $(echo bash $(echo world))"
      C-r for
      echo 'select, copy and paste' コピーする
      echo insert mode -> overwrite mode
      ls
      echo complete ble-TABdTAB histexpand !#:2
      echo "$HIST[TAB]"

      $ seq2gif -f 0 -b 15 -h 14 --render-interval=10 -p rosa --play-speed=1.5 < demo.tty > demo2.gif

      gif のフォーマット的には 0.01s よりも小さな遅延は設定できない。
      また、現実のブラウザでは 0.02s (50fps) よりも小さな遅延にすると強制的に 0.10 になってしまう。
      更に、Safari や Internet Explorer では 0.06 (16.67fps) よりも小さな遅延は 0.10 になってしまう。
      更に、Windows に附属している viewer では 0.10 よりも小さな遅延は全部 0.10 になってしまう。

      [[Frame Delay Times for Animated GIFs by humpy77 on DeviantArt>http://humpy77.deviantart.com/journal/Frame-Delay-Times-for-Animated-GIFs-214150546]]
      [[How to match animation rate of gif files accross browsers (Fenrir Developer's Blog)>http://blog.fenrir-inc.com/us/2012/02/theyre-different-how-to-match-the-animation-rate-of-gif-files-accross-browsers.html]]
      [[Nullsleep | Jeremiah Johnson - Animated GIF Minimum Frame Delay Browser Compatibility Study>http://nullsleep.tumblr.com/post/16524517190/animated-gif-minimum-frame-delay-browser]]


2015-08-14

  * [memo] builtin check [#M0003]

    eval "grc --color --exclude=./test '\b(builtin[[:space:]]+)?$command\b' | grep -Ev '\bbuiltin[[:space:]]+$command\b'"

  * [memo] leak variables check [#M0002]

    ble/debug/leakvar#list を実行する。

    ble/debug/leakvar#reset var
    ...
    ble/debug/leakvar#check var tag1
    ...
    ble/debug/leakvar#check var tag2

  * [memo] 解析(ble-syntax/parse)の際の原則 [#M0001]

    データ配列とは _ble_syntax_stat, _ble_syntax_nest, _ble_syntax_tree を指すとする。
    或る点 p1 から或る点 p2 に解析を進める場合を考える。

    1 この時データ配列に対する変更は p1-p2 (exclusive) の間にだけ行われる。
      これは解析状態の復元と再開が適切に動作する為に必要である。

    2 解析の過程でデータ配列に格納されている情報は使用しない。
      これは解析状態の一致チェックの為に必要である。
      データ配列の内容に依存して動作が代わる場合、
      解析状態が一致しても解析結果が異なってしまう可能性があり、不整合を生む。

      但し、_ble_syntax_nest については専用の関数を通して 0-p2 の任意の場所を参照しうる。
      これ(専用の関数を通して得られる情報)については
      解析状態の一致チェックの対象に含まれているからである。
      (_ble_syntax_nest の任意の情報を参照して良いという意味ではない。)

    tree-append および nest-pop に対する制限

      tree-append は _ble_syntax_tree[i-1] に格納を行う。
      従って上記の条件1から p1<=i-1 つまり p1+1 <= i である必要がある。
      これは少なくとも 1 文字 i を進めてからでないと tree-append を呼び出せないという事である。
      nest-pop も内部的にそのまま tree-append を呼び出しているので同じ制限がある。


*******************************************************************************
    bug-bash, third-party bugs & reviews
-------------------------------------------------------------------------------

2023-02-20

  * review: completion 自動生成

    argument-parser と一緒に completion を自動生成する試みがある。

    - spf13/cobra や rsteube/carapace 等の仕組み。

    - https://github.com/adoyle-h/bash-completor

    - ble.sh でも最初期に getopts interface を実装して、これだけで引数パーサー
      と同時にそれと consistent なコマンド依存単語着色を実装しようと試みた。結
      局、これは argument parsing 速度が遅いという事で放棄されて
      archive/getopt1.sh に眠っているが、直接実行するのではなくて、事前に関数を
      生成して置くという方式にすればそれは気にしなくても良いのかもしれない (但
      しその分だけ footprint が大きくなる)。実のところ ble-face だとか ble-bind
      の様に初期化時に大量に呼び出される物でなければ、別に其処まで速度を気にす
      る必要はない気もする。

    - 最近もシェルで getopts と同時にヘルプ等も自動的に生成しようという試みがあ
      る。これである。

      https://github.com/ko1nksm/getoptions

    - 他にも類似の物が定期的に github 上に現れる気がするが忘れた。

    ble.sh 的には以下の物を同時に全てしてくれるととても良い。

    - 引数解析器
    - 引数補完候補生成
    - 単語着色
    - 引数指定方法のエラーの検知、診断情報の取得、修正候補の生成

    一般的な枠組みとしては更に以下の様な物もあると便利なのだろう

    - ヘルプ自動生成
    - 引数に関する単体テストの自動生成 (特殊ファイル名、巨大数、etc.) →でも正
      しく動作しているかどうかの判定は別で書かなければならないのでは?


2023-02-14

  * bug-bash: bash-5.2 で -u extquote しても ${var//[$'\n']} が改行を削除する。

2023-02-06

  * bug-bash: 実は colored-stats は本来 LS_COLORS を反映するらしい。然し、
    readline 初期化前に設定されている必要がある。colored-stats も bind 等ではな
    くて inputrc 経由で有効にしなければならない様だ。

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' のバグに引っ掛かった。
    これはやはり直して貰いたい。

2022-02-15

  * tmpenv builtin eval vs DEBUG trap
    Ref #D1772

    function print { echo "v=${v:-(not found)}"; }
    function trapdebug { echo "$FUNCNAME:1:v=($v)"; }
    builtin trap 'trapdebug' DEBUG
    v=xxxx eval print
    v=xxxx builtin eval print

    以上に於いて builtin eval print で実行される print に対する DEBUG trap の中
    から v=xxxx が見えない。eval print の時にはちゃんと見えているので意図的な振
    る舞いとも思われない。

2022-01-23

  * wezterm, bash-preexec に対する patch を終結させる。

    * bash-preexec に API 安定化のお願いをする → これは PR を出したが返事がない。
      時々活動はあるみたいなので少しでも反応があった時に改めてお願いする事にする。

  * bash-preexec は既存の DEBUG trap を正しく実行できていない様に思われる

    $ trap 'echo XXX' DEBUG
    $ echo 1; echo 2; echo 3
    XXX
    1
    XXX
    2
    XXX
    3
    $ source bash-preexec.sh
    XXX
    XXX
    XXX
    $ echo 1; echo 2; echo 3
    XXX
    1
    2
    3

    これは意図的な物なのだろうか。。と思ったら以下に議論がある。

    https://github.com/rcaloras/bash-preexec/issues/52
    https://github.com/rcaloras/bash-preexec/pull/54
    https://github.com/rcaloras/bash-preexec/pull/109

    o ユーザーが trap DEBUG etc を実行しても破壊されない。
    o DEBUG trap の overhead がない。
    o 他の枠組みが DEBUG trap を設定・削除しても問題が起こらない。

2021-12-11

  * bash-completion

    2022-02-02

    * [DraftPR で修正済み] _services が failglob で問題を起こしている。

      _comp_init_set_up_service_completions も駄目。うーん。failglob ではある
      がこれは自分が修正している途中の物ではない新しい物だろうか? →これは既に
      fix-failglob　の中に含まれていた。

    * [修正済み] rsync で *-from が云々という failglob が発生している
      →これは最新版では既に修正されている。

      結局ロードして欲しい bash-completion が全然ロードされない。何故 → 結局ロー
      カルの場所ではなくて其処で make install されている物が読み出されている様だ
      が、make install しても何故かずっと古いままという状態になっている様だった。
      autoreconf -i をし直して実行したらちゃんと新しい物に置き換えられた。make 自
      体がちゃんと動いていなかったという事になるのだろうか。何れにしてもこれでちゃ
      んと動く様になった。

    2022-01-23

    683 にも unresolved patch suggestion がある。
    https://github.com/scop/bash-completion/pull/687#discussion_r790203991 : IFS=$'\0' in mount
    https://github.com/scop/bash-completion/pull/687#discussion_r790203132 : mechanism of save/restore shopt

    2022-01-11

    * bash-completion: curl　の抽出オプションが極端に少ないのは何故か→これは
      curl --help は最低限のオプションしか表示しないから。そして --help all を
      呼び出せば全部表示される。確認すると --help all は指定されているが、quote
      されていない。

      類似の問題が過去にあったがその時に一緒に直されなかったのかと思ったが、こ
      れが正にその時の問題であって、test などが用意されていなかった為に未だマー
      ジされていないのだった。

      https://github.com/scop/bash-completion/pull/560

    2021-12-22

    * fixed: man の中で _expand を呼び出しているが意味ないのでは? info も同様。

    * man の _expand の直後にある eval は危ない気がする。
      →これは別項目で議論する。

      info にも同様の問題が存在する。

    * grc '&& [^[:space:]]+ \|\|'
      →何故 SC2015 で検出されないのだろうか? 変数代入の場合には許されるのだろうか。

    * command ls $... となっている部分が幾つかある。 -- を付加するべき。
      他にも色々とあるのではないかと思われる。

    2021-12-11

    * curl --http0, --http1, --proxy1 等存在しないオプションが生成されている
    * printf -v varname
    * test, [ の引数の文法に従った補完

2021-12-08

  * space

    https://space.sh/
    https://github.com/space-sh/space (7k LoC)
    https://github.com/space-sh/space/blob/master/completion/init_autocompletion.sh

  * bashible というフレームワークでは関数名は ble_ で始まる様だ。

  * bash-dev: "help test" の -n の引数に STRING が二回登場している。

    →と思ったが、これは分かった。 [[ -n STRING ]] と [[ STRING ]] の二種類の指定の仕方を
    両方載せているというだけの話である。

2021-09-22

  * bash-it で気になる事

    * bash-it disable alias を実行すると何も表示されず何も実行されない。
    * bash-it --help もしくは bash-it で色々表示されるが、明らかに表示されてい
      ないコマンドが存在している。
    * bash-it update に外部から登録できる機能?
    * bash-it に自動でインストールする機能もつける可能性について

  * bash-5.2

    $ i=0; b=$(< "file${a[i++]}"); echo "$i"
    1

    $ f=; b=$(< "${f:=file}"); echo "$f"
    file

    $ i=0; b=$(< "file$((i=123))"); echo "$i"
    123

    $ RANDOM=0; echo "$RANDOM"
    20814
    $ RANDOM=0; b=$(< "$RANDOM"); echo "$RANDOM"
    24386

    うーん。これに関しては zsh も ksh も副作用を残す形に実装している様だ。つま
    り、$(< ...) は特別な構文として同じシェルで評価するものとしているという事。

2021-09-07

  * segv: bash-dev -c "declare -A A; unset 'A[\${v[0]}]'"

2021-09-01

  * review: bash-raytracer
    https://github.com/aneeshdurg/bash-raytracer

    固定小数点で実装している。Issue 1 で遅いから inline 化して微妙に改善したと
    いう話をしているが、その改善したコードは push されていない。

2021-08-30

  * review: bash-timestamping-sqlite
    https://github.com/csdvrx/bash-timestamping-sqlite

    - typo: synthax -> syntax

    - 行末に改行が抜けている事を示すマーカーを表示している。然しこれは CPR を使っ
      ている気がする。実装を見ると __notbottom という関数で判定していてこの関数
      では CPR を使っている。

    何れにしてもこれは他の人が組み込んで使える様な plugin ではなくて、一つの完
    結した設定になっている。コードも綺麗ではない。現段階では単に個人用の設定に
    説明がついているものと見るべきの気がする。これに対して色々と他の人が使える
    様に改善の提案をするのは違う気がする。

2021-08-19

  * st: st 2>&- で開始しようとすると何も表示されない。st 2>&- 0>&- で開始しよう
    とした場合にはちゃんと動く。これは以下の様に修正するべき。後で送る。

    $ NOBLE=1 ./st.master 0>&- 1>&- 2>&-
    $ ./st.master 0>&- 1>&- 2>&-

    | diff --git a/st.c b/st.c
    | index ebdf360..a9338e1 100644
    | --- a/st.c
    | +++ b/st.c
    | @@ -793,14 +793,15 @@ ttynew(const char *line, char *cmd, const char *out, char **args)
    |                 break;
    |         case 0:
    |                 close(iofd);
    | +               close(m);
    |                 setsid(); /* create a new process group */
    |                 dup2(s, 0);
    |                 dup2(s, 1);
    |                 dup2(s, 2);
    |                 if (ioctl(s, TIOCSCTTY, NULL) < 0)
    |                         die("ioctl TIOCSCTTY failed: %s\n", strerror(errno));
    | -               close(s);
    | -               close(m);
    | +               if (s > 2)
    | +                       close(s);
    |  #ifdef __OpenBSD__
    |                 if (pledge("stdio getpw proc exec", NULL) == -1)
    |                         die("pledge\n");

    メールを投稿してみたが全然以下のページに反映されない。
    ブロックされているのだろうか。或いは初回は手動承認が必要になるという事か。
    maintainer は数日に一回しか返信しない様なので取り敢えず一週間待ってみようと思う。

    https://lists.suckless.org/hackers/2108/index.html

2021-07-20

  * bashbug: ${text//$'\n'+( )/$'\n'} が滅茶苦茶遅い
    https://www.reddit.com/r/bash/comments/m4ts7j/why_is_this_spacereplacing_parameter_expansion/

    この記事では bash はそういう用途に使う物ではないだの何だのと言って別の手法
    を使えと書いているが、明らかにこれは bash のバグである。修正するべきだし修
    正は難しくない筈である。後で観察する事にする。

2021-06-09

  * complete: contra x screen-4.99 で auto-menu を有効にしていると、

    $ cd .mwg/src/ble.sh/wiki
    $ l backup/[TAB][C-u]

    とした以降にコマンド1文字目を入力した時点で glitch が生じる。
    contra がどういうデータを受信しているのか確認する必要がある。

    通常の screen では問題は生じない様だ。また contra の代わりに mintty を使っ
    ても問題は生じない。変な文字幅モードが関係している可能性もある。

2021-05-30

  * https://github.com/dnmfarrell/jp
    https://www.reddit.com/r/bash/comments/nmzans/jp_a_real_json_processor_in_bash

    何か変な事をしている。プロセス置換で読みだした fd に対して読み書きを実行している。
    一体どういう事だろうか…。

    $ exec 3< <(:)
    $ echo hello >&3 # これはエラーになる
    $ echo hello >/dev/fd/3 # これは行ける
    $ read -u 3
    $ echo $REPLY # 読める
    $ yes | head -1000000 > /dev/fd/3 # これはやはりブロックする C-c で中止
    $ mapfile -t arr < /dev/fd/3
    $ echo ${#arr[@]} # 32768要素 ("y" + LF)x32768 = 64kB つまりパイプバッファのサイズ

2021-05-27

  * declare -p -A として見たら contra の状態が壊れた。何だろうか。

2021-05-23

  * bash: いつの間にかに日本語の文字幅の計算がおかしくなっている

    [現象]

    | ble/util/c2w 及び ble/util/c2w-edit の計算は正しい。新しい bash セッショ
    | ンを開始した時には何も問題は発生しない。つまり、reload を通して壊れるとい
    | う事だろうか。然しそうだとしても不思議な壊れ方である。
    |
    | 何かが変わってしまっているという事なのだろうと思うが新しい bash セッション
    | で発生しない様なので取り敢えずこれの解決は後回しにする事にする。
    |
    | うーん。textmap が可笑しくなっている気がする。
    |
    | と思ったら ble/util/s2c で日に対して 230 が返って来ている。何故だろうか。
    | 実装を確認すると単に printf %d "'日" を実行しているだけである。実際に
    | builtin printf の出力結果がおかしくなっている事を確認した。うーん。不思議
    | な事である。

    builtin printf %d "'あ" が正しい値を返さなくなっている。一文字目の文字コー
    ドを返している。実装を見ると mbtowc を呼び出している。失敗したら一文字目の
    コードを返す実装になっている。これにより ble/util/s2c が誤った文字コードを
    返し、そして文字幅計算が間違って textmap に間違いが入る。というのが表示が乱
    れる原因であった。

    [再現条件?]

    a 新しい bash で ble-reload をしても特に問題は発生しない。

    b 一度でも LANG を C 辺りに変更すると問題が発生する様になる可能性? 特に再現
      はしない。LANG を元に戻せば元通りになる。また、問題の発生しているセッショ
      ンで LANG=C して LANG=ja_JP.UTF-8 にして見ても問題は治らない。

    ? 或いは設定が異なるのか。bind -v の結果を比較しても shopt の結果
      を比較しても $SHELLOPTS:$BASHOPTS の結果を比較しても同じである。dotglob,
      nullglob の設定の違いはあったがこれを解除しても振る舞いは変わらなかった。

    ? 或いは LANG 辺りを unset した痕跡があるだろうか。コマンド履歴を探したが
      unset でも LC でも LANG でも怪しい物は見つからない。実際に unset するなど
      しても特に問題は発生しない。

    ? よく分からないので bash を見に行くと builtins/printf.def で mbtowc を呼び
      出して文字を一文字抽出している。この mbtowc の文字コードの設定ができなく
      なっているのが問題なのだろう。うーん。やはり setlocale の問題の気がする。

    ? うーん。不思議である ble-detach しても状況は変わらない。然し何故か
      readline の文字幅判定等はちゃんと正しく動作している様である。printf
      \u3042 等もちゃんと動いている。

    ? うーん。実際にこのセッションで実行したコマンドの一覧を作って観察して見た
      が特に問題がある様には思われない。特に locale を破壊する様な事が起こると
      は思えない。怪しい物に setsid があるがこれで全てのシェルが駄目になるとい
      う事があるのだろうか。うーん。特に問題は発生しない。

    もう全然分からないので exec bash してみる事にする→exec bash したら治った。
    結局どういう事だったのか分からず終いである。結局不明である。C標準ライブラリ
    か Linux のバグなのだろうか。

2021-05-21

  * bash: fix a problem that "set -e; builtin eval false || true" exits the shell
    false || true # OK
    eval false || true # OK
    builtin false || true # OK
    builtine eval false || true # 駄目

2021-05-08

  * bash: Cygwin でも mapfile/read で unbuffered read に変更できないだろうか。

2021-05-06

  * bash: complete -p の -F はやはり quote するべきなのではないか。
    $var となっている場合、!! となっている場合、{1..10} となっている場合。

  * bug-bash localvar_inherit: dynamic variables の性質も継承されるのは意図的か。
    Ref #D1532

    例:

      shopt -s localvar_inherit
      local BASH_COMMAND='xxxx'
      local LINENO='xxxx'
      local RANDOM='xxxx'

    * PS1 を評価する為に BASH_COMMAND を一時的に別の物に置き換えたい。
      localvar_inherit を一時的に off にしたり或いは tempvar を通して
      BASH_COMMAND を変更する等すれば一応 BASH_COMMAND を置き換える事は可能だが
      非自明である。

    * localvar_inherit は local variable という形で初期化を行わなかった時の振る
      舞いを制御する物と思っていたが、実際には上記の様にした場合に影響が出てく
      る。つまり、localvar_inherit の下で上を実行すると set/get がコピーされた
      上で代入が行われる様で、動的変数としての性質が継承される。振る舞いが変わっ
      てしまって困る。特に代入した値が消滅してしまう。

    * また、マニュアルを見ても attr 及び value が継承されるとは書かれているが
      dynamic variable としての性質が継承されるとまでは書かれていない (?)。

      > info bash より (man bash は本質的に同じ)
      >
      >   localvar_inherit
      >
      >         If set, local variables inherit the value and attributes of a
      >         variable of the same name that exists at a previous scope before
      >         any new value is assigned.  The 'nameref' attribute is not
      >         inherited.
      >
      >   declare
      >
      >         The '-I' option causes local variables to inherit the attributes
      >         (except the 'nameref' attribute) and value of any existing variable
      >         with the same NAME at a surrounding scope.  If there is no existing
      >         variable, the local variable is initially unset.
      >
      > declare --help より
      >
      >   -I    if creating a local variable, inherit the attributes and value of a
      >         variable with the same name at a previous scope

    * 他の実装はどうだろうかと思って zsh で RANDOM, LINENO を試してみたが、
      RANDOM に関しては local にしても何も振る舞いの変化は見られず、LINENO に関
      してはそもそも代入不可能だった。そもそも zsh は local var; とすると前のス
      コープの値は保持される単に unset になる。

    * 実際にこの継承を行っているのは variables.c:2738 の以下の部分である

      variables.c L2738
      > if (localvar_inherit || (flags & MKLOC_INHERIT))
      >   {
      >     /* It doesn't make sense to inherit the nameref attribute */
      >     new_var->attributes = old_var->attributes & ~att_nameref;
      >     new_var->dynamic_value = old_var->dynamic_value;
      >     new_var->assign_func = old_var->assign_func;
      >   }

    2021-06-09 SECONDS も影響を受けるだろうか。

    より現実的な例として以下の様な場合を考える事ができる。

    evaluate_prompt() {
      local BASH_COMMAND=$(HISTTIMEFORMAT=x history 1 | sed '1s/^[[:space:]0-9]*x//')
      result=${PS1@P}
    }

    Note: 実は上記の BASH_COMMAND 抽出方法は正確ではない。複数コマンドがある場
    合、本来 BASH_COMMAND は一番最後のコマンドだけを含む。また、HISTCONTROL 等
    によって履歴にコマンドが登録されなかった場合にも結果がずれる事になる。例示
    するならば具体的に結果を無理に模倣しようとせずに、何か適当に内容を書く事に
    するのが良い気がする。例えば、

    evaluate_prompt() {
      local BASH_COMMAND='echo "Hello, world!"'
      result=${PS1@P}
    }

2021-05-04

  * empty associative array subscripts: これは結局返事がないが ToDo リストに入っ
    ているのかもしれない。或いはそうでもないのかもしれない。何れにしても、今少
    しずつ associative array subscripts の取り扱いの変更が行われているので、そ
    れらが済んでから処理されるのではないか。

  * return without arguments in trap handlers. これは結局強い理由がないと変更さ
    れない雰囲気になっている。

2020-12-19

  * bug-bash: jobs in trap handlers

    以下を実行して端末を resize すると (true) の偽ジョブ情報が出力される

      trap '(true); jobs' WINCH

    SIGWINCH に限らない。以下を実行して C-c を押しても同様の問題が発生する。

      trap '(true); jobs' INT

    実は直後の bind -x の中で jobs を実行しても同様。
    一度でもユーザーコマンドを実行すれば偽情報は消える。

      trap '(true)' INT
      bind -x '"\C-t": jobs'

    2022-07-11 以下でも同様の問題が発生した。これは PROMPT_COMMAND 実
    行中に発生する事である。
    https://github.com/petobens/trueline/pull/46#issuecomment-1179853850

2020-04-25

  * starship コマンド実行時間の計測
    preexec と precmd を使っている?
    https://github.com/starship/starship/blob/master/src/init/starship.bash

    追記 2022-02-17 これは ble.sh でも類似の物を実装した。

  * pipexec という物があるそうだ。と思ったが調べたら C で書かれている。
    https://github.com/flonatel/pipexec

  * zsh のテーマである powerlevel10k は実は結構複雑な処理を実装している。
    ごちゃごちゃとした雑多の設定の寄せ集めではない。
    ble.sh 程ではないが単にプロンプトと呼べるレベルを超えている。
    * https://github.com/romkatv/powerlevel10k
    * https://github.com/Powerlevel9k/powerlevel9k
      p9k と initial commit が同じなので再実装というよりは fork の気がする。

  * https://github.com/aristocratos/bashtop
    これは最近現れた物で pure bash で色々な UI を実装している。
    オプション引数はなく設定は直接編集する様になっている。
    背景が明るい時の配色に対応していない。256色要求。

    * 実用性よりも見た目重視。これはツールの性格による。
      ble.sh 自体は他のプログラムを呼び出す為の物なので主張は控え目。
      然し、宣伝の為には見た目を派手にした物も必要なのかもしれない。
    * 何故か現れたばかりなのに 6.3k も集まっているし、
      一体何が起こるとこのように話題になるのだろうか。不思議である。
      HN にも reddit にも大して人気になった物は見られない。
      何処から広まってどう人気になったのか不明である。
    * freebsd, aur, debian, fedora/centos にまでパッケージが在る。


@todo
*******************************************************************************
    ToDo
-------------------------------------------------------------------------------

* bump 時にする事
  - version up in README
  - Copyright year
  - Acknowledgments
  - todo 項目の整理
  - leakvars
  - version up in GNUmakefile
  - note.txt に含まれるログの移動 -> done.txt
  - keymap の移動 (これは別 commit にする?)
  - make_command.sh の整理 (scan 分離, char_width 分離)

2023-04-02

  * set -o posix で起動すると keymap が見つからないというエラーが発生する

  * history (bash 3.0): 履歴が重複して記録される

    bash-3.1 以降では問題ない様だ。つまり bash-3.0 だけで起きている問題である。
    これの優先度は低い。或いはもしかすると既知の問題である可能性?

  * prompt: 右プロンプトの範囲に合わせて textarea の横幅を途中で切り替える?
    https://github.com/akinomyoga/ble.sh/discussions/310

    これはこれまでにも考えた事があるはずだと思ったが todo 項目が見つからない。
    もしかすると頭の中で思っていただけかもしれない。

    * scroll 機能との兼ね合い → rps1 も一緒に scroll する事にすれば良い。

      少し考えてみたがどうも scroll 機能と conflict する気がする。scroll する毎
      に各行の折返を実行し直すというのは well-defined なのか。というかそもそも
      他のアプリケーションでもその様な変な形の枠の中で scroll しながら枠に合わ
      せて折返を実行し直すという実装は見た事がない。

      或いは、scroll する場合にはそれに応じて rps も一緒に scroll するという可
      能性? その様にすれば変な事は気にしなくて良い。rps1 を途中で切断しなければ
      ならないかもしれないがそれに関しては clip すれば良い気がする。

      然し長いコマンドラインを実行した後に rps1 が表示されない状態で次のプロン
      プトに行くという事にならないか。或いは長いコマンドラインの時には全体を一
      旦出力して次に進むという事にすれば良いのだろうか。新しいコマンドラインに
      移動する直前であればターミナルを溢れてしまっても問題ない筈なので。下手に
      削られて記録が消えるよりはそちらの方が自然の気がする。

      と思ったがスクロール範囲はプロンプトの最終行から始まる。なので、右プロン
      プトもプロンプトの最終行以降に被っている部分だけスクロールする事になるの
      だろうか。何だか複雑である。然し、そもそも右プロンプトもプロンプトの高さ
      で範囲を制限していて非自明な事をしているのでその程度の事は寧ろ自然の気も
      する。

2023-03-27

  * menu-complete: 長い候補を表示した後の再配置
    Ref #D2025

    これは WINCH 後の振る舞いにも関係している。WINCH があったら menu を閉じるか
    或いは再配置を行う必要がある。現在は開きっぱなしになっている気がする。或い
    は…何か変な状態になっている。info panel の高さはクリアされているけれども描
    画されていない状態? の気がする。

    本当は info に関係する winch の callback も欲しいという事。或いは panel
    height 決定で要求したのと異なる高さになった時に呼び出す hook? というか単に
    panel height change に対する hook で良い気がする。そして既にその仕組は
    onHeightChange で実装されている。現状では info#panel::onHeightChange は実装
    されていない。此処で info#panel::onHeightChange に際して現在の選択項目が範
    囲外になっていたら再描画を発生させる hook を登録できる様にする。現在表示し
    ている内容が menu なのかどうかの情報を何処に記録するのかはよく分からない。

    どうも winch を実行すると瞬間的に高さが縮む様である。その後で続きを処理しよ
    うとすると高さがまた元の高さに戻る。うーん。と思ったがそうでも無いような気
    がする。前回と同じ高さであっても onHeightChange が呼び出されている。何故だ
    ろうか。内容がクリアされてなくなってしまった場合にも呼び出されるという事と
    思って良いか。

    →うーん。どうやら潰れて見えなくなった時には onHeightChange は呼び出されな
    い様だ。その後で最初に有限の高さに戻った時に onHeightChange が呼び出される。

    然し height change を受け取ったとしてもその場で再描画する訳には行かない。既
    に描画の途中でその処理の途中に height change が起こっているかもしれないから
    である。

    a うーん。onHeightChange に於いて invalidate を設定する? でもこれだと現状で
      潰れた時に onHeightChange を呼び出していないので、潰れた事を検知できない。

    b もしくは info#panell::render に於いて高さを毎回チェックすれば良いのかもし
      れない。と思ったが、これも潰れた時に一度も呼び出されないので潰れてまた拡
      大した時に検知できないのではないか。

    取り敢えず menu-complete 中に長い行が選択されて info が縮まった後にもちゃん
    と onHeightChange は呼び出される様だ。但し、onHeightChange が呼び出された後
    に果たして render が呼び出されるのかは保証できない。上の枠組みで高さが変化
    したら render を改めて呼び出すという事を処理する様にしてしまうと今度は無限
    ループになるのではないかという懸念が生じる。

    現状の canvas panel の枠組みにおける問題点は以下の二つである。

    * onHeightChange が潰れた時に呼び出されない。潰れた時にも呼び出す様に変更し
      たいが、既存の onHeightChange の処理がどうなっているか気になる。

      更に潰れたという事が command-layout 等の都合で一時的に潰れる (後で全体を
      再描画する予定) という事なのか、それとも他の panel が大きくて潰れざるを得
      なかった (後で再描画はしない。より小さい領域に fit する様に処理する必要が
      ある可能性はある) という事なのかで振る舞いが違っても良い。

      一時的に潰れているだけなのであれば現状の様に onHeightChange は呼び出さず
      に別の種類の処理を呼び出すべきの気がする。

    * 一つの描画処理の中で既に描画し終わった panel の size change が発生した時
      に、その panel を改めて再描画する様に処理するか?

      然しそもそも描画処理の途中に高さが変わるという事があるのかというのは疑問
      である。調べてみるとどの panel も途中で reallocate-height.draw を呼び出し
      ている。そもそもこの段階で処理を再考するべきなのではないか?

      最初の処理の段階で希望の高さを提出しておいて reallocate-height を実行した
      後に各 panel の描画を開始する。各 panel は与えられた高さの中で表示する様
      にする。もし足りない場合には fallback するか collapse する (減る分には問
      題はない筈)。

    * invalidate は panel 側でも管理するべき? 但し、分からない。

2023-03-24

  * histdb: sqlite3 がクラッシュしていた。或いは timeout した物の情報が同期され
    ていなかった可能性? timeout をより短くして再現するかどうか確認する必要があ
    る。

2023-03-09

  * sabbrev: suffix alias in Zsh (拡張子で実行形式を選択)
    コマンド名補間も一緒に対応する必要がある。
    つまり suffix alias がある時には対応する拡張子を持つファイルも候補に表示する。

  * complete: 末尾に不完全な \ がある候補の specialchars フィルタリング?

    最後に中途半端な \ がある時には実はフィルターする時にも \ で quote する必要
    性のある文字が続いている物だけにするべきなのではないか。と思ったが処理的に
    複雑になるのではないか? 取り敢えず末端に中途半端な \ があるかどうかは
    comps_flags に B が含まれているかどうかで分かる。

    その上でその事実を用いて生成するファイル名を制限するかどうかというのが問題。
    然しその制限を適用する事によって候補がなくなってしまっては変な気もする。

    a 全ての候補を生成してから、生成候補を制限しても候補が残るようであれば制限
      をかける事にしようと思ったがそうしたとしても異なる種類の候補が混ざってい
      る時に不用意にフィルタできない。例えば sabbrev 候補は絞り込みの為に cand
      には quote を処理した後の値を入れている。

    b と思ったが quote の必要のない候補ばかりの時には生成候補がなくなっても良い
      気がしてきた。

    そうは言っても問題になるのが bash-completion によって生成される候補を制限す
    るかしないかという事。実際に生成している側でないとその意図は分からない。

2023-03-08

  * :name: に対して emoji 変換を実装する?

    https://www.webfx.com/tools/emoji-cheat-sheet/ に一覧がある。
    然し、emoji リストの難点は思い出すのが大変という事。リストを表示できたら良いのだが。
    例えば sabbrev -m 経由で挿入するというのが良いかもしれない。:: を使う。

  * [保留] canvas/panel: 一旦 scroll buffer に行ったものを元に戻す可能性? (motivated by mozirilla213)

    https://github.com/akinomyoga/ble.sh/discussions/288#discussioncomment-5226973
    > (And the completion words fill and cut the previous output when scrolling
    > up the terminal which I think is a known limitation which is fine,

    panel の set-height で行が消えてなくなる? うーん。然し報告者の使っているら
    しき konsole では特に内容が失われるということはない様である。ちゃんと
    scroll buffer に内容が残っている。

    恐らく scroll buffer に行って一旦画面から見えなくなるという事を言っているの
    だろう。或いは、一旦 scroll buffer に行った物を、menu が閉じた後にある程度
    回復するという事。端末によっては何かそういう様な拡張をしていた様な気がする
    のでそれを有効にする可能性はある。

2023-03-02

  * menu-complete: C-TAB を連続で押すと仮挿入をそのままに新しい補完が始まる

    menu-complete の外側の keymap で menu-complete が設定されている時には単に
    menu_complete/forward にしたりなどした方が良いのではないか。

    と思ったが menu_complete に対して引数が指定されている時などにどのように対処
    するべきかわからない。例えば insert_all や insert_brances や context=* が指
    定されている場合には単に移動するのではなくて今の補完を明示的にキャンセルし
    て新しく補完し直すべきなのではないか。然し、単なる complete や
    menu-completion や menu-complete backward 等の時には改めて開始するのではな
    くて内部での補完候補の移動を行いたい気もする。

    然しチェックするにしても全ての文字をチェックしていると大変である。と思った
    が、UTF-8 decode や key decode 等の処理の重さなどを考えたら大した事ないとい
    えば大したことない。

  * menu-complete: suffix もメニュー選択時に表示する機能?
    https://github.com/akinomyoga/ble.sh/discussions/297#discussioncomment-5159146

    然しこれは最後の確定時にならないと計算されない。メニューを選択した時にそれ
    も計算する? 然しそうするとしてもrequote だとか前方の文字列の吸収だとかその
    他の処理についてはどうするのか。

    特に前方の文字列の吸収に関しては実際に実行してしまうと元々の内容が消滅して
    しまうので駄目である。或いは前方の文字列に一致する物がある場合には単に挿入
    部分の方を短くすれば良いのかもしれないが、それはそれで着色範囲が変になって
    しまって見にくい。更に前方に完全に一致する場合には挿入文字列の幅が 0 になっ
    てしまって見えなくなる。また確定した時に何処にカーソルが移動するのかという
    のも分かりにくい。

  * wiki: Design Widget の翻訳?
    https://github.com/akinomyoga/ble.sh/discussions/272#discussioncomment-5013253
    https://github.com/akinomyoga/ble.sh/discussions/294
    https://github.com/akinomyoga/ble.sh/discussions/301

    何やら色々変な事を試そうとしている人がいるみたいなので。

2023-03-01

  * [保留] decode: M-S-o と M-O のどちらか一方でに強制的に揃える?

    現状では二つの形式に同じ binding を与える様に設定しているがわざわざ両方設定
    するのは大変である。一方で、CapsLock 等を考慮に入れると両者は実は互換ではな
    い。更に端末によって CapsLock がある時の振る舞いや、S を付加している時に
    Shift 前の文字を底字にするのか Shift 後の文字を底字にするのか振る舞いが異な
    る。なので正確に判定するのは難しい。

  * [保留] ble/builtin/readonly などの上書きを function#push で行う?

    ユーザーが独自に定義していた時などにそれを保持する為。また、ユーザーコマン
    ドを実行した直後にユーザーが上書きしていたら改めて push を行う。その時には
    既に push chain の中に登録済みであればそれを削除する等の仕組みが欲しい気が
    する (opts 引数で指定)。

    これはわざわざ表示しなくて良い気がする。

2023-02-27

  * [保留] complete: compopt -o filenames が指定された時に末尾の空白を除去する?
    bash の振る舞いを確認する。

2023-02-20

  * autoenv 実装

    既存の物と同じ設定ファイルを使い回す事を検討するべきだろうか。zsh-autoenv
    は .autoenv.zsh を使っている。これに倣うのであれば .autoenv.blesh という物
    を用意するのが便利である。

    * authorized 的なファイルの形式はどうするか。何処に記録するか。sha256sum を
      呼び出せば良い。然し、sha256sum が存在しなかった時にどうするのかや、前に
      無かったのに新しくインストールされた場合にどうするのか等が非自明である。
      取り敢えず cksum は存在すると思っておくべき? あと、前にはあったけれどもな
      くなってしまったという場合にもどうするのか困る。うーん。ファイルには hash
      の形式も一緒に記録する事にするのが良い気がする。

    * bleopt push/pop の機能を実装するべき。bleopt --push ... 等とする? 或いは
      全ての設定を一斉に push するという手もあるだろうか。或いは、bleopt 自体に
      hook して .autoenv を実行中の変更を全て track する。これが楽の気がする。

    * function については ble/function#push/pop を使ってもらう。alias は ble.sh
      側で追跡する。adjust の中で定義して大丈夫なのか? 抜ける時には特に今まであっ
      たものを敢えて削除する事はしないので一応使える? 然し、以前の alias が退避
      されていた場合にそれが restore される時に上書きされて昔の物に戻ってしまう
      という事が起こるのでは。という事を考えると alias に関しては adjust を一旦
      restore しておく必要があるのではないか。他にも FUNCNAME 等が気になる。

2023-02-12

  * syntax: 5.0 以降では関数名として function `xxx` 等も実は許されている。5.3
    以降では更に <(...) も関数名として使える。しかもこれらは `xxx`() や
    <(...)() の形式でも定義できる。

    現在の実装では関数名を function NAME まで一回の解析で進むようにしている。何
    故だったか。何か理由があった気がするが、この取扱になっている限りはちゃんと
    対応するのは難しい。過去の記録を調べる必要がある。

  * complete: shopt -s extglob failglob で @(aa)() { echo; } という関数を作成し
    て置くと screen -dr の補完の途中でエラーメッセージが表示される。何処から表
    示されているのだろうか? 関数名を拾って更にその上でそれをパス名展開に晒して
    いる箇所があるのだろうか? simple-word ではないので ble.sh の内部ではないの
    ではないか…という気がするが分からない。

2023-02-06

  * auto-complete: cd 等簡単に成否が分かる物については判定して除外する可能性

    然し cd を上書きしている場合等にはやはり問題になる。またコマンド毎に対応す
    るのは大変なのでこれも progcomp, chroma の様に判定するシェル関数を用意する
    可能性。ただ、問題なのは、単純コマンドでない時にコマンドの位置などの判定を
    行う必要があるという事。そしてその為には構文解析を各項目に対して回す必要が
    ある。という事を考えると重くて現実的でない気がする。

2023-02-03

  * contrib: ble-import で contrib/ は不要なのではないか?

2023-01-26

  * histdb: history の中から情報を取り出してそれを使って何かする機能

    これができなければそもそも実装する意味がない。例えば auto-complete で単語を
    表示する等。

    * done: wiki: BLE_SESSION_ID, BLE_COMMAND_ID

    * 履歴を操作・編集(削除)する機能も欲しい。

      histdb [list]                 コマンド一覧
      histdb list-session [options] セッション一覧
      histdb delete [OPTIONS]       コマンド削除
      histdb -s [.|session]         セッション指定
      histdb -d [.|dir]             ディレクトリ指定
      histdb -t [.|dir]             ディレクトリ指定(サブディレクトリも含める)
      histdb -g glob                コマンドをパターンで絞り込み
      histdb -c command_id          コマンドIDによる指定

2023-01-25

  * complete: 英単語の曖昧補間やスペルミスの検出など

    この場合には一意確定だとしても挿入はしない方が良い。コマンド引数
    (source:argument) についてその他の候補生成が全て生成に失敗した時にこれを実
    行するのが良い気がする。そしてその場合には勝手に挿入しない事を表す flag か
    何かを設定する事にすれば良い。

    英単語辞書は bash で処理すると遅いので awk か或いは外部コマンドを呼び出すべ
    き。或いはこれまでに実行したコマンドから拾ってくる? これまでに実行したコマ
    ンドに関しては変な切り取り方をしても仕方がないので、

    a 予めコマンド実行時の文法解析結果を元に単語を抽出してファイルに記録してお
      く。これは comps との一致対象。記録は state ディレクトリの中にファイルを
      作成すれば良い。~/.local/state/blesh/history.xword.txt 等。

    b 同様に単語がファイル名に一致する場合にはそのファイル名を記録する
      (history.filename)。現在ディレクトリとの組にして記録するとより良いかもし
      れない。これは compv に対して一致を試みる。

      x 現在ディレクトリとの組にするのだとしたら結局現在ディレクトリで普通にファ
        イル名補完をするので十分なのではないか。逆にディレクトリに関係なくファ
        イル名を記録するとしても何か用途はあるだろうか。結局単語補完と実質同じ
        なのではないか。

    c 更に、simple-word の時には展開結果を記録する (history.vword.txt)?

      x 展開結果が長大になる可能性がある。

    d 更に c をスペース等で分割して単語を記録する (history.eword.txt)?  然しこ
      れも変な物を記録しても仕方がないので bash special chars に関しては含めな
      い様にする。もしくはそれらも分割子として取り扱う。これも compv に対して一
      致を試みる (特にスペース等で分割した後の直近の文字列に対して判定する)。

    history に関しては ToDo 2021-05-17 に関連項目がある。

2022-12-09

  * edit,complete: alias expansion で alias sudo='sudo ' 等による引数の展開に対応?

2022-12-03

  * declare -f の出力は特殊関数名には使えないのではないか?
    https://lists.gnu.org/archive/html/bug-bash/2022-12/msg00010.html
    https://lists.gnu.org/archive/html/bug-bash/2022-12/msg00011.html

    取り敢えず、これは evaldef の時点で function を prefix すれば良い気がする。
    今後の Bash の振る舞いの変更で function が追加されるかもしれないので、その
    時にはそれを避ける様にする。

    更に変数代入の形の関数名は declare -f &>/dev/null でテストする事もできない。

  * colorglass: face から読み取る時に作用する色設定?

    現在は全ての出力に対して色を変更しているが、プロンプトのテーマを別に指定し
    ている場合などを考えると、プロンプトの色には作用して欲しくない気がする。一
    方で元々の colorglass のアイディアでは全ての色に対して作用する事を考えてい
    た。両方の種類のオプションを提供するという手が考えられる。例えば、現在のオ
    プションはそのままにして、colorglass_face_* という物も提供する。

    インターフェイスは別として実装は考える必要がある。

    a 現在は face は全くキャッシュしていないので、face 読み取り部分に filter を
      挟むとなると遅くなる。或いはキャッシュするか。キャッシュするとしても将来
      的に face 間に依存性を持たせる実装を考えると個別にキャッシュできない。

    b 或いは、別の colorglass domain の区分けとしてプロンプトを処理する時とそれ
      以外で分けるという事も考えられるだろうか。しかしそれだと vim-airline の設
      定は prompt に含まれるので既定の色を抑える等の調整ができなくなる。

2022-09-15

  * vim terminal や neovim terminal における keymap-timeout に対応する設定は何
    か。調べてみると ttimeoutlen や timeoutlen という物がある様だが、これの設定
    を変更しても振る舞いに変化はない気がする。後でちゃんと調べる必要がある。

2022-09-11

  * 何らかの拍子に P[0 q の様な謎の文字列がユーザーコマンドの実行後に出力される
    様になる。

    これは DECSCUSR に関係しているのは確かだと思われるが、どうやって起こるのか
    分からない。例えば _ble_term_Ss 関係の変数が変な値になっているのが原因かと
    も思われたが別にこれらの変数に問題はない。P[0 q の様な文字列が含まれている
    変数も存在しない様に見える。

    * bleopt term_cursor_external=1 を設定してみたらコマンドが始まる前にも変な
      メッセージが出力される様になった。つまりやはり cursor-state の管理の部分
      で起こっている問題なのだろうと思われる。

    * 新しい bash を開始すると別に問題は生じない。また、そもそも表示幅も狂って
      いる気がする、と思ったがこれは本来端末に文字列として表示されない物が表示
      されている事によって位置がずれているだけなので、元の問題を解決すればこれ
      も解決する筈。

    コードを確認してみたら分かった気がする。quote-passthrough によって付加され
    た P が表示されてしまっているのである。そして、端末の入れ子情報が壊れている。
    実際に問題が生じている端末で C-xC-v で端末情報を出力してみた所、どうやら
    screen が三重に入れ子になっていると勘違いしているようである。

    terminal: TERM=screen.xterm-256color wcwidth=14.0-emacs, screen:49900
    (83;49900;0), screen:49900 (83;49900;0), screen:49900 (83;49900;0),
    contra:0 (99;0)

    何故後になってこの様な変な状態になるのか分からないが、ble.sh を reload した
    らちゃんと端末の入れ子状態の情報も正しくなって問題も起こらなくなった。

2022-08-31

  * complete: 'a b c' というファイルがある状態で 'b [TAB] すると変な事になる。

    →今試してみると再現しない。bash-completion をロードしていてもしていなくて
    も問題なく補完される。

  * complete: ~/b/c/スペースを含むファイル[TAB] としても requote されない。

  * complete: 変数名の曖昧補完が効かない。一旦候補を生成したら menu-filter によ
    る曖昧絞り込みはできている。

2022-08-29

  * DEBUG trap についても関数呼び出しの階層を再現する?

    user-handler#{load,has} がそれぞれの文脈で "現在の文脈での handler" を取得
    しようとしているのか、或いは "何れかの文脈で handler があるか" を取得しよう
    としているかをちゃんと区別する必要がある (というか関数を二種類作るべき?)

    また "現在の文脈" を正しく取得できているかどうかについてもちゃんと確認する。

    install-hook については top-level での hook があるかどうかを確認したい。結
    局 trap - DEBUG されない限りは何処かの stackframe で定義されている DEBUG
    trap が top-level に適用されると考えると、何れかの階層の handler があればそ
    れで判定していると思って良い。但し、install-hook については、初期化時に
    user が builtin trap で既に設定しているかどうかを判定する為に用いていて使い
    方が特別である。何れにしても、何処かの階層で既に定義があればユーザーの設定
    した builtin trap は無視するというので良い。[ しかし実はそもそも DEBUG は
    install-hook 内に継承されないので extdebug/functrace が設定されていない限り
    判定できないしその様に条件で弾いている ]

2022-07-10

  * syntax: posix syntax check in posix mode?

    対応が面倒そう。本当にエラーになる訳では無いので普通のエラー着色とは少し異
    なる着色にする?

  * 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 展開も引き起こす。然し一方でコマンド
    さえ確定してしまえば後はそのコマンドの補完によって対応するべきという考え方
    もある。うーん。それでも alias を設定するのはユーザーであり、そのコマンド自
    身ではないと考えるのであれば、やはり ble.sh の側でその辺りを解決して補完を
    呼び出すべきではないだろうか。

2022-07-06

  * complete: func() TAB 及び function func TAB で関数定義を挿入する。

    bash-completion では function func [TAB] でこれに対応しているので。現在は
    function aaa の時 aaa には単語を設置していないが必要があれば登録しても良い。

2022-07-04

  * [保留] debug_xtrace を bash-4.0 以下でも対応する?

    debug_xtrace が bash-3.2 で動いていない。と思ったらそもそも BASH_XTRACEFD
    は bash-4.1 以降の機能だったのだ。bash-4.0 以下では 2 を redirect する事に
    よって実現する? と思ったが 2 は ble.sh が出力するのに使っている気がする。特
    に ble/util/buffer.flush で使っている。更に他にも様々なエラーメッセージが 2
    に出力されるのではないか。という事を考えると 2 を xtrace に使うのは余り良い
    ことではない様な気がする。取り敢えず保留という事にする。

  * ext: trueline と組み合わせた時に問題が起こるとのこと。
    https://github.com/lecramyajiv/Emptydeeds/commit/b57e8354cc350d71c655d93c32112427ec8addda#diff-0a1c1083789380c5f4b4aaebd19b6a4b2431ae808f8b456cf865825cfb93b9dfR2527

2022-06-19

  * 履歴番号を検索やプロンプトで表示しているが、これは history の最初が 1 でな
    い時にはずれるのではないか。後で確認する必要がある気がする。

2022-06-14

  * cygwin: bash --norc, source すると C-xC-v 等の keybinding が動かない
    bash_execute_unix_command のエラーが出る。

    これは元々存在している inputrc か何かが悪さをしている可能性? 然しそうだとし
    ても普通に attach したら問題は生じない。なのでやはり違うのだろうか。

  * eterm: Emacs に実装されている M-x term 若しくは M-x ansi-term

    端末実装が色々滅茶苦茶である。infocmp にて対応している事になっている機能で
    も振る舞いが変である。

    * 先ず、IL, DL は行の途中で実行するとおかしな事になる。IL はその位置に改行
      を挿入して行を2つに分ける機能を持っている。DL は一方で emacs 内部で C-k
      をするのと同じ機能である。即ちその位置以降の文字列を消去するか、行末にい
      る場合には次の行と結合する。これは一応行頭に移動すれば問題ない気がする。

    * RI に関しては端末の一番下にいる時に全体を scroll down し、端末の一番上に
      いる時には何も実行しない。

    未だちゃんと動かない。これは後でちゃんと調べる必要がある。

2022-06-02

  * bash-4.4 crash (reported by notmike-5)
    https://github.com/akinomyoga/ble.sh/issues/195

    source した瞬間に crash するという事だろうか?

    一方で別の問題を発見した。bash-completion scp の補完で 4.4 がcrash する。こ
    れは ble.sh なしでも再現する。また、bash-5.0 以降では発生しない。
    bash-4.2..4.4 の全てで再現する。これは後で bash-completion の側で対処が必要。

2022-05-12

  * isearch: 現在行と全く同じ内容の行には一致しないというオプション

2022-04-13

  * bash が `vi-edit-and-execute-command' を追加している。

    これは自分が以下で報告した事が元になっているのだろう。
    https://lists.gnu.org/archive/html/help-bash/2022-02/msg00031.html

    d70b5339 で追加されている。つまり help-bash で発言した次の日には修正が入っ
    ていたのだった。

2022-03-19

  * 編集文字列に含まれる制御文字の反転表示の可能性

    現在は見た目には区別がつかない。プロンプトシーケンス \w, \W, etc に含まれる
    制御文字については反転の toggle で対処している。

    一方で、現在の実装だと単純に編集文字列に含まれる制御文字の反転状態を変更す
    る事はできない。着色に関係なく制御文字の表現を決めている、つまり地の反転状
    態に関係ない escape sequence を決める必要があるが、地の反転状態が分からなけ
    れば制御文字が終わった位置で正しく反転状態を復元することができなくなる。

    これについてはまた今後必要性を感じた時に実装すれば良い気がする。

2022-03-03

  * 起動時の fork について

    * ble/base/adjust-builtin-wrappers/.assign (2 fork) ... 此処で builtin,
      alias を保存する為に2回に分けて defs=$(...) を実行している。この時点では
      初期化が終わっていないので ble/util/assign は使えない。

      これはそもそも勝手に上書きした builtin や alias を保持する必要があるのか
      という事を考えるとスキップしても良い様な気がする。起動の高速化の為にこう
      いった物を省略するオプションを用意して良い様な気はする。

    * ble/util/msleep/.check-builtin-sleep ... これはロードに失敗した時の事を考
      えて subshell 内部で実行している。

      これも sleep の方法を予め引数等で指定する仕組みを用意しておけばスキップす
      る事は可能である。また builtin sleep に頼り切るのも問題の気がする。という
      か builtin sleep だと C-c が効かない等の問題がある。

      改めて plain Bash に builtin sleep を読み込んで動作を調べてみる。と思った
      が再現しない。というよりそもそも ble.sh をロードしていても bash-5.0 でし
      か再現しない。つまり bash-5.0 & ble.sh の時にだけ bultin sleep 3 で C-c
      に対して即座に実行が中止されない。ble-detach していてもこの問題は発生する。
      plain Bash で直接 enable -f /path/to/sleep sleep して sleep 3 に対して
      C-c した時にはちゃんとすぐに終了する。

    * ble/builtin/bind/read-user-settings/.reconstruct ... これは記録されている
      default bash の binding と、現在の binding を比較してユーザーが設定した
      keybinding を抽出する為に awk を呼び出している。

      これは既存の readline 設定を読み取らない事にすればスキップはできる。実際、
      ble.sh の読み込み時に --noinputrc を指定すればこれは実行されない。

    以上の物は何れもユーザーオプションで省略できる様な機能ではある。然し一方で
    ロードのボトルネックは実は fork ではない。少なくとも Linux では。但し、
    Cygwin では 50ms/fork かかるので 4 fork 省略できるだけで 200ms も時間を短縮
    できるので大きい。

2022-02-20

  * より一般の補完 framework に向けたインターフェイスについて
    https://github.com/rsteube/carapace/issues/431

  * compopt 実装: 現在の実装では "name" や -DEI が与えられた場合には何もせずに
    戻る様になっているが、本来現在の設定を変更するべきなのではないか。また、丁
    度変更対象の補完が現在の補完と一致している時には現在の補完の振る舞いに影響
    を与えるべきなのではないか。これについては実際の Bash の振る舞いを確認する
    必要がある。

  * rsteube の記事
    https://dev.to/rsteube/a-pragmatic-approach-to-shell-completion-4gp0

    filtering を description に対しても適用するという事が書かれている。それは確
    かに便利そうである。現状の実装では対応が難しい様には思われるが。これは fzf
    の様に一旦絞り込み専用の入力欄に移動するなどの事がないと使いにくいだろう。

  * trap (lastarg): 一応 heredoc 等を使えば eval の中から複数行の lastarg を設
    定する事ができるのではないか。他に複数行で、eval されても余分な実行が起こら
    ない様な方法はあるだろうか。不完全な引用符の場合には結局エラーが出力されて
    しまう。

    Ref #D1853

  * [保留] exec: builtin sleep に対して C-c が効かない

    % 現在の実装だと bash-5.0 以下で C-c でループ中に走っている外部コマンドを止
    % めた時に応答がなくなってしまう。bash-5.1 以上では一旦実行が停止するものの
    % 一応応答はする。

    と思ったらこの問題は外部コマンドではなくて builtin sleep を呼び出している時
    特有の問題だった。trap INT を設定しているのは問題なのだろうか。

  * edit: 現在の TRAPDEBUG の枠組みを拡張して try/catch/finally を実装できるのでは
    Ref #D1783

    もしその枠組がちゃんとできるのであれば edit.sh から util.sh に移動する。

2022-02-14

  * 全ての ble.sh session にコマンドを送る機能があれば screen に再 attach した
    時の再調整等に役立つのでは。

    _ble_term_TERM の最初期かもできるし、或いは DISPLAY 環境変数の再設定もでき
    る。チェックの頻度は history-share と同様で良い気がする。

  * ble/builtin/trap DEBUG は関数の入れ子や trace 属性などは考慮していない。こ
    の事によって問題が起こる可能性もある。

2022-02-12

  * highlight: ls -l ~/.c{onfig,a/b}
    ブレース展開の中に / が含まれているとディレクトリパス着色が動かない。

    うーん。そもそも highlight の仕組み的に / が含まれているとどうしたら着色で
    きるか謎という可能性がある? と思ったが恐らくそういう事ではない。何れにして
    も全体を一番最初に一致した PATH に対する色で同じ色で着色する様になっている
    筈。但し、その着色を実行する上で / で分割してから各 segment に対して着色す
    る様になっている為に、brace 展開中に / があると / で分断されてしまって正し
    く着色できないという事になるのだろう。

    ちゃんと対応する為には、"ブレース展開に対して最初の要素で着色をする" のでは
    なくて、ちゃんと各要素に対して着色をするという方向に改める必要があるのかも
    しれない。然し、それは実際の所面倒だし、そこまでする必要があるのかというの
    も謎である。これは優先度は低いがもし実装できたら面白いだろうという事である。

2022-02-08

  * [保留] compat: bind -x 実行後の再描画はプロンプト最後の行以降
    https://lists.gnu.org/archive/html/help-bash/2022-02/msg00023.html
    https://lists.gnu.org/archive/html/help-bash/2022-02/msg00031.html

    どうも bash で試して見た所 に於いてはプロンプトの一番最後の行以降だけが再描
    画の対象らしい。現在の ble.sh の実装だと全体を再描画している。これだと
    help-bash に投稿した様な hack が使えなくなる。

    a Bash と同様に途中から出力する様に調整すれば良い。と思ったが、よく考えたら
      現在の実装では prompt は一気に出力する事になっているので一番最後の行だけ
      出力するという話はない。

    b うーん。その場で clip すれば良いのかもしれない。然しそれは処理として重く
      なる。また、clip した場合には結局描画する時にはカーソルを相対移動させる事
      によってカーソルが本来の位置に戻ってしまう。つまり、hack は結局使えない。

    そもそも hack を使える様にするという発想がおかしいのだとも言える。特に件の
    hack に関しては ps1_final で代用できる。それ以外の目的で描画を乱すとしたら
    それはやはり対応外であるし、もしそういった描画に対する介入を想定しないので
    あれば、結局全体を描画するという現在の振る舞いで特に問題は生じない筈である。

2022-02-05

  * syntax: a=(%{1..10}) の % を '\x' に書き換える時文法構造が破壊 (?)

    $ bash
    $ rep=(%{25,08,0A,2{0..2},24,2{6..9},3B,3C,3E,5C,5E,60,7C})

    として起動した直後に上記の文字列を貼り付けて、それから先頭の % を削除して
    '\x' と入力したら文法構造が壊れてしまった。然し二度と再現しない。問題は '\x
    迄入力した時点で発生していた。もしかすると ' か \ を入力した時点で既におか
    しくなっていたのかもしれない。

2022-02-03

  * キャッシュの判定でファイルを使って判定しているが、よく考えたら現在ロードさ
    れているコードとファイルに含まれているコードが同じとは限らないのではないか。
    もし、現在のシェルの起動時刻よりも比較に使っているファイルのほうが新しい時
    は、ble.sh 自体を reload した方が良いのではないか。と思ったがそれによって失
    われる設定も考えられる。という事から勝手に reload する訳にも行かない。

    起動時刻(というよりble.shロード時刻)を示す一時ファイルを使うという手も考え
    られるが、それだと後になってロードした module の場合には不正確になる。と思っ
    たが、古いコードを使って更新を実行してしまうよりは、新しいコードなのに古い
    情報を更新せずに利用するという位の方が未だましである。

    実はロード時刻は $_ble_base_run/$$.load に既に存在しているのでそれを使えば
    良い。

    検索してみると結構影響のありそうな箇所は沢山ある。一方で具体的にどの様に直
    すのか。load time だけで判定すると毎回キャッシュを更新する事になってしまっ
    て意味がない。(キャッシュが最新でない) & (load time よりも前に元のファイル
    が更新されている) という条件で判定するのが良い気がする。

    * キャッシュが最新でないというのは必須の条件である。そうでなければそもそも
      更新を実行する意味がない。load time が元ファイルより最近の場合にも何も問
      題は生じないので今迄通りに何も気にせずに更新すれば良い。

    * 従って、特に判断が難しいのは (キャッシュ),(LoadTime) > (元ファイル) の場
      合である。更に元ファイルを source した時刻は実は元ファイルよりも後の可能
      性もある。その時にはメモリ上には最新版があるのでそれに従ってキャッシュを
      更新しても問題ない。

    * よく考えたらここで対策をしても問題は生じるのではないか。元々キャッシュファ
      イルが存在しなくて、メモリ上に古い version の関数があって、それに基づいて
      新しくキャッシュを作成した場合、古い version のキャッシュがずっと残ってし
      まう。

      うーん。load time で time stamp を書き換える様にすれば良いのだろうか。

2022-01-23

  * "for ((i=0;i<10;i++)); do sleep 1; done" で C-c すると ble.sh 全体がその場で停止する

    これは外部コマンドを実行中にそのコマンドが SIGINT で終了した場合、trap INT
    に登録されたハンドラーを介さずに即座に実行全体が終了してしまうのが原因であ
    る。

    もしそれがトップレベルのコマンドであれば ERR を用いて捕まえる事はできる。但
    し、それが SIGINT によって引き起こされたものなのか、普通のエラーとして返さ
    れたのかを判定する方法はない。

    更に関数内で実行された場合には ERR でも INT でも捉えられない。RETURN を使っ
    ても捕まえられない。これを解決する方法はない気がする。

2022-01-08

  * mandb: echo のオプションの抽出 (help echo) がおかしい at fc35 vm
    chatoyancy では問題は発生していない

2021-12-22

  * ディレクトリ固有の local commands & aliases を可能にする?

    一方で、勝手に設定をロードする様にしてしまうと怪しいディレクトリに入っただ
    けでそれが有効になってしまうという事が発生する。なので、一旦は enable する
    操作を求めるべきだし、また内容が変更されたらその都度承認を求めるべきである
    (過去に承認したものは hash か或いは実体を記録しておいて再度尋ねはしない様に
    できる)。

    →direnv が丁度同じ事を目的としたプロジェクトの様である。

    2023-01-30 direnv が一体どういう事をしているのかについて調べる → #M0023 に
    纏める事にした。

2021-12-20

  * git-prompt, git-status 等の機能の模倣?

2021-12-18

  * contrib/git: dirty で rps1 が更新された瞬間にカーソル位置がずれた。これは後
    で調べる必要がある。

  * deprecated functions の枠組みを整える。

    散発的に deprecate して行くと毎回設定を変更しなければならず面倒なので、
    version を指定して特定の version 以降になった時に限り初回だけ警告を表示する
    様にするのが良い。

    ((_ble_version>=500)) && ..... と言った具合。

    ? reject: deprecation は version ではなくて独立な番号付を使う可能性?

      →omb において考えていたが、これは特定のバージョンを予め指定するよりは
      deprecation level の様な 1 個ずつ増える整数にするのが良い。というのも、そ
      もそもどの version で完全廃止するのかというのは廃止を決定した瞬間には分か
      らないという事。そして、実際に廃止する瞬間には基本的には全て一度に廃止す
      るのであって、機能によって廃止したり廃止しなかったりという事はない。なの
      で基本的には、新しく廃止をマークする時には次の deprecation level を指定し
      ておいて、deprecation level が上がる時に一斉に廃止するのが良いと思われる。

      一方で、もしかすると緊急で廃止したいという状況が現れるかもしれないので、
      deprecation level は基本的には 100 の倍数にして置いて、細かい廃止を実行し
      たい時に限って 1 ずつ上げる様にするというのも手である。と思ったがその様に
      考えると結局それは _ble_version と同じになるのではないかという気もする。
      但し、基本的に廃止等は master でしか起こらない気がするので patch level と
      deprecation level に関してはずれが生じるだろう。

      また minor version とは無関係に廃止するという事があるのかも分からない。と
      いう事を考えるとやはりその意味に於いても ble.sh に於いては deprecation
      level と version は一致させて良いのではないか。という気がしてきた。

  * complete: FIGNORE と -o filenames

    どうやら元の bash では -o filenames が指定された時にのみ FIGNORE が使われる
    様である。一方で、現在の ble.sh では FIGNORE が設定されている時には強制的に
    fignore が実行される様になっている気がする。と思ったらこれは shopt -s
    force_fignore の設定を参照しての事だった。よく分からないのは bash は
    force_fignore が設定されていても、-o filenames が指定されていなければ
    FIGNORE が有効にならない様だという事。

    * FIGNORE で全て候補が消えた場合には FIGNORE を無効化して全て採択するべきで
      は? と思ったが元の bash ではその様な取り扱いはしていない。

    * Note: bash FIGNORE は glob は解釈しない。bash FIGNORE はそれが実際には存
      在しないファイル名だったとしても、FIGNORE に一致すれば候補削除する。bash
      FIGNORE は候補が FIGNORE で全滅してもそのまま。bash FIGNORE は単一候補だっ
      た時にも FIGNORE を適用して候補を消す。

2021-12-14

  * compat: RLogin で ble-detach した後に modifyOtherKeys の状態がおかしい。
    bash --norc してもおかしい。RLogin である事は検出できている。

  * compat: terminator で status_line で表示が崩れる
    →これは今確認した所再現しない。terminator ではなく terminology の可能性?
    或いは古い vte の問題だった可能性もあるかもしれない。

  * compat: mlterm 起動時に表示が乱れる with statusline

    →これは単純に初期の char_width_mode,char_width_version が一致していない事
    による問題だった。始めから east にしておけば乱れは生じないという事は確かめ
    た。然し、auto で幅を判定する迄の表示の乱れは一般の問題ではないだろうか。

    乱れを最小限にするには文字幅を大きめに取るという意味で east で始めるという
    手もあるかもしれないが、実際には west の端末の方が多いという事を考えると別
    の問題が出てくる可能性がある。また、CPR に応答しない端末の場合ずっと east
    という事になってしまって問題である。起動して暫くは east にしてそれから west
    になるという様な感じの物を auto で判定中の幅にするべきだろうか?

  * C-backspace の問題 (端末自動判定?)
    https://github.com/akinomyoga/ble.sh/issues/94
    https://github.com/akinomyoga/ble.sh/issues/104
    https://github.com/msys2/MSYS2-packages/pull/2490
    https://github.com/microsoft/terminal/issues/755

    以前に色々の端末の動作を調べたと思ったが記録が全く残っていない。辛うじて上
    記の MSYS2 にどのようなパターンがあったかが記されているが、それぞれどの端末
    がどう振る舞っていたかの情報はない。改めて調べる。→ wiki にまとめた。

    うーん。^? と ^H が異なる形に bind されているという事は。。。どうしようもな
    い。既定では両方とも backspace だと思って置くしかない。ユーザーが自分で設定
    をする時にちゃんと判定するのが良い。

    もしくは端末を自動的に判定して C-h, C-_, etc を C-BS に置き換える設定を行う
    という事も考えられる。

2021-12-11

  * declare の引数チェックをもっと真面目に実装する。chroma のインターフェイス
    設計の足がかりにする。

    * wattr=- (未着色) の時にのみ着色しているが、実際には一つでも未着色があった
     らそれ以降の引数に対して与える影響を考慮に入れなければならない。但し、これ
     を実行すると毎回ファイル名着色が全て計算されるなどの様な形になりとても遅く
     なると思われるので、未だ実装しない。

      これは一般の問題なので別項目で議論するべき気がする。mandb_opts 等を用いて
      指定する可能性。

    * declare: -f, -F が含まれる場合には関数名として任意の名前を含む事ができる。
      というかオプション名も含む事ができる? (declare -F -f とした時の解釈はどちら
      になるのだろうか?)

    * 変数代入の形式をしていない引数に関しては中身によってOKかもしれないし駄目
      かもしれない。

  * refactor: highlight-variable というインターフェイスを作る。

    と、思ったが quote 等も考えるとそういった関数を提供する事に意味があるのか
    分からなくなってくる。先に quote 除去した時の対応関係について解決する枠組
    みが必要になるのではないかという気もする。

  * cmdspec: cd 関連の cmdinfo は core-cmdspec ではなくて contrib/cmdspec/* 辺
    りに移動する?

  * PROMPT_COMMAND / trap DEBUG で問題が起こる? (found by rashad-moves)
    https://github.com/rashad-moves/HomeConfigurationFiles/commit/efbac4153fd5021f1bc00d42c618fd9d6f4090b9

    2022-03-03 うーん。どうもこの問題は以下で報告されている物と同じの気がする。
    timer_show が含まれている。
    https://github.com/akinomyoga/ble.sh/issues/176

    実行時間の表示について Q&A にでも書いておくべきだろうか。

  * complete (source:rhs): 変数名依存の補完に対応しても良いのでは。

  * complete: ARGEX (eval 文脈) の補完

    現在は "variable:=, command:D, file" で生成しているが、本来は一番先頭の引数
    を元にして argument (including progcomp, etc.) を呼び出すべきなのではないか。

  * complete: [[ の中の文法も考慮した補完。これは [[ の中の文法にちゃんと対応し
    た後で考える事の気がする。

2021-12-06

  * mandb: コマンドの名称を抽出して保持して置けば binary の呼び出し時に使える。
    dnf や apt 等に問い合わせても良いのかもしれない。或いは、含まれているパッケー
    ジを見るという手もある。

    然し各コマンドについて man 等を呼び出すのは高価である。

    rpm, dnf でファイルの所属する package と含まれるファイルを抽出するには。
    https://linux-audit.com/determine-file-and-related-package/

    $ dnf -C repoquery --installed -f /usr/bin/git-lfs --qf '%{summary}'

    等の様にすれば良い。

    * resolved: しかしこれを呼び出すと package 一覧のダウンロード等を実行し始め
      るので問題がある気がする。或いは、更新を無効化した状態で呼び出す事ができ
      るだろうか →どうやら dnf -C とオプションを指定する事で cache から情報を
      取得できる様だ。

    * background で生成するにしても時間がかかるので、複数の bash session で同時
      に更新が実行されない様に注意が必要である。*.part.$$ に書き込んで、その後
      でそれを mv するという形にすると良い。更に、他の session が既に生成を試み
      ている場合には、background 生成を止める事にする。

    うーん。以下の結果を加工すれば一挙に全てのコマンドについて情報を抜き出せるのでは。
       $ dnf -C repoquery --installed --whatprovides /usr/bin/\* --nvr
       $ LANG=C dnf -C provides -q /usr/bin/\*

    * man -f ...

      というか man -s 1:6:8 -f command... を呼び出せばよいらしい。

      * linux では man -s 1:6:8 -f command 等として結果を得られる。whatis -s
        1:6:8 command としても同じ出力結果である。というか whatis 自体が man に
        よって実装されている疑惑 (-s オプションなどがあるので)。

      * cygwin で実行したら駄目だった。whatis sed awk とした時と全く同じ出力結
        果になったので、whatis を使っているのだろう。

      * solaris では man -f sed は表示されるが、man -f sed awk や man -f sed -f
        awk 等の様にして複数の結果を取得しようとすると何も表示されなくなる。1行
        目は空行で、2行目に man ファイルの情報があって、3行目にようやく説明が表
        示される。

      * minix では man -f sed で whatis を間接的に呼び出そうとしている。そして
        whatis はデータベースがない等の文句を言って動かない。

      * freebsd でも whatis を呼び出している様だ。警告が出ているが、複数指定し
        たら複数の説明をちゃんと出力してくれる。, 区切りで一行に複数の名称を出
        す事もある。例えば man -f awk とすると "awk, nawk (1) - <説明>" という
        具合の行を出力する。

  * complete: 文字列引数の中にファイル名を含めたい事もあるのでは。つまり "add
    a.sh" の様な。特に complete -m '...' の編集で欲しくなる。

  * bash-completion: awk - で long option だけが生成される。調べてみると
    complete -F _longopt が割り当てられているコマンドについては全てこのパターン
    の様である。

  * bash-completion: 空文字列に対して最初からオプションも生成して欲しい。
    そうしないと絞り込みの際に都合が悪い。

    うーん。bash-completion や他の補完の事を考えると一文字目に - が入力された時
    点で候補を再生成するべきの気がする。或いは - から始まる候補も追加する? 追加
    する場合には以前にあった物と重複する候補を削除しなければならない事に注意する。

  * syntax: for $(echo hello) に対しては着色しない。もしくはエラーとする。

    これは heredoc 単語と同様の問題である。因みに heredoc の単語に $() を含めた
    場合には、終端位置判定が正しくできなくなっている。普通に入力すると終端位置
    を逃す。終端を書いてから heredoc の中身を編集すると位置を正しく特定できる。

2021-11-23

  * kitty shell-integration (requested by kovidgoyal)
    https://github.com/akinomyoga/ble.sh/issues/110#issuecomment-976182311
    https://github.com/kovidgoyal/kitty/issues/3948

    | [Check default shell-integration]
    |
    | * ok: 前のコマンドの内容を less で見る: C-S-g
    |
    |   vim-airline を表示している時に問題が生じる。中途半端に切れたりする。
    |
    | * ok: プロンプト移動(scrollback): C-S-{z,x}
    |
    | * マウスによるプロンプト内の移動:
    |
    |   遅い、vi_nmap の中にいると変な事になる。うーん。これはまた後で確認する。
    |
    | * xterm-title で現在ディレクトリを表示する。
    |
    |   これは別に何か新しい機能という訳でもないだろう。敢えて ble.sh で対応する
    |   とするのであれば、bleopt prompt_xterm_title を用いるぐらいの事である。
    |
    | * これも特に変な事はない。但し、ble.sh 側でユーザーが何か設定している場合に
    |   は、kitty integration の設定は off にすれば良い。
    |
    | * ok: winch glitch の解決。これは綺麗に動いている。
    |
    | * Sophisticated completion for the kitty command in the shell. これは
    |   core-complete の領分であるが何か特別な事が起こるとも思われない。
    |
    | 結局 vim-airline を実行した事による問題点は C-S-g で閲覧する内容の切り取り
    | 以外では特に問題になっていない様に見える。以下の三点を報告する。
    |
    | x subshell の中でちゃんと動作していない。従って tmux の内部でも動作しない。
    |
    | x 複数行コマンド編集時に vi_nmap で位置がずれる。他の keymap では問題は生じ
    |   ない。
    |
    | x vim-airline を使っていると時々コマンド内容が切れる

    最初の項目については意図的なのだという返信が来た。だとしても tmux で空にな
    るというのは変である。後で patch を作っても良い。問題にしているのは
    invasive という事だったので SHLVL, SUBSHELL, $- 辺りを参照して本当に kitty
    の中にいる時にだけ有効にするというのが良いのかもしれない。(と思ったが、元々
    の kitty.bash でも kitty かどうかをチェックしているのではないか?)

    2つ目の項目に関しては仕方のない制限だという事。up/down を有効化する
    sequence について提案した所、patch が送られてきたら見るとの事。これは忙しい
    ので今は未だ。

    3つ目は調査中。

2021-11-21

  * complete: インラインでヘルプ・次に期待する引数の種類を表示するという話
    https://www.reddit.com/r/bash/comments/qrm3s2/hints_for_argument_types_in_bash/
    https://github.com/fish-shell/fish-shell/issues/2201

  * やはりメモリを使うという事は明記するべきである。

    bash-3.2 16MB 19MB
    bash-4.3 26MB 31MB
    bash-5.1 33MB 40MB

2021-11-05

  * vim の :term 内部で実行すると振る舞いが変だ

    * 先ず最初のロード時に行が一行ずれる。それ以降は発生しない。modifyOtherKeys
      もしくは文字幅判定の為に出力している何かが問題を起こしているのかもしれな
      い。

      →どうもこのずれは status_line に関係している様だ。

    * うーん vim :term の中だと NUL (C-@, C-SP) を入力することができない。C-wは
      vim の側での操作に使われている様だ。これらは ble.sh の外側でも同様である
      事から、ble.sh の問題ではない。寧ろ vim term の仕様と見るべきである。

  * bash-5.2 で builtin bind -Xs を観察するとところどころ \000 が余分に挿入され
    ている。これは何か。bash-5.1 では問題はない。

2021-10-26

  * winch: Window サイズを変化した時に menu の座標計算がずれる
    (menu_style=dense)そもそも resize した時点で menu の再配置を実行しなければ
    ならない筈である。

    或いはサイズが変わった時には menu-complete はキャンセルするべきなのではない
    か? 特に大量の WINCH を送ってくる端末があって、大量のメニュー項目の後ろの方
    のページを表示しているとすると、ほぼフリーズした様な形になってしまう。

    或いは次に TAB を押して他の項目を移動しようとした時点で改めて配置計算を実行
    する? 例えば、WINCH を受け取った時点では info を単に非表示にしておいて、次
    にメニューに対して表示の変更等を行う必要が生じた時に改めて計算を実行する。

    2022-03-04 そもそも ble/edit/info 自体が WINCH の時に再計算するべきなのでは
    ないか。特に高さだけでなく幅についても考えて再計算しないと内容が乱れてしま
    う。

  * スタートしてから数秒間は user input detection for C-m を off にした方が良い
    のでは。スタートした直後にペーストを実行する事があるとは思われない…。

    と思ったが bash を含む大量のテキストを入力した場合にどうなるのかというのは
    疑問である。とは言いつつも、その場合には親シェルの側でちゃんと paste
    detection ができているべきではないかという気がする。

2021-10-04

  * fzf を直接読み込んだ時に動かない問題について
    https://github.com/akinomyoga/ble.sh/issues/126

    ble-update を実行すると動く様になるが最初から source ble.sh すると動かない。
    ble-import contrib/fzf-key-bindings をすると動く様になる。

    というか改めて説明を読むが一体どういう操作をしようとして問題が生じているの
    か謎である。C-r, C-s をしようとした時に問題が生じているという事だろうか。現
    在の実装では補完については contrib/fzf を自動でロードする様にしている。
    widget に関しては contrib/fzf-key-bindings 経由で呼び出さなければ駄目である。

    うーん。自動的に検出して補正する様にしようと考えたがそんなに単純ではない様
    に見える。

    a 例えば bind する瞬間に fzf 関連であるかどうかを調べて fzf 関連であると分
      かった時点で fzf-key-bindings を呼び出すという方法。

      x ユーザーが実行したい binding が fzf-key-bindings と同じかどうか分からな
        い。ユーザーが自分で調整して binding のキーを変更しているかもしれない。
        この場合には勝手に fzf-key-bindings を読んでしまうとユーザーの予期しな
        い binding が定義される事になり問題である。

        一方で、諸々の関数は fzf/shell/key-bindings.bash に定義されているのだか
        ら、そこに含まれている関数を使おうとしている時点で其処にある binding が
        そのまま使われていると仮定して良いのではないか。もし、ユーザーが
        fzf/shell/key-bindings.bash を自分でコピー・編集して使っているのだとし
        たら、やはり contrib/fzf-key-bindings.bash についても同様に自分の設定に
        合わせて編集するべきなのではないか。

      o bind で -x に fzf 関連を指定した場合に関数の中身を差し替える等の事をし
        ようとしても、例えば inputrc キャッシュで初期化を誘導する等の事までは
        キャッシュできない気がする。

        →これに関しては fzf-key-bindings では関数の中身を差し替えるのではなく
        て、別名の関数を定義してそれに差し替える様にして、更にその別名の関数に
        ついての autoload を def.sh 辺りに記述する事にすれば良い。

        x この方法だと __fzf_cd__ や __fzf_history__ をユーザーが直接自分で
        bind した時に対策できない。

    b 或いは、bind -x を実行する時にコマンド名が __fzf_history__ または
      fzf-file-widget だった場合にこれらの関数を上書きするという手法。

      x この方法だと __fzf_cd__ の検出ができない。__fzf_cd__ は、
        fzf/shell/key-bindings.bash だとマクロ経由で呼び出される様になっている。
        つまり bind -x ではないという事。かと言って accept-line に作用して、コ
        マンド実行前にコマンド内容を調べて関数を上書きするというのも非現実的な
        気がする。

      うーん。やっぱり現状の様に設定するべきなのではないだろうか。

2021-09-28

  * fast-syntax-highlighting

    https://www.reddit.com/r/zsh/comments/oyege0/is_completionaware_syntax_highlighting_possible/
    https://github.com/zdharma/fast-syntax-highlighting/tree/master/%E2%86%92chroma
    https://github.com/Valodim/zsh-capture-completion

    どうやら programmable highlighting に相当する機能は
    fast-syntax-highlighting で既に実装されていて "chroma" と呼ばれているらしい。
    然し実のところそれ程沢山の実装がある訳でもない。

    他に zsh-capture-completion というモジュールに含まれる関数で capture.zsh
    'command' を実行すると 'command[TAB]' とした時の補完結果を取得できるらしい。
    これは ble.sh の上で作成する事も可能である。補完機能のテストで使うのに便利
    な気がする。

    bash-completion のテストをコピーできたら良い気がする…。でも全て python で
    定義されているというのは難点である。うーん。結局、その場で補完を実行する機
    能を実装したとしても使う機会がないからテストされずに残って意味のない機能に
    なりそうな気がする。

  * https://www.reddit.com/r/commandline/comments/pv1fm8/what_are_the_main_advantages_of_the_various_shells/

    fish の便利な機能について紹介している。

    * M-{right,left} でディレクトリ移動。これについては異なる keybinding で提供しても良い気がする。

      iswitchb の如く C-x C-b 等で探索するのもありではないか?
      その際には menu の機能を有効活用できる気がする。

    * fish の Abbreviations の振る舞いが気になる。
      zsh の zsh-abbr も気になる。

    然し、実際に ble.sh をロードさせてテストするというのは有効の気がする。

  * menu: C-x C-d で今迄に訪れたディレクトリの一覧。

    iswitchb と同様に絞り込みをしたいが入力した文字列は何処に表示するのが良いのか。
    panel に表示するのが良いだろうか。或いは、そもそも表示しなくても良いのかもしれない。
    何れにせよ太字で表示されるのであるから。

    太字ではなくてより強調した形にしても良いのかもしれない。これは face 経由で
    設定できる様にするのが良い様な気がする。現在は太字固定になっているが。

  * menu: C-x C-j で job 制御用の TUI メニューを表示しても良いのかもしれないとも思う。

2021-09-26

  * bash-5.2: array が sparse でない ./configure option が追加された。

    もしかすると sparse arrays に declare -gA を指定する必要があるかもしれない。
    sparse かつ ordered な配列については簡単な workaround は存在しない。唯、そ
    の様な配列を実際に使っているかは分からない。なければ気にしなくて良い。

2021-09-22

  * edit: 複数行モードの時は prior/next でページ移動?

  * plug: git clone 用の判定:

    これは

    $ grep -q '^github\.com' ~/.ssh/known_hosts
    $ grep -qEi '[[:space:]]*HostName[[:space:]]+([^[:space:]]+[[:space:]]+)*github\.com' ~/.ssh/config

  * 実は local rex=... [[ a =~ $rex ]] は関数に纏めたら良いのでは。

    速度的にはどうだろうと思って比較してみると4倍位遅くなる。もしくは 0.014ms
    だけ遅くなる。70回の評価で1ms, 1400回の評価で20ms, 7000回の評価で100msの差
    が出る。

    $ ble-measure "local rex=':point=([^:]*):'; [[ alpha:beta:point=end:b = \$rex ]]"
         3.618 usec/eval
    $ function ble/regex#match { [[ $1 =~ $2 ]]; }
    $ ble-measure "ble/regex#match alpha:beta:point=end:b ':point=([^:]*):'"
        17.402 usec/eval

    うーん。一般的には気にする速度低下ではないが、構文解析などの中心部では控え
    た方が良いかもしれないというぐらいである。通常の場所ではどんどん使って問題
    ないのではないか。

    →検索してみたが実は意外とそんなに沢山あるという訳でもない様だ。少しずつ置
    き換えていけば数日で終わるぐらいの箇所しか無い。概算で140箇所程度である。然
    し、そもそも其処までして置き換える必要があるのかという疑問もある。現状で動
    いているのであればそれで良いのではないか。一応他のシェルに移植する時に一括
    で動作を変更するのが楽という可能性はなくはない。

    2021-12-11 ble/string#match という関数名で追加した。

2021-09-20

  * sabbrev: accept-line の時にも展開する可能性について (requested by pl643)
    https://github.com/akinomyoga/ble.sh/discussions/138

    * zsh-abbr の振る舞いについても確認する。

    * 振る舞いについての考察

      a グローバルに全ての合致する単語を置換する。

        x 先ず、意図しない物まで展開されてしまう可能性がある。

        x 展開を意図する単語があったとしても、通常は magic-space によって既に展
          開されていると期待するべき。なのでわざわざグローバルな展開を試みるま
          でもない。

      b 或いはその場所にある単語だけを展開する magic-accept 的な物。

      元の要求が結局どのような物だったかは返事がないので不明だが、考えて見るに
      b の方が良い。

2021-09-15

  * haiku: ble/builtin/bind/.reconstruct-user-settings の gawk が無限ループになっ
    ている? 或いは滅茶苦茶遅くなっている。gawk 4.2 である。bash-4.4.23 から呼び
    出している。変な事が起こる様な余地はない様な気がするが…或いは正規表現エン
    ジンなどが壊れているという事なのかもしれない。

  * solaris: ble-bind を bashrc 内部で呼び出した時点で未だ attach していないの
    に色々と info を表示してしまっている。
    $_ble_base_cache/decode.cmap.gdict.*.dump を削除した時に再現する。

  * grapheme: SpacingMark, Prepend の幅は一体どうなっているのだろうか [#T0008]

    現在の実装では幅を全く考慮に入れていないが、入れるべきの気がする。c2w で
    combining に対して 0 を返す様にしたら Extend や Prepend に対しても c2w で値
    を計算して加算する様にすれば良いだろうか。然し、絵文字の Emoji_Modifier な
    ど組み合わせた時と単体の時で幅の異なる物も存在する。

2021-09-06

  * menu: メニューの詳細表示を toggle できる様にするべきではないか。

    表示するか表示しないか完全に固定するのは微妙な気がする。

    後、desc-raw しか実際には使わない様な気がする。二種類の表示方法を用意したと
    しても、そもそも説明を生成する側で二種類を分けて生成する訳にも行かないので、
    どちらかに統一するべきではないか。速度が気になるというのはあるが、もしテキ
    ストだと解釈するとしても、全角文字などが含まれる場合には結局位置計算は省略
    できない。逆に ascii 文字だけで構成されているのであれば esc を解釈するとし
    てもそんなに速度低下なく処理する事ができる。

    表示の toggle は各メニューが表示される度に行うか或いは一回変更したら暫くそ
    の設定を保持するか。ユーザーの指定した設定を既定値として各 menu が表示され
    る度に toggle を行うという事を考えたがそれは如何にも面倒である。それよりは
    toggle は永続的な変更を引き起こすとした方が分かりやすい様な気がする。その場
    合には、bleopt の設定を永続的に設定してしまっても良いのではないか。

    然し、それだと desc モードになっている時に align 等を設定した時にどの様に振
    る舞えば良いのか分からない。一つの手は一旦完全に toggle 状態を clear して、
    改めて既定の style として align を設定するというのが自然な気がする。

    * toggle するとしたらその表示切り替えのキーボード操作はどうするのか。C-m と
      思ったがそれだと確定と同じ。C-d だと削除みたいな感じがする。insert は確か
      に toggle だがやはり直感的ではない気がする。 ScrLk や CapsLock NumLock 等
      も同様である (というか OS 側のキーボードの状態が変わってしまったりして大
      変である)。

      後、実際に menu-complete に入らなくても切り替えられた方が良い様な気がする。
      その場合には他と被らない様な操作にする必要がある。他で使われていない
      single-key の操作はそうそう残っていない気がするし、残っているとしてもそれ
      をたかが menu toggle に割り当てるべきなのかという問題もある。或いは、2
      keys による操作としても良い様な気はしている。

      例えば C-x | 等。特に C-x は menu-complete やその他の complete に色々割り
      当てているから丁度良い気がする。

      - "C-x d" は emacs では dired,
      - "C-x ?" は emacs では keybinding 一覧,
      - "C-x h" は emacs では全選択に割り当てられている。
      - "C-x |" は emacs では割り当てがない。
      - "C-x C-h" は前の文を削除する。
      - "C-x C-t" は行の入れ替え。

      若干操作しにくい気がするが、うーん。一旦 menu-complete に入ってしまえば
      "|" で入力できるようにすれば良いと思ったが…普通に "|" を入力したいという
      時があるのでそれは駄目だ。やはり C-? の形の方が良い。

  * menu: preview 機能をつけても良い。preview に表示する中身は候補の種類に応じて色々。

    そもそも desc の内容自体その場に表示するのではなくて preview 的な小さな窓の中に
    選択した時にだけ表示するという形式でも良いのではないかという気がする。

2021-09-02

  * 改めて確認した所また Windows Terminal で動かなくなっている

    調べると Cygwin 経由で接続した時だけの問題の様である。
    これは Cygwin の側の conpty の副作用という可能性もある。
    というか最新版の Cygwin で直っている可能性もある。

    ? wt を path に加えて実行もできるのにも関わらず構文着色で赤になっている。不思議だ。
      type wt とするとちゃんと成功する。

    ? Cygwin から起動した時とスタートメニューから起動した時で、Windows
      Terminal の中で Cygwin タブを開いた時のプロンプトに含まれるシー
      ケンスが異なっている気がする。と思ったが、これは Cygwin の
      screen の中から起動すると、Windows Terminal の中の Cygwin も
      screen の中にいると勘違いするからであろう。気にしなくて良い。

      取り敢えず環境変数が継承される事は確認したし、
      CYGWIN=disable_pcon を指定していても指定していなくても Windows
      Termianl - Cygwin では座標計算がずれるという事が確認できた。やは
      り pcon は関係ないのかもしれない。

  * 起動時間を計測しているようだ

    ble.sh でかなり時間がかかっている様だという事。

    * ble.sh は background 処理を行う。特に ble-attach の末尾で行っている気がす
      る。なので、ユーザーが何も入力しない限り background 処理を完全に終えるま
      で ble-attach から抜けないのではないか。逆に、ユーザーが何か入力している
      時にはより早く初期化できるのではないか。と思って試してみたがそうでもない。
      というか殆ど変化がない。どういう事だろうか。

      ユーザー入力の検出ができていない? 或いはそもそも background 処理は最初は
      行っていない? 後者の様な気もするが後で確認する必要がある。

      letsnote でも試してみたがやはりユーザー入力があっても殆ど変化はない。
      GNU/LInux でも Cygwin でも同様にユーザー入力があっても変化はない様だ。

      実装を確認してみると確かに ble-attach の末尾で .tail を呼び出してい
      て、.tail は idle.do を呼び出している。うーん。不思議だ。或いは .tail の
      前後だけに注目すればより短くなっているかもしれない。

    * MSYS2 環境では ble.sh のロード及び attach にはかなり時間がかかる様だ。と
      いうかこれは fork の回数に直結しているという気もする。MSYS2 で調べると
      spawn が 10/s だった。

      一方で Cygwin だと 23/s 程度である。実は Cygwin の方が軽量である。或いは
      最適化が施されていると見るべきか。或いは whitelite に入れていただろうか。

2021-08-31

  * complete: -E (_EmptycmD_) に対応していない

    一方でこれは一体どの様に振る舞うものとして実装すれば良いのか分からない側面
    がある。文字列が本当に空の時にはこれを使って補間するので良い。

    * ; で区切って未だ何も入力していない状況の時にはどう振る舞うべきか。元の
      bash では本当に空文字列の時にだけ呼び出される様である。また -E の用途とし
      て空の時のコマンド候補を生成するという役割もあるかもしれないが、

      というか改めて考えると ; で区切って未だの時には -I が対応する補完になるの
      ではないか。という事を考えると -E はやはり完全に空の時に対応するのではな
      いだろうか。実際に試してみるのが良い気がする。

      complete -F _initial -I, complete -F _empty -E で試してみると ; の次で呼
      び出した補完の場合には _initial が呼び出される。完全に空の時には _empty
      が呼び出されていて一文字でも入力されていれば _initial が呼び出される。入
      力されているのが空文字列であっても同様である。

    実装するとしたらどの様に実装するべきだろうか。単に空の時には新しく -E で呼
    び出す仕組みを作れば良いのだろうか。

  * msys2 での ble-update で変な動きをした。。

2021-08-30

  * complete: overridden builtin 及び他の framework

    | * https://github.com/csdvrx/bash-timestamping-sqlite
    |
    |   この実装では history コマンドを上書きしている様な気がする。然し同時に
    |   ble.sh との併用を推奨している。うーん。この時 ble.sh が history を上書きす
    |   る、もしくはble.sh の history がこの枠組に上書きされるという事があったら何
    |   が起こるのだろうか。何か悪い事が起きる気がする。
    |   ble/function#push とかを使って何とかすれば良いのだろうか。
    |   その場合にはこの interface を固定する必要がある。
    |
    |   と思って実際にコードを確認したが history を上書きしている訳でもない様だ。

    何れにしてもこれは注意点として README に記述しておくべきなのではないか。

  * complete: そもそも遡って書き換える補完候補と純粋な意味での補完候補は区別す
    るべきなのかもしれない。TAB 補完では後者に基づいて補完を実行するが、メニュー
    の表示には両方を表示するという手がある。その場合にはメニューの内部で
    section を分けると良いだろうか。ページング等をちゃんと考慮に入れる必要があ
    る。

2021-08-29

  * bashrc に直接設定を書く方法についても説明する。

    但しこの場合には ble-reload をした時に設定が消えるという事に注意する。→うー
    ん。この様な面倒な事が起こるのであればやはり記述しないほうが良いのではない
    か。

    よく考えてみたら source ble.sh と ble-attach の間に書いた bind にも同様の問
    題があるのではないか? と思ったが、ble-attach よりも前に書いているのであれば
    ちゃんと readline の側にも反映されている筈で問題はない筈。

    ユーザーがコマンドラインから設定した設定は消えてなくなってしまうという事に
    注意する。これらを記録して後で拾える様にするという手もあるかもしれないとは
    思う。

2021-08-26

  * CPU 100% in macOS (reported by killermoehre)
    https://github.com/akinomyoga/ble.sh/issues/131

    CPU 100% になっている時に同時に gawk が待機している様である。
    100% になっている時の gawk の引数について尋ねたら返答が来た。

    二つの bash について異なる gawk が呼び出されている。前者は
    ble/history:bash/resolve-multiline/.awk で、後者は
    ble/history:bash/load/.background-initialize である。両方とも
    history に関係している。

    Q というかどちらの bash が CPU 100% になっているのだろうか。或いは両方?

    Q bash が起動した時に暫く 100% になるのか起動した後もずっと 100% のままなの
      か。もし暫くしたら収まるのだとしたらどれぐらいの間 100% でいるのだろうか。
      これがそんなに長くなければ少なくとも見た目の動作に影響がない限りはそのま
      まにしておいても良い様な気がする。

    Q CPU 100% になっている間 bash は応答するだろうか。応答するとしたら

    Q いつでも現象は再現するだろうか。或いは確率的に発生するだろうか。

    ----

    取り敢えずやはり巨大な history が問題であるという事までは分かった。
    自分の手許の linux では同じぐらいの巨大な history を用意したとしても
    そんなに遅くはない。

    ? 一方で向こうの報告によると builtin history を実行しているプロセスが重いと
      いうことの様である。自分の手許で確認しようとしているがすぐに処理が終わっ
      てしまうので確認できない。

    * 終了時にもかなり待たされる。

      終了時の nawk が滅茶苦茶遅くなる。gawk だと遅くないとかあるのだろうか。と
      思って改めて観察してみると最初に bash が 100% になって、その次に nawk が
      100% になるという具合に処理が進行している。

      ble/builtin/history/.write で時間を消費している。

      A:1630043056.816931
      B:1630043056.936962 0.12s ... history/.get-min
      C:1630043056.942516 0.06s ... history/.get-max
      D:1630043079.487224 13s ... builtin history >> file
      E:1630043092.465937 13s ... nawk の処理

    Q hang と slow は区別しているのだろうか。自分的には hang というのは待っても
      絶対に終わらないという意味である。然し、向こうは有限時間で終わるという事
      を確認しているのにも関わらず hang と言っている可能性がある。よく分からな
      い。

2021-08-23

  * bash-4.2 では [[ ${arr[*]} == *" 2 "* ]] (where arr=(1 2 '')) が駄目

    一応該当しそうな物を検索すると以下の様な物がある。
    何れも空白には関係なさそうなので問題は起こらなそうな気がする。

    $ grc '\[\[ \$\{.*\[[*@]\].*\} [!=]= .* \]\]'
    ./ble.pp:145:    { ((${#BASH_SOURCE[@]})) && [[ ${BASH_SOURCE[${#BASH_SOURCE[@]}-1]} == *bashrc ]]; } ||
    ./src/decode.sh:3632:    [[ ${keys[*]} != "$bind_keys" ]] &&

2021-07-14

  * bash-it によるプロンプト設定が prompt attach で反映されない。

    PROMPT_COMMAND 経由で PS1 を設定していると反映されないのだろうかと思ったが
    そういう訳でもない様だ。

    powerline-multiline で発生するとの事だが再現しない。
    というか powerline-multiline で発生する固有の問題なのか、
    それとも他の theme でも動作するのかの情報についても書いていない。

2021-07-13

  * auto-menu: 一旦 (no items) が表示されるとそれ以降 auto-menu が動作しない

    auto-menu が有効になっている時に一旦 (no items) が表示されるとそれがそのま
    まになって二度と auto-menu が起動しなくなる。

    またこの時に C-l で再描画すると info に何も表示されなくなる。実はこれは
    menu が表示されている時には常に再現する問題である。

2021-06-21

  * auto-menu が有効になっている時に複数行編集で座標が変になる

    2021-07-13 今試しても問題は再現しない。

    2021-07-18 再現した。履歴に複数行の項目が含まれている時に、その履歴が呼び出
    されると問題が発生する。ble-bind ... と入力した時に発生した。というかこれは
    本当に auto-menu の問題なのかどうか分からない。取り敢えず、textmap を再確認
    する必要がある気がする。ずれの量的にも前回の textmap の時と似たような振る舞
    いの様に見える。

    2021-07-19 chatoyancy の上では再現しない? vaiio2016 の上でも再現しない。

2021-06-18

  * grapheme: ble/canvas/trace の lc lg の grapheme cluster 対応について
    Ref #D1619

    基底文字だけを指定しても、最後の Extend を指定しても端末によって左の書記素
    クラスターが破壊される可能性がある。書記素クラスター全体で出力する必要があ
    る。lc lg の組ではなくて lcs lw lg の組で結果を返さなければならない。lc lg
    はデバグ用なので其処まで配慮する意義は薄い。

    そもそも lc lg の枠組みはそろそろ削除しても良いのではないかという気すらする。

  * grapheme: 私用文字で置き換える事により書記素クラスター単位での編集を可能にする可能性
    Ref #D1619

    現在の所その必要性は限りなく低いと考えられる。

  * grapheme: Unicode version 毎の振る舞いの違い?
    Ref #D1619

    emoji_version と同様に grapheme_cluster についても version 毎の違いを考えて
    も良いのかもしれない。

  * emoji: Emoji 対応状況自動判定
    Ref #D1619

    | これも自動検出の対象にしても良いのでは。という気がする。というかそうする
    | べきである。所で Zle は実は内部的にそういう事をしている可能性がある。
    |
    | と思ったが端末によって unqualified の取り扱いもばらばらだろうし ZWJ に対
    | 応しているのかどうかも不明だし、という事を考えていくと単に
    | legacy/extended を区別すれば良いという訳ではない。場合によっては ZWJ シー
    | ケンスに対応しているかどうかと言ったフラグまで管理しなければならないかも
    | しれない。とは言いつつ実際にそのように振る舞う端末が存在するのかどうかも
    | 不明である。なので、これは実際の端末の振る舞いを整理しながら考える必要が
    | ある。
    |
    | 端末ごとの絵文字の振る舞いについて調べる必要がある気がする。kitty/vte は
    | unqualified はテキスト表示で EPVS によって絵文字になる。RLogin は
    | unqualified は半角で表示される? 幅は VS で変化しないように見える。mintty
    | は試した限りでは Emoji に対応していない。既定で off になっているという事
    | だろうか。
    |
    | 以下の振る舞いも端末の対応状況に応じて実装する。
    |
    | * EPVS の時には emoji_width または 2 になる様にしている。然し、絵文字の表示
    |   ができない端末では 2 にせずに普通の文字として求めた方が良い可能性もある。

    * legacy vs extended
    * unqualified をどう取り扱うか。EPVS 及び TPVS がどう作用するか
    * ZWJ sequence に対応しているかどうか

    現実の端末に於いてそれぞれどう対応されているか、そして三つの対応状況の組み
    合わせはどうなっているかについても調べる必要がある。

  * test: ログを何処かに保存する機能? その場合には着色等は除外する

  * syntax_debug の時にコマンド実行すると実行位置が変だ

    うーん。info　を削除する時のシーケンスが間違っている? menu の表示時には何も
    問題がない。menu に関しては消去してから実行するからだろうか。或いは、変なタ
    イミングで info が更新されて info が表示されてはいけないタイミングで表示さ
    れているという事だろうか。

  * progcomp の出力に関する議論 (reported by oc1024)
    https://github.com/akinomyoga/ble.sh/issues/121

    うーん。どうするのが良いのか微妙。Bash と同じ様に動作するべきなのか、或いは
    出力を抑制するべきなのか。関連する議論が幾つかあった様な気がする。というか
    最近抑制する様に変更した様な気がするが何故再発しているのだろう。実際に確認
    してみた所、歴史的には常に出力を許している様にも見える。不思議だ。

    うーん。実は progcomp-helper-func ではなくて、compgen の時点で出力を抑制し
    ていたのだったろうか。

    * 98835b5 2021-05-17 これは _ble_util_fd_stderr 等に保存した fd を使う様に
      する変更。本質的には tty を使う様になっている。元から helper-func で tty
      にリダイレクトしていた。

    * 9d4ad56 2021-05-06 うーん。以前の報告が見つかった。よく見たらこれも
      oc1024 による報告である。この commit では stderr に関連する変更はない。

      https://github.com/akinomyoga/ble.sh/issues/97

      どうもこの時は個別にバグのある関数を置き換えたのだった。修正は 9d4ad56 で
      ある。stderr/stdout に対しては全く変更していないし細かい議論もしていない。

    * 4fc51ae 2021-03-10 fzf に対する対策。これについては明示的に tty にリダイ
      レクトしている。これより前は compgen 呼び出しの stderr への redirect の為
      に stderr は抑制されていた。

    * 68f8077a 2020-04-06 これは compgen 呼び出しに builtin を付加しただけ。

    * 1ca53868 2019-01-01 これは complete -p の解析に機能を追加した物。この時点
      で compgen の stderr は抑制している。

2021-06-13

  * menu-complete: 末尾一致 (skip-completed-text) が考慮に入っていない

    これは最終的な挿入時に処理するべきか、或いはメニュー項目を一時挿入している
    時から処理するべきか。メニュー項目を一時挿入している時から処理しないと振る
    舞いとして不自然になる気がする。

  * 終了ステータスが 2 の時に前回のコマンドを再ロードするというのは面白い試みかもしれない

    最近人気らしい thefuck により修正後のコマンドが取得できればなお良い。

2021-05-29

  * syntax: 単語が sabbrev に一致する場合には着色するのが親切だ

    これは sabbrev に対する仕様拡張を行ってからでも遅くないのではないか。
    ble/syntax/progcolor/word:default 辺りに修正を加えれば良い。
    本来は progcolor よりも上の枠組みで着色したい気もするが
    それだと layer を増やす必要がある。処理が重くなりそうである。

    check-sabbrev 的な感じで付加的な処理として実装できれば良い。
    そうすれば custom な着色関数からでも呼び出せる。
    と思ったがちゃんと忘れずに呼び出すのも面倒である。
    やはりもっと下の枠組みで提供するべきだろうか。
    例えば、最終的に着色を格納する部分に介入してしまうという手もある。

2021-05-27

  * wiki の更新
    * done: \g{...} について記述する (2021-06-13)
    * wiki: ble-import の -f オプション
    * wiki: bleopt の wildcard, -r, -u
    * wiki: blehook の -a
    * 2021-06-12 wiki: bleopt -I
    * 2021-05-24 airline: 使い方を説明に書く

  * やはり source_if() { source "$@"; } 等とすると引数が一つしかない場合に、自
    分自身が引数であると誤認してロードがキャンセルされる。

    % これは実は簡単に判定できるのではないだろうか。つまり引数が唯一つでしかも
    % 自分自身を指している場合には関数内で無引数でsource されたのであると判定で
    % きる。と思ったが違う。これで見えているのは外側の関数の引数なのだから、必
    % ずしもそういう形になっている訳ではない。

2021-05-23

  * menu-complete: SIGWINCH による info#panel::invalidate の際にメニュー項目の
    再配置を実行するべきである。

    * info 拡張: というか info の表示を担っている class を動的に変更するべきな
      のではないか。現在の実装だと内容を変更する時には必ず info の関数を即時で
      呼び出さなければならない仕組みになっている。然し、そうではなくて機に応じ
      て丸ごと制御を移すなどの事をした方が良いのではないか。然し、一方でどの内
      容が一番上に来るべきかなどの制御も必要になる。現在は default/non-default
      の二層構造になっているがそれをもっと動的に変化できる様に改良するという手
      も考えられる。

2021-05-21

  * progcolor: 取り敢えず builtin から始めるのが良いのではないかという気がする。

    ble.sh の関数についても着色及び補完関数を定義して行きたい。

2021-05-19

  * complete: [TAB] 補完の場合には、ユーザー入力があった時に即座にキャンセルす
    るのではなくて timeout があっても良いのかもしれない。

2021-05-17

  * 此処で思ったのだが nawk は Unicode の対象を取り扱えるのだろうか。。。UTF-8
    ならば通常の制御文字はそのままなので問題は生じないのではないかという気もす
    るが。文字数を数えて何かする様な処理では何か変な事が起こるかもしれないが、
    そうでなければ大丈夫の気がする。

    問題が起こるかもしれないのは brace expansion の形式でファイル名一覧を挿入す
    る処理。これに関しては UTF-8 だと例えば平仮名の途中で分断されたりして変な事
    が起こる可能性がある。

  * global: /dev/null を $_ble_util_fd_null に置き換える?

    #D1552 で議論した。毎回 open するよりも dup した方が高速である。一方で
    _ble_util_fd_null が上書きされたりした時は /dev/null の方が頑健である。

  * syntax: redirection が正しく解析できていない気がする
    以下の手順で編集した時に着色が間違っている。

    $ exec {fd}>/dev/null
    $ exec {}>/dev/null
    $ exec {_ble_base_fd_null}>/dev/null

  * 色見本について探した

    多くのサイトは微妙である。そもそも sRGB とかの概念があるのかないのか不明で
    ある。単純に RGB #XXXXXX の値を線形で CMYK に変換していたりしてかなり怪しい。
    色用語の場所にも sRGB やガンマ補正などの単語は見られない。

    https://www.color-sample.com/popular/jiscolor/ja/

    このサイトはちゃんと sRGB/Adobe RGB 等について載っているので少なくともちゃ
    んとその辺りの事を認識した上で作られたサイトであろうと思われる。然し権利関
    係の記述もないし、連絡先もない。メールボタンがあると思って押したら単に "友
    達にこのサイトを紹介する" メールを送る為のボタンだった。© 2021
    Color-Sample.com. All Rights Reserved. という表記の右にあるアイコンがリン
    クになっていたので押して見たが、単純にトップに跳ぶだけだった。Twitter アカ
    ウントは https://twitter.com/color_sample で見に行ったら 2014 で更新が止まっ
    ている。著作権が 2021 になっているのは機械的に置き換えているだけという事だ
    ろうか。何だかよく分からない。というかよく見たらブラウザサポートというアイ
    コンも古いブラウザが並んでいたりして更新が止まっている事を示唆している。

    https://triple-underscore.github.io/css-color-ja.html#rgb-to-lab

    w3 の CSS の仕様の翻訳。ここにちゃんと色々の知識が書かれている。この文書は
    最初から最後まで読むべき。

    http://mezala.la.coocan.jp/pc/jiscolor/jiscolor.html

    このページは複数の情報源からの差異について見せているがそもそも CMYK, RGB の
    変換式として異なるサイトから二種類持ってきていて (どちらかが間違っているの
    に違いない) 更に、Wikipedia からの数値も比較していて、どれだけ見た目が変わっ
    てくるかを見せているが。色には絶対的な基準はないのだとか色々言って納得して
    いるが、これらは単に sRGB と RGB の解釈を間違えて変換しているから起こってい
    る間違いのような気がする。(とはいいつつ画面の輝度やその他の要因もあるだろう
    から一概には言えないのかもしれないが、少なくともどういう条件の元での変換を
    行っているのか明示した上で、その差異について議論していなければ情報としては
    使い物にならない)

    https://www.colordic.org/w

    このサイトは和色大辞典と言って 460 色掲載しているそうで一番大きい気がする。
    然し、その RGB 値が sRGB なのかどうかとかも分からない。Q&A には再利用・再頒
    布可能性などについては述べられていないし、各色の出典についても書かれていな
    い。このサイトの RGB 値が実際に sRGB なのか何なのか確認して、その上で他の色
    についても変換を確認するのが良い気がする。

2021-05-15

  * AUR blesh-git のカスタム update について
    https://aur.archlinux.org/packages/blesh-git/
    https://aur.archlinux.org/cgit/aur.git/tree/blesh-update.sh?h=blesh-git

    * {PRE,POST}_VERSION を local で宣言する
      これはもう既に修正してもらった。

    * _package.sh の属性は 644
      これに関しては結局指摘する機会がなかったからそのままだが、まあ大して問題
      はないだろう。

  * syntax

    1>&$fd- は使えない
    1>&./- もエラーになる

    もっとちゃんと調べる必要がある。

2021-05-09

  * Fedora の package にするには結構面倒な手続きが要りそうな感じである。
    https://blog.jwf.io/2017/11/first-rpm-package-fedora/

    何れにしても ble.sh は頻繁に変更が加わっているし未だ 0.* の version の段階
    なので未だ公式に提出はしない事にする。1.0 を出す時に一緒に提出を考えるのが
    良いだろうと思われる。

  * v1.0 を出す迄に何か目玉の機能を実装したい所であるが、実の所、他のシェルに全
    くない様な機能で便利そうな物は存在しない。

    * syntax-highlighting ... 文法もちゃんと追跡した物

    * error message ... これは他のシェルにはない機能である。fish にあったりする
      かもしれないが。

    * vim mode ... これは highlighting も含めてなかなか気に入っている。

    * complete
      * sabbrev ... 個人的にこれは結構便利だと考えている。
      * auto-complete ... これは別に他のシェルと比べて何か良い訳でもない。
      * auto-menu ... これはちょっと煩い。けれど他のシェルにもあるので。

    * bottom panel ... 一つは bottom panel かもしれないがそんなに便利なのかとい
      うと微妙な所である。tmux の方の設定で似たような物を表示できる筈だし特に便
      利でもない。見た目に派手なので最初は喜んで使う人がいるかもしれないという
      位。

    * enhanced history ... 相対パスでファイル名を参照しているのを記録したい。そ
      れを auto-complete の実装に役立てたい。

    * TUI configuration?

    逆に欠けている物。ex mode の :cmd が全然対応できていない。

2021-05-06

  * progcomp: complete -C completer で改行のエスケープに対応していない

    man bash によると completer の出力した結果は行志向であるが \ によるエスケー
    プで改行を含める事ができるらしい。然し、\ が特別な意味を持つのだとすれば行
    末に \ を置きたい時にはどうすれば良いのか。行内全体に於いてエスケープが意味
    を持つのだろうか。よく分からない事が多い。実際に試してみないと分からない。

    或いは read line で読み込む事ができる形式だろうか。

    →実際に動作を確認したところ、エスケープの除去は行われず \ も含まて補完文字
    列とされる様だ。よく考えてみれば、実際に挿入した時に複数の単語として解釈さ
    れてしまっては困る訳だから、確かにこの動作でなければならない。

    ? 末尾に \\ があったらどうなるだろうか → \\ であってもその後の改行は候補の
      一部と見做される様だ。

    さて、具体的にどの様に実装するのが良いか…という事を考えようと思ったが難し
    い。先ず標準出力を勝手に自分で COMPREPLY に代入するのは違う様に思われる。と
    いうのも、呼び出し元の compgen で -S suffix 等の加工をしてもらわなければな
    らないからである。だとすると、最終的な compgen の出力結果を解釈する時に行末
    の '\' で行を繋げる様に処理しなければならないのだろうか。

    そもそも改行を含むファイル名があった時に compgen はどの様な出力をするのか。
    うーん。普通にエスケープせずに改行を出力した様な気がする→確認した。確かに
    そうなっている。なので '\' が行末にあるからと言って勝手に振る舞いを変更する
    のも憚られる。

    或いは compgen の全ての機能を自前で模倣するという手もなくはない。その場合には区切りは全て制御下にある。

  * progcomp: -F もしくは -C で生成した候補に対しても dir/ 等の suffix を付ける
    必要はあるのか。もし付けたければ completion 側で付けるべきなのではないかと
    いう気がする。

2021-05-04

  * robustness: ble.sh では exit を上書きしているが set -o posix の時にはそれが
    無効になる。

  * util: builtins 復元、function#advice, etc. において functrace 属性は復元し
    なくて良いのだろうか。復元という事を考えるとやはり declare -pf を使う必要が
    あるのかもしれない。

    bash version, posix mode も含めてどういう方法があってそれぞれどの様に振る舞
    うのか調べる必要がある。

    取り敢えず問題が起こらない事を確かめた上で getdef 自体を更新するのが良いの
    ではないか

    →と思ったが実際は複雑である。getdef を使って関数を別名にコピーするのに使っ
    たりしているが、その時に先頭部分だけを置換している。しかし declare -ft の部
    分についても関数名を置換しなければならない。そういう事になるぐらいであれば、
    個別に declare -ft かどうかを判定して、改めて declare -ft で属性を付加し直
    す様にしないと行けない筈である。

2021-05-03

  * rlfunc: fetch-history
    8f485ff8 - new readline "fetch-history" bindable command
  * rlfunc: C-x s, spell-correct-word
    6be3a741
  * rlvar: enable-active-region
    b1965836 new "enable-active-region" readline variable
  * rlbind: prior, next
    65822e50 - alias expansion fix in case statements
  * vi-undo

  * 5.2: LS_COLORS *.readline-colored-completion-prefix (bash e59452c7)

    rlvar colored-completion-prefix が on でかつ LS_COLORS の中に
    *.readline-colored-completion-prefix という項目がある時、共通一致部分の着色
    をそれに書き換える。

    実際に bash の振る舞いを調べてみようとしたがどうも有効にならない。調べてみ
    ると、_rl_color_ext_list が初期化されていない。これを初期化する為には何かす
    る必要があるのだろうか。_rl_parse_colors という関数で初期化しているようだが、
    この関数はどこから呼び出されているのだろうか。

    うーん。分かった。readline.c:1327 で呼び出している。これは初期化部分である。
    つまり、readline を初期化するよりも先に LS_COLORS を設定しておく必要がある。
    更に言うと、bind 'set ... on' も事前にやって置かないと駄目。というか
    colored-stats の時点で同じ問題があったのではないか?

    これは単純に _rl_color_ext_list が空だったらその場で _rl_parse_colors の呼
    び出しを試みるという事と、それから LS_COLORS の値が変更される時に
    _rl_color_ext_list をクリアする。と思ったが、これだと LS_COLORS が空の時に、
    毎回 _rl_parse_colors が試みられて非効率的である。

    * 後、_rl_colored_stats = 0 が _rl_parse_colors の中で設定されている。

2021-04-30

  * ble-reload: blerc 外のユーザー設定の保持

    外部のツールが呼び出した blehook PREEXEC+=... 等は別枠で保存しておくべきで
    はないか。そうしないと ble-reload した時に設定が消えてなくなってしまう。或
    いは、blerc の中から呼び出したか外から呼び出したかで取り扱いを変える。blerc
    の中で呼び出した設定は消えてしまっても仕方がない。一方で、blerc の外側で実
    行した物については保持しておくのが自然なのではないか。

2021-04-29

  * robustness: main/init: readonly POSIXLY_CORRECT されていたらどうするのか。

    少なくともどちらの側の設定であっても ble.sh 的には困る。

    然し、readonly まで気にし始めるとあらゆる変数名で問題が起こるので気にしても仕
    方がないのかも知れない。せめて全て大文字の変数だけが readonly になっていると
    いう事を要請するのが妥当だろうか。ローカル変数で大文字を使っているというと
    KEYS WIDGET ARG FLAG REG 辺りは危ないかもしれない。

    然し、ここまで行くと「ユーザーが自分で変な事をしたのだから責任は持てない」と
    いうレベルの事の様な気がする。

  * robustness: main/init: 最初の bash version 判定も alias 対策可能かもしれない?
    然し、return/exit が上書きされる場合等も考えると難しいかも知れない?

  * robustness: "builtin read -e" 対策?

    これは今迄考えて来なかったが関連する考察 #D1520 があったので記録として残し
    ておく。但し、纏めた物を眺めるに総じて困難である様に思われる。

    a set -o emacs / set -o vi の切り替えを利用して read が使える様にする。つま
      り、ble.sh は裏側の keymap に bind して、ユーザーコマンドを実行する時に反
      転させるという方法。この方法には問題が多い。

      x 全てのユーザー関数 (補完関数、プロンプト、trap、blehook 等) で keymap
        を反転する必要があるのではないか。

      x ユーザーが emacs/vi keymap を切り替える rl bindable function を実行する
        と結局 ble.sh の bind している keymap が表に出てきてその時点で制御不能
        になってしまう。勝手にそういった binding を削除するのも非現実的な気がす
        る。

      x bash の version によっては keymap を切り替えると bind -x が中断した様な
        気もする。

    b trap DEBUG 等を使って builtin read -e が呼び出されるのを検出して、ble.sh
      で wrap した処理を行ってからそのコマンドの実行をスキップする。この方法に
      も色々の問題がつきまとう。ちゃんと透過的に対応できるかというと困難の気が
      する。

      x DEBUG のコストがある。

      x ユーザの設定した DEBUG の管理が面倒。結局 trap DEBUG を透過的に利用でき
        る様にする枠組みは完成していない。(これはその枠組さえ完成すれば余り気に
        しなくても良いのかもしれない)

      x 本当に実行するコマンドを入れ替える事が可能なのだろうか。例えば builtin
        read -e の呼び出し元から見て、本当に関数実行が入れ替わった様に見えるの
        か。exit status はどうなるのか。これは実際に実験してみないと分からない。

      x DEBUG の BASH_COMMAND を用いて元のコマンドを本当に再現できるのか。例え
        ば $1 等が使われていた時にその内容を取得する事は可能なのか (BASH_ARGV
        を有効にしておかなければならないのか? ユーザーが設定を変更してしまった
        らどうなるのか)。また、引数の境界等もちゃんと BASH_COMMAND を見ただけで
        分かる様になっているのか。これも色々実験しないと分からない。

    c builtin read -e に入った後で ble.sh の widget が呼び出されたら良い様に
      状態を adjust して widget の振る舞いを変更できないだろうか。

      x C-c に明示的に対応して、C-c が呼び出された時には設定を restore して抜け
        る様にする。これは面倒なだけで処理としては十分可能である様な気がする。
        但し、外側に SIGINT を伝播する必要はあるのかもしれない。

    d ユーザーがコマンドを実行する度に realine 設定を完全 unbind して、終わったら
      再度 bind し直す。でも、これは文法エラー等によってコマンド実行が中断された
      時に、ble.sh session に復帰せずに通常の readline の状態に落ちてしまう。

2021-04-06

  * logout も exit と同様に置き換えるべきなのではないか。

  * prompt を評価する時に $var が local 変数に被覆されている。

    然し $var だけならば良いが $() で呼び出された関数が更に内部で変数を使用して
    いる可能性等を考えると下手に変な調整はしない方が良いかもしれない。PS1 に直
    接 $var と記述するかしないかで $() の内部でも変数が見えるかどうかが切り替わ
    るというのは不自然すぎる。それならば ble.sh 自体が変数を定義するのでそれに
    よって被覆されてしまうと説明した方が自然である。

    グローバルでない変数を列挙する方法は存在するだろうか。

2021-04-26

  * keymap/vi: vi における既定の keymap を imap ではなく nmap にするオプション

    現在の振る舞いではコマンド実行後に nmap であれば insert-mode に戻すという操
    作をしていた筈である。その箇所を書き換えて、オプションに応じて変更先のモー
    ドを切り替える様にすれば良い。それと ble-attach した時の最初の設定を行った
    直後に、自動的に nmap に移動する様にする処理を加えれば良い。

  * ble-bind: ble-bind -P で、他のオプションで指定したタイプの binding だけを出力する?

    % -T を指定すれば -T の設定を出力する。--cursor を指定すれば --cursor の設
    % 定を出力する。cmap 関連のオプションを指定すればそれに関連する設定を出力す
    % る。と思ったが、-T, --cursor, --csi, -k, etc. はそれぞれオプション引数を
    % 取るので、引数読み取りの段階で -P の後で振る舞いを変更する様にしなければ
    % ならない。これはコマンドライン引数の解釈として不自然である。

    別のオプションを使って dump する内容を選別するのが良い。例えば、
    --filter=timeout:cursor:csi:cmap:etc 等である。

  * decode: [refactor] _ble_decode_KEYMAP_kmap_@ ?

    いきなり KEYMAP ではなくてその前に何か挟みたい。例えば
    _ble_decode_kmap_KEYMAP_@ に変更する等。この場合には KEYMAP の名称として紛
    らわしい物が定義された時に問題になるのではないか。前の実装で KEYMAP の直後
    に固定の文字列を挿入していたのは、末尾から KEYMAP 以外の部分を一意に切り取
    る事ができる様にする為の設計だったのではないか。

    現在の実装は末尾からの一意性が保証される様になっている。_kmap_ が他で使われ
    ていない限りに於いて、ちゃんと一意になっている。然し、名前空間として変であ
    るというのも分かりにくい。なので、 _ble_decode_kmap_KEYMAP_xxxx_yyyy にして、
    xxxx には yyyy に絶対に現れない文字列を指定すれば良い。例えば data 等。

2021-04-04

  * history auto-save

2021-03-21

  * robustness: 様々な基本的な変数が readonly でグローバルに固定されていたらど
    うするのか。ロードした瞬間に様々な良くない事が起こる気がする。然し、それを
    言い出すと、bash-completion や他のフレームワークにも強い影響が出てくるので、
    ble.sh だけが対応しても仕方がないという考え方もできる。

2021-03-07

  * edit: キーボードマクロで "M-d" が "M-d d" と記録されてしまっている
    vi でも emacs でも同様に記録されてしまう。

2021-02-28

  * canvas/trace: wordwrap に対応する。つまり、単語の途中で改行しない様にする。

    これは今の所具体的な用途もないので取り敢えずこの儘にしておく。

  * canvas/trace: より詳しい justify の仕様について設定できる様にする。

    #D1494 の案では "SEP*WEIGHT FILL SEP" を単位として指定するという話だったが、
    これはやはり不自然な感じで分かりにくいのでもっと分かりやすい指定方法を考え
    るべき。

    例えば、最低幅1重み2 '%1.2S{FILL}' という具合にするなど。こうすると % を
    SEP に指定できないし } を FILL に指定できないが使う機会があるとも思えない
    ので気にしない。或いは '%{1.2SFILL}' とする? うーん余計に分かりづらい。或
    いは printf strftime を真似て '%1.2(FILL)S' という具合にする。

    空白は既定で '%1.0( ) ' に相当する。その他の文字は '%0.0()X' に相当する物
    とする。

    2021-03-08 というより、各 sep の性質として登録するよりも、\q{...}  を通して
    設定できた方が自然なのではないか。

    \q{hfill w=2 fill=...}... という具合に。その場合には \1\2 と同様に特別なシー
    ケンスで fill を表現する必要はある。OSC か其処らを使えば良い気がする。或い
    は ANSI seq に何かあった気がしないでもない。

2021-02-27

  * /dev/tcp/... についても特別に着色を行いたい。

    例えば < /dev/tcp/.../.. において正しいパスであるのにも拘らず、存在しないファ
    イルとしてエラーが検出される。

2021-02-24

  * canvas/trace: trace の g0 は後で合成するのではなくて \e[m の段階で設定する
    べきなのではないか。

    後、g0 という名前も余りよくない気がする。他の x0 y0 からの連想で初期の g の
    値という雰囲気が出てしまう。然し一方で sgr0 からの連想で背景色という雰囲気
    もある。実際に別の場所では sgr0 を指定する事によって背景色を設定できる様に
    なっている。

    名前はさておきどの様に振る舞うのが良いのか。例えば \e[39m で既定色に戻すと
    いう操作の場合は本当に端末既定色に戻すべきなのか、或いは g0 で指定した色に
    するべきなのかというのは微妙な所である。g0 で指定した色にするべきの気がする。

    一方で、下線などの属性に関しては g0 で指定したものから解除できる様にするの
    が自然な気もするし、或いは g0 で指定した物は常に設定されているのが自然の様
    な気もする。どちらが良いのかは分からない。やはり現状の実装で良い様な気もす
    る。

    うーん。単に設定のあるなしという捉え方ではなくて下線ありと下線なしという独
    立したスタイルがそれぞれあるのだと思えば、やはり g0 を毎回上書きするのでは
    なくて、\e[m 等に対応する操作の時にだけ g0 の値に設定するというのが正解の気
    がする。

2021-02-23

  * util: カーソルが bottom-dock にいる時の vbell の座標計算
    Ref #D1495 ... 取り敢えずの対策

    現在の実装は vbell が sc..rc を自由に使える前提になっている。しかしカーソル
    が bottom-dock に停泊している時に vbell が来るとvbell によって floating
    panels の位置が分からなくなってしまい、表示がずれてしまう事になる。

    同じプロセス (親シェル) の中で vbell を処理している場合には、一旦 floating
    panel の位置に戻ってから sc..rc をしてそれから再び bottom-dock に戻るという
    手順を踏む事によって問題を回避できる。然し、サブシェルの中にいる場合には現
    在の最新の配置情報にアクセスできないのでこの方法は取れない。

    現在は取り敢えずカーソルが bottom-dock に停泊している事はないとの想定で
    sc..rc を実行しているが、例えば info_display=bottom にして vi_cmap を使って
    いる時などにこの前提が破れてしまう。

    [解決方法]

    ちゃんと実装する為には、親シェルで全ての描画を行う様にする必要がある。その
    時に問題になるのがどうやって visible-bell の消去のタイミングを親側で決める
    かという事。idle を使う方法は bash-4 以降でしか使えない。シグナルを使う方法
    には余り頼りたくないが、現実的にはそうするしかないのだろうか。bash-3 と
    bash-4 で実装を切り替えても良い。何れにしてもサブシェルと通信を行う枠組みを
    整える必要がある気がする。

2021-02-22

  * cavnas: 描画の最中で status が高さを取得する時に textarea の内容を削り取る可能性がある

    現在の render 中に配置を決定する仕組みは問題があるので再考する必要がある。

  * cygwin: 下部での IL が動かない旨を報告する?

    後 DA2 応答をしてくれないか頼みたい。

    $ printf 'Line %s\n' {0..100}; /bin/sleep 1; printf '\e[L'; /bin/sleep 1

    最下部で DL を実行した時にも何か変な事が起こる。

    $ printf 'Line %s\n' {0..100}; /bin/sleep 1; printf '\e[M'; /bin/sleep 1

2021-02-13

  * edit: C-x e に続いて e を連続して押した時にマクロ実行を繰り返す様にしたい

  * 実は bash の read -e は C-r でコマンド履歴を参照できる。ble.sh では read 専
    用の履歴を独立に管理しているが、コマンド履歴にもアクセスできる様にするべき
    なのでは。と思ったがやはり何だか微妙な気がする。

    read 専用の履歴を別に管理するというのもありなのではないかという気がする。
    その場合には保存場所は何処にするべきだろうか。
    ~/.local/share/blesh
    ~/.config/blesh
    ~/.cache/blesh

    https://github.com/fish-shell/fish-shell/issues/744

    fish は過去に config に置いていてユーザの文句によって local/share に移動し
    た様だ。然し、local/share はそれはそれで何だか変な気もする。

  * gnuplot など他のコマンドに対して ble.sh によって編集機能を提供する事は可能
    だろうか。少なくとも pty を自分で開いてその中で gnuplot を起動する必要があ
    る? 或いは、gnuplot のリンク先の readline library を勝手に書き換えて bash
    を起動させて、更にその中で ble.sh を使って readline 関数の振る舞いを模倣す
    る?

    rlwrap 等を使うという手もある? rlwrap のじっそうはやはり pty を開くという物
    のようである。rlfe という物もあるようである。

    どうも gnuplot の場合には普通に gnuplot & で起動しても操作できる様
    な気がする。ble.sh で _ble_syntax_lang=gnuplot として更に
    exec:gnuplot を提供したらそれだけで普通に動く様な気がする。

    - ble-edit/is-single-complete-line で syntax:bash を呼び出している
      のをsyntax:$_ble_syntax_lang として呼び出す様に変更する必要があ
      る。他にも accept-line が is-complete を呼び出している。

    * shell-expand 系統の widget は gnuplot モードでは無効にしたい。
    * command-help 系統の widget も gnuplot モードでは別の実装にする。

2021-02-10

  * main: 関数内で引数なしで source すると関数の引数がそのまま source の中から
    見える。これらを区別する方法はあるだろうか。

    うーん。shopt -u extdebug であれば BASH_ARGC の数が二種類の source の仕方で
    異なるようである (但しその具体的な数は bash-5 から変わっている。更に入れ子
    source や関数呼び出しなどが絡んできた時にどうなるかは不明である)。然し、
    shopt -s extdebug の時には両者は同じになる。

2021-02-06

  * tui: TreeView

    以下の様な物があるのを見つけた。
    https://gitlab.com/TheDalaiAlpaca/saturnon/-/blob/master/saturnon

    実際どんな物かは確かめていないが、TUI 要素としてファイルピッカーは定番である。

    その基礎として先ず TreeView を実装するというのは一つの方向性。TreeView は
    List の拡張として作成するのが自然であろう。List の各要素の高さを変えられる
    様にして、更に中にそれぞれリストを保持するようにしたものと解釈できる。問題
    になるのはリスト項目が増えてきた時に高さの累積計算が重くなるという事。シェ
    ルで実装すると成ると重み付きB木の様な複雑なデータ構造にもしにくい。或いは、
    本気で重み付きB木をBash上で実装するという方向性もあるのかもしれない。

    Midnight Commander と同等の機能を ble.sh の内部で実装するというのも
    demonstration として良いのではないかという気がする。

2021-02-05

  * 他の bash プログラム

    * https://stackoverflow.com/q/41043916/4908404
      history 候補を自動的に表示する可能性について議論している

      上記 StackOverflow の質問で提案されている。Google Chrome の search bar の様に、
      幾つか文字を入力した時点でもう履歴から項目を拾って幾つか表示し始めるという可能性。
      これは fzf の領分である様な気もするが shell integration を考えるとなかなか非自明である。

      というか普通の検索でも複数の候補を表示した方が分かりやすいのではないかという気がする。
      例えば或る一定以上の時間が経ったら一致する候補を列挙するなど。
      更に待っていると曖昧一致も列挙してくれる、という具合にする。

      2021-02-09 hstr が同様の機能を提供している。hstr の動作も参考にした方が良いのではないか。

    * https://github.com/dylanaraps/shfm/blob/master/shfm (file manager in POSIX shell)
      これは dylanaraps の fff の再実装

    * これは README に乗せるバッジの話
      https://img.shields.io/github/downloads/akinomyoga/ble.sh/total
      ダウンロード数の画像を生成できる様だ

    * Incremental parsing:

      ble.sh で行っている構文解析は特殊な物であるが如何にも既存の例がありそうである。

      検索したら以下の様な物があった。

      [Tree-sitter｜Introduction](https://tree-sitter.github.io/tree-sitter/)

      参考にしている論文を見てみると state matching で skip と書いているので、
      やはり単に途中から始めるというだけでなく途中で解析を中断するという考えも
      ある。寧ろ、完全に一致していなくても局所的な一致であれば解析を跳ばすとい
      う事を実行していると思われ、より積極的な最適化である。

      恐らく先にこれを見つけていたら ble.sh の構文解析の実装ももっと複雑になっ
      て、更になかなか完成しない日々が続いたのではないかという気がする。何事に
      も一長一短があるのであって既存の研究だって参考にできる部分と捨て置いて良
      い部分がある筈だが調べてしまうと完全に対応したく成るのが問題である。なの
      で、取り敢えず持てる範囲の知識で何かやってみるというのは大切な事なのであ
      る。

      oil 等は沢山調べすぎて行き詰まっているのではないかという気もする。或いは
      逆に何だか Python -> C++ translator を開発するなど変な方向に走っていて、
      それで余計に時間を取られているのではないか等等。やはりメンテナンス等を考
      えると、Python は prototype として捨て置いて、C++ で完全に書き直した方が
      得策なのではないか。Python -> C++ をずっと使う事にしていると、少しの機能
      追加で毎回 translator にも大幅に手をいれなければならず、結局メンテナンス
      が困難になる。特に第三者がコードに手を入れるのが極度に難しい。この構造を
      保持したまま続けるには最初に完全なる translator を作って、その後は
      translator の改良を行わないという決断が必要である (状況に応じて最適な翻訳
      が異なりうる事まで考えていたら完成した translator があってもきりがない)。

2021-02-05

  * evaluate-path-spec (by 3ximus)

    evaluate-path-spec の改良に挑戦してみるという事なので。先ずは説明が必要である。

    * notilde に関しては eval の側で処理するべきではないか
    * 後で全体 path 以外については single を加える様にお願いする

    2021-12-31 詳細は以下にある。
    https://github.com/akinomyoga/ble.sh/issues/82#issuecomment-773487368

    83.sh に実装を入れて試してみる事にする。

    と思ったが具体的にどの様に実装すれば良いのだろうか。先ず初めに短い物から長
    い物まで順番にパスを構築する。その後に一番長い物から順番に一致を試みる。一
    番長い物が一致すれば、後はその得られたパスを既存のパターンに当て嵌めれば良
    い。と思ったのだが、どうやって当て嵌めるのだろうか。

    * extglob まで絡んで来ると余計に分からなくなる。と思ったが extglob は
      simple-word の要件を外れるのでここでは考えなくて良い。

    うーん。glob を解釈して正規表現に変換すれば行けるかもしれない。或いは、
    ${path#$pattern} または ${path%$pattern} 等として削って行けば良いのでは? と
    思ったが、$pattern の場合には * も一致してしまうのではないか。。

2021-02-03

  * edit: 例えばファイル一覧を表示する機能を付けても良いのではないだろうか。

2021-02-01

  * complete: complete_timeout_compvar でタイムアウトした単語の glob 文字を quote しない?
    Ref #D1457

    現在はグロブ文字も quote して COMP_WORDS と COMP_LINE を構築している。例え
    ば **/*.txt に時間がかかった時に COMP_WORDS には "'**/*.txt'" という文字列
    が格納されるが、これは本来 "**'/'*'.txt'" であるべきなのではないかという事。

    * 一方で、補完関数の方が複雑な quote に対応しているかという問題もある。

    * また、ここで quote しないと結局補完関数の方でも時間がかかってしまうのでは
      ないかという恐れがある。

    という事など考えると、取り敢えずは完全に quote する実装にしておく。後で気が
    向いたらまた考える。

  * highlight: failglob の時の a/b*/c/d.txt の着色が最後のファイル名になっている。
    本来はどの時点で failglob になるか判定して着色するべきなのではないだろうか。

2021-01-28

  * progcolor: ble/syntax/progcolor/eval-word を着色を跨いでキャッシュできないか

    特に展開結果を何処かに保存しておきたい。新しい配列を用意するか、或いは hash
    にして記録するか。

    a hash にして記録すると一度評価した単語を再評価する機会が失われる。ファイル
      が追加・削除された時に更新されなくなってしまう。

      やはり、単語単位でやはりキャッシュしたい。そうすると shift にも耐えうる仕
      組みにしたい、という事で新しい配列を用意するか、或いは既存の配列に格納す
      るという方法になる。

    b 新しい配列を追加する

      また shift 等の操作が増える。面倒である。

    c 既存の配列に要素を追加する

      既存の配列に格納する場合には任意の文字列を含める事ができないので、補助配
      列にデータを格納する事にしてその添字を既存の配列に入れるという手がある。
      特に単語に id を振っておけば今後の word に関するデータ拡張にも使う事がで
      きる。

    →これに関しては ble/syntax:bash/simple-word/eval の側でキャッシュする様に
    したので、今の所はここでは対応しなくて良い気がする。当初は simple-word/eval
    では非常に短期のキャッシュしかしない方向を考えていたが、ファイルシステムが
    そう頻繁に変わる訳でもないので、取り敢えずは行毎にキャッシュを保持する事に
    した。なので、simple-word/eval のキャッシュは単語よりも寿命が長いので単語毎
    のキャッシュは今の所は考えない事にする。

    * 但し、やはりファイルシステムの変化に追随したいという事であれば、適当にキャッ
      シュを更新する必要がある気がする。或いは、globpat を含む様な場合にのみキャッ
      シュを行うというのでも良い様な気がしている。

    * また、ここでの実装手法は例えばエラーメッセージの記録等の場合にも使えるの
      ではないだろうか。という気がする。

2021-01-22

  * highlight: 引数が沢山あると cygwin で滅茶苦茶遅い

    これは様々な種類のパス名展開を試そうとするのが原因だろうか。
    command 名と同様にキャッシュする様にしても良いのではないだろうか。
    でも少しずつ微妙に異なる引数が沢山ある場合には結局遅い。
    それよりは着色自体の高速化について考えた方が良いのではないか。

    * chat でも遅くなるかどうかについて確認する。
      やはり微妙に遅い様な気がする。

    何が遅くなっている原因化について確認する必要がある。
    例えば fork している可能性はあるだろうか。

2021-01-08

  * syntax: 算術式の quote が変である

    x echo $((a['$hello'])) の $hello は展開対象なのに着色されない。
      →然しこれは文法上の問題なので寧ろ着色しない方が自然である様に思われる。
      (これは eval の引数を着色するのかという問題にも通じる)

    x ((a["$index"])) がエラー着色になっている
      →どうもこれは bash-5.0 から振る舞いが変わったという事の様である。

    x bash-5.1 からは (()) でも ' は quote ではない。

    x 更に言うと a['...'] の ' は a が連想配列の時には必ずしもエラーではない。
      現在はエラー着色になっているがこれは修正するべきの気がする。

2020-12-19

  * Note (#D1435): blehook WINCH を処理している最中に終了したユーザのジョブがあ
    るとその通知が画面に表示されない可能性がある。これは実際に起こりうるのかど
    うか確認していない。

2020-12-14

  * progcomp: progcomp で生成された補完候補を現在 quote している。

    * 生成された候補が既に quote されている場合や展開を含む場合に、
      意図したのと異なる結果になってしまう問題がある。
    * 更に既に入力済みの部分に一致しなくなるので遡って書き換わる可能性もある。
    * 生成された候補が複数の単語に分かれる場合に、
      それが blesh の quote によって一つに結合されてしまう問題もある。

    理想的には生成された候補を改めて simple-word/eval して、
    その結果に基づいて単語を再度挿入し直すという事が考えられるが、
    x 全ての候補に対してこれを実行する事を考えると処理が重くなってしまう。
    x また、\**\* 等を展開すると *** になってしまうので
      その quote を復元する方法についてもちゃんと考えなければならない。

    或いは simple-word element を一つずつ抽出して処理すれば良いのかもしれない。

2020-11-30

  * tui: face editor の TUI の様な物を作っても良いのかもしれない [#T0007]
    というより fish の Web interface の様な物を TUI で提供しても良いのでは。

    2021-04-25 @Alyetama から似たような提案を受けた。
    https://github.com/akinomyoga/ble.sh/issues/80#issuecomment-826194833これは
    初期設定 wizard の様な物を想定している様だが、TUI config ではもっと自由にい
    つでもどの設定でも選んで設定できるのでより自由度は高い。そう言った物でも良
    いかという事を一応確認はしてみる。

    作るとしたら先ずは Color Picker?
    その前に layout engine? 或いは画面の切り替え?

    Window system がどうのこうのという計画があったような。window system に関し
    ては内部バッファだとかスクロールだとか textarea だとか様々の物を内包する物
    であった筈で、此処で必要になる物は其処まで複雑な物ではない。でも一緒に実装
    してしまっても良い様な気もする。

    - Windows system に必要な物。control, window, layout-engine,
      background-buffer, redraw, resize, etc.

      既にある panel, textarea 等を拡張する感じに考えても良いのかもしれない。但
      し、これ以上の ble.sh の肥大化を避ける為に canvas ではなくて新しく
      lib/core-forms.sh 的な物を追加して其処で実装するのが良いのではないか。
      textarea に関しては、forms が或る程度形になってから対応するという形で良い
      気がする。

      control に属する変数の記録方法? これは textarea と同様にしたいが、
      textarea の方も forms に対応しようとすると調整が必要になると考えられるの
      で、最初は既存の枠組みに捕われずに実装するので良い気がする。

    - window: overlay を実現する方法として二つの可能性が考えられる。

      a redraw 関数の方で clip 等を処理する方法。

        これは各 control の実装が複雑になってしまう。というより任意の clip
        region の形状に対応しようとしたら非現実的な実装になってしまう。

      b もう一つは Window の側で buffer を内部に保持し、最終的な描画の際にそれ
        を適当に clip して出力する方法。

        これに関しては内部 buffer の表現方法に工夫が必要になる。

    取り敢えず何も考えず少し実装してみた。clip に関しては redraw の側で適当に処
    理する事にした。また、trace に於いても clip 機能を実装した (#D1493)

    invalidate 範囲を記録できる様にしたい。

    更に、要素のサイズが変更された時、移動した時には親の該当範囲も一緒に
    invalidate する必要がある。


    自身の内容が変化した時、自身に被っている別の要素も一緒に更新する必要が出て
    くる事に注意する。

    a 上に物が被っていない時には clip 領域を勝手に広げて描画しても良いのではな
      いか。描画範囲を広げても良いかどうかについては render.draw の呼び出し元か
      ら指定できる様にすると良いのかもしれない。

    c 或いは、そもそも被らない様にするか、被っている時には更新しない様にすると
      いう手もある。

    d 或いは、render.draw の呼び出し元で一旦シーケンスを取り出して、その上でそ
      れを再度 trace によって clip するという手もあるかもしれない。然し、これは
      描画内容が大量にある場合にとても遅いので実は避けたい。

2020-11-20

  * bash: declare -c や ${var~} 等は 5.2 で削除するとしているが本当だろうか

2020-11-13

  * complete: bash progcomp と ble.sh progcomp の競合問題

    現在は complete:* の方が builtin complete の設定よりも優先される様になって
    いる。これは ble.sh がロードされていない時はbash-completion を使い、ロード
    されている時は ble.sh 様に特化した補完設定を使うという状況を考えると自然で
    ある。

    然し一方でユーザーが自分の好きな設定を builtin complete で設定してもそれが
    反映されないという問題が生じる。やはり builtin complete の方を優先させるべ
    きだろうか。或いは、complete:cd は既定ではロードしない様にして、contrib か
    何かに入れてユーザにロードさせる様にするのが良いのではないかという気もする。
    然し、ユーザにロードさせるとしてもコマンドを一つ一つロードするのではなくて、
    まとめてロードするという状況も考えられる。その場合には、やはり builtin
    complete と complete:* の競合が起こってしまいどちらを優先させたら良いのか分
    からなくなる。

    或いは ble.sh に特化した設定も builtin complete 経由で呼び出す様にする?
    しかしそうすると ble.sh から ble-detach した時に動作しなくなってしまう。

    attach/detach の際に設定を保存・復元するという方向性も考えられる。

    complete を上書きして両方の設定を行える様にするという手もある。この場合には
    attach/detach する時に既に設定した内容を読み取る等の工夫が必要になる?

2020-11-11

  * syntax: $HOME 等の変数展開があるパスに対して simple-word/eval が重い問題

    中でグローバル変数の復元等の複雑な処理をしている。一回呼び出すだけならば良い
    が $HOME/.mwg/src/ble.sh/archive/layers ... 等の様なパスの着色で各ディレクト
    リの階層で展開を試みている場合に、何度も呼び出す事になると遅さがかなり目立つ
    ようになる。

    単語着色では determine-separated-path -> locate-filename ->
    highlight-pathspec という具合に三段で処理していて各段で毎回 eval しているの
    で特に重い。これは処理を統合して高速化する余地もある。コードが汚くなるという
    問題はある。よく考えたら現在の実装では locate-filename は特に eval は実施し
    ていない。単に : で区切っているだけである。なので locate-filename に関しては
    気にしなくても良い。

    或いは複数のパスを一度に eval する機能があっても良いのかもしれない。その場合
    に結果をどの様に返すのかは難しい。複数単語に展開される事を考えて既に一つの
    eval の時点で ret が配列だからである。各パスの最初の単語だけを返す事にするか、
    或いは全ての単語を全部混ぜて一つの配列に返すか。一つの配列に格納する場合には
    各パスに対応する index の範囲を返す事ができるがインターフェイスとしては分か
    りにくい。

  * bashbug: builtin で while という名前の builtin を load すると他の builtin が
    使えなくなる。

    ? 使えなくなるのは、同じ dll の中の物のみなのか或いは全ての dll の loadable
      builtin が使えなくなるのか。

    ? while 以外にも問題を起こす名前は存在するか。

    ? 影響を受ける builtin はキーワードと一致する名前の物のみか或いは全てか。

2020-11-07

  * complete: PATH=path1:path2:path3 の補完

    PATH=path1:path2:path3 の時に着色が最後の要素にしか適用されないし、また補完
    は全然働かない。全く動かないのならばまだしも中途半端に動くのは変なのでちゃん
    と対応したい。

    →着色に関しては #D1409 で議論する。

    complete に関しては元の bash ではちゃんと動いているので尚の事問題である。

  * highlight: 条件コマンドの中での着色が効かない。着色しても良いのではないだろうか。
    今まで実装していなかったのは正しい文法解析や入れ子などの処理が面倒だったから。

    今確認してみると 条件コマンドの中でも ( && || ) などは特別な意味を持つ様であ
    る。更に & や | を使うとエラーになる。<< 等のリダイレクトもエラーである。必
    ずしも空白で単語が区切られる訳ではない様なので、これに関しては文法解釈のレベ
    ルで修正が必要になる。

    今試すと ; も途中に現れると区切りとして取り扱われてエラーになる。

    * |&;<>() は特別に取り扱う必要があるという事。単体の < と > に関しても正し
      い演算子の文脈に現れれば大丈夫だが、二項演算子の現れない場所で使うと構文
      エラーになる。この様な構文エラーまでチェックする必要があるだろうか。或い
      は演算子の結合まではチェックしない事にするか。

    * 括弧の途中で ]] が現れた場合にもエラーになる。

2020-11-06

  * complete/mandb: progcomp で生成したオプションに関してもできれば desc を表示する様にしたい。
    progcomp に候補を生成させてもしオプションが含まれていて、
    かつそれが mandb の中に含まれているという事が分かった時に desc-raw を表示する。

    * git 等の場合には man git で得られるオプションと
      サブコマンドで得られるオプションは異なるので注意する。

  * complete/mandb: bash の場合にはビルトインコマンドのオプションまで混ざって列
    挙されてしまって駄目。bash 固有のオプションについてまとめたファイルを用意し
    ておくべきである。

    bash builtins のオプションに関しては builtin ... --help を使用すれば取得でき
    る。これはこれでまた解析の為のコードを書かなければならないが、bash の
    builtin に限れば形式が定まっているので解析のコードを書くのは難しくはない。

  * complete/mandb: 何と man git は .PP ... .RE 4 ... .RS でオプションを説明している。
    この様に .TP を用いない様な場合にも対応するべきなのだろうか。

  * complete/mandb: 同じ意味を持つオプションについて。
    同じ意味を持つ複数のオプションを分ける時に、
    分けてから sort するのではなくて sort してから分けるべきではないか。
    同じ意味を持つオプションは連続されて表示されて欲しい。

2020-09-07

  * complete: メニュー絞り込みが働いている状態で単一確定ができない場合がある

2020-09-03

  * main: attach 戦略再考 [#T0004]

    attach の戦略に関する議論は以下にある。
      #D1382, #D1124, #D0940, #D0737

    | a 即attach。PS1 表示
    |   x PS1 が後で変更された時に問題。
    |   x 後の設定の出力が消滅する
    |
    | b 即attach。PS1表示はする。出力抑制はしない
    |   x PS1 が後で変更された時に問題。
    |   x 後の設定の出力と混ざる
    |
    | c 即attach。PS1表示はpromptまで遅延
    |   x keymap初期化に時間がかかる
    |
    | d 即attach。PS1表示する。出力は記録して後でdump
    |   x 後の設定が対話的なインターフェイスを起動した時に問題
    |   x 後の設定が /dev/tty に対して出力したら防げない
    |   x 後の設定が初期化進捗などを出力するとそれが実時間で反映されない
    |
    | e PROMPT_COMMAND。trap DEBUG/RETURN を用いて変更検知
    |   関連: #D1124, #D0737
    |   x DEBUG はコマンド直前の実行なので最終行での書き換えは防げない
    |   x RETURN は rcfile 末尾では発生しない
    |
    | f PROMPT_COMMAND の読み書きを hook する(非ネイティブな)手法はあるか?
    |   x ない
    |
    | g 他の hook/trap を用いて適切なタイミングを検出?
    |
    |   a EXIT はシェルが終了する時なので使えない
    |   b command_not_found も使えない
    |   c kill -USR2 $$ によるハンドラは?
    |     x 試すと rcfile 終了を待たずに次のコマンドですぐに実行される
    |     x kill ... & として別プロセスから投稿しても同様
    |   d bash (execute_prompt_command) を確認したが介入点は他になさそう
    |   e PS1 に kill 等を埋め込んで通知させる
    |     x これは PROMPT_COMMAND よりも信頼できない
    |
    | h PROMPT_COMMAND の中の最初のコマンドを DEBUG で検出?

    可能性があるとすれば h の手法である

    * trap DEBUG/RETURN の性質を熟知していないとユーザの設定した
      DEBUG/RETURN と干渉しない様にするのは難しいと考えられる。
      これは DEBUG/RETURN の枠組みを整えてからにする必要がある。

    rcfile で ble.sh をロードした時には rcfile を抜けた後の
    PROMPT_COMMAND 直前でアタッチを行う。

    * "PROMPT_COMMAND の最初のコマンド" は恐らく判定可能である。

      rcfile 及び最初の PROMPT_COMMAND 内にいる時は BASH_LINENO の最後の
      要素は0 になっている。rcfile 内にいる時は FUNCNAME の最後の要素は
      "source" になっている。更に bash-4.4 以降では rcfile から
      PROMPT_COMMAND に移る時に $- に s が追加される。

      PROMPT_COMMAND で何か実行するならば、最初のコマンドは必ず
      FUNCNAME[-1] != source になっている筈である。

    対話シェルで ble.sh をロードした時は "bashrc を抜けた直後" という戦
    略は使えないが、HISTCMD, ${_histcmd@P} を用いてユーザコマンドか
    PROMPT_COMMAND かの判定が可能である。

    * HISTCMD は ユーザコマンドを実行している時には $(history 1) の最初
      の要素に一致する。PROMPT_COMMAND を実行している時には常に 1 になる。

    * HISTCMD が unset されている場合には代わりに _histcmd='\!';
      "${_histcmd@P}" が使える (bash 4.4)。HISTCMD が unset されているか
      どうかは HISTCMD=A して値が変化するかどうかで判定できる。

2020-08-27

  * 真面目に宣伝など考えるべきなのかもしれない。

2020-08-03

  * README: bashrc 設定方法の更新
    関連: #D1382, #T0004

    最終的には bashrc の何処に ble.sh を記述しても動くようにしたい。取
    り敢えず、比較的信頼できる手法が確立するまでは README の load 方法
    はそのままにしておく。

  * macOS で遅いという話 (reported by tigger04)
    https://github.com/akinomyoga/ble.sh/issues/58

    チェック項目は…

    * complete -r の代わりに
      shopt -u progcomp を指定したら改善するか?

    問題になっている可能性がある処理は
    ble/complete/progcomp/.compgen の builtin compgen 経由で呼び出される。
    特にユーザの定義した関数・コマンドは以下の関数経由で呼び出される。
    - ble/complete/progcomp/.compgen-helper-func
    - ble/complete/progcomp/.compgen-helper-prog

    上記の関数に benchmark を設定して stackdump なり何なりを計測する?

    ble/function#advice \
      around ble/complete/progcomp/.compgen-helper-prog \
      ''

    * 対策としては auto_complete の時には progcomp を実行しない
      というオプションを追加するというのが一つの可能性。
      bleopt complete_auto_progcomp=1 という事にするのが良い。

      実現可能性について。
      現在の呼び出し文脈が auto_complete かどうかを判定する必要がある。
      確認してみると comp_type に auto を含めている様である。
      実際にそうなっているのか確認する。

    情報をメールで貰った。
    メールではどの期間だけ complete -r を除いていたか分からないとしているが。

    2020-08-05 05:12:50 IST
    2020-08-05 05:13:27 IST
    2020-08-05 08:43:54 IST
    2020-08-05 08:43:57 IST
    2020-08-05 11:02:53 IST

    まあ、どの期間だけ有効になっていたのかという情報は実はそんなに重要ではない。

    眺めていて気づいた事。

    最後にユーザが入力を行ってから auto-complete が起動するまでに一定の時間がかかっている。
    大体 200ms の様な気がするが、しかし時間帯によって変わっている気もする。
    TAB 補完の場合にはこの delay が存在していない (0.06s) 事を考えると、
    これは history 補完にかかる時間という事だろうか。
    history 補完を無効にしたらこの delay は少なくなると判断して良いだろうか。

    補完が走らずに入力できている部分は history に match している入力であろう。

    どうも後半で時間がかかっているのは history の様に思われる。
    TAB 補完の時には 150ms 程度の遅延だが自動補完の時には 600ms に増えている。
    然し、その後で 200ms 程度に減少したりもしている。
    うーん。或いは単語の展開に時間がかかっているのかもしれない。

    * reject: 取り敢えず history 展開について高速化できないか確認する。

      | search-history-heavy について改善できないか考える。
      |
      | a 特に bash-5.0 以降では history -d range を用いて削除した上で
      |   history -p を実行すれば高速に過去の履歴を読み出す事ができるのではないか。
      |   →と思ったがよく考えたらどの範囲を削除したら良いのか不明である。
      |
      |   !string で一致させてその後その候補が当て嵌まらないと分かったとする。
      |   この時その候補以降の履歴項目を全て削除してから再度 !string で
      |   一致させれば良い様に思うが、最初に一致した候補が何番目の履歴項目か
      |   という情報がないのでどの範囲を削除したら良いのかが分からない。
      |
      |   a 例えば二分法で探索する? と思ったがこれだと二分の一の確率で
      |     サブシェルを生成しなければならない。明らかに非効率的である。
      |     或いは履歴展開に履歴番号も一緒に展開させる方法があったろうか。
      |     ない気がする。
      |   b やはり履歴番号を抽出できないかと思ったが、その様な履歴展開はやはりない。
      |     !string で一致させて単語指示子で履歴番号に置換できれば良かったが
      |     その様な単語指示子は存在しない。
      |   c 或いは、番号を指定しなくても一致した項目以降を削除する方法があれば良い?
      |     然し、history -d の引数はやはり数値であって履歴展開ではない。
      |
      |   この方針は難しいのではないかと思われる。
      |
      | b 或いは、history | grep を用いて最後に一致した項目を取り出す事ができるのではないか。
      |   但し、grep の時の問題は行区切りをどうするのかという事。
      |
      |   grep -z を用いれば NUL 区切りで判定する事が可能。
      |   然し、これは GNU extension である。安易には使えない。

      →うーん。調べてみたがちゃんと history search を呼び出す時に
      stop_check を指定しているのでユーザの入力があった瞬間に復帰する筈である。
      つまりこれ自体に時間がかかっていたとしても動きが遅くなる事はない筈?

      そもそも complete -r で解決したという事を考えると明らかに history は関係ない。

      然し、実際に timing log を見るとユーザの入力が待機されている…という事はない様な気がする。
      やはり現在の情報では history からの自動補完が問題になっていると考える根拠がない。
      従って、(不自然な方法を取ってでも) history 展開の高速化方法について考えるのは不毛である。

    * 再び報告があった。コンピュータ自体の処理が重くなっている時に動かなくなるという事らしい。
      普通に bash を動かしている時には問題ないという事を考えるとファイルアクセスが怪しい。
      ファイルアクセスしている箇所は沢山ある。特に着色のためのパス名展開である。

2020-06-04

  * 行数が極端に少ない時の動作 (横スクロール)
    bash-5.1 では横スクロールモードに移行するそうだ。

    そもそも現状で一行しか使える行がない時に何が起こるか。
    実際に試してみると (line 1) という表示だけになって
    更にその上に何か表示しようとするのでまともに表示できない。
    2行の場合にもまともに動かない。vi-mode の mode name で 1 行消費している為である。
    3行の場合にようやくまともに動く様になるが、それでも vbell が上に被ってしまう。

    横スクロールまで実装しないとしてもまともに動作する様にはしたい。
    そもそも (line N) という表示を省略する様にする?
    現状の実装ではプロンプトは必ず表示する様になっている。
    然し、プロンプトを表示するからこそ変な事になっているのである。

    a 行数が 1 になった時にはそもそもプロンプトを表示しない?
      然し、それだとプロンプトが何も表示されなくなってしまってそれはそれで変だ。

    b プロンプトは固定で残りの部分で文字列を編集する?
      これだとプロンプトが画面よりも長い時に何もできなくなる。

    c プロンプトも一緒に横スクロールする?

      | これに対応する為にはプロンプトの内部の各文字の配置を追跡する必要
      | が出てくる。
      |
      | Bash native でも \[...\] を使っている場合にどうやって数えるのだ
      | ろう? という疑問が残る。
      | →bash の動作を見たところ、prompt も一緒にスクロールする。しかし
      | prompt の途中位置でスクロールが止まる事はない。つまり、prompt は
      | 全体が表示されるか全く表示されないかのどちらかである。
      | →prompt 自体の長さが画面の横幅よりも大きい時には、常に横スクロー
      | ルした状態になってしまい、コマンドの1文字目は常に '<' に隠れて表
      | 示されない状態になる。また表示の乱れも発生する。

      Bash は横スクロールによってプロンプトが表示されるか、全く表示さ
      れないかのどちらかの状態になる。中途半端にプロンプトが表示されて
      いる状態はない。プロンプトの長さが画面の長さよりも大きい場合は対
      応しきれていない。

    * プロンプトが範囲内に収まらない場合には何が起こるのか?
      プロンプトの trace の時に高さを制限していただろうか。
      →駄目。制限はしていない。そもそも制限する事自体が自然な動作なのかも分からない。
      リサイズした時に上に流れた情報を参照したいという場合を考えれば、
      プロンプトは制限せずに上に流れてしまうという振る舞いが自然の気がする。

    現在のスクロールの実装はプロンプト行の次以降で実施する前提になっている。
    つまり画面の高さが1行しかない場合には色々弄らなければならない。
    プロンプトが複数行ある場合にはそれだけ多く画面の高さが必要になる。

    * プロンプトの出力は気にせずに実施する。画面がスクロールしても気にしない。
      →これを実行するとその他の panel の描画位置もずれてしまう事になる。
      他のpanelの内容を上書きしないように事前に空行を挿入しようにも、
      空行を挿入した時点で他の panel の内容が反対側の端から流れてしまう。
      という事を考えると、行数が厳しい時には他の panel は全て潰すのが現実的。

      潰す条件がプロンプトの高さが一行に収まりきらない場合、というのは
      プロンプトとして変な物を指定する場合を考えると制限が強い気もするが、
      その様な場合は余りないと考えればそれでも良い気もする。

      因みにプロンプトの高さが1行に収まらない状況としては、
      プロンプト自体に改行が含まれている場合以外にも、
      プロンプト内に長い文字列が含まれていて何度も折り返す場合を含む。

  * util: ble/dict#* を用意する可能性?

    設定ファイルの自動アップデートの実装に関連して
    ble/dict#* という物を作成しても良いのかもしれないとも思う。
    既に辞書的な構造は ble.sh の各所で個別に実装して使用している。

    辞書の bash-4.0 未満における最適の実装は何だろうか。
    任意の key を取り扱える様にする必要性を考えると、
    : 等を区切りにして scalar に key を格納する訳には行かない。
    そうすると配列に key を格納する必要が出てくる。
    配列が巨大になってくると重くなってくる。

    a 簡単な hash を作るという手もあるだろうか?
      例えば配列サイズが小さい時には最初のバイトだけを使って、
      要素が増えてきたら n 番目のバイトまで使って hash を生成する。
      と思ったがそれだと共通の接頭辞を持つ key が沢山ある時に hash が衝突する。
      例えば /home/murase/... という物が沢山ある場合。

    b 或いは全ての文字を用いて hash を計算する?
      という事にすると今度は長い文字列に対して各文字について文字コードを取得する手間がかかる。
      特に bash-4.0 未満では色々面倒な事をする。何れにしても ble/util/assign を使うので遅い。
      (実際にこれでキャッシュをしていないのは下手にキャッシュするよりも ble/util/assign
      を実行した方が高速であるという事からであろうという気がする。)

    c key の sorted list を管理する。
      文字列で辞書順でどちらが速いかについては [[ str < str ]] で判定できる。
      後はアクセスの度に二分探索を実施すれば良いのである。
      挿入には結構時間がかかりそうな気もするが、まあ、大丈夫。
      然し、よく考えたら bash-4.0 未満の配列はアクセスが線形時間だった気がする。
      という事を考えると二分探索よりも線形探索の方が実は良いのかもしれない。

    使用ケースによって色々なので汎用的な実装はやはり難しい気がする。

    * key が整数の場合には普通に配列を使えば良い。

    * key が有限の単語 (識別子) の集合であれば、
      local apple=1 banana=2 pineapple=3 orange=4 等の様にして、
      普通に arr[apple]=red 等とという風にすれば良い。

      或いは普通に変数に保存すれば良い。
      eval "arr_$key=red" という具合である。
      この場合大量の変数が散らかってしまうが、
      それが気にならなければ最良の気がする。

    * key に ":" が含まれない場合には
      keys にコロン区切りの key の集合を保存しておいて、
      head=${keys%%:$key:*} head=${head//[!:]} 等とすれば
      key が何番目の要素であるかというのを取得する事ができる。

    * key が文字である場合も同様にして
      head=${keys##"$key"*} 等としてから ${#head} で文字数を見れば
      それが何番目の要素であるかというのを判定する事ができる。

    * 辞書をメモ化に用いている場合には実は関数自体の計算時間が
      bash による辞書の模倣よりも速い可能性を考えるべき。
      例えば ble/util/s2c については ble/util/assign printf %d '$c の方が
      下手な辞書よりも高速なのである。

    * key の種類がそんなに沢山でない場合には、
      key を配列に格納して線形探索するというので良い。
      これが最も単純で自然な実装になる。

      key を sorted list に入れて二分探索するという可能性もあるが、
      Bash-4.0 未満の配列のランダムアクセスは線形なので、
      それよりは普通に線形探索で舐めた方が良い気がする (実測すると違うかもしれない)。

    結局使用ケースによって最適な実装方法が異なるという事から統合は難しい。
    ble.sh の内部で使わない以上は用意しても仕方がない様に思われる。
    そもそも ble/dict#... の形式による配列アクセスは文法的にそんなに綺麗でもない。
    等の事を色々考えると、ユーザの為に用意する程でもない。

2020-05-20

  * 破壊的変更と後方互換性

    * done: keymap_vi_nmap_name は keymap_vi_mode_nmap_string 等に改名するかもしれない。
      或いはもっと別の名前? やはり keymap_vi_mode_normal で良いだろうか。
      改名するとしたら complete_stdin_frequency と同様に別名に書き換える様にする。
      実はオプションの改名について枠組みにしてしまっても良いのかもしれないという気がする。

    * 勝手に古い設定を書き換える機能を作っても良いかもしれない。
      毎回一行ずつ書き換えを実行するのではなくて、
      書き換えを実行する sed スクリプトを貯めておいて、一括で書き換えを実行する。
      cp a a.bk && sed "$script" a.bk > a 等の様に実行する。

      sed スクリプトは何処に貯めて於けば良いのだろうか。
      書き換え対象のファイル名と一対一に対応するファイル名にする必要がある。

      a 辞書にファイル名を記録するか或いは hash を用意するか。
        hash は計算に時間がかかるので辞書にファイル名を記録するのが良い気がする。
        然し、bash-4.0 未満ではどの様にするのが良いのか微妙である。

      b 或いは、別に辞書など作らなくても直接ファイルシステム上に書き出しても良い気がする。
        つまり、 "$file.sed" に書き出して置いて、それを適用して削除する。という具合にする。
        問題はファイル名が被らない様にするという事。乱数で決定する事にすると駄目。
        "$file.__BLE_REWRITE__.sed" 的なファイル名にするのが良いのではないか。

    * ble{-edit => }/prompt/{print,process-prompt-string,backslash} についても
      警告を表示する様にする仕組みが必要になる気がする。

2020-05-16

  * TERM=alacritty で何か変な事が起きるらしい。
    https://github.com/rux616/init/commit/b03e7ef3dab5171d1f60aa61323ef823401217d5#diff-0af95dc8119f1c458b7a0fd76dfe8042R37-R39

    調べてみると alacritty:extra/alacritty.info が terminfo らしい。tic -x extra/alacritty.info で入れる。
    然し、何も問題は起きていない様に見える。256color もちゃんと動いている。ずっと使っていると発生する問題だろうか。
    これは時間があれば rux616 に何が起こるのか尋ねても良い。
    所で、いつの間にかに alacritty は jwilm/alacritty から alacritty/alacritty に移動したらしい。

    →cache/alacritty.term を確認した所 ich, ech, dch が空になっている。
    然し、ble.sh は ich, dch は使っていない。ech を使う場合でも、
    [[ $_ble_term_ech ]] の時にのみ有効になる様になっている。

    他に気付いたのは 8-15 の着色が 0-7 と同じになっているという事。
    然し実際に tput で tput setaf 15 とすると CSI 9 7 m になる。
    何かが間違っている。再度実行してみた所、問題なく初期化された。
    と思ったら alacritty.term と xterm-256color.term の内容が同一になった変だ。

    続けて何度試しても問題は発生しない。何が起こったかは謎である。

2020-04-25

  * trap: DEBUG trap を用いて DEBUG trap を再現できるか? [#T0003]
    参考: #M0016

    つまり関数呼び出し毎に DEBUG trap が設定されるというのを実装する必要がある。
    ble.sh が使っていなければ特に問題は発生しないが、
    INT を受信した時に ble.sh が DEBUG trap を設置する事になっている。
    従って、実装できれば実装するのが良いという様に考える。

    要件は以下の通り

    * 何も DEBUG trap が設定されていない時には overhead 0 にする。
      つまり builtin trap で何も設定されていない状態にする。
      ユーザか ble.sh のどちらかが何か設定している時に有効にする。

      実のところ、ble.sh の使い方は一時的な物なのでユーザの trap と
      同レベルの取り扱いで良いという気がする。唯単に trap で列挙されない、
      ユーザの設定した trap も保持する、という事が異なるだけ。

    * 関数呼び出しでの継承・非継承を再現する。
      実はこれはそのまま bash の継承・非継承に従うだけで良い気がする。

    * 呼び出し元への影響についても再現する。
      これは新しく trap DEBUG が呼び出される時に、
      builtin trap DEBUG もやり直せば良い?
      と思ったがそもそもそんな事をする必要もない気がする。
      現在のフレームに既に何か設定してあるという事は
      呼び出し元ではそれが必ず有効という事だから。

      bash-4.3 以下では何れにしても呼び出し元に影響を与える事はできない。
      うーん。bash-4.3 以下では trap DEBUG で保存した trap handler を
      関数が抜ける時に削除する必要があるという気もする。
      これについては実装時に注意深く実装すれば良いだけ。

    * DEBUG trap の中で DEBUG trap は設定できるが発火しない。
      BASH_COMMAND は書き換わらない。

    実の所、DEBUG は C-c の時にしか設定していないので、
    取り敢えず気にしない事にする。

    先ず試験的な実装を作成して見るのが良い気がする。

  * trap: INT
    現在の実装ではユーザの設定した INT で握りつぶしても、
    ble.sh の設定したハンドラによって実行が中断される。
    ユーザが INT を設定している時には握りつぶさない様にするという手もある。

  * [保留] bash-4.4 trap 内無引数 return の修正

    ref #D1350

    bash-4.4 以降では trap 内の無引数 return は trap handler が開始する直前の $? を返す。
    強制的に trap handler の内部での直前の $? を返す様にする方法はあるだろうか。

    * return() { builtin return $?; } とする案
      x 本来の return を実行する方法がない。
        RETURN trap を使って return 関数呼び出し後に builtin return できないか?
        x RETURN trap は抑も終了しようとしている関数内の文脈で実行される。
        x RETURN trap 内部では RETURN は発火しない。
    * alias return で何とか無引数の場合を $? に置き換える事は可能か。
      x 引数がある場合とない場合の両方に alias で対応するのは難しそう。

2020-04-19

  * history: 履歴の管理の枠組みで欲しい物

    1 実行したコマンドを追記で記録する仕組み (勝手に編集したりしない)
      他のシェルと同様に追加の情報も記録する?

      * 実行したディレクトリ。実行した時刻。$$.$LINENO

      * コマンドラインに含まれる有効なファイルパスの集合

        | fish はこの情報を用いて history autosuggestions の時に
        | コマンド履歴のフィルタリングを実行する様だ。
        | 然し疑問なのは echo > a.txt で a.txt など出力ファイルが元から存在していた時には、
        | 新しくファイルを作成したいという時にその履歴が候補に出てこない、
        | という事態になってしまうのではないかという事。
        |
        | その様に考えるとやはり実は個別のコマンド毎に判定した方が良いのではないか。
        | 例えば cd の場合には使い方が決まっているので、
        | 実際にそのコマンドラインを実行した時に成功するか失敗するかはすぐに判定できる。

        自動補完のフィルタリングに関しては完全な判定はできないので
        取り敢えず core でサポートしなくても良い。

      * zsh は実行にかかった時間も記録する様である。

        | 然し、これは微妙。何故ならば bash ではコマンドの実行開始前に履歴を追加するから。
        | 実行後に書き換える仕組みが必要になる。或いは開始の記録と終了の記録を別々にする?
        | そうすると複数のセッションで実行している時に互い違いになってしまう。
        | なので実行するコマンド毎に ID を設定する必要がある気がする。
        | と思ったが ID は $$.$LINENO 等で良い気がする?
        | x と思ったが同じ PID でシェルが起動する事もあるのでは?
        |   o と思ったが同じ PID で複数のコマンドを同時に走らせるという事はないので問題ない。

        開始と終了をそれぞれ記録する。$$.$LINNO でコマンド毎に ID を設定して対応を取る。

    2 記録されたコマンドとは別に bash の履歴で遡れるコマンドのリストを管理する仕組み。
      こちらは長いコマンドを自由に削除したりできる様にする。
      倍加したりすると嫌なので枠組み 1 で得た差分に基づいて更新する?
      差分を取る方法を気をつけないと結局倍加するので、
      ちゃんと同期して差分を取れる様な枠組みを整理する。

2020-04-09

  * 別の bash の枠組みについて
    https://github.com/sio/bash-complete-partial-path
    https://github.com/mgalgs/fuzzy_bash_completion
    https://github.com/brujoand/sbp

2020-04-02

  * test: テストフレームワークの追加機能

    * 単体テストの機能
      * テストを直接本体の関数の近くに書き込める様にする?
        これは mwg_pp.awk の枠組みを用いた対応が必要である。というか出力
        先が ble.osh と分かれている場合を考えると、#%$> の右辺に変数を指
        定するべき? と思ったが #%$> を含む行自体をマクロに入れれば良い。

    * テスト集合の管理
      * 集計・サブシェルで実行した結果も扱える様に。
      * テスト結果のキャッシュ
      * 並列テスト
      * 様々な bash の version の結果を集計

    * 他のフレームワークの機能を確認
      * bats
      * oil/test
      * shellspec
        kcov を用いて coverage が計測できる
        skip を設定できる。前回成功したものをスキップできる。

    * GitHub 用に Travis を設定する。

2020-03-22

  * read -t や read line の戻り値が変だ
    →今試してみると別に変な事はない。-e が入っていても入っていなくても。

    一応 C-c で read -e を止めた時の終了ステータスは 130 の所が
    ble.sh の実装では単に 1 になっているという違いはある。

  * bash-3.0 が malloc array.c botched というエラーが出てクラッシュした。
    これは bash のバグである。そして古いバグなので治りそうにない。
    更に言うと再現性もあるのかどうか微妙である。

  * oilshell で色々説明を行った。
    それらの説明へのリンクを作成して後で纏めるのが良い気がする。
    これは後で実行する。

  * decode: 大量の貼り付けの高速化4 (report by dylankb)

    現状の ble.sh の枠組みの中では大幅に改善した。
    然し、やはり decode を自前でやっている。
    そもそも decode の結果を整数の列にする時点で遅い。

    bracketed paste だと分かった時点で、
    stdin から文字列として読み取って、
    文字列としてそのまま挿入する等の事が可能な筈なのではないか。
    そうすれば無駄な処理をする事なく即座にエディタを起動できる。

    現在の nonblocking-read の実装に
    bracketed paste を検出する機能をつけて
    bracketed paste の処理中にはそれを使って
    良い感じに実行すれば良いのだろうか。

2020-03-11

  * __line_limit__ の実装の制限

    1 replace-limited を直接呼び出している箇所については確認したが、
      replace-limited が .replace-range を通して呼び出している時、
      外側で ind, mark を設定していると計算がずれて範囲外になる可能性がある。
      特に vi で .replace-range を多用しているが面倒なので細かくチェックしていない。

    2 容量超過でもコマンドラインが短縮されていない場合
      (これは isearch の途中などで起こりうる)
      複数のキーから為るキーシーケンスが間に入る __line_limit__
      によって無効化される。

      これの対処方法として mouse_move と同様に特別に
      __line_limit__ を keyseq に属さないキーとして取り扱う方法がある。
      然し、現在ではチェックが非効率になるので対応していない。
      或いは keyseq に属さない keycode の範囲を定義して、
      その範囲で判定できる様にするのが良い気がする。
      (その様なキーは実は沢山ある)

  * history: fish の autosuggestions はファイルが存在しない履歴項目はスキップする (suggested by cole-h)
    https://oilshell.zulipchat.com/#narrow/stream/121540-oil-discuss/topic/autosuggestions

    うーん。どうやら fish は履歴を保存する時にその時に使った有効なパスも一緒に記録する様だ。
    Bash はそれを記録しない。という事は ble.sh が代わりに記録する等の工夫をする必要がある。
    然し、ble.sh が代わりに記録するという事になると履歴の一貫性を保つ為に工夫が必要になる。
    或いは、ble.sh の履歴を本体として bash の history は全部それを元に再構築する?
    その様にするしかない気がする。

    或いは cmdinfo:color の実装が完全であれば、わざわざ履歴を見て
    ファイルパスかどうかを判定しなくても、それが有効な履歴かどうかを判定する事が
    可能になる。特に cd に関しては簡単に判定する事ができる筈である。
    という事を考えるとわざわざ実装する必要はないのかもしれないとも思う。

2020-02-02

  * vi mode の時は read も vi mode になっているべきではないのか?
    と思ったが vi mode にはコマンド実行等の色々と
    危ない機能も沢山ついているので、寧ろ cmap を使うべきで、
    然し、cmap を使うのだとしたらそれは殆ど現状の read の様な物だ。

    これはその内に request があるかもしれない。その時に対応する。

    と思ったが既定の readline では vi-map が使える様になっている。
    コマンド実行等はどの keymap に定義されているだろうか。
    或いは accept-line や edit-and-execute-command の意味を差し替えられる様にするか。
    そちらの方が現実的である様な気がする。

2020-01-26

  * progcolor: 非同期で実行できる様にする可能性?
    場合によっては重い計算が必要になるかもしれないし、
    実は非同期で実行しても良いのではないかという事。

  * progcolor: redirect の場合にも対応したい
    実は補完の時にも redirect をプログラム補完しても良いのでは。
    但し、補完と着色で違うのは補完は一つの単語について呼び出されるのに対して、
    着色は一度に複数の単語を着色する事があるという事。
    補完に関しては引数とリダイレクトを別々に処理すれば良いが、
    着色の場合には一度に処理できる様にしたい。

  * progcolor: here document にも対応したい。
    here document に対応するコマンドを抽出する事は可能か?
    →here document は開始部分に対する参照を確か持っていたのでできる筈。

    実際にユーザは何を提供すれば良いのか。
    ble/cmdinfo/color:XXX を呼び出す様にするのか。
    然し、それだとそのコマンドの引数が変更される度に、
    対応する heredoc を抽出する必要が出てくる。それは面倒だ。
    或いは、heredoc に変更があった時に着色するだけで良いのでは。

    というか heredoc は単語ではない。でも一つの nest ではある。
    うーん。然し wrange に登録しているかは謎。
    その辺りも整理しつつ実装すると良い。

  * progcolor: コマンド自身が書き換えられた時には
    全ての引数について再度着色の確認が必要になるのではないか。

2020-01-23

  * 前々から発生していたが曖昧補完などを実行すると時々ごみが残る。
    これは何故だろうか。そもそもカーソルよりも右に何か文字列が入るはずがないのに?

    再現させようとしても再現できない。
    これは実際に起った時に再度確かめる必要があるのである。

2020-01-21

  * lmorg/murex という新しいシェルの対話環境

    https://github.com/lmorg/murex

    このシェルは POSIX 互換でないので微妙。
    パス名展開をするのに面倒な指定をしなければならない。
    既存の様々なツールと相性が良いかというと微妙な気がする。
    しかし fish や PowerShell よりは unix shell よりである。

    一方で対話インターフェイスに関しては色々工夫している。
    入力していくと一行下に現在入力しているコマンドの説明が表示される。
    何も入力していない場合は git リポジトリの情報を表示している。
    (然し、なにか入力するとすぐに消えてしまうので何処まで使いやすいかは分からない)
    kill まで入力すると補完候補としてプロセス ID を表示してくれる。
    プロセス ID に対してコマンドラインを説明として表示している。

    * 所で ble.sh ではメニューの形式は事前にユーザの側で指定する事になっている。
      然し、これは微妙な気がしてきた。というのも説明文があるかどうかの情報は
      補完生成側が知っている事である。なので、補完候補生成器の側で、
      メニューの表示形式を上書きできる様にするべきなのではないかという気がする。

2020-01-17

  * Minix で無限ループになっている?

    echo と入力しようとすると確率的に無限ループになる。
    (それでも可也高い確率で無限ループになる。)
    auto-complete を off にしても発生する。
    menu-filter を off にしても発生する。
    という事は着色か或いは。。

    調べてみると暴走しているプロセスは別の Bash だという事が分かった。
    恐らく子プロセスで暴走している。何が悪いのだろうか。履歴?
    →履歴はちゃんとロードできている。その後で暴走する。
    →再度確かめたらやはり子プロセスの暴走としか思えない。
      と思ったがよく見ると親プロセスの暴走だった。両方で起こる?

    2020-02-03 新しい ble.sh を実行しているが固まるという現象が再現しない。
    これは新しい ble.sh のお陰だろうか、それとも偶だろうか。
    →暫く使っていたが全く再現しないので以前の ble.sh の問題と思って良いだろう。

    と思っていたら実は裏でちゃんと無限ループになっていた。
    どうも ssh が予期せず切断すると無限ループになる?

    気になるのは暴走していたプロセスは stderr にリアルタイムで
    データを出力し続けていたという事。

    | -rw-r--r--  1 murase  users  14174140 Feb  3 21:58 5726.stderr
    | -rw-r--r--  1 murase  users  14324924 Feb  3 21:59 5726.stderr
    | -rw-r--r--  1 murase  users  14504088 Feb  3 22:01 5726.stderr
    |
    | 出力内容は以下の通り 0d 1b 5b 4b の 4B を繰り返し出力している。
    |   $ < $_ble_base_run/5726.stderr od -t x1
    |   0000000   0d  1b  5b  4b  0d  1b  5b  4b  0d  1b  5b  4b  0d  1b  5b  4b
    |   *
    |   67250220   0d  1b  5b  4b  0d  1b  5b  4b
    |   67250230
    |
    | 0d 1b 5b 4b とは何か? \r\e[K である。CR EL である。うーん。
    | ble.sh の該当しそうな部分を調べてみる。
    |
    | * canvas:344 (negative cup:el)
    |   ble/canvas/put-cup.draw 1 $((x0+1))
    |   ble/canvas/put.draw "$_ble_term_el"
    | * canvas:1928 (negative sgr0:cr:el)
    |   ble/canvas/panel#goto.draw "$index" "$x" "$y"
    |   ble/canvas/put.draw "$_ble_term_el"
    | * edit:1520 (negative sgr0:cr:el)
    |   ble/canvas/panel#goto.draw "$_ble_textarea_panel" "$fminx" $((fminy-new_scroll))
    |   ((new_scroll==0)) &&
    |     x=$fminx ble/textarea#render/.erase-forward-line.draw # ... を消す
    | * edit:1680 (negative sgr0:cr:el)
    |   ble/canvas/panel#goto.draw "$_ble_textarea_panel" $((cols+1)) "$y"
    |   ble/canvas/put.draw "$_ble_term_el"
    | * edit:1696 (negative sgr0:cr:el)
    |   ble/canvas/panel#goto.draw "$_ble_textarea_panel" "${pos[0]}" "${pos[1]}"
    |   ble/canvas/put.draw "$_ble_term_el"
    | * edit:3869 (negative cuf:sp:sp:el)
    |   ble/canvas/put-cuf.draw "$advance"
    |   ble/canvas/put.draw "  $_ble_term_cr$_ble_term_el"
    | * edit:7322 (negative cr:el:sgr)
    |   ble/canvas/put.draw "$_ble_term_cr$_ble_term_el${_ble_term_setaf[9]}"
    |
    | うーん。何れも関係なさそうな気がする。
    | もしかして _ble_term_el2 に CR EL が入っている?→確認したがそうでもない。
    | 上の中で一番怪しいのは panel#goto.draw だと思ったが、
    | sgr0 が消滅している理由が分からないし、
    | 一度 CR を出したら _ble_canvas_x=0 になるのだから、
    | 何度も CR を出力し続けるのは変だ。

    暴走した bash は何れも console ではなくて pty だった。
    接続が途中で落ちると無限ループになるのだろうか。
    hp2019 側及び vmminix 側で nc/sshd を kill -9 しても再現しない。

  * 英語圏のニュースサイトに投稿する可能性 (suggestion by dylankb)
    Hacker News を紹介されたがここが適切なんだろうか?

    reddit に投稿した話がある。
    https://rcmdnk.com/blog/2014/02/23/computer-bash-zsh/

    単にリンクを貼るというのでも良いけれども。
    やはり様々な機能を惜しげもなく紹介する
    長い記事を書くのが良い気がする。

    →返信で自分の作品を投稿する時のルールの頁があった。
      なるほど。やはりルールがあったのである。危ない所である。
      https://news.ycombinator.com/showhn.html

      これによると作品の紹介は一度きりしかできないとの事。
      > The community is comfortable with work that's at an early stage.
      と書かれているがまさかこれは初期の作品でなければならないという訳でもあるまい。
      > Blog posts, sign-up pages, and other reading material can't be tried out
      と書かれているが…。使い方の説明記事の様でも駄目なのだろうか。
      Blog posts でなければ良い? 或いは README を派手に改造してしまうという手もある。

    https://news.ycombinator.com/shownew
    ここを観察していると "Show HN: 作品名 ― 説明" という名前の物が多いが、
    実は "Show HN: 今〇〇なのを作っているんだけど" というタイトルの物の方が upvote が多い。
    "作品名 - 説明" だといかにも宣伝という感じで入る余地がない気がする。
    一方で "〇〇なんだけど" みたいに書くと "自分も何か貢献できるんではないか" と錯覚して人がたくさん来る。
    そういう仕組になっているんだろうという気がする。

    * reject: "Show HN: Bash Line Editor -- syntax highlighting, autosuggestions, etc. in Bash"
      これは普通。つまらない

    * "Show HN: I am developing a line editor in pure Bash script. I'd like to hear your comments!"
      これだと面白そうとは思ってくれるかもしれないけれど使ってくれる人は少なそう。
      後 explicit にコメントが欲しい! という事をタイトルに書いても良いのだろうか?
      眺めてみるとそういう投稿はない。やはり雰囲気が分からないのである。

    * reject: "Show HN: I made syntax highlighting, autosuggestions, etc. in Bash"
      これも普通。つまらない

    * "Show HN: "Bash Line Editor" with syntax highlighting, autosuggestions, ... written in pure Bash!"
      やはり宣伝っぽい。

    * "Show HN: Bash Line Editor -- syntax-highlighting, autosuggestions and vim emulation written in pure Bash"
      vim と書くと他のエディタを使っている人やシェルでは別に vim は使わないという人が敬遠してしまわないか?
      然し話題に乗るという事だけであればその辺りを無視して投稿しても良い気がする。

    * reject: "Show HN: I wrote a line editor (syntax highlighting, autosuggestions, vim amulation, etc.) in pure Bash script"
    * reject: "Show HN: I wrote a line editor in pure Bash script which provides syntax highlighting, autosuggestions, vim emulation, etc. to Bash"
    * reject: "Show HN: Bash Line Editor written in pure Bash script for syntax highlighting, autosuggestions, vim emulation..."
      長い
    * "Show HN: Bash Line Editor totally written in pure Bash script"
      案外これぐらいの方が気を引けるのかもしれないと思う。
    * "Show HN: Bash Line Editor -- a next-generation Bash configuration"
      或いはこんな感じに煽った感じのタイトルにしても良い。zplug の真似
      でも技術的に面白いのは pure Bash script であるという事。

      "with syntax highlighting, autosuggestions, vim emulation" 等は書かなくてよい。
      書かない方が煽りになるのである。本当か? と思ってみんなリンクを開く。
      そしてどんな機能があるのかとみんな確認する。
      少なくともこれだけの物があるのだからがっかりする事はないだろう。

      でも落ち着かなければならない。Bash configuration と書くと、
      従来の PS1 や aliases や functions を包含する物と考えられてしまう。
      その様に考えると、Bash plugin と書いた方が良いか?
      或いは、plugin manager として突貫で他の物を取り込める様にするか、
      或いは README に強調しておくことにするか。

      というか Bash configuration というのが良くない。違う。
      もっと土台になるものなのである。
      実のところ "a next-generation Bash Line Editor" なのだ。
      然し line editor という意味では全然 next-generation ではない。普通だ。
      つまり Bash の設定にしては next-generation なのであって、
      line editor として next-generation な訳ではない。

      a next-generation Bash interface/infrastructure/extension/framework

      Framework としての側面も強調してよいのかもしれない。
      (或いは真面目にライブラリとして独立させても良い。
      decode 部分に関しては大幅に手を入れる必要があるかもしれない?)

    * "Show HN: I wrote a featureful line editor in pure Bash scripts"
      みたいな単純な物の方が気を引けるのではないかという気がする。

    調べるとスタートアップという文字が頻りに見える。
    投稿してみた感想を観察してみるとやはり何かのお誘いがある様である。
    タイトルに文字数制限は在るのだろうか。

    何れにしても今は忙しいので沢山の要望などが来てしまっては困る。
    従って暫くはこのまま放置するというので良い気がする。

2020-01-05

  * Homebrew の設定を作成する?

    先ず Linuxbrew (Homebrew for Linux) を ~/opt/linuxbrew に入れた。
    普通と違う場所に入れようとしたので色々問題が起こって時間を食ってしまった。

    * brew tap について調べてみる事にする。

      % brew tap akinomyoga/ble.sh を実行すると https でダウンロードしようとする。
      % brew tap akinomyoga/ble.sh git@github.com:akinomyoga/ble.sh.git とすれば良い様だ。
      % それから brew install を試そうとするがどうやっても動かない。
      % どれをやってもそんな formula は見つかりませんのエラーになってしまう。
      % もしくは tap を確認すらしない場合もある。不思議だ。
      % $ brew install akinomyoga/ble.sh
      % $ brew install akinomyogable.sh
      % $ brew install akinomyoga/homebrew-ble.sh
      % $ brew install homebrew-ble.sh
      % $ brew install brew-ble.sh
      %
      % $ brew tap
      % を実行してみると。自分が登録した物の他に homebrew/core がある。
      % homebrew/core は中に formula を沢山入れた repo の筈である。
      % もしやと思って調べてみる。
      %
      % https://qiita.com/wkentaro/items/d4981582e08b134f1e1d

      どうも user/name に対応して github.com:user/homebrew-name を作成して、
      その中に formula.rb を入れて置くという事になっている様だ。
      面倒なのでそれよりは直接 core に取り入れてもらった方が楽だ。

    * 自分で formula を作ってみるのを試す

      仕方がないので自分で formula を作ってみるのを試す事にした。
      $ brew create --set-name blesh

      全て自分で記入しなければならない様だ。適当に formula を作成してみる。
      sha256 は何の sha256 を記入すれば良いのか分からないのでコメントアウトする。
      結局分からないので以下を参考にして埋めてみる事にする。
      https://github.com/10sr/homebrew-pkg/blob/813de30c121e8dea970f11e7c1e63e57d3a6a0ed/Formula/ble-sh.rb_
      * ビルドは gawk に依存しているので gawk に依存させてみる。
      * gmake については調べてみた所 macOS ではデフォルトで GNU make だそうなので不要?
        然し、mac ではデフォルトで make が入っているのだろうか。
        或いは自分で追加で入れる必要があったりするのだろうか。よく分からない。

      と思ったが何処にも *.rb が作られていない。
      $ find ~/opt/linuxbrew/ | grep blesh
      で調べてみたら ~/opt/linuxbrew/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/blesh.rb
      に新しく blesh.rb が作成されていた。これを使う事にする。
      試しに $ brew install blesh としてみたら動き出した。
      gawk を入れるためにその依存関係まで全てダウンロードしてインストールしようとしている。

    ? brew では自分で何処かで入手した formula を使うにはどうすればよいのか?

    * homebrew-core に登録する為には test を用意しなければならないようだ。

2019-12-31

  * progcolor: 引数の中の着色 (zsh -c '...' の ... の部分)。

    いつか実装しようと思っていたら fast-syntax-highlighting が既に実装している。

    | fast-syntax-highlighting
    | →引数の中も着色すると思ったら '$(...)' の中も着色を行っている。
    | 然し、zsh -c '...' に関してはちゃんと zsh や -c を認識して着色している様だ。
    | 調べてみると awk もちゃんと文法的なチェックを行っている。
    | (→ うーん gawk --source '...' で文法チェックをできる様だ。)
    | sed に関しては行っていない。何れにしてもコマンド毎の着色を実現している。

    * コマンド毎の着色設定を指定できる様にした #D1245

    | 次に例えば awk に対応する事を考える?
    | 或いはそれよりは sh もしくは bash に対応する方が楽?
    | 色々考えてみたがちゃんと対応するのは可也大変である。
    | 先ず単語が単純単語でない場合にどの様に実装するか。
    | 等、色々難しい。既にある文法構造を利用して何とかできる可能性はある。
    |
    | awk に対応するとしても awk の様々な実装によってオプションなど異なる。
    | このオプションが異なっていると異なった着色になって、
    | ユーザに混乱を齎す。従って対応するとしたら完全に対応している時にだけ有効にする。
    | 何れにしても面倒である。awk よりは先に bash で対応した方が懸命ではないか。
    | awk の対応に関しては自分の blerc の中だけに留めておく。
    | その自分の blerc の中での awk の着色の設定で必要になると
    | 思われる補助機能をble.sh の方で実装する。

    * awk の着色対応を通じて ble.sh 側で支援の必要な機能を実装する。

    * 単純単語に関して。評価値を求める方法。
      評価値の各文字が元の単純単語のどの位置に対応するか。
      或いはその逆? どちらの方が適切だろうか。

      例えば引用符等に関しては対応する文字はないのでそのままの色が良い。
      従って評価後の文字に対応する評価前の範囲を取得すると良い気がする。
      然し、逆に評価前の $a が評価後に沢山の文字列になる事もある。
      その場合には評価後の各文字の色を評価前に割り当てるのは難しい気がする。

    * 対応する物がない文字をそのままの (下の層の) 色にする事は可能だろうか。
      恐らく getg 等で取得しなければならない。面倒である。
      或いは ble/highlight/layer:syntax では少し違う様に処理していた気もする。

    * 複雑な単語に関しては文法構造を利用する事も考える。

    * 現在の layer:syntax の枠組みでは一旦着色情報を wattr に格納してから、
      それを word table に対して適用するという仕組みにしている。
      この様にする事に何の意味があったのだったか?

      直接 word table に適用した方が早いのではないか?
      →これは何度も単語着色を求め直すのを省略する為である。
      つまり、単語着色を決定する部分と実際に適用する部分を分けて、
      前者をできるだけ省略する様にしている。

      実際に適用する必要がある場合でも前回求めた値を
      そのまま使えば良い場合があるという事なのである。

  * fast-syntax-highlighting の機能を確認する
    https://github.com/zdharma/fast-syntax-highlighting

    * コマンド毎の着色。オプションや引数が正しいかのチェックも行う。
      これは丁度 ble.sh で将来的に対応したいと思っている機能である。
    * 括弧の対応に応じた着色
    * gawk --source による文法チェック?

  * theme: 流石に theme を作った方が良い気がしてきた。
    少なくとも枠組みだけでも作って置くと良い気がする。
    と思ったが実際に例がないと枠組みの良い設計も分からない。
    zsh-syntax-highlighting はどうしているのだろうか。
    zsh-syntax-highlighting theme で検索してみる。

    どうも zsh-syntax-highlighting は theme を提供していない様だ。
    https://highlightjs.org/static/demo/
    ここは dark/light の両方を提供している theme があって参考になる。
    但し、ファイル名着色に使う色は色々調整しなければならないが。。

    fish の theme はあるだろうかと思って探すと。
    https://github.com/oh-my-fish/oh-my-fish/blob/master/docs/Themes.md
    どうもシェル業界では theme というのはプロンプトの事を指す様で。
    然し、fish のブラウザ設定画面ではタブは colors となっている物の、
    色々な設定の部分には theme という文字も見える。
    何れにしても theme というのは紛らわしいかもしれない。
    注意書きを書いておく必要があるかもしれない。

  * tui: TUI 設定画面?
    fish はユーザフレンドリーを謳っている。
    ブラウザで設定できるなど (リモートの場合には使えない気がするが)。
    ble.sh ではブラウザでなくても TUI で設定画面を用意しても良いのかもしれない。
    マウスサポートまですればブラウザでなくてもOKなのである。

    →fish の web 設定画面を確認してみた。
      実は theme と prompt が選べるだけだった。
      他は関数・変数・履歴・束縛・略語展開の一覧が見えるだけで、
      何も設定することはできないのだった。
      但し履歴項目の削除はする事ができる。
      略語展開も実は編集することができた。
    →theme に関しては配色が選べるだけで、
      具体的にどの色がどの意味というのは余り考えられていない気がする。
      適当に順番に割り当てただけなのではなかろうか?

    その様に考えると履歴の着色でも良いのかもしれない等と。

  * complete: 重い補完関数に対する対策

    * 曖昧補完の為に何度も progcomp を呼び出していて非効率的
      →無駄があると思ったが実際にどういう補完を行っているか調べると
      様々な補完点を試しているのだった。うーん。
      自動補完の補完候補がすぐに見つかる場合にはそんなにたくさん呼び出されない。
      補完交互が見つからない時には自動補完によって何度も補完が実行されて遅くなる。

      もしかすると自動補完を off にしたいという人は時間のかかる
      補完関数を使っているという事なのかもしれない。
      よく考えたら peco の類を設定している場合大変に面倒な事になるのでは?
      自動補完が実行される度に選択メニューが表示されてしまう。
      そもそも補完に peco を設定している時点で変ではあるが。

      色々な補完点で試すとしても現在の単語を 0 文字または 1 文字しか
      入力していない場合には、同じ状態で呼び出す事もあるだろうという気がする。
      その場合の為に compgen の呼び出し結果をキャッシュする利点はあるだろうか。
      つまり、同じ補完状態で再度呼び出される事を見込めるかどうかが問題になる。

    * 或いは、処理を非同期で呼び出すというのが良いのかもしれない。
      その場合には計算結果を何処かファイルに書き出す様にしなければならない。

      非同期で呼び出すのは -CF が設定されているときだけで良い。
      と思ったが -F の中で環境を変更したいという場合にはどうするのだろう。
      非同期で呼び出すという事にすると環境に対する変更が適用されない。
      これは bleopt で変更できる様にしても良いのではないだろうか。

  * complete: menu-complete 中の通常文字挿入は
    絞り込みに戻すのが良いのではないか。
    というか普通にキャンセルして挿入すれば絞り込みになるのでは?
    と思ったが menu-complete 状態からは抜ける事になる。

    後、suffix を挿入せずに確定する方法がなくなる。
    これについては別の操作方法について考えると良さそう。
    例えばスペースを押すと suffix 挿入を抑制して確定する等。

    →やはりこれは分かりにくいのではないか。
      fish, zsh の動作を確認してみたが menu-complete 中に
      新しい文字を入力すると何れも現在の選択肢を確定させた後に
      続きの文字が入力される様になっている。
      これらのシェルと異なる振る舞いをするのは良くない。

      だとすると絞り込みをする為には明示的に
      絞り込みのモードに入るキーを設定するべきなのでは。
      例えば M-e 等?

      因みに emacs で試してみると M-e, M-a は end/beginning of
      sentence 的な動作をしている様に見える。
      なので上書きしてしまっても良い様な気がする。
      うーん。でも end of line の代わりに使っている人がいるだろうか?

      因みに現在の ble.sh では M-e は何にも紐付いていない。
      うーん。M-e を勝手に補完の絞り込みモードに割り当てる事にする。
      絞り込みモードにいる時にはカーソルの動く範囲と編集範囲を制限する。
      と思ったが vi の様な複雑なモードの場合にそれを実現することは可能か?
      移動だけならば __after_widget__ で範囲外に出た時に
      強制的に範囲内に移動させる事が可能であるが、編集まで入ると困難である。
      編集を禁止しなければならないがそれは難しい。

      だとすると新しいプロンプトで編集させるというのが現実的だろうか。

2019-12-29

  * color: term_true_colors=auto

    自動判定は難しい。screen-4.99.0 が truecolor on/off
    のオプションを持っているので実際にユーザが有効にしているかどうかは
    TERM や DA2 を使っても分からない。結局試しに色を設定して、
    その色を読み出すという事をしなければ判定できないのだろうか。
    然し、これも端末によって問い合わせができたりできなかったり
    (セキュリティ上の都合から)無効になっていたりする気がする。

    以下の優先順位で試すというのが妥当な実装方法の気がする。
    然し 1 の判定を非同期に行わなければならないので面倒である。

    1. 色を設定して問い合わせる

      http://nanno.dip.jp/softlib/man/rlogin/ctrlcode.html
      https://qiita.com/kefir_/items/c2bd46728364bdc7470b
      OSC 10 ; ? ST で前景色RGB問い合わせ、
      OSC 11 ; ? ST で背景色RGB問い合わせの様である。
      応答は OSC 10 ; "rgb:rrrr/gggg/bbbb" ST の形式?

      よく考えたら現在の実装では ESC-[ (CSI) しか特別扱いしていない。
      これに対応する為には "ESC ]" (OSC) についても処理する必要がある。
      これは ble-decode-char/csi/consume の辺りを拡張する必要がある。
      特に BEL または ST (ESC \) で終端する様に処理を書く事に注意する。

    2. DA2 を元に判断する
      然し https://gist.github.com/XVilka/8346728 のページには
      各ターミナルの対応 version が書かれていないので使えない。
      自分で調べ上げるしかないのだろうか。

    3. TERM を元に判断する (*-24bit *-24bits *-truecolor)
    4. terminfo を元に判断する (setf24, setb24, tc, RGB)

2019-10-21

  * ずっと起動していると段々と遅くなっていくのは何故か。

    Ubuntu bash-4.3 (song437) で動かしていて気づいた。
    bash として新しく起動すると速い。
    ble-update や ble-reload をしたり、
    ble-detach / ble-attach しても直らない。

    カーソル移動だけでも遅くなって行くので描画が関係しているとは思われない。
    また、reload しても直らないという事から考えられる事は何か。
    履歴がどんどん溜まって重くなるという事でもない様な気がする。

    或いは変数のアクセスが遅くなって行くという事なのだろうか。
    変数に代入するスクリプトを回してみたが特に遅いという事はない様だ。
    (それにそもそも使用している時間に比例して変数が増えていくという物でもない)

2019-09-24

  * ble.sh で export PATH=aaa:bbb:ccc で最後の部分しか着色されない。
    それぞれ着色するべきなのではないか。

2019-09-22

  * complete: = を含むファイル名を補完すると = 以前の部分が重複して挿入されてしまう。

    →今確かめてみると再現しない。\= としていても = としていても同じ。

    2019-12-31 ./configure の引数で --prefix= を補完している時に
    = が \= になったり --prefix= も丸ごと置換されたりなど変な動作をする。
    一方で、complete -r で progcomp を消してやると変な事は起こらない。
    これは要するに progcomp の仕様の微妙な違いに起因して変な事が起こっている。

2019-07-16

  * complete: パス名展開で複数語に展開される場合の補完に関して
    現在の実装ではパス名展開が起こったとしても展開された最初のファイル名を使って補完を実行する。
    然し、実際には展開された各パス名について補完を実施しても良いのではないだろうか。うーん。

    更に failglob の場合には続きを入力したら一致したかもしれなくても常に展開に失敗してしまう。
    というか現状でそもそも failglob だった時にそれを検出しているのかどうかすら怪しい。
    確認する必要があるのである。

    既に COMPV には複数の値が入る仕組みになっていた。
    それならばと COMPV に入っている値の数だけ source を呼び出せば良いのかと考えたが、
    実際に試してみると全く同じ候補が何度も生成されるだけに終わってしまった。
    よく考えたら progcomp では独自に展開を行っていたのではあるまいか。
    調べてみたらやはりそうである…。これに対応するのは面倒である。

    或いは複数語に展開される場合には先ず始めにその内のどれか一つに絞らせるという可能性もある?
    然しそれはそれで不便な気もする。

2019-07-09

  * history.mlfix: bash-3.0 で実現する方法?
    history -s が使えないので複数行の履歴を登録する事が不可能である。

2019-07-02

  * menu: 複数選択を可能にしても良いのではないか
    C-@ で toggle をする等。抜ける時に全てを挿入する?
    然し使いみちがよく分からない。使いたくなったら追加するというので良い気がする。

2019-06-18

  * history: interactive な history 編集に対応できたらする
    つまりメニューを表示して其処で選択したり削除したりする。
    検索などもできる様にする。遅延で着色をする。

    core-complete に実装されている既存のメニューの枠組みは、
    menu item を配列に格納する。従って容量を食う。
    更に重そうである。これは独自に新しく実装した方が良いだろうか。

2019-05-27

  * 次に機能を追加するとしたらマウスなのだろうという気がする。
    fish は未だマウスに対応していない。
    zsh はそういう拡張があるらしいがちゃんと動くのかは知らない。

    zsh extension: https://unix.stackexchange.com/questions/444601/any-terminal-shell-with-mouse-support
    fish suggestion: https://github.com/fish-shell/fish-shell/issues/4918
    question: https://superuser.com/questions/322367/are-there-any-unix-shells-that-support-mouse-reporting

    マウス対応の問題点はマウスが有効になっていると、
    従来の端末に対するマウス操作(端末に表示されている内容のコピー・ペーストなど)が使えなくなる事である。
    端末に表示されている内容まで全て ble.sh の管理下であればそういう事もできたかもしれない。

    部分的なサポートとして何らかのモードに入っている時だけマウスを有効にするというのはあるかもしれない。
    例えば補完のメニューを出している間だけ、など。然し、それもなかなか分かりにくい気はする。
    或る特定の範囲だけでマウスを有効にするという制御機能があった様な気がする。
    それが使えればそれを使ってマウスを有効にするというのが可能になる気がする。
    何れにしてもこれは考察が必要になるのである。

    2019-07-22 どうも既存の端末では Shift を押しながら操作すると
    Mouse report ではなくてローカルでの端末上でのマウス操作になる、
    というのを採用している物が多い、という話を何処かで見かけた。
    何処で見掛けたかは忘れたし実際にそうなのかの確認はしていないが。

2019-04-21

  * 実は背景色を判定する方法はなくはない様だ。
    https://qiita.com/kefir_/items/c2bd46728364bdc7470b
    しかしそうだからと言って暗い背景用に配色を調整する必要があるので、
    それを実行するまでは対応しても仕方がないかもしれない。

    % というか、調べていたら DECSCNM (SM/RM(?5)) が背景が暗いか明るいかの設定の様だ。
    % という事は DECRQM して DECRPM を受け取れば普通に背景が明るいか暗いか分かるのでは。
    % そして Poderosa や screen の側でもそれを設定すれば良かったのではないか…。
    % と思ったが xterm は明るいか暗いかが反転している。
    % つまり、DECSCNM は飽くまでその端末の既定の背景と比べて反転しているかどうかしか分からない。
    % 既定の背景色が明るいか暗いのかの情報は取る事ができない。

    一方で、背景色の問い合わせで返ってくる色が DECSCNM の影響を受けるのか
    は気にして置かなければならない。

2019-03-23

  * menu: alias select='while myselect $# "$@"' 等として select を上書きできるのでは

    というか現在の ble.sh で select を実行すると悲惨な事になる気がする…。
    と思ったが select は別に readline は使っていない様子だ。
    元の bash でも全然行編集できない感じの入力になっている。
    なので現状で問題が発生しているという訳でもない。

    もし置き換える事ができるのであれば便利かもしれないという程度である。

  * menu: 今後の拡張性

    * 因みにフィルタリング機能は menu-filter を統合・整理する形で実装したい。
      フィルタリング文字列の入力に関しては isearch や iswitchb の様な、
      単に文字を入力するか BS で戻るかだけしかできない様なものでも良い事にする。

      フィルタリングに関してはフィルタリングを実行する関数と、
      フィルタリングを誘発する為の機能を分離して実装する事にする。
      既存の menu-filter の機能は自動的にフィルタリングを呼び出す。
      明示的なフィルタリングの場合には keymap にフィルタリングを紐付ける。

    * cdhist では更にリスト編集機能までついている。
      つまり項目を並び替えたり削除したりと言った事ができる。

      うーん。これをどの様に返すかは微妙かもしれないが、
      _ble_complete_menu_items にある物を呼び出し元で参照してもらうというので良い気がする。
      或いは callback でどの様に並び替えたかを返すという手もあるが分かりにくいだろうか。
      両方という事で良い気がする。使う側で便利そうな方を選んでもらう。
      どの様に並び替えたかの操作が欲しければ callback を使うし、
      最終的な結果だけ欲しければ _ble_complete_menu_items を参照してもらう事にする。

    * callback という事で思ったが、実は accept だとか cancel だとかも
      全て menu_class 経由で定義した方が良いのではないだろうか。
      一つずつ全て callback を変数に設定していくのは面倒である。
      更に、並び替えの callback だとかどんどん増やしていくと際限がない。

2019-03-22

  * menu-filter の使い心地が微妙なのはもしかして
    menu-complete を実行中に絞り込みができないからなのではないか。
    現在は menu-complete を実行している途中に入力をするとその場で確定してしまう。

    では bash の振る舞いはどうなっているだろうか。
    確認してみた所、bash の menu-complete はもうその場所に挿入してしまう。
    そして文字を入力すれば続きに挿入される事になる。

    現在の ble.sh の振る舞いはどうだろうか。
    その場で入力すると addtail 等の処理をせずにいきなり続きから入力されてしまう。
    少なくとも addtail ぐらいはするべきなのではないか。
    また、絞り込みを実行しても良いのではないかという気もする。
    然し、それでも何か違う様な気がする。

    絞り込みの入力欄と現在選択されている内容というのは別に一致している必要はない。

2019-03-19

  * complete: 実装されていない補完関連の rlvar は以下の通りである。
    実際に対応するかどうかも含めて考察する必要がある。

    - set completion-map-case off
    - set disable-completion off
    - set expand-tilde off
    - set horizontal-scroll-mode off
    - set page-completions on
    - set completion-display-width -1
    - set completion-prefix-display-length 0
    - set completion-query-items 100

    うーん。これらの設定は bash の既定値では余り便利ではなかったりする。
    ble.sh で折角実装してもユーザに使ってもらえないのでは仕方がない。
    それならば最初から ble.sh の bleopt として提供してしまった方が良いのでは。
    元々 bash を普通に使っていて設定している人の為に、
    bash の規定値と異なる値を敢えて選択している時に限り
    ble.sh でその効果を再現する様にすれば良い。

2019-02-09

  * main: --attach=prompt の問題は何だったか
    ref #D0940

    何か問題があって現在はこれを使っていないが、それは何だったろうか。
    何処かに記録されていて良い筈なのに何処にも記述がない。
    対応した時の記録は #D0737 にある。
    動かしてみた所、ちゃんと動いている様に見える。

    →恐らく、先ず古い ble.sh の version では使えないという事。
      それから PROMPT_COMMAND を上書きすると使えなくなってしまうからという事。
      ユーザに PROMPT_COMMAND を設定しないように要求するのは面倒である。

2018-09-21

  * [保留] 2018-09-15 complete: 文脈の変更範囲で end0 だけ負になるバグ (ref `#D0818`)
  * [保留] 2018-09-11 complete: 端末が操作を受け付けなくなるバグ (ref `#D0817`)

2018-08-16

  * complete: オーバーレイによる実装?

    現在の実装では仮挿入しているが、
    これによって現在の入力内容でエラー着色するべき所が、
    補完が実行された後の着色になってしまっていて、
    補完前の現状でエラーなのかどうなのかが判別できなくなっている。

    やはり仮挿入ではなくて overlay で実装するべきなのではないか。
    しかし overlay の仕組みを実装するのは面倒である。
    どの様な仕様にするのが良いのかの吟味から実装まで。
    しかし、これについては後回しで良いだろう。

    以下に仮入力の4種類の方法について言及がある。
    https://mattn.kaoriya.net/software/vim/20170905113330.htm

    リンク先は消えている。web archive のリンクを追記 (2018-09-23)。
    https://web.archive.org/web/20110630165743/https://www.mozilla-japan.org/projects/intl/input-method-spec.html

    * 2018-09-23 自動補完時の着色について
      cmplstofB さんからも指摘があった。
      https://github.com/akinomyoga/ble.sh/issues/5

      自動補完の候補文字列は実際に挿入しているので構文着色に影響を与える。
      "現在の内容" で着色するべきなのではないか、ということ。
      そうしないと例えば今入力したコマンドが実際に存在するコマンドなのかどうかが分からない。

2018-08-05

  * edit: set blink-matching-paren on に相当する機能
    対応するならカーソル移動ではなくて着色でやった方が良い。

    | 括弧の対応と region が両方走っていると分かりにくい。
    | 既に region には複数箇所を highlight する機能がある。
    | そういう意味で region を使うという手もある。
    | と思ったが、分かりにくい問題に関しては region の方を上に配置すれば良い。
    | 複数箇所を highlight する機能は実装を参考にするだけで良い。
    | 論理的には全く異なる (region は _ble_edit_mark を参照する) し、
    | それぞれ独立に on/off する事を考えれば別の highlighter にするべき。

    region の複数箇所着色の実装を参考にする可能性も考えつつ、
    region とは独立な highlighter にしたい。
    その時は region の一つ下の層に挿入したい。

    また対応する括弧はどの様に検出するのが良いだろうか。
    やはり文法構造を参照する実装にするしかない様に思われる。
    しかし、括弧の対応には色々ある。引用符の対応、
    括弧の対応、if then else などのキーワードの対応、
    ヒアドキュメントの始まりと終わりの対応である。
    それらは必ずしも記録されていないし、また、記録されているとしても
    様々な形式で記録されている。取り敢えず一番簡単な対応として
    nest に記録されている物を着色するというのが良さそうである。

    2023-03-26 https://github.com/akinomyoga/ble.sh/discussions/308

    対応する request が来た。うーん。もっと最近にも関連した考察をした気がするが、
    メモに記録があるかどうかは覚えていない。

2018-07-29

  * complete: メモ

    - 生成候補のキャッシュを行うとすれば source 内で実装するべきである #D0705

2018-07-19

  * ble-decode: 'set convert-meta on' 的な操作

    ref #D0699 (LANG=C bash で ble.sh をロードすると全く操作できない)

    ble.sh の内部環境では set convert-meta off にしているが
    (そうしてないと特殊文字の受信時に無限ループになる)、
    外部環境で set convert-meta on だった時に、
    それをエミュレートする様な動作を行っても良い。

    外部環境における set convert-meta の状態は
    変数 _ble_term_rl_convert_meta_external に記録してある。

  * 現在の `LC_CTYPE` で表現できない文字を入力した時の `self-insert` の振る舞い

    ref #D0699

    self-insert で入力するのは逆符号化したバイト列であるべきでは?

    というのも LC_CTYPE が正しくない場合でもファイルシステムのファイル名などは
    そのまま謎の文字列として取り扱われるからである。
    然し逆符号化したバイト列は文字列として正しくないかもしれない。
    逆符号化したバイト列を更に一バイトずつ現在の LC_CTYPE に変換すると意味がない。

    これは文字列を編集などしようとすると分からない事になりそうなので、
    取り敢えず現段階では \u???? を出力するという現状の振る舞いを維持する。
    後で落ち着いてから再考する事にする。

    以下の c2s 使用箇所は一貫している必要がある。

    ble/widget/self-insert 編集文字列の入力
    ble/widget/vi-command/search-char.impl/core 検索文字列の入力
    ble/widget/vi_xmap/visual-replace-char.hook 置換に使う文字の入力
    ble/lib/vim-surround.sh/get-char-from-key 囲み文字の入力 (あらゆる遅延入力)

2018-02-21

  * vi-mode: nmap (, ), {, }

    カーソルを N 文元に戻す or 先に進める。N 段落元に戻す or 先に進める。

    これは operator:d,c で "- ではなく "1 に記録するという例外の対象であるので、
    対応したらその例外のリストに登録する必要がある。

    2020-08-27
    https://www.youtube.com/watch?v=hIJh-KlQ7io
    この動画で zsh/bash の vi mode に (){} がない事を嘆いている。
    然し、"文" をどの様に定義するのか。文法的なコマンドで定義するのか、
    或いは、元の vim と同様に . の位置で判断するのか。
    シェルの機能としては . の位置で判断するのは使いようがない。
    一方で、シェル文法の . で移動する様にすると
    vim に使い慣れた人に取っては混乱の元である。

2018-02-12

  * [保留] vi-mode: operators 保留項目 [#tmp0002]

    * 領域折り畳み zf には対応しない。

    * gq の formatexpr, formatprg には未対応である。

2018-02-11

  * [保留] keymap/emacs: 連続する delete-backward-char の場合 undo の記録をまとめる可能性?

    現状では一文字ずつ記録しているので一文字ずつ undo される。
    現在の振る舞いの方が良いのか emacs と同様にまとめた方が良いかは微妙な所である。

2017-11-21

  * syntax: for^J で改行にエラーが設置されるが見えない [#T0005]

    改行のエラーは何らかの方法で見える様にするか、
    或いは、改行位置にエラーがある様な時は、
    その前の文字でエラーが発生する様にチェックを行うべき。

    Note: これは端末によっては表示されたりする。端末による。
    エラー着色はどの様に行われているのか。for の後には FARGX1 に入る。

    これは ble-syntax:bash/ctx-command/.check-delimiter-or-redirect の冒頭部分が怪しい。
    と思ったが FARGX1 に関してはチェックが入っていないのでやはり関係ないだろうか。
    うーん。調べるとやはり文法レベルでの着色になっている。

    2019-03-11

    | rps1 で表示している時に EL を空白で代替していると、
    | 改行の着色が空白に反映される。これでも良いような気がしてきた。
    | 然し、右側が全て着色されるというのもうるさい。
    | 最初の1文字だけ着色して SGR(0) するかと思ったが、
    | そうするとその次にある文字の着色も消えてしまう。
    |
    | それの対策のために _ble_textmap_ichg があるのでは。
    | と思ったが、実装を見てみると違っている様に見える。
    | _ble_textmap_ichg は着色の調整に使っている事は確かだが、
    | _ble_textmap_ichg に登録されている文字の着色を計算しているのであって、
    | _ble_textmap_ichg に登録されている文字の次の文字の着色は計算していない様に見える。
    | うーん。_ble_textmap_ichg は他の箇所では全く使っていない。
    |
    | そうだ。思い出した…。_ble_textmap_ichg に登録されている文字は、
    | 配置の場所によって中身が変わるので、shift が使えないという事だった。
    | 特に、中身が変化している場合には文字を取り出して変更を行うのだった。
    | では以前 ichg に登録されていて、現在位置では ichg に登録されていない文字はどうなるのか。
    | と思ったら既定の文字形は別の所で決定されている様だ。
    | ble/highlight/layer:plain/update/.getch である。

    a 右側の1文字だけ着色される様にする?

      x 問題点はコピーペーストした時に必ず余分な空白が入る事である。
        これは右側の全てを着色させる場合にも同様の問題が生じる。

        また、エラーが有る時にだけ (着色の必要がある時にだけ)
        右側に空白を入れるという方法もある。
        しかし、その為にはその位置にエラーが有るのかないのかを
        外部から取得しなければならない。

        ble/textmap#update は edit.sh だとかの仕組みに依存しない、
        独立した枠組みにしたいので余り変な機能は取り付けたくない。

      x また実装上の問題点として、rps1 が表示されている時に、
        _ble_term_ech を使わない場合、2文字目以降の空白文字を SGR(0)
        でクリアしなければならない事である。この場合、
        改行の次の文字の SGR を復元する為には…

        _ble_textmap_ichg に次の文字の番号も追加するか、
        或いは現在の改行文字の SGR 状態を復元する必要がある。
        しかし textmap の処理をしている間は、
        未だ着色が完了していないので SGR 状態を取得できない。

        或いは着色部分だけ textmap#update よりも前に持ってきても良いのだが、
        その様にしたとしても色情報を textmap#update に伝達する手法が必要である。
        例えば getg なる関数を textmap#update から呼び出してもらう事にするのか。
        或いは呼び出す関数名も外から指定できる様にするのか。

    b やはり改行の前の1文字を描画時に強制的に着色するという手もあるのではないか。
      と思ったが…エラー着色だけ特別扱いするというのも変な話である。

    c その様に考えると初めから改行にはエラー着色はしないというのが正しい気がする。

      改めて調べると ble/syntax:bash/ctx-command-compound-expect がエラーを設置している。
      うーん。for だけの問題では無い様である。他に select, case の時にも同様である。

      ('for'|'select'|'case')
        [[ ${text:i:1} == $'\n' ]] &&
          ((_ble_syntax_attr[i-1]=ATTR_ERR))
        case $word_expanded in
        ('for')    ((ctx=CTX_FARGX1)) ;;
        ('select') ((ctx=CTX_SARGX1)) ;;
        ('case')   ((ctx=CTX_CARGX1)) ;;
        esac
        processed=begin ;;

      実際に上記の様にして見たら見える様になった。
      しかし rps1 が有効になっている時はやはりうるさく感じられる。
      また端末に依っては rps1 が無効になっていても行全体が赤く着色される。
      そういう端末 (mintty など) どういう発想なのかはよく分からないが…。

      更に here documents も行末にエラーを設置する。
      これについても対策したいが、here documents に関しては、
      nest の終端がない事によるエラー着色である。
      これは nest の範囲を変更しないと着色を変更できない。

      何だか中途半端な実装の気がしてきたので取り敢えずこの変更はなかった事にする。

    d うーん。右側の内容の消去は実は改行文字を使って行うのではなくて、
      描画した後に消去するという方法にした方が良いのだろうか。
      しかし、その様にすると、今度は urange の中にある行末というのを列挙して、
      それから各行末について位置を計算して実行するという事をしなければならない。
      textmap さえあれば指定範囲内の行末は二分法によって特定する事が可能である。
      しかし面倒である事に変わりはない。もっとまともな方法はないのだろうか。

    結局実装の面倒さを考えなければ三種類の仕様が考えられる。

    a 右側に1文字赤く表示する
    b 行末まで赤く表示する
    c 行の最後の文字を赤くする
    d 表示されなくても気にしない

2017-11-09

  * complete: 候補の優先順位? 例えば拡張子でフィルタすると絞りすぎることがある。
    拡張子の要件を満たすものを先に表示して、満たさないものを後に表示する。
    満たさないものに関してはサブ候補として、TAB による接頭辞挿入には寄与しない。

    2018-07-28 候補間の優先順位をつける可能性。
    weak な優先順位は、候補を表示する時の順序。
    strong な優先順位は、候補絞り込みの際に一番優先順位の高いものが一つしかない場合にはそれに確定する。

2017-11-05

  * vi-mode

    :help 関連の気になること:

    - v_p v_P: Implementation details に書かれている処理の順序は実際は逆
    - exclusive-linewise: ここの inclusive/linewise になる条件の記述は曖昧だし全く合っていない
    - star: vim-jp の文書だと WORD と書いてあるが、振る舞いは word (しかも \<\> で囲まれる) に近い

    振る舞いで気になること

    - i<C-o><C-c> とすると普通のノーマルモードに移行したように見えるのに、
      モード表示は -- (挿入) -- のままである。これは何故だろう。
      ble.sh ではノーマルモードに完全に移行する。

    - qa<C-c>q とすると ^C が二重に記録される。これは何か?
      ble.sh では単に ^C は入力された通りに一個だけ記録する。

    - C-v <bracketed paste> では矩形挿入にするべきなのではないか。
      ble.sh では矩形挿入を行う。


2017-11-03

  * vi-mode (registers): 各種特殊レジスタの対応

    http://vim-jp.org/vimdoc-ja/change.html#registers

    - done: "% は現在のファイル名を保持するが、これは $HISTFILE の内容を返す事にした。

    - done: ": は一番最後のコマンドラインの内容である。
    コマンドラインを入力し途中でキャンセルした場合などには記録されない。
    空のコマンドラインで確定した時にも記録されない。
    コマンドが入力された場合は、それが存在しないコマンドであっても記録される。
    コマンドが実行されている途中では未だ設定されていない。
    つまり、そのコマンドが実行された後で値が設定される。

    - ". は挿入モードで挿入された文字列を保持する。挿入モードから抜ける時に記録すればよいだろうか。
    と思ったが説明をよく読んでみるとそういう振る舞いという訳でもなさそうだ。
    よく分からないので実際に動かして試してみる必要がある。

    - "# は代替ファイル (副ファイル) の名前だそうだが何か良くわからない。
    C-^ の動作と関係しているそうだ。これは未だ実装しない。

    - "= これは複雑だ
    - "* "+ "~ これは GUI で選択した範囲を表すものだそうだ。

2017-10-31

  * [保留] vi-mode (_ble_keymap_vi_REX_WORD): Unicode categories?

    Bash の正規表現 (<regex.h> ERE) で対応するのは難しい。
    また必ずしも Unicode (UTF-8) で実行されるとは限らない。
    現在は UTF-8 しか対応していないが枠組みとしては
    別の文字コードにも対応できる余地は残して置きたい。

2017-10-12

  * vi-mode まだ対応していない・考えていないコマンドを列挙する

    意外とそんなに残っていないようなので。

    * nmap: C-^ '括弧 `括弧
      C-t C-] M Q ZZ ZQ do dp { }
      [{char} ]{char} z{char} C-w{char}
      g<C-a> g<C-g> g<C-h> g<C-]> g# g* g$ g&
      g` g' g+ g, g- g8 g; g< gD gH gN gP gQ gT gV
      g] ga gd gf gF gh gn gp gq gs gt gw gx g@

  * [保留] vi-mode: xmap <C-]>

    % <C-]> なる物は今見ても存在しない。vivis https://qiita.com/b4b4r07/items/8db0257d2e6f6b19ecb9
    % 辺りに在ったものかとも思ったが、ない。zsh-vimode-visual を見てもない。
    % vim で C-] としてもベルが鳴る。何かの間違いで C-[ を C-] と書いてしまっただけなのかもしれない。
    % と思って改めて vimindex を見ていたら実はあった。

    C-] で "選択した文字のタグ" へジャンプと書かれている。
    タグとは何だろうと思ったら http://vim-jp.org/vimdoc-ja/tagsrch.html に説明がある。
    ctags のタグと同じものと思って良さそうだ。因みに :help ... で表示されるのもタグの様だ。
    またノーマルモードの C-] はカーソル位置の単語を ":ta" で検索と書かれているが、
    実質 xmap の時と同じことのようだ。

    % これについてはシェルの操作としてどの様な意味を持たせるのかというのは微妙な所である。
    % 履歴項目のブックマーク的なものとして利用することはできるかもしれない。
    % しかし、既にコマンドラインに入力されている文字列を元にジャンプをするとなると矢張り微妙だ。
    % 唯一意味がありそうなのは、指定した単語がコマンドライン上で定義された
    % シェル関数だった時にそこにジャンプするという物だが…本当に需要があるのかは微妙である。
    % しかし、シェル関数の定義を確認したいのであれば寧ろ command-help を呼び出せば良い。
    % シェル関数を修正するという目的ならば使えるかもしれない。
    % 然し、必ずしもシェル関数をコマンドラインで定義したとは限らないし、
    % 該当するファイルがあったとしてもそれをコマンドラインで表示する訳にも行かない。

    既に入力した文字列に対応して適切な履歴項目またはコマンドライン中の文字があればそこにジャンプする。
    例えばシェル関数を定義した履歴項目に跳んだり、変数名から declare に移動するなど。
    そういう機能でまともそうなのが定義できればそれを実装する。

2017-09-18

  * vi-mode: operator = [#tmp0001]

    :help = を見ると (設定 equalprog || 内部関数 C-indenting, lisp || 外部コマンド indent) が使われるそうだ。
    但し、indentexpr が非空白の時、indentexpr が使われる (参照: indent-expression)。

    インデントの規則について調べる。
    先ず初めに空行 (空白だけの行) を隔てて前の行に括弧がある場合には、
    それを考慮に入れて初めのインデントが決定される。
    空行を隔てて前の行がインデントされていればそれを継承する。

    結局空行を隔てた前の行のインデントまたは最後の括弧の位置を継承するということ?

    また括弧の種類は () しか見ていない {} や [] は見ていないようだ。
    デフォルトが lisp だからだと思われる。
    これは実のところシェルに適したインデントを実行するようにするべきなのだと思われる。
    しかしながらシェルのインデントはかなり面倒くさい。
    特に if, then, else, while, do, done 等については現在の解析では状態を記録していない。

    関連してコマンドが閉じていない時 RET を押すと改行挿入にするという物がある。
    この機能を実装する為にも現在の入れ子の状態を調べる仕組みが必要になる。
    RET で改行挿入にする機能のほうが幾らか単純なので、
    それを先に実装してからこれを実装する方が良い気がする。

  * vi-mode: 関連して [/ 等の実装についても調べたい。

    既に vim-surround.sh で類似の機能について実装したが、
    [/ についても個別に実装したい所である。

    他にテキストオブジェクトで [{ [} [( [) などと同等の機能も実装している。

    [# [' [( [* [/ [` [D [I [P [p [[ [] [c [d [f [i [m [s [z [{ [<mouse2>
    ]# ]' ]) ]* ]/ ]` ]D ]I ]P ]p ][ ]] ]c ]d ]f ]i ]m ]s ]z ]} ]<mouse2>

  * vim-surround: ds cs インデント

    surround.vim では改行が絡むとき = によるインデントを実行している。
    現在 vim-surround.sh ではインデントを実行していない。

    2017-10-09 追記

    yS ySS でもインデントは起こる様である。
    更に、xmap S でもインデントを行う (xmap gS はインデントは行わない)。

2017-09-17

  * cmplstofB: ビジュアルモード・選択モード?

    関連 #D0672 選択モード対応

    * テキストオブジェクトで範囲を選択し、また範囲を拡大する。

      どうやらテキストオブジェクトの拡大では左右の両端からの拡大を試みるような気がする。
      決して右端からテキストオブジェクトを拡大するというわけではないようだ。

      というのも変なところから初めて (...) の中に右端を移動して、
      その上で ib としてもエラーになるからである。或いは短くなる。
      どうも ib の動作としては左端から外側の ( を見つけて、
      それに対応する ) を右端に直すようである。

      うーん。これはテキストオブジェクトによって動作が異なるのかもしれない。
      aw などは明らかに右に向かって拡大を行っている。
      因みに矩形選択かどうかは気にしないようだ。
      同じ動作をする。行の右端に行くと次に次の行に普通に移動する。

    2018-02-22 現状の xmap におけるテキストオブジェクトの状況について整理する。
    - ble/keymap:vi/text-object/word.impl に於いては既に xmap での振る舞いに対応している様子である。
    - ble/keymap:vi/text-object/quote.impl は明らかに対応していない→対応した #D0670
    - ble/keymap:vi/text-object/block.impl も対応していない
    - ble/keymap:vi/text-object/tag.impl も対応していない
    - ble/keymap:vi/text-object/sentence.impl も対応していない
    - ble/keymap:vi/text-object/paragraph.impl も対応していない

2017-09-16

  * cmplstofB: vim-surround.sh: ds cs cS yS ySsd ySSd S gS 'C-s' 'C-g s' 'C-g S'

    現在のところ特に要望は出ていないが ds cs あたりは使いたくなるのではないかと思われる。
    → ds cs に関しては要望が出たので対応した。
    → cS yS ySs ySS vS vgS にも対応した。

    残っているのは imap <C-s> <C-g>s <C-g>S のみである。

2017-09-15

  * cmplstofB: here string 候補について

    here string 候補にファイル名以外のものがあれば対応する。返信待ち → やはり候補は難しい。

    コマンド名に応じた補完関数の設定を可能にする?
    例えば python3 に対する here document の場合には、import を補完候補に出すなど。

    2018-10-02 C++ の場合にはこんな感じに clang を呼び出せば良い様だ。
    clang -cc1 -fsyntax-only -code-completion-at=test2.cpp:7:7 test2.cpp
    http://d.hatena.ne.jp/ohtorii/20110319/1300514225

    Here document で補完候補を出す為には、
    Here document の内容 (先頭から現在位置まで) が
    単純内容 (単純単語に近いがシェルの特殊文字を使える) でなければならない。
    その為の関数を追加する必要がある。simple-word の実装を真似れば良い。

2017-08-19

  * [保留] cmap/default.sh: "CAN @ ?" 代替?

    "CAN @ ?" は "C-x C-x" と較べて曖昧ということで現在無効にしている。
    これの代替キーシーケンスを定義しても良いかもしれない。
    といいつつ現実の端末に存在するものを登録しなければ意味がない。
    (そういう意味では "CAN @ ?" もこれに対応する現代的な端末が実在するのか怪しいのであるが。)

    思うに s-x だとか H-x だとか A-x を送りたければ CSI 2 7 ; ... ; ... ~ を使えば良い。
    何故 Emacs が "CAN @ ?" に対応しているのかは謎である。

    →実はこれは isolated esc と同じ方法を用いて区別して受信可能かもしれない。
    しかし、何れにしても "CAN @ ?" に対応している端末は殆どないので、対応する理由がない。
    https://superuser.com/questions/407391/super-key-over-ssh によると Konsole がこの形式を使うそうだ。

2017-03-04

  * syntax: bug ヒアドキュメントによる nparam の更新が追いついていない。

    これは何でかというと nparam の計算に stat 保存点を超えた過去の情報を用いているからである。
    部分更新をしている為に過去の情報が書き換わったとしても
    stat 保存点で解析状態が一致したと見なされてしまい、
    其処で解析が中断してしまうのがいけない。

    これを解決する為にはヒアドキュメントの word に相当する部分は
    一気に解析する様に修正しなければならない。
    結局 word 部分は最終的には独自の方法で読み取るのが良い様な気がする。

    或いは暫定的に範囲を指定して stat を消去する様な機能があったような…?
    →昔その様な処理の仕方をしていたような気がするが、いま確認してみるとない。
    恐らく何か問題が色々生じて結局その方法は使わないという事になった様な気がする。
    記憶が正しければそれは time ... や function func () だとか func () を解析する時の話だった。
    結局何れの場合でも一回の解析で行けるところまで解析するという事になった。
    ヒアドキュメントでもその様に実装するのが一貫している。

  * syntax: ヒアドキュメント 終端 word 着色

    todo: 取り敢えず RDRS 等と同様に完全に入れ子を追跡する様に実装する。

    $() ${} の入れ子も含めた実装が必要になる。

    実は、通常通りに解析してしまって、
    後の着色で一様な色に塗り潰してしまうという方策で良いのではないか。
    しかしそれだと tree-enumerate の際に $() の内部で着色が起こる気がする…。
    % 特に部分更新などをすると確実に内部での着色が発生するのでは…??
    % →部分更新の時は一番外側の単語についても着色が判定されるから特に
    % 部分更新仮想で内科に依る違いは発生しないと思われる。

    取り敢えずの実装として通常通りに解析する様に変更した。
    単に ble-syntax:bash/ctx-heredoc-word から
    ble-syntax:bash/ctx-redirect に処理を委譲するだけで良かった。
    ヒアドキュメント特有の処理は ble-syntax:bash/ctx-heredoc-word/check-word-end
    の方にしかなかったからである。
    また、同時に CTX_RDRI, CTX_RDRH の単語を上から塗りつぶす様にした。
    しかし、やはり予想通り $() の内部などの単語の着色は発生してしまっている。

2017-03-02

  * syntax: パラメータ展開・算術式評価内部の quote 除去が為されない状況での _ble_syntax_attr

    以下の項目で対応しきれなかった (対応しないことにした) ものをここにまとめる。
    cf. #D0375 "2017-03-02 [2016-08-06] syntax: extquote と "${}" の入れ子に関して"

    > - $(()) の中の () のネストに関しては対応していない。
    >   つまり () が一つでも挟まれば quote 除去が有効であるかのように着色される。
    >   →これは対応した。

    - $((a['1+1'])) などの添字の quote 除去は有効であるが、現実装では quote の着色はしていない。
      つまり $(('1+1')) などと同様に quote 除去が為されない物として着色を行っている。

      これに対応する為には $(()) の中でも [] に対応するネストを判定する様にしなければならない。
      ※一方で [] の中では () に対応するネストの判定はしなくても良い。

    - $(("${hello}")) などの構造では CTX_QUOTE の中で自身が有効かどうかを判定して
      自身の着色を変更したりするのは面倒なので、普通に (有効であるかの様に) 着色している。

      算術式の場合には quote 除去されないと分かっている時点で文法エラーになるので
      1文字目をエラーの色にするというので良い気がする。
      パラメータ展開の内部の場合には quote 除去されないからと言ってエラーにはならない。

    - bash では "${var# ... }" の中の '' は quote 除去される一方で、
      "${var:- ... }" の中の '' は quote 除去されない。
      この実装では取り敢えず quote は除去されるという取り扱いである。

      これらについては包括的に振る舞いを調査する必要があるだろう。
      他にも様々な種類のパラメータ展開があるし、
      また将来的に各種類のパラメータ展開についての詳細な構文解析にも対応する可能性がある。
      (特に ${var//a/b} の quote (\?) の取り扱いがややこしいのでこれは視覚的に分かる様にしたほうが良い。)

    - 現状では $(("a")) はエラー着色になっているが実は文法的に有効である。
      同じクォートでも $(('a')) や $((\a)) は文法的に駄目。

    - Bash 5.1 以降では (('a')) がエラーになる様に文法が変わった。

2016-07-15

  * isearch: 現在の履歴内の位置を % で表示しているが、
    これは検索の進捗状況の表示の方が分かりやすいのではないか。

  * complete: declare の引数を特別扱いしているがこれも compgen があればそれに従うべきでは。
    もしくは、何か特別な処理をするとしても compgen を介して特別な処理をするべきではないのか。

    現状の実装だと、declare などの変数を宣言する組み込みコマンドについて、
    ユーザが complete によって補完の制御を行う事ができない。

2016-07-08

  * prompt: 最終行・先頭行に何か表示する機能があっても良い。

2016-07-07

  * isearch: 正規表現検索?

    →取り敢えず vi-mode で実装した #D0513。incremental ではない。

    正規表現で incremental にすると一度通り越したものに一致する可能性があるので直観的でない。
    もし incremental にする需要がある場合には再度考える必要がある。
    因みに、emacs は (分かりにくい動作だが) 現在の位置から続きの検索をする。

  * edit: 置換モード (正規表現・固定文字列・globパターン)?

    その為には置換前・置換後を入力する欄を別に表示する必要がある。
    入力欄でも様々な binding が使えた方が嬉しい。

2016-06-22

  * tui: prompt-toolkit という物がある様だ。ちょっと観察してみるのも良い。

    基本的には補完候補を勝手に出すという事と、
    表示の仕方が emacs auto-complete と同様に
    overlay によって実現されているという事。

    所で overlay で実現するためには複数行で編集を行っている時に、
    下の行にある内容を記憶しておく必要性が生じる。
    Emacs の場合には表示している内容を完全に内部に保持しているので問題にならなかった。
    (a) 現在の実装で実現するためには内容を完全に記憶するか、そうでなければ
    (b) 複数行で編集を行っている場合には枠の位置・大きさを変更する際に
    毎回下の方にある行を再描画するかといった事が必要になるだろう。

    Bash では 2 次元配列を実現するのは辛いので
    結局内容を完全に記憶するというのは余り嬉しくない事だろうか。
    と思ったが、表示領域の幅 (COLUMNS) さえ把握しているのであれば、
    実は 1 次元配列の上に terminal の内容を保持してしまっても問題ない気がする。
    というか枠の大きささえ決まっていれば普通に sub window の様な物も
    bash で実現する事ができる。今まで余り考えたくないとして避けていたことだが、
    この方法ならば楽である。

  * tui: GUI Window System を整える? Window を出したり消したりだとかそういう事。

2016-04-05

  * tree-enumerate による skip の実装と解析一時中断の不整合に関して。

    ble-syntax.sh: ble-syntax/parse/shift.impl2 の問題点である。

    現状の方法では、解析一時中断を行った時に shift 対象の高速な列挙が出来なくなる。
    唯一の現実的な高速化手法は "直前非空白要素の位置" を管理するように変更する事である。
    これは解析自体の動作とは全く関係なく、_ble_syntax_tree/stat/nest の配列としてのデータ構造を拡張するという事である。
    解析自体の実装とは直交して実装する事が可能と思われるが、新規情報の管理コストが増えるという問題点が残る。

    →一方で tree-enumerate を使った場合には閉じている単語内部の shift を省略できるなどの利点がある。
      最終的にはこれらを組み合わせたような shift が必要になるだろうと考えられる。
      もう少し詳しく考察を行う必要性がある。

2015-12-20

  * complete: 履歴を用いた候補生成? 特に単語について。

    2018-09-23 これは動的略語展開によって部分的には対応された。
    しかし処理の重さから一度に全ての候補は計算しないし、
    また文法的な単語ではなくて COMP_WORDBREAKS によって分割された単語である。
    これを本当に対応しようと思ったら background でプログラムを
    走らせるなどの事が必要になる気がする。

2015-11-21

  * 公開までに追加であった方が良いかも知れない物

    + 拡張性の提供 (拡張の仕方の説明)
      + theme の枠組を整える事 (setting files の置き場?)
        ble-color-list
      + 文字コード拡張 (Unicode との mapping)
      + 端末制御コード拡張
        tput からもっと積極的に読み込むべきなのでは?
        cmap/default.sh に加えて cmap/tput.sh 的な物も?
        > minimal.sh, xterm.sh, rosaterm.sh の整理。

    + 簡単なキーボードハンドラのサンプル (テトリスとか? 或いは sentaku 再実装とか)

      サンプルとしては、端末の出力画面に現れる物よりは、
      画面を altscreen で完全に切り替える物の方が実装しやすいと思われる。
      それでいて、read -t 0 などを有効に使えるとなるとテトリスなどになるだろうか。

    + マウス対応

    + キーボード入力内容を全部 vbell で表示する方法?

2015-11-06

  * まったく同じ nest 状態になると思われるのに解析中断が起こらない

    ☆これは表面上は何の問題も起きない。多少無駄な処理をするだけである。
      従ってそんなに対処に緊急を要しない。

      | function ble-syntax/parse/nest-equals {
      |   local parent_inest="$1"
      |   while :; do
      |     ((parent_inest<i1)) && return 0 # 変更していない範囲 または -1
    -->     ((parent_inest<i2)) && return 1 # 変更によって消えた範囲
      |
      | local _onest="${_tail_syntax_nest[parent_inest-i2]}"
      | local _nnest="${_ble_syntax_nest[parent_inest]}"
      | [[ $_onest != $_nnest ]] && return 1
    変更によって消えた領域を指している場合は、
    既に消えた領域のデータを捨てているので nest の判定を行う事ができない。
    そんな訳で解析中断はできないと判定されてしまうのである。

    ここで解析中断を出来るようにする為には消えた領域のデータも取って置いて、
    その上で全く同じ解析結果になったら解析中断を行う、という事になろう。
    以降の解析の動作に違いがなければ良いのだから
    過去の nest の状態だけが一致していれば解析中断には充分である。
    これは別項目として独立させて残す事にする。

    ※問題は解析領域拡大によって i1 が後退する事によって
      変化の無かった部分についても解析結果が消去されてしまう事にある。

2015-08-20

  * エラー検出・表示の管理について

    現状

    現在エラーは様々な方法で使用者に対して提示している。
    解析の途中状態で既にエラーと分かる物については
    _ble_syntax_attr に ATTR_ERR を設定している。
    これは _ble_highlight_layer_syntax1_table を経由して表示の着色に反映される。
    もう一つのエラーの種類は入力したコマンドラインの末端で入れ子が閉じていない物である。
    これは一番最後の文字と対応する入れ子の開始点の色を変更する事によって提示する。
    この着色は解析点より前に対して行われるので部分更新の対象とする事は難しい。
    従って _ble_highlight_layer_syntax3_table を介して、毎回全消去・再計算を実行している。

    以下に改善したい箇所について列挙する。

    - この様に複数の方法を用いてエラーを提示しているのは少し醜い。
      もう少し統一した枠組を作っても良いのではないかという気がする。

    - ATTR_ERR を用いて設定したエラーは、
      後の処理で追加される単語毎の着色によって上書きされてしまう。
      つまり、折角エラー通知の為に着色を設定していても使用者に見えない事がある。
      別の場所にエラーを登録しても良いのではないかという気がする。

    - 各エラー項目に対して何が問題なのか・何のエラーなのかのメッセージを設定したい。
      これらのメッセージも枠組の中で管理して、カーソルの位置に応じて表示できる様にしたい。

    もう少し現状について調べて実装の方法について考える。
    先ずエラー情報を記録する為の配列の形式について。
    既存のエラー着色に使っている配列 _ble_highlight_layer_syntax3_table が気になる。
    これを拡張する形で実装する事はできないだろうか。。
    →この配列は部分更新できないような情報を保持するのに使っている。
      部分更新できない様な着色であっても今回の実装によって
      よりましな方法に変更できるのではないか、という気もするが、
      それは今回の実装が終わってから考えれば良い事である。
      (初めからその様な物にも対応できる様に今回の実装を設計するという事も出来るが
      複雑になるので、取り敢えずは何も考えずに実装する事を目指す。)

    つまり、_ble_highlight_layer_syntax3_table は non local な着色の為に使うとして残し、
    それとは別にエラーを管理する為の配列を作成する。

    部分更新の際の効率を考えると _ble_syntax_attr と同様に、
    編集文字列中の位置を配列のインデックスとする方法が良さそうに思われる。
    然し一方で、エラーの数はそんなに沢山になるとは考えがたい (sparse) なので、
    リストにして管理するという方針も考えられる。どちらの方が良いだろうか。
    リストにしている場合、"エラー設置点 エラー開始点 エラー終了点 メッセージ" というデータ形式になるだろうか。
    shift や解析中断後の再開に際してはエラー設置点を用いた filtering を行う。
    % このエラー情報の内容は解析の動作に全く影響を与えないし、
    % 解析が同じように進めば全く同じエラー情報を生成すると期待できるので、
    % 解析中断の判断基準に含める必要はないと考えられる。
    →本当だろうか。エラー開始点・終了点などの情報は解析状態が同じになっても異なる値になりうるのでは?
      特に、現在 _ble_highlight_layer_syntax3_table で管理している物はその最たる例である。
      ここで、エラー開始点・終了点が正しく設定される為には次の条件が必要である。

      エラー設置点を p1 とする。ble-syntax/parse の 1 step で i=i1 から
      i=i2 まで進む (但し i1 <= p1 < i2) 時、エラー開始点 p2, 終了点 p3 は、
      i1 <= p2 < p3 < i2 を満たす。

      この条件が揃っている時のみに現状の解析中断条件で部分更新安全である。
      因みに p2, p3 を設置点からの相対位置で記録しておけば shift の操作が必要なくなるのでその様にするべきである。

2015-08-16

  * 入れ子構造を考慮に入れた効率的な単語着色

    現状: 新規生成単語及び消滅単語の範囲 (range1) に関して再度単語の着色を実行する。

    x 但し、着色は "消滅単語の存在していた範囲" 及び "新規生成単語登録位置の範囲"
      に登録されている単語及びその子孫だけになっている。
      本来は、range1 に被さっている全ての単語について処理を実行するべきである。

    - 考慮に入れるべき事として、将来的に解析を途中で停止した場合でもそれなりに動くような方法がよい。
      しかしながら未だ解析を終えていない部分については結局どうしようもないから、
      解析が完了している部分文字列について木構造を作成して処理する事になるだろう。
      結局、現在 shift を実行するのに用いているのと同じ事をする事になる。
      (そしてそれは tree-enumerate/.initialize で実装されているので余り気にする事はない。)

    方法

    a 一つの方法は tree-enumerate を使用して末端から順に単語の範囲をチェックしていく方法である。
      つまり、現状の shift の実装と同じになっている。

    b もう一つの方法は、先に単語の木構造の情報だけ構築してから、
      range1 に対応するノードを列挙して構築する方法である。
      木構造として親ノードの位置・子ノードの配列を保持していれば、
      指定した範囲に対応するノードの範囲を効率的に計算する事が出来る。

      ただし、木構造の情報の構築自体にどれだけのコストがかかるかについて考える必要がある。
      木構造は後ろから掘り出すようにして実行する為、
      更新範囲の beg から文字列の末端 iN 迄を完全に構築し直す必要がある。
      部分更新するというのが難しいと思われる。

      しかし、部分更新は全くできないのでは等と考えていたが、
      考えてみると意外と部分更新も出来るのではないかという気になってくる。
      更新範囲に含まれていないノードの内部構造に関しては実は更新の対象ではない。
      また、更新範囲より前にあるノードの内部構造についても同様である。
      但し、親ノードの位置は、更新範囲より前にあるノードであっても更新する必要がある。

    c 或いは、parse の過程でより分かり易い木構造データも同時に構築してしまうという手もある。

      x parse の内部状態を増やせば増やす程、解析中断が難しくなるが
        最終的に構造を再構築するのであれば結局中断してもしなくても同じかも知れない…?
        しかしながら木構造を考えずに parse した後、木構造に対する更新を行った方が処理量は少なくなるはずである。
        というのも木構造を考えながら parse する事にすると、
        更新の必要のない文法的処理も木構造の構築と同時に実行してしまうからである。
        それよりは、文法的処理で必要最低限の所を parse で処理して、
        木構造の構築について必要最低限の所を後の処理で実行する、という形の方が良さそうである。

      o ただ、parse の過程で木構造も一緒に構築するようにした方が、
        データ同士の依存関係が整理されて良いという側面もある。
        parse の後で木構造としてどの範囲を更新するべきかを決定するのは面倒でありバグを生む原因にも成る。
        →parse の後で処理をする際にも何らかの "原則" を決めてその下で実装するなどした方が良いと思う。
        (逆に言えば上手に原則を決める事さえ出来れば、parse で木構造を構築する事の利点はなくなる。)


    入れ子構造の実装後に改善できる箇所
    - tree-enumerate-in-range 及びその呼出元
      現在は愚直に範囲内に設置されている単語識別子を

2015-08-15

  * syntax: `function ...' において関数名の部分に使用した履歴展開を解釈する?
    履歴展開だけを解釈する新しい文脈が必要になると思われる。

    然し乍ら、履歴展開の結果として複数の単語になる場合などを考えると、
    そもそも一つの単語として読み取って良いのかなど疑問点が残る。

    % 或いは、その場で履歴展開としての妥当性を検証して色をつけてしまうという手もある?
    % →これだと正しく解釈されない。例えば履歴展開には $ が含まれて良いが関数名には $ が含まれないので、
    %   先に関数名としての切り出しを実行すると $ の直前で不正に関数名が中断する事になる。

2015-08-14

  * 高速化: ble-syntax/parse: より厳密な shift 範囲の特定・省略?

2015-08-11

  * 今後必要になる大きな書換・再実装は2つある:
    1 コマンドライン着色の効率的方法の模索
    > 2 shift の高速化の為の _ble_syntax_word, etc. のデータ構造の変更

2015-02-24

  * layer の仕組みに対する問題提起

    | 現在の実装では各レイヤーは下のレイヤーが提供した文字配列を弄る事によって動作している。
    | しかし、実の所受け継ぐのは文字配列ではなくて描画属性の配列の方が良いのではないだろうか。
    |
    | o 先ず第一に実装の簡便さがある。
    |
    | o 次に、更新範囲というのは複数のレイヤーで似たような箇所になりがちなのではないかと思う。
    |   属性の配列で渡して置いてから一番最後の所で更新範囲に対して切り貼りをして文字配列を構築した方が良いかも知れない。
    |
    | x ただ、文字配列にするという事の利点も存在する。
    |   region 等の様に大域的に色を一時的に変更する様な物の場合、
    |   文字配列として region の下層にあるレイヤーについて記録を行っておく事は有意である。
    |   選択が解除された時に再び構築し直すというのは時間が掛かる。
    |
    |   但し、その様な動作をする物は限られている様にも思われる。
    |   殆どの場合には纏まった箇所でコンパクトに更新が行われる。
    |
    | x 括弧の対応などの場合、まとめて描画属性から文字列を構築する場合に細かい最適化が出来ない。
    |
    |   複数のレイヤーの描画属性の配列からまとめて文字列を生成する場合、
    |   複数のレイヤーが報告した更新範囲を総合してその範囲で文字列を再生成する事になる。
    |   しかし、括弧の対応など、実際の変更が小規模に渡るにも拘わらず、
    |   離れた二点で実施される色付けの場合には、変更の実体に反して範囲が拡大する。
    |
    |   今迄の様に文字列を各層で構築する方式の場合には、
    |   更新を各層の関数の中で自由に行う事ができるので、
    |   自身の変更の update に関しては最適な方法で更新する事ができる。
    |
    |   とはいいつつも更に上のレイヤーに渡す更新範囲はやはり巨大な物になる為、
    |   上のレイヤーでの合成作業が大域に渡る事は考えておかなければならない。
    |   実のところ合成作業についてはちゃんと実装していない。
    |   region に関しては可能な限り最適な方法になる様に実装したが滅茶苦茶複雑になった。
    |   実際の実装では被覆によって隠される更新などについては考慮に入れなくても良いが、
    |   複雑になりそうだという事に代わりはない。
    |   結局、内部的に描画属性の配列を持って更新に望まなければならないという事態になりそうだ。
    |
    | 何れにしても現在の実装は、今後拡張していく上で非現実的な感じがする。
    | ベースを (下層の情報を含まない) 描画属性の配列を上流に渡す方法に変更した方が良いのではと思う。
    | region 等の実装の際には cache を行う様にする等の工夫をその上で実装する様にしてみたい。
    |
    | また、実装が複雑になるが仕様がない。
    | 取り敢えず現在の所まともに着色を行っている所が syntax だけなので、
    | これを ble-highlight-layer:syntax に対応する上で考えてみる。
    |
    | ble-highlight-layer:syntax の内部で三つの描画属性の配列を用意し、
    | これらの三つの描画属性の配列を総合する事で文字列を構築する様にしてみた。
    | 可もなく不可もない感じの実装である。
    | 少なくとも各層で文字列を構築する様な実装はしたくない。
    | これぐらいが丁度良い実装の複雑さである様に思う。

    将来的には描画属性の配列で対応できる様にする。

2015-02-23

  * bleopt_suppress_bash_output 制限

    - SIGWINCH (ウィンドウサイズ変更) の時に bash の表示する物になってしまう

  * 描画ちらつき: DCH や ICH 等を用いた効率化?

2015-02-18

  * エラーメッセージの設定を可能にする

2015-02-16

  * syntax: ToDo

    - [[ 条件式の文法。より正確に。特に括弧の入れ子。

      →括弧の入れ子というのはどういう意味であったか?
      今試してみた所括弧の入れ子などは関係なく ]] が来れば条件コマンドは終了とみなされる様である。
      例えば $ [[ ( [[ == ]] ) ]] は構文エラーになる。初めの ]] で条件コマンドが終了と解釈される為である。

2013-06-10

  * sword で quote を正しく処理する?
    これは少なくとも解析器が出来た後に考える。

2013-06-01以前

  * ble-decode
    + [kbd] terminfo からの読み取り (entry 名は tmux が参考になる)
    * ble-bind: -s オプションで文字入力の羅列を指定できる様にする (2019-02-10 #D0915 で実装)

  * 説明書
    + 文字コード decoder の追加方法
    + keysequence を指定する文字列の文法 (2018-09-23 done)
    + スタイルを指定する文字列の文法 (2018-09-23 done)

    取り敢えず GitHub の Wiki 上に作る事にした。


*******************************************************************************
    Done (実装ログ)
-------------------------------------------------------------------------------

2023-04-03

  * main (adjust-builtin-wrappers): IFS= が設定されてしまう @ bash-5.0 (reported by pt12lol) [#D2030]
    https://github.com/akinomyoga/ble.sh/issues/311

    POSIXLY_CORRECT=y の環境で IFS= ble/bash/read を実行していた為に IFS= が関
    数呼び出し後も残る様になってしまったのだった。

    ? 然し不思議なのは何故か bash-5.0 だけで振る舞いが再現するという事。
      bash-5.1 以降は関数呼び出しの変数代入は posix であっても環境に残らない様
      になっているのは良い。然し、bash-4.4 以前については bash-5.0 と同様に環境
      に tempenv が残る様に見える。何故この時にだけ問題がないのだろうか。或いは、
      何処か別のレベルで local IFS が設定されているという事か、或いは呼び出し元
      の local POSIXLY_CORRECT=y は影響を与えないという事なのだろうか。よく分か
      らないが取り敢えずは問題は封じた筈なので気にしない事にする。

    取り敢えず関数呼び出しの前に変数代入を置かない様にする。明らかに ble.sh の
    内部だけで使われる関数については気にしなくて良い。util.sh の一般のライブラ
    リ関数についてはちゃんと posix を避ける様にする事にする。

    ? これよりも前には問題にならなかったのかというのが疑問である→どうも試して
      みた所 read や builtin read では tempenv は posix モードであったとしても
      環境には残らない様である。つまり、本当にシェル関数特有の振る舞いだったと
      いう事である。

      builtin read から ble/bash/read に置き換えられたのが a5b10e8b である。こ
      れは #D1981 に関係している。

2023-04-02

  * bgproc: bash-4.2 での bgproc#start で {bgproc[0]} は存在しないというエラーメッセージ [#D2029]

    これは exec {fdvar}redirect で発生しているエラーだった。bash-4.1,4.2では
    {fdvar} の fdvar として配列要素には対応していない。

  * bgproc: シェルの終了時に即座に強制終了するオプションをつける? (motivated by bkerin) [#D2028]
    https://github.com/akinomyoga/ble.sh/discussions/309#discussioncomment-5498921

    然し実際にそれが良い事なのか分からない。というか現状の実装ではそうはなって
    いないのだったか? → child session はちゃんとすぐに終了する。然し端末が閉じ
    ない。これは stderr, stdout, stdin の何れかが未だ開いたままになっているのが
    原因と思われる。

    .kill ではちゃんと全部閉じている筈と思ったがよく考えたらスタートしたプロセ
    ス自体が stderr を保持しているのが原因の気がする。

    そのまま強制終了するというのもどうかという気がするが、それならばそれで良い。

    * done: 或いは終了チェックの interval をより短くする。これは
      ble/util/bgproc#stop/.wait で使っている 1000 という値を設定できる様にすれ
      ば良い。然し、これを変更したとして実際に終了にかかる時間がそんなに速くな
      るのだろうか。

      うーん。或いは conditional-sync の progressive-weight を使う? と思ったが
      conditional-sync は新しいサブシェルを待つ物なので単に或る条件を待つという
      事には使えない。conditional-sync を拡張して任意の条件を待つ事ができるよう
      にする可能性も考えたが、

      a うーん。或いはコマンドを開始するのではなくて既存のプロセスを待つという
        機能を持たせる? この時に conditional-sync に足りていないのは kill を二
        段階で行う機能である。SIGKILL を送る様にするオプションは実装しているが、
        kill で駄目だった時に段階的に SIGKILL を送るという機能は実装していない。
        そういう機能も追加して良いかもしれない。

        うーん。取り敢えず conditional-sync を2回呼び出して二回目で SIGKILL を
        指定すれば良いのだと気づいたので conditional-sync 自体に段階的に kill
        を実行する機能は実装しなくて良かった。

      b 或いはコマンドが空の時には指定された条件だけを待つという振る舞いにする。
        この場合にはコマンドの kill までは実行しない。

      然しもし原因が .kill の interval による物なのだとしても、
      stdout/stderr/stdin を封じている限りは生きているというのは .kill が原因な
      のではないのでは? 然し、プロセスが瞬間的に終了する事ができなかった場合に
      は .kill による自動 kill が起動する迄は bgproc が保持している stderr が開
      いたままである。然し、その場合には timeout になるまで相当待たなければなら
      ない (既定では 10sec である。或いは SIGKILL まで更に 10sec ある)。

      * ok: と思ったがもしかすると .kill 自体が fd を保持しているから bg
        process が終了しない可能性? と思ったがそれも変だ。.kill 自体は fd を閉
        じてから呼び出している筈 → 実際に確認した。

    ? ok: ところで set -m して起動した bgproc のなかで更にパイプやサブシェルな
      どを立ち上げた時に更に別の PGID になっているとその別の PGID までは kill
      しきれないのでは。なので set +m を中で実行しなければならないのでは。

      →と思ったが、実験してみた限りでは set -m が実際に効果を持つのはそれを呼
      び出したサブシェルだけの様である。なので更に入れ子で呼び出された物に関し
      ては敢えて set -m を実行しない限りはちゃんと元の pgid に属する様になって
      いる。

    即座に終了する方法について考えたがこれは単に kill-timeout を 0 に設定すれば
    良いのでは。結局向こうで起こっている事が何か分からないのでどうしようもない。

    * 2023-04-03 うーん。即座に終了しないのは subshell の stdout/stderr/stdin
      を閉じていても、ble/fd で保持している fd が残っているからでは。
      ble/fd#finalize を呼び出せば良いだろうか。或いは tty に関しては
      ble/fd#finalize での自動 close を抑制していただろうか。

      →確認してみると ble/fd#finalize には tty は登録されていない様だ。という
      か寧ろ msleep 等が使っている fd を削除してしまう様だから中で sleep が使え
      なくなってしまう。ble/fd#finalize は呼び出しても仕方がない。

      うーん。待避している fd を閉じても駄目の様である。どうも builtin exit 0
      を呼び出して終了しようとしているのだがその時に redirect をしている。その
      redirect によって保管している fd が未だ生きている様だ。つまり、本当に全て
      閉じようと思ったら redirect によって保管している物も全て閉じる必要がある。
      すべて閉じる為には fd を列挙しなければならない。

      a 一定の範囲の fd を全て閉じる? linux (もしくは bash) は現在の所は 255 付
        近に redirect にの fd を保管している様だが os によってはもっと巨大な値
        に保存しているかもしれない。なので可能性のある fd を全てスキャンすると
        いう訳にも行かない気がする。

      b 或いは /proc/$BASHPID/fd の中にある物を全て閉じる? 然しこれも使えるシス
        テムが限られている。

      また fd をスキャンして閉じるとしても msleep 等が使っている fd を閉じてし
      まうとサブシェルの動作に問題を起こしてしまう。これについては -t で判定し
      て端末だけを閉じる様にすれば良い気もする。

  * make: インストール時に元のコメントなどの情報への pointer をつける (suggested by bkerin) [#D2027]
    https://github.com/akinomyoga/ble.sh/discussions/309#discussioncomment-5498921

    make_command.sh install からでは元のソースがどれかは原理的には分からないが、
    取り敢えず現状では ble.sh 以外は全て対応するファイルが同名で存在しているの
    で、その仮定の下でファイル名を含める事にした。ble.sh についても ble.pp と
    src/*.sh を全て含める事にした。

    果たしてコメントを削除しないインストールが本当に必要なのかは謎だが一応機能
    としてはつけておく事にした。何れにしても元々ある日本語のコメントは個人用の
    物であって他の人に見せる為のものではない。

  * bgproc: bash-3 で idle.cancel がないと表示される [#D2026]

    実装を改めて確認してみたらそもそも bash-3 に対する考慮が全く入っていない。
    然し、将来的に bash-3 でも idle を使える様にする可能性を考えると単にバージョ
    ンで判定するのもよくない気がする。結局 function#try で調整する事にする。

2023-03-26

  * menu-complete (linewise): 長い行がある時に表示が崩れる (reported by bkerin) [#D2025]
    https://github.com/akinomyoga/ble.sh/issues/307

    これは実装を詳しく調べてみたら選択時の部分更新の時の幾何を記録する部分で、
    描画範囲を限定した時の記録が残っていないのが原因だった。そもそも linewise
    は試験的に最初に実装したもので余り真面目に実装されていない感じがする。その
    後で desc の実装でもっとちゃんと実装されてその時に限定された描画範囲につい
    てちゃんと対応が行われている。その desc に使われた仕組みを linewise からも
    使うだけで良かった。

    然しそれとは別に長い候補を入力した時に panel の高さが変わった時に menu の高
    さを制限した上で再描画を行う仕組みが欲しい。これについては簡単ではなさそう
    なので別の項目で議論する事にする。

2023-03-16

  * edit: bind -x で PS1 も一時的に復元する (requested by adoyle-h) [#D2024]
    https://github.com/akinomyoga/ble.sh/issues/304

    lincheney/fzf-tab-completion で退避中の一時 PS1 が表示されるというから何か
    と思ったら自分で PS1 を出力しているのだった。

  * 2023-03-06 menu-complete: 番号で選択する (requested by bkerin) [#D2023]
    https://github.com/akinomyoga/ble.sh/discussions/284

    これは実は実装はそんなに大変ではない気がする。

    LASTWIDGET のチェックは必要?  否、他のものは全て抜けるから関係ない? と思っ
    たが TAB や cursor key 等の移動コマンドの後も番号はリセットしたい。なのでや
    はり LASTWIDGET はチェックする。番号が溜まって一致する物がなくなったら一つ
    ずつ古い文字を削除して一致するものが出るまで削る。一つも一致しなかったら削
    る前にリセットして新しい文字自体をなかった事にする?

    試しに実装してみたが操作性に疑問が残る。先ず menu-complete の中に入らないと
    番号で選択できない。一方で、menu を表示しているだけの場合にも選択しようとす
    るのが自然の気がする。

    a menu-complete の外からでも M-0 等で選択できる様にするとしても
      menu-complete に入らずに select しても仕方がない。

      もう一つの問題点は menu が表示されていたらどの文脈であっても M-0 で menu
      に入ってしまうのかという事。auto-menu を実装していたりすると実質的に M-0
      は常に menu に入ってしまうという事になり操作できない。或いは、TAB を二回
      押した時に complete に入るのと同じ様に、LASTWIDGET が complete だった時に
      M-0 で menu-complete に入るというのは手の気がする。

      更にもう一つの問題点は menu の中に番号を表示していない時でも番号による選
      択を有効にするのかという事 → これは M-0 等のキーを使っている時点で、実際
      に番号が表示されているかどうかに関係なく menu-complete に入るという事で良
      い気がする。

    b 或いは、menu-complete の外で M-0 等で引数を入力し始めたらその場で
      menu-complete に入るという可能性も考えられる。

    * どの menu-style についても番号を表示する機能が欲しい。

      設定名を変更する?

        bleopt menu_item_prefix
        bleopt menu_item_prefix_linewise
        bleopt menu_item_prefix_align
        bleopt menu_item_prefix_desc

      と思ったが現在の設定名は他の設定と共に menu_STYLE_NAME の形で一貫している。
      これを壊すのも変な気がするので、既存のルールは保持する。全体の設定を一括
      で変更するオプションを用意したい気がするが、その名前は何にするか。単に
      menu_prefix で良いだろうか。

        bleopt menu_prefix
        bleopt menu_linewise_prefix
        bleopt menu_align_prefix
        bleopt menu_desc_prefix

      取り敢えず align と desc について候補番号に対応した。dense は対応していな
      い。が、完全性を期する為にはやはり dense も対応した方が良い気がする。→対
      応した。

    * done: wiki, blerc: menu_prefix, menu_{aling,dense,linewise,desc}_prefix

    * 返信

      for key in {0..9}; do ble-bind -m vi_imap -f "$key" 'append-arg enter-menu'; done
      for key in {0..9}; do ble-bind -m menu_complete -f "$key" 'menu/append-arg always'; done

2023-03-14

  * 2021-10-26 ble/builtin/read: WINCH を受信できていない気がする [#D2022]
    もしかすると subshell の中では受信できないという事なのかもしれない。

    2023-03-14 winsize を更新する関数を作ったのでこれにも対応する事にする。

    % と思ったが WINCH を受信できていない? 問題は WINCH を受信しても LINES
    % COLUMNS が更新されない事と思ったが、そもそも WINCH を受信できていないという
    % 事なのだった。
    % →即時 WINCH を受信できる訳では無いがユーザーが文字を入力した時にちゃんと
    % 受信できている。

    subshell の中で実行するとちゃんと内部で設定した trap が発火している様に見える。

    * fixed: ble/builtin/read/TRAPWINCH でも update-winsize を呼ぶ事にした。と
      思ったが 個別に色々処理するよりも単にここで ble/application/onwinch を呼
      び出してしまうのが自然である→その様に修正した。

    x fixed: "bash: ble/term/visible-bell:/clear: そのようなファイルやディレク
      トリはありません" というエラーが発生する。/clear は
      ble/term/visible-bell/.erase-previous-visible-bell から呼び出されるが、こ
      の関数は $_ble_base_run/$$.visible-bell.* に属している物を全て削除しよう
      とする。なので subshell で設定された物も削除しようとする。

      この時親 shell で一度も visible-bell を使っていないと visible-bell が初期
      化されていない状態になっていて問題が生じる。

      或いは subshell で発生した visible-bell は subshell だけで管理する事にし
      て subshell を抜ける時に始末する事にする? subshell というか read を抜ける
      時に処理すれば良い → read を終了する時に visible-bell/erase を呼び出して
      消去する事にした。C-c を押した時には結局中断して駄目なのでは? と思って試
      してみたが C-c の時にもちゃんとその場で visible-bell/erase が呼び出されて
      いる様なので、C-c もちゃんと ble.sh の上で処理されているという事なのだろ
      う。

    実際に read -ep でも WINCH もちゃんと発火している様に見える。LINES, COLUMNS
    も更新されている。それなのに textmap が更新されていない様な気がする → と思っ
    たが textmap を更新した後に出力して確認していたので更新されていない様に見え
    ただけだった。ちゃんと更新されていて新しい端末幅を反映した値になっている。
    ずれて見えたのは単に端末の折り返しによって行が増えている事による物だった。

    ? reject: redraw-here がちゃんと働いていない様な気がする? と思ったがそもそ
      も幅が縮まった時には、縦に内容がはみ出てしまってその分まで遡ろうとはしな
      いので、現在見えている振る舞いが元々意図した物である気がする。なので気に
      しない。

    * fixed: サイズの変更があった後に read を中断すると親のプロンプトが表示され
      てから [EOF] 等のマーカーが表示される。何故?

      うーん。read -ep ; read -ep をコマンドから実行すると一つ目の read と二つ
      目の read の間で既にプロンプトを表示しようとしている。SIGWINCH が走ってそ
      れで再描画が起こっている?

      ble-edit/attach/TRAPWINCH ではちゃんと _ble_term_state を確認しているのに
      何故かそれをすりぬけて表示が実行されている。_ble_term_state が一時的に
      internal になっている様に見える。

      と思ったら分かった気がする。ble/builtin/read/.impl の中で一旦
      ble/term/enter してその後で ble/term/leave している。この ble/term/leave
      するよりも前に WINCH が走って其処で internal 状態にあると勘違いしてプロン
      プトが表示されてしまうということの気がする。何故 subshell の中で実行しな
      いのかというと C-c やその他の事故で subshell が予期せず終了した時に状態の
      復元に失敗しない為だろうという気がする。

      →これは ble/application/onwinch を呼び出す時の条件を増やして対処する事に
      した。

2023-03-13

  * trap: winch の様々な問題 [#D2021]

    * fixed: bash-4.3..5.0 で ble-reload 後に WINCH が効かない

      一方で Cygwin の bash-4.4 で ble-reload した後に WINCH が正しく処理されな
      くなっている。chatoyancy 上では bash-5.2 も 4.4 もちゃんと動いている。

      builtin trap WINCH 自体が発火していない様だ。一方でウィンドウサイズを変更
      した後は謎の PS1 への代入ジョブ (終了ステータス 127) が表示される。而も、
      その PS1 に代入される値は現在の値とは関係ない。

      うーん。chatoyancy でも 4.4 で再現した。histdb を無効にした状態で reload
      すると動かなくなる。bash-5.2 では問題になっていない。5.1 でも OK。5.0,
      4.3 は駄目。bash-4.2 はちゃんと動いている。つまり 4.3,4.4,5.0 の問題。何
      故 reload だと駄目なのだろうか。

      詳しく調べてみると ble-detach してから ble-attach すると再び動く様になる。
      これは要するに rl winch hook のインストールが関係しているという事ではない
      か?  確認してみると実際に winch が再設定されている。既存の trap を確認し
      てみると、空になっている。つまり unload の時にクリアされているという事。

      unload-for-reload から呼び出している時には WINCH を削除しない事にした。動
      く様になった。因みに INT についても同様の処理はしなくて良いのか? と思った
      が取り敢えずは問題は起こっていない気がするので気にしないことにする。現在
      は WINCH だけ特別扱いする。

      x この実装だと元々存在していた user WINCH trap が消えてしまうのではないか。
        →実際に確かめてみたら消滅する。別の変数に記録しておく事にした。別の変
        数に記録しておいた物を拾う処理をする為に、今まで内部 trap を install 済
        みの時に単に return 0 していたのを trap_string, trap_command を空にして
        処理を続ける事にした。取り敢えず動いている。

    ? ok: bashrc で ble-attach しても WINCH はちゃんと有効なのか? bash-4.3 以外
      は大丈夫。

    * ok: bash-4.3 で WINCH が即時発火しない問題

      逆に bash-4.3 は最初から ble-attach しても prompt attach しても WINCH が
      全然発火していない。というか 4.3 は --norc で起動して WINCH に trap した
      としても WINCH が発火しない。次にユーザーが入力を試みた時に初めて発火して
      いる。逆に言えば 4.3 では入力を開始すれば何れにしても正しい幅で描画される。

      これは取り敢えず入力を開始さえすれば直るので取り敢えずは気にしない。

    * fixed: bash-5.2 でコマンド実行中にサイズ変更が発生した時に反映されない問題

      うーん。全てのコマンドを実行する度にサイズ再取得を実行する必要があるか?
      或いは idle で処理する必要があるかもしれない。

      できるだけ高速に判定する方法が欲しい。複数のコマンドで速度を比較する?

      stty size, resize, tput lines cols, bash -c

      試してみた所、tput が最も速く、その次が stty、更に resize が来て bash -c
      による方法が最も遅かった。一方で、stty size は ble/term/stty/enter で呼び
      出している stty とくっつけることができる。取り敢えず優先順位として stty,
      tput, resize, bash の順に試し、stty による実装が使える場合には
      ble/term/stty/enter の stty 呼び出しを修正する方法も考慮に入れる事にした。

      取り敢えず実装した。動いている。

  * edit: WINCH で拡大した時のサイズの変わり方が変だ [#D2020]

    調べてみると onwinch が入れ子で呼び出されている。SINGWINCH の処理が入れ子に
    なっている。bash 自体は入れ子にはしていないが、read-timeout が WINCH 発火を
    遅延していて、read-timeout の中から主導で呼び出した WINCH の中で、更に trap
    WINCH が発火している様だ。

    一方で、ble/application/onwinch の実装を見ると入れ子で呼び出した時の対策は
    ちゃんとしてある様に見える。

    うーん。ble/application/onwinch の中では何れにしても一切の更新処理は実行し
    たくない。ble/application/onwinch を抜ける時に改めて処理を行いたい。

    ? 今の実装だと _ble_decode_hook_Processing=body|prologue の時に winch を受
      け取ると後の ble/application/render の際に無駄に二回描画される気がする。
      どうせ onwinch の中で ble/application/render が発生するのだから、直接
      ble/application/render を呼び出せば良いのではないか。

    取り敢えず onwinch 全体を WINCH の抑制対象として onwinch の末尾でも WINCH
    の発火が途中であった時に onwinch を呼び出す様にした。ble/application/render
    の前に onwinch があった時には ble/application/render をせずに最初から
    onwinch をする様にした。実装した。動いている。前よりも素早い動作になった。

  * execmark: wrong usage (2), command_not_found (127) 等の文字列 [#D2019]
    https://qiita.com/Linda_pp/items/1104d2d9a263b60e104b に面白い記述がある

    /usr/include/sysexits.h に幾らか値が定義されている様だ。EX_USAGE..EX_CONFIG
    が 64..78 に定義されている。

2023-03-12

  * global: ret が leak する様になっている [#D2018]

    だいぶ遡ってもずっと leak している。何故だろうか。取り敢えず最新版で修正した。

    * ble/util/bgproc#keepalive がリークしていた
    * ble/complete/sabbrev/expand もリークしていた

    →ずっと遡っても発生している ret の上書きはどうも ble.sh --norc で発生して
    いる? 調べてみると任意のキー入力の後で低確率で発生している様に見える。或い
    は auto-complete が関係しているのだろうか。

    * 結局 emacs keymap の __after_widget__ に問題があった。
    * 更に類似の呼び出しで PS0 についても ret の leak があった。両方とも直した。

  * bgproc: histdb から切り離して再利用可能にする (motivated by bkerin) [#D2017]
    https://lists.gnu.org/archive/html/help-bash/2023-03/msg00068.html
    https://github.com/akinomyoga/ble.sh/issues/302#issuecomment-1462977627

    * done: ble/opts#has バグ修正。影響は cmdspec_opts の plus-options だけの様だ。
      全然判定できていなかった。常にほぼ false になっていたと思われる。

    * done: ble/util/bgproc 既に開いている prefix を指定した場合は以前のものは
      削除する。

    * done: 複数のプロセスが走っている場合に対応できる様にプロセスグループを作
      らせる事にする。set -m を実行すれば良い。

      * done: 実は負の引数を kill -0 に渡すことでプロセスグループの何れかのプロ
        セスが残っているかどうかを判定することができると分かった → これを利用
        して改めて kill 部分の処理を作り直した。

      * done: どうやらコマンド置換の中でやるとプロセスグループが作られない様だ。
        なので bgpid=$(set -m; bgproc & echo "$!") ではなくて ble/util/assign
        bgpid '(set -m; ...)' とする必要がある。

        一方で、そもそもコマンド置換にしていた理由はあったのだったか。もし別の
        理由があったのであればそれについても () で壊れないか確認する必要がある。
        調べてみるとコマンド置換を使っていたのは最初からで (#D1925) 特に考察は
        していない様に見える。取り敢えず普通のプロセス置換にしても大丈夫。

        修正した。

    * done: EXIT (もしくは internal_EXIT) に自動で登録する?

      →と思ったが単なる close ではなくて EXIT の時に特別の処理をしたい時に
      EXIT もしくは internal_EXIT を設定していると、期せずして先に bgproc#close
      されてしまって後処理ができなくなってしまう。

      a うーん。後処理を行いたい場合の為に internal_EXIT に登録しない設定を作る?

        特に指定しない場合に自動で終了処理を追加するとしても、internal_EXIT で
        呼び出して良いのだろうか。他の EXIT 処理が bgproc を利用したいという場
        合に問題が起こる可能性がある。という事を考えると、EXIT の方に登録するべ
        き? 然し EXIT の方に登録したとしても呼び出しの順序によって変なことが起
        こる可能性がある。

      b reject: bgproc/onclose:prefix の中で EXIT 処理を実装してもらう

        別の方法として bgproc#close の中で終了処理としての close なのか一時的な
        close なのかを判定して各自処理を切り替える方針で実装してもらう? しかし
        これだと bgproc が生きていても死んでいても実行するべき処理の場合に困る。
        単に bgproc#close からの呼び出しを期待していると bgproc が走っていない
        場合にその処理が呼び出されなくなってしまう。それに分かりにくい。

      取り敢えず owner-close-on-exit と no-close-on-exit を opts として指定可能
      にすることにした。

    * fixed: unload の時にも同様に呼び出すべきなのではないか? というか寧ろ今ま
      で EXIT でやっていたのは unload でやるべきだったのではないか。

      →histdb と bgproc の両方を EXIT ではなく unload を使う様に変更した。

    * done: close-callback は関数に置き換えるべきなのでは? 結局 bgproc#close を
      呼び出す必要があるのであれば、opts の中に直接コマンドを記述するよりはちゃ
      んとした関数を定義して関数名を close-callback に指定することになるが、そ
      うであるのならば最初から関数名を ble/util/bgproc/close:_ble_histdb 等に固
      定してそれを直接呼び出す様にした方がわかりやすい。

      また callback の中で ble/util/bgproc#close を呼び出すのも一見して無限ルー
      プになるのでインターフェイスとして分かりにくい。それよりは単に close 直前
      の終端処理として呼び出す様にするのが良い気がする。それでも
      ble/util/bgproc#close を入れ子で呼び出した時の対策は今のまま残しておく事
      にする。

    * done: request を送る機能 & 死んでいたら再始動する機能

      timeout でデータを削除してしまうと restart 時に問題なのでは? なので
      timeout 時には [4] だけ消す事にする? timeout で終了した場合と期せず終了し
      てしまった場合は区別するべき。

      適当にいい加減な bgproc を作って動作確認した。取り敢えず簡単な使い道の範
      囲ではちゃんと動いている様である。

      また help-bash で提供されていた例に関しても cotnrib/config/github302 に実
      装してみて動作確認した。動いている気がする。

    面倒なので取り敢えずこれで push する事にする。何れにしても histdb は未だ実
    験中でドキュメントにも記していないし、また例として実装した perlre-server も
    help-bash / GitHub #302 の為の例に過ぎないので寧ろテストしてもらうぐらいで
    良い。

2023-03-10

  * complete: complete_source_sabbrev_ignore が動いていない [#D2016]

    * done: そもそも全然動作していなかった。修正した。

    * fixed: opts の方も動作をチェックする。no-empty-completion は '\' から始め
      ても候補が生成されない様だ。うーん。COMPV ではなく COMPS に対して適用する
      べきである。

    * done: wiki, blerc: complete_source_sabbrev_{opts,ignore}

2023-03-09

  * readonly blacklist のチェックを m scan に含める (motivated by mozirilla213) [#D2015]
    https://github.com/akinomyoga/ble.sh/issues/289#issuecomment-1457920928

    * done: m scan

    * done: readonly でファイル名・行番号を表示する。

    * done: 警告の表示の回数上限はパス毎に決める? (dict が使えない場合を除く)

      →一回表示した(パス,行,変数)の組み合わせに関しては二度と表示しない様にす
      る。トップレベルの呼び出しの時には回数上限を使う。

    * done: 回数上限はコマンドラインの実行ごとにリセットする?

    2023-03-10 ちゃんと動いていない。FUNCNAME を最後の要素までチェックする事にした。

  * complete: option:source を他のコマンド名として呼び出せる様にする (requested by mozirilla213) [#D2014]

    complete: progcomp_alias と同様の処理をその他の補完生成の時にも行う
    https://github.com/akinomyoga/ble.sh/discussions/287

    と思って source:options の実装を確認したが既にちゃんと alias を考慮した処理
    になっている。

    より詳しい設定について尋ねたら返信が戻ってきた。要するに、他のコマンドのオ
    プションを別のコマンドの補完に表示したいという事らしい。これに関しては自前
    で新しい補完を定義する必要がある。

    * done: それと現在の source:option の生成はコマンド名を決め打ちにしているの
      で、それを関数に切り出して調整可能にしたい。取り敢えず source:option を真
      ん中で分割した。

    取り敢えず試しに簡単に実装してみて振る舞いを調べる。動いている気がする。

2023-03-08

  * contrib: sabbrev 補完候補を生成しない設定 (motivated by mozirilla213) [#D2013]
    https://github.com/akinomyoga/ble.sh/discussions/288#discussioncomment-5159335

    これを contrib に入れて改良する。例えば simple-word eval する。argument か
    ら呼び出された時にだけ不活性にする。ADVICE_FUNCNAME で本来の FUNCNAME を記
    録する (もしくは function#advice 側で advice 関連の FUNCNAME を削除した物を
    取得して返す関数を作る?)。

    ble.sh 側でも sabbrev は empty completion しない設定や、literal sabbrev 候
    補の生成を抑える設定などを考えても良い気がする。etc.

    bleopt complete_sabbrev_opts=no-empty-completion:literal

    うーん。実装仕掛けたがこれは literal を実装してからにするべきの気がする。取
    り敢えず inline, linewise sabbrev を実装した (#D2012)。

    改めて考えてみたが取り敢えず literal sabbrev の類いは wordwise ではないので
    source:argument では生成しなくて良いという気がする。後になって欲しくなった
    らその時に考える。

  * 2021-05-19 sabbrev: 単語でなくても任意の文脈で発動する sabbrev が欲しい [#D2012]

    \ 等で前置すれば特に問題ないのではないか? 然し、その為には全ての場合につい
    て一致するかどうか確認する必要がある。

    2023-03-08 どうも実際に \ に色々割り当てて使おうとしている人がいる様だ。こ
    の用途だと実際に単語でしか発動しないというのは困るのではないだろうか。
    https://github.com/akinomyoga/ble.sh/discussions/288#discussioncomment-5226973

    例えば ble-sabbrev --literal 的なオプションにするのはどうだろうか。通常の
    sabbrev が見つからない場合に --literal sabbrev を試みる。literal sabbrev に
    関しては -m は対応しなくて良い (もしかしたら最終的に実装する可能性もあるが
    今ではない)。

    ? resolved: 取り敢えず literal という名前で実装したが本当にそれで良いのか。

      % literal というと -m の反対という気もするし、そもそも sabbrev 自体が
      % literal である。元々伝えたかったのは文法情報等を無視した sabbrev という
      % 事だった。例えば context-free sabbrev expansions 等の方が自然の気がする。
      % 然し、context-free を表現するオプション名として適切な物が思い浮かばない。
      %
      % a 何も考えなければ頭文字の -c だが、実際は context 依存の逆という事なの
      %   で変な気がする。
      %
      %   或いは漢字変換的な使い方を想定して conversion の頭文字と取る事もでき
      %   る?  然し漢字変換というとどういう名前だろうか。IME と考えて -i とする
      %   か。然しそれだと i は input の i なので一般的すぎて微妙? 否、input 専
      %   用と思えばやはり良い? 然しオプション名が例えば input-no-insert だとよ
      %   く分からない。やはり実際の呼称と紐づいたオプション文字にしたいと考え
      %   ると呼称自体から丁寧に決めたい。
      %
      % b context に依存しないという意味でやはり literal 的な要素があって、そう
      %   思うと -l でも良い様な気もしてくる。
      %
      % c -c の逆という事で -C 等を使うという可能性もある? がやはり分かりにくい
      %   気がする。
      %
      % d -f はどうだろうか。ble-bind -f (bindable Function) という既存の例があっ
      %   てその印象があるが、それを抜きにすれば悪くない気はする。然し、やはり
      %   自然かというと疑問が残る。
      %
      % e 英小文字にしたい。という事を考えると片っ端から可能な物を列挙して考え
      %   てみても良いのかもしれない。zsh alias で既に使われているオプションは
      %   避けたい。
      %
      %   zsh alias で使われているのは gmrsL である。grs はそれぞれ alias の種
      %   類を指定する為のオプションで、-g はグローバル alias (ble-sabbrev に対
      %   応)、-s は suffix alias (拡張子展開)、-r は通常 alias である。-m
      %   PATTERN はまとめて複数の alias を glob で指定するのに使う。-L は現在
      %   の alias の定義を出力するのに使われる。
      %
      %   ble-sabbrev では -P を出力に使いたい気がする。
      %
      %   * -a は grep の -a の様に文字列 (ascii) をそのまま解釈するという意味
      %     に使えるかもしれない。
      %
      %     或いは anywhere という意味にも取れる。これが良い気がする (anywhere
      %     という意味に取れば every where -e もありかもしれないが -e はより色々
      %     な意味に取れそう)。でも anywhere というのも微妙なのは、anywhere と
      %     言いつつカーソルの直前で起こる必要があるという事。何処からスタート
      %     しても良いという意味での anywhere であるが、それを表現するのに丁度
      %     良い別の表現はあるだろうか。
      %
      %   * -b は backward?
      %   * -i は inplace という漢字がするけれど違う気もする。
      %   * -djkwyz ???
      %   x -e は grep の様に次に通常のパターンが来るという意味の引数に使えるか
      %     もしれないが、それはいま目的としている物とは違う気がする。
      %   x -gs は既に zsh で別用途に使われているので混乱の元
      %   x -n は特別な効果を全て削除しているという雰囲気が出るかもしれない? で
      %     もやはり変な気がする
      %   x -o はオプションを指定しそうな気がする。
      %   x -p は出力という漢字がする。
      %   x -q は quoted という感じがするが現在の目的からすると混乱の元
      %   x -t は tail という意味に取れる気もするがそもそも sabbrev は常に末尾
      %     にカーソルがある時に発火している。これは context-free sabbrev 特有
      %     の特徴ではない。類似の考えで -h (here) 的なものも駄目。
      %   x -u は変更のある項目の選択に使いそう? でも ble-sabbrev に既存設定や
      %     既定値などない為、登録されている全ての物が変更ありになるのでこのオ
      %     プションをその意味で使っても意味がない。
      %   x -v も literal 的なものを想起する。C-v 関係だろう。然し、これも現在
      %     の用途に合っているかというと微妙な気がする。
      %   x -x は何か実行しそう。
      %
      % 長い呼称を先に決めてからそれの短縮オプション文字を決めるのが良さそう。
      %
      % literal-no-insert, conversion-no-insert, contextfree-no-insert,
      % inplace-no-insert, inword-no-insert 等。うーん。inword が良い気がしてき
      % た。類似の物として inword subword, substr, substring, suffix, 等。
      % inword だと空白も含む略語展開に合わないし、丁度単語に一致している時も変
      % な気がする。代わりに inline というのも良いのかもしれない、と思ったが
      % sabbrev 自体既にある意味で inline なので混乱の元かもしれない。唯の置換
      % と思えば substitute だとか replace だとかもありなのだろうか。然し、これ
      % も sabbrev 一般の性質を表して言えるのに過ぎない。

      うーん。コマンド行全体に作用する sabbrev も定義したくなって来た。それも定
      義すれば全体として consistent になる気がする。

      →結局 -l (--linewise) 及び -i (--inline) を両方定義する事にした。これが
      インターフェイス的にも分かりやすい。

    * done: 取り敢えず実装仕掛けた literal は inline に変更する。と思ったが、-il
      をまとめて linewise と呼ぶ事にする。

    * done: wordwise vs literal は最長一致に変更する。呼び出し元で一々指定しな
      くて良い様にする。同時にどの種類の展開が起こったのかを取得できる仕組みを
      作る。文字で返すのが良い? もしくは終了ステータス?

    * done: 現在の実装では inline も単語で切ってから判定しているが
      _ble_edit_str 全体に対して適用するべきの気がする。

    * done: 呼び出し元に展開の種類を返す機能。

    * done: ble-sabbrev の -mil は全体に作用する様にインターフェイスを変更する。

    * done: ble-sabbrev に long option を用意する事にする。

    * done: wiki: ble-sabbrev -il

    * done: wiki: edit_magic_opts
    * done: blerc: edit_magic_opts

    * done: -w で通常の sabbrev の種類を選択できる様にする。通常の sabbrev を選
      択するのに毎回 --type=wordwise としなければならないのは不便である。

    ? resolved: linewise は本当に linewise と呼んで良いのか? コマンドライン全体
      に一致するのだから bufferwise とか whole とか all とか exact とかにするべ
      きなのでは。或いは実際に linewise に一致する様に変更した方が便利? その時
      にはインデントも許す様にする。extglob を一時的に有効にしないと面倒だろう
      か。

      [[ $1 == "$key" || $1 == *$'\n'*(["$sp"])"$key" ]]

      或いは $'\n' で切断して trim しても良いかもしれないと思ったがそうすると今
      度は key に改行や空白が含まれていた場合に都合が悪い。それに trim は regex
      を使っているので別に extglob よりも早いとも限らない。

      extglob は実装の問題から遅くなる可能性があるがそれは気にしない事にする?
      と思ったが現在の codebase では extglob はほぼ使っていない。というか確認し
      てみたらユーザーの提供したパターンなどを評価するときを除いて全く使用して
      いない。なので、ここでも使わない実装を目指したい様な気もする。

      というか最初に末尾が $key に一致するか確かめてその上で残っている文字列に
      対して regex で確認を行えば良いだけなのでは? その様に実装する事にする。

  * 2023-03-02 complete (source:argument): sabbrev 候補が気になるのは最初に表示されるから? (motivated by mozirilla213) [#D2011]
    https://github.com/akinomyoga/ble.sh/discussions/288

    後ろに回した方が良い気がする。修正した。

    コマンド補間についても同様ではないか? と思ったが変数名よりは sabbrev の方が
    先に来て欲しい。コマンド名と sabbrev だとどちらが先にくる事を期待するのかは
    微妙である。コマンドは基本的に大量にある。一方で、sabbrev は有限個である。
    具体的にコマンド名を入力してコマンド名が絞れてきた頃には sabbrev も絞られて
    いると期待される。なので、コマンド名に関しては表示しなくて良い気がしてきた。

    然しそう考えると引数の場合も本当に sabbrev を後回しにするべきなのか分からな
    い。と思ったが、引数補間の場合にはオプションの数は少ない可能性がある。一方
    で予め定義しておいた sabbrev が大量に存在している時には、sabbrev 候補で全部
    が埋め尽くされて実際に知りたいオプションのリストを見る事ができなくなる。な
    のでやはり引数補間の場合には sabbrev 候補は後ろに回すべきである。

  * [棄却] prompt: $PWD in airline が更新されない? [#D2010]
    https://github.com/akinomyoga/ble.sh/discussions/294#discussioncomment-5227252

    bind -x の中でディレクトリを移動してもそれが反映されたりされなかったりする
    という事。うーん。\w を使っていればちゃんと反映されるのではないか。

    直接 $PWD があれば自動的に抽出される筈だし \w や \W があっても抽出されるの
    では? と思ったが、勝手に変更をリアルタイムで追跡するのは変だという事になっ
    た様な気もする。例えばコマンド終了直後の値を表示しておきたいのにすぐに変わっ
    てしまっては困るのである。

    然しそうだとしても別の理由でプロンプトの再評価が起こった時に結局表示が更新
    されてしまうのだから、そういう揮発性の情報を表示する時には元より ble.sh で
    はちゃんと別の変数に記録しておく必要があるのではないか。

    →実際試してみると \w にしておけばちゃんと反映される。$PWD だと反映されない。
    section 毎のキャッシュがちゃんと働いているからであろう。

    これに関しては更新したければ適切に設計する必要がある。

    * ok: wiki に説明を書く? と思ったら既にちゃんと add-hash が記述されていた。

    実際に簡単なものを作って実演してみる(以下)。動いている。これは後で返信する。
    これに関しては現状で修正する事はない気がする。

      function ble/prompt/backslash:mypwd {
        ble/prompt/unit/add-hash '$PWD'
        ble/prompt/print "$PWD"
      }
      bleopt vim_airline_section_c='\q{mypwd}'
      bind -x '"\C-t": cd - &>/dev/null'

  * complete: limit line length for auto-complete [#D2009]

    "a @b" の時に @ に { を入力すると固まる

    どうも a5b10e8 で問題が発生する様になっている。うーん
    ble/application/render で固まっている。となるとやはり文法が関係しているので
    はないか。という気がする。調べて行くと textmap#update で時間がかかっている。
    どうも巨大な文字列が自動補完で挿入されてそれの解析で時間がかかっている様だ。
    長さ 50170 になっている。

    x fixed: 自動補完で limit が効いていないのは何故か? line_limit_length は
      10000 の筈である。それの5倍の長さになっている。

      →挿入の時点では replace-limited を使っている。然し、何故かそれをすり抜け
      ている。うーん。line_limit_type が editor で、editor の場合には
      replace-limited の時点では何も行わない。__line_limit__ という名前の特別な
      キーが送信されてくる仕組みになっている。

      誰が __line_limit__ を送っているのかというと ble/content/check-limit とい
      う関数である。そしてこの関数はどうやら ble-decode/EPILOGUE から呼び出され
      ている。丁度最後の render を呼び出す直前である。期待としては表示を試みる
      前に editor が起動されるという事だが、auto_complete の中にいるので
      __line_limit__ が単に無視されてそのまま描画ルーチンに入っているということ
      の様だ。

      うーん。そもそも auto-complete に入るのが間違いの気がするので
      auto-complete/enter の時点で reject する様に修正した。

    x この巨大な補完候補は何処から生成されているのか? histdb? → どうやら
      histdb の様である。とても長い単語が登録されているのだろう。histdb の側で
      余りに長い物は除外するべきだろう。登録する時点で保持する? それとも補完す
      る時点で保持する?

      取り敢えず今はテストの為にこの長い単語を保持しておく事にする。

    x ok: 幾ら文字列が長かったとしても 50k 程度でフリーズするのは変な気がする。
      何故?

      →調べてみたら textmap#update で 20s かかって update-syntax (parse) で
      39s かかっている。更に何処かで 20s ぐらいかかって最終的に表示される。
      textmap#update は全ての文字の表示位置を計算しているので遅い。parse は勿論
      時間がかかる。その他も何か一つずつ処理しているか何かなのだろう。つまり、
      何処かが特別に時間がかかっているのではなくて、全体的に処理に時間がかかっ
      ているということの様だ。

      うーん。これは結局単に時間がかかっているというだけの事。

    * histdb: もし巨大な単語が紛れ込んでいたとしても検索の時点で文字数に制限を
      かける事はできないか→取り敢えず検索の時点で文字数に制限をかける事にした。
      動いている。

  * edit: ~name による "named directory" 展開機能? [#D2008]
    https://github.com/akinomyoga/ble.sh/discussions/299

    sabbrev の新しい展開の種類として実装する可能性? チルダ展開と同じ文脈で活性
    化して、それが直前の単語に含まれていた場合に展開する。コマンド実行前に展開
    する機能は混乱の元なので実行したくない気もするが…。

    * 然し ~xxx の状態で展開されていないと補完が効かない気がする。補完する時に
      内部で ~xxx も考慮に入れて候補を生成するのは大変だ。なので補完を試みる前
      に展開するべきの気がする。/ を入力する瞬間か或いは補完を実行する直前か。
      うーん。というか magic-insert という widget を作る方が良い気がして来た。
      それで / も magic-insert にしてしまう。

    * 同時にコマンド実行の瞬間に全体をスキャンして展開する仕組みを作っても良い
      気がする。

    % 取り敢えず magic-insert は実装する。実装した。
    %
    % さて、ここでの疑問は既定で / magic-insert を設定しておくべきかどうかという
    % 事。というか / で履歴展開が実行されると困るのでは。なので、一部の展開だけ行
    % うべきの気がする。というか alias 展開も実行したくない。
    %
    % やっぱり現在の振る舞いは space だからこそ動くのである。magic-insert はやめ
    % る事にする。

    色々考えると / に対しては sabbrev だけ行う関数を定義するべきの気がする。
    magic-slash を実装してみた。

    x done: 然し、tilde 展開を装っている場合に普通と違うのは変数代入形式の引数
      の右辺で : 区切りの位置の最初から sabbrev expansion を試みる必要があると
      いう事。

      と思ったがこれは通常の sabbrev expansion でも対応するべきの気がする。うー
      ん。対応した。

    ここでの疑問はこの magic-slash を既定の binding として登録するべきかどうか
    という事である。或いは ~ で始まる物だけを magic-slash で変換の対象とする?
    或いは / に感応する sabbrev の category を新しく作る? うーん。~ で始まる物
    だけを特別扱いするのが良い気がする。

    * done: wiki

    * done: slash-strip: magic-slash で挿入を行う場合は元から sabbrev の定義に
      含まれる末尾の / は削除する。

    * done: slash-strip: -m の方も対応する必要がある? と思ったが実際にやってみ
      ると menu-complete が始まった後に / が挿入されて変な事になる。これはちゃ
      んと magic-space でやっているのと同様に処理する必要がある。一意確定の時に
      は slash-strip を自前で処理する。

  * syntax: echo alpha[0]+=~ がチルダ展開として認識されていない [#D2007]
    これは単純なミスだった。修正した。

  * sabbrev: 変数代入右辺での展開の対応 [#D2006]

    変数代入の右辺では右辺に対して sabbrev 展開を行う。: で区切ったフィールドも
    認識する。

    * ok: 然しこれに対応するには複数の sabbrev 展開位置について考慮に入れる必要
      がある気がする。例えば locale-key の context に rhs も対応すれば良い気が
      するが、そうすると今度は通常の sabbrev で = も含めて展開しようとしている
      物が動かなくなる。と思ったが、現在の設定だと = を含む sabbrev はそもそも
      定義できないのでは?なので rhs は含めてしまって良い気がする。

    * done: 変数代入右辺の特定

      実際に変数代入の右辺での sabbrev に対応するとしてどの様にして変数代入の右
      辺を特定するのか。一旦その様な関数を書いたかもしれないと思ったがどのよう
      に探せば良いか分からない。使っていそうな所を探すのが良い気がする。

      arr=([0]=xxx) 及び var=xxx の場合には rhs でちゃんと抽出できている。問題
      は argument の時にどの様にしているのかという事。

      a var=xxx の時にどの様に抽出しているのかを確認すれば良いのではないか?

      b 或いは complete 側で source:argument の fallback をどの様に処理している
        か。うーん。これは単に正規表現で一致させているだけの気がする。

      c と思ったら ble/syntax:bash/find-rhs という名前のそのままな関数があった。
        この関数を使って見る事にする。

      取り敢えず対応した。更に : による区切りにも対応したい気がするがそれは後回
      しにする。と思ったがやはり後になると面倒なのでここで対応する事にする。

    * done: rhs や argument (変数代入) の時に : 区切りで一番近いフィールドに対
      して sabbrev 展開を実行する?

      ":" を含む sabbrev があっても良いが、特に a=...:... の形式をしている時に
      は効かない様にしてしまっても良い気がする。

      a 取り敢えず simple-word で区切る事にした。

      b もっとちゃんとやろうと思ったら文法情報を参照する事もできるかもしれない。

        特に、rhs の文脈では必ず : で stat を設置しているのだから rhs 内部を舐
        めて stat に記録された ctx をチェックすれば良いのでは?

        local i
        for ((i=asrc[1];i<comp_index;i++)); do
          [[ ${_ble_edit_str:i:1} == : && ${_ble_syntax_stat[i]-} ]] || continue
          local ctx=${_ble_syntax_stat[i]%%' '*}
          [[ ${_ble_syntax_bash_command_IsAssign[ctx]-} ]] &&
            ((asrc[1]=i+1))
        done

        と思ったがこれだと $() 等の内部にある : も拾ってしまう。なので本当にちゃ
        んとやろうと思ったら nest 情報も参照しなければならず大変である。今は実
        装しない事にする。

    * done: _a-zA-Z0-9 に統一する。検索しやすい為。

  * complete: adb completion で "no devices/emulators found" というエラーメッセージ (reported by mozirilla213) [#D2005]
    https://github.com/akinomyoga/ble.sh/issues/292

    これは結局通常の bash での TAB 補完でも同様のエラーメッセージが発生するとい
    う事だった。何が問題なのかは分からないが、ちゃんと設定されていない状態で補
    完を試みようとするとエラーメッセージが表示されるという事なのだろうか。設定
    されていても設定されていなくても補完の途中でエラーメッセージは出すべきでは
    ない気がするが、取り敢えずエラーメッセージは封殺する事にする。

    * upstream に報告しようと思ったが何処に報告すれば良いのかよく分からない。
      platform/system/core に昔 adb.bash が含まれていた? ような含まれていなかっ
      た様だ。野良 repository に adb.bash が追加されていて、それが広まったとい
      う可能性もある。或いは、大本の repository では管理していないが配布アーカ
      イブには含まれていた?

      sdk/bash_completion/adb.bash 的な物もあるようだが。これは大昔だ。
      https://android.googlesource.com/platform/sdk/+/3056c8e/bash_completion/adb.bash

      ここにもあるがこれは報告者の使っている物とは微妙に異なる様だ。
      https://github.com/mbrubeck/android-completion

      結局よく分からない。Google が何処か人目に触れないところで最新版を管理して
      いて配布しているという事なのだろうか。

  * decode: M-S-o in konsole? (reported by mozirilla213) [#D2004]
    https://github.com/akinomyoga/ble.sh/issues/298

    これは取り敢えず分かった。 ESC O が他のキーの prefix になっている為に次の文
    字を待っている。失敗した時には decode_error_cseq_discard=1 になっているので
    全体が捨てられる。という事が起こっている。

    x 保留: テストで ESC [ を何回か押していたら無限ループになって死んでしまった。

      何が起こっているのだろうか。ESC { を複数回押したのがよくなかったのかもし
      れない。 M-{ は補完をブレース展開で全て挿入する機能になっていて、空のコマ
      ンドラインで実行すると全てのコマンド名をブレース展開で挿入する事になる。
      とても長いコマンドラインになって処理に時間がかかっていたのではないか。

    * reject: charseq 毎に timeout を設定できるようにする機能についても考えたが、
      必要性がない気がする。そもそも keyseq に timeout を指定できる様にしたのは
      ユーザーがそれで動作を変える (keychord などの様に) ことができるためであっ
      た。然し、charseq にそのような使い方があるとは思えない。また、考えてみる
      と timeout が必要なケースも実はかなり限られている。実は ESC <char> の時だ
      けの個別対応で良い。

    * ok: ESC [ 1 等についても手で入力した場合と続きがある場合で区別が付かない
      のではないか。と思ったが、手で一瞬で ESC [ 1 まで入力することはできないし、
      ESC [ で止まった時点で M-[ に確定する気がする。逆に ESC [ 1 まで一気に受
      信したとしたらこれはより長い CSI シーケンスの一部であると判断するのが自然
      である。なので、 ESC [ 1 等に対して timeout を考える必要はない。

    取り敢えず timeout を設定する事にした。現在の位置で一致するが続きがあっても
    良い曖昧なシーケンスの場合、または ESC を受け取った状態の時には 5ms 待って
    続きが来なければ現在のシーケンスで確定という事にする。取り敢えずは動いている。

    ? yes: vim はちゃんとこの場合に対応しているのだろうか。と思って確認してみた
      らちゃんと動いている。やはりユーザーから文句があったのだろうか。

2023-03-06

  * edit (rps1): PS1 に prompt_rps1 の色が残る (reported by linwaytin) [#D2003]
    https://github.com/akinomyoga/ble.sh/issues/293#issuecomment-1452786142
    https://github.com/akinomyoga/ble.sh/issues/293#issuecomment-1453507285
    Ref #D1972

    今迄問題が生じていなかったのは ble/textarea#render/.show-rprompt の直後にプ
    ロンプト原点以外の場所にカーソルを配置していたので、sgr に色が設定されてい
    たとしても何れにしても goto.draw の際に色がクリアされていたから。

    それが e128801c1 によってプロンプト原点に強制的に戻る様にしたので PS1 の開
    始位置に移動する時の sgr0 が出力されなくなって色が残る事となった。元々移動
    する時に sgr0 を出力したのはそうしないと変な所の色に影響が出てしまう端末を
    避ける目的があったので、元々 show-rprompt で先頭に戻る CR の直前の時点で
    _ble_term_sgr0 を出力するべきである。その様に修正した。

  * contrib/prompt-git: git gc したら branch 名など取得できなくなった [#D2002]

    調べてみるとどうも .git/info/refs の中にまとめて記録される様になった様だ。
    対応した。

2023-03-05

  * コマンドラインに文字列を挿入する関数 (zsh print -z) (requested by mozirilla213) [#D2001]
    https://github.com/akinomyoga/ble.sh/discussions/291

    * done: TMOUT= は ble/bash/read の中で指定してしまうのが良い気がする。
      ble/bash/read を使う時に必ず TMOUT= の設定を試みなければならないというの
      は面倒な契約であるし忘れてしまう可能性が高い。

    * Bash プロセス間通信の整備

      これは何らかのプロセス間通信を実装する必要がある気がする。前々から考えて
      いた枠組みをこれを機に実装してしまうのが良い気がする。さて、何らかのメッ
      セージが来た時にどの瞬間に読み込むのかという問題がある。

      a joblist をチェックするタイミング? 今回の場合に丁度良い気がする。

        joblist.flush は現在は ble-edit/exec:gexec/.end から呼び出している。コ
        マンドを実行していない時の joblist の表示は何処で呼び出している?
        →ble/util/joblist.bflush を .insert-newline の中から呼び出していた。

      b history_share をチェックしている箇所? これはコマンド実行直前、
        discard-line、履歴移動直前等で行っている。今回の場合には余り適していな
        い様に思われるし、一般の枠組みとしても適したタイミングを与える様には思
        われない。

      c 何かキー入力をする度に? 然しこれは何か画面更新をしたい場合等には余り適
        していない気がする。

      d PRECMD と同じタイミングで呼び出すという手もある気がする。と思ったが、
        precmd が呼び出されるのは既に leave-command-layout した後なので不用意に
        何かを出力できない気がする。

        一方で joblist.bflush のタイミングだとしても問題になる様な気がする。

        寧ろ precmd でなにか出力したい時には enter-command-layout /
        leave-command-layout を自分で呼び出して出力する事にすれば問題ない気がす
        る。既に enter-command-layout には呼び出し階層のカウントも実装している
        ので呼び出している箇所が既に command-layout なのかどうかなどについて考
        えなくて良い。更に ble/util/buffer の flush 等についても意識しなくて良
        い。

      % 最終的に複数の処理タイミングの種類を考える必要があるかもしれないが、取
      % り敢えずは a という事にする。後で処理タイミングを追加できる様に最初の実
      % 装から処理タイミングを指定するフィールドを作っておく。暫定的な名前は何
      % にするか。postexec だと複数 exec の時に正しくないし、exec_end にしたと
      % してもまた空のコマンドを実行した直後にも発火することを考えると正しくな
      % い。

      うーん d の方が良い気がしてきた。これにすれば最初の実装における既定の処理
      タイミングに対応する名前も precmd で良くてすっきりする。また、単に
      blehook internal_PRECMD に ble/message.check を指定しておけば良い。

      ユーザーの作成したイベントについても処理できる様にしたい。broadcast の関
      数も作りたい。message という関数も用意する。

      取り敢えず一通り実装した。試験的な handler print で動作確認もした。
      subshell からデータを送信できる事も確認した。

    * コマンドラインへの文字列挿入を実装する。

      コマンド名は何が良いか。ble-print はない。ble insert-string string ぐらい
      にする→結局 append-line にした。文字列を挿入するとしても既に入力されてい
      る行に続けて挿入するのも変である。独立な新しい行を追加するのが自然である。
      すると insert-string よりは insert-line の方が自然である。line は widget
      の名前でもよく使われている。また、現在のカーソル位置などにいきなり挿入す
      るのも変な気がする。コマンドラインの末尾に挿入するのが自然である。という
      ことを考えると append-line が自然の気がする。

      取り敢えず実装した簡単だった。

    ? ok: 特に大量の文字列を挿入する時に何が起こるか? line_limit_length のチェッ
      クはどの時点で入るのだったか → ble-edit/content/replace-limited によって
      挿入している限りはちゃんとチェックが入る様だ。

    o C-o とちゃんと一貫した動作になるか→OK ちゃんと動いている。
    o 複数の append-line があってもちゃんと動くか → 動いている。

    ----

    その他の修正

    * main (read): ble/bash/read で bash-5.2 で -r を付け忘れていた。

    * main (ble): "- " が名前に含まれている ble.sh 関数 "ble-*" も "ble *" の形
      で呼び出せるようにする。

    * util: ble/string#quote-word を set -ue 等で呼び出しても大丈夫な様にする。

    * util: "builtin : >| file" は単に ">| file" で良い。

    * global: builtin read する時の TMOUT= は ble/bash/read の中で指定する

    ----

    2023-03-06 直接 eval するのはやはり変な事が起こりそうで嫌なので is-simple
    の判定だけ行ってから eval する事にした。

    ----

    wiki に ble-append-line の説明を追加した。

    * done: wiki: ble append-line

  * 2022-07-06 highlight: "function aaa bbb ccc" と素早く入力すると変なエラー着色の残り方をする [#D2000]

    % function aaa bbb ccc として C-l すると描画の着色がおかしい。C-l としなく
    % ても高速に入力するとこういう事が起こる様だ。

    素早く入力した時などに発生し C-l で再描画しても残っている。

    調べてみるとどうやらエラー着色が layer に残留してしまうのが原因の様である。

    _ble_syntax_attr/tree/nest/stat?
    06 a    000 'f' |  stat=(CMDX w=- n=- t=-:-)
     | a    001 'u' |
     | a    002 'n' |
     | a    003 'c' |
     | a    004 't' |
     | a e  005 'i' |
     | a    006 'o' |
     | a    007 'n' +  word=CMDI:0-8/(wattr=d)
     3 a    008 ' '
    22 a    009 'f'

    しかもこのエラーは単語着色のエラーではなくて文法的に閉じていない時に実施
    されるエラー着色である。何故この様な中途半端な事が起こるのかよく分からな
    い。うーん。起こる条件が分からない。滅多に起こらない。

    これはなかなか再現しないので別項目にして後で考える事にする。
    →どうも syntax.sh が遅延ロードされた時に発生する様である。

    2023-03-05 SIGWINCH 対策を行った時に改めてこれについて考えた

    | * reject: 文法情報が初期化時に壊れるのは SIGWINCH などによって再描画が解
    |   析の最中に発生するからではないか。その場合には SIGWINCH の処理を延期す
    |   るべきである。というか、それは ble/application/render の時点で入れ子で
    |   render が発生しない様に調整するべきである。→と思って実装を確認したら既
    |   にその様な実装になっていた。
    |
    |   →というか初期化時に壊れるのは SIGWINCH とは関係ない。ウィンドウサイズ
    |   を変更していなくても、文字列を素早く入力するだけで文法情報が破壊される
    |   ので。やはり初期化時に function というのを素早く入力した時に壊れがちで
    |   ある。特に入力し始めた時に未だ syntax がロードされておらず白黒の状態の
    |   まま入力した後に発生する気がする。
    |
    | * reject: ble/syntax/parse の呼び出しを確認してみたが別に入れ子で呼び出さ
    |   れる等の問題が起こっている訳でもない。
    |
    | ble/highlight/layer:syntax/update-error-table の実装が関係している気がす
    | る。特にコメントアウトされている syntax3_table をクリアする行を入れる様に
    | してみると問題は発生しない。うーん。_ble_highlight_layer_syntax3_list に
    | 登録されているエラーを削除する事になっているが、この配列に登録されている
    | データが壊れるか或いは失われるかずれているか、という事なのだろうか。
    |
    | どうも _ble_highlight_layer_syntax3_table の compaction が起こっている様
    | な気がする。というか layer table は shift の対象だと考えると sparse になっ
    | ているのが問題なのでは? うーん。shift の履歴を見ていて気づいた。どうも
    | (DMIN,DMAX0,DMAX) の呼び出しが欠けてしまっている? なので本来挿入されるべ
    | き要素が挿入されずに sparse になって変な事が起こっている。では何故
    | (DMIN,DAMX0,DMAX) が欠けてしまうのだろうか。
    |
    | →つまり遅延して読み込まれているので、読み込まれた後の (DMIN,DMAX0,DMAX)
    | しか受け取れていないという事。

    [原因] core-syntax は遅延して読み込まれる。読み込まれる迄は syntax_buff や
    その他の layer 固有の buffer は更新されない。そして読み込まれた時に空の配列
    として初期化している。

    一方で、これらのテーブルに対して layer/update/shift が呼び出される時、配列
    は前回の更新時の文字列の長さと同じだけの要素を持つ dense な配列であることを
    想定している。ここで実際に要素の足りない配列に対して layer/update/shift が
    呼び出されると意図しない compaction 等が発生してエラーの設置位置がずれてし
    まう。

    [修正] 初期化時に要素の数が足りていない時にはちゃんと補う必要があるという事。
    initialize-vars の時点でちゃんと要素を必要な数だけ入れておけば良い。

    うーん。然し、どの長さを持っている事が期待されているのかは非自明である。

    a initialize-vars の時点での要素数は直前の ble/highlight/layer/update の呼
      び出し時における _ble_edit_str の文字数である。もし現在の _ble_edit_str
      及び DMIN,DMAX,DMAX0 から遡って取得しようと思ったら DMIN,DMAX0,DMAX が記
      録されている場所を知らなければならない。遡っていくと
      ble/textarea#update-text-buffer で _ble_edit_dirty_draw_{beg,end,end0} を
      拾っている。うーん。これを取得するのは複雑だし、edit.sh からの呼び出しを
      仮定する事になる。モジュール外の呼び出し元の情報を参照しなければならない
      のでカプセル化に失敗している。

    b 或いは別の buffer の要素数をそのまま真似するのが良い様な気がする。という
      か plain_buff は必ず存在する事になっているのでその要素数をそのまま真似れ
      ば良いのではないか。

    実際に plain buff の長さを確認してみたらちゃんと期待通りの要素数を持ってい
    る。この要素数を真似て新しい配列を初期化する事にした。動いている。問題は解
    決した様に見える。

  * term (mlterm), vim-airline: prompt_status_line がちゃんとレイアウトできていない [#D1999]

    * mlterm detection

      0;96;0   v3.1.0 (2012-03-24) https://github.com/arakiken/mlterm/commit/6ca37d7f99337194d8c893cc48285c0614762535
      1;96;0   v3.1.2 (2012-05-20) https://github.com/arakiken/mlterm/commit/6293d0af9cf1e78fd6c35620824b62ff6c87370b
      1;277;0  v3.4.2 (2014-12-27) https://github.com/arakiken/mlterm/commit/c4fb36291ec67daf73c48c5b60d1af88ad0487e6
      1;279;0  v3.7.2 (2016-08-06) https://github.com/arakiken/mlterm/commit/24a2a4886b70f747fba4ea7c07d6e50a6a49039d
      24;279;0 v3.7.2 (2016-08-11) https://github.com/arakiken/mlterm/commit/d094f0f4a31224e1b8d2fa15c6ab37bd1c4c4713

    mlterm: どうも status_line の内容がちゃんと表示できていない。カーソルの位置
    計算については今の所問題は生じていない様だが。実際に出力されているシーケン
    スと、それを出力した時に mlterm がどの様に振る舞うかについて確認しておく必
    要がある気がする。

    どうやらシーケンスを生成した時点で何故か一番右のフィールドを折り返してしまっ
    ている様だ。何故?

    最後の全体の trace によって (1\E[80D\E[1B,36) という具合に生成されている。
    二つの問題がある。

    x fixed: sep の幅を 1 と仮定しているので mlterm ではstatus_line に収まり切
      らない内容が設定されている。sep の幅もちゃんと考えて判定を行うべき。

    x fixed: confine が指定されているのにも関わらず何故か折り返されている。これ
      に関しては ros, cols を確認してみた所、何故か 80x24 になっていた。
      status_line の場合には高さ 1 に制限していた筈。或いはその制限を解除する等
      しただろうか?

      →うーん。確認してみたが prompt_rows=24 に明示的に設定されている。どの段
      階で設定されているか確認する事にする。

      ble/prompt/unit:_ble_prompt_term_status/update では prompt_rows=1 を設定
      している。と思ったら _ble_prompt_term_status は別の物であって
      _ble_prompt_status が問題の関数だった。確認してみた所 prompt_cols=1
      prompt_cols=$cols としていてこれは明らかに prompt_rows=1 の間違いである。
      これを修正したら折り返しが被さってしまう問題はなくなった。

    x reject: 初期化時 (char_width_mode 未確定時) に status_line が二重になってしまう問題

      更にもう一つの問題は char_width_mode が response によって変化して再描画が
      発生した時に、以前出力した status bar が残ってしまって二重になってしまう
      問題。

      a WINCH の時には全体をクリアしていたので折り返しがあっても問題がなかった。
        char_width_mode の変更に際しても同様に間にある内容を消去する様にしても
        良いのではないか。うーん。winch の時に何が画面を消去しているのかと思っ
        たが、これは恐らく ble/canvas/panel/invalidate height ではないか。
        char_width_mode=auto 完了時にも呼び出すか?

        x 然し、これを呼び出してしまうと char_width_mode 確定時に結局配置に変更
          がなかったとしても必ず再描画を実行しなければならなくなる。再描画の必
          要が分かった時にだけ消去するという事はできない物だろうか。

      b 或いは bottom-dock の一番上の panel を描画する時点で全消去する? と思っ
        たが行数が分からないので bottom-dock の別の panel を消去しない様にする
        ことができない。

      c 或いは端末からの応答がある迄は描画を開始しない

        x 折角色々の処理を遅延させてプロンプトを先に表示する事によって応答を早
          くしているのに、端末の応答を待つようにしてしまっては意味がない。また
          端末が応答しなかった場合にプロンプトが表示されない事になってしまう。
          短い timeout を設定するとその timeout の間だけ確実にフリーズする事に
          なるので避けたい。また制御も面倒である。

      d もしくは二回完全描画を行い二回目は全消去を実行する。

        これはちらつきが気になるし、殆どの場合には必要にならない二回の描画を毎
        回実行する事になるので避けたい。特定の条件を満たした時にだけ二回完全描
        画にするとしても、完全性を期すのであれば厳密な Unicode version 一致も必
        要になるので問題である。

        とは言っても結局プロンプトは二回表示しているのでは? と思ったがそれは
        git 情報を表示しているから? うーん。基本の設定では、プロンプトは最初に
        一回だけ表示すれば十分という事になっている筈。

      e 或いは vim-airline を char_width_mode 未確定の時には表示しない様にする?

        然し結局応答しない端末が合った時に vim-airline がいつまで経っても表示さ
        れないという問題が発生する。

      f 或いは最初の char_width_mode は安全側に倒して char_width_mode=east にし
        ておく? 然し最近の端末は全て west なので、east を規定値にすると毎回必ず
        再表示が起こってやはり不都合なのではないか。

        ja_JP の時にだけ最初を char_width_mode=east にする? と思ったがそれでも
        mlterm を別の言語で使っている人もいるだろうし、完全な解決にはならない。

        しかし再描画が起こって、プロンプトの配置が微妙に変わるだけであれば大し
        た問題ではないのでは? と思ったがカーソル位置が変わったり、或いは rps1
        の表示位置が変わったり等の事が起こるのはやはり微妙な気もする。うーん。

        x これもやはり応答がない west な端末の場合に問題が持続してしまう。

          最初の描画の瞬間だけ幅を変更する様にしたらどうか。そうしたとしても、
          やはり応答がない端末の場合に変な不整合が起こるかもしれない。次の再描
          画の時に再配置するとしても、char_width_mode とは独立に表示幅などを勝
          手に弄ると文字幅キャッシュ等で不整合が起こって変な事になる。なので
          char_width_mode と _ble_unicode_c2w_ambiguous を独立に一時的に変更し
          て処理することは非現実的である。

      やはり mlterm の場合には最初から bleopt char_width_mode=east を設定してお
      く様にしてもらうしかないのだろうか。逆に言えば最初から
      char_width_mode=east を設定してもらうだけで済むのであればそちらの方が良い
      気がする。

      これには対応しない事にする。

    2023-03-06 うーん。~/b.txt にデバグ用のデータを出力していた。行を削除する。
    make_command.sh make scan でチェックしていたと思ったが確認した所 a.txt しか
    チェックしていなかった。危ない。[a-z].txt を全てチェックする様にした。

  * syntax: ${arr[@]@k} に対応できていない [#D1998]

    対応した。

2023-03-04

  * 2022-10-13 nix completion で止まる問題 (reported by aiotter, Aleksana) [#D1997]
    https://github.com/akinomyoga/ble.sh/issues/58#issuecomment-1272222143

    これは説明を書く。何処かにこういうののまとめを書く方が良いのではない
    かという気がする。

    Sorry for the late reply. I have been busy recent days (and am stil
    busy actually...). This is actually one of the compatibility
    problems that are hard to solve.  ble.sh extends the usage of the
    programmable completions for auto-complete

    やはり問題を解決してから対処する事にする。

    2022-12-03 報告を受けた筈なのに何処かに行ってしまったとおもったら #58 の下
    にあった。

    2022-12-04 cevhyruz への私信での解説を何処かに移植して説明するのが良い気が
    する。

    https://github.com/akinomyoga/ble.sh/issues/246#issuecomment-1294893636
    ここでも少し言及している。

    2023-03-03 また issue が上がったので見てみる事にする。

    以前の nix-bash-completion のファイルを持ってきて試してみたが動かない。補完
    しようとすると行が消えてしまう。調べてみると同じ現象が以下で報告されていて、
    しかし最早このリポジトリは管理されていなくて古いということの様に思える。

    https://github.com/hedning/nix-bash-completions/pull/22

    という事は最新版は何処か別の場所にあるという事になるが何処にあるのだろうか。
    というか普通に nix を入れたら入るという事なのだろうか。だとしても何処にある
    のか謎である。よく読むと ncfavier が代わりにメンテナンスするとかしないとか。

    https://github.com/NixOS/nixpkgs/pull/207224

    然し ncfavier の github 上のリポジトリに bash-completion っぽいのはない。別
    の場所で管理しているという事なのだろうか。

    適当にファイルを漁ってみると以下の場所に nix completion が置いてある。これ
    を確認してみる事にする。

    /nix/var/nix/profiles/default/share/bash-completion/completions/nix

  * syntax: coproc 変数名が alias に一致する時、着色を変更する [#D1996]

    うーん。実はもっと詳しく調べてエラー着色にするべきなのではないか? →多少
    alias の中身もチェックする事にした。alias の中身が複数の単語に展開される場
    合にはエラー着色になる様にした。

    展開前の時点でキーワードに一致している場合にはどうするのか。内部での解釈と
    は独立に構文解析が行われる事になるので、内部でキーワードに展開されたからキー
    ワード着色にするなどの工夫をした所で外側の構文解析が壊れてしまう。

    →alias が展開されてキーワードになる場合には、当初はその場で簡単な物だけ処
    理する様にしてみたが、結局通常のコマンド処理に fallback する様にした。元々
    変数名に一致しない場合にはその様に処理していたので問題ない。

2023-03-03

  * menu-complete: enter_menu であっても一意確定なら補完完了する機能 [#D1995]
    https://github.com/akinomyoga/ble.sh/discussions/297#discussioncomment-5159146

    実装した。menu を既に表示してしまっている時に単に menu に入る処理をしている
    所では、既存のメニューを選択してから即座に menu の確定処理を行う。menu を未
    だ表示していない時には menu の処理は一切せずにその場で挿入を実行する。menu
    を既に表示していて二回連続 TAB を押した時についてはまた別の処理が必要になる。

    うーん。単純に opts を継承する事にした。調べてみると menu/enter が処理して
    いる opts は backward と今回追加した insert_unique だけなので別の物が指定さ
    れていたとしても突然問題になる様には思われない。なので、単に opts を
    menu/enter に渡してしまう事にする。この様にすれば個別に insert_unique を実
    装しなくて済む。

    うーん。widget/menu-complete は enter_menu:insert_unique を既定にしてしまっ
    て良いのではないか → 変更した。

  * vi: operator:filter で end が文字列の最後の時には追加の改行は入れない [#D1994]

    x fixed: うーん。v 等で中途半端な場所にある時に beg は行頭に移動するけれど
      も end は行末に移動しない状態でフィルターが適用されて変な事になる。vim の
      振る舞いを見ると何れにしても行全体に適用される様である。

      実装を確認してみると ble/keymap:vi/expand-range-for-linewise-operator を
      呼び出しているので、行志向に拡張するのは意図的に行っている。然し、それが
      ちゃんと拡張されていないということの気がする。

      →これは思いっきりバグだ。local end と宣言してしまっていたので折角実行し
      た変更が関数の呼び出し元に伝わっていなかった。修正した。

    どういう条件で改行を挿入するのかは非自明である。取り敢えず変換前の文字列に
    改行が含まれていれば改行を挿入する? うーん。空文字列だった時にはそうではな
    い気がするし、更に改行が含まれていなかったとしても続きに文字列があればやは
    り改行が必要な気がする。

    1 end の次に改行以外の文字がある時は改行を入れる必要がある。

    2 end の次に改行がある場合でも改行を入れる必要があるのでは。これは二重改行
      の時に起こる。然し、非空行の行末に end があった場合 (本来この様な事は起こ
      らない筈だが) には改行は入れたくない。

      従って非行頭行末の時には改行は省略する? 然し本来この様な状況にはならない
      と思っているし、いざなったとしても改行は入れるか入れないかは微妙な気がす
      るので、この様な複雑な判定はせずに、この場合でも常に改行を入れるという形
      で良い気がする。

    つまり end が文字列末尾にあるのでなければ常に改行を挿入するという事で良い気
    がする。

  * zoxide: zi を bind -x から呼び出すと Enter が効かないらしい (reported by linwaytin) [#D1993]
    https://github.com/akinomyoga/ble.sh/issues/293#issuecomment-1451208995

    何故か自分の手元では再現しないが取り敢えず stty icanon を実行すれば直る様で
    ある。bind -x の度に stty を二回実行するのはコストが高いのでデフォルトで実
    行するのは微妙だが、zi を実行した時にだけという事であればそんなに問題にはな
    らないだろう。という事で関連する関数を上書きする事にする。

  * histdb: bash-3.2 で idle を使おうとして失敗している [#D1992]

    bash-3.2 では自動的に kill する機能はなくす?

2023-03-02

  * edit: ジョブ情報が出力されるとステータスバーが消える (reported by mozirilla213) [#D1991]
    https://github.com/akinomyoga/blesh-contrib/issues/11
    Ref #D1800

    うーん。これは coproc でなくても sleep 1 & で発生する。joblist の出力部分を
    ちゃんと command layout で囲んで置かなければならないという事? 或いは
    display-shell-version 等と同じ様にして出力する必要?

    ble/widget/print を呼び出せば良い様な気もする。

    うーん。出力は joblist.bflush で行われていて buffer に問題の文字列が混入す
    るという事になっている様だ。呼び出し元を見るとble/util/joblist.bflush
    ble/widget/.insert-newline となっている。つまり、layout 変更の途中の様な気
    がするのでこの状態で command layout への切り替えなどすると変な事になる気が
    する。後でよく考える必要がある。

    一方で joblist.check や ble/util/joblist では直接出力はしていない様なので
    joblist.bflush と joblist.flush だけ抑えて置けば大丈夫の気がする。実はこれ
    らは三箇所でしか呼び出されていないので対応はそんなに難しくない気がする。

    うーん。調べてみたが joblist.bflush を呼び出す所まではちゃんとできている気
    がする。それよりも一旦 collapse した状態を抜けていないのが原因の気がする。
    実際 joblist.bflush の呼び出しをなくしても問題が発生する。

    どうもこれは #D1800 で問題にしていたのと同じ問題の様に見える。うーん。どう
    も keep-info が指定されている時には enter/leave-command-layout がバランスす
    るという仮定の様な気がする。keep-info が指定されていない時は #D1800 を気に
    してコメントが書かれているが、keep-info のついている .insert-newline に関し
    ては #D1800 のコメントはついていない。

    単に keep-info の時に leave-command-layout を呼び出す様にしたら解決した。

  * [棄却] external: coproc c { sleep 1; echo; } とすると文法エラーになる [#D1990]

    "bash --norc" だと問題はない。何故? "bash --norc" で .blerc を読み込んでも
    問題はない。 mshex をロードしていると blerc をロードしていなくても問題にな
    る。何らかの shopt が関係しているという事だろうか。

    shopt を完全に合わせてみたがそれでも問題は再現しない。mshex について bisect
    するしかないのだろうか。

    うーん。分かった。alias c が展開されている。つまり、coproc の次はコマンドで
    も良いし変数名でも良いので取り敢えず alias 展開が実行されてしまうという事。
    そして一文字エイリアスはよく使われてかつ一文字変数も良く使われるので衝突す
    るという事。

2023-03-01

  * syntax: 5.3: 配列要素代入の右辺でブレース展開は無効 [#D1989]
    https://git.savannah.gnu.org/cgit/bash.git/commit/?h=devel&id=349e21043e362914551277728159f8e55350bad7

    これの修正は簡単だった。

  * vi_imap: M-S-o に対する fallback が ESC o になっている [#D1988]

    これは redispatch の時に S-o が O になっていないのが原因。そもそもの問題と
    して S-o も ble-bind を用意しておくべきなのかそれとも常に S に解決するべき
    なのかという疑問がある。うーん。然しキーボード上で両者を区別する事に意味は
    ない様な気がするのでこれで良い気がする。

    ? CapsLock が入っている場合にはどうするべきなのか。この場合には実際のキー入
      力として [Shift]+[O key] を送っている気がするが、操作としては "o" を送っ
      ているつもりなのではないか…。うーん。CapsLock の状態を取得するのは難しい。
      それも送信する様にするプロトコルもある様だが、そういうプロトコルばかりで
      はないので CapsLock の情報に依存せずに処理できる方法が望ましい。

      うーん。結局 CapsLock は信用できないし CapsLock が入っているからと言って
      操作体系を変更するのも変な気がするので、そのまま S-o を信じて S-o は常に
      O に変換するということで良い気がする。

    * 実は類似の箇所が他にもあるのではないか。検索してみると以下の様なものが見つかった。

      $ grc 'KEYS(\[[^][]+\])?&~_ble_decode_Meta'
      ./keymap/vi.sh:120:    ble/decode/widget/redispatch-by-keys "$esc" "$((KEYS[0]&~_ble_decode_Meta))" "${KEYS[@]:1}"
      ./keymap/vi.sh:141:    ble/decode/widget/redispatch-by-keys "$esc" "$((KEYS[0]&~_ble_decode_Meta))" "${KEYS[@]:1}"
      $ grc '&=?~_ble_decode_Meta'
      (同じ物しか当たらなかったので省略)

    * reject: 既に似たような処理を何処かで実装している様な気がする。例えばレジ
      スターの文字を取得する箇所など。確認する。_ble_decode_Shft で検索すれば見
      つかる筈…と思ったが見つからない。 k2c という名前の関数だった気がする。→
      ble/keymap:vi/k2c だった。然しこの関数は C-? を byte に戻す役割であって
      S-o を O にするなどの処理を実装した物ではなかった。

      なので今回はまた別に実装する必要がある。と思ったが既に上記の検索で当たっ
      ていた 141 行目が decompose-meta という関数で汎用に用意した物だった。120
      だけ特別に実装したものだった。なので基本的にこの二箇所を修正するだけで良
      い。

    修正した。と思ったが動作していない。

    % うーん。実際に流れてきているキーを確認してみたら既に M-S-o は
    % M-O に翻訳されていた。なのでわざわざこの場所で再構成する必要はな
    % いのであった。という事はちゃんと処理されていない原因は別の場所に
    % あるという事になる。

    →よく見たら M-O になっていて欲しいのに M-S-o でも M-O でもなく単
    に M-o になっていた。受信しているのは 27;2;111 でありこれは S-o で
    あるのにも関わらずちゃんと復元できないという事。

    ===== keys =====
    M-o ESC o C-u b l e auto_complete_enter
    / d e b u g C-e C-_ e auto_complete_ente
    r n d C-m C-m

    うーん。最初に受信した時点で S が消えている。どの時点で消滅したの
    か確認する必要がある。

    分かった。これは意図的に通常文字に対して S だけが付加されている時にそれを削
    除している。何故なら xterm & vte で <Meta-Shift-o> というキー入力に対して
    M-S-O というシーケンスを送ってくる為。M-S-o というシーケンスが来た場合には
    CapsLock が有効になった状態で Meta+Shift+O → M-S-o となったという解釈なの
    である。一方で contra は CapsLock 等関係なく実際のキーの組み合わせに一対一
    対応する様に処理している。

    * 今回はどの様に修正するか。取り敢えず contra での取り扱いについてはそれ専
      用に実装する事にした。一方で他の端末での振る舞いについても考える。konsole
      はそもそも modifyOtherKeys に対応していない。単に ESC O を最初から送信し
      て来ている。

      xterm は CSI 27;4;79 ~ で M も S も同時に指定した状態で来ている。これだと
      M-S-o になってしまう。然し本当は M-O になって欲しい。どの様に処理するべき
      だろうか。

      受信時点で調整しようかと思ったがやはり両方許容しておいて良い様な気がして
      きた。もし ESC 大文字 で送られてきたら M-O 等の形式にするのは自然だが、
      CSI 27;4;79 ~ 等の形式で来た時にどの様に取り扱うかは微妙。

      実際に確認してみると既存の binding は M-S-y と M-Y の両方の形式を同時に設
      定する様になっている。取り敢えずは現状のままにしておく事にする。

    * konsole の端末判定

      https://qiita.com/kefir_/items/0bda5e55f43392420d66 '0;115;0'
      https://github.com/KDE/konsole/blob/0bd20ac6542de5ea16d06f5af255389a3afa8f67/src/Vt102Emulation.cpp#L2051 '1;115;0'

      以下 (2022-02-24) によると v22.03.80 (2022-03-18) より 1 に変わった様だ。
      https://github.com/KDE/konsole/commit/0cc64dcf7b90075bd17e46653df3069208d6a590
      以下 (2001-09-16) によると v3.0.0 から 0;115;0 だった様だ。
      https://github.com/KDE/konsole/commit/2d93fed82aa27e89c9d7301d09d2e24e4fa4416d

      2023-03-02 初期化時に _ble_term_TERM が未初期化の状態で modify-key が呼び
      出されると負の配列添字になってエラーになる。

  * vim mode ! で複数行の結果を返すと描画位置がずれて変な事になる [#D1987]

    どうやら行数が増えると駄目な様だ。単に複数行を replace-range で挿入する
    widget を作成しても問題は再現しない。終了時の _ble_canvas_y の問題だろうか。
    うーん。.replace-range を実行している時の _ble_canvas_y の位置は正しい。ちゃ
    んと復帰した位置になっている。またこの時点で buffer.flush を実行しても問題
    の振る舞いに変化はなかったので buffering の問題ではない気がする。

    * todo: 行末の場合には末尾の改行は省略する。然しこの処置は現在のバ
      グを隠してしまうので現在のバグを修正してからにする。

    どうやら determine-scroll をした瞬間にずれている? 中身を見ると panel_height
    を拡張して更にその分だけカーソル位置も移動したことになっているが、実際には
    移動していないということが問題になっている気がする。

    何か分かった気がする。 DRAW_BUFF の中身をスクロールの直後で flush したら問
    題が発生しなくなった。これが意味する所は、後ろの方の出力で DRAW_BUFF ではな
    くて直接 util/buffer に出力している箇所があるという事。特に各行の文字数を調
    整する部分が怪しい。

  * global: コード中の /dev/tty は予め持っておいた fd に置き換えるべきなのでは [#D1986]
    修正した。

  * util: readonly を上書きする? (requested by mozirilla213) [#D1985]
    https://github.com/akinomyoga/ble.sh/issues/289

    其処まで積極的にユーザー環境を上書きして良いのか不明である。

    - alias doesn't affect existing functions.

    - command line can be easily detected, but this is still incomplete
      detection because even if the user does not directly write declare -r,
      the functions called by the user could contain declare -gr, etc.

    The scope that the readonly is called and the scope of the variable
    specified to readonly are unrelated to each other.  One needs to test each
    variable name whether it is in the global scope or not.

    * propagating tempenv にも気をつけなければならない。

      $ f1() { ble/variable#is-global fdsafdsa; }
      $ fdsafdsa=a f1

      このテストだと global ではないと判定されてそれは is-global の判定としては
      期待する動作である。然しこれに対して export/readonly を実行すると外側に
      propagate してしまう。global に propagate しないという事までちゃんと判定
      する方法はあるのだろうか。そもそも tempenv をそうと判定する方法があるのか
      という事も疑問である。

      まあこの場合は仕方がないと思って諦めるべきだろうか。

      これの判定は完全ではない。

    * done: global readonly に対しても whitelist は作っても良いのかもしれない。
      全て [A-Z0-9_] であり 2 文字以上で Bash の特殊変数に一致していなくて
      ble.sh が使っていない変数名?

      ble.sh 内部で使っている大文字変数も実は改名するべきの気もする。特に vi.sh
      の中で使っている変数が気になる…がこれは禁止リストに入れてしまっても良い
      気がする。

      小文字でも _ble で始まらない _[a-zA-Z]* の様な変数名も許容して良いのでは
      ないか。然し、ble.sh の内部で使っている変数もあるのでそれらは ble.sh の側
      で改名する等して避ける事にする。

    * done: is-global の実装で readonly が使われている。

    * done: adjust builtins: readonly はユーザーによる上書きを許容する。

    * done: エラーメッセージは一回しか実行しない→もう何回か表示して良い気がす
      る。10回迄表示する事にした。

    * ユーザーが既に readonly を上書きしている場合にはどうするのか。
      function#push,pop で処理する事にすれば良いだろうか。と思ったがその様にす
      るのであれば他の builtin も同様にする必要があるのではないかという事になっ
      てくる。もしこれについて考えるのであれば全ての builtin について同時に適用
      するべき。

    2023-03-02 文法エラーが発生している。bash-4.0 以降では "!" 単体はエラーにな
    らないのだろうか。何れにしても修正した。

  * exec: BLE_PIPESTATUS 公開する (motivated by mozirilla213) [#D1984]
    https://github.com/akinomyoga/ble.sh/issues/290

    * done: wiki misc

    * ok: 然し、実際に BLE_PIPESTATUS をどの様に PIPESTATUS と使い分けるのかと
      いうとよく分からない。現在のコマンドが ble.sh 内での一番最初のコマンドか
      どうかの情報がないので両方にアクセスできる時にどちらを選ぶべきか分からな
      い。

      一応 exec が終わったら BLE_PIPESTATUS を削除すれば良い気もするが、でもそ
      もそも exec が終わったら ble.sh の内部なので誰も BLE_PIPESTATUS を参照し
      ないので削除してもしなくても関係ない気がする。

      然し気にし出したら限がない気がするので考えない事にする。

    * ok: 唯一削除したほうが良いかもしれないのは ble-detach する時だが、そうだ
      としても ble-detach する時のステータスを復元する必要はないのか。というか、
      ble-detach した時の $_ $? などはちゃんと保持されているのか (そもそも保持
      する必要があるのかも怪しいが。何故なら ble-detach コマンドを結局呼び出す
      のでその $? や $_ が適用されるのでは。より複雑な構成で非自明な場合を考え
      る事も可能だが其処まで考えても意味がない気がする)。同様に PIPESTATUS に関
      しても敢えて ble-detach の PIPESTATUS を保持する事が有用である様には思え
      ない。なので考えなくて良い事にする。

    * done: 序でなので POSTEXEC 及び ERREXEC にも BASH_COMMAND を引数に指定する
      様に変更する事にした。

    * done: README Limitations

  * decode: compat zoxide bind -x (reported by linwaytin) [#D1983]
    https://github.com/akinomyoga/ble.sh/issues/293

    leave-for-widget を毎回呼ぶ事にしてしまっても良いのでは。

    ? ここで fzf-key-bindings の advice を残すかどうかが問題になる。もしこれら
      の関数を completion にも流用しようとしている人がいてこれらを直接呼び出し
      たとすると問題になる。しかし、fzf-completion を弄って (もしくは自分で新し
      く設定を作って) いる人がいたら何れにしても fzf-completion はちゃんと動か
      ない。なので、現状で中途半端に fzf-key-bindings の中の関数だけ patch して
      も余り意味は無いのではないか。

      やはり単純に削除してしまって良い気がする。

    * ok: もう一つの懸念事項は bind -x の全てに対して毎回呼び出すと重くなるので
      はないかという事。うーん。ble.sh の上で更に ble.sh 的な事をしようという様
      な事がない限りは多少エスケープシーケンスが端末に沢山送られても別に大した
      処理量にはならない気がする。

      但し、visible-bell/erase に関してはファイル等をチェックする等するはずなの
      で多少のコストはあるかもしれない。然し、ble/util/assign 等もっと沢山の非
      自明な事をしているのだから bind -x の時にファイルを確認するぐらいであれば
      無視できる筈である。

  * 2023-02-21 histdb: 終了時に sqlite3 のエラーが発生して失敗する事がある [#D1982]

    Runtime error near line 779: database is locked (5)

    調べてみるとどうやら timeout を指定していたとしても BEGIN TRANSACTION は即
    座に失敗するらしい。IMMEDIATE を指定する必要がある。

    https://blog.ver001.com/sqlite-databaseislocked/

    これは単に IMMEDIATE を指定したがそれ以降エラーは出ていない。これ
    で直っていると良いが、エラーがそもそも出る確率が少ない様だから確認
    が難しい。次にまた問題が出た時に考える。

    2023-03-01 やはりまたエラーが出た。改めて確認してみるとどうやら exec でバッ
    クグラウンドで起動した時に timeout が指定できていない。起動時にちゃん
    と.timeout を指定する事にした。何度か起動と収量を繰り返したが新しいものの方
    では問題は生じない様に見える。と思ったが古い方でも起こる確率はやはり小さい
    様なので何とも言えない。

    もう一つ気づいた事は histdb の remarks に ANSI 色シーケンスが混入しているこ
    と→これは単に .blerc で明示的に colored を指定していたのが悪い。修正した。
    更にこれを元にして作成した histdb の既定の remarks にも同様の間違いがあった。
    これも修正した。

    % 2023-03-03 うーん。やっぱり駄目。何らかの拍子に失敗する。timeout をもっと
    % 長く取るか或いは諦めてエラーを強制的に suppress するか。どうも終了する時
    % に発生する様なのでエラーメッセージに関してはそれ程気にしなくても良いのか
    % もしれない。一方で、終了する瞬間にメッセージが表示されることを思うと実は
    % .timeout が短い事による問題ではなくて、やはり .timeout で待たない様な設定
    % になっているという事だろうか。と思って気づいたが contrib の dev ブランチ
    % に前回の修正があって、それが有効になっていなかった。

    取り敢えず平和に動いている様な気がするので #D1992 と一緒に修正を適用する事
    にする。

  * 2023-02-21 どうも bash-5.2 で WINCH が効かなくなっている [#D1981]

    最初は効いているが、同時に複数の WINCH を受け取る等の事が一旦起こるとそれ以
    降は WINCH が効かなくなってしまう。bash-5.1 では問題は起こらない。より簡単
    な設定で再現しようとしたが再現しない。bash 自体の内部で何が起こっているのか
    確認するべきの気がする。

    * 更に devel で試してみると無限ループになってしまう。何故? 自前で適当に
      setup しても無限ループにはならない。この devel の無限ループでは別に
      ble/builtin/trap/.handler が沢山呼び出されている訳でもない様だ。bash の側
      で無限ループになっている。

      devel 407d9af (20221119) は大丈夫。3687888 (20230220) も大丈夫。という事
      は DPF で勝手に書き換えているのが問題という事? 或いは debug version が駄
      目という事なのだろうか。どうやら ./configure --with-bash-malloc=no でコン
      パイルすると駄目? と思ったが ./configure でも駄目の様だ。どうも maint の
      時にだけ発生する問題の様である。うーん。これの優先度は低い。

    * うーん。一応 WINCH は受信はできている様だ。然し COLUMNS LINES が更新され
      ていないという状態。subshell を呼び出したとしても更新されない。但し内部で
      改めて builtin trap 等を実行して WINCH を呼び出すと WINCH 自体が動かなく
      なる。

    これは結局 histdb の timeout の処理の為に動かしている msleep が良くない様だ。
    つまり、ble/util/msleep (中身は read -t) が待っている間に WINCH が来るとそ
    の WINCH は消えてなくなるという事。実は 5.1 では read -t の途中で WINCH が
    来ても read -t が終わった後にちゃんと WINCH が発火してくれる。これは
    sigmask 等を弄ったら動く様にならないだろうか。

    改めて bash-5.2 --norc で起動して read -t 5 をしてみたら実はその場 (read -t
    の timeout を待たずに) で発火する。何れにしても 5.1 とは振る舞いが微妙に違
    うが、これは ble.sh の時に全く発火しないのとは振る舞いが違う。或いは、read
    -t の読み取り元の fd の種類によって振る舞いが違うのだろうか。

    * ble.sh の中にいると WINCH が不活性になってしまう問題。起動した瞬間に
      builtin trap WINCH を実行している場合には問題は生じない。つまり、WINCH の
      処理中に更に新しい WINCH が来るなどの事があると不活性になってしまうという
      事だろうか。

      またこれは bash のバグなのかという事もある。bash のバグとしての修正と、そ
      れから既に出ている bash-5.2 に対する workaround の両方を実装する必要があ
      る。取り敢えず bash 側で何が起こっているのかについては確認する必要がある。

    * WINCH が不活性の時は bash の中で何が起こっているのか。

      % 先ず _rl_signal_handler は通常の動作している状態であっても ble.sh の中で
      % は呼び出されていない。つまり、自分が設定した WINCH だけが有効になっている
      % 状態で、readline signal handler がない状態だろう。これは不活性になってい
      % る時でもちゃんと WINCH が活性している時でも問題になっている。
      %
      % trap でどう設定されるのかを見て呼び出し経路を探る事にする。set_signal を
      % 呼び出している。中では trap_handler という関数をシステムに登録している。
      %
      % 実際に trap_handler が呼び出されているかどうかを確認してみると
      % trap_handler までは不活性の状態でも呼び出されている様だ。trap_handler は
      % set_trap_state を呼び出して抜ける。更に pending_traps[SIGWINCH]++ が実行
      % される。この配列をチェックして実際の trap string を実行している箇所を探せ
      % ば良い。
      %
      % →どうやら set_trap_state までは呼び出されるけれどもその後
      % run_pending_traps が実行されない状態になっているということの気がする。
      %
      % どうも running_trap が有効になったままになってしまい無限ループ状態になっ
      % ている。つまり running_trap の復元に失敗している。running_trap はどの様に
      % 復元する事になっているのだったか。
      %
      % どうも parse_and_execute で実行している最中に実行が途切れて戻ってこないの
      % が問題の様である。然し何故だろうか。実行しているコマンドの内容による? 特
      % 定のコマンドの後に変な事が起こるのか、それとも最後まで実行した挙げ句に変
      % な事になるのか。
      %
      % 調べてみると blehook internal_WINCH の実行途中に制御が消滅する様である。
      % どんどん調べていくと結局やはり ret=$(msleep 50; bash -c ... ) として端末
      % サイズを取得しようとしている所で失敗している。これを assign に置き換えて
      % も失敗する。assign は mapfile で失敗する。つまり、read -t の最中に起こっ
      % たシグナルの中で何らかの読み取り動作を実行しようとすると失敗するという事。
      % 実際に sigmask で sigwinch が即時発火しない様に修正したら問題は生じなくな
      % る。

      まとめると、read -t (msleep) で待っている間に SIGWINCH を受信するとその場
      で WINCH handler が呼び出され、更にその中で a=$() や mapfile 等の読み取り
      を使おうとするとエラーが発生して、run_pending_trap 自体の実行が中途半端に
      キャンセルされてしまう。これにより run_pending_trap が設定している
      runnning_trap がクリアされずに残ってしまい、入れ子の trap 実行と判定され
      て run_pending_trap が全く実行されなくなってしまう。

      read -t の実行時に sigmask を指定して SIGWINCH をブロックしておけば変な事
      は起こらない。なので 5.3 以降では気にしなくて良い。

      以下 ble/application/onwinch の COLUMNS, LINES 取得部分で行った実験コード

      | # bash-5.2 では read -t の最中の WINCH がその場で発火して、(1) 内部で
      | # ble/util/msleep を実行しようとすると外側の timeout 設定が削除されてロッ
      | # クする (2) WINCH が受信できない変な状態になる。
      |
      | # local ret
      | # ble/util/msleep 50
      | # ble/util/assign-words ret 'ble/bin/stty size'
      | # LINES=${ret[0]}
      | # COLUMNS=${ret[1]}
      |
      | # (ble/util/msleep 50)
      | # local cmd='(:); echo "COLUMNS=$COLUMNS LINES=$LINES"' ret
      | # ble/util/assign ret '"$BASH" -O checkwinsize -c "$cmd"'
      | # builtin eval -- "$ret"
      |
      | echo "$FUNCNAME @3" >/dev/tty
      | # 5.2 コマンド置換 $() を使うと停止する。
      | #builtin eval -- "$(sleep 0.05; "$BASH" -O checkwinsize -c '(:); echo "COLUMNS=$COLUMNS LINES=$LINES"' 2>/dev/null)"
      | #local ret=$(ble/util/msleep 50; "$BASH" -O checkwinsize -c '(:); echo "COLUMNS=$COLUMNS LINES=$LINES"' 2>/dev/null)
      | #local ret=$(sleep 0.05; "$BASH" -O checkwinsize -c '(:); echo "COLUMNS=$COLUMNS LINES=$LINES"' 2>/dev/null)
      | #local ret=$(echo echo yes)
      | #(echo yes)
      | (ble/util/msleep 50)
      | echo "$FUNCNAME @3.1" >/dev/tty
      | (echo >/dev/null; bash -c ':')
      | echo "$FUNCNAME @3.2" >/dev/tty
      | (bash -c ':')
      | echo "$FUNCNAME @3.3" >/dev/tty
      | local _ble_local_tmpfile;
      | echo "$FUNCNAME @3.31" >/dev/tty
      | ble/util/assign/.mktmp;
      | echo "$FUNCNAME @3.32" >/dev/tty
      | builtin eval -- "(echo echo yes)" >| "$_ble_local_tmpfile";
      | echo "$FUNCNAME @3.33" >/dev/tty
      | local _ble_local_ret=$? _ble_local_arr=;
      | echo "$FUNCNAME @3.34" >/dev/tty
      | mapfile -t _ble_local_arr < "$_ble_local_tmpfile";
      | echo "$FUNCNAME @3.35" >/dev/tty
      | ble/util/assign/.rmtmp;
      | echo "$FUNCNAME @3.36" >/dev/tty
      | #ble/util/assign ret '(echo echo yes)'
      | echo "$FUNCNAME @3.4" >/dev/tty
      | local script='(:); echo "COLUMNS=$COLUMNS LINES=$LINES"'
      | ble/util/assign ret '"$BASH" -O checkwinsize -c "$script" 2>/dev/null'
      | #ble/util/assign ret '(ble/util/msleep 50; "$BASH" -O checkwinsize -c "$script" 2>/dev/null)'
      | #builtin eval -- "$ret"
      | echo "$FUNCNAME @4 ($ret)" >/dev/tty

    5.2 における対策としては ble/util/assign を全く使わないという処置は大変なの
    で、(read -t 実行中) または ble/decode/.hook 実行中は SIGWINCH をその場で処
    理するのはやめて後回しにする? 然し、これは SIGWINCH に限った問題ではない気
    がするので、trap/.handler 全般に read -t を実行中の場合にはそれが終わるまで
    trap を pending するという機能が必要の気がする。

    ? bash: 然しそもそもの疑問は何故 SIGWINCH が即時発火するのかという事。
      run_pending_trap が read -t の最中に呼び出されるという事があるのだろうか?
      trap_handler は単にシグナルを受信して pending_traps 配列に記録するだけの
      筈なので、何処か別の場所から run_pending_trap を呼び出す必要がある。そう
      しないとその場で発火はしないのではないか。

    * 再現スクリプト? 少し試してみたが全然再現しない。そもそも別の修正で発生し
      なくなるからこれについて簡単なスクリプトで再現する必要は実はない。

    * done: 実は builtin read は全て置き換える必要があるのではないか? 序に
      _ble_bash_tmout_wa の配列も関数の側で指定する事にする。

      builtin read -t 0 や builtin read --help 等は一瞬で終わると思われるし、ま
      た内部で実際の読み取りを試行する訳でもなさそうなので入れ子にしても問題は
      ないと期待してそのままにする。また detach 状態で呼び出す builtin read に
      関してもそのままで良い。

      と思ったが動かない。と思ったら分かった。bash version 判定に使っている
      _ble_bash が定義されるよりも前の段階で ble/bash/read を _ble_bash に基づ
      いて切り替えようとしていた。実際に ble/bash/read が使われるのはもっと後な
      ので、もっと後ろに移動する事にした。直った。

2023-02-27

  * idle: prompt-defer による自動更新が発生していない気がする [#D1980]

    以前は background で処理が完了し次第プロンプトが更新される様にしてその様に
    実際に動いていた気がする。しかし現在はキー入力が来るまで更新されない様だ。

    →実は idle sleep の最中には表示更新が発生しないという可能性? 或る一定以上
    の時間 sleep するのであれば更新するべきである。

    * reject: sleep の interval を決定する際に使っている時間が idle.do を開始し
      てからの時間になっているがそれで良いのだろうか。最後の task からの時間の
      方が良いのではないか。

      と思ったが、screen saver 的な使い方や定期的に時刻を更新する使い方を考える
      と、task が走る度にリセットされると本来の意図と異なる事になる。なので、や
      はり idle.do の開始時刻からの時間を使って決定するという事で良い。

    * 取り敢えず待機時間の最初に DO_EVENTS を実行して、それ経由で
      ble/application/render を呼び出す様にして見ようと思ったが、これだと毎秒プ
      ロンプトの再描画を試行してしまって重いのではないか?

      以前に時計を表示する実験をした時にはどのようにしていたか。.blerc にある時
      刻表示を確認してみたら時刻を info に表示しているので info だけの更新をそ
      の場で呼び出していた。そもそもこれは実際に更新が起こる時に呼び出しを行っ
      ているので、再描画を呼び出すのは当たり前である。一方で今回の場合には恐ら
      く更新がないのに全体再描画を試行する事になっていて問題である。

      DO_EVENTS の中で render を呼び出す条件を指定するべきなのではないか。プロ
      ンプト更新の可能性がある場合にそれを伝える仕組みが必要? 現在は一応その枠
      組として prompt hash を使っているが、それでも複数のプロンプトを管理してい
      ると全てのプロンプト hash を eval しなければならず、それはコスト的に高い
      様な気がする。

    ? また、DO_EVENTS 経由で描画を実行するのも変な気がする。IS_IDLE と同じ箇所
      で上書きするのであれば良いかと思っていがが確認してみたところ IS_IDLE は
      decode.sh で上書きしている。ble/application/render を入れるとしたら寧ろ
      canvas.sh か edit.sh の様な気がするので、別の箇所で定義しなければならない。
      それは避けたいので、ここはそれ専用の hook を用意する方が自然なのではない
      か。

    * reject: ble/textarea#render-defer.idle という枠組みが edit.sh で既に実装
      されている事に気づいた。つまり元から遅延して再描画する仕組みが整っていた?
      と思ったがこれはどうやらユーザー入力に対して反応しているのに過ぎない様だ。
      更に使っている箇所を確認するとこれは prompt-defer ではなくて単語着色に時
      間がかかっている時に先にユーザー入力を処理する、という時に使っている。
      wait-for-user-input で中断するかどうかを確認しているのはこれが理由という
      事だろう。なのでこれは今回のものとは関係ないし、今回使えるものでもない気
      がする。

    プロンプト更新の必要性がある可能性があるという事を示す枠組みを入れる? 現在
    の invalidate 関係の仕組みがどうなっているのかについて確認する必要がある。

    a 先ず以下の panel::invalidate によって 設定される変数に関しては、そのパネ
      ル全体について実際に再描画のシーケンスを出力する必要がある事を示している。
      つまり、「内容が更新されている可能性がある&もしチェックして必要があれば変
      わった部分だけ更新する」というものに使われるものではない。

      _ble_prompt_status_dirty=1
      _ble_edit_info_invalidated=1
      _ble_textarea_invalidated=1

    b 次に _ble_prompt_update_dirty は単に現在既にプロンプトが表示されているか
      どうかの判定に使っている様な気がする。

      % と思ったが処理の流れが何か変な気がする。dirty だったら dirty=dirty という
      % 値を設定する。その次の呼び出しで dirty だったら dirty=done に設定し直して
      % 改めて再描画するという構造になっている。これは何だかおかしい気がする。必
      % ず2回呼び出されるという事?
      %
      % 実際にこの部分を追加した commit は e199beee であり #D1750 である。この議
      % 論では wezterm integration が勝手に PROMPT_COMMAND から何か文字列を出力す
      % るという問題に対する workaround を追加している。どうも textarea 以外の枠
      % 組みから ble/prompt/update が呼び出された時に、その時点で dirty という事
      % になって、それをその後で処理したい時に done を指定している気がする。
      %
      % うーん。実はプロンプト毎にも _ble_prompt_ps1_dirty 等の様なものを管理して
      % いるのでプロンプト自体が毎回重複して出力されるという訳では無い様だ。然し、
      % そうだとしても ble/prompt/update が必ず2回 dirty を返すという事になってし
      % まって、だとしたらそれはおかしいのではないか?
      %
      % と思って実際に試してみたが一回しか prompt dirty になっていない。何故だろ
      % うか。分かった。そもそもプロンプト内容に変更がなければ dirty にならないの
      % である。なので確かめる時には cd の直後の振る舞いを調べるべきである。
      %
      % うーん。実際に cd 直後のプロンプトの初回更新時に見てみると既に最初の呼び
      % 出しの時点でちゃんと _ble_prompt_update_dirty=done になっている。何故?

      分かった。現在の実装では ble/application/render の時点で既に
      ble/prompt/update を呼び出す事になっているのである。なので、
      textarea#render からの ble/prompt/update の呼び出しは単に先に呼び出した時
      の計算結果を参照しているのに過ぎない。:check-dirty: というのは実際に
      prompt update 操作を試行せずに結果だけ読み取るという取り扱いなのであって、
      同時に実際にその結果を使って描画を行うから dity state をクリアするという
      役割があるという事なのである。

      そしてそもそも :check-dirty: なしでの呼び出しは ble/application/render か
      ら必ず毎回行われるので、:check-dirty: 以降のコードも
      ble/application/render を呼び出す場合には毎回実行される。なので、
      _ble_prompt_update_dirty の値は実際には ble/prompt/update 処理の省略に使
      われている訳では無いという事なのである。

    c ble/prompt/clear ... これが最も怪しい。と思ったが、この関数を呼び出すと結
      局内部で textarea#invalidate を呼び出しているので全体の強制再描画を引き起
      こしてしまう。これはではない気がする。

      或いは新しい関数を追加してプロンプト情報の更新だけ試みる? hash だけクリア
      すれば良いのでは? と思ったが、今は ble/application/render 自体の呼び出し
      を省略できないかという事を考えているのであって、hash をクリアして更に
      ble/application/render を呼び出すというのでは半分だけである。

      というか b の項目は実は余り関係なかったという事が判明した今改めて
      _ble_prompt_hash の取り扱いを見てみると、別に _ble_prompt_hash を更新して
      いようが更新していまいが ble/prompt/update の各プロンプトの hash 値確認は
      全部行っているので、 _ble_prompt_hash をクリアしようがしまいが
      ble/application/render を呼び出す限りは同じ事の気がする。

    今欲しい物は何かについて改めて考える。idle.do の中で何か更新が必要になって
    いないか確認し、もし必要になっていたら強制的に再描画を実施するという事を考
    えている。

    d 或いは application/render を実際に毎回呼び出してしまっても良いのではない
      か?  タスクが走る度に実行するとは言っても、実際に本当にタスクを走らせてい
      るのであれば、呼び出してしまっても問題がない気がする。

      →これで実装してみたら実際に思うように即時に反映される様になったが、今度
      は逆に ble/application/render が各キー入力の後に重複して呼び出されるよう
      になった。うーん。そもそも ble/application/render を先に呼び出している筈
      なので、改めて呼び出す必要はない筈なのである。

    今気づいたのだが、実はそもそも auto-complete すら動いていなかった。sleep し
    ている時には定期的に抜けて処理を実行する必要があるのであった。

    do_events で ble/application/render を呼び出す様にしたがそれでも重複して
    ble/application/render が呼び出されている様だ。更に、重複して呼び出されてい
    るのにも関わらずプロンプトが期待通りに更新されていない。二つの問題があるの
    で分けて考える。

    * idle do_events がキー入力毎に複数回呼び出されるのは何故か。

      % 背景処理がそんなに実行されるのだろうか。どういう処理が実行されているの
      % か出力して観察してみる事にする。
      %
      % →idle.do の中から呼び出しているのは一回である。これは期待通りである。一
      %   方で、bind/.tail からの呼び出しが二回ある。これは期待していない。
      %
      % 一方で histdb をロードしていない時には各キーストロークに対して2回実行して
      % いる。これは期待通りである。idle を実行する前と idle を実行した後。
      %
      % うーん。これは auto-complete を無効にしても同様である。なので、
      % auto-complete を抜ける時に内部的に生成しているキーが原因ではない。という
      % かそもそも内部的に生成するキーに関しては bind/.tail は呼び出されない気が
      % する。

      分かった。これは (1) ユーザー入力があって idle.do から抜ける時 (2) ユーザー
      入力の処理の後に抜ける時 (3) 更に auto-complete 等を処理した後に sleep を
      開始した時 の三回処理が実行されているという事である。

      実際には単に sleep しているだけで最終的に何も実行する前にユーザー入力があっ
      た時には抜ける時の render は必要ない。do_events に対する処理は実は
      idle.do の内部で呼び出すべきなのかもしれない。そもそも idle.do が中で実際
      に処理が行われたかどうかに応じて修了スターテスを決めるというのも変な気が
      する。と思ったが「最後にタスクを処理してから do_events を実行したかどうか」
      を終了ステータスにするのはもっと変だ。

      うーん。do_events は after_task, onaftertask, on_after_task 等に変更する。
      blehook idle_on_after_task, blehook idle_after_task うーん。
      idle_after_task という名前にする事にする。

      実装した。idle 後の再描画も idle_after_task 経由で実行する事にした。取り
      敢えず期待通りに動いている。

    * プロンプトが prompt-defer で更新されないと思っていたが、上の問題を解決し
      たら何故かこちらの問題も発生しなくなっていた。関係していたのだろうか。或
      いは、表示されてはいたけれどもデバグ用の情報出力によって紛れて更新されて
      いないと勘違いしていた可能性もある。

      何度かやってみたが問題は全く発生しなくなっていた。前はほぼ確実に問題が生
      じていたのを考えると実際に解決したのだと思って良い気がする。

  * menu (linewise): 行番号を表示すると表示レイアウトが壊れる (reported by bkerin) [#D1979]
    https://github.com/akinomyoga/ble.sh/discussions/284
    https://github.com/akinomyoga/ble.sh/issues/286

    これは簡単なミスだった。単に x を更新した後に x を参照していた。すぐ直った。

  * completion: fzf-completion がまた動かなくなっている (reported by christianknauer) [#D1978]
    https://github.com/akinomyoga/ble.sh/issues/285

    コードを調べてみると ble/syntax-raw を指定していても noquote を指定していな
    いとちゃんと quote しないという分岐に入らない様だ。一方で、contrib で
    2022-11-12 に noquote を外している。議論としては #D1889 である。

    https://github.com/akinomyoga/blesh-contrib/commit/e102241466dfda8cf3e7efb6891e223102e0b2a9
    https://github.com/akinomyoga/ble.sh/issues/250

    ? これは fzf 経由で生成された候補は quote された状態で生成されるけれども、
      fzf が更に呼び出している bash_completion の側では quote されていないとい
      う事なのだろうか。

      具体的にどの様に候補が生成されているの確認する事にする。うーん。
      fzf-completion の内部で見ている時点で既に cd sp**[TAB] の時と cd sp[TAB]
      の時で quote されるされないが分かれてしまっている。これは ble.sh なしの普
      通の bash の時には問題にならなかったのか。何故か。改めて確認する。

      うーん。plain bash だとちゃんと動いている。COMPREPLY の内容を確認してみて
      も cd sp[TAB] と cd sp**[TAB] で異なる結果を返している。それにも関わらず
      どちらも同じく正しい quoting を最終的に実行できているのは何故か。compopt
      の呼び出しが粉割れている可能性? compopt によって生成された comp_opts の内
      容も確認する事にする。

      うーん。"space dir" という名前で生成されている時には compopt -o filenames
      が指定されていて、"space\ dir" という形で生成されている時には filenames
      が指定されていない。filenames に関してはちゃんと実装しているのか不明であ
      る。以前に filenames の時の振る舞いについて確認した気がするが、それはどう
      だったか。

    元の補完の枠組みの範囲内で noquote は指定していないのだから、ble.sh の内部
    で勝手に noquote を指定した物として見做してその上で filenames が指定されて
    いる時されていない時で振る舞いを変える等の実装にすると混乱の元である。特に、
    本当にユーザーが noquote も指定した時にどう振る舞うのかだとかと整合性が取れ
    なくなる。なので、#D1889 以前の様に noquote を改めて指定してその上で条件判
    定で振る舞いを調整するというのは良い解決方法ではないと思われる。

    ble/syntax-raw が指定されていてかつ filenames が指定されていない時の振る舞
    いを変更するのが良い気がする。

    * ok: command noquote の時の awk batch の処理が通常の処理と違っている様な気
      がする。通常の処理の時には noquote を参照しているが、awk batch では参照し
      ていない。通常実装の方の変更に伴って awk 実装も更新しなければらないところ
      を忘れていたのではないか。これについては後で確認する必要がある。

      % 調べてみるとこの部分は d6242a79 (2021-12) に導入されている。そもそもそ
      % れより前には command に対する分岐は存在していなかった。同時に awk batch
      % の方にもコードが追加されているが、その時点で異なる条件になっていた様だ。
      % これはどういう事だろうか。別の場所で処理されているという事だろうか。
      %
      % 改めて noquote が処理されている箇所を確認して他で処理されていなければ処
      % 理が一致する様に変更する。実際に調べてみたが処理している気配はない。一
      % 方で command の場合には DATA に対して判定を行っている。
      %
      % うーん。そもそも yield.batch の段階では DATA は生成されていない。全体共
      % 通の DATA が渡されているだけの気がする。一方で、action:command に対して
      % はそもそも DATA が指定されていない? 或いは動的に生成されている可能性も
      % ある。
      %
      % という事は DATA を参照して noquote かどうかを判定しているのは完全に無駄
      % な機能? 或いは DATA ではなくて comp_opts の勘違いだろうか。元の意図が完
      % 全に分からなくなった。そもそもコマンド名は progcomp で生成していない限
      % りは自前で生成しているのだから勝手に noquote が付加される事も考えにくい。
      % 将来的に付ける事を考えての処理だったかもしれない。
      %
      % 1 そもそも action=command を生成しているのは soruce:command しか存在し
      %   ない。progcomp でコマンド名を生成するとしても action=command にはなら
      %   ない。
      %
      % 2 source:command の中では noquote という文字列に対しての取り扱いは存在
      %   していないように見える。

      と思ったら alias の生成に対して :noquote: を指定していた。そして alias の
      設定には yield.batch を用いていない。これはコメントで補足が必要である。補
      足した。

    動作確認する。

    x fixed: うーん。quote しない様にしようとしたら単純に元の文字列がそのまま挿
      入される様になってしまった。何故だろう。調べるとちゃんと候補は生成されて
      いる。

      どうやら .apply-partial-comps によって元に復元されてしまっている様だ。うー
      ん。comp_opts が syntax-raw の場合にはその処置を行わない様にする? 然し
      comp_opts の情報は既に失われている様な気もする。

      取り敢えず単一確定の時に progcomp の時は cand_pack DATA に comp_opts が記
      録されているのでそれを参照して判定する事にした。そもそもこの様な特別な処
      理が必要になるのは bash の既存インターフェイスである progcomp から借用し
      ようとしている時の不整合によって起こるのだから、それ以外の場合には問題に
      ならない筈である。よって progcomp の時にだけ処理すれば良くて、一般化した
      枠組みにする必要はない。

    x ok: 今度は普通に補完しようとした時に動作していない。filenames が付加され
      ていれば quote に進む筈であるのに。と思ったらこれは単にテストコードの埋込
      時に失敗していただけだった。テストコードを除去したらちゃんと動く様になっ
      た。

    本当にこれで完全なのか等よく分からないが取り敢えず ble/syntax-raw は現在は
    fzf しか使っていないし、fzf で動かないのであれば他の枠組みが ble/syntax-raw
    を使ったとしてもやはり動かない場合があるという事だろう。なので取り敢えず
    fzf に合わせるというので良い気がする。本来は syntax-raw が指定された時には
    完全に readline と同じ振る舞いになる事が求められているのかもしれない (つま
    り quote する条件もちゃんと調べる?) が取り敢えずは現状のままで良い。

    * done: compopt に他の quote を制御するオプションがないかだけは最後に確認しておく。

      →特に他には関係のありそうな物はなさそうだ。filenames の項目には trailing
      spaces を suppress すると書かれている。これは後で問題になった時に処理する
      事にする。

2023-02-21

  * prompt: PS1='\g{fg=#FF0000,bold}\$ ' としても色が反映されない [#D1977]

    これは単純なバグだった。

  * 5.3: case insensitive history search (bash 72c4a0f4) [#D1976]

    rlvar search-ignore-case を on にすると readline での検索機能が ignore-case
    になる機能が bash devel に実装されている。

    実装してみた。

    x fixed: 動いていない→ nocasematch を使うべきなのに nocaseglob を使ってい
      る場所があった。修正した。

    x fixed: 一文字目は大文字小文字が違っても一致しても、続けて文字を入力して行
      くとより前の物を探しに行ってしまう。これは文字追加の時の検査で失敗してい
      るという事だろうか → 確認したら単に ignore-case を渡すのを忘れていた。直
      した。動いている。

    x nsearch で一致範囲を着色する機能があるが、大文字小文字が違って見つかった
      項目については一致範囲の着色ができていない。カーソル位置も末端になってし
      まっている。

2023-02-20

  * cygwin: sudo すると PS1 の \u が bash に化けてしまう。何故? [#D1975]

    PS1='\u' だと発生しない。 PS1='\u\$ ' だと発生する。Cygwin では '\$' を特別
    視してこれが含まれている時には自前処理している。

    何と \s で展開していた。これは a9551e54 (2022-03-12 #D1801) で導入されている。

  * 2022-06-09 macOS の nawk の振る舞いが変だという事 (reported in killermoehre) [#D1974]
    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 は実はちゃんとコンパイルできてい
    % なくてそもそも全く動作していなかった。

    Apple nawk を改めて確認するべきかもしれない。

    2023-02-19 改めて apple の awk を見てみたがまた最近更新されている。然し、こ
    れに関連する部分が修正された様な形跡はない。恐らくずっとエラーを出力し続け
    るつもりなのだろう。よく考えてみたら nawk は元々 unicode にサポートしていな
    かったので、macOS awk を強制的に LC_ALL= LC_CTYPE=C で動かしても問題はない
    のではないか。

    * github actions

      うーん。これに関しては取り敢えず GitHub Actions の macos-latest を使って
      実験してみる? 取り敢えずダミーのリポジトリを作って見てその上で振る舞いを
      実験してみる。

      awk --version の出力は "awk version 20200816" であり当てにならない。報告
      されている awk も同じ年月日を出力している様だが、blame を見ると問題のエラー
      メッセージがソースコードに埋め込まれたのは awk-32 (2021-02-08 もしくは 16
      Feb) である。strings で "towc: multibyte conversion failure on:" という文
      字列を抽出して見る? →実際にこれを試してみた所、ちゃんと文字列が含まれて
      いるという事が分かった。

      うーん。LC_ALL=en_US.UTF-8 で特に問題もなく動作している気がする。というか
      最初から en_US.UTF-8 が設定されている。色々変えたがよく分からない。因みに
      macos-11 ではそもそも multibyte conversion failure のエラーメッセージが
      /usr/bin/awk に含まれていないので、これは影響がないのだろうと思われる。

      github actions の上で awk-32 をコンパイルする様にしてみたが、それでもエラー
      メッセージは再現しない。或いは特定の環境だけで起こる問題? 或いは特定の文
      字列に対してだけ発生する問題?

    何時迄も保留にしていても仕方がないので取り敢えず対策を入れておく。単に
    LC_CTYPE=C を指定する。

2023-02-19

  * edit: EXIT trap の中のサブシェルの中で exit が動作しない [#D1973]

    builtin exit 自体の処理判定が駄目という事。実際に確認してみるとexit 経由で
    これらの close の処理が呼び出されているので入れ子の exit を実行している事に
    なっている。入れ子の exit に対する特別の処理を行っている?

    →うーん。これは EXIT の中で exit してしまう駄目な設定を回避する為に使って
    いる。然し、subshell の中での exit は別に main のシェルを終了させるのに使っ
    ている物ではないから気にしなくても良い。なので、単に
    _ble_builtin_trap_processing を確認するだけでなくて BASHPID を記録してそれ
    から確認する必要がある。もしくは BASH_SUBSHELL の値を確認する。

    a _ble_builtin_trap_processing に BASH_SUBSHELL も一緒に記録する

      _ble_builtin_trap_processing を現在のどの様に使っているか確認する。現在は
      _ble_builtin_trap_processing には基本的には sig の番号を入れているが、特
      別に exit:* という値を設定している。値を使っている箇所は実は exit:* かど
      うかの判定を行っている所しかない様だ (+ 値が "exit:xxx" の時 trap
      postproc に ble/builtin/exit xxx を設定している)。つまり、sig の値を使っ
      ている箇所は存在しない?

    取り敢えず _ble_builtin_trap_processing に BASH_SUBSHELL を入れる事にした。

    * exit の判定条件はどの様にするのが良いか

      現在の判定には subshell で実行しているかどうか、attach しているかどうか、
      trap を処理中かどうかという三要素を使っている。

      attach していない時に関しては、trap 処理中でなければそのまま exit してい
      る。trap 処理中の時には DEBUG を用いて上まで bubble する様にしている。先
      ず、何故 trap 処理中には bubble を行うのかという事。いきなり終了では駄目
      なのだろうか。うーん。でもやはり trap 処理中であれば trap handling の途中
      で勝手に終了されては困るという事だろう。

      だとすると trap を処理しているサブシェルよりも更に下のサブシェルにいる時
      には普通に builtin exit して良いという事になる。

      つまり以下で良い様な気がする。

      if (trap processing) {
        if (trap processing subshell != current subshell)
          builtin exit
      } else {
        if (subshell || unbound)
          builtin exit
      }

      % 実は
      %
      % if (trap processing subshell != current subshell)
      %   builtin exit
      % else if (unbound)
      %   builtin exit
      %
      % で良いのではないか? subshell の中にいて trap の外にいる場合には何れにして
      % も trap processing subshell ＝ nil ≠ current subshell なので、最初の分岐
      % に入る。と思ったが、unbound の時には !(trap processing) の時にだけ
      % builtin exit したい。!(trap processing) かつ unbound の時は最初の分岐に入
      % るが、(trap processing) かつシェルレベルが同じの時には、やはり強制的に
      % exit する訳には行かない。

      改めて整理する。builtin exit せずに特別な処理を実行する必要があるのは、
      (1) trap processing を top レベルで処理する為 (2) 実際に抜けようとする時
      に job 等のチェックをする為。の二種類がある。(1) の処理に関しては同じサブ
      シェルの trap でなければ必要ない。(2) の処理に関してはトップレベルのシェ
      ルでかつ attach しているという事。従来の判定は単に ¬(1)∧¬(2) を書き下
      しただけの話である。という事で (1) の条件を更新すれば良いだけ。

    実装した。動作確認する。ちゃんとその場で終了している。OK

    histdb/sqlite3.kill の方は実は exit ではなくて単に return を呼び出しておけ
    ば良いのでその様に修正しておく。

2023-02-18

  * 2022-10-02 prompt: 実行直前の rps1 の更新時にカーソル位置がずれる [#D1972]

    * [reject] dirty 状態の更新時にカーソル位置がずれる?

      →これは勘違いだった。或いは別の問題? と思って repository 切り替え直後に
      色々入力してみる等したが、rps1 に固定文字列がある場合だとやはり何も問題は
      発生しない。なので素早く入力した時にずれが生じる問題も rps1 の更新に伴う
      物だったのだろうと思われる。

    gnome-terminal と mintty でも起こっている。screen や contra では起
    こっていない。

    * bleopt prompt_rps1='\q{blerc/rps1}' では発生するが bleopt
      prompt_rps1='\q{contrib/git-info}' では発生しない。bleopt
      prompt_rps1='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\q{contrib/git-info}' として
      幅を合わせてみても再現しない。分かった。時刻が含まれているとずれる。そし
      て rps1='$RANDOM' でも再現する。

    つまり実行直前の rps1 の更新時にずれが生じているという事。固定文字列を表示
    している限りは実行直前に rps1 が再描画されないのでずれが生じないという事。
    また、通常の初期描画時にずれが発生しないのは途中に \r 等があってそれによっ
    てやはりずれが生じないからなのだと思われる。

    rps1 は丁度最後の列のぎりぎりまで文字列を描画する。その時のカーソル位置のず
    れの問題によるものだろう。或いは最後のぎりぎりまで描画した後にシーケンスが
    続く場合にずれが生じるという事。実際に以下のコマンドで振る舞いに違いが見ら
    れる。

    $ printf '%*s\e[5Dworld\n' "$COLUMNS" hello

    というかそもそも rps1 は relative で trace しているのだから右端に到達した時
    にカーソル位置がどうなるのかについては分からないのではないか? 何故右端ぎり
    ぎりに出力する様になっているのだったか。実際に確かめると
    confine:relative:right:measure-gbox で解析している。

    ? つまり、relative なので、例えば複数行のrps1 の時にも mintty や vte では表
      示がずれてしまうという事になる。と思って試してみたが複数行の rps1 の表示
      自体は普通である。$RANDOM 等を含むとやはり実行直前の更新時に問題のずれが
      発生してしまうが。

      別に screen や contra の中で逆にずれるという事が起こっている訳でもない。

      うーん。どうやってぎりぎりの位置で rps1 内部の移動の時に正しくカーソル位
      置を移動できているのか。一旦は rps1 の esc 生成結果を確認する事にする。

      \e[205Chello\e[5D\e[205D\e[1B\e[205Cworld\e[5D\e[205D\e[1B\e[206C6785

      うーん。何だかすごい移動の仕方をしている。vte や mintty 等の一部の端末に
      対して特別なシーケンスを出力しているのかとも考えたが、screen の中で実行し
      ても同様に物凄いカーソル移動を行っている。

      \e[234Chello\e[5D\e[234D\e[1B\e[234Cworld\e[5D\e[234D\e[1B\e[234C11235

      うーん。何故この様な実装になっているのか。justify で right にしている時に
      は必ずこの様に振る舞うのだったか。

      実際に canvas/trace の中でどの様に処理が進んでいるかを確認してみると、
      end-line で生成している内容の時点でこのカーソル移動が発生しているという事
      が分かった。更に詳しく見てみると、justify_fields として [改行] と [右寄せ
      内容] が含まれている。つまり、改行の操作自体もフィールドとして登録されて
      いて、それが一旦カーソルを行頭に移動する役割を果たしているという事。

      ? これは恐らく改行ではなく CUD で下に移動した時等の動作も保持する為? 然し
        CUD だと実際に端末によって座標計算がずれてしまう気がする。というか
        justify する前の解析ではカーソル位置が末端に行っているかどうかも分から
        ないのだから CUD を出力したら確実に CUD がそのまま調整無しで出力される
        事になり、右寄せの場合には確実にずれが生じる事になる。

        結局 CUD 等だと動かない気がするが、これはそもそも rps1 の中で行末でその
        様な事を試みる事自体が問題の気がするから気にしなくて良い気がする。

    何故複数行 rps1 で問題が起きないのかについては複数行 rps1 に含まれる \n が
    実際にカーソルを行頭に運んでいるからなのだと分かった。然し、そうだとして現
    在の問題である rps1 の末端でのカーソル位置が不定になってしまう問題に対する
    対策には関係がない。

    現在の問題に対してどの部分で対策を実装するべきなのかという問題がある。

    a trace の時点でカーソルを丁度良い位置に移動してカーソル位置が不定にならな
      い様にする?

      x 然し、trace は指定した文字列を出力した後のカーソル位置 x y を計算して返
        すという事になっている。

        これで例えば x=0 等として調整された後の物を出力すると、使う側で続いて続
        きの文字列を末尾から続けて出力したい場合等に問題が起こる。
        ble/canvas/trace を通して複数の文字列を調整してから出力したとしてもその
        振る舞いが変わってしまうのは困る。

        x=0 まで移動するのは大袈裟だとして x=cols-2 の位置にカーソルを置くこと
        にすれば派手にずれるという事はなくなるが、この様にしたとしても連続して
        出力する文字列の一文字目が前の文字列の最後の文字を上書きする事になって
        しまうので元のふるまいと厳密に同じにはならない。

    b 或いは rps1 の出力の側で調整を行う。

      trace 生成結果 (_ble_prompt_rps1_data) の時点で調整を行うか、出力の際に調
      整を行うか。最初は生成結果を弄る方が良いと思ったが、出力部分の調整の方が
      すっきりする。生成結果の座標などを弄ると、他の箇所で特定の想定の下に座標
      位置を参照している箇所があった時に壊れてしまう。少し確認した所その様な場
      所はないような気もしたが、ちゃんと確認している訳でもないし、出力部分の調
      整で既に十分にすっきりしているのでこちらの方向は考えないことにする。

    c うーん。或いは、そもそも \r を prompt_rps1 の末端に加えてから trace を呼
      び出すと何が起こるのだろうか。

      もし \r が justify_fields に含まれてしまうのであれば、右寄せが効かなくなっ
      てしまう。或いは効いたとしても相対移動になってしまうので行頭までは戻って
      くれない。

      →うーん。やっぱり現在のフィールドの中で先頭に戻るだけで全体の行の先頭に
      戻る訳ではない様だ。

    →b の方針で実装する事にした。特に出力部分で CR を出力して横位置をクリアし
    てしまう事にする。

    ? ble/textarea#render/.show-rprompt で

      local rps1x=$((_ble_prompt_rps1_data[3]+COLUMNS-_ble_prompt_rps1_gbox[2]))

      として出力後のカーソル位置を計算しているのは何故だろうか。

      % 単に _ble_prompt_rps1_gbox[2] では駄目なのだろうか。うーん。そもそも
      % _ble_prompt_rps1_data[3] と _ble_prompt_rps1_gbox[2] は本来は同じ結果に
      % なって欲しい。\r 等が rps1 に含まれている時にずれてしまう。ずれたとして
      % この様な方法で計算するのは何故だろうか。
      %
      % うーん。先ず、 COLUMNS と gbox[2] は一緒になる様にしている筈。ずれると
      % したら gbox[2] が COLUMNS よりも左に来てしまうという事である。例えば 3
      % 文字左までしか実際の文字列を出力しなかったとする。この時に rps1x は
      % data[3] が報告する x 位置よりも 3 文字だけ右側にずらした位置を実際の出
      % 力後の位置として報告する様にしている。よく分からない。
      %
      % 変更履歴を探る事にする。
      %
      % cf8d9493
      % -  local rps1x=$((_ble_edit_rprompt[1]+COLUMNS-_ble_edit_rprompt_bbox[2]))
      % +  local rps1x=$((_ble_prompt_rps1_data[3]+COLUMNS-_ble_prompt_rps1_gbox[2]))
      % 4fa139ad (canvas/trace の右寄せ対応 #D1502)
      % -  local rps1x=${_ble_edit_rprompt[1]}
      % +  local rps1x=$((_ble_edit_rprompt[1]+COLUMNS-_ble_edit_rprompt_bbox[2]))
      %
      % 先ず gbox は元々は bbox だった様だ。gbox にしたのは右寄せを実際に出力さ
      % れる文字内容に位置で行う様に変更した時に一緒に変更したのだろう。実際に
      % このよく分からない調整が付け加えられたのは canvas/trace 側で右寄せが実
      % 装された時の様である。#D1502 の議論を確認したがこの補正について特に言及
      % している気がしない。
      %
      % うーん。端末幅が最後に解析してから変わった時に備えての事だろうか。それ
      % が一番疑わしい気がする。実際に rps1 の解析を行った後に COLUMNS が増えた
      % り減ったりする場合を考えると、うーん。 rprompt[1] が (0,0) から仮描画し
      % た時の終了位置で、COLUMNS-_ble_edit_rprompt_bbox[2] が描画開始位置とい
      % う事だろうか。なのだとすると現在の実装でこの計算が問題を起こしていない
      % のは奇跡の様な気もする。(と思ったが単に rprompt[1] と bbox[2] の両方に
      % 同じだけ offset が加わったのだと考えれば余り影響はない)。
      %
      % そう考えてみたら、そもそも端末幅が変わる様な事を考えなくても、ちゃん
      % とこの様にして開始位置の分だけずらす処理をしなければちゃんと計算でき
      % ない。

      つまり、元々は rprompt[1] + (COLUMNS - bbox[2]) であった。この時
      rprompt[1] 及び bbox[2] の計測は x=0 を起点として行った物がそのまま入っ
      ていたので、rprompt[1] を直接使う訳には行かなかった。rprompt 表示開始位
      置 (COLUMNS - bbox[2]) の分だけ右にずらす為に、これを加算していたのだっ
      た。

      現在は _ble_prompt_rps1_data[3] に直接実際の描画終了位置が入っているの
      で、わざわざ変な補正を実施する必要はないのであった。

      ところで #D1502 当時の考え方だと rps1 は右からの相対病がなので端末の幅
      が変わっても、適切な位置から描画を開始して相対移動で描画することで、表
      示が崩れたりせずに右端にプロンプトを配置できることを意図した様だ。然し、
      現在の実装では端末幅が変わる毎に再計算を行う様になったし、そもそも描画
      の際にも 0,0 から描画を始めている。なのでその様な配慮の元で描画終了位置
      を調整するなどの事は今となっては難しい。

2023-02-16

  * histdb: bg process timeout [#D1971]

    * 終了を指示した後にもしプロセスが残り続けた時にどうするかの問題について

      a .pid ファイルを残したままにすると正常に終了してその後に別のプロセスが同
        じ pid を持った時に誤爆する可能性がある。

      b .pid ファイルをクリアするとプロセスが残ってしまった時に残り続ける。

      c background で一定時間待ってから生存確認をして生きていたら強制終了する事
        にすると、bgpid 変数が混ざってしまって変な事になる? と思ったが bg だと
        subshell になるので関係ない? どうせ暫く idle にした時に呼び出されるのだ
        から、subshell background ぐらい作れば良い気がする。或る一定時間プロセ
        スが消えなかったら強制終了する。

      d 或いは foreground で暫く待つ? と思ったがビジー状態等の時には結構長くデー
        タベース更新に時間がかかるという事もあるかもしれない。なので余りに長く
        待つのは非現実的である。

      ここは c の方針で良い気がする。実装した。

    2023-02-19 うーん。プロセスが残る様になってしまっている。また、tty が閉じら
    れるのに時間がかかる様になっている。これも何れかのプロセスが fd を掴んだま
    ま残っているのが原因である。

    どうも sqlite3.kill のプロセスがやはり残留してしまっている。

    % * ble/bin/msleep が固まって動かなくなるのが原因のようだ。msleep の実装は
    %   run/$$.util.msleep.pipe に対する fd を用いた物だが、もしかするとこの
    %   pipe ファイルが削除されると動かないのかもしれない。或いは、この fd を開
    %   いているプロセスが2つ以上ないとだめという事なのかもしれない。一応最初の
    %   msleep は動作しているので、サブシェルでは msleep は使えないとかそういう
    %   問題ではない筈である。
    % →これを ble/bin/sleep に変えても元の問題は直らなかったし、逆に本体の問題
    %   を解決したら別に msleep でもちゃんと動いた。

    然し、msleep を ble/bin/sleep に置き換えてもやはり暫くプロセスが生きている
    様である。exit を builtin exit に変更したらちゃんと動く様になった。

    これは ble/builtin/exit の問題なので別項目で議論する (#D1973)。そもそも実は
    ここでは exit よりも return を使うべきなので、ここは単に return に変更する
    事にする。動作している。

2023-02-14

  * make: no-argument return がまたある。make scan でチェックするべき [#D1970]

    $ grc 'return[[:space:]]*($|[;|&])'

  * histdb: git info 等追加情報を user の指定で記録できる様にする [#D1969]
    → "bleopt histdb_remarks" として実装した。

    2023-02-18 そもそも rps1 での dirty 更新が発生していない。因みに
    prompt_status_line に関しては dirty 更新は働いている様だ。然し、これは独立
    した問題の気がする。

    うーん。mintty の中だけでなく、普通に新しいセッションでは全て動いていない。
    何故? うーん。histdb_remarks の対応 commit で以降で動かなくなっている。→同
    期処理等を破壊したかと思ったが単に dirty_mark の生成コードでバグを埋め込ん
    でいただけだった。

  * histdb: PS1=(\$ ' で ( を挿入した時にエラーメッセージ [#D1968]

    これは master 81e376a (もう存在していない。対応するのは 8d5cab8 が近い) で
    は発生していない。

    これは最初は syntax のバグかと思ったがどうやら histdb-word で発生している。

    うーん。response で現在のコマンド内容と全く関係ない物が生成されている? とい
    うかそもそも空の文字列で候補生成されているのではないか。然し、そうだとして
    も index が 8 になっているのはよく分からない。

    _ble_edit_str='PS1=(\$ '\''' len=9
    _ble_edit_ind="5"
    ret="8:'.timeout 1001'" # response

    うーん。分かった request の時点で全ての単語に対して補完を試みようとしている。
    何故かというと現在のカーソル位置がコマンドラインの末端にあるという事を仮定
    している。

    カーソルが行の途中にある場合には個別に実装する必要があるのではないか。と思っ
    たが、カーソルが単語の途中にある時にはその単語について補間する必要はない。
    飽くまで単語の末尾にいる時にだけ補完を実行すれば良い。行の途中にいてかつ単
    語の末尾にいるという状況では、まだ閉じていない単語の末尾にいるという事はあ
    りえない。という事は、現在位置にある単語について調べれば十分である。

    うーん。現在の単語の開始位置を調べる方法が非自明だったが (wbegin を stat に
    設置せずに一気に読み取ってしまう単語が存在する) 取り敢えず実装した。

  * blerc.template: update unicode versions [#D1967]

2023-02-13

  * 2021-10-26 edit: winch の際の遡って再描画する条件をより広げる [#D1966]
    https://github.com/akinomyoga/ble.sh/issues/142#issuecomment-955181640
    https://github.com/akinomyoga/ble.sh/issues/276
    ref #D1679

    取り敢えず端末の reflow について仮定はする事にする。つまり、行末にまで達し
    ていなければ、端末幅を広げた時のその行の次の行が一緒に動くという事はない。
    一方で、行末で折返しが起こっていなかったとしても一番最後の列まで文字が存在
    している時には、端末によっては行継続として取り扱う可能性があるので、安全側
    を取って幅が変化している可能性について考える。

    * ok: 直前のコマンドが行末まで文字を埋めている時

      | というか直前のコマンドの出力結果が端末末端まで存在している時には結局問題
      | になるのではないか? 然し、その様な場合は少ないと考えられる (全画面 TUI な
      | コマンドの場合にはそれも怒るかもしれないがその場合には altscreen 上に描画
      | すると期待したい)。
      |
      | また、折返しをちゃんと記録する端末で更に xenl の場合には、(a) 行末ぎりぎ
      | りで終わった場合には、 [EOF] マーカーが挿入されるし (b) もし行末で改行を
      | した場合には行が切り離されるので端末幅を広げた時に行がくっつくという事も
      | ない。折返しを記録せずに単に最後の列に文字があるかどうかだけで再配置をす
      | る端末については関知しないとして良い気がする。

      その様な場合は少ないし、xenl な端末で折り返しをちゃんと記録していれば、
      ble.sh では EOF マーカーがあるので問題にならない筈。

    * そもそもこの判定は edit よりは canvas の側で管理するべき事の気もする。

      各パネルについて再配置で予期しない結果になる可能性について判定する。

    2023-02-13 改めて考える。各パネルの内容を見に行く事にする。実装していない時
    は安全側に倒して行数が変わっている可能性を考慮に入れる。

    うーん。各パネルは safe/unsafe で判断するのではなくて、最低でも終端点が何処
    以降になるのかという事を返す様にすれば良いのではないか?

    というか現在のカーソル位置から文字数を割り出して最低でも上から何行目以下に
    あるという事までは計算できるのではないか?

    * canvas_winch_action に関する端末依存性は色々考えられる:

      * 全角文字や emoji, 結合文字などの折り返しはどうなるのか。折り返した事に
        よって結合していなかった物が改めてくっついて幅が減るなどの減少はあるだ
        ろうか。

      * 全角文字が入り切らなくて行末に空白を空けて折り返しがあった時に reflow
        でまた行がくっついた時に空けて置いた空白は潰れるのかそれとも残ったまま
        になるのか。

        →複数回 winch が来たらその回数の分だけ減少している可能性がある。然し、
        処理中に届いた WINCH は消滅してしまうのでこれを正確に測るのは困難である。
        最悪の場合は伸びた文字数だけ幅が消滅する事があるのではないか? うーん。
        最悪でも拡張前の行数よりも沢山の空白が潰れるという事はありえない。

      * reflow するかどうかの marker は ECH, EL, DCH によって破壊されるのか其処
        に残り続けるのか。

      * 行末まで文字が行った時点で reflow mark がつくのか、更に文字が追加されて
        次の行に行った時点で reflow mark がつくのか。

      * カーソルの位置は reflow と一緒にどの様に動くのか。

      * DECSC/DECRC で一時移動していた時に、一旦記録していた位置も一緒に reflow
        するのか、それとも戻ってきたら絶対位置に戻ってくるのか。

      * 連続的に複数の再配置が起こる端末と一気に最終サイズに於いて再配置が起こ
        る端末の振る舞いの違い等も考えられる。

    * done: wiki redraw-safe
    * done: blerc: redraw-safe
    * done: ChangeLog

  * README: ビルド過程に対する説明 [#D1965]

    勘違いする人が沢山いるし勝手に馬鹿にしている人がいるので README の make の
    部分に色々書いておく。

    * make/README にも各ファイルの説明を書いている。

  * README: Guix package の位置が変わっている [#D1964]

2023-02-12

  * prompt: \g{} は ble/color/setface/.spec2g を使う? [#D1963]
    https://github.com/akinomyoga/ble.sh/issues/278

    そうしたらカスタム face を指定できて、ユーザーが自分で定義する事に直接の意
    義が出てくる。

    * done: wiki: 他にも faces はあるという事を書く (motivated by bkerin)

    2023-02-13 .spec2g は動的な face の為に算術式を返すので、color.sh の枠組み
    の外側で算術式評価する様になっていると、後に face 継承などを実装した時に評
    価文脈が違って変な事になる可能性がある。評価文脈をちゃんと把握する為に、算
    術式評価した結果を返す関数を color.sh の側で用意してそれを呼び出す様にする
    べきである。.spec2g は .spec2gexpr に改名し、それとは別に spec2g という関数
    を用意してそれを呼び出させる事にした。

  * syntax: 5.2 以降では (()) [[]] の直後は } 等が来ても良い [#D1962]
    これの修正は簡単。

  * color: ble palette の並び方をより分りやすく (suggested by stackoverflow/caoanan) [#D1961]
    https://superuser.com/a/1512656/980046 コメント by caoanan

    色の排列を考え直す余地はある。現在は横幅 64 使っている。高さが 32 なのは実
    は端末の 80x24 には入り切らない。

  * syntax: 履歴展開 & "$!", heredoc [#D1960]

    bash-4.1 以下で echo "$!" を実行しようとしても履歴展開周りで変な事が起こっ
    てコマンドを実行する事ができない。更に bash-3.0 では

    bash-3.0: ble/history:bash/resolve-multiline: そのようなファイルやディレクトリはありません

    と表示される。

    また暫くして実行してみた所違う失敗の仕方をする。どうも本当に履歴展開が起こっ
    ている様だ。--norc で実行しても履歴展開が起こって変な事になってしまっている。
    つまり、これは ble.sh 自体の問題ではないという事。

    a ble.sh の側で履歴展開があるかどうかの判定を行って、履歴展開文字が存在しな
      い時には履歴展開をそもそも試みないという可能性?

      然しそれだと普通の履歴展開と "$!" が混在している場合には結局履歴展開を実
      行することになるので、問題を回避できていない。それに元々の bash の振る舞
      いとして履歴展開が起こる筈なのにそれを無理やり回避するのは間違っている気
      がする。

    b 或いは履歴展開の文法解釈を弄る。というかその様に対応するべきである。そう
      すれば混乱もないだろう。

    →b の方針で修正する事にする。

    * fixed: というか調べてみるとどうやら 4.2 でも "echo!" 等で展開は実施される
      様である。これについては対応した。

    * fixed: 4.1 以下での $!... の展開

      然し今回問題になっているのは 4.1 以下では $! の ! であっても履歴展開を誘
      導してしまうという事である。これを文法的に正しく処理するのは難しい。とい
      うか、$! に続いて何か文字列があると必ず展開されてしまうという事になる。こ
      の振る舞いは困る。もう少し色々試してみる事にする。

      $ echo $!a

      も履歴展開されてしまう。${!} は展開されない。つまり $! に丁度一致する時に、
      $! に引き続き履歴展開がある場合には履歴展開とするという事。

      これに対応する為には check-dollar の中で $! に一致した時に 4.1 以下で特別
      に check-history-expansion を呼び出す必要がある。所で histchar も考えると
      単に '$!' だけ確認すれば良い訳では無い。

      因みに check-dollar が有効な文脈は全て履歴展開も有効の様なので、
      check-dollar の中で履歴展開を試みるかどうかについて追加の条件で判定を行う
      必要はない。

      →実装した。取り敢えず実際の bash の振る舞いと同じになる様に履歴展開の着
      色がされる様になった。

    * fixed: 履歴展開 in heredoc

      履歴展開の着色がされていない。また、\\ \$ 等の着色もされていない。但し、
      \a 等の元よりエスケープする必要のなかった物についてはエスケープとしては処
      理されない。\" もエスケープとしては処理されない。\<LF> はエスケープとして
      認識される。\! は unquote されないが履歴展開を抑制する効果はある。

      * heredoc 内での \\ \$ \` \<LF> エスケープの着色に対応した
      * heredoc 内での履歴展開の着色に対応した

    * fixed: 3.0 での ble/history:bash/resolve-multiline のエラーメッセージは依
      然として表示される。

      どうやら bash-3.0 では resolve-multiline は有効になっていないのに、その外
      側で resolve-multiline を呼び出している箇所が2箇所ある。それぞれに対応す
      る (mutiline サポートなしの) 実装を提供する事にした。とは言っても
      multiline サポートなしなので両方ともほぼ自明な操作である。

    * fixed: histreedit は二回連続だと accept するべきなのでは? 4.1 で展開に失
      敗する時何度でも失敗する。と思ったが、寧ろ 3.0 で二回連続で実行した時に実
      際に実行された方が問題であった。plain Bash だと histreedit だと何回実行し
      ようとしても実行できない。

      代わりにエラーメッセージが表示される。というか何故エラーメッセージが表示
      されていない? in ble.sh → 分かった。ble/widget/.internal-print-command
      が $command を被覆している所為でちゃんとエラーメッセージの起こる履歴展開
      を評価できていなかった。

  * [棄却] histdb: コマンドも histdb-word と同様に数えて良いのではないか? [#D1959]

    これは quote 等を除去した状態で数えるのが良い? それとも quote も含めて記録
    する? コマンドの種類も記録するべき? 然し、実の所、わざわざ記録しなくても、
    後でコマンド履歴を見れば何を呼び出したかは基本的に分かる。

    これは #D1958 と同様の理由で今は数えない。実際に必要になったらその時に実装
    すれば良いが、実際に必要になるのか分からない。

  * [棄却] histdb: histdb-word で一つのコマンドに同じ単語が複数あった時に数える? [#D1958]

    然し目的が使用頻度を記録して後の補完での優先順位に役立てるのだとしたら、一
    つのコマンドの中で複数同じ単語が登場するのは自明の可能性が高く、使用頻度と
    して計上するのは違う気がする。もし実際に単語の使用頻度を興味として知りたい
    のであれば、command_history の command を抽出して自前で処理するべきなのであ
    る。histdb で記録するのは高速にそういった処理をするのが大変だから補完候補生
    成の為のキャッシュとして用いているという側面がある。

  * histdb: auto-complete-history で ' を含むコマンドがあると SQL でエラーメッセージが出る [#D1957]

    これは単に q=\' qq=\'\' の初期化していない状態でエスケープを実行していたか
    らだった。修正した。

  * histdb: bash-3.0 で fork したプロセスが消滅してしまう。謎 [#D1956]

    普通に自分で実行すると生きている様な気がする。

    どうも bash-3.0 では function fname { ... } <&"$fd1" >&"$fd2" 等の様にして
    リダイレクトするとちゃんとリダイレクトされていない様だ。何故か /dev/null に
    繋ってしまう。中でリダイレクトする様にしたら直った。

  * [棄却] histdb-word: edit insert-last-argument 等についても [#D1955]

    実は histdb-word を使った方が良いのでは。と思ったが

    x 現在の histdb-word の実装だと単語の順序等が失われるし (同じコマンドの中に
      含まれている単語は同じ時刻になるのでは)

    x また重複する単語があった時に古いものが抜けてしまう (その方が望ましいとい
      う考え方もあるかもしれないが、やはり思い出しながら探す時に通り過ぎた後で
      もちゃんと現れた方が親切な様な気もする)。

    また現在の insert-last-argument の実装を確認すると履歴展開を使って単語を抽
    出しているので、結局別に現在の実装で問題があるという訳でもない。寧ろ、現在
    の実装は (subshell fork するものの) 他のプロセスとの交信がない分だけ安定し
    ているのではないかという気がする。

2023-02-10

  * histdb: 4.2 で算術式のエラー(配列負の添字) のエラーが生じている [#D1954]

    実は printf %(%s)T に対応しているとは言っても、bash-4.2 では -1 を指定しな
    いとちゃんと現在時刻になってくれない様だ。これが為に BLE_SESSION_ID の為の
    時刻決定で失敗していた。

    * 2023-02-12 bash-4.2 の last_time が 0 になっている。これも同じ事が原因だっ
      た。ble/histdb/.get-time の関数の中でも %(%s)T を用いて時刻を取得しようと
      していたが、明示的に -1 を指定する必要がある。

  * histdb: 3.2以下で session が登録されていない [#D1953]
    これは単にデバグ用に置き換えていた関数名 assign2 が残っていたのが原因だった。

  * histdb: sqlite のエラーメッセージは端末に表示するようにする [#D1952]

    本来は全く表示されない事を期待しているので、もし表示されるのだとしたらバグ
    である。なので表示する。

2023-02-06

  * 2022-01-23 [対応済み] コマンドのログ機能を作成する [#D1951]

    特定のファイルに情報を書き込む。

    同時に複数の書き込みがあった場合に混ざり合う危険性がある。滅多に起こらない
    と思いたいがちゃんと防止策は作っておく必要がある。例えばシェル毎に履歴を記
    録して終了する時に合成するという手が考えられる。合成自体が衝突する自体を防
    ぐために mkdir/rmdir を使うのが一つの手である。

    コマンドにはコマンド実行前とコマンド実行後の二つに分けて結果を書き込みたい
    という欲求がある。という事を考えると、

    $ printf '%x/%s/%s.e%s\n' $(printf '%(%s)T' -1) "$HOSTNAME" $$ "$LINENO"

    * バックグラウンドのジョブの状態はどの様に記録するのか。うーん。ジョブに関
      しては一応 ble.sh の中で追跡はしている。それに従って終端を幾らか荒い尺度
      で検出する事はできる。しかし正確な時間は分からない。

      プロンプトを表示した時刻も記録しておくと良い様に思われる。しかしそうなる
      と大量の記録が残ってしまう事になるのではないか。うーん。プロンプトを表示
      した時刻に関しては別に全てを記録する必要はない。前回のプロンプトの表示時
      刻だけ覚えておいて、ジョブ変化を検出した時にその情報を備考として乗せるだ
      けで良いのである。

    * 記録する情報は以下の通り。

      cmd, pwd, 終了ステータス(PIPESTATUS), 各種時刻情報, files(自動補完用), 構
      文解析情報(後で単語を抽出する為。というか単語の範囲だけで良い).

      これを使って処理するのはもしかしたら外部プログラムに頼らなければならない
      かもしれない。

    或いはデータベース等も保存先として考えても良いのかもしれない。但し、その場
    合には sqlite3 等に対する依存性が発生する。一方で、sqlite3 には最低限の排他
    制御が含まれている様ではある。

  * 2022-06-28 [対応済み] コマンド名の曖昧補完ができない。./adf[tab] [#D1950]

    これは . で始まるコマンド名を列挙してそれで補完を実行しようとしている為であ
    る。/ が含まれる場合には glob で一致させてその上で実行属性でフィルタする必
    要がある気がする。

    引数の場合にはできている。うーん。/ が含まれる場合は別に生成するべきなので
    はないか。

  * 2022-07-20 [解決済み] konsole drag&drop [#D1949]
    https://github.com/akinomyoga/ble.sh/issues/211
    https://invent.kde.org/utilities/konsole/-/merge_requests/714

    konsole に PR を出したが返事がない。この2日の間に別の PR はマージされている。
    暫く待っても何も反応がなかったら Bugzilla の方にも提出する事にする。もしく
    はメーリングリストに直接問い合わせる。

  * [棄却] histdb: 現在の有効なファイル名をコマンドに紐づけて記録する可能性について [#D1948]

    * コマンドが前提としているファイルの存在を確認して history を skip する。

    ファイル名着色などの情報を参照したい。そうすればファイル名と偶々一致してい
    る単語を誤って登録してしまうという事もなくなる。chroma を充実させる動機にも
    なる。

    複数のファイル名が考えられるので別テーブルに記録する事も考えたが、それだと
    データベースサイズが大きくなる気がする。或いは、別テーブルにファイル名だけ
    記録しておいて但し id リストを command_history の entry の中に保存するとい
    う事にすれば良いのかもしれない。

    余り形式を複雑にしても仕方がないしデータベース上でファイル名を操作するとも
    思えない。後で特定のファイル名を指定しているコマンドを探るとしても、ファイ
    ルの相対パスを解決しなければ使えない。

    然し改めて考えたら、既にファイルが存在しているかどうかに関わらず実行するコ
    マンドもあるのだからファイル名と一致するかどうかで候補として生成するかどう
    かを変えるのは余り良いアイディアではない様な気もする。どうなのだろう。

    * 更に改めて考えてみると本当に fish がここまでの情報を記録しているのかも不
      明である。oil の zulip ではその様な事を言っている人がいたが、実は単に
      fish は cwd だけを見て判定している可能性もある。実際検索しても其処まで積
      極的に履歴を記録している訳でもない様だ。2016に初めて cwd を一緒に記録し始
      めた程度である。

    →今 fish の振る舞いを試してみたが、コマンド実行時に存在したファイルを消し
    ても、同じディレクトリで同じファイルが autosuggestion の候補として表示され
    る。つまり、(少なくともデフォルトの設定では) fish は別にコマンドライン中に
    含まれるファイル名について記録して存在を照合しているという訳ではない様だ。

    逆に cd 等の既知のコマンドについてそれが成功するかどうかをその場で判定して
    いるというだけの事なのかもしれない。

    うーん。これについては棄却する事にする。代わりにコマンドが成功するかどうか
    を高速に判定できればそのコマンドをスキップするという機能を項目として残す。

  * histdb: 様々の sql query エラーの修正 [#D1947]

    * main: bash-3.2 で BLE_SESSION_ID の時刻決定が誤っている。

      bash-3.2 でちゃんと words を登録できていない気がする何故? 或いは、もっと
      前から駄目だった? と思ったらどうやら時刻が誤っている様だ。そし
      て_ble_base_session の時刻を見ると何故か 1000000 分の1の少数にされている。
      うーん。結局これは ble/base/initialize-session の初期化が問題だった。

    更に bash-3.2 で session が登録されていない。うーん。調べてみた所様々なエラー
    が出ていた。bash-3.2 に限らず bash-4.0+ でも sqlite がエラーメッセージを出
    しているのを捨てていた。直した。

  * 2022-01-08 term: prompt_status_line でずれが生じる端末がやはり存在している。何故だろうか [#D1946]
    Ref https://github.com/borisfaure/terminology/pull/115

    2022-02-02 windows terminal でもずれる。改めて確認してみる。実は status を
    表示していなくても端末の一番下の行で改行をしようとしても改行されないのであ
    る。という事はここで使っているシーケンスの内 windows terminal で動作しない
    物が存在しているという事。

    increase-height.draw が動作していないのではないだろうか。

    うーん。もしかして DL をした時に新しく追加した行が削除されて逆スクロールし
    ている? 更に IL も動作が変だという事が判明した。

    →Cygwin に報告したらすぐに修正してくれた。これで待っていればちゃんとした振
    る舞いになる。それまでは仕方がないので我慢する。

    * 2022-03-04 terminology でずれる原因は分かった。これは terminology のバグで
      ある。以下で変な振る舞いをするという事が分かる。

      $ printf 'O\e7\e[%d;%dHA\e8K\n' $LINES $COLUMNS

      https://github.com/borisfaure/terminology 報告しようと思ったが何だか良く
      分からない。http://issues.terminolo.gy/ から
      https://phab.enlightenment.org/project/view/8/ に跳んだが issue を作る方
      法が分からないので取り敢えずログインする事にしてみた。そしたら元からある
      チケットですら見ることができなくなってしまった。

      面倒になったのでこれは PR にして出す事にした。
      https://github.com/borisfaure/terminology/pull/115

      * terminology version 判定

        WA を追加しようと思ったが terminology を判定する方法は実は無い。xterm の
        ふりをしているので区別が付かない。もし terminology の区別がつくのだとした
        ら、terminology では最後の行を使わない様に修正するのが良い。

        DA2 応答は 1.4.0 以降は 61;337;0 である。それより前は 41;285;0 だった様だ。
        https://github.com/borisfaure/terminology/commit/96bbfd054b271f7ad7f31e699b13c12cb8fbb2e2 1.4.0 "61;337;0"
        https://github.com/borisfaure/terminology/commit/e4d7cb93f2ad3c09d50362cee557815e10997687 1.4.0 "41;337;0" (not-released)
        https://github.com/borisfaure/terminology/commit/59ad20f6f8e364b02e1c65ec28f480649eea714a 0.4.0 (DA2 には変更なし)
        https://github.com/borisfaure/terminology/commit/526cc2aeacc0ae54825cbc3a3e2ab64f612f83c9 0.3.0 "41;285;0"
        https://github.com/borisfaure/terminology/commit/db902446540f5e014694da0ec6fb495cfab15e62 0.2.0 "0;271;0"
        https://github.com/borisfaure/terminology/commit/500e7be8b2b876462ed567ef6c90527f37482adb 0.2.0 "1;271;0" (not-released)
        https://github.com/borisfaure/terminology/commit/8b822a61d7721fce16e145b57dc67ca6ae8b752d 0.1.0 "\e[?1;0c" DA2 じゃない (initial commit)

        まとめると、

        terminology-0.1.0 ... DA2 応答は返さない
        terminology-0.2.0 ... 0;271;0
        terminology-0.3.0 ... 41;285;0
        terminology-1.4.0 ... 61;337;0

      一応 temrinology はこれで100%ではないが検出できる。然し、考えてみれば検出
      できたとしてもどうやって workaround を加えれば良いのか不明である。うーん。
      \e8 する前に一旦 \r で行頭に戻るというのが一つの対策かもしれない。
      →この対策でちゃんと動く様になった。

    * [自然解消] 2022-03-08 上記と同様の現象が bash-3.2 では未だ健在である。何故だろうか。

      terminal ID がうまく動いていないという事だろうか。→terminal ID はちゃん
      とうまく行っている。terminology 1.4 という事になっている。

      また別の問題という事だろうか → patched terminology では発生していない。
      つまり同じバグ。

      _ble_term_rc がちゃんと置き換わっていない可能性? → そうでもない。ちゃん
      と \r が挿入されている。

      直接 '\e8' を記述している箇所がある可能性? →うーん。そういう箇所もない。
      DECSTBM のテストに用いている \e[r によって wrapnext が不自然な状態になっ
      ている可能性? → テストの方にも \r を入れてみたが振る舞いは変わらない。

      また問題が発生するのは最初の1回だけの様でもある。つまり、未だ端末の種類を
      特定するよりも前の時点で実行した rc により wrapnext が壊れている可能性。

      2023-02-06 うーん。今実行したら再現しない。恐らく terminology の側が修正
      されたので問題が出なくなったのだろう。なのだとすれば、わざわざ古い
      terminology を持ち出してテストするのも大変だし、気にしない事にする。

    * fixed: 2022-03-04 terminology で最初のコマンドを実行する迄 C-h 及び BS が
      全く効かない。何故だろうか。そもそも C-h を受信できているのかも不明である。
      一回コマンドを実行すれば問題なくなる。

      builtin bind -X を見た感じが問題ない。然し、何故か bind -X の実行結果に

      "\C-h": "ble-decode/.hook 8; builtin eval -- \"$_ble_decode_bind_hook\""

      というのが混入する状態になっている。

      ? 何故 terminology だけで発生するのだろうか。うーん。不思議だ。調べるとど
        の端末でも bind uvw は何か変な状態になって登録されている状態になってい
        る。然し、\C-h も同様に設定されているのは terminology だけである。

        然し、そもそも何故 uvw が直接 bind されてそれが bind external に登録さ
        れてしまっているのか。これは何らかのミスなのではないか。

        そもそもこれらの bind が設定されている箇所を特定すれば何処でこれが起こっ
        ているのか判明する筈。

        うーん。bind -x を実行している箇所を見たが別に .hook 8 を特別に指定して
        いる箇所もないし、decode.bind.50108.UTF-8.bind も特に変な事はない。

      * うーん。bind -X で違いが出るという事は bind.save に問題があるのかもしれ
        ないと考えたが、どうやらそうでもない様だ。別に bind.save の内容は変化し
        ていない。

      * bash の version によるバグかもしれないと思って調べてみたが bash-3.2 か
        ら 5.1 まで全て問題は再現する。plain Bash + ble.sh --norc でも再現する。
        noattach でスタートして ble-attach を使って attach した時にも再現する。

      * うーん。分かった。terminology は erase を ^? から ^H に差し替えて端末を
        初期化している。これによって UVW? の workaround が効かなくなっていたと
        いう事。うーん。つまり、原理的にあらゆる文字がこの影響を受ける可能性が
        あるという事では。

      --- stty1.txt^I2022-03-08 20:10:24.782885825 +0900
      +++ stty2.txt^I2022-03-08 20:10:44.466968954 +0900
      @@ -1,5 +1,5 @@
       speed 38400 baud; rows 24; columns 80; line = 0;
      -intr = ^C; quit = ^\; erase = ^H; kill = ^U; eof = ^D; eol = <undef>;
      +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 = ^V; discard = ^O; min = 1; time = 0;
       -parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts

      * 愈 bind-tty-special-chars を off にする必要があるという事だろうか。

        但し bash-3.0 には bind-tty-special-chars は存在していない様である。

      結局これは ble/decode/bind/adjust-uvw で ^H についても同時に上書きする事
      にした。これで動いている。adjust-uvw は実際の所、初回呼び出し時だけしか処
      理を行わないのでここで多少沢山のコマンドを走らせても困らない。

    2023-02-06 一年以上も放置されているのでまた改めて確認する。うーん。どうも少
    し弄ったら直った様なのでこれで良い事にする。

  * util/idle: background で何が動いているのか分からないので immediate-show で表示する? [#D1945]

    オプションで切り替えられる様にする。うるさいので既定では off。

    immediate-show で表示していると menu-complete 等他の物が使えなくなるので、
    scheme == default の時にだけ ble/util/idle で現在実行中のタスクを表示する。

    * info: Emacs の *Messages* の様に後で記録を見返す事ができると良い気がする。
      後でログにする事も考えて時刻も含めておく (但しどの様にログにするのかは謎。
      info に新しく schene を追加して log という事にして、更に何処かのファイル
      にキャッシュとして保存するなど? 何れにしても全然必要性を感じないので今の
      所は気にしない事にする)。

  * histdb: backup機能 [#D1944]

    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 しておけば十分の気がする。

    と思ったが integrity_check を行うのであれば hourly で十分の気がする。或いは
    そんなに頻繁に壊れる物でもないと考えれば daily でも良いのかもしれない。

  * histdb: sqlite3 のプロセスだけ残ってしまったのをどう始末するか [#D1943]

    * sqlite3 のコマンドライン引数に親 pid を含める可能性

      考えたが、無駄な文字列を指定できる様な雰囲気はない。と思ったが -cmd を使
      えばコメントを指定できるのではないか。然し、その様にしたとしても ps をし
      た時に見える様になるだけで、スクリプトから対応する親プロセスを抜き出して
      殺すのに使える訳でもない。というか、そもそも sqlite3 のプロセスを列挙する
      時点で簡単ではない。なので、これは単に ps をした時に分かりやすいというだ
      けの事である。

      或いはプロセスツリーで見やすくする為に直接親プロセスから起動して disown
      する? と思ったが、やはり無駄なメッセージが表示されてしまう。そもそも、$!
      を勝手に書き換えてしまう事になるのでやはり避けたい。

    a 別の方法はプロセスを書き込んでおいて他の ble.sh session がそのファイルを
      削除する時に中に書かれているプロセス ID に対して kill を送信するという事。
      然し、これも pid 記録ファイルの削除のタイミング等によって変な事にならない
      かの懸念が残る。

    b うーん。或いは。。sqlite3 のプロセス id で run/histdb.$bgpid.ppid という
      ファイルを作って置いて、もし run/histdb.$bgpid.ppid に含まれている親プロ
      セスが既に存在していなかったらその sqlite3 プロセスは kill する。

    c 或いは本当は $$.histdb.pid というファイル名にして中に記録する方が良い様な
      気もするが、それだと ble.sh 本体の方の管理によって削除されてしまうので駄
      目。或いは、ble.sh 本体の方で *.pid というファイル名だったら中に書かれて
      いるプロセスを削除するというルールにしておくという可能性もある。

      うーん。その方が今後類似の事をしたいと思った時に consistent に処理できる
      様な気がする。

    d reject: 別の可能性としては、一つの sqlite3 プロセスを全体で共有するという
      可能性?  その様にすれば常に一つのインスタンスだけを持っていれば良いし、一
      旦起動したら起動しっぱなしで良い気がするので、わざわざ kill しなくても良
      い。と思ったが、そうすると今度は stream の同期の問題が出てくる。複数の
      query が混ざり合ってしまうともう駄目になってしまう。そもそも同期の問題を
      解決する為に sqlite3 を使っているのだから、やはり sqlite3 をセッションご
      とに持つのは避けられない。

    この b の方法が良い気がする。と思ったが c の方法にする。

  * histdb: _ble_histdb_exec_ignore の管理をちゃんとする [#D1942]

    現在の実装だと複数の exec lines がある時に最後のコマンドの ignore が最初の
    コマンドの ignore として使われる事になってしまっている。

    a 毎回判定する事にする? →それだと途中で設定が変更された時に変な事になる。

    b 同じ command_id で既に項目が登録されている時にだけ更新する? →無駄にコマ
      ンドを発行する事になる気がする。然し、update を使えば該当する項目がない時
      には無視されるだけなので、単に request を一回送信するだけである。

      これを考えたら単に _ble_histdb_exec_ignore の現在のチェックを削除するだけ
      で良い。そもそもよく考えたら session 情報の更新は histdb_ignore に該当し
      たとしても行っておくべきだし、何れにしても request は送るのではないか。

    c exec line に追加情報を埋め込める様にする? 然し histdb だけの為に専用のフィー
      ルドを用意するのは拡張性がよくない (使いたい項目ごとに拡張を行う必要があ
      る) し、別の配列に項目を保存するとしてもインデックスの管理などをどうする
      のかが分からない。

      と思ったが command_id を使って記録すれば良いだけなのでは? そして使ったら
      unset する。

    結局 c の方針で実装する事にした。結局 ignore されたコマンドに関しては
    session 時刻及び cwd も更新されないがそれで良い事にする。

2023-02-05

  * histdb: 同じディレクトリの一番最近の履歴を抽出する [#D1941]

    有効なファイル名を記録するのよりも先にこちらを実装するべきである。

    histdb-history

    * ディレクトリが移動した後も追跡できれば追跡する。

      ディレクトリの inode を記録するという手もある? 然しファイルシステムが異な
      る場合もあるので何とも言えない。別のファイルシステムのディレクトリを掴ん
      でしまったら仕方ないので諦める。そもそもディレクトリが移動して元の場所に
      ないのであれば別の物を拾っても仕方がない。それを言い出したら一旦ディレク
      トリを削除した後に別のディレクトリを移動して持ってきた場合なども考えなけ
      ればならなくなる。

      と思ったが inode を持っていてもそのディレクトリのパスを取得する方法がない。
      ファイルシステム依存で特別のコマンドを走らせれば inode に対応するファイル
      名を列挙する事はできるが、一般にはファイルシステムを浚うしかないので単な
      る補完の為には現実的に実行できない。
      https://stackoverflow.com/questions/14822611/is-there-any-way-that-i-can-search-for-a-file-or-a-filename-using-a-given-inode

      可能性があるとしたら移動先のディレクトリでコマンドを実行した事があるとし
      たら、inode が一致する物をデータベース内で探して列挙する事はできる。

      * うーん。どうやら stat は posix ではないらしい。つまり、inode を取れるか
        どうかは分からない。ls -i もあるが、これも明らかに posix ではない。

        しかも stat ですら BSD と Linux でオプションの指定方法が異なる。Linux
        では stat -c %i file だが BSD では stat -f %i file である。因みに ls
        -di file は寧ろ BSD と Linux で同じである。

        確認してみた所 ble/file#mtime で既に stat を使っていて -c と -f の判定
        も行っていた。取り敢えずこの判定を流用する事にする。

      % うーん。track_directory というテーブルを作る事にする。作った。一応登録
      % はできている→結局これは使わない事になったので削除した。

    一文字コマンド等の自明なコマンドを対象としない。これは histdb_ignore で指定
    すれば良さそうな気もするが、実行時間などが気になる場合もあるかもしれないし、
    完全なログを後で欲しいという場合もあるかもしれないので、ignore は別に指定で
    きる様にするべきかもしれない。つまり、ログに残すかどうかの ignore と補完で
    現れるかどうかの ignore は本来は別の物であるのに関わらず元の bash では一緒
    くたになっていた (寧ろ元の bash ではログを残すという意味合いは弱くて後でコ
    マンドを再利用するというのが目的だったのだから、元の bash で設定ができない
    のは理解できる)。

    * source:histdb-history で source:history を置き換える?

      うーん。それだと .bash_history にあって histdb にない物が表示されなくなる。
      また、HISTIGNORE で除去していた物も設定される様になるので不都合があるかも
      しれない。strip が HISTCONTROL にある時には strip を実行するべきだろうか?
      等色々難しい。そもそも検索時には先頭の空白は無視しても良い気がする…が
      sqlite はその様な場合の glob には対応していない。

    これの実装は意外と簡単だった。単語補完が難しかったのは実の所、単語の抽出及
    び不完全単語のん特定などの処理が難しかったのだという事。

    * done: track_directory 登録廃止

      一方で、track_directory による inode の検索はそんなに簡単ではない。うーん。
      現在ディレクトリで検索して見つからなければ inode で検索して云々としたい所
      だが…。うーん。track_directory なるテーブルを作ったのは余り意味がなかっ
      た様な気もしてきた。現在いるディレクトリの inode を使って検索すれば良いだ
      けなのでは? 元々 track_directory で何をしたかったのかというと、"現在ディ
      レクトリ名 → inode の集合" だろうか。然しそれは変である。"inode" は一つ
      しか無い筈で、それは現在ディレクトリの inode を参照すれば良い。

    結局 command_history に新しく inode カラムを追加してそれを元にして検索する
    事にした。

  * 2023-01-26 histdb: 形式を変更する時は形式自動アップグレードを実装する [#D1940]

    misc/version に基づき行う。ダウングレードが必要ならば代わりにファイル名にバー
    ジョン番号を含めて (例: history@chatoyancy.v1.sqlite3) ファイルを開き直す。

    正に同じ事 (column がなければ column を追加する) をしようとしている人がいた。
    然し、sql query 一発で実行する方法はない様である。
    https://stackoverflow.com/questions/56762261/sqlite-how-to-use-select-count-in-case-statement

    仕方がないので version を取得してそれを元に upgrade が必要であれば実行する
    という事にした。結局これは実装する。実装した。取り敢えず動いている。

  * contrib: fzf, bash-preexec などは integration dir に移動する [#D1939]

    install 時に symlink を貼る。

    古いインストール先を上書きする場合を考えたら symlink でなかったら削除するべ
    きでは。→実際にやってみたら timestamp で比較してちゃんと rule が発火するの
    で ln -sf で上書きしてしまえばOK。

  * histdb: 今までに入力した単語を記録する機能。単語自動補完 (histdb-word) [#D1938]

    当初は対応する 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 で十分の気がする。

    2023-02-03 まず最初に newline を実行する前の時点で項目を登録する様にする必
    要がある。新しく blehook exec_register を作って、其処から histdb のコマンド
    登録を実行する事にした。

    * fixed: LINENO の設定と実際の値が変な事になっている気がする。

    * fixed: PS1 \# についても更新のタイミングと初期値がおかしい。

    * fixed: また、\# は初期値は bash では 1 の様である。然し、現在の実装だと 0
      になっている気がする。

    * fixed: history_index の値も変である。1 少ない。更に履歴を遡って編集して実
      行した場合も変である。histdb_ignore で無視された項目は前の項目よりも次の
      項目と同じ履歴番号になるべきである。

    取り敢えず実装した。

    * fixed: HOSTNAME に / が含まれている時にファイルが作れないのでは。/ は %
      に置換する事にした。

    更に記録した単語を元にして auto-complete で単語を提示する?

    * done: 外部から auto-complete source を追加する枠組みは整えた。

    * 現在位置を含む単語を列挙する。これは wbegin を辿っていけば良い筈だが…。
      既に類似の事をしている箇所はあるか?
      ble/syntax/completion-context/.check-prefix で現在位置が属している単語を
      決めている。うーん閉じていない非単語 node の先頭を見つけるのは難しそうだ。
      tprev を辿って行って -1 になった所で更に遡って node を見つける? 否、stat
      に格納されている nlen を見れば良い気がする。

      然し、よく考えてみればそもそも単語の途中にカーソルがいる時に自動補完で単
      語として補完するのは変な気がする。特に suffix が続きと一致している時に、
      それを skip するのかしないのか。等。(但し skip についてはちゃんと処理して
      いるのではないか? ble/complete/insert が処理する)

      最後の時点で単語を閉じているのではなかったか? と思ったが syntax_debug を
      設定してみてみても単語は閉じていない様だ。単に最後に閉じていない単語のエ
      ラーを列挙しているだけ。逆に言えば閉じていない文脈を同様に拾ってその文脈
      での単語の開始点を調べれば良いのである。
      ble/highlight/layer:syntax/update-error-table の実装を参照すれば良い。

      うーん。同様にやってみたが一番上の文脈の情報しか取れない。何故? というか、
      同様の処理を実は parse の最後でもやっている様な気がする。何が違うのだろう
      か。また、nest-pop を実行する時に tree に登録している様に見えるが、何故そ
      れが参照できないのだろうか。

      一方で syntax_debug ではちゃんと木構造を再構築できているので何処かには情
      報がある筈である。と思ったが tree-enumerate の場合には最初に木構造を閉じ
      るための処理を追加で行っていた気がする。→
      ble/syntax/tree-enumerate/.initialize を見たら当にその様な処理を行ってい
      た。

    * 単純単語の場合にそれがファイル名かどうかを記録する? そうすると最悪単語の
      登録数は2倍になる。勿論 simple-word でない物は展開できないので、これは二
      倍にはならない。しかし其処までするのも変な気がする。

    2023-02-06 words の登録順序が気になる。ちゃんと順序が保たれる様に変更した。

  * 5.3: ble/builtin/trap -P [#D1937]

    trap に -p と -P の両方が指定されていた場合はどちらが勝つのか? と思ったら両
    方指定する事はできませんというエラーになった。ble/builtin/trap でもその様に
    実装する。

    うーん。builtin trap -P を使ってより効率の良い実装に切り替えようと思ったが、
    実際には ble.sh の中では « trap '' xxx » の形になっている事を想定した処理に
    なっていた。読み取る時も結局 eval "ble/builtin/$(trap -p INT)" 的な形にして
    ble/builtin/trap に委譲して処理している (つまり、eval を使って引数を評価し
    ている)。なので今迄通り trap -p を使い続けるので良い気がする。敢えて複雑に
    処理を切り替える必要もない。

  * 2022-03-19 [対応済み] compat bash-5.2 で \q{...} が動かなくなっている [#D1936]

    どうもこれは bleopt の設定時に \ が重複しているのが原因の様だ。表示時の問題
    ではなくて本当に値が変わってしまっているという事を確認した。

    どうもこれは ${var[@]/%/"=$value"} の振る舞いに関する物の様だ。というかこれ
    は既に別に patch を用意した物の気がする。というか既にこの問題を発見してそれ
    で修正したという事の気がする。やはり早く patch を提出する事にする。

    →これはもう修正を提案して修正されている。現在の 5.2 では何も問題は生じてい
    ない。

  * 2021-06-12 [対応済み] bash: 開発版 version に関して [#D1935]

    実は bash-dev 版は 5.1.xxx の儘推移している。本当は 5.2.xxx-alpha の様な形
    にするべきなのではないかという気がする。よく分からない。提案しようかとも思っ
    たが実際の所は 5.1.x-maint になっている事から、本来は devel branch は既に出
    た version のメンテナンスモードという意味合いだったのかも知れない。然し、こ
    の様になっていると次の version かどうかを判定するのに BASH_VERSINFO を利用
    する事ができない。今迄は新しい version になる事によって何か機能が減るなどし
    て動かなくなるという事はなかったので余り気にならなかったが、"テスト" という
    観点から本来は早くに bash-5.2 に増やすべきなのではないかという気がする。

    差し当たっての ble.sh の側では release status も見て version を上げる様にす
    るのが良いだろうか。と思ったが…。自分はテストの為に release を release に
    しているし、逆に maint で動かしているユーザーがいたとしても遅くて使い物にな
    らない。自分の relstatus に関してはまた別の値を指定するという手もあるのかも
    しれない。と思ったが、それをするぐらいであれば実は configure.ac に於いて
    version を 5.2 に書き換えてしまえば良いのである。

    2023-02-05 これは一回提案したが自分が決めるんだと言って reject された。仕方
    がないんで自分の側で処理する事にする。

  * 2021-05-03 [対応済み] 5.2 新機能: READLINE_ARGUMENT [#D1934]

    調べてみると引数が存在している時にのみ定義される様である。また今気づいた事
    だが -x 属性が入っている。

2023-02-02

  * leakvar: いい加減に pending な leakvar fix を入れる [#D1933]

    最近の profile.d 変数たちも除外リストに追加する。

    * done: key という変数が mshex によって leak している → これは修正した。

    j という変数が確率的に leak している。

  * ble/syntax/highlight/vartype: ローカル変数を拾っている [#D1932]

    declare -p ret (配列), echo ${lookahead} (空変数) などグローバルに存在しな
    い変数の属性を拾ってしまっている。

    これに対応するには ble/util/print-global-definitions の様にトップレベルの変
    数にアクセスする必要があるが subshell 内部で行わないと行けないので問題があ
    る。ローカル変数に当たってしまってグローバルを直接見れない時にのみ特別の処
    理をするとしても、その判定に ble/variable#is-global 等を呼び出すだけで fork
    コストがかかるので既定でこれに対応するのは余り気が進まない。

    ? ok: 所で、 ble/util/print-global-definitions の中で呼び出している
      ble/variable#is-global は先に declare -g -r してしまっているので、常に真
      を返すのではないか。つまり、ローカルかどうかの判定には使えない → と思っ
      たが見えている一番上が local readonly であれば global readonly があっても
      関係なく新しく local 変数を内側の関数で定義できる様だ。なのでちゃんと判定
      する事ができる。

    例えば bleopt syntax_ensure_global_variable 等の設定が指定された時にだけ
    global 変数の状態を見に行く等?

    試しに実装してみたが動かない。readonly にする方式だと ret という変数自体を
    新しく定義する事ができなくなるので駄目。結局実装してしまった。うーん。多少
    遅くなるかもしれないが気にしない事にする。

    2023-02-03 $_ でエラーメッセージが表示される。$$ に対しても readonly からエ
    ラーメッセージが表示される。どうも ble/variable#is-global は特別変数に対
    して使ったことがなかった様だ。単に stderr を潰す事にした。

2023-02-01

  * main: ble-reload が動かなくなっている [#D1931]

    "--rcfile=$HOME/.blerc" を指定して再 source しようとして $HOME/.blerc が存
    在しない事によって失敗している

  * complete: ../ で始まるパスの曖昧補完が効いていない [#D1930]

    ../out/data/c2w.wcwidth-compare.musl-vs-12.1.txt[TAB] の曖昧補完が効いていない

    どうやら .. を .*.* 等に変換すると .. に一致しなくなってしまう様だ。
    ble/complete/source:file/.construct-ambiguous-pathname-pattern を修正したら
    すぐ直った。

  * canvas: char_width_mode=musl の判定をより正確にする [#D1929]
    https://github.com/akinomyoga/ble.sh/issues/269#issuecomment-1407360550

    konsole の中で起動すると文字幅スキームが 15.0-musl であると勘違いしている。
    何故? 或いは konsole が内部的に musl を使っている可能性? と思ったが、
    Unicode 15.0 等もちゃんと認識している。もし本当に musl の実装であれば最新の
    Unicode には対応できていない筈。

    Refs: #D1880 #D1668

    これは fedora でも発生している問題。

    * konsole で U+D7B0 の幅が 1 ではなく 2 を返すのが問題の様である。

    他の端末の振る舞いを調べる。

    * kitty はちゃんと 1 になっていて 15.0-west と判定されている。U+D7B0:U+3099
      に対して 1:0 である。

    * xterm は 0 を返していて 14.0-west と判定されている。U+D7B0:U+3099 に対し
      て 0:0 である。

    * terminology は 15.0-west で大丈夫と思ったが、何故か 3099 に対して 2 を返
      している。Unicode 15.0 に従っていない気がするが大丈夫なのか?

    * lxterminal は U+D7B0:U+3099 に対して 0:0 を返していて 15.0-west になって
      いる。

    うーん。これらの振る舞いを見るとどの端末も何処か異なる振る舞いをしている。

    * というかそもそも ble.sh が使っている musl のテーブル自体も古いという事が
      判明した。何処かの野良 github repository から持ってきたが滅茶苦茶古い。こ
      れも一緒に更新したい。もしかすると新しい musl では 0 にならないという可能
      性もある。確認してみると以下の時点で修正が入っている。

      2017-12-18 /src/ctype/{wide,nospacing}.h
      2019-10-25 /src/ctype/{wide,nospacing}.h
      2020-01-01 /src/ctype/wcwidth.c
      2021-12-27 /src/ctype/nospacing.h

      % 取り敢えず最新版に更新する事にする。うーん。どうやら D7B0 は以前は幅2だっ
      % たが現在は幅 0 の様である。使えない。改めて
      %
      % $ (source make/canvas.c2w.list-ucsver-detection-codes.sh)
      %
      % を使ってテーブルを生成してみる。
      %
      %                | -----Unicode EAW+GeneralCategory                   |musl
      % ws[0]  U+09FBC | -1  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2 | 2
      % ws[1]  U+09FC4 | -1 -1  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2 | 2
      % ws[2]  U+031B8 | -1 -1 -1  2  2  2  2  2  2  2  2  2  2  2  2  2  2 | 2
      % ws[3]  U+0D7B0 | -1 -1  2  2  2  1  1  1  1  1  1  1  1  1  1  1  1 | 0 (Note: これは結合文字なので xterm/konsole/vte 等で 0 で上書きしている)
      % ws[4]  U+03099 |  2  2  2  2  2  2  2  0  0  0  0  0  0  0  0  0  0 | 0
      % ws[5]  U+09FCD | -1 -1  2  2  2  2  2 -2  2  2  2  2  2  2  2  2  2 | 2
      % ws[6]  U+1F93B | -1 -1 -1 -1 -1 -1 -1 -1 -1  2  2  2  2  2  1  1  1 | 2
      % ws[7]  U+0312E | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  2  2  2  2  2  2  2 | 2
      % ws[8]  U+0312F | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  2  2  2  2  2  2 | 2
      % ws[9]  U+16FE2 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  2  2  2  2  2 | 2
      % ws[10] U+032FF | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  2  2  2  2 | 2
      % ws[11] U+031BB | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  2  2  2 | 1
      % ws[12] U+09FFD | -1 -1  2  2  2  2  2 -2 -2 -2 -2 -2 -2 -2 -2  2  2 | 2
      % ws[13] U+1B132 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  2 | 1
      %
      % うーん。これを見る限りは musl と Unicode 12.1 の違いはない。プログラムで
      % 具体的に Unicode 12.1 との違いを確認する事にする。
      %
      % $ ./canvas.c2w.wcwidth.exe compare_musl2023
      % $ awk '$4 == 0' ../out/data/c2w.wcwidth-compare.musl-vs-12.1.txt
      % 00ad       wcwidth=1 width(eaw=3,gencat=Cf)=0 0
      % 1160..11ff wcwidth=0 width(eaw=1,gencat=Lo)=1 0
      % d7b0..d7c6 wcwidth=0 width(eaw=1,gencat=Lo)=1 0
      % d7cb..d7fb wcwidth=0 width(eaw=1,gencat=Lo)=1 0
      % e007f       wcwidth=1 width(eaw=1,gencat=Cf)=0 0
      % e01ef       wcwidth=1 width(eaw=3,gencat=Mn)=0 0
      %
      % 最初の四行は他の wcwidth 実装と同じ。なので本質的には最後の2行で区別でき
      % る可能性がある。U+E007F はタグをキャンセルするという制御文字。U+E01EF は
      % variation selector である。U+E01EF は端末側で特別に処理していると予想され
      % るので使うとしたら U+E007f である。

      やはりこれを見ると実は musl の最新版は殆ど Unicode と一致している。なので、
      敢えて区別する必要もないのではないかと思われる。やはり古い musl を区別す
      るのを目的として、musl のテーブルは今まで通り古い musl の物にして、但し、
      最近の Unicode を誤って新しい musl と判定しない様に判定の調整を行う。

      と言っても konsole が変な振る舞いをしているだけなので気にしなくて良いかも
      しれない。

    * konsole の wcwidth がどの様に振る舞うのかについてちゃんと調べて判定できれば判定する

      更に調べてみると konsole は konsole_wcwidth という関数を持っているらしい。
      https://api.kde.org/legacy/4.12-api/applications-apidocs/konsole/html/konsole__wcwidth_8h_source.html
      と思ったが現在の konsole には konsole_wcwidth という関数は存在しない。テス
      トコードのコメント内にはあるので、恐らく昔は実際にそういう関数が存在した。
      改めて konsole_wcwidth を検索してみると11年前のコードなどが当たる。kde-4.12
      で検索してみると 2013年12月の記事が出てくる。なので、純粋に古いのだろう。見
      つけた。現在のコードは以下にある。

      https://github.com/KDE/konsole/blob/master/src/characters/CharacterWidth.src.cpp テンプレート
      https://github.com/KDE/konsole/blob/master/src/characters/CharacterWidth.cpp 生成結果

      そして幅のテーブルを生成しているコードは以下にある。

      https://github.com/KDE/konsole/blob/master/tools/uni2characterwidth/uni2characterwidth.cpp

      うーん。konsole の幅スキームまでテーブルを埋め込んで対応するのは大変だ。
      しかも version が変わる度に変更される。

      分かった。どうやら以下のファイルによって U+D7B0 の幅が上書きされている? 然
      し、結果として 2 になっている理由は謎。

      https://github.com/KDE/konsole/blob/master/tools/uni2characterwidth/overrides.txt
      https://github.com/KDE/konsole/commit/cfff2326f98e1077c519bbb8d18c80262d1e2d1b 導入コミット

      うーん。konsole_wcwidth の文字幅を Unicode の文字幅と比べると以下の差分が
      ある。wcwidth の段階では U+D7B0 は幅0の様である。つまり、konsole は
      grapheme clusters に対応していてそれでハングルだと判定して文字幅2にしてい
      るという事だろうか。U+D7B0 は Unicode 6.1 の判定に使われている。代わりに
      別の文字にしたらこういう変な事が起こらないで済むだろうか?

      $ ./canvas.c2w.wcwidth.exe compare_konsole2023
      $ awk '$4==0' ../out/data/c2w.wcwidth-compare.konsole2023-vs-15.0.txt
      00ad       wcwidth=1 width(eaw=3,gencat=Cf)=0 0
      1160..11ff wcwidth=0 width(eaw=1,gencat=Lo)=1 0
      d7b0..d7c6 wcwidth=0 width(eaw=1,gencat=Lo)=1 0
      d7cb..d7fb wcwidth=0 width(eaw=1,gencat=Lo)=1 0
      1f1e6..1f1ff wcwidth=2 width(eaw=1,gencat=So)=1 0

      調べてみると Unicode 6.1 で新しく変更された幅は全てハングル関係である。然
      し、これらは恐らく全て konsole のハングルの実装によって幅2になってしまう
      と予想される。一方でこれらの文字は musl でも全て 2 になっている。つまり、
      どの文字を Unicode 6.1 に選んだとしても musl の判定には使えないという事に
      なる。

    * unicode version も参照して musl を判定する事にする。

      うーん。本当に musl2014 の場合には unicode version 判定の時点で特定の ver
      になるはずなので、それも一緒に確認する事で musl を判定するのが正しい気が
      する。

      musl は判定用文字幅は以下のようになっている。

      $ ./canvas.c2w.wcwidth.exe vector_musl2014
      ws[0]=1 # U+25BD
      ws[1]=1 # U+25B6
      ws[2]=2 # U+9FBC
      ws[3]=2 # U+9FC4
      ws[4]=2 # U+31B8
      ws[5]=2 # U+D7B0
      ws[6]=0 # U+3099
      ws[7]=2 # U+9FCD
      ws[8]=1 # U+1F93B
      ws[9]=1 # U+312E
      ws[10]=1 # U+312F
      ws[11]=1 # U+16FE2
      ws[12]=1 # U+32FF
      ws[13]=1 # U+31BB
      ws[14]=2 # U+9FFD
      ws[15]=1 # U+1B132

      これに基づくと char_width_version=10.0 になる。なので 10.0 の時にだけ
      musl と判定する事にした。

2023-01-31

  * decode: bash-4.4 以下で補完が全く起動されない [#D1928]

    cygwin で completion を起動しようとすると固まる。何故?
    最近の変更が原因かもしれない。確認する必要がある。

    そもそも complete が全く呼び出されていない。色々試してみたがそもそもキー入
    力がちゃんと通っていない気がする。

    auto-complete 候補が出ていても出ていなくても関係ない。

    どうも 138c476 の前後で振る舞いが変わっている。+o posix を追加すると問題が
    再現する。どうもそもそも $_ble_bash_options_adjusted が有効になっていない状
    態で .hook が呼び出されている。然し、それもなぜだか分からない。

    Linux でも bash-4.4 以下で再現する。

    うーん。分かって来た。set +o posix すると complete が bash の complete に変
    わってしまう。ここで readline のコマンドラインは空なのでコマンド名補完が行
    われる。no_empty_cmd_completion off にしているので、そのまま全てのコマンド
    の補完を処理しようとして固まる。

    set +o posix は実際に変化がある時にのみ実行するべきである。

2023-01-30

  * main: 空の LANG に対して警告を表示する (movivated by Ultra980) [#D1927]
    https://github.com/akinomyoga/ble.sh/issues/269

    文字幅計算がずれる。空の LANG なのに starship&terminal が UTF-8 を想定して
    いる。

  * main: openSUSE inputrc.keys は強制的に排除する? (motivated by Ultra980) [#D1926]
    https://github.com/akinomyoga/ble.sh/issues/268

    これが何度も問題を起こしている。

    a 最早強制的に off にしても良いのではないか。

    b 或いは自前で ~/.inputrc だけ読み取る事にする。

      元々 --noinputrc は最早 inputrc とは関係なく bind の出力を plain Bash と
      diff を取ってユーザー設定を復元している。という事を考えたらどの方式でユー
      ザー設定を復元するかをオプションで選べる様にしても良いのではないか。

      --inputrc={none,user,all,diff}

    c 或いは、デフォルトとの bind diff を取った後で比較するのではなくて、仮に
      ble-bind で全部登録した後の状態で diff を取って残った物だけ採用する? と思っ
      たがこれだと問題は解決しない。

    と思ったら既に opensuse では振る舞いを変える様になっていた。今までは
    https://github.com/openSUSE/aaa_base/pull/84 の修正が入っているかどうかで問
    題があるか判定していた気がするが、もう inputrc.keys が存在する時点で問題が
    あると判定する事にする。

    2023-02-02 実際に openSUSE で試してみたらエラーメッセージが色々表示されてし
    まう。改めて確認したところ --inputrc=auto に対する処理で openSUSE での既定
    の方法が誤っていた。修正した。

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]

    展開する条件をより制限する事はできないか。或いは、展開せずに置換できるパター
    ンを増やす。

    最たる場合が echo $_ble_base_cache/mandb[TAB] である。曖昧一致によって遡っ
    て置換が起こるが、それによって変数展開の中身まで展開されてしまう。少なくと
    も / で区切ってできるだけ展開せずに一致する様にできないだろうか。

    ? 曖昧一致に於いて変数展開から得られた文字列は塊で取り扱う?

      というかよく考えたら変数の中身に対してまで曖昧一致で一致させるのは変な気
      がする。曖昧一致は元の原始的な構成要素に対しては塊で一致する様にするべき
      なのではないか。と思ったが 'aaa' の中身の様にユーザーが手で入力した内容に
      ついてはやはり曖昧一致であって欲しい。という事を考えると曖昧一致で塊とす
      るとしてもその対象は変数展開だけに限られてくるのではないか。

    2023-01-24 #D1923 で曖昧一致によって遡って書き換わって展開される場合につい
    て対応した。勝手に変数の中身が展開されるパターンがこれだけなのかは分からな
    いが、取り敢えずは解決した事にする。暫く使って勝手に展開されてしまう他のケー
    スに気づいたらその時に新しく項目を立てて対応する事にする。

  * complete: パス名の曖昧補間でできるだけ各種展開を保持したい [#D1923]

    現在の実装では quote-insert で生成候補が COMPV に文字列を追加した物の場合に
    は COMPV の部分については COMPS で置き換える様になっている。しかし、遡った
    置換がある場合には問答無用で全体が展開されてしまうので、曖昧補間が起こった
    時には必ず全体が展開されてしまう。

    COMPS を unquoted / 毎に切って、eval して対応する部分 compv を生成して、最
    長一致するものについて部分 comps で置き換える。unquote / 毎に切るのは個別の
    quote-insert でやっていたら大変なので、事前に処理しておく事にする。

    quote-insert.batch で awk で処理する場合にどうするのかについては微妙。awk
    の内部で unquote / 毎に切るのを実装するか或いは外で切ったものを何とかして
    awk に渡すかする。外で定義したものを渡す方が見通しが良いと思われる。

    ToDo 2022-02-03 に関連項目がある → #D1924

    unquoted / で区切るのは既存の
    ble/syntax:bash/simple-word/evaluate-path-spec をそのまま使えば良い。

    * reject: あらゆる単語について判定を行うと大変なので CAND が既存のファイル
      名に一致する時にだけチェックをおこなう? 未だ存在しないファイル名を候補と
      して生成する可能性はあるだろうか。例えば Makefile target 等。うー
      ん。-o$HOME/ 等の様に short option の optarg として指定している場合等も考
      えたら例え存在していなかったとしても一致するかのチェックはするべきの気が
      する。

    うーん。fixed part との兼ね合いがどうなるのか分からない。取り敢えず
    evaluate-path-spec は noglob で呼び出す事にしてチルダ展開・パラメータ展開等
    文脈に依存しない物のみを実行する事にする (コマンド置換、算術展開などは元よ
    り simple-word ではないので対象ではない)。

    ? quote-insert.initialize で実行するべきか或いは COMPV を評価する時点で
      evaluate-path-spec で展開しておくべきか → COMPV を評価する時点で同時に評
      価してしまうべきの気がしてきた。

    結局 fixed part を拡張する形で実装する事にした。既存の変数である
    comps_fixed 及び quote_fixed_comp{s,v}{,_len} 等を配列に拡張して第1要素以降
    に部分パスの展開前・展開後を格納する事にする。

    実装した。取り敢えずは動いている気がする。

  * 2023-01-02 complete: コマンド名(パス名)の曖昧補間・部分一致など [#D1922]

    現在の実装だと PATH に見つかっているコマンドについては曖昧補間が有効である
    が、パスを指定して補完している時にはそれが無効になっている。関数名について
    は / が入っていてもちゃんと生成できている。

    補完対象に / が含まれている場合にはファイル名補完と同様にパターンで候補生成
    を行って、その結果を [[ -x file ]] でフィルタする様にするべきなのではないか。

    ? ok: チルダ展開が展開されてしまう。調べてみると compgen -c の場合にはちゃ
      んと ~ が保持される。なので、おそらくチルダ展開の復元などを処理していなかっ
      たのだろう。

      実はディレクトリ名に関しても同様に処理する必要があったのでは。

      →何故展開されるのかについて調べてみたら ~ を復元するのは $CAND ==
      "$COMPV"* の時だけだが、曖昧補完の時にはこれが常に不成立の為に復元しない
      という事。これに真面目に対応しようと思ったら COMPS を unquoted / 毎に切っ
      て、eval して対応する部分 compv を生成して、最長一致するものについて部分
      comps で置き換えるという処理にする必要がある。これは面倒である。

      そして、これについては通常引数の曖昧補間についても同様にチルダ展開が展開
      されてしまう。もし対応するとしたらまとめて対応する必要がある。これは独立
      した項目にする事にした。

2022-12-13

  * fzf-completion: ファイル名に付く suffix の判定ができていない (reported by qoreQyaS) [#D1921]
    https://github.com/akinomyoga/ble.sh/issues/264

    結局問題は ble/syntax-raw で fzf にファイル名を渡しているので結果として生成
    される物が、必ずしもそのままでファイル名になっているとは限らないのが原因だっ
    た。

    [原因解明]

    bash-completion & fzf & ble.sh の組み合わせで再現する事を確認した。色々調べ
    た所、単に以下の補完設定でも ble.sh だと問題が再現する。

      function _test2a {
        compopt -o filenames
        COMPREPLY=("~/opt")
      }
      complete -F _test2a test2a

    ble.sh の中の動作を調べると ble/complete/action:file/complete 迄期待通りに
    呼び出されているが、そこで分かった。~/が定義されていないのである。

    ? ok: fzf の補完で ~ が直接渡って suffix が付かなくなるのは良いとしても、不
      思議なのは普通の補完で同様の修正が働かない理由である。そもそも ~/opt は
      /home/murase/o に変換してから補完が走る設計にしていた様な気がする。何故 ~
      が直接補完関数に渡っているのだろうか??

      と思ったがよく考えたらテストの問題である。問題再現の為に直接
      COMPREPLY=('~/opt') の様にしていただけで、実際に COMP_LINE や COMP_WORDS
      に '~' が含まれていた訳では無い。

    [修正]

    取り敢えず ble/syntax-raw の時にはその場でパス名展開を試行してファイル名か
    どうかの判定を実行する事にする。


    ? 存在しないファイル名がある時に nullglob で消えてしまうのでは。これだと一
      番最後の単語でない物を拾ってテストしてしまう可能性がある。

      こういった設定を変更しないでできるパス名展開は存在しただろうか。と思った
      が util の eval-pathname-expansion は元からその様な物だった。

    * reject: comp_opts の値を記録する事を考える。或いは、DATA は progcomp の時
      には常に comp_opts だと仮定して良いのだろうか。と思ったが、駄目。progcomp
      のものに関しては問題が起こらないが、それ以外で生成された物について DATA
      は別のものを含んでいるので、直接 DATA を読み取っていると誤作動の原因にな
      る。

      或いはそれが progcomp によって生成された物であるかどうかを判定する方法は
      あるのか。確認した所、action=progcomp らしい。action=mandb もあるような気
      がしたがそれは source:mandb から生成された物だけの様である。更に、
      action=mandb で出てきた物はファイル名ではないのは明らかなので、やはり除外
      しても良い。

      progcomp から出てくる物は action=progcomp であると仮定して良い。

    実装した。動いている。auto-complete の場合でもちゃんと / が挿入される。

    x fixed: と思ったが menu-complete の着色の為にファイル名を判定している所で
      結局同様にファイル名の判定に失敗して全てが赤くなっている。これにも対応す
      る必要がある気がする。

      これについても修正を行った。ファイル名取得の処理を共通化して、そしたら簡
      単だった。

    ? 生成される物が eval した後にファイル名になるという事を仮定しているが本当
      にそう思って良いのだろうか。元の bash の振る舞いでは空白が入っていたとし
      ても -o filename を指定したら quote してくれるみたいな事になっていたりは
      しないのか?

    x bash の振る舞いについて確認する事にする。更にそもそも不用意に eval して良
      いのかという問題がある。コマンド置換など含まれていたらどうするのか。
      syntax/simple-word で判定してから eval するべきなのではないか。

      チルダ展開だけを実行するためにはどうしたら良いか。ble/widget/tilde-expand
      を確認してみた所、これは command line に含まれる物に対する作用だったので、
      単に syntax 情報を参照していた。

      コマンド置換が含まれていたらチルダ展開は諦めると思ったがコマンド置換が含
      まれていたとしても、結局は quote されるので inactive である。取り敢えずチ
      ルダ展開だけ試みるというのが正しい動作の気がする。という事を考えると、最
      初がチルダであって次の / までに何か特別な文字が含まれていない時に限ってチ
      ルダ展開を試みるという処置が必要である。

      先ず最初に作った以下のコードは全て棄却である。

      | local -a dtor=()
      | if shopt -q nullglob; then
      |   shopt -u nullglob
      |   ble/array#push dtor 'shopt -s nullglob'
      | fi
      | if shopt -q failglob; then
      |   shopt -u failglob
      |   ble/array#push dtor 'shopt -s failglob'
      | fi
      |
      | # Note: 一番最後の文字の直後の文脈を知りたいので、末尾に '' を追加して評価
      | # してから最後の単語を抜き出す。
      | if ble/util/eval-pathname-expansion "$file''" && ((${#ret[@]})); then
      |   file=${ret[${#ret[@]}-1]}
      | else
      |   file=
      | fi
      |
      | ble/util/invoke-hook dtor

      実装し直した。動作確認する。動いている。auto-complete もOK。menu-complete
      もOK。その他の微妙なファイル名でも bash と同様に動作する事を確認した。

  * bind: M-C-@ が正しく捕まえられていない気がする [#D1920]

    bind -s で確認するとマクロ置換後の C-@ が消滅している。これは単にマクロが内
    部的に null-terminated string で表現されている為である。

    更に同様の状況を考えてみると C-x C-@ も正しく検出できていない。また M-C-x
    (in bash-4.2, emacs binding) もその瞬間に検出できていなくて遅延が生じる。実
    際にその場で入力を検出できていないという事を確認した。

    取り敢えず M-C-@, C-x C-@, M-C-x (bash-4.2 -o emacs) を修正した。

    ? reject: これは bash の側で修正するべきなのだろうか? 然し、bash は null
      terminated な raw string でマクロを補完していて、これを変更するのは難しい
      し其処までする理由もない様な気がする。取り敢えずは現在の workaround を保
      持して、bash には何も要求しない方向が妥当の気がする。

  * highlight: パス名着色において ls_colors が動いていなかった (reported by qoreQyaS) [#D1919]
    https://github.com/akinomyoga/ble.sh/issues/263

    どうも type=g:* の形で指定した後にそれを外側で g に反映させる事になっている
    のが反映させていなかったのが問題であった。いつ壊れたのか確認した。3f1f472d
    #D1095 で type == g:* の時の特別の処理が削除されている。実に3年半も動かない
    状態で放置されていた事になる。

    ディレクトリ名に関しては単純に今まで対応していなかった。

    ble/syntax/highlight/ls_colors の値の返し方自体を変更する事にした。この関数
    は今迄二箇所でしか呼び出していなくて、両方で呼び出し側で同様に色の合成など
    を行っていたので、その色の合成も ble/syntax/highlight/ls_colors に統合する
    事にした。そして直接に g に書き込む様に振る舞いを変更した。その上で / の前
    のディレクトリ名の ls_colors による着色にも対応した。動いている。

2022-12-11

  * colorglass: オプションで指定した時に256色(またはより少ない色に)に減色する機能? [#D1918]

    →よく考えたら bleopt term_true_colors が設定されていなければ自動的に減色さ
    れるのではないか。実際に実装を確認してみた所そうなっている。この事を
    colorglass の説明に書いておくべきではないか? → 記述した。これで十分である。

  * README: RET や C-RET 等について 3.1.1 及び 3.3.6 に対するリンクを含めておく [#D1917]
    https://github.com/akinomyoga/ble.sh/issues/262

    取り敢えずリンクと説明を書いた。

  * _ble_term_TERM (comment): wezterm の commit id は 8 文字では足りない (requested by SuperSandro2000) [#D1916]
    https://github.com/akinomyoga/ble.sh/commit/486564ad314cef3f95317e88cf26879378dae507

    うーん。行(特に120列)に収まり切らない様な気がするが面倒なので気にしない事にする。

  * github/workflows: 何故か grep が windows-latest でクラッシュする [#D1915]

    別のリポジトリで試しに実行してみたがやはり再現する。最終的に以下の単純な
    workflow の定義ですらクラッシュするという事が分かった。

    ---- .github/workflows/build.yml ------
    name: grep-in-windows
    on:
      push:
        branches:
          - master

    jobs:
      check:
        runs-on: windows-latest
        steps:
          - name: Check out
            uses: actions/checkout@v3
          - name: Check
            run: echo 'GNU Awk' | grep -Fi 'GNU Awk'
    ---------------------------------------

    grep -i や grep -F だけでは問題は発生しない。 grep -Fi や grep -F -i 等、-F
    と -i を組み合わせた時にクラッシュする様だ。grep の version は GNU grep 3.0
    (2017) の様である。よく分からないが面倒なので grep を使わずに実装する事にす
    る。head -1 による処理も一緒に sed で処理すれば良い。

2022-12-08

  * ble-reload した時に M-z が効かなくなる [#D1914]

    何とそもそも ble-reload にて blerc が読み込まれていない。確認してみると
    --rcfile=/dev/null という事になっている。何も指定していない時には
    _ble_base_arguments_rcfile は空になっている。なので空の時にはやはり何も指定
    せずに source ble.sh するべきであって、何か特定の blerc は指定しない様にす
    る。

    ? 或いはもしかすると元々指定したかったのは _ble_base_rcfile ではないか?
      うーん。そんな気がする→その様に修正した。

  * 2021-09-08 complete: sabbrev (magic-space) vs auto-complete [#D1913]

    auto-complete で履歴から候補が表示されている時には sabbrev が効かない。そも
    そも sabbrev 展開が発生するかどうかも分からないので毎回 auto-complete を抜
    けるというのも変な感じがする。理想的には sabbrev が起こった場合は再び
    auto-complete を実行し、sabbrev が起こらなかった時には従来の auto-complete
    と同様にカーソル位置を一つ進める事を試行する。

    うーん。この問題は自動候補の先頭文字が空白の時にのみ起こる。それ以外の時に
    は auto-complete を抜けて再度 SP が実行されるのでちゃんと sabbrev も呼び出
    される。

    2022-12-09 然しそもそも一つ上の keymap で SP に magic-space が割り当てられ
    ているのかどうかも非自明である。うーん。やはり SP に対しては一旦
    auto-complete を抜けるのが自然な気がする。

    或いは一つ上の keymap の SP に magic-space が割り当てられているかどうか判定
    する? うーん。ESC に関してはひとつ上の keymap の情報を参照している物があっ
    た様な気もするが何だったか。うーん。ESC や M- で検索しても関係ありそうな物
    は見つからない。→分かった。bleopt decode_isolated_esc=auto の処理である。
    decode.sh の ble/decode/uses-isolated-esc で判定が行われている。

    さて実際に magic-space に bind されているという事が分かったとして、どの様に
    処理するべきか。その場でいきなり magic-space を呼び出す事を考えたが、そうす
    ると auto-complete によって補正されている内容が壊れてしまう。特に
    _ble_edit_mark 等の位置も変わってしまう可能性がある。また、magic-space は現
    在の keymap を見て振る舞いを変えているので一旦 auto-complete から抜けるか抜
    けたふりをする必要がある。色々考えるとやはり本当に一旦抜けて通常の状態に戻っ
    てから処理するべきの気がする。

    →その様に修正した。

    x 今度は magic-space による空白挿入の後に auto-complete が再開しない。よく
      考えたら self-insert は登録しているけれども magic-space に関しては登録し
      ていない。登録するべき気がする。登録した。試した。ちゃんと期待どおりに動
      いている。

  * 2021-02-28 magic-space で alias 展開する機能があっても良いのでは? (requested by telometto) [#D1912]

    というか magic-space で何を展開するかの集合を設定できる様にするべき?
    bleopt edit_magic_expand=sabbrev:history:alias という具合に。
    流石にコマンド置換等まで展開するのはやりすぎの様に思われる。

    2022-12-08 https://github.com/akinomyoga/ble.sh/discussions/260

    まず最初に bleopt を実装する事にする。実装した。

    alias expansion についても sabbrev expansion を元にして実装した。

    ? ok: ところで他の discussion でも同様の物があった様な気がする。

      https://github.com/akinomyoga/ble.sh/discussions/138

      ここにある。と思ったが、これは alias expansion ではなくて、magic-space を
      コマンド実行時にも呼び出すという話なのだった。というかこの項目が todo に
      なかったので新しく項目を作って置く事にした。と思ったら項目自体はあって単
      に GitHub#138 へのリンクが記録されていなかっただけだった。

    x auto-complete が有効になっていると ' ' が magic-space として働かない。
      →これは別に項目が存在していた筈なので別に処理する事にする。

    * done: blerc/wiki: bleopt edit_magic_expand の説明。

  * 2022-12-03 menu-complete: 一時挿入をしない設定 (requested by DUOLabs333) [#D1911]
    https://github.com/akinomyoga/ble.sh/discussions/252#discussioncomment-4293518

    * done: complete_auto_after_complete はやはり廃止してより一般のオプションと
      して complete_auto_complete_opts=suppress-after-complete とする事にした。

    * done: blerc/wiki: update complete_auto_complete_opts

    * done: blerc/wiki: add complete_menu_complete_opts

    * done: temp-insert -> insert-selection

    取り敢えず動いている気がする。多分大丈夫。

  * 2022-10-04 refactor(edit): 適当な一時ファイルを作っているのを assign/.mktmp に置き換える [#D1910]

    暫く dev にあって邪魔なので些末な修正に過ぎないがもう master に入れる事にす
    る。他には特にその場で生成してその場で使用済みになるファイルは存在していな
    い様な気がするのでOK。

  * term: wezterm が DA2 を変えている。対応する [#D1909]

    DA2R が 1;277;0 になっている。xterm との区別ができない気がする。うーん。或
    いは 277 だったら wezterm に決め打ちにする? しかし、wezterm である事を利用
    しているのは、現状ではどうやら DECSCUSR に対応しているかどうかの判定のみで
    ある。然し、xterm も元々 DECSCUSR に対応しているので、その意味でわざわざ
    1;277;0 (xterm:277) を wezterm と敢えて判定する必要もない。

    念の為、現状での wezterm の DA2 の変更履歴について確認する。

    コミット [1] (2022-04-07) で今迄の "0;0;0" から "1;277;0" に変更している。
    wezterm のバージョンはどうやら日付と時刻の様である。取り敢えず
    _ble_term_TERM では日付だけ考える事にする。このコミットは 20220408 のバージョ
    ンで最初に入っている。どうやら vim でマウスを使う為の変更の様である。

    [1] https://github.com/wez/wezterm/commit/ad91e3776808507cbef9e6d758b89d7ca92a4c7e

  * contrib/fzf-key-bindings: C-r で呼び出した fzf で modifyOtherKeys の状態が変 (reported by SuperSandro2000) [#D1908]
    https://github.com/akinomyoga/ble.sh/issues/259

    xterm ですらちゃんと動いていない。以前はちゃんと動いていた筈なので
    regression の可能性が高い。うーん。ちゃんと hook はできている。つまり、
    modifyOtherKeys のシーケンス自体を正しく出力できていない可能性? 内部でどの
    ように設定しているかを出力しつつ振る舞いを調べる必要がある。

    * うーん。今振る舞いを確認してみた所、xterm でも CSI >4;1m を指定した後で
      C-x であっても特殊なシーケンスを送るという事が判明した。うーん。もしかし
      て xterm は昔から 4;1 で C-x に対して特殊なシーケンスを送っていたという事
      なのだろうか? xterm -v の結果は 371 である。改めて他の xterm についても調
      べてみる事にする。

    * xterm 322 では 4;1 の時 C-p は通常のシーケンスを送信していた。

    * と思ったら直接 xterm 371 を起動して \e[>4;1m を指定しても特に変な事は起こ
      らない。うーん。別の箇所で何か modifyOtherKeys が変更されている可能性?

      うーんわかった。ble/util/buffer にキャッシュされていて端末に対して出力さ
      れていない状態だった。修正した。

2022-12-05

  * README: fzf-integration について記述する (motivated by SuperSandro2000, tbagrel1) [#D1907]
    https://github.com/akinomyoga/ble.sh/issues/259
    https://github.com/akinomyoga/ble.sh/issues/261#issuecomment-1346450426

    * display-shell-version にも integration が入っていない時にメッセージを表示
      する様にする。fzf についてはメッセージを出力した。

    その他 (bash-preexec, zoxide) については必要になった時点で自動的にロードさ
    れる事になっているので、その場で未だロードされていなくてもそのままにしてお
    く事にする。と思ったが zoxide がない。

    * done: zoxide についても情報を表示する事にする。

      zoxide の初期化スクリプトで一番古い関数は何だろうか。

      __zoxide_hook は以下のコミット (2020-09-16) で _zoxide_hook から改名され
      ている。この関数は最新版の zoxide でも存在している。

      https://github.com/ajeetdsouza/zoxide/commit/f4525db02fde1efa77f56f9f50b27cc1830d4912

      _zoxide_hook は以下のコミット (2020-03-13) で導入されている。

      https://github.com/ajeetdsouza/zoxide/commit/9c8e8da71a03f5c3c070247f5b0bffd971a70f62

      _zoxide_precmd は以下のコミット (2020-03-11) で追加されている。これが
      bash 対応の最初と思われる。

      https://github.com/ajeetdsouza/zoxide/commit/f0c5e28fd7e56d7cec045a40154ab4768339da44

      取り敢えず __zoxide_hook を使って判定する事にする。

    * done: 動作を確認してみた所 _z という関数が存在しない。つまり、zoxide の側
      で変更があったという事だろうか。以下のコミット (2021-12-29 v0.8.1..) によ
      ると _z から __zoxide_z_complete に改名された様である。

      https://github.com/ajeetdsouza/zoxide/commit/d106f4e3580d5594d8f1c96c256a8f085e2781a4

    2022-12-13 更に bash_completion を先にロードしておくべきという事についても
    記述した。

  * colorglass: saturation (彩度) についての設定を追加する (motivated by auwsom) [#D1906]
    https://github.com/akinomyoga/ble.sh/issues/258

    24-bit color のサポートがない時には256色に減色する機能もつけようと思ったが
    自動で検出するのは困難である。既定で256色にして指定した時にだけ256色にする
    というのだと、既定では色が思うように変化しなかったり急に変わったりして使い
    にくくなる。指定した時にだけ256色に減色するというのもありかもしれないが、其
    処までする必要は今の所は感じられない。→取り敢えず項目は作る事にした。

    * fixed: contrast -100..100 の境界値も許容する様に修正した。

    * fixed: 色がすぐに PS1 に反映されない問題を修正した。trace_hash に
      clear-g2sgr cache の回数を含める事にする。

    * reject: ble-face で face 設定を変更した時にも clear-g2sgr を呼び出す事に
      する? それ程頻繁に変更する事もないので大丈夫だろう

      x と思ったが face -> g に関しては毎回完全に計算していてキャッシュしていな
        いので g2sgr キャッシュをクリアする必要もない。特に g2sgr は重くなる可
        能性があるので余り頻繁にクリアはしたくない。実際に vim-airline が編集す
        る度に face を変更しているのでこれでキャッシュをクリアするのは割に合わ
        ない。

      * それよりはプロンプトの計算が face に依存しているのにプロンプトのキャッ
        シュがクリアされないという所が face 更新における問題である。vim-airline
        の時には背景色を変更していたが背景色は _ble_lib_vim_airline_mode という
        変数で決まっており、更にこの変数は prompt/unit の枠組み経由で更新してい
        た。なので何れにしてもプロンプトが更新されるので気にしなくても良かった。

    * done: brightness についても対応した。

2022-12-03

  * README: bashrc 設定の背景に対するリンクを載せる (motivated by telometto) [#D1905]
    https://github.com/akinomyoga/ble.sh/discussions/254#discussioncomment-4284757

    日本語の説明はないが仕方がない。

  * contrib/README: PATH に fzf が見つかれば _ble_contrib_fzf_base は設定しなくて良い (reported by Strykar) [#D1904]
    https://github.com/akinomyoga/blesh-contrib/issues/9

    修正した。というか手動で指定したとしても fzf を PATH の中に見つける事ができ
    なければ結局動かないのではないか? と思ったが fzf-initialize の中にちゃんと
    PATH を追加する処理が組み込まれていた。

    と思ったが、存在しないディレクトリを追加していたりしないか? →している。こ
    れはディレクトリが存在する時にだけ PATH に追加する事にした。

  * prompt: bind 'set show-mode-in-prompt on' が何故か PS1 の後に表示される? (reported by Strykar) [#D1903]
    https://github.com/akinomyoga/ble.sh/discussions/256
    https://github.com/akinomyoga/ble.sh/discussions/257

    実際に試してみるとそうなっている。変なミスである。。。修正した。

2022-12-01

  * contrib/colorglass: 実験的に実装したものを追加する事にした [#D1902]
    少なくともこれでテーマを自分で作るのが以前よりは簡単になった気がする。
    但し調整の仕方は普通のユーザーに対しては少々難しいかもしれない。
    同時に自分でフィルターを設定できる様にもする。

  * complete: TAB completion の直後でも auto-complete が表示されるのは変だ (reported by DUOLabs333) [#D1901]
    https://github.com/akinomyoga/ble.sh/discussions/252

    * done: うーん。確かに言われてみれば変な気がする。これは単にバグの気がする。
      調べてみる。

      ble/complete/auto-complete.idle では _ble_decode_widget_last が
      self-insert 等の時にだけ auto-complete が実行される事になっているが、よく
      見ると ble/widget/complete または ble/widget/vi_imap/complete の時にも明
      示的に auto-complete を誘起する様になっている。これには理由があったのだっ
      たか。

      関係しているのは 63ddeffd #D0736 と 6081e0a9 "complete: support "bleopt
      complete_ac_delay"" (議論なし?) である。うーん。周辺の議論を確認したが、
      やはり関係する議論はないし、done.txt で delay についても mention されてい
      ない。次の項目番号が #D0727 で auto-complete が導入されたのが #D0724 なの
      で、#D0725 か #D0726 以前のどちらかが関係していそうだが、どちらも異なる。

    うーん。やはり当初から意図した振る舞いの様な気がしてきた。少なくとも使って
    いて問題が起こった事はない。menu-complete に入れば当然モード判定があるので
    勝手に auto-complete が混ざって変な事になるという事もない。うーん。オプショ
    ンを追加する事にする。実装した。

    * done: blerc.template
    * done: wiki

    ? reject: 既定値を変更するべきか。うーん。少し使ってみる事にする。うーん。
      考えて見るにこれを有効にしていたのは単語補完ではなく過去の履歴に自動補完
      で一致する可能性を残しておきたかったからだと思われる。一律で無効にしてし
      まうと履歴に依るコマンド挿入ができなくなってしまい不便なことがあるかもし
      れない。元々明示的に有効にしていたのは他にもそれなりの理由があったのでは
      ないかという気がする。というか delay の導入と一緒に導入されていたのだから、
      待っていたらコマンド履歴による補完が起動しそうだという期待があったからか
      もしれない。更に続く #D0736 では vi でも同様に動く様にわざわざ変更してい
      る。そもそも表示していても別に問題はない気がするのでやはり既定では補完を
      実行する事にする。

  * complete: `#advice: _parse_usage is not a function.` というエラーメッセージ (reported by nik312123) [#D1900]
    https://github.com/akinomyoga/ble.sh/issues/251

    bash_completion の新しい version を使っていると発生するのかもしれない。と思っ
    たがそうでもなかった。まだこれらの関数は bash_completion の内部で改名されて
    いない。つまり、_parse_help や _longopt を勝手に定義しているが _parse_usage
    を定義していない外部の補完ライブラリが存在する。

    ? no: もしくは、古い bash_completion には _parse_usage は存在していなかった?
      と思って調べてみたが _parse_usage も _parse_help も bash_completion
      68f6f1c68 で同時に導入されているので片方だけが定義されていたという時期は
      存在しない様に思われる。

    何れにしても _parse_help という関数を勝手に定義する場合を考えると、勝手に他
    の関数も定義されていると想定する訳には行かない。単にエラーを suppress する
    事にした。

  * 2022-10-24 rename to blerc.template [#D1899]
    https://github.com/akinomyoga/ble.sh/issues/244#issuecomment-1288439503

    書きぶりから blerc を直接編集すれば良いと勘違いしているのかもしれないと思っ
    たが別にそういう事ではなかった。しかし、それでも勘違いする人がいるかもしれ
    ないので blerc のファイル名を変える事にした。blerc.template という名前にし
    ておけば直接編集すれば良いと勘違いする人もいないだろう。

    README の該当する部分も更新する。wiki には言及されていない様なので更新しな
    くて良い。

    * 何処かでリンクされていたのに対して通知した方が良いかもしれない。

  * 2022-10-24 複数 widget を実行したい時: Q&A や wiki にも説明を書く (motivated by micimize) [#D1898]
    https://github.com/akinomyoga/ble.sh/discussions/241#discussioncomment-3937949

    * done: wiki の Q&A を編集した。

    README では直接説明をしているが、特に他の部分には記述しない事にした。

    というより [編集関数の作成] が wiki における主要な解説部分だが英語版がない。
    然し翻訳するのも面倒だし今回の質問のレベルだとこれ全体を翻訳する程のことで
    はない。将来的にそういった細かい仕様についての質問が出てきた時に翻訳すれば
    良い気がしている。

  * 2022-10-24 cancel line by C-c in vi mode (motivated by micimize) [#D1897]
    https://github.com/akinomyoga/ble.sh/discussions/241

    * done: C-c in blerc
    * done: gg & G in blerc

  * 2022-10-24 delete word by M-backspace (motivated by KiaraGrouwstra) [#D1896]
    https://github.com/akinomyoga/ble.sh/issues/243

    * done: blerc に追記した for emacs

    * done: vi_imap rlfunc の更新

      後 vi_imap の backward-kill-word が widget:kill-backward-uword になってい
      たが実際に plain bash で動作を確認する限りはやはり emacs と同じ様に
      widget:kill-backward-cword になっている気がする。実際に試してみても uword
      は振る舞いが異なる。vi_imap での対応を変更する事にした。

    * done: blerc 追記 for vi

2022-11-28

  * posix: sh --login at MinGW で沢山エラーメッセージが出て segfault (reported by rashil2000) [#D1895]
    https://github.com/akinomyoga/ble.sh/issues/237

    % どうも set +p posix してもその効果が次の実行時に消滅するのが原因の様だ。
    % Linux などで sh --login をしても再現しない。Cygwin では再現した。Cygwin
    % と MinGW だけで今のところ再現している。

    取り敢えず set +ev している箇所で +o posix も指定したら問題は発生しなくなる
    様である。と思ったが MinGW では問題は起こらなくなるものの Cygwin では依然と
    して駄目だった。manual attach でも prompt attach でも Cygwin では動かない。

    →何と sh --login で起動した場合は起動時には non posix だがその後で posix
    に変化する様だ。

    * 一方で Linux で問題が発生していなかったのは単に bashrc が読み込まれていな
      かった為である。

      また、PROMPT_COMMAND の中から set +o posix した時には問題が生じていない様
      にも見える。然し実際に prompt attach を実行してみると問題が生じる。追加で
      PROMPT_COMMAND で set +o posix を設定すると問題は生じなくなる。
      PROMPT_COMMAND における set +o posix の位置を attach よりも後に変更してみ
      ると問題が発生する。

      うーん。何らかの瞬間に adjust bash options の制御が変になっている可能性?
      そもそも adjust-POSIXLY_CORRECT の呼び出しにまで至っていない気がする。こ
      れはユーザーコマンドを実行する瞬間に呼び出される。

      1 うーん。元々 ble-attach でもちゃんと adjust は呼び出しているが、そもそ
        も既に adjusted の状態になっている為にわざわざ adjust を実行していない
        という事の様だ。

        そして source ble.sh の時点で調整に入っているのでその後での変更に対して
        ちゃんと確認しなくても良いという判断である。というかこれだとユーザーが
        自分で set -o posix を設定した時にも問題になる。代わりに他の
        bash-options と同じタイミングで restore/adjust するべきなのではないか。

        →と思って確認してみた所ちゃんと restore している気がする。と思ったがど
        うやら条件判定に失敗して restore がちゃんとされていなかった様だ。これを
        直したらちゃんと動く様になった。

      % 2 また、何故かこの時点で既に posix モードではなくなっている。或いは関数
      %   の中でだけ posix モードが自動で消えるなどの仕組みがあるのだろうか。と
      %   思ったら単に確認用のスクリプトが間違っていた。

    * ble-attach を明示的に呼び出した時にも現在の対策だけで動くのだろうか。或い
      は +ev と同様に改めて設定する必要があるだろうか。

      % うーん。そもそも +ev と同じ箇所で再調整をしたとしても失敗している。
      % segfault する。.hook とは別の場所で調整する必要がある? 取り敢えず
      % ble-attach は無事に完了している事は確認した。問題は何処で一番最初に
      % ble.sh の処理に突入するかという事である。自然に考えると .hook の筈であ
      % る。

      →と思ったら単に +ev している箇所が二箇所あったというだけであった。修正し
      たら segfault も直った。つまり、何れにしてもこの処理は必要になるという事
      である。

    * もしこれが問題なのだとすると以前の修正で +ev としていたのは不要だったので
      はないか? と思ったが +ev の設定に関しては source ble.sh してから変わると
      も思えないし、関係ない? 或いは+ev が必要になったのはユーザーが自分で -ev
      を指定した時?

      51113237 #D1832 の説明を読むと、これは寧ろ ble-attach を明示的に指定した
      時の問題であって、今回の restore し忘れの問題は関係ない。何れにしても
      restore はしないのだ。bash -e で起動すると bashrc の読み込み後に設定が変
      わるという事の様に見える。なのでやはり必要な気がする。

      何れにしても上の項目で +o posix は実行する必要があると判明したので +ev も
      保持するのは確定である。

  * 2022-10-13 ble/canvas/trace: rps1 の位置の問題 (reported by rashil2000) [#D1894]
    https://github.com/akinomyoga/ble.sh/issues/239

    * どうも gbox の計算にバグがある。\nworld を指定すると高さ1になっている。
      foo\nworld はちゃんと2になっている。というかそもそも終点 x,yの時点でバグ
      がある。

      PS1 でも同じ様な事が起こるのではないかと思ったがそういう訳でもない。
      relative にすると駄目という事なのか。或いは measure-gbox の時にのみ起こる
      事なのか。或いは right alignment によって変な事が起こっているのか。align
      right が怪しい。

      ? invalid: 何と rps1 の中でデバグの為に状態を /dev/tty に出力しようとする
        とクラッシュする。history に何かを追加しようとしているが謎 → と思った
        が typo で failglob を発生させていた。つまり変な所で ble.sh の動作がク
        ラッシュしていたのが原因の気がする。

      \n\nbar に対して振る舞いを見てみるとどうも行番号 y がリセットされている様
      である。このリセットは最初の \n に対してのみ発生する様である。\n の呼び出
      し回数に関しては問題ない。

      どうも2回目の end-line の呼び出しの際に y が 1 から 0 に戻ってしまう様だ。

      見つけた。どうも最初の行の情報を消去せずに early return している所為で2行
      目が1行目と勘違いして処理されている様であった。ちゃんと最初の行の情報をク
      リアする様にしたら問題なく動く様になった。というかこれで完全に動く様になっ
      たのではないか。

      取り敢えずこの問題に対する対処は此処までとする。

    * done: テストを追加する。追加した。以前は失敗して今回は成功する事を確認し
      た。

    * done: 然し starship での問題が完全に解決したかどうかは分からない。そもそ
      も被っている場合には rps1 は表示されないのでは? 実際の環境で確認する必要
      がある。

      % →結局どの環境で以前試したのか分からない。と思ったら chatoyancy の
      % ble.sh の中に issue239 という名前のディレクトリがあってそこでテストを実
      % 行していた。

      新しく chatoyancy 上で再現させて動作確認もした。取り敢えずちゃんと設定す
      れば動く。

  * 2022-10-28 edit: display-shell-version を直接実行できる様にする (reported by DhruvaG2000) [#D1893]
    https://github.com/akinomyoga/ble.sh/issues/246#issuecomment-1294843777

    直接 ble/widget/display-shell-version を実行すれば良い。C-x C-v が
    効かない端末でもOK。例えば報告者の環境では C-v が「貼り付け」に奪
    われていた。

    * done: 直接実行しても表示が壊れない様に ble/widget/print を修正した。
    * done: issue template を修正した。
    * reject: wiki に関しては確認してみたがそもそも C-x C-v の指示も書
      いていなかった。敢えてここで新しく解説を追加する必要もない気がす
      る。

  * 2022-10-28 edit: display-shell-version で git/gmake/gawk の情報を表示 [#D1892]
    https://github.com/akinomyoga/ble.sh/issues/246#issuecomment-1294893636

    git, gmake 及び gawk の version も表示する? 変な生成のされ方をして
    いないか確認する時にこの情報があった方が良い。

    これは生成に用いた物の version なので生成時に埋め込むべきの気がする。

  * 2022-10-13 github/workflows について (reported by Harduex) [#D1891]
    https://github.com/akinomyoga/ble.sh/pull/240

    ? cpio -pd を使えば良いのではないか。と思ったが cpio がどのシステム
      でも使えるとは限らないし、そもそも cpio のオプションとして何が使え
      るかもシステムに依存するのかもしれない。という事でやはり cpio に依
      存するというのは避けたい。結局 POSIX cpio には -p はないみたいなの
      で (むしろ異なる意味のオプションの様である) GNU cpio の non-POSIX
      option を使うのだったら、そもそも GNU tar の -x を使うところなので
      ある。

      →改めて ble.pp を見てみたら cp -Rf を使っている。これに倣う事にした。

    * それとは別に現在 ble-nightly* としているディレクトリ名を何とかした
      い。

      a done: うーん。そもそも ble-nightly でダウンロードする人は細かい
        version 等を気にするとは思えないし、そうでなくとも標準的な手順に
        従うと結局ディレクトリの version 名は移動した時に失われてしまう。
        なので、初めから単に ble-nightly というディレクトリにしてしまえ
        ば良い気がする。→ 変える事にした。

      b ユーザーに直接ディレクトリ名を指定させる? しかしそうするとしても
        ディレクトリ名は毎回変わるし commit id が含まれているので README
        に載せられない。なのでユーザーにその都度 ls などで確認してもらう
        必要があって、その為には結局 ble-nightly* などとしてもらう事にな
        る気がする。

    後は README, wiki 等を更新する。というか wiki に nightly version の
    記述はあっただろうか。なかった気がする。追加する必要はあるだろうか。
    追加しなくて良い気がする。

    % 2022-11-28 ble-nightly.tar.xz 展開後のディレクトリ名について毎回
    % 全てを入力するのは大変である。なので、ble-nightly に生成する事に
    % する。ディレクトリ名に version が記録されない事になるが、そもそ
    % も ble-nightly をダウンロードしている時点で細かい version は気に
    % していないのだし、直後に削除する事を想定しているのだから気にして
    % も仕方がない。何れにしても ble.sh 本体の内部には記録される。
    %
    % →これは実質的に 2022-10-13 の議論と同じである。

    2022-11-28 所で、これに関しては master に直接変更を push するので
    はなく、向こうの branch に push して確認するしかないのでは。と思っ
    たが、別に独立に変更をしてから向こうの branch を調整しても良い気が
    する。どちらでも良い。取り敢えず dev の上で作業して後で移し替えて
    すぐに merge してしまえば良い。

    と思ったが既にその様に変更を実施済みである。うーん。後は README を
    更新すると書かれている。

    * done: README を更新した。PR は何故か curl 版だけしか更新していな
      い。関連する物は全て更新するべきである。また日本語の README も更
      新した。

    * done: ble.pp でも ble-nightly で検索を実施している。これについて
      も修正を行う。

      というか今までのこのコードは set -f に対して対策はしていたのだっ
      たか? failglob と nullglob しか設定していない気がする。<del>何れ
      にしても最早パス名展開は使わなくなったので気にしなくて良い。
      </del> と思ったがよく見たら昔に展開した結果の始末や cp -Rf 本体
      でもパス名展開を使っているのでやはり set +f, -u failglob, -s
      nullglob はつけておく必要がある。後、cp -Rf で変な事が起こらない
      様に -u nullglob に変更する事にする。

2022-11-12

  * test: テストで用いている rm が alias によって rm -i になって失敗する [#D1890]

    これはテストの方を修正する事にした。他に類似の箇所はなかった。これは単独修
    正で良い。但し #D1889 のcontrib の更新も含める。

  * fzf-completion 経由で補完した path の特別文字が正しく quote されない (reported by MK-Alias) [#D1889]
    https://github.com/akinomyoga/ble.sh/issues/250

    fzf-completion.bash の中で noquote をしているのが原因の様である。noquote を
    つけた経緯について調べる。syntax-raw を付加したのは fb145dea (contrib) であ
    る。そして noquote をつけた箇所を確認しようとしたがどうも contrib の
    initial commit から noquote がついていた様である。つまり、色々の報告があっ
    た間も全然修正されなかった振る舞いという事である。なので余り深く考えられて
    いる訳でもない気がする。

    contrib を導入したのは f2901158 #D1335 (2020-04-16) の様である。contrib の
    最初の commit では補完関数の advice は以下の様になっていた。

    function _fzf_complete.advice {
      [[ :$comp_type: == *:auto:* ]] && return
      compopt -o noquote
      COMP_WORDS=("${comp_words[@]}") COMP_CWORD=$comp_cword
      COMP_LINE=$comp_line COMP_POINT=$comp_point
      ble/function#push printf '[[ $1 == "\e[5n" ]] || builtin printf "$@"'
      ble/function#advice/do <> /dev/tty >&0 2>&0
      ble/function#pop printf
      ble/textarea#invalidate
    }

    そんなに深く考えられている様には思われない。単に noquote を外してしまって良
    い気がする。

2022-10-02

  * README: Guix の package 一覧に追加する (motivated by kiasoc5) [#D1888]
    https://github.com/akinomyoga/ble.sh/issues/235
    https://guix.gnu.org/en/packages/blesh-0.4.0-devel2/
    https://guix.gnu.org/ja/packages/blesh-0.4.0-devel2/

  * make: GNUmakefile の contrib/.git に対する依存性を削除する? [#D1887]
    https://github.com/NixOS/nixpkgs/pull/185866#issuecomment-1264567117
    https://issues.guix.gnu.org/57659#2

    どうも nix 系統は package の git を fetch する際に .git を削除する様である。
    なので特別に git submodule を GNUmakefile から削除したり、或いは空の .git
    ディレクトリを生成したりしている。然し、そもそも .git がなくても正しく動作
    する物なのかという疑問もある。

    少なくとも親ディレクトリの .git は存在していないとバージョンを決定する事が
    できない。contrib/.git には実は余り依存していない気がする。うーん。試してみる。

    * done: どうも contrib/contrib.mk の中にある contrib/.git も削除する必要がある。

      取り敢えずこれで問題なく動いている様である。そもそも何故 contrib/.git に
      対する依存性を持たせていたのかはよく分からない。存在確認だけしかしていな
      いのであればそれが最新になっているかどうかを保証できない。そして .git の
      存在確認をするだけなのであれば、それによって何を期待しているのかも謎であ
      る。

      ? 或いは、contrib.mk が存在していながらそのファイルが存在しない (が .git
        が存在すれば大丈夫保証される) という事態を想定している? と思ったが、そ
        もそもファイル一覧を生成するのに wildcard を使っているのでファイルが存
        在していないという事はありえない。。

      ? 或いは .git の更新時刻を確認しているのだろうか、と思ったが | の右側に
        contrib/.git を指定していたので更新時刻は全く関係ない。存在確認しかして
        いない。

      ? 或いは単にコピーする前に contrib 最新に更新したかっただけかもしれない。
        然し、単に contrib/.git の存在を要求するだけだと更新はされないので意味
        がない。今まで更新されなくて問題がなかったのだから気にしなくて良いので
        はないか。

      やはり contrib/.git の存在確認をする理由がよく分からないので単純に削除す
      る事にする。取り敢えずこれだけ修正したら .git がなくても動く様になった。

    ? .git が存在していない状態で make をすると何が起こるのか。依然として make
      が成功するのだろうか? 以下の二つの変数の値を決定するのに git を使っている。

        _ble_init_version
        _ble_base_branch

      実際に値を確認してみると以下の様になっていた。エラーが出ていても make の
      失敗にはならない。

        _ble_init_version=0.4.0-devel3+
        _ble_base_branch=

      release version ではこれらの変数にどのような値が設定されていたのだったか。
      もし、ここに固定の値が入っているのだとすれば .git がない場合にはそれと一
      貫した固定した値でも良いのかもしれない → うーん。release version でも、
      nightly version でもちゃんと branch 及び hash は生成されている。ble-0.3.0
      についても BLE_VERSION に hash が含まれている。

      という事を考えるとやはり version/branch に適切な値を入れないという選択肢
      はない様な気がする。何れにしても debug の時の情報がかけてしまう事になる。

    * done: git commit id の取得失敗時に ble.sh 生成を明示的に失敗させる

      GNUmakefile で明示的に .git を要求する様にしてみたが、これだと依然として
      ダミーの .git を作って無理やり通そうとする人が現れるのは必至である。やは
      りちゃんと hash が取れる事を要求するべきの気がする。hash を取得するのに失
      敗したら ble.pp の変換自体を失敗させる仕組みが必要の気がする。

      現在は #%$ にその様な機能はない。或いは一旦は #%[] で受け取ってその後で処
      理する? と思ったがそもそも #%[] を使っていたとしてもその場で変換を失敗さ
      せる仕組みはない様な気がする。

      1. 取り敢えずは #%error の様な directive が必要の気がする → と思ったら既
        にあった。

      2. 更に #%$ の結果を取得する方法か、或いはそのコマンドの失敗に対して即座
        に変換が失敗するオプションの様な物が必要ではないか。というかそもそも
        gawk でそれが可能なのかも分からない。取り敢えず確認する事にする。以下の
        ページによると終了ステータスを gawk から実行したコマンドで取得すること
        はできない様だ。なのでコマンド内部で色々して終了ステータスを標準出力に
        流す等の事をする必要がある。

        https://stackoverflow.com/questions/21296859/how-do-i-get-the-exit-status-of-a-command-in-a-getline-pipeline

      今回の場合には hash が空だったら失敗する様にすれば良い。branch については
      detached の状態にあって空になることもあるのでチェックしない。取り敢えず実
      装した。動いている。system() という関数を mwg_pp.awk に実装した。

      ? 更に外側の関係ない .git の commit を拾ってしまう可能性もあるのではない
        か? うーん。その様な場合を考えだしたら限がないので考えない事にする。

    * ok: GNUmakefile の .git で .git を要求されたらエラーメッセージを表示する
      事を考えたが、わざわざ変な事をしなくても良い気がしてきた。もし無理やりダ
      ミーの .git を作る人がいても今度は ble.sh の方が失敗する筈。なので、.git
      を要求するだけで良い。

    * done: 失敗しても壊れた ble.sh が生成されてしまうのを何とかできないか。GNU
      make が失敗時にファイルを削除したりしなかったりするが、その条件は何だろう
      か。と思ったら .DELETE_ON_ERROR というルールがある様だ。ble.sh を其処に指
      定する事にした。

2022-09-28

  * benchmark: -o KSH_ARRAY の中のコードが外と同じの気がする [#D1886]
    これは fe751acb の最初に benchmark.sh を追加した時からそのままである。
    実際 zsh の振る舞いを調べてみると KSH_ARRAYS を設定していると match の中身はずれる 。

    2022-11-11 実際に zsh の上で使おうとしたらたくさんの修正が必要になっ
    た。取り敢えず現状で分かっている分を追加修正した。

    2022-11-28 ksh で動かそうとしたら全然駄目だ。ksh は local を始めとして違い
    が大きすぎる。取り敢えず動く様にはしたが、色々違いが大きいので mwg_pp で別
    途 ksh 用に修正した物を生成する事にした。

2022-09-26

  * vte で unsupported modifyOtherKeys のシーケンスが画面に表示されてしまう (reported by dongxi8) [#D1885]
    https://github.com/ohmybash/oh-my-bash/issues/360#issuecomment-1256927443

    一旦は解決したと思ったが駄目の様だ。調べてみると vte:* の時には無効化してい
    る。実際に Ubuntu 16 LTS で GNOME terminal で試してみると再現した。どうも起
    動時に表示される様だ。それ以降は特に何も表示されない。つまり、端末情報を未
    だ取得し終わっていない段階で表示されてしまうのが問題という事。

    これに対してはどの様に対策したら良いだろうか。例えば端末情報が初期化される
    までは modifyOtherKeys は設定しない? 端末情報が出揃った段階で改めて
    modifyOtherKeys を設定する。しかし、そうすると端末情報を返答しない端末に於
    いて modifyOtherKeys が決して有効化されないという状況になるのではないか。と
    思ったが、modifyOtherKeys に応答する現代的な端末では常に DA2 に対しても反応
    すると仮定して良いのではないか。

    x と思ったが本当だろうか。例えば alacritty は DA2 に対応していなかった気が
      する。現在は対応している様だ (v0.11.0)。

      https://github.com/alacritty/alacritty/blob/1df32309fe69d4e8113813a3e9049a7039650f44/alacritty_terminal/src/term/mod.rs#L1170
      https://github.com/alacritty/alacritty/commit/0dfd8601c92666c45d0c2e056bd68f600a4cbe47
      https://github.com/alacritty/alacritty/issues/3100

      然し、実は alacritty は modifyOtherKeys の方に対応していない。

      https://github.com/alacritty/alacritty/issues/3101

    ? DA2 の後に modifyOtherKeys を有効にするというアプローチで問題ないだろうか。
      kitty では DA2 を受け取った後に再度 modifyOtherKeys を設定している。なの
      で、それが動いているのであれば他の端末についても問題ない筈。

      唯、現在の実装だと有効・無効の判定と端末の判定が別々になっている。ユーザー
      が internal/external を指定している時には端末のサポートに関係なく強制的に
      modifyOtherKeys を出力している。auto の時にのみ端末判定を行っている。これ
      で正しく端末状態を設定するにはどうしたら良いだろうか。

    うーん。取り敢えず DA2 を受け取る迄は modifyOtherKeys を設定しないように変
    更したが本当にこれを実行するのか。或いは bleopt で無効化する様にお願いすれ
    ば良いだけなのではないか。そもそも古い vte を使っているのが悪いのであって、
    その vte のバグの為にその他の端末についても制限を課すのは変な気がする。一方
    で、現実的に DA2 に対応していないが modifyOtherKeys に対応している端末とい
    う物が存在するのかというのはまた別の疑問である。うーん。正直 bleopt で各自
    無効化してもらうので良い様な気もするが、面倒なのでやはり ble.sh の側で対策
    するという事にする。

    2022-10-02 テスト: Ubuntu 16 LTS の上での gnome-terminal では問題が直る事を
    確認した。Fedora 35 の上の gnome-terminal, kitty, alacritty で問題がない事
    を確認した。そもそも gnome-terminal と alacritty は modifyOtherKeys に対応
    していないので余りテストの意味はない。chatoyancy (Fedora 36) の上では
    terminology, terminator はそもそも modifyOtherKeys に対応していない。xterm,
    mlterm は modifyOtherKeys に対応していて問題はない。mintty も問題ない。
    恐らく特に問題はないだろうと思われる。

  * 2022-09-23 prompt-git: rebase や  merge 等の状態を表示したい [#D1884]

    色々方法は考えられるがどうやら git-prompt.sh の __git_ps1 で使われている判定方法を用いれば良いらしい。
    https://stackoverflow.com/questions/30733415/how-to-determine-if-git-merge-is-in-process
    https://stackoverflow.com/questions/3921409/how-to-know-if-there-is-a-git-rebase-in-progress
    https://stackoverflow.com/a/3922581/4908404

    取り敢えず以下を元にした実装にする。
    https://github.com/git/git/blob/4fd6c5e44459e6444c2cd93383660134c95aabd1/contrib/completion/git-prompt.sh#L452-L475

  * global: return $? IFS [#D1883]

    未だ残っている? もしくは新しく増えた物かもしれない。修正する。
    make scan でも $? を検索する様に変更する。

2022-09-25

  * test: sha256sum がないというエラー @ macOS [#D1882]

    元々 Linux の上で動かす事を想定していたので色々問題が出てくる。

    test-util.sh の関数一覧 ToDo も序でに更新する。

  * github: GitHub#227 CI tests in macOS/Windows (reported by aiotter) [#D1881]
    https://github.com/akinomyoga/ble.sh/pull/227

    * macOS の sleep の実装は此処にある。特に変な事をしている訳でもない。
      https://github.com/apple-oss-distributions/shell_cmds/blob/main/sleep/sleep.c

    * macOS の CI ではテストをスキップする様にする方法について模索する。

      https://docs.github.com/ja/actions/learn-github-actions/environment-variables

      の環境変数 RUNNER_OS を参照すれば良い。github workflow の中で動いている事
      を確認する為に、CI == true 及び GITHUB_ACTION についても確認する。

    * macOS で問題が発生した時に誰が解決するのかという問題が生じる気がする。修
      正に時間が掛かるし実際の macOS で試してみないと分からない事もある。誰かを
      頼ろうと思っても誰に頼んだら良いのかも分からないしすぐ応答してくれるとは
      限らない。

      その間 nightly が全くビルドされなくなる。という事を考えるとやはり nightly
      と macOS のテストは少なくとも分離するべきである。

      また直る迄の間ずっと X がならぶ事になる。直す事ができないとずっと失敗する
      という事になる。うーん。一方で時々確認しておくという事はしたい気もする。
      確認する時だけ macOS をテストに含めるという使い方もあるだろうか??

    * PR に対しては一応実行しておきたい気はする。と言っても minor change や
      rebase に対して毎回テストを実行していたら clone stat が大変な事になる。テ
      ストを実行する時に approve をする機能があるみたいなので、それをどの様にす
      れば良いか確認する。

    * msys のテストで色々失敗している。GraphemeCluster に関して調べてみようとし
      たが、そもそも msys2 bash の上では $'\U1F6D1' が1文字ではなく2文字とカウ
      ントされる様である。

      $ a=$'\U1F6D1'
      $ echo "${#a}"
      2

      確認してみた所、実は Cygwin でも同様の問題があるという事が判明した。うー
      ん。これは Bash の側で修正するべき事の気がする。或いは Cygwin の側で修正
      するべき事の可能性もある。後で調べる事にする。

      うーん subst.c:8046 の MB_STRLEN を呼び出している。そしてこの MB_STRLEN
      は include/shmbutil.h で

      #define MBSLEN(s)       (((s) && (s)[0]) ? ((s)[1] ? mbstrlen (s) : 1) : 0)
      #define MB_STRLEN(s)    ((MB_CUR_MAX > 1) ? MBSLEN (s) : STRLEN (s))

      の様にして定義されている。mbstrlen は lib/sh/shmbchar.c で定義されている
      関数である。中では mbrlen を呼び出している。これは標準ライブラリから来て
      いる。

      -------------------------------------------------------------------------

      cygwin の上で mbrlen を呼び出すコードで再現した。newlib-cygwin の
      newlib/libc/stdlib/mbrlen.c (mbrlen) は単に mbrtowc を呼び出している。
      newlib/libc/stdlib/mbrtowc.c (mbrtowc) は wchar_t に変換する関数である。
      一方で windows では wchar_t は 16bit である。なので surrogate を読み取る
      しかないという事。うーん。この状況だとどのように直すのが正しいのか不明である。

      * mbrlen の実装を弄って mbrtowc ではなくて Unicode code point を読み取っ
        た時のバイト数を返す様に変更すると、今度は他の箇所で mbrtowc との不整合
        が問題になる可能性もある。

        そもそも bash ですら途中で wchar_t に変換して行う処理があった筈なので問
        題が起こる可能性が高い。

      * 或いは mbrtowc に変わる mbrtoc32 的な物があれば良いのだが。然し
        char32_t は C++ の物だし、もし一連の関数を提供するとしても bash の側で
        も大幅な変更と検証が必要になるので色々難しい気がする。

      だとすると ble.sh の側で上手に surrogate も処理できる様にする? 然し、
      UTF-8 で表されている文字列を bash でちゃんと切り取る事ができるのかも謎で
      ある。切り取る事ができたとしてもちゃんと処理できるのだろうか。。。

      -------------------------------------------------------------------------

      一つの手は Grapheme Cluster の判定に Surrogate pair も考慮に入れるという
      事。或いは既に考慮に入っている? →確認してみたが考慮には入っていない様だ。

      GraphemeClusterTable を確認すると surrogate pair U*D800..U+DFFF は全て 0
      になっている。つまり通常文字として取り扱われている。これを取り敢えず新し
      いカテゴリとして登録する事にする。

      取り敢えず実装したが、実際に Cygwin の上で動かすと動かない。どうも
      surrogate pair の後半に対して ble/util/s2c を実行しようとしても常に 0 に
      なってしまう。これは printf '%s' に渡す前に文字を切断する必要があるが、文
      字を切断する時点で空文字列になってしまうから? 調べてみると ${s:i} で切断
      した時点で 4byte 中の 3byte が処理された状態になっていて UTF-8 の最後の文
      字が切り出されるという事態になっている。

      -------------------------------------------------------------------------

      うーん。また変な振る舞いを見つけてしまった。これは bash の側で修正した。

      s=$'\U1F6D1'
      printf '%d ' "'$s" "'$s" "'$s"
      printf '%d ' "'$s" "'x" "'$s" "'x" "'$s"
      echo

      https://lists.gnu.org/archive/html/bug-bash/2022-09/msg00055.html

      他にも色々振る舞いについて修正などが必要だったが取り敢えず通る様になった。

2022-09-16

  * canvas: Unicode version 更新 [#D1880]
    15.0.0 が出ている。各テーブルを更新したが、更にversion 判定ロジックを改めて
    更新する必要がある。

    既存の判定用テーブルは #D1668 にある。これを更新する。うーん。このテーブル
    を生成するのに使ったスクリプトがある筈。だが見つからない。と思ったら

      make/canvas.c2w.list-ucsver-detection-codes.sh

    であった。うーん。U+1B132 (平仮名の小さな「こ」) を採用する。更新されたテー
    ブルは以下の様な感じ。

                   | -----Unicode EAW+GeneralCategory-------------------|musl
    ws[0]  U+09FBC | -1  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2 | 2
    ws[1]  U+09FC4 | -1 -1  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2 | 2
    ws[2]  U+031B8 | -1 -1 -1  2  2  2  2  2  2  2  2  2  2  2  2  2  2 | 2
    ws[3]  U+0D7B0 | -1 -1  2  2  2  1  1  1  1  1  1  1  1  1  1  1  1 | 2
    ws[4]  U+03099 |  2  2  2  2  2  2  2  0  0  0  0  0  0  0  0  0  0 | 0
    ws[5]  U+09FCD | -1 -1  2  2  2  2  2 -2  2  2  2  2  2  2  2  2  2 | 2
    ws[6]  U+1F93B | -1 -1 -1 -1 -1 -1 -1 -1 -1  2  2  2  2  2  1  1  1 | 1
    ws[7]  U+0312E | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  2  2  2  2  2  2  2 | 1
    ws[8]  U+0312F | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  2  2  2  2  2  2 | 1
    ws[9]  U+16FE2 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  2  2  2  2  2 | 1
    ws[10] U+032FF | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  2  2  2  2 | 1
    ws[11] U+031BB | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  2  2  2 | 1
    ws[12] U+09FFD | -1 -1  2  2  2  2  2 -2 -2 -2 -2 -2 -2 -2 -2  2  2 | 2
    ws[13] U+1B132 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  2 | 1

  * mandb: longname の説明に対応する short option 名を併記するう (suggested by bbyfacekiller) [#D1879]
    https://github.com/akinomyoga/ble.sh/issues/231

    これはもしかすると実際に short flag も選択できる様にして欲しいという要求か
    もしれないとも思ったがよく分からないので、取り敢えず作ってみて見た目だけ見
    せたらそれで良いというのでそのまま採用する事にする。

  * color: term_index_colors を優先する様に変更 (motivated by StavromulaBeta) [#D1878]

    これで強制的に減色したい時にユーザーが term_index_colors を設定できる。

  * [棄却] neovim terminal / vim-autocomplpop で i/a を入力した時の問題 [#D1877]
    https://github.com/akinomyoga/ble.sh/issues/232

    変な文字列が挿入・実行される

    # これは報告者が使っている AutoComplPop というプラグインが古いのが原因だった

    neovim は nvim というコマンドで起動する様だ。

    再現しない。nvim-0.7.2, bash-5.2-rc2, としても再現しない。

    * plain vimrc? .vimrc をコメントアウトして試したが再現しない。

    * reject: 或いは i, a に対する delay が関係している可能性? 実際に操作してい
      てい ESC がちゃんと即座に処理されていない気がする。
      https://vi.stackexchange.com/questions/16148/slow-vim-escape-from-insert-mode
      と思って ttimeoutlen や timeoutlen を短い値に変えてみたが振る舞い(遅延)に
      変化は見られない。これらの設定は関係ないという事か?

    * 27_feedPopup() という文字列が挿入されている。9_feedPopup で検索すると vim
      の中にある自動補完の仕組みが関係している様な気がするが詳細はよく分からな
      い。これでエラーが出ているという事は、実際に ble.sh がこの文字列を受信し
      ているということである。vim の保管機能が意図しない形で ble.sh に対して送
      信されて、変な文字列が挿入されると共に実行まで開始されている。

      https://askubuntu.com/questions/382407/vim-autocomplpop-issues

      このページを見る限り AutoComplPop という何かが関係している?
      元々のページ at bitbucket は消滅している?

      https://github.com/vim-scripts/AutoComplPop

      ここを見ると最後に更新されているのは12年前。runtime path 以下にファイルを
      コピーしろと書かれているが runtime path が何か分からない。検索すると
      runtimepath という変数に入っているみたいだが、今度は runtimepath という変
      数の値を取得する方法が分からない。と思ったら ":set runtimepath^M" で良い
      様だ。set で右辺を指定しなければ現在の値が表示される。実際に表示してみる
      と以下の様になっている。

      # runtimepath=~/.config/nvim,/etc/xdg/nvim,~/.local/share/nvim/site,
      # ~/.local/share/flatpak/exports/share/nvim/site,
      # /var/lib/flatpak/exports/share/nvim/site,
      # /usr/local/share/nvim/site,/usr/share/nvim/site,/usr/share/nvim/runtime,
      # /usr/share/nvim/runtime/pack/dist/opt/matchit,/usr/lib/nvim,
      # /usr/share/nvim/site/after,/usr/local/share/nvim/site/after,
      # /var/lib/flatpak/exports/share/nvim/site/after,
      # ~/.local/share/flatpak/exports/share/nvim/site/after,
      # ~/.local/share/nvim/site/after,/etc/xdg/nvim/after,~/.config/nvim/after,
      # /usr/share/vim/vimfiles/

      取り敢えず .config/nvim に入れる。

      OK 再現した。うーん。何故これが発生しているのだろうか。

      うーん。然し、そもそも ble.sh をロードしていなかったとしても i または a
      を押すと最後に実行したコマンドが強制的に実行される様である。これは変であ
      る。そもそも ble.sh だけの問題ではない気がする。

      検索すると https://github.com/othree/vim-autocomplpop/issues/9 で同じ現象
      が報告されている。というかこれが acp の最新版なのではないか。これを入れて
      みたところ、今度は ***** L9 library must be installed! ***** というメッセー
      ジが表示される。検索してみたらこれは行番号ではなくて "L9" という名前のラ
      イブラリらしい。同じエラーメッセージについての質問があった。

      https://stackoverflow.com/questions/22902141/l9-library-must-be-installed-error-occurred

2022-09-14

  * prompt: clear-screen 後は same-dir でも transient prompt を残しておく [#D1876]

    transient same-dir で起動後の一番最初のプロンプトは全部残しておくべきである。

    と思って試して見たがちゃんとそうなっている。或いは clear-screen した時にディ
    レクトリ名が消えてしまうという事だったか。これは振る舞いを修正しても良い。

    p10k の方の振る舞いを見てみたが clear-screen しても same-dir で trim されて
    しまう様である。なのでそういう意味では ble.sh も気にしなくても良いのかもし
    れないが、やはり clear-screen した後は残っていて欲しい気がする。

  * hook: blehook | cat がデフォルトで着色になっている [#D1875]

    bleopt ble-bind ble-face ble-sabbrev 等は問題ない。常に auto の振る舞いである。
    これは blehook の read-argument が悪い。修正した。

2022-09-13

  * HISTCONTROL に trim 的な物を追加しても良いのではないか (motivated by aiotter) [#D1874]
    https://github.com/akinomyoga/ble.sh/issues/226#issuecomment-1243759012

    bash のソースを見たら stringlib.c に strip_{leading,trailing} というのがあ
    るので trim ではなく strip を名前として使う事にする。

    取り敢えず bash の patch も作ってみる事にする。
    https://gitlab.com/akinomyoga/bash/-/commit/d43c167e9ec150d1fe4a730475a590d48a4cc9cd

2022-09-06

  * decode: ble-bind --cursor で設定したカーソルが反映されない [#D1873]

    vi のモードを遷移した時にしか反映されない。set -o emacs や set -o vi を実行
    してもそのままである。調べたら keymap#{push,pop} の時にしか cursor を設定し
    ていない気がする。base を変更した時や ble-bind で cursor を設定した時にも設
    定を反映するべきではないか。

    * 現在キーを受け付けている状態かどうかをどうやって判定するか。現在表に出て
      いる時にだけ cursor 設定をその場で変更する。それ以外の時には記録してある
      状態を書き換える、という具合にすれば良いだろうか。

      →これは ble/term/cursor-state/set-internal を指定すれば良いだろうか。
      実際、keymap/{push,pop} ではこの set-internal を指定している。

      他の箇所で一時的に cursor を書き換えていたりはしないか。つまり、同じ
      keymap であっても別の要因で別の cursor を表示しているという事はあるだろう
      か。→調べたがその場所はない。基本的に keymap/{push,pop} でしか cursor
      shape は変更していない様だ。

    * base map を設定している箇所を確認する。恐らく reset-default-keymap だけだ
      ろう。他は ble-bind -P で INITIALIZE_DEFMAP をしているがここでは
      _ble_decode_keymap はしていない。改めて確認したが _ble_decode_keymap を変
      更しているのはやはり decode.sh の中では keymap/{push,pop} と
      reset-default-keymap だけである。

    * ble-bind で cursor を設定した時にもその場で反映したい→対応した。動作も確
      認した。

    また、以前の xterm.js の為に指定した workaround が動いていないのではないか。
    結局 term enter する時に unknown を設定してしまっている。そして、コメントを
    見る限りはこれは vim がカーソルの状態を残したまま終了してしまう事に対する対
    策の様である。

    うーん。これに対してはどの様に対処するべきだろうか。vim の設定が悪いのだと
    思えばわざわざ直さなくても良い。と思ったが元々これは ble.sh の中で keymap
    の cursor を設定しているのにも拘らず vim の実行後にその設定が変わってしまう
    というのが問題なのであった。

    default と unknown という値を区別する事にして、ble.sh が cursor 設定を変更
    していない時は default という事にしてユーザーコマンドが変更した cursor につ
    いては関知しない事にする。

2022-08-31

  * 2022-08-23 complete: progcomp 引数について [#D1872]
    https://github.com/scop/bash-completion/issues/790
    https://github.com/scop/bash-completion/issues/791

    ? ok: そもそも現在の ble.sh の実装だと = などが存在した時の単語の分割の仕方
      が異なる。これはやはり Bash に合わせた方が良いのだろうか。と思ったが、

      $ test1 a=[TAB]
      $ test1 a=b[TAB]

      の両パターンの一貫性を考えれば現在の ble.sh の分割の仕方の方が自然だし、
      後者を実装しているのであれば前者についても ble.sh の分割の仕方で自然に動
      作しそうな物である。という事を考えると、敢えて bash の変な振る舞いに合わ
      せる必要はない様に思われる。

    * ok: 更に報告された振る舞いで問題になっているのは、分割文字 = の直後で補完
      した時に、何故か新しい単語ではなくて = に対する補完になっているという
      Bash の振る舞いがそもそもの問題である様な気もする。それを回避する為に $2
      に空文字列を設定するというのも何だか変な実装である。

      然し一方で分割文字 = 自体を書き換えたいという場合も考えられるので遡って書
      き換えられる様に "=" の単語の中に含めて補完するというのもそれはそれで理解
      できる。なので Bash 自体に振る舞いの変更を実装して解決するという訳にも行
      かない。

    ? ok: 所で "echo aaa [TAB] bbb" とした時に ble.sh はどの様に振る舞うのだっ
      たか。bash では変な分割のされ方と CWORD の設定のされ方になっているとして
      文句が出ていた物である。

      →これは ble.sh ではちゃんと途中に空文字列を作成している。OK

    ? done: コマンド名自体が COMP_WORDBREAKS で分割される場合にはどう振る舞うべ
      きか。Bash の振る舞いを確認してみた所、COMP_* を作成する時点でコマンド名
      も COMP_WORDBREAKS に従って分割されてしまっている。一方で、補完関数の $1
      に渡される文字列は分割前のコマンド名の様である。

      その様に実装する。

    bash-completion#791 の実装を単に移植する事にした。

    * reject: うーん。そもそも bash の振る舞いを厳密に再現する必要もない様な気
      はする。特に simple-word/is-simple-or-open-simple 等を使ってより良く判定
      できるのではないかという気がする。然し、取り敢えずは Bash の動作に厳密に
      一致する様に振る舞う事にする。そもそもこの振る舞いを便利に使っている補完
      があるとも思われないので。

    x fixed: そもそも現在の ble.sh において COMP_WORDBREAKS が正常に動作してい
      ない気がする。

      確認してみた所 ble/syntax:bash/simple-word#break-word に引数を渡し忘れて
      いる? ここに単に $wordbreaks を渡せば良いのではないか。

      ? 或いは、既定の値 (:=) を使う理由が何かあったのだろうか? 調べる。変更は
        6c6bae5 で行われている。これは #D1098 である。この時の議論を確認してみ
        たが特にこの部分で特別な取り扱いをするという議論はない。寧ろ
        COMP_WORDBREAKS に対応する為の議論なので wordbreaks 変数を全く使ってい
        ない現在の実装は変である。

      分割子として "$wordbreaks" を指定する様に修正した。

    x fixed: 新しく実装した cur が全く反映されない。と思ったら helper-prog (-C)
      の方だけ対応していた。helper-func (-F) の方も対応する。動作も確認した。

    ? ok: bash の COMP_WORDBREAKS による単語分割は @ や $ や \ に対しても他の分
      割文字と同様に働くのか? つまり独立した subword を形成するのだろうか? →
      試してみた所、ちゃんと独立した subword になっている。つまり abc@def が
      "abc" "@def" と分割される等の特別な事は起こらない。特別な取り扱いは $2 限
      定の様だ。

    * 何と $2 には現在の単語だけが設定される訳では無い様だ。COMP_WORDBREAKS に
      よる分割の前の単語が全て入る可能性がある。

      $ test1 abc@def
      declare -a COMP_WORDS=([0]="test1" [1]="abc" [2]="@" [3]="def")
      <test1><@def><@>

      これにもちゃんと対応した。

2022-08-29

  * 2022-08-23 blehook HOOK+= を HOOK!= に統一する [#D1871]

  * 2022-08-14 nix develop が保存された EPOCHREALTIME を復元しようとしている [#D1870]
    https://discourse.nixos.org/t/nix-print-dev-env-command-shows-some-assinments-to-readonly-variables/20916
    https://github.com/NixOS/nix/pull/6800

    一方で ble.sh は EPOCHREALTIME が勝手に別の機能に置き換えられると動作が全く
    おかしくなるので (そしてはそれは他の EPOCHREALTIME を参照しているスクリプト
    も同様であろう)、勝手に EPOCHREALTIME の機能を消去させられてしまっては困る。

    * そもそも Bash では EPOCHREALTIME をそのまま上書きしても意味がない。一旦
      unset しなければならない。実際に上書きしている箇所で unset をしているのか
      どうかまでは明言されていないが、報告されているエラーメッセージを観察する
      限りは unset は試みられていない。unset が最初に試みられていたのであれば、

      bash: unset: EPOCHREALTIME: cannot unset: readonly variable

      というエラーメッセージになっていた筈である。

    * もし unset してまで固定した時刻にしたかったのだとすれば、そして実際にそれ
      をやったとしたら ble.sh の内部の時刻関連の制御が滅茶苦茶になる。場合によっ
      ては固まってしまうかもしれない。

      というかもし対話シェルで使っているなのだとしたら

    ? というかそもそも何故対話シェルの設定と print-dev-env 的なコマンド的な設定
      が混ざり合っているのだろうか。

      % ? 会話を見ると print-dev-env は単に現在のシェル変数を出力するのに使って
      %   いるだけの様に見える。sed でフィルタ等するという話をしている。なので、
      %   対話シェルとして動作するとも思えない。
      %
      % ? nix develop でエラーメッセージが表示されると書いている。nix develop
      %   を調べてみると、 nix shell + 開発用のコマンドという環境に入るらしい。
      %   なので bashrc を読み込む。問題は print-dev-env が何故同じシェルで呼び
      %   出されるのかという事である。特に直接 print-dev-env を自分で明示的に呼
      %   び出しているのではなくて、nix develop を実行した時に自動で実行される
      %   のだという事を書いている。謎だ。
      %
      % ? 仮に ble.sh が --lib で読み込まれるのだとしても、それを bashrc から読
      %   み込むというのも変な話である。もし ble.sh の関数を個別のシェルスクリ
      %   プトで使いたかったとしても、それは使うシェルスクリプトの中で個別に
      %   source するべきなのであって、bashrc で一括して読み込むという使い方は
      %   想定していない。
      %
      % ? 或いは print-dev-env というのはシェル関数なのだろうか。

      % https://github.com/NixOS/nix/blob/master/src/nix/develop.cc を見ると、
      % どうも print-dev-env と develop は内部のコードを共有しているという事の
      % 様だ。つまり、develop の中で呼び出された print-dev-env が EPOCHREALTIME
      % を触ってのではなくて、nix develop のコード自体が EPOCHREALTIME に触ろう
      % としているのである。更に、print-dev-env も develop も単に現在の値を出力
      % しているだけであって、明示的に EPOCHREALTIME に値を設定するコードが含ま
      % れているという訳では無い様な気がする。
      %
      % そういう事を考えると、そもそもこの現在の値を出力するコードの時点で、
      % EPOCHREALTIME, EPOCHSECONDS, SECONDS, LINENO, BASH_LINENO, FUNCNAME,
      % BASH_SOURCE, BASH_VERSION, BASH_VERSINFO, BASH_COMMAND 等の変数に値を代
      % 入しようとしているのが間違っている。

      develop.cc のコードを確認した。先ず、print-dev-env は、実質的に nix
      develop を中で呼び出してその環境における変数を出力するという様な処理を行っ
      ている。そして、正にそれが目的なのだろうという気がする。

      nix develop は何処かに .json で保存されている変数を読み取ってそれを bash
      に設定しようとしている様に見える。その .json に EPOCHREALTIME が記録され
      ているのは恐らく何か別の用途にも使われる事を想定しての物だろう。一方で、
      nix develop で使う時には幾ら何でも全ての変数を復元するのは変である。
      BASH_* は避けるべきだし (もしかするとこれらは既に保存する時点で除外されて
      いるのかもしれない)、その他の FUNCNAME や LINENO 等も復元を試みるのは滅茶
      苦茶である。

      BASH_VERSINFO は bash が readonly にしていてこれに関しては警告が出ていな
      いというのは BASH_* は除外しているという事なのだろうという気がする。

    ? NixOS/nix #6800 も謎である。error ではなく warning だったと言って閉じてい
      るのも謎だし、zsh では readonly だからと言って bash で動く nix develop の
      上でスキップするというのもよく分からない。

    * 色々 develop.cc を読んだりして思った事は TLATER の 99% sure と言っている
      内容はかなり怪しいという事だ。恐らくこの TLATER は何も分かっていなくて出
      鱈目な事を書いている。

      或いは実際に何処か別の箇所で EPOCHREALTIME も明示的に保存しているのだろう
      か。でもコードを見る限りは ignoreVars でブラックリスト式にしているし、恐
      らく全ての変数を出力しているのだろうという気がする。

      やはり TLATER は出鱈目を書いている。もし本当にそうなのだというのであれば
      わざわざ 99% sure などと書かないし、というか 100% sure とも書かずに、断定
      で書くはずである。I'm sure なんとかとか書いている時点で勝手に推測をしてい
      るのに過ぎない。

      そもそも本当に build environment を同一にしたいのであれば、単に変数の値を
      変更したとしても意味がない。システムの時刻自体を固定しなければならないの
      ではないか。そもそも最近の bash の機能である EPOCHREALTIME を参照してビル
      ドを行うシステムがどれだけ存在するのかというのも謎である。そしてシステム
      の時刻を固定しているのであれば、わざわざこの様な処理は必要がない筈である。


      →と思ったがこの json はもしかすると各 derivation の作者が手書きで用意す
      る物なのだろうか。なのだとしたら EPOCHREALTIME を誤って設定している人がい
      ても不思議ではないのかもしれない。然し検索してみてもその様な物は見つから
      ない (とは言いつつ GitHub の検索は余り当てにならない。経験上最近検索され
      たページに含まれている文字列しか検索対象になっていないような気がする)。

      https://github.com/NixOS/nix/search?q=EPOCHREALTIME
      https://github.com/NixOS/nixpkgs/search?q=EPOCHREALTIME

    2022-08-29 これは結局 nix の側で修正されたので OK
    https://github.com/NixOS/nixpkgs/pull/185866
    https://github.com/NixOS/nix/pull/6944

  * ok: 2022-08-26 何と bash の regex は ^ で文字列の戦闘ではなくて行頭に一致してしまう? [#D1869]

    と思ったがそうでもないようだ。特別な条件で発生する。

    rex='^b'; [[ $'a\nb' =~ $rex ]]; echo $?    ... 一致しない (OK)
    rex='^[^a]'; [[ $'a\nb' =~ $rex ]]; echo $? ... 一致しない (OK)
    rex='a^'; [[ $'a\nb' =~ $rex ]]; echo $?    ... 一致しない (OK)
    rex='.^'; [[ $'a\nb' =~ $rex ]]; echo $?    ... 何故か一致してしまう?????
    rex='.^'; [[ $'ab' =~ $rex ]]; echo $?      ... 一致しない (OK)
    rex='^.^'; [[ $'a\nb' =~ $rex ]]; echo $?     ... 一致しない (OK)
    rex=$'\n^'; [[ $'a\nb' =~ $rex ]]; echo $?     ... 一致する!
    rex=$'a\n^b'; [[ $'a\nb' =~ $rex ]]; echo $?     ... 一致する!
    rex=$'^..^b'; [[ $'a\nb' =~ $rex ]]; echo $?     ... 一致する!

    この変な振る舞いは 3.0..5.2 まで全てで再現する。或いは Linux/glibc 側の問題
    の可能性もある。

    何れにしても .^ や \n^ の様な (single line regex では) 意味のない正規表現で
    しか問題が起こっていないので取り敢えずは何もしなくて良い。うーん。例えば ^
    より前に何かが存在する時に限り ^ は multiline mode に変更されるなど? もしか
    すると関連して現実的な正規表現でも問題が起こる可能性があるかもしれないが。

    だとしたら ^$ で空文字列にしか一致しない様にしているのは不味いのではないか?

    $ a='x\n\ny' r='.*^$'; [[ $a =~ $r ]]; echo $? ... 一致しない (OK)
    $ a='x\n\ny' r='.+^$'; [[ $a =~ $r ]]; echo $? ... 一致しない (OK)
    $ a='x\n\ny' r='.*(^$)'; [[ $a =~ $r ]]; echo $? ... 一致しない (OK)
    $ a='x\n\ny' r='.+(^$)'; [[ $a =~ $r ]]; echo $? ... 一致しない (OK)

    と思ったがこの場合には問題は起こらない様だ。不思議だ。

    取り敢えず問題にはならないとは思われるが、一応注意点として記録はしておく。

  * [自然解消] refactor: TRAPRETURN の中に余分な i=1 が残っている [#D1868]

    結局関連するコードは #D1867 の際に消滅した。

  * trap: gexec による DEBUG の処理を ble/builtin/trap に統合する [#D1867]
    * trap DEBUG, ERR についても関数呼び出しに従った構造を記録する。

    x 統合する上での問題は trap の中で trap が走った時に
      _ble_builtin_trap_postproc 等の変数が混ざって問題にならないかという事。
      (そもそも trap の実行中に trap が走るのかどうかもよく分かっていない) →
      実際に試してみた所、やはり trap の中で DEBUG trap は走る様だ。

      Ref. memo/D1867.recursiveTrapWA-stub.patch (試験的な実装)

      これは実は RETURN でも同様なのではないか。trap handler の中で RETURN が発
      生するのでは?

      a 混ざらない様にするには trap 毎に別の変数に trap_postproc を保存する?
        と思ったが RETURN の中で呼び出される RETURN などの状況を考えると単に
        trap 毎に変数名を変える方法では対応できない。

        % * 以前 RETURN の中で RETURN が呼び出されるというので無限ループ
        %   になった事がある気がする
        %
        %   →と思って今試してみたらやはりそういう事は起こらない様である。だとす
        %   れば単に trap 毎に保存すれば良いだけなのではないか。
        %
        %   以前の議論を探してみた所、実際に以前これについて調べていた (#D1350)
        %   がその時調べた結果は RETURN は RETURN 以外の trap では発生するという
        %   事。RETURN 内部で RETURN は発生しないという事。この時調べたのは、無限
        %   ループにならないかというのが心配になったからだったという記憶が微妙に
        %   残っていただけだろう。

      b というか単に trap の nest level を変数に入れておけば良いのでは? そして
        _ble_builtin_postproc[_ble_builtin_trap_depth] を参照する。

        と思ったが全てを handler に入れておく必要もない気がする。要するに
        .handler を呼び出した直後に postproc を評価するのだから、.handler の最後
        で postproc を設定すれば良いだけなのでは? と思ったがやはりそう簡単でもな
        い。.handler を呼び出した後に eval "${postproc}" を実行する間に別の trap
        が走る可能性もあるのである。

      c という事を考えると、

        depth++; .handler; eval postproc; depth--

        の様な具合にしなければならないのではないか? 然し depth-- を保証する方法
        がない。

      d 或いは

        depth=depth+1 eval '.handler; eval postproc'

        という具合にするしかないのだろうか。と思ったがこれも駄目な気がする? 否、
        例え .handler と eval の間に別の handler が入ったとしてもその handler
        が中途半端に終了しない限りは大丈夫の筈。


        _ble_builtin_trap_depth=$((_ble_builtin_trap_depth+1)) builtin eval -- "${_ble_builtin_trap_handler/SIGNUM/1}"
        _ble_builtin_trap_handler='ble/builtin/trap/.handler SIGNUM "$BASH_COMMAND" "$@"; builtin eval -- "..." \# "..."'

        うーん。これで行けると思ったがやはり駄目だ。eval を入れ子にすると $_ が
        変わってしまうので駄目。なので eval を入れ子にしない方法を考えたいが…
        或いは trap によって lastarg が変わらないという事にしてしまって一番外側
        の eval に \# "${_%%$_ble_term_nl*}" を渡すという手もあるかもしれない。


      e 或いは handler の中で local inc したらどうなるだろうか。

        handler() { local depth=$((depth+1)); postproc[depth-1]=設定; }

        問題が起こるとしたら

        ? handler が呼び出されて local depth を実行する間に DEBUG が走った場合?
          然しこの場合には実のところ DEBUG の処理が終わったらまた元の状態に戻る
          筈なので気にしなくて良い。とにかく postproc を触る前までに depth を
          inc して置けば良い筈。

        ? 或いは handler が終了してから eval postproc[depth] する間に DEBUG が
          走った場合? 実はこれについても特に問題は発生しない様に思われる。

          →うーん。やっぱり駄目だ。handler が終了した時に postproc[depth] には
          handler が設定した物が入っているが、この時に別の trap が走るとそれが
          上書きされてしまう。

          代わりに push/pop 方式にするとしても pop せずに抜けてしまった時に、よ
          り外側の handler が誤って内側の物が設定した postproc を実行してしまう
          事になる。

      f 或いは別の方法で trap の入れ子レベルを知る事ができれば良い。と思ったが
        難しい。FUNCNAME の中に含まれる ble/builtin/trap/.handler を数える方法
        を考えたが、これだと結局 handler ... eval の間に走る trap に対して対処
        できない。というか eval の入れ子レベルを取得する方法はないにだろうか。
        PS4 の最初の文字を複製する回数でもあるが、これをもっと普通の方法で取得
        する方法がないのは何故だろうか。

      g うーん。或いは postproc を設定してからそれを評価する迄の間に発生した
        trap は全て無効化するという可能性?

        x しかしこれも何らかの拍子で postproc が実行されずに終わってしまうとそ
          れ以降の全ての trap が実行されなくなってしまう。

          然し、実際にそれが発生する事はあるのだろうか。先ず INT は塞いでいる。そ
          もそも trap の内部で INT は発生しない気がする。trap の内部で発生する可
          能性があるのは DEBUG, RETURN ぐらいの物である。errtrace が設定されてい
          れば ERR も発生するかもしれない。

          * DEBUG と RETURN には介入している。一方で、ERR には介入していない。
            DEBUG と RETURN に関しては無効化すれば良い。ERR で return などが実
            行されて trap 終端処理がスキップされた時に問題になる。

          その他の理由で実行がキャンセルされる事はあるだろうか。

          * 外部からのシグナルの場合には trap handler の実行中には何も起こらな
            い。trap handler の実行が終わった後に実行される筈である。
          * readline の timeout (TMOUT) に関しては ble.sh は無効化して自前で実
            装しているので問題にならない筈。
          * KILL を受け取ったら何れにしても終了するので関係ない。
          * exit で trap の中から終了する場合…と思ったがこれは起こり得ない。今
            ble.sh の trap string を実行しているのだからその他のコマンドが実行
            される余地はない。

          うーん。別の方法で trap を実行している事を検知する方法はあるだろうか。

          * reject: 例えば bash-4.4 以降では trap 実行中に return の戻り値が変
            わる事を以て現在 trap の内部かどうかを判定できると思ったが、入れ子
            の trap の場合には 2 重か1重かを判定しなければならないのでこの方法
            は使えない。そもそも使えたとしても、この振る舞いは議論の対象であり
            将来的に変更されるかもしれないし古い bash では使えない。

        恐らくこれで基本的に問題ない。

        1 DEBUG に対しては postproc 直前の発火に対しては無視する。

        2 RETURN に対しては trap/.handler RETURN について無視する。

          うーん。これは元からそうなっているのでは? と思ったがそうでもない様
          だ。現在は trap 内部の RETURN しか無視していない。これに加えて
          blehook/invoke.sandbox | blehook/invoke | ble/builtin/trap/.handler
          に対して発火した RETURN も無視したい。

        3 ERR に関しては trap/.handler が失敗しない限りは大丈夫の筈。

        但し、何らかの拍子に postproc が設定された儘になってしまった時の為に、
        随時 postproc をクリアする。例えばトップレベルで呼び出された
        ble-decode/.hook でクリアすれば良いのではないか。少なくとも trap
        handler の中でトップレベルで ble-decode/.hook が呼び出される事はない。

    改めて考え直してみたが同じ trap が入れ子で呼び出される事はやはりないと仮定
    して良い気がする。だとすれば a の方法で実装すれば良い。一方で g.2 の
    [RETURN 以外の trap についての trap/.handler に対する RETURN] の発火は無視
    する事については対処したい。

    * RETURN 以外の trap/.handler に対する RETURN を無視する事について。

      というか現在の実装の blehook/invoke.sandbox | blehook/invoke |
      ble/builtin/trap/.handler のスキップは全て無視して単に BLE_TRAP_FUNCNAME
      を参照すれば良いのではないか?

      と思ったがそれだけだと駄目である。先ず trap/.handler は内部で色々な関数を
      呼び出している。RETURN を extdebug で設定しているとこれらの全ての関数に対
      して RETURN が発火して面倒な事になる。

      うーん。exit 時に RETURNが呼び出されると思ったが、これは unload で元の
      RETURN を復元した後に発生している物である。

    * _ble_builtin_trap_{postproc,lastarg} を trap 毎に記録する様に変更する。

      _ble_builtin_trap_lastarg については基本的に2つの関数でしか使われていなかっ
      たのですぐに修正できた。_ble_builtin_trap_postproc も殆ど同様だったが、但
      し edit.sh で DEBUG trap の postproc/lastarg 抽出に使用されていた。これは
      _ble_edit_exec_TRAPDEBUG_postproc の代わりに
      _ble_builtin_trap_postproc[_ble_builtin_trap_DEBUG] を使う様にすれば良い
      だけである。

    * #D1853 で最近行った修正について気付いたのだが、実は既に lastarg に改行が
      含まれる場合については既に trap/.handler の内側で対処済みであった
      (#D1757)。trap string 内の無駄な $_ble_term_nl に関係する消去は除いた。

    * _ble_edit_exec_TRAPDEBUG_lastarg も同様に処理する様に変更するべきなのでは
      ないか。というか今はどの様に処理しているのだったか→取り敢えず似た様に修
      正する事にした。

    x fixed: TRAPDEBUG を early return する時に lastexit を復元していなかった。
      これは問題である。修正した。

    以降は少しずつ TRAPDEBUG の機能を trap/.handler に移植して行く事にする。

    * TRAPDEBUG では通常であればユーザートラップは関数の外で postproc を用いて
      実行している。一方でこの機能は現在の trap/.handler には存在していない。

      この手法の問題はユーザートラップによって設定される lastarg が失われてしま
      う事。と考えるとやはり handler の中で実行した方が良いのだろうか。然し、意
      図的に trap によって $_ を書き換える事も考えにくいので、やはりこの様にし
      て $_ が変わらない様に評価するというのの方が良いのかもしれない。或いはこ
      れはオプションで切り替えられる様にする。

    * user trap を呼び出す時に ble-attach している時には LINENO を設定している
      がどういう事か。これは恐らく LINENO を以前 unset していた為に、trap の中
      で LINENO が変な値になってしまう問題があったのだろう。然し現在は LINENO
      の機能を上書きしない様にしている。とは言いつつ ble.sh の内部で LINENO を
      実行すると関数内部でも一番外側における LINENO が表示されてしまうという問
      題がある。

      この振る舞いと consistent にする為に今までの様に一番外側の LINENO を設定
      していたと考える事もできるが…うーん。どう振る舞わせるのが良いだろうか。

      本来の bash における LINENO at trap string は trap/.handler の中では
      BASH_LINENO[1] を参照すれば取得できる。但し、これが top-level context の
      場合には、 _ble_edit_LINENO を代わりに参照する必要がある。というか、単に
      BLE_TRAP_LINENO を修正すれば良いだけなのでは。

    * DEBUG も install-hook する? →但し inactive にて。と、思ったが DEBUG の場
      合には inactive ともまた微妙に振る舞いが異なる。現状の edit.sh でやってい
      る処理のままで良い。

      もしかすると DEBUG でやっている様な trap の仕掛け方についても将来的には
      ble/builtin/trap に組み込んでも良いかもしれないが今ではない。

2022-08-25

  * trap: ユーザーが INT を設定している時は INT によるキャンセルはしない [#D1866]

    INT によってコマンドがキャンセルされるのを防ぐ為に trap '' INT としても意味
    がない。結局コマンドが中止される処理が走る。

  * trap: user trap handler 内で $@ を復元する [#D1865]

    2022-08-29 テストが動かなくなった。何故→これは単純なミスだった。shift を実
    行したが、それよりも後で $1 を参照している箇所があった。修正した。

  * trap: refactor and fix ble/builtin/trap [#D1864]

    * ble/builtin/trap 及び blehook 関連のコードが util.sh の中で肥大化して、他
      の util 内の関数に対する依存性が問題になってきている。より後ろで定義され
      ている関数に依存しているので初期化を遅延させるなどしなければならず不都合
      である。コードをもっと後ろに移動する代わりに、ファイルを分離する事にした。

    * fixed: 元からあった trap は出力されるのか

      これは実装を確認してみると出力されない気がする。実際に試してみるとやはり
      出力されない。修正した。

    * fixed: そもそも ble/base/unload した時に元の trap を復元するべきなのでは
      ないかという気がする。と思って確認してみた所、元から復元する様になってい
      た。然しちゃんと動いていない。

      * fixed: 然し、trap - INT という設定が外側に伝播しない様だ。EXIT はちゃん
        と解除されるが INT と WINCH は外側へ行かない。

        と思ったら単に $sig を参照する所を存在しない変数 $index を参照して trap
        に渡すシグナル名を決めていたのが原因だった。修正した。

      * fixed: というか復元するコードでカスタムシグナルに対しても勝手に trap が
        呼び出されてしまう。これは修正するべき。特に install-hook 等を通して設
        定された物だけを復元する。

    * ok: ble-reload した時に元々ある _ble_builtin_trap_handlers を保持するべき
      なのではないか? 現在は上書きしてしまっているので install-hook 経由で設定
      されている hook 等は消滅してしまう気がする。

      →これは ble/base/unload の際にちゃんと builtin trap を復元する様にしたら
      動く様になったので良しとする。

    * done: trap CUSTOM なども trap -p で出力

2022-08-24

  * trap: RETURN trap はちゃんと動くのだろうか [#D1863]

    現在の trap の実装で RETURN はちゃんと設定できるのだろうか? → 試してみた所、
    ちゃんと意図した箇所で RETURN trap が呼び出されているが、関係ない場所でも
    RETURN が呼び出されてしまっている。更に、設定した関数を抜けた後でも RETURN
    が呼び出されている。

    本来の Bash の実装を見ると trap RETURN を設定した関数 (追記: とその呼び出し
    元) のみで trap RETURN が発火する様である。但し、trap -p / trap -p RETURN
    すると何故か関数が抜けた後でも関数内部で使用した RETURN trap が出力される。
    然し、trap -p で出力されていてもこれは決して呼び出される事はない様だ。

      bash$ function a { trap 'echo RETURN a' RETURN; a2; echo a; }; function a2 { echo a2; }; a; trap -p
      a2
      a
      RETURN a
      trap -- 'echo RETURN a' RETURN
      ble.sh$ function a { trap 'echo RETURN a' RETURN; a2; echo a; }; function a2 { echo a2; }; a; trap -p
      RETURN a
      RETURN a
      a2
      a
      RETURN a
      trap -- 'echo RETURN a' RETURN
      RETURN a

    と思ったが、RETURN a が発火している関数を調べてみた
    所、_ble_edit_exec_gexec__TRAPDEBUG_adjustだった。そしてこれは declare -ft
    を設定している関数なのであった。

    % * というか試してみたが実は RETURN は元からそんなに賢い実装ではない様だ。
    %
    %   bash$ function a0 { echo a0; a1; }
    %   bash$ function a1 { trap 'echo "RETURN:a1"' RETURN; echo a1; a2; }
    %   bash$ function a2 { trap 'echo "RETURN:a2"' RETURN; echo a2; }
    %   bash$ a0
    %   a0
    %   a1
    %   a2
    %   RETURN:a2
    %   RETURN:a2
    %   RETURN:a2
    %
    %   先ず、内側の関数で設定された trap が外側の関数で定義された trap を上書き
    %   してしまって、関数を抜けた後でもそれが復元される事がない。次に、内側の関
    %   数で設定された trap が外側の RETURN を設定しなかった関数でも実行される。
    %
    % * RETURN trap が ble/builtin/trap に対しても呼び出されてしまう問題に関して
    %   は、単に RETURN trap の側で上手に処理してもらうべきなのではないか。という
    %   のも、元から設定した関数とは別の関数で呼び出される可能性があるのだから、
    %   ちゃんと関数を判定してから実際の処理を行う様に実装してあるべきだからであ
    %   る。
    %
    %   と思ったが本当だろうか。trap - RETURN をちゃんと実行するようにしていれば
    %   RETURN が復元されるのではないか。そうでなかったとしても trap - RETURN と
    %   だけしておけば本来ちゃんと動いたのではないか。
    %
    % →試してみたらそうだった。RETURN trap の中でちゃんと trap を解除している
    %   限りは各関数の RETURN trap が各関数で呼び出されるという形になる様だ。
    %
    %   bash$ function a0 { echo a0; a1; }
    %   bash$ function a1 { trap 'echo "RETURN:a1"; trap - RETURN' RETURN; echo a1; a2; }
    %   bash$ function a2 { trap 'echo "RETURN:a2"; trap - RETURN' RETURN; echo a2; }
    %   bash$ a0
    %   a0
    %   a1
    %   a2
    %   RETURN:a2
    %   RETURN:a1

    RETURN trap の中でちゃんと 'trap - RETURN' で trap を解除している限りは、
    RETURN trap はちゃんと設定した関数の中だけで実行する振る舞いになる。これは
    明らかに ble.sh の中では壊れてしまう。

    "trap - RETURN" を関数内で実行してもちゃんとその効果は外に持続するだろうか?

      $ st() { trap "echo '[RETURN:$1]'" RETURN; }
      $ us() { trap - RETURN; }
      $ f1() { st f1; echo f1; us; }
      $ f1; trap -p
      [RETURN:f1]
      f1
      [RETURN:f1]
      trap -- 'echo '\''[RETURN:f1]'\''' RETURN
      $ trap - RETURN; trap -p
      $ st() { trap "echo '[RETURN:$1]'" RETURN; }
      $ us() { trap - RETURN; }; declare -ft us
      $ f1() { st f1; echo f1; us; }
      $ f1; trap -p
      [RETURN:f1]
      f1

    うーん。駄目持続しない。逆に declare -ft を実行すると削除されるがうーん。もっ
    と現実的な設定で実験しないと分からない。

    * memo/D1863.RETURN-recursive.sh

      意外と簡単にちゃんと動く様にできた。interactive でもスクリプトでも両方と
      も期待どおりに動く事を確認した。これと同じ様に実装する事を考える。

    うーん。install-hook 等の枠組みを通じて修正するのではなくて RETURN は
    RETURN で特別に実装するのが良い気がする。RETURN を設置する時には既存の user
    trap を気にする必要もない。単に trap, ble/builtin/trap 内部で発生する
    RETURN をスキップするだけで良いのでは? と思ったがスキップする為には結局
    trap/.handler の様な複雑な仕組みが必要になる。

    実は単に install-hook RETURN inactive にすれば良いという可能性もある? → そ
    の様にして見たら各関数ごとに記録されている trap が消滅して駄目だった。trap
    を各関数呼び出し階層に対して記録する必要があるのだった。

    * どの様に記録してどの様に取り出すかについて落ち着いて考える必要がある。


      取り敢えず trap - RETURN されない限りは内側で設定された trap はずっと残る
      という事。全ての階層について記録しておいて一番深い階層で記録した物をいつ
      も取り出しておくという実装で良いのだろうか。

      ? しかし A->B->C1 と呼び出して C1 で設定した trap は A->B では有効である
        が、A->B->C2 と更に呼び出した別の関数の中では (C2 が -t を持っていない
        限り) 無効の筈である。なので B に戻った時点で C1 のレベルに設定した
        handler を除去して B のレベルに再設定するべきではないだろうか。

        x と思ったが B に戻った時点を特定する手段がない。結局そのように実装した
        としても C2 で有効になってしまうのではないか。

        o と思ったが、もし本当に継承されないのだとしたら C2 の中でそもそも
          trap/.handler は呼び出されないので気にしなくても良いのではないか。も
          し C2 の中で trap/.handler が呼び出されるのだとしたらそれは別の
          handler が明示的に設定されたという事であり、その時点で handler が上書
          きされてなくなっていると期待して良いのではないか。

        ? C2 が -t を持っている場合 (C2/t) や、extdebug/-T が設定されている場合
          はどうだろうか。この場合には結局 C1 が設定した handler を呼び出すのが
          期待される振る舞いなので handler が C1 のレベルに残留していても特に問
          題はない。

      ? trap - RETURN した時に別の文脈で設定された handler をどう処理するべきだ
        ろうか。基本的には自身のレベルよりも高いレベルの物は全て削除するという
        ので良い気がする。然し、別の子関数で設定された物も一緒に削除してしまっ
        ては駄目である。

        例えば A->B->C1 で設定された handler を A->B->C2/t で trap - RETURN し
        た時には

      ? というかそもそも A->B->C1 で handler を設定して、その後で A->B->C2 でも
        handler を設定して最後に trap - RETURN する場合を考えたら、元々
        A->B->C1 に設定した handler は A->B の階層に移動して置かないと問題にな
        るのではないか。

        と思ったがこれに関しては C2 で handler を新しく設定する時に C2 の階層に
        ある handler を B に移動すれば良い? とも思ったがそれだと同じ C2 の呼び
        出しで設定した物と区別が付かない。

      * extdebug や -T についても確認しておく必要がある → 対応した。

    実装した。動いている気がする。FUNCNAME 等が色々面倒な事になるので
    BASH_TRAP_{FUNCNAME,SOURCE,LINENO} という変数も提供する事にした。本当はもっ
    と色々なパターンでテストするべきの気がするが、

      source memo/D1863.RETURN-recursive.sh

    が取り敢えず plain Bash と同様に動くのでそれで良い事にする。

  * trap: EXIT trap が subshell で発火しない [#D1862]

    これは恐らく subshell の中で改めて trap を実行しないと有効にならないのが原
    因である。

    a subshell の中で初めて trap を実行した場合には改めて同じ trap で trap を実
      行する。

    b 現在は trap -p の結果と設定しようとしている trap が同一の場合には trap を
      スキップしようとしているが、そうではなく毎回ちゃんと実行する様にする。

      そもそも同じ trap_command を用いていたからと言って builtin trap の実行を
      省略したとしても、そもそも trap 処理自体そんなに思い処理という訳では無い。
      なので実行を省略せずに単に毎回実行すれば良いのである。

      * done: と思ったが builtin/trap の処理を custom で処理している
        ble/builtin/trap:DEBUG 等の関数についてはどうすれば良いのか。うーん。こ
        れは ble/builtin/trap:DEBUG 等の関数が存在する時に限ってはちゃんと設定
        するという事にすれば良い。

      * ok: 然し、その時に疑問なのは DEBUG や ERR や RETURN の様な関数の外側に
        対して効果を持たないものがどう振る舞うかという事。うーん。これは落ち着
        いて考えたら実は気にしなくても良いかもしれない。

        うーん。trap を関数内で実行した時に外に設定が反映されないかもしれないと
        いうのが以前の問題だった。一方で、今回は余分に trap を実行した時に外に
        影響を与えないかという事である。これは外に影響を与えたとしても与えなかっ
        たとしても結局振る舞いは同じ筈なので問題にならない筈である。

      * done: WINCH 等の様に readline が介入する物についてどうするのか。これに
        関しては subshell で実行している限りは、元々の bash の時点で readline
        の hook が設定されないと思われるので気にしなくて良いのではないか。

        * done: 確認してみたらそもそもそのような trap/hook に対しては subshell
          かどうかの判定を install-hook の時点で行っている。今、新しく trap の
          中でも builtin trap を再設置するという様に変更した時、同様の判定が必
          要になるのではないだろうか。つまり、subshell の外で実行している時には
          readline の介入を破壊しない為に再設置を抑制する。

          subshell の中では元々 readline の介入を期待できない (恐らく) ので気に
          しなくて良い。

    c subshell の中で実行する trap の場合には実は ble.sh による介入は不要になる
      のでは。だとすれば単にそのまま builtin trap すれば良い。

      EXIT は後述の様に EXIT で ble.sh の終了処理をする為に用いている。

      INT はコマンド実行時に ble.sh の処理までキャンセルしてしまわない為に用い
      ている。問題の処理は親シェルで行う物なので subshell の中では特に特別な事
      はしなくて良い。

      % WINCH についても read の中で subshell で使ってはいるが、~~中で改めて設
      % 定を行うので~~ trap は自分では実行しないので問題ない。結局設置済みの
      % trap WINCH から blehook internal_WINCH 経由で処理を行っている。と思った
      % が本当だろうか。本当に read の中で WINCH は呼び出されるのだろうか…と思っ
      % たが、やはり確認してみたところちゃんと read の中で install-hook を呼び
      % 出しているのでやはり改めて設定はしているのだろう。

      WINCH についても親シェルで設定している WINCH への介入を ble.sh でもすると
      いう事はない気がする

      ? 但し、子プロセスが WINCH を受け取って親シェルがそれを逃した場合には何が
        起こるのだろうか?)。

        ble-bind -x C-t 'x=$(sleep 5);echo hello;sleep 1'

        試してみた所、ちゃんと再配置計算が subshell の外で呼び出される様である。
        中で WINCH が呼び出されている気がする。なので子プロセスが受け取ったもの
        を更に自分で親シェルに伝達する等という処理は必要ない気がする。

    上記は b を採用した。

    * そもそも blehook EXIT は親シェルの終了時に呼び出される事を想定して作って
      いた。なので、今 subshell の中でも EXIT trap が走る様に変更すると変な事に
      なってしまう。

      Note: ble/base/unload は ble/builtin/trap/.handler から直接呼び出されてい
      る (#D1797)。他に ble/history:bash/TRAPEXIT が登録されている。逆に言えば
      subshell EXIT では ble.sh による介入は不要である。

      ? blehook EXIT を subshell で使おうと思っても、trap EXIT をユーザーが
        subshell で実行しなければ、そもそも subshell の中では有効ではないのでは
        ないか。なので blehook EXIT は subshell の中で使えない様にするべきでは
        ないのか。

        a うーん。この様に微妙な振る舞いになるのだとしたら EXIT は元よりユーザー
          には提供しないという事にするべきか。でもそれだとユーザーは trap EXIT
          を使わなければならず、一個しか登録できないので自前で色々管理しなけれ
          ばならない。blehook はその管理の煩雑さを解決する為に導入した物なので
          やはり機能として保持したい。

        b 或いは BASHPID 毎に blehook EXIT の内容を記録する事にするか。blehook
          に変更があった場合には改めて builtin trap を実行する。

        c 或いは開き直って blehook SIGNAL は親シェルのみで発火するという事にし
          ても良い。一方で internal_EXIT 等の方については subshell でも実行する
          というので良い。そうでないと WINCH 等の処理ができなくなってしまう。

          ユーザーが subshell で WINCH を受信したいという状況はあるだろうか? と
          思ったが、そもそも subshell に WINCH は元から継承されないし、改めて
          trap WINCH をする事になっている。代わりに、"改めて blehook WINCH を設
          定する" 方式にしたとしても元から存在している hook をどうしたら良いの
          かなど、色々と面倒な事が存在する。という事を考えると、やはり WINCH で
          あっても subshell 内では blehook WINCH を一括で呼び出すという様な事は
          しない事にする。

        うーん。blehook EXIT や blehook INT については c が現実的な気がしてきた。
        もしそうだとすればやはり UNLOAD は不要なのではないかという疑惑。と思っ
        たが物事は単純ではない。

        実際にユーザーに需要がありそうな物は EXIT である (親シェルでしか呼び出
        されないとしても)。一方で、ble.sh の内部処理はユーザーの blehook と分離
        しておきたい。だとすれば internal_EXIT に登録すれば良いのかというとそう
        でもない。何故なら 1) internal_EXIT は EXIT の前に実行されるが、処理の
        順序でユーザーの EXIT を実行する前に ble.sh の終了処理をする訳には行か
        ない。 2) internal_EXIT は今迄の議論だと subshell かどうかに関係なく実
        行するという事になっている。これは blehook EXIT だけでなく通常の trap
        EXIT の処理の前処理でもあるからである。という事を考えると内部処理用の
        unload hook を用意するのが良い。

        →c で実装することにした。

      ? ok: 更に上記の事は INT など他の trap でも同様でないか確認しておきたい →
        うーん。INT の場合に試してみたがどうも C-c を送ると親シェルがそれを受け
        取って処理するのでサブシェルの trap INT は元々呼び出されない様だ。

        つまり個別に考えるべきの気がしてきた。

      * EXIT の代わりに unload という blehook を導入する事にした。今までの終了
        処理は unload で実行する事にして blehook EXIT は trap EXIT と等価な物と
        いう事にする。また ble/base/unload は親シェルの中にいる時だけ
        trap/.handler から呼び出す。

        →と思ったら既に unload は存在していた。しかし誰も使っていない。今まで
        history が unload を使わずに EXIT を使っていたのは何か理由があったのだ
        ろうか。特に理由もないし寧ろ unload で実行するべき気がしたので単にそれ
        を使う様に変更した。

        更に、ble/base/unload の subshell かどうかの判定も、既に
        ble/base/unload の中に存在していた。

    * reject: wiki: EXIT や INT などの blehook は親シェル (main shell) でしか呼
      び出されない。WINCH についても → 改めて確認してみたがそもそも INT や
      WINCH は wiki に記述されていなかった。EXIT は既に記述として Bash が終了す
      る時に呼び出されるとしているので変更しなくて良い。

    ? subshell で本当に INT は継承されないのか?

      % 先程試した時はコマンド置換 $() でしか試していない。
      %
      % $ (trap 'echo INT2' INT; echo do;sleep 5;echo done)
      % do
      % ^CINT2
      % done
      % $ trap 'echo INT1' INT; (trap 'echo INT2' INT; echo do;sleep 5;echo done)
      % do
      % ^CINT2
      % done
      % $ trap 'echo INT1' INT; (echo do;sleep 5;echo done)
      % do
      % ^C
      %
      % →やはり外側の INT は継承されない様だ。
      %
      % 一方で subshell 内部で改めて設定した trap は有効になる。これはコマンド置
      % 換の時とは違う。コマンド置換の時には内側の INT の前に外側の trap が INT
      % を捉えてしまい、コマンド置換自体を別の方法で強制的に終了してしまう。或い
      % は SIGPIPE か SIGTERM が呼ばれていたのかもしれない。と思って色々試したが
      % どうもいかなるシグナルも受信していない様だ。もしかすると単純に sleep 5 が
      % 中断されるだけで続きの物も実行されるのかと思ったらそうだった。
      %
      % $ echo $(for sig in INT QUIT TRAP ABRT PIPE ALRM TERM; do trap "echo $sig >/dev/tty" "$sig";done;echo do >/dev/tty; sleep 5; echo done >/dev/tty)
      %
      % というかその振る舞いは通常の subshell も同じだった。subshell ではなくて一
      % 番上で実行しても同じなのであった。というか sleep を実行中に受信した INT
      % は結局 bash 側では全く処理されないのであった。

      sleep 5 だと sleep が INT を食ってしまって bash の trap INT が呼び出され
      ない事があるのでので正しく振る舞いを調べられない事が判明した。改めて busy
      wait 等を用いてそれに対して INT を送信して試す必要がある。

        # see memo/D1862.INT-in-subshell.sh

        $ set_trap;process_something
        do
        ^CINT

        $ (set_trap;process_something)
        do
        ^CINT

        $ echo $(set_trap;process_something)
        do
        ^CINT
        done
        $ set_trap;(process_something)
        do
        ^C
        $ set_trap;echo $(process_something)
        do
        ^C
        INT (これは単に外側のシェルで発生した trap INT である)

      うーん。直接・サブシェル() の場合には INT で中断する事ができる。コマンド
      置換の時には trap は発動するが kill -INT $BASHPID によって自身を中断でき
      ていない。そして、外部で設定された trap は何れにしても subshell の中では
      発火しない。

        # see memo/D1862.INT-in-subshell.sh

        $ echo $(set_trap; process_something)
        start
        ^CINT
        end

        $ echo $(set_trap; process_something)
        start
        ^CINT
        end

        $ (set_trap; process_something)
        start
        ^CINT

        $ echo $(process_something)
        start
        ^C

      うーん。コマンド置換の内部で INT に処理を追加しつつ自身を中断させる方法が
      謎。trap を設定していなければその場で INT で終了する。trap INT を単に設定
      しただけだと当然 INT による中断は発生しない。一方で trap - INT して kill
      -INT $BASHPID しても何故か何の効果も発生しない。

      これは bash-dev 特有の問題だろうか。調べてみた所、先ずスクリプトでは発生
      せず interactive session で発生する。4.3 まではちゃんとその場で終了する。
      4.4 と 5.0 では何故かコマンド置換はその場で終了するが、裏でプロセスが走っ
      ていて後になって "end" が出力される。5.1 と dev ではコマンド置換の実行が
      待たされる。変な振る舞いだが仕方がない。

2022-08-21

  * blehook: wildcard @ に対応する [#D1861]

    bleopt, ble-face が対応しているのに blehook が対応していないのは混乱の元。
    実際に使いたくなるので対応する。

  * history: blehook history_* を blehook history_onchange に統合する [#D1860]

    history_{delete,insert,clear} は何れも同じ箇所でセットで登録している。だと
    したらわざわざ別の hook にしている意味もない。逆に一貫性を考えたら一つの登
    録で全てを一貫した方法で処理しなければならない。

    統合した hook の名前については結局 history_change にする事にした。結局 on
    をつけ始めたら殆ど全てに on を付けなければならなく成るので余り付けても意味
    がない。同様に history_onleave も history_leave に改名する事にする。

  * util (ble-import): 調整する [#D1859]

    * done: source 時の引数の継承についてチェックする
    * done: 既にロード済みのファイル一覧 --list, --list-imported → これは -q,
      --query という名前で登録した。
    * done: ble-import --help でもっとちゃんとした説明を表示する (wiki も参考)
    * done: wiki update. -f の説明がない。-q の説明も追加する。

  * blehook: ERR 関連の動作が怪しい [#D1858]

    x fixed: 更に ble/builtin/trap 経由で設定した通常の trap が
      ble/builtin/trap 経由で削除できていない気がする。USR2 等、他の通常シグナ
      ルに対してはちゃんと削除できているので、これは EXIT 等の特別 trap に特有
      のバグの気がする。

      取り敢えずこれを最初に修正する事にする。

      振る舞いを調べてみた所、どうやら関数内部から外側の trap ERR を削除する事
      ができない様である。

        $ function trapERR { builtin trap "${1--}" ERR; trap -p; }; declare -ft trapERR
        $ trapERR 'echo trap ERR'; trap -p
        trap -- 'echo trap ERR' ERR
        trap -- 'echo trap ERR' ERR
        $ trapERR; echo x; trap -p
        x
        trap -- 'echo trap ERR' ERR
        $ declare -pf trapERR
        trapERR ()
        {
            builtin trap "${1--}" ERR;
            trap -p
        }
        declare -ft trapERR

      declare -ft をしても駄目だった。set -T でも駄目。bash-dev でも駄目。
      bash-3.0 でも駄目。set -E を設定していれば OK。但し、trap - ERR を実行す
      る瞬間だけ set -E をしていても意味はない。

        $ function trapERR { set -E; builtin trap "${1--}" ERR; set +E; trap -p; }
        $ trapERR 'echo trap ERR'; trap -p
        trap -- 'echo trap ERR' ERR
        trap -- 'echo trap ERR' ERR
        $ trapERR; echo x; trap -p
        x
        trap -- 'echo trap ERR' ERR

      仕方がないので ERR を削除したい時に限っては代わりに空文字列を
      trap string として設定する事にする。

    ? trap ERR を設定すると ble.sh の内部処理に対しても trap が呼び出される。特
      にコマンドが失敗した後の何らかの処理に対して複数回呼び出されている。成功
      したコマンドの後では呼び出されていない様なので、これはちゃんと実装すれば
      回避可能な物なのではないだろうか。或いは ERR の実装を誤っているか。

      また失敗したコマンドに対して重複して ERR trap が実行されているのも気にな
      る。これは調べる必要がある。

      ? というよりそもそもこの ERR は SIGERR と同じ物を意図して追加した物なのだ
        ろうか。zsh の hooks を確認してみると、その下に TRAPERR と TRAPZERR が
        言及されていて、これらは trap の物と大体同一である様だ。つまり各リスト
        に対して実行される。

      うーん。然し、改めて考えて見るにコマンド実行後の ERR の場合に使う ERRと、
      各トップレベルコマンドの設定に使う ERR は区別するべきの様な気がする。どち
      らもあった方が良い様な気がするのは難しいところではある。

      取り敢えず現状の実装では blehook ERR に登録しても SIGERR に対しては発火し
      ない実装になっている。一方で、blehook ERR は SIGERR を誘導する様になって
      いる。

      * done: うーん。ERR がユーザーによって設定されている時に限って builtin
        trap を設定する仕組みを整えたい。install-hook だと強制的に必ず設定を行
        う様になっているが → 実装した。動いている。

      * done: エラーが起こった時に呼び出される hook は ERREXEC に改名する事にする。

      * done: internal_NAME から通常のシグナルの実行をキャンセルする仕組みを整
        える。ble.sh 内部の ERR に対しては user ERR trap を発火しない様にする。

        取り敢えず実装したが bash-3.2 で無限ループになっている。何故だろう。
        と思ったが発火しない処理を追加したら問題は発生しなくなった。

      * done: trap に対して BASH_COMMAND を伝播する。bash-3.0,3.1 はそもそも
        trap による BASH_COMMAND には対応していない様なので設定しなくて良い
        →代わりに _ble_edit_exec_BASH_COMMAND を設定する事にした。

      ? ok: 無限ループの最中に発生した ble/builtin/history: unknown option --
        は何だったのか? 少なくとも history -- 1 等はちゃんと動いている。うーん。
        もしかすると history -xx-yy の様な引数が渡されたという事なのかもしれな
        い。何れにしても今は発生していない問題なので気にしない。

      * done: wiki: blehook ERR を ERREXEC に改名。

        * reject: 改名に関する枠組みを整える必要はあるだろうか? うーん。ble-0.4
          は開発版だし、特に ERR に関しては trap ERR を意図して設定した物と
          ERREXEC を意図して設定した物が混ざって混乱の元なので、改名についての
          提案はしない事にする。

    ? done: history の呼び出しを確認した所 history 1 を builtin なしで直接呼び
      出している箇所があるようだ。確認して修正が必要なら修正する。→これは単純
      な builtin つけ忘れだったので修正した。

    変更点

    * TRAPERR は廃止した。以下の場所で言及があるが廃止された旨をコメントする。
      https://superuser.com/questions/1512618/autocompletion-background-colour-in-ble-sh

    * blehook ERR は trap ERR と分離して ERREXEC に改名した

  * 2022-07-13 blehook: blehook の出力結果を init.sh にそのまま載せている人がいる [#D1857]

    これだと += なので重複してハンドラーが登録されてしまう。

    設定を保存・復元する為に a=$(blehook) として後で eval "$a" する様な使い方も
    考えられるので、最初の項目については += ではなく = にするべきではないか。うー
    ん。然しそれだと後で設定を merge する時に不便なのではないか。色々考えるとど
    うするのが便利なのかは非自明になってくるが、やはり自然な実装という事を考え
    たら設定を完全に復元するのに使えるコマンドという事で、最初の項目が = で追加
    が += という形にするべきである。

  * 2022-07-13 blehook: 内部 hook はユーザーに見えない様にするべきの気もする [#D1856]

    つまり同名の小文字 hook を用意してそちらに登録する。hook の発火については呼
    び出し元で両方とも呼び出す。入れ子にするという手もあるが色々変な事が起こる
    と嫌なので並列にする。

    内部使用の trap について確認する。contrib 等によって設定される物は、ユーザー
    から見えても良いので、除外する。

    * done: blehook DA2R='ble/color/initialize-term-colors'

      これはそもそも内部的に使用する hook であって、全て大文字なのは導入時の偶々
      の決定だった。後で大文字 = public という事になったので、初めから public
      にする意図があった訳では無い。undocumented でもある。なので、これは
      term_DA2R に改名してユーザーからは見えない様にする。

    * done/checked: blehook ERR='ble/builtin/trap/invoke ERR'
    * done/checked: blehook PRECMD='ble/keymap:vi/update-mode-indicator'

      * 実は今まで必ず PRECMD が設定されている事により状態 (PS1) の待避・復元が
        毎回実行されるという事態になっていた。つまり、本来はユーザーによって設
        定された hook もしくは PROMPT_COMMAND がある時にのみ必要だった退避処理
        が毎回実行されていたという事。今回新しく internal_PRECMD と PRECMD を分
        離した事により待避が必要な時にのみ実行される様になった。

        改めて確認した所、待避・復元されている状態は既定では PS1 だけだったので
        大した違いはないかもしれない。但し、bleopt
        prompt_command_changes_layout が設定されている時には再描画等の複雑な処
        理が実行されていた (が、もしユーザーがこの設定変数を設定しているのであ
        れば恐らく PROMPT_COMMAND が設定されているので何れにしても再描画は毎回
        実行されたのだろうという気はする)。という事を考えるとこの事は大した影響
        はなかったと思われる。

    * done/checked: blehook EXIT='ble/history:bash/TRAPEXIT'
    * done/checked: blehook INT='ble-edit/exec:gexec/.TRAPINT'
    * done/checked: blehook WINCH='ble-edit/attach/TRAPWINCH'

    * blehook ERR+='ble/function#try TRAPERR'

      これは削除しても良いのではないか。undocumented でもある。うーん。取り敢え
      ず ERR についての別項目でまとめて対処する事にする。

2022-07-29

  * test: cd -P . / README からリンク for nixpkgs (reported by aiotter) [#D1855]

    - blesh-share を実行するとスクリプトのファイル名が返される。実際に動かそう
      と思うと色々他にも変な所がある。修正するべき。

    - LC_ALL が設定されている…。これは大丈夫なのだろうか→調べてみたが ble.sh
      の関数は全て LC_ALL に対する対策が個別に為されている様なので気にしなくて
      良い。

    取り敢えず cd -P . だけは追加して後は nixpkgs 側は変更を依頼する。所で
    nixpkgs の各パッケージについての問い合わせ方法・問い合わせ先はあるのだろう
    か。maintainer の情報は埋め込まれているが連絡先は書かれていない。

  * edit: display-shell-version (C-x C-v) で /etc/os-release も参照する [#D1854]

    /etc/os-release の中の NAME= と VERSION= を見れば良さそう?

    OpenSUSE は VERSION が何故かコメントアウトされている。PRETTY_NAME はある。
    VoidLinux は NAME=void である。VERSION は存在しない。PRETTY_NAME はある。
    Arch も VoidLinux と似たような物である。
    FreeBSD も実は /etc/os-release を持っている。

    - Solaris は /etc/release を持っているが中身はシェルスクリプトではなくテキ
      ストファイルである。一番最初の行を抜き出して trim したら OS の名称になる
      だろう。

    - Minix にも /etc/release があってこれはやはりテキストファイルだった。然し
      何故か NetBSD 3.3 と書かれている。もしかして Minix は Minix kernel の上に
      NetBSD のパッケージを載せているという事なのか? 調べてみたら Minix 3.2 以
      降では NetBSD technology を導入するという様な記事があった。

      逆に言えば NetBSD でも /etc/release があって一行目にその情報が書かれてい
      るという事だろうか。

    * 取り敢えず OS 名は抽出する様にした。

    * done: 更に待避した locale 変数も元の状態をできるだけ再現する様にして表示
      する事にする。

2022-07-24

  * edit: starship (DEBUG trap) がある時に $_ が正しく復元されない [#D1853]
    https://github.com/akinomyoga/ble.sh/issues/215

    starship で再現。starship の DEBUG trap の処理後に $_ の再設定ができていな
    い。以前に関連する項目があった筈。

    * 現在の実装を見たら DEBUG に関しては lastarg の復元を諦めていて、その他の
      trap の場合には eval に \# つきで渡していた。その他の trap の時に lastarg
      の2行目以降が eval によってコマンドとして実行されてしまうという問題がある
      のではないか。この問題は認識していた筈である。不完全な状態で放置されてい
      たという事だろうか。

    何故今中途半端な実装になっているのか、過去の記録について洗ってみる。

    * ToDo 2022-02-20 に複数行 lastarg に対する処置の方法の可能性についての言及
      がある。と思ったが具体的に heredoc でどの様にこれを再現するのか? 当時何を
      考えていたか思い出せない。

      例えば以下の様な形にするという事を考えていた様な気がする (32 は使われそう
      にない fd)。

        eval 32<<xxx \# xxx
        yyy
        zzz

      然し、この方法も最終行の内容が "単語" の形をしている時にしか使えない。そ
      れに毎回無駄なパイプまたはファイルを開くのは嫌な感じがする。

    * 時期と内容的に #D1782 の対処の時にこの対策を部分的に実装したと思われるが、
      見る限りは #D1782 ではこれについての議論は行っていない。

    * と思ったが blame して確認してみると dfc62211 (#D1757) で変更されている。
      議論 #D1757 のコメントを見たが複数行 lastarg で発生しうる問題については言
      及されていない。この時点 (2022-02-02) では気づいていなかったという事なの
      だろうか。

    結局、DEBUG 以外の trap で複数行 lastarg の場合に問題が起こるのは、単に気づ
    いていなかっただけ + 後で気づいたが ToDo に入れて放置していただけである。

    取り敢えず暫定的な対策としては lastarg の最初の行までだけを復元するという事。
    本当に対策しようと思ったらどの様にするのが良いのかは不明である。(1) DEBUG
    の中で return/continue/break 等の制御コマンドを実行した場合に正しく動作しな
    いか、(2) $_ を正しく復元できないか のどちらかを選ぶしかない。DEBUG の本来
    の目的を考えると制御コマンドは使えないと変である。一方で本来の使い方とは異
    なるおかしな使い方が世に蔓延っている。

  * ble-reload の時に最初に指定した rcfile, norc を反映するべきではないか [#D1852]

    --norc を指定して起動したセッションでも ble-reload をした時に ~/.blerc を読
    み込んでしまっている。

    元の引数を全て保持する様にしようと考えたが微妙かもしれない。というのも、元
    の引数には --norc 等の引数も指定されているかもしれない。これは bashrc の中
    で別に ble-attach を呼び出す事を前提としている物なので ble-reload の時にま
    で継承するべきではない。更に --test や --lib 等の別の引数が指定されていた時
    にもどの様に取り扱うのか微妙である。

    という事を考えると、特定の予め選んだオプションについてだけ記録して再指定す
    るべきである。というか特に blerc だけ復元すれば良い気がする。

  * starship ble-reload で無限ループ (reported by tars0x9752) [#D1851]
    https://github.com/akinomyoga/ble.sh/discussions/212#discussioncomment-3205291

    自分の手許でやってみた範囲では発生していない。starship を先に初期化してから
    ble.sh を有効にしている時に発生する。ble.sh を先に初期化してから starship
    を初期化しても再現しない。source ble.sh --noattach, eval starship init,
    ble-attach, ble-reload の順番で実行しても再現しない。

    nightly を使っているそうなので ble.sh の version の違いではないだろう。

    問題のファイルを開きすぎですのエラーが出ている箇所で関数呼び出しスタックを
    確認してもらった所、以下の様な結果になった。

    | ble/function#advice/before:ble/util/assign
    | ble/function#try
    | ble/function#advice/.proc
    | ble/util/assign
    | ble/builtin/trap/install-hook
    | ble-edit/attach/.attach ble-edit/attach
    | {
    |   ble/base/attach-from-PROMPT_COMMAND
    |   ble/function#lambda/0 starship_precmd
    |   _ble_prompt_update__eval_prompt_command_1
    |   ble/prompt/update/.eval-prompt_command
    | } * 沢山繰り返し
    | ble/base/attach-from-PROMPT_COMMAND
    | ble/function#lambda/1
    | blehook/invoke.sandbox blehook/invoke
    | ble-edit/exec:gexec/invoke-hook-with-setexit
    | ble/prompt/update ble/application/render
    | ble-edit/bind/.tail
    | ble-edit/exec:gexec/.end

    うーん。再帰呼び出しを防ぐ様な仕組みがあった様な気がするがそれはどうなった
    のだったか。改めて確認してみる事にする。うーん。確かにその仕組はあるが、再
    帰的に呼び出した際には再帰的に実行される様である。

    % 自分の手元で改めて再現を試みているが再現しない。starship の他にも更に別の
    % PROMPT_COMMAND を触る設定も読み込んだ時には発生するという事なのではないか。
    %
    % * 再現はしないが何が起こっているかは分かっている。此処での疑問は何故毎回
    %   eval-prompt_command を実行する必要があったのかという事である。
    %
    %   入れ子で呼び出す時に…うーん。これは以前の PROMPT_COMMAND を利用した開始
    %   時刻の判定などの為の可能性もある。改めて過去の議論を確認する。
    %
    % * #D1778 が多少関係しているのではないか。そもそも eval prompt_command を此
    %   処で実行する必要性がよく分からない。
    %
    %   →もし PROMPT_COMMAND 経由で attach が呼び出されるのだとしたら、ここで
    %     eval prompt_command を実行しなくても更に外側で PROMPT_COMMAND の続きの
    %     処理が実行された時に必要な処理が行われるのではないか。然し、これは
    %     PROMPT_COMMAND の後続の設定で PS1 の設定などが行われている時に問題であ
    %     る。更に、PROMPT_COMMAND の中から様々の出力や端末に対する問い合わせの
    %     seq 等を送出するという場合にも問題になるかもしれない。
    %
    %   なので、やはり少なくとも一回は eval prompt_command を此処で実行する必要が
    %   ある。一方で、入れ子で呼び出された回数だけ実行する必要性は謎である。うー
    %   ん。普通に考えて不要に思われる。
    %
    % * 然し改めて再帰呼び出しのコードを見ると save_index を指定して
    %   PROMPT_COMMAND を呼び出している。つまり、save_index による無限ループが発
    %   生しない限りはこの様な事にはならない筈なのである。うーん。不思議だ。
    %
    %   とここまで来て分かった様な気がする。save_index を使っている時は
    %   PROMPT_COMMAND に値を設定して古い PROMPT_COMMAND の実行を行っている。もし
    %   この時に他の PROMPT_COMMAND[] 要素にも値が設定されていたらどうなるか。そ
    %   れらも一緒に呼び出されてしまう。特に starship がそこから既存の
    %   PROMPT_COMMAND を呼び出そうとした時に其処に attach-from-PROMPT_COMMAND が
    %   入っていると無限ループが発生する。
    %
    %   然し、そもそも save_index を使うのは array PROMPT_COMMAND が使えない時で
    %   はなかったか。つまり、bash 5.0 以下。然し一方で starship がもし bash-5.0
    %   以下であるにも拘らずに PROMPT_COMMAND 配列に何か設定した場合には何が起こ
    %   るか? Fedora 36 の starship (1.2.1 2022-02) で
    %
    %     $ starship init bash --print-full-init
    %
    %   の結果を見ても PROMPT_COMMAND は scalar だと思っている様だ。或いは最近の
    %   starship で配列 PROMPT_COMMAND に対応する様になったのかもしれない。
    %
    %   実際に報告によると使っている bash は bash 5.0 の様だ。

    うーん。ここまで来て bash 5.0 で試したら再現した。starship の出力を見る限り
    は別に PROMPT_COMMAND に配列で設定を行っている訳でもない。具体的に何が起こっ
    ているのか確認する。

    何が起こっているのか何となく分かった。最初に

      starship_precmd -> attach-from-PROMPT_COMMAND 0 -> empty

    が設定される。然し、ble-reload の際に

      attach-from-PROMPT_COMMAND 0 -> starship_precmd

    が設定されるが、以前の attach-from-PROMPT_COMMAND 0 が starshop_precmd の中
    に保存されているので starship_precmd がそれを呼び出して、その事によって無限
    ループになっている。

    うーん。unload する時に starship_precmd の中に記録されている前回の attach
    用のコードを除去しなければならないが、それができていないという事。この時に
    どうすれば良いか。。うーん。

    ? そもそも入れ子で attach-from-PROMPT_COMMAND を呼び出す事を許可しているの
      は何故だったか。また入れ子になった呼び出しの各階層における PROMPT_COMMAND
      の書き換えをちゃんと追跡しているのは何故だったか。そもそも複数回の
      install-prompt-attach を実行していなければ複数の
      attach-from-PROMPT_COMMAND が起こる事はないのではないかという気がするが、
      何故その様な事を考慮に入れていたのだったか。

      或いはそれこそ ble-reload をした時に前に設定されていた内容が消滅してしま
      わない様にする為だったかもしれない。つまり、
      _ble_base_attach_PROMPT_COMMAND に格納された元の PROMPT_COMMAND が
      ble-reload した後に使えなくなってしまうと行けないが、PROMPT_COMMAND は既
      に更に別の物によって上書きされてしまっている為に単純に復元できない。その
      時は unload するとしても attach-from-PROMPT_COMMAND はそのままにして、昔
      の _ble_base_attach_PROMPT_COMMAND を引き続き呼び出させる。という具合になっ
      ているのではないか。

      なのだとすると、初期化の際に _ble_base_attach_PROMPT_COMMAND を上書きして
      クリアしてしまうという実装が誤っているという事。

    * check: 元々この仕組は #D1650 (39ebf533) で導入された。然しこの時から既に
      記録用の配列はロード時に空に初期化してしまっていた。本当に当初の意図は複
      数回の ble.sh のロードだったのだろうか。

      →この時の記録を見てみると別に複数回のロードの事を考慮した訳ではなくて、
      単に念の為に「何らかの要因」で複数回設定された時に無限ループを防ぐという
      物だった様に読める。然しその何らかの要因として ble.sh の複数回ロードは想
      定していなかったし、従って複数回のロードに跨って記録配列を保持するという
      事は考えていなかったという事である。

    * done: PROMPT_COMMAND 配列が bash 5.0 以下で設定されている時の対策をする。

      これは報告にあった物とは関係ないがこれも対策しておくべきである。これは
      PROMPT_COMMAND と lambda が一致している場合でも横着せずに毎回
      PROMPT_COMMAND を local 変数として設定して処理する様にした。一致している
      場合には unlocal した後に改めて値を設定し直す事によって処理する。

  * util: starship で ble-reload した後に C-d で抜けると滅茶苦茶沢山のログが出る [#D1850]

    declare が無引数で呼び出されているという事だろうか。ble-reload していない時
    には関係ない。EXIT trap を先ず確認するのが良いだろう → blehook EXIT= とし
    ても同様に問題が生じる。trap - EXIT とすると問題は発生せずに exit する事が
    できる。

    どうも trap handler に "set" という文字列が登録されている様だ。何故? 実際に
    trap handler の配列を見てみると以下の様になっている。

      declare -a _ble_builtin_trap_handlers=([0]="set")

    因みに starship init bash の出力には trap も set も含まれてはいない。うーん。
    実際に値を設定している箇所は一箇所しかない様な気がする。確認する。確認して
    みた所、実際に ble/builtin/trap -- set EXIT という呼び出しが行われている。

    これは元々設定されていたtrapを再設定する時に、元々設定されていたtrapの抽出
    に失敗しているという事だろうか。ble/builtin/trap の呼び出し元を確認すると

      ble/builtin/trap/install-hook

    であった。やはり既存設定の抽出に失敗しているという事だろう → うーん。何故
    か builtin trap -p EXIT の結果が本当に trap -- set EXIT になっている様だ。
    何事だろうか。unload の差異に set を設定する様になっている可能性? というの
    も変な気がする。だとしたら starship と関係ないはず。

    どうも ble/base/unload-for-reload に於いて trap -- set EXIT が設定されてい
    る様である。つまり、元々の trap を設定する際に誤って set を設定してしまって
    いる。

    これは結局単純なミスだった。

  * main, util: make check が nix-build @ macOS で失敗する (reported by aiotter) [#D1849]
    https://github.com/NixOS/nixpkgs/pull/181963#issuecomment-1193125126

    * fixed: 他に sh -c 'echo -n $PID' において echo が -n を特別に解釈していな
      い事によってそのまま出力してしまっている問題があった。これは元々自分の環
      境で動かす事を想定していた為に適当にしていた事が悪い。修正した。

    * done: readlink が期待通りに動作していない。nix-build の外でも発生している。

      うーん。これは readlink が一体どの実装を選択しているのかに依存する。

      * nix-build @ macOS で一体何が選ばれるのか確認したい。と思って実装を確認
        したがこれは実際にどう動作するか確認するまでもなく .resolve-loop 一択で
        ある。なので、.resolve-loop のテストを実行すれば良い。

      * 先ずそもそも $PWD 自体が symlink だった時にどの様に振る舞うべきなのか?
        うーん。これはちゃんと考えていなかった。

        readlink -f の振る舞いを見ると現在のディレクトリがリンクだった時に、そ
        れについても全て解決している。ble/util/readlink の目的を考えると其処ま
        でする必要はないが、実装毎の差異を吸収する為には其処までしなければなら
        ないのだろうか。

        と思ったがこれはテストを実行する時に cd -L . をしておけば良いのでは。
        →というか ble/test/chdir で移動する時に cd -L "..." で移動すれば良い。

      改めて実装を確認してみたが、そもそも実装自体が怪しい気がしてきた。確かめる。

      実際に代替実装の動作を確認してみた所 Linux の上でも動いていない。動作を確認する。

      * fixed: resolve-physical-directory の実装が怪しい。取り敢えず設定されていないか
        もしれない pwd を参照しているのはおかしい。修正は必要だがどの様に修正し
        て良いのか分からない。

        * done: check: mshex の実装を確認する → mshex の実装は古い実装しかなかっ
          た。コメントにある taken from はもう古いので削除するべきなのかもしれな
          い。念の為再度 grep -r で検索してみたがやはり readlink の実装は単純な物
          しかない。

        * done: check: #D1720 以前の readlink の改良の時の議論を参照する。これは
          #D1720 だった。うーん。しかしここには大した説明は書かれていない。元の参
          考にした qiita の記事とその repository も見てみたが、其処にも余りコメン
          ト等は書かれていないし、其処から大きく書き換えてしまっているので参考に
          はならない様だ。結局改めて動作について確認する必要がある。

        恐らく元の resolve-physical-directory の実装で元のディレクトリ名ではな
        くて cd -L . した後のディレクトリ名に移動しているのは、現在ディレクトリ
        が改名された場合等にも正しいディレクトリに戻る為である。実験してみる事
        にする。

        Ref: D1849-cd-physdir.sh

        分かった事。

        1 pwd の結果は最後に cd を実行した時のそのディレクトリのパスになってい
          る。PWD を書き換えたとしても変化しない。また現在ディレクトリが他者に
          よって改名されたとしても変化しない。新しく現在ディレクトリの位置を取
          得し直すという訳では無い様だ。

        2 PWD は cd した時のディレクトリのパスに設定されるが当然後から自由に書
          き換える事ができる。

        また、当然の事ながら PWD の値が信用できるのかという事もある。ユーザーが
        勝手に変な値に設定しているかもしれない。pwd の結果を読み取るという手も
        あるがファイルに一旦書き込んでそれを読み取るというコストがある。なので、
        cd -L . した後に PWD を読み取るというのは確かに一つの手である。

        実装を修正して Note を残しておく事にした。

    * 先ず初めに nix-build environment では locale が全くないという疑惑。元々の
      locale が utf-8 でない上に、そもそも en_US.utf8 を設定するのですら失敗し
      ている。どの locale が利用可能かについて調べてもらう必要がある。

      これはどうしたら良いのか分からない。取り敢えず locale がどうなっているの
      かについて尋ねるのが良い。特に、en_US.utf8 がそもそもないという所を見ると
      locale を正しく設定してもらう所から始まる様な気がする。

2022-07-21

  * 2022-07-06 syntax: "function word1 word2 word3 word4()" [#D1848]

    % word1 がオプション形式の場合何故か word2 まで関数名として認識される。
    % word3 に対して type が走ってエラーメッセージが表示されて表示が乱れる。文
    % 法構造が一体どういう事になっているのか確認する必要がある
    % →どうも関数名として認識される問題とエラーメッセージが表示される問題は独
    % 立な問題の様だ。後、オプション形式化どうかは関係ない。

    * 関数名として着色される問題。以下のコマンドの形の時に再現する。

      $ function aaa bbb()

      どうやら a は文法エラーにはちゃんとなっている。然し、単語着色によって
      FUNCDEF が上書きされている様だ。

      →うーん。分かった。function -t a() と記述すると function -t { a(); } 的
      な解釈になっていて、本来は関数名の直後には複合コマンドしか来れないが、コ
      マンドがそのまま来てしまっていると解釈されている。一方で、コマンドが来て
      は行けない文脈であってもコマンドとしての単語着色が有効になってしまってい
      るのがいけない。

      然し、本来文法的に其処にコマンドが来ては行けない文脈に於いては単語着色も
      有効にならない筈なのに有効になってしまっているのは何故か。例えば "if
      true; then false; fi echo" とすると echo は文法エラー的なコマンドであり、
      そしてちゃんとエラー着色のままである。

      うーん。通常のエラーの場合には単語の種類自体が _ble_attr_ERR になっている。
      関数定義の場合にはそれを上書きして消去してしまっているのが原因?

    * エラーメッセージは auto-complete の中で発生している様である。

      $ function aaa bbb ccc ddd

      ddd を入力している時に "ccc" に対してコマンドではないというエラーメッセー
      ジが発生する。

      →これは結局最終的には bash-completion の _function が悪かった。これはま
      た別に bash-completion に出す。

      但しそれとは別にそもそも function aaa bbb ccc ddd に対して "function ccc
      ddd" に対する補完を試みているという事も変ではある。

      a そもそも bbb がエラーになっているのだから、extract-command の時点で bbb
        をコマンドとするtべきなのでは?  然し、その他の別の理由でエラーになった
        単語が含まれているかもしれない。なので bbb をコマンド名と解釈するのも変
        である。

        望ましいのはやはり "bbb ccc ddd" に対して補完が実行される事であるが、そ
        れを正しく実行する方法はあるだろうか。うーん。やはり extract-command で
        エラー単語をスキップせずにコマンドとみなす方法しかない? 然し、エラー単
        語が文法的に引数を取らないコマンドに指定された引数の可能性もある。例え
        ば、[[ ]] aaa や (( )) aaa など。

      b 現在は aaa を単語として登録していない。然し、aaa も単語として登録する様
        にすれば良いのでは? 然しそうだとしても "function aaa ccc ddd" に対して
        補完が試みられる事になって結局不自然である事に違いはない。

      うーん。或いはエラー単語も全て extract-command で生成する引数に含めて、更
      に関数名も単語として登録して一緒に抽出する様にする? その方が自然の気がす
      る。

      と思ったが echo hello (aaaa) bbbb 等の場合にはどの様にするべきだろうか。
      実際に現在どの様に抽出されているかを確認してから考える。

    * 2022-07-16 改めて考えるに bbb を単なるエラー単語としてではなくエラーコマ
      ンドとして登録するべきの気がする。

      →どうやら wtype を ATTR_ERR にしているのはコマンドの文脈しかない様である。
      なので extract-command で ATTR_ERR が見つかったらそれをコマンドとして取り
      扱って良いのではないだろうか。(或いは、ATTR_ERR ではなくて別の新しい分類を
      作った方が分かりやすいだろうか。)

      更に "[[ ... ]] word" の様な場合には attr には ATTR_ERR を設定していたが
      実は文法的にはエラーとしていなかった為、word が既存のファイル名に一致した
      りするとエラー着色が解除される等していた。取り敢えず現在の所は此処も新し
      いコマンドが開始する物として良い様な気がする。他に ARGX0 が設定される文脈
      はあるだろうか

      a 新しく CTX_CMDX0 を導入して概ね CTX_ARGX0 と同様に取り扱う。wtype に
        CTX_CMDX0/CTX_ARGX0 を設定する? 着色は ATTR_ERR のまま。extract-command
        では CMDI, ARGI の他にこの CMDX0 と ARGX0 も考慮に入れる。

        うーん。CTX_ARGX0 は設定する必要ない?

      ? wtype で CMDI と CMDX0 を区別する必要はそもそもあったのだったか

        →CMDI だと普通に着色を実行してしまう気がする。では単に全て CMDI とい
        う事にして、attr が ERR だったらコマンド着色をスキップするという手も可
        能なのではないかという気もする。うーん。然し単語情報と attr は格納位置
        が異なるし、現在の実装では恐らく単語の判定に元々の色を参照している例は
        ない。単語に内部構造がある場合等も考えると余り robust でもない様な気が
        する。

        やはり取り敢えずは CMDX0 を使って単語自体を区別する様にする。

      * 取り敢えずは CMDX0 を定義する事にする →定義した。

      * lib/core-syntax.sh:3711: elif ((ctx==CTX_CMDXE)); then で ctx=CTX_ARGX0
        を設定している。この文脈は { { echo; } >/dev/null } 等の文脈である。こ
        の } は CTX_ARGX0 ではなくて別の文脈で読み取るべきの気がする。

        やはり CTX_CMDX0 的な物を新しく導入するべきだろうか。その方がすっきりす
        る様な気がする。

        その場合には現在の ARGX0 を指定している箇所の多くは CMDX0 に変更した方
        が良いのかもしれない。例えば (()) ... や () ... や [[ ]] ... 等。うーん。
        本当だろうか。これらはやはりそのままで良い気がする。但し補完は発生しな
        い様にしなければならない。

        2022-07-20 うーん。今改めて確認した所 redirection で別にエラーになって
        いる訳でもない。うーん。どう修正したのだったか確認する。CMDX0 にしてい
        る。なのに何故エラー着色が消えているのだろうか。

        2022-07-24 現在はちゃんとエラーコマンド・エラー着色になっている。制御構
        造の終端としても取り扱わない様にしている。これで良いと思われる。

      ? ok: CPATX0 についてはどうするのか。これについてもちゃんと考えておきたい。

        →これは特に今まで通りで問題ない。元々 wtype = ATTR_ERR を設定した単語
        をコマンド名として extract-command するとした案の時に問題が起こる可能性
        を考えていた。然し今は CMDX0 を新しく導入して、エラーコマンド名に関して
        は wtype として CMDX0 を使って区別する事にした。なので、CPATX0 の単語に
        対して ATTR_ERR で単語登録しても問題は生じない。

      ? ok: エラーコマンドに対して補完は実行するのか? →これは補完しない様にす
        るのが自然の気がする。

        →現在はコマンド名は補完しない。一方でエラーコマンドの引数に関しては、
        エラーコマンドのコマンド名に従って引数補完を実行する様になっている。こ
        の振る舞いで良いだろう。

    * aaa を単語として登録するかどうかはまた別の問題で、これは function aaa
      [TAB] とした時の補完を progcomp で提供するかどうかという事に関係して来る
      様な気がする。

      * bash-completion は既存の関数の内容を挿入する事になっているが、その他の
        物を挿入したいという可能性はあるだろうか。他にない気がするので現在の関
        数定義を挿入するという事で決め打ちで良い気がする。

      * また関数定義は複数行からなるが、現在の progcomp の仕組みだと複数行の候
        補は全て分割されてしまうので、何れにしても bash-completion を使ってもちゃ
        んと動かない。これを回避するには compgen を自前で実装し直すしかない様な
        気がする。或いは compgen -0 の patch が取り込まれれば新しい bash では大
        丈夫になる。然しそれはまた独立な話題である。

      * またこの方針だと func() [TAB] の時に同様の機能を提供できない。

      そう思うと補完は progcomp とは別に実装するので良い気がする。そして、もし
      そうするのだとしたら aaa を単語として登録する意義は薄いのではないか。これ
      は func() [TAB] 及び function func [TAB] の補完の実装時に考えれば良い事で
      ある。

2022-07-13

  * mandb: ls のオプションの抽出がおかしい [#D1847]
    https://github.com/akinomyoga/ble.sh/issues/204#issuecomment-1181790000

    * fixed: 手許でも具体的な振る舞いは異なってはいるが ls の man 情報の抽出が
      ちゃんとできていない。日本語の説明が混入してしまっている。

      実際生成されているキャッシュの man.d/ls を確認すると誤った位置で引数が抽
      出されているのを確認できた。確か、空白が2個以上などの条件で分離していたが
      それがいけないという事なのではないか。当該箇所を確認してみる事にする。

      うーん。途中で出力してみるとどうやら man を変換した時点で変な位置に
      __ble_desc__ が挿入されている様である。元の groff ソースを見ると以下の様
      になっていた。

      | .TP
      | \fB\-\-time\fR=\fIWORD\fR            \fB\-l\fR と併せて使用し、デフォルトのファイル更新時刻の代わりに
      | WORD で指定した時間を表示する: atime/access/use (\fB\-u\fR),
      | ctime/status (\fB\-c\fR)。
      | \fB\-\-sort\fR=\fItime\fR を指定した場合はソートのキーとして
      | 指定した時間が使用される

      つまり変な形式で man が書かれているのが原因である。取り敢えずこれには対応
      した。動いている。

      x fixed: と思ったがやはり動いていない。うーん。"-" を入力してから補完する
        時には問題は発生しないが、空文字列から生成すると問題が発生する。キャッ
        シュは man.d/ls は問題ないが ls に問題がある。これは合成して新しく ls
        を作る時に問題になっているという事だろうか。と思ったら
        _parse_help.d/ls.00000000000000 が問題であった。つまり _parse_help への
        介入の解析が問題。問題になっている ls --help の出力の行は以下の形をして
        いる:

        |      --author               -l と合わせて使用した時、各ファイルの作成者を表示する

        うーん。これも空白が3個以上間にある時は説明とオプションの境界と解釈する
        などの対処が必要になるだろうか。

      x fixed: 更にこれでも変な物が抽出される。以下の物が抽出されている様だ。

        |                               -l と使用した場合、名前でソートし、アクセス時間を表示する。

        空白が単一であったとしても後に続く文字列に [、。] が含まれている場合に
        はオプション引数として解釈しない様にした。

      x fixed: 然しこの様にしても、今度は -l の説明がこの偽物の説明で上書きされ
        てしまっている。本当は以下の説明が抽出されて欲しい。

        |  -l                         詳細リスト形式を表示する

        複数の同じオプションがある場合にはインデントの最も小さい物を選択する様
        にしたい → L4510 で uniq している所を何とかしたい → 取り敢えず一旦
        indent の情報と一緒に全部記録して最後に出力する様に変更した。同じ名前の
        オプションの説明があった場合は indent の小さい物を優先させる。

    * 補完設定の違いによる cache の違い

      というかそもそも日本語で表示されたり英語で表示されなかったり一定していな
      いのも変である。man/help のどちらかが優先されるのだとしたらちゃんと両方と
      も表示されるべきである。うーん。bash-completion 経由で初期化すると --help
      の説明を抽出する形になって、built-in completion だと man page が優先され
      るのが違いの原因の様である。問題はキャッシュが後々に残ってしまうという事
      にある。キャッシュを生成する時にちゃんと両方を個別に記録して後に合成する
      必要があるのではないか。

      % と思ったが今確認してみるとちゃんと bash-completion の有無で補完の説明が
      % 異なるし、オプションの説明の切り出しも変な事にはなっていない。問題がど
      % のような条件で発生するのか確認する必要があるのである。と思ったが
      % LANG=C.UTF-8 にしていたのだった。LANG=C.UTF-8 にしている時には日本語の
      % 説明がオプション引数の部分にくっつく等の事は起こらず、ちゃんと抽出でき
      % ている。

      うーん。他にも変な現象が起こったりしていた様な気がするが、これは古い
      ble.sh で動作している session も書き換えているからなのではないかという気
      もする。これについては以前考察した筈なのでまた改めて考察はしない事にする。

    * ok: 何故か最初の menu の列だけ sep の " : " が挿入されていない。謎。と思っ
      たが、これは単にとても長いオプション名がその列に含まれているからというだ
      けの様だ。気にしなくて良い。

    * fixed: __ble_decode__ の切り分けの失敗がどの様に起こるのかは気になる。改
      めて実装を確認してみるとどうも __ble_desc__ が行の途中に埋め込まれる様な
      状況は想定していない?

      うーん。mode == "key" の途中で __ble_desc__ が現れる事も原理的にあるし、
      また mode == "desc" の途中で __ble_key__ が現れる事もある。→実装してみた
      が検証のしようがない。というか面倒である。取り敢えず既存の物がちゃんと動
      いているかどうかだけ確認する。

    取り敢えず安全側に倒した実装に変更したので動く様になっていると考えたい。他
    の可能性として \b を使って上書きする事により太字を再現している場合に、太字
    になっている __ble_desc__ や __ble_key__ を検出できないという可能性もあるが、
    下手に対策して逆に動かなくなるケースがあっても嫌なので、それは実際に起って
    から考える事にする。

    * というか、単に修飾を外してからマッチさせる方法だと、実際に欲しい着色や太
      字の修飾が外れてしまうので、修飾を外す前の文字列を正規表現で一致させなけ
      ればならない。だとすると ble に対して b(\bb)?l(\bl)?e(\be)?  等の様にしな
      ければならない。なのだとすれば、逆に動かなくなるケースもない様な気がする。
      とは言いつつ実際にあるかも分からない事例に対して実装するのも変な気がする
      ので現状のままにする。

2022-07-12

  * ble.sh built-in completion で既定でオプションを補完するが他の候補よりも前に来るので邪魔 (reported by geekscrapy) [#D1846]
    https://github.com/rsteube/carapace-bin/issues/1219
    https://github.com/akinomyoga/ble.sh/issues/204

    % と思ったが、よく考えるとそもそも空文字列でオプションも含める様にしたのは
    % ちゃんと絞り込みで候補を絞った時にオプションも表示する様にする為だった。
    % 空文字列での補完に対してオプションを生成しなかった時に何が起こるのか改め
    % て確認する必要がある。

    改めて確認したが別にオプション名はソートによってファイル名よりも先に来てい
    るのではなく、単に生成する順序に従って先に来ているだけだった。"-" で始まる
    補完の時にはオプションを先に表示して、空文字列に対する補完の時にはファイル
    名よりも後にオプションを生成する様に変更した。

    * 2022-07-12 空文字列からの補完によるオプション生成の時は説明を表示しない。
      https://github.com/akinomyoga/ble.sh/issues/204#issuecomment-1181743592

      これは本当はその内に詳細に設定できる様にしたいが、色々考えてから実装した
      い。然し、今回の場合は確かにその方が良さそうな気がするので既定の動作とし
      て採用してしまって良い。

  * kitty の keyboard protocol を terminal multiplexer 越しに有効化する (motivated by ferdinandyb) [#D1845]
    https://github.com/akinomyoga/ble.sh/issues/209#issuecomment-1179994203

    取り敢えず一番外側の kitty に送るのは実装した。

    ? pane を切り替えた時に kitty の keybaord protocol が有効になったままになる
      事によって問題が発生するのではないか。更に途中で detach した時にも問題に
      なるのではないか。

      % →これに関しては kitty keyboard protocol は普通のキー操作 (C-b など) に
      % ついては通常通りに送信して、C-S-a 等の従来のシーケンスで区別できなかっ
      % た物だけについて異なるシーケンスを送る物の筈だから問題ないのではないか。
      % 一方で通常の modifyOtherKeys に関しては深刻な問題が起こるのでこの方法は
      % 使えない。
      %
      % これは本当にそうなのか確認する必要がある。一応試した感じではそうだった様
      % な気がする。改めて確認する。
      %
      % →これは確かめて見た所駄目だった。

      つまり、中途半端な状態で抜けると外に抜けた時にまともに操作できないという
      事になる。特に kitty は keyboard protocol に関して push/pop を数えている
      ので外側が ble.sh だったとしても駄目な事になってしまう気がする。

    ? 端末マルチプレクサにも modifyOtherKeys を送るべきだろうか。これについては
      端末マルチプレクサの振る舞いによる。もし tmux が受信したキーシーケンスを
      翻訳して単純なキーシーケンスしか送らない様にしてしまうのであれば tmux に
      もちゃんと modifyOtherKeys を送る必要がある。一方でもしそのまま通過させる
      のであれば特に設定は必要ない。

      これについても tmux, screen の両方について振る舞いを確認する必要がある。

      * うーん。tmux について ble.sh なしで直接 printf して振る舞いを確かめよう
        としたが tmux 自体が何かを送信しているせいか kitty の設定が解除されてし
        まっている? よく分からないので ble.sh つきで確認する事にする。

        と思ったがどうやら tmux は extended-keys を on にしても always にしても
        kitty の送ってくるキーを正しく認識する事ができない様だ。kitty は余分に
        flag 128 を加算している為に tmux が解釈できない function key
        modification と判断して裸の文字にしてしまう。例えば C-r を入力すると
        133=128+4+1 という function key modification になるが tmux はこれを解釈
        不能として 0 にしてしまう。結果として唯の文字である "r" が入力される事
        になってしまう。

      * screen に関しては完全に透過してしまうので modifyOtherKeys 的な入力を
        ble.sh で受け取るのには問題ない。然し、逆に screen が modifyOtherKeys
        に全く対応していないので、外側の kitty の設定が全ての window に対して適
        用される事になる。つまり window を切り替えた時に ble.sh の外側と内側の
        齟齬があると全く動かないという事になる。

        うーん。これは実験的機能として封じて置く必要があるだろうか。

    * tmux に伺いを立ててみる必要があるのではないか。

      * 一方で kitty に関してはどの version からこういう事をするようになったの
        かの確認もしておきたい。或いはずっと前からこの様にしていたのだろうか。
        過去の version をコンパイルするのは面倒なのでソースコードの変更履歴を追
        う必要がある。

      取り敢えず tmux のソースコードを確認してみる。一体何処でこれを処理してい
      るのか。これは意外と簡単に見つかった。然し疑問点が幾つかある。

      * 7 の時だけ IMPLIED_META を付加していないのは何故か。
        https://github.com/tmux/tmux/blob/dc6bc0e95acc04cdf43e869294ecba897a11d850/tty-keys.c#L954

        うーん。IMPLIED_META の説明を読むとどうも ESC による Meta と function
        key modification Alt による Meta を区別する為という様に見える。という事
        を考えると、modifiers 7 で IMPLIED_META が抜けているのは単なるミスでは
        ないか。
        https://github.com/tmux/tmux/blob/dc6bc0e95acc04cdf43e869294ecba897a11d850/tty-keys.c#L114-L118

        更にこちらの配列ではちゃんと IMPLIED_META が付加されている。
        https://github.com/tmux/tmux/blob/dc6bc0e95acc04cdf43e869294ecba897a11d850/tty-keys.c#L258

      * 9 に対しても Meta を付加しているが元からそういう物だったか? 9 は super
        なのではないか。これはもしかすると古い DEC のマニュアルの間違いを引きずっ
        ているのかもしれない。後で調べる必要がある。

        →恐らく問題の変な割当をしているのは xterm のマニュアルだったと思ったが
        今確認すると 8 しかない。という事は 9 は一体何処から出てきたのだろうか。
        他の端末でこの辺りをもっと aggressive に parse していた物がある筈。例え
        ば iTerm2 か vte だった様に思う。それらの実装も確認する必要がある。

        うーん。然し他にもこの様な変な事をしている端末がある様な気がする。

        * vte について調べてみたがこれは 0,2-8 を hardcode していた。
          super/hyper も認識していない。

        * iterm2 については以下の部分で flag を生成している?
          https://github.com/gnachman/iTerm2/blob/698b83ec79d882ee5acb25b7e358680f9db47e01/sources/iTermRawKeyMapper.m#L48-L83

          と思ったが色々と様子がおかしい。lshift, rshift, loption, roption,
          lcontrol, rcontrol,... という具合に bit を割り当てている。これだと滅
          茶苦茶にずれるのではないか。

        * xterm について確認するのが良い気がする。と思ったらここにちゃんと表が
          ある。そして 8 は Meta という事になっている。
          https://github.com/ThomasDickey/xterm-snapshots/blob/13e30fcb98357d456660fdfc74fc86725a49934f/input.c#L358-L373

          向こうにはこの表を提示しておけば良いだろう。

      * kitty の実装について確認を取る。ソースコードが滅茶苦茶なので何処に何が
        あるのかよく分からないがようやく見つけた。どうやら 128 は NumLock だった様だ。
        https://github.com/kovidgoyal/kitty/blob/4c2800b294a4b1189a6f0dfaa236f52d5380bb70/kitty/key_encoding.py#L290
        https://github.com/kovidgoyal/kitty/blob/4c2800b294a4b1189a6f0dfaa236f52d5380bb70/kitty/key_encoding.c#L55-L61

        * done: numlock を解除したらちゃんと普通の数字の範囲で値を返してくれるという事が分かった。

        さてこの numlock がいつ実装されたのかというのを調べてみると 2021-04 で割合最近だ。
        https://github.com/kovidgoyal/kitty/commit/4c644b855649f9de29be4feac89cfeae1b981541

      * mintty で modifier の割当をどうしているのかも確認しておく
        https://github.com/mintty/mintty/blob/b939fa6231ab7f9b5606821135e63d0d22ee3b2e/src/config.h#L7-L8

        | vte    | S, M, C                             |
        | xterm  | S, A, C, M                          |
        | mintty | S, A, C, Win, s, H                  |
        | kitty  | S, A, C, s, H, M, CapsLock, NumLock |

        これについて contra の escseq.html にも追記しておく事にする。

      取り敢えず tmux に変更を提出しておいた。好感触なので何れ merge されるだろう。

    * done: wiki: set -g extended-keys について記述する
    * done: wiki: 新しいオプションについて記述する。注意事項も含める必要がある。
    * done: blerc: 新しいオプションについて記述する。

  * wiki: named prompt sequences についても記述するべきなのではないか [#D1844]

    ./keymap/emacs.sh:138:function ble/prompt/backslash:keymap:emacs/mode-indicator {
    ./keymap/vi.sh:512:function ble/prompt/backslash:keymap:vi/mode-indicator {
    ./src/edit.sh:1016:function ble/prompt/backslash:position {
    ./src/edit.sh:1024:function ble/prompt/backslash:row {
    ./src/edit.sh:1031:function ble/prompt/backslash:column {
    ./src/edit.sh:1038:function ble/prompt/backslash:point {
    ./src/edit.sh:1042:function ble/prompt/backslash:mark {
    ./src/edit.sh:1046:function ble/prompt/backslash:history-index {
    ./src/edit.sh:1050:function ble/prompt/backslash:history-percentile {

    取り敢えずユーザーも使える事を想定したものは記述した。vim-airline の物は本
    来内部使用を意図して実装された物なので省略。

  * vi: status_line ではなく mode indicator 自体を変更する方法を与える (motivated by ferdinandyb) [#D1843]

    mode indicator の部分をプロンプト設定として提供する事にした。

    * done: うーん。vi のモードが変わった時にしか更新されないので、モード以外の
      情報を表示しようとしても次にモードが変更される時にしか更新が走らない。
      仕方がないので PRECMD に update-mode-indicator を登録する事にした。
    * done: emacs の方も同様に設定できる様にするべきの気がする。

    * done: blerc, wiki に記述
      * done: wiki: prompt_emacs_mode_indicator
      * done: wiki: prompt_vi_mode_indicator
      * done: wiki: pointers to prompt_*_mode_indicator in §Edit

2022-07-11

  * term: kitty の keyboard protocol が有効になっていなかった [#D1842]
    https://github.com/akinomyoga/ble.sh/issues/209

    返信を書いている時に kitty の振る舞いを確認していて気づいたのだがちゃんと
    kitty Keyboard Protocol が有効になっていなかった。"push keyboard mode" の分
    岐の条件が反転していた。

2022-07-10

  * complete: "g add newdir/z[TAB]" とするとファイル名が消える [#D1841]

    % 既に登録されているファイルの場合には問題は起こらない様だ。既に登録されて
    % いるファイルがあるディレクトリの中の新しいファイルであっても、そのファイ
    % ルが登録されていない場合にはやはりファイル名が消える→というか改めて試し
    % た所既に登録されているファイルでもやはりファイル名が消える。

    "git add newdir/z[TAB] " の時には問題は生じない。

    これは分かった。COMP_POINT が正しく更新されていない。

      declare -- COMP_LINE="git add lib/i"
      declare -- COMP_POINT="11"
      declare -a COMP_WORDS=([0]="git" [1]="add" [2]="lib/i")
      declare -- COMP_CWORD="2"

    そしてこれは comp_line,comp_point の更新が正しく出来ていない事によると思わ
    れる。と思ったがそうでもない様だ。comp_line, comp_point の時点では変な事に
    はなっていない。つまり最初のコマンドを差し替える時点で COMP_POINT を更新す
    るのを忘れているという事。うーん。と思ったが

      declare -- comp_line="g add lib/i"
      declare -- comp_point="11"
      declare -a comp_words=([0]="git" [1]="add" [2]="lib/i")
      declare -- comp_cword="2"

    となっていて comp_words と comp_line で不整合が生じている。コマンド名を置き
    換える時にちゃんと comp_line, comp_point も置き換える様に修正した。

      declare -- comp_line="git add lib/i"
      declare -- comp_point="13"
      declare -a comp_words=([0]="git" [1]="add" [2]="lib/i")
      declare -- comp_cword="2"

    * 実装してから思ったが単に .compline-rewrite-command を呼び出せば良いだけで
      は。→その様に書き換えた。ちゃんと動作しているのでOK。

  * command-help (ble/widget/command-help/.read-man): ble/util/assign/.rmtmp を忘れている [#D1840]

    0.2 backport 中に気づいた。これは単純に追加すれば良い。

  * encoding:C: 初期化出来ない。大量のエラーメッセージ [#D1839]

    0.2 backport 中に気づいたのだが encoding:C で既に削除された関数
    ble/init:bind/bind-s が使われている。実際に input_encoding=C にして開始して
    みると大量のエラーメッセージが表示されて変な文字列が入力される。
    これは単に改めて関数を追加する事にした。

  * complete: zoxide completion が動かない (reported by ferdinandyb) [#D1838]
    https://github.com/akinomyoga/ble.sh/issues/207

    zoxide も fzf と同様の戦略を用いている。

    * ok: zoxide については (以前試した時の fzf と違って) stdout/stderr をちゃ
      んと繋ぎ変えている様だ? 或いは単に中で呼び出している最新の fzf が
      stdout,stderr を /dev/tty に繋ぎ変えているだけかもしれないが。

    * ok: zoxide は中で \builtin bind や \builtin printf を用いているので振る舞
      いを上書きするのは困難である。builtin を上書きしようにも \builtin local
      も使われている事からこれを関数の中で実行する訳にも行かない。

      或いは printf, bind を enable で一時的に削除するという事も可能かもしれな
      いが色々テストするのが面倒である。

      というより stdout は封じているのだし、bind は特に悪さをするという訳でもな
      い様な気がするので単にそのまま放置していても特に問題は起こらないのでは。
      →取り敢えずそのままにしておいても特に問題は生じていない様な気がする。

    x 生成した候補がちゃんと反映されない。何故だろうか。

      と思ったら分かったかもしれない。何か端末に送信している為に端末からの返答
      が届いていて is-stdin-ready に引っ掛かって補完がキャンセルされている。

      % うーん。そしてそれは恐らく 1 ではなくて独自に開いた /dev/tty 経由で送信
      % されているので抑制する方法がない。

      % → \builtin printf をコメントアウトしたら動く様になった。というか既定で
      % は stdout/stderr は抑制していなかった様な気もする。然し、builtin printf
      % を抑制する方法がないので困る。と思ったが全体を >/dev/null としてしまえ
      % ば良いのでは? 実際にその様にして見たら動く様だ。

2022-07-09

  * fzf kill completion が動かない (reported by ferdinandyb) [#D1837]
    https://github.com/akinomyoga/ble.sh/issues/206

    実際に動かしてみると確かに動かない。呼び出し時の ADVICE_WORDS 及び COMP_*
    の値についても確認してみたが特に違いは見られない。もう一つの違いは呼び出し
    後に COMP_WORDS が書き換えられているという事。

    うーん。_fzf_complete_kill の実装を確認してみると COMP_WORDS を書き換える事
    になっている。つまり、何故か書き換えたか或いは書き換えたのにそれが反映され
    ていないという事になる。もう少し詳しく振る舞いを調べてみる事にする。

    →うーんちゃんと書き換えは発生している。しかし折角書き換えたのにその後でま
    た状態が元に戻ってしまっている様だ。と思ったら分かった。advice を付加した関
    数を入れ子で呼び出しているので、外側で設定した COMP_WORDS が内側で呼び出さ
    れる時に上書きされてしまう。COMP_WORDS が上書きされる事を想定していなかった
    のが原因である。

    x fixed: それでも未だ動かない。と思ったら内部で caller 0 を呼び出している。
      advice を付加した事によって caller がずれているという事。caller のずれは
      修正した。実に 5 段も余分に実行している様だ。更に caller 自身の置き換えも
      含めて 6 段先の caller を参照する事にする。

    x fixed: それとは別に何故か ps で生成しているプロセスのリストの代わりに現在
      のディレクトリ以下にあるファイルのリストが表示されている。

      と思ったが分かった。_fzf_complete の場合は標準入力に候補を流し込んでいる
      事があるので、勝手に /dev/tty に書き換える訳には行かない。使用箇所を確認
      してみた所、_fzf_complete の場合には常に標準入力に対して候補を流し込む使
      い方しかしていない様なので、_fzf_complete の時は標準入力はそのままにする
      事にした。取り敢えず動いている。

2022-07-08

  * history: HISTFILE が空の時は履歴ファイルは無効化する [#D1836]

    HISTFILE が設定されていない時は既定の位置 (.bash_history) に書き込むのでは
    なくそもそも履歴ファイルが無効化される様だ。今まで .bash_history に対して読
    み書きしていたのを修正する。

  * 整数が IFS に含まれている可能性もあるので ${#...} や $((...)) や >&$fd も quote する [#D1835]

    redirection も word-splitting の対象である。今まで数字は空白でないから大丈
    夫と考えていたが IFS に数字が含まれている可能性もある。ble.sh は内部では
    IFS を調整しているとは言え、ユーザーから呼び出した場合なども考えると一律で
    ちゃんと quote する様にするべき。

    grc '[<>]&\$'

    実は $(()) も同様である。現状では $(()) は数字だから quote しなくて良いと考
    えて裸で記述しているが、やはり任意の IFS の可能性を考えると quote するべき
    である。これは物凄く沢山ある。

    grc ' \$\(\('


    grc '([ (])(\$\(\(([^()]|\([^()]*\))*\)\))([; )]|$)' --exclude=docs
    grc '( |=\()(\$\{#([^{}]|\{[^{}]*\})*\})([; )]|$)' --exclude=docs

  * complete: command_not_found_handle が自動補完で呼び出されて操作不能になる (reported by telometto, wisnoskij) [#D1834]
    https://github.com/akinomyoga/ble.sh/issues/203
    https://github.com/akinomyoga/ble.sh/issues/192

    stdin に [y/n] を要求するが ble.sh が stdin をブロックしている為に補完が終
    了できず操作不能になる。

    ? というか入力が受け付けられなくなったとしても C-c だけは効く様にして良いの
      ではないか。

      x 一方で、C-c をそのまま有効にすると ble.sh の処理自体がその場で止まって
        しまう事になる。C-c を trap で捕まえて適切な stack frame まで戻るにして
        も再び DEBUG トラップで複雑な事をしなければならない。

      x そもそも外部コマンドの C-c を正しく検出できるのかという問題もある。C-c
        で外部コマンドだけが終了したとして、その後補完スクリプトがそのまま走っ
        た時に変な事にならないかというのは非自明である。

      x 更に補完の度に stty を呼び出して C-c の状態を変えなければならない。失敗
        すると次に stty を調整する迄 C-c を ble.sh で受信できなくなる。

      うーん。色々考えると C-c を一時的に有効にするというのも余り良い選択肢では
      ない様に思われる。取り敢えずは command_not_found_handle を一時的に無効に
      するしかない。

    * bash-completion の側でも修正するべきか。もし plain Bash では progcomp の
      最中には command_not_found_handle が無効化されるという事であれば
      bash-completion の側で修正は必要にはならない。

      command_not_found_handle() { echo "$FUNCNAME is called"; }


      既に bash-completion で報告されていないか確認する。

      https://github.com/scop/bash-completion/pull/390

      ここで既に議論されている。scop は upstream bash に request できないかとい
      う事を提案している。他にも色々の箇所でそういうのがあるとも述べている。

      と言っても将来的に Bash の側で off にする機能ができるとしても、古い Bash
      は依然として存在するので取り敢えず個別に対応していくべきなのではないかと
      いう気がする。

    取り敢えず command_not_found_handle は function#push する事にする。

    * 2022-07-09 未だ直っていないという (reported by telometto)
      https://github.com/akinomyoga/ble.sh/issues/192#issuecomment-1179191747

      先ずは PackageKit をインストールして動作を確認しようと思ったら既にインス
      トールされている。然し /etc/profile.d/PackageKit.sh を確認してみても存在
      していない。dnf search で検索してみると PackageKit-command-not-found とい
      うのがあったのでそれを入れてみると入った。再現した。

      確かに command_not_found が呼び出されて固まっている。然し、
      command_not_found は一時的に無効化している筈。command_not_found_handle の
      中から呼び出しの構造を調べてみた所、どうやら ble.sh が独自に
      __load_completion を呼び出していてその時に command_not_found_handle が走っ
      ている様だ。つまり、__load_completion を呼び出す時にも workaround で
      command_not_found_handle を無効化する必要があるという事。

      ? __load_completion を呼び出す時には別に tty を封じてはいなかった様な気が
        するが固まるのは何故だろうか。うーん。不思議だ。確認した所、&>/dev/null
        で寧ろ入力ではなくて出力の方を組み替えている。なのに出力は出来て入力は
        できないというのも変な事である。

    * 2022-07-09 使っていたら元から command_not_found_handle が定義されていなかっ
      た時に pop 時に問題が発生する。これは ble/function#{push,pop} の実装の問
      題である。

      これは function#push 時に関数定義を与えなかった時に関数を unset する機能
      を導入した時の手落ちと考えられる。調べてみるとこれは a41279e (#D1720) に
      おける変更である。この時に一応 function#pop に対しても対応する変更がなさ
      れているが、それが不完全だったという事。

    * 2022-07-10 "bash: return: echo: numeric argument required"
      https://github.com/akinomyoga/ble.sh/issues/208

      これはミスだ。修正する。

2022-07-07

  * main: fd 0, 1 が TTY かどうかのチェックが常に偽になっている [#D1833]
    Ref #D1749

    ble-0.3 に 711c69f (#D1749) を backport している途中に気づいた。今までは
    /dev/tty もチェックしていたので、このチェックに失敗しても問題が表面化してい
    なかっただけ。ble-0.3 で /dev/tty のチェックをスキップする様にしたら問題が
    表面化した。ble-0.3 に対して行ったのと同じ修正を適用する。

2022-07-06

  * main, decode: ble-attach & set -e [#D1832]

    bash -e で開始した時は寧ろ --attach=prompt でないと駄目な事が分かった。
    ble-0.3 及び ble-0.4 で再現した。--attach=prompt を指定していても bashrc 内
    部で手動で ble-attach すると失敗する。

    うーん。これは ble/decode/.hook で set +e したら回避できるだろうか→どうや
    ら回避できる様だ。-e も勝手に無効にはなっていない。

    x これは文法エラー等によって状態回復に失敗した時に次の ble-decode/.hook の
      呼び出しの時に set -e が消滅する原因になり得るが、その様な事は余り起こら
      ないし起こったとしてもそもそも対話セッションで set -e を設定する事の方が
      変だから基に思案くても良い?

      a 或いは attach した直後だけは set +e を実行する様に変更する? 然し、
        attach した直後かどうかを判定するのにまた処理時間を食う気がするし、微妙
        な気がする。

      b 或いは別の hook に登録するという可能性もある。

      c 周りのコードを見渡してみたら既に set +v をしている部分がある。#D0930 が
        対応する項目である。確認してみたら今回の -e と同様の事が書かれている。
        うーん。前回のコマンドで解除に失敗した時にどうなるのかは非自明だが取り
        敢えずここに set -e を追加しておけば良い気がする。

        前回のコマンドで解除に失敗した時にはそもそもその場で errexit して終了し
        てしまう筈なので、再び .hook が呼び出される事もない気がするので気にしな
        くて良い気がする。

      取り敢えず c の方針を使う様に修正した。改めてちゃんと動くか確認する→OK

2022-07-05

  * bash: history timestamp に問題がある時に history の初期化が正しくない (reported by johnyaku) [#D1831]
    https://github.com/akinomyoga/ble.sh/issues/202

    bash がエラーメッセージを出力する (bash-5.0+) または segfault する
    (bash-4.4-)。現状ではエラーメッセージがそのまま履歴に混入してしまっている。
    うーん。stderr も読み取ってしまっているのかと思ったが実際に試してみるとエラー
    メッセージが stdout に出力されている。

    % これは後で bash に提出する。
    %
    % * reject: bug-bash: HISTTIMEFORMAT=%s history でエラーメッセージが stdout
    %   に混入するエラーメッセージは stderr に出力するべきなのではないか。
    %
    % と思ったがこの文字列はエラーメッセージとしてではなく履歴時刻の文字列の代
    % わりに埋め込まれているという事が判明した。という事はやはり history の出力
    % の中にメッセージを埋め込むべきという事なのかもしれない。

    取り敢えず問題のエラーメッセージは正規表現によるパターンで除去する事にする。

    * fixed: 更に履歴を書き込む時にも問題になっている。これも修正した。

    * done: 履歴読み込み時に invalid timestamp を検出したらそれを vbell で報告
      する様にする。

    これで bash-5.0+ 以降でエラーメッセージが履歴に紛れ込むのは修正した。一方で
    bash-4.4 以下で segfault してしまうのに対する対策は難しいのではないか。一応
    終了ステータスを確認する事で segfault した事は検出できるが、もし検出したと
    してどの様に対処するのが良いか。例えば、HISTTIMEFORMAT なしで改めて履歴を読
    み直す事にする? 履歴行の境をどの様に判定するべきだろうか。或いは、エラーを
    検出した時に vbell に表示してしまって、history の状態は壊れた状態でも仕方が
    ないという事にする? それが良い気がする。

    * 実際にエラーになった時に問題の行を指摘したい。

      どの様な形式の時にエラーになるのか調べようとしたがよく分からない。先ず、
      そもそも数字でない場合には timestamp 行として認識されない。数字の後にごみ
      が入っていてもそれらは単に無視される。得に巨大な数が指定された時に於いて
      問題が生じる様である。問題が起こる最小の整数を探索すると
      67768036191644399 であった。これは16進数で見ても特に特別な数ではない
      (0xf0c2ab7c542aef)。検索してみたらどうもやはり時刻関係で特別な数字の様で
      はある。

      > https://mevius.5ch.net/test/read.cgi/unix/1590454119/
      >
      > 115名無しさん＠お腹いっぱい。2020/06/01(月) 17:52:40.57
      > macos での限界
      > $ date -r 67768036191644399
      > 2147485547年 12月31日 水曜日 23時59分59秒 JST
      > $ date -r 67768036191644400
      > date: localtime: Value too large to be stored in data type

      実際手許の date で試してみても同様である。

      $ date --date=@67768036191644399
      $ date --date=@67768036191644400

      これは一体何が決めているのだろうか。と思ったらどうも 2147485547 年という
      のは1900 + 0x7FFFFFFF らしい。つまり localtime で時刻構造体に変換する時に
      代入できないという状態になるという事だ。

      https://www.wdic.org/w/TECH/21%E5%84%844748%E4%B8%875548%E5%B9%B4%E5%95%8F%E9%A1%8C

      67768036191644399 で検索して日本語のページが幾つかしか出てこないのは
      upper bound が TZ に依存するからである。

      さて、TZ に依存するのだとすればこの数値を threshold に選ぶ事はできない。
      それに正規表現で判定できなければ問題の行の検出に於いて不都合である。更に、
      この上限の値は time.h の実装にも依存するのではないだろうか。

    更に bash-3.2 以下では無限ループになる。関係ない無限ループかもしれないと思っ
    たが実際に履歴の timestamp に問題がある時にのみ無限ループになる。何処で無限
    ループになっているか確認する。

    →実際に ble.sh なしで試して見た所、単に history を実行しただけで無限ループ
    になって固まってしまう。これに対する対策は難しい気がする。。builtin history
    を呼び出すあらゆる操作で問題が起こる可能性があるという事になるのであるから。

    * done: bash-3.2: history の読み出しに使っている部分だけ conditoinal-sync で呼び出す。

      conditional-sync で timeout を設定してみたがやはり 100% になってしまう。
      という事は関係ない別の history -n 等でも全て無限ループになっているという
      事か。と思ったが手許で実行している限りは特に無限ループにはならない。

      →と思ったら分かった。.get-min で history | head -1 を呼び出している。こ
      の history で無限ループになっている。

    ? ok: 実際に conditional-sync で呼び出してみたところ timeout よりも断然早く
      中断する。何かと思ったら conditional-sync 経由で呼び出した時には無限ルー
      プにならずに 300ms 程度でちゃんと終了する様である。何故だろうか。

      もしかすると conditional-sync を使わなくても subshell ならばちゃんと終了
      する可能性? と思ったが、元より問題になる箇所では subshell を使っていた。
      なので、bg で動かした時にだけ無限ループにならないという事だろうか。だとし
      たらやはり conditoinal-sync 経由で呼び出して置くのが楽である。

    取り敢えず bash-3.2 でも固まらなくなった。OK

  * edit: プロンプト評価時に LINENO は一時的に現在の行番号に設定するべき [#D1830]

    →これは DEBUG を PREEXEC に使っている設定でも重要になる。
    うーん。DEBUG trap を呼び出す時にも設定するべきだろうか。
    →DEBUG trap を呼び出す時にも LINENO を設定する事にした。

2022-06-28

  * contrib/prompt-git: untracked content は赤ではない色で表示する for submodule [#D1829]
    →untracked files in submodule は単に無視するオプションがあったのでそれを使う事にする。

  * contrib/config/execmark: 同じ行に errexit を表示していると気づきにくい [#D1828]
    →分けて表示する様にした。

  * global: awk -v var=value を介して任意の文字列を渡さない [#D1827]

    awk の -v で任意の文字列を渡すことはできない。"" の中であるかのように \? が
    処理されてしまうので。文字列をそのまま渡したければ ENVIRON を使うしかない。

  * util: ble/string#split-words 最適化 [#D1826]

    どうも頻繁に呼び出される割に其処まで早い訳でもない様なので速度について確認
    する。うーん。多少弄ったら結構速度が変わったので採用する事にする。

    * 既存の呼び出しで引数を複数渡している場合はあるだろうか? →ない様なので分
      割文字列の引数は一つしか渡されないと仮定して良い。

    * ble/string#split も同様に最適化する。ble/string#split に関しても対象文字
      列の引数は必ず単一の様なので、それを仮定する。

    * 序に ble/util/assign & ble/string#split-words のパターンは関数にしてしま
      う。

    * done: refactor: ble/debug/profiler/{end => stop}
    * done: ble/debug/profiler: varleak nline
    * done: ble/debug/profiler: $prefix.line.txt の行番号の形式変更

    * 古い benchmark のスクリプトも追加する事にした。

2022-06-27

  * util (eval-pathname-expansion): bash-4.0以下で shopt *glob がクリアされる [#D1825]

    ble-0.3 backport で見ていたら気づいた。BASHOPTS (Bash 4.1+) を使って shopt
    の状態を記録しているが、Bash 4.0 以下に対する分岐がない。0da0c1c で埋め込ま
    れたバグである。visible-bell 消去時に glob 関連の shopt が全て unset されて
    しまう事になる。修正した。

    * 他の BASHOPTS 使用箇所は問題ないか → 他には ble.pp で使っているだけであ
      る。そして ble.pp の使用箇所ではちゃんと分岐している。

2022-06-26

  * debug: profiling 機能 (motivated by SuperSandro2000) [#D1824]

    LINENO を先ず何とかする。LINENO=... eval '...' とすれば一時的に LINENO を置
    き換える事が可能なのではないか。と考えたが、どうやら以前発見した bash の
    bug である tempenv=... builtin eval -- 'echo;echo $tempenv' で tempenv が消
    滅するバグの為に期待通りに動かない様だ。

    うーん。workaround の方法はあるだろうか?

    a ここの eval は builtin を使わずに呼び出す? → eval の上書きを現状では許可
      しているがこの対応を除去する必要がある。これは避けたい。バージョンごとに
      この対策を切り替えるのも面倒である。

    b eval を二重にしたら回避できる可能性はあるだろうか → 駄目だ。うーん。駄目。

      $ e=1234 builtin eval 'builtin eval ":;echo \$e"'
      $ e=1234 builtin eval 'e=1234 builtin eval ":;echo \$e"'

    c adjust-builtin の restore を遅延させて eval の内部で実行する可能性? → と
      思ったら既にその様になっていた。なので builtin eval にしなくても良い。

    時間を合計するプログラムを書いてみたが何だか振る舞いが変だ。そもそも関数呼
    び出しをしているのに + の数が増えていない気がする。うーん。説明を見ると
    levels of indirection と書いてあるがこれは何か確認する必要がある。→動作を
    見たら関数呼び出しでは増えない様だ。つまり、eval 等の数しか数えないという事。
    入れ子をちゃんと処理する為には + の数に加えて FUNCNAME の要素数も数える必要
    がある? FUNCNAME は関数の内部でしか有効にならず関数内に入るとトップレベルコ
    ンテクストの名前 (main) と共に要素数が2増えるので、代わりに常に存在している
    BASH_LINENO の要素数を数える事にする。

    * done: 関数毎の統計も取る
    * done: 前回の記録を最初に読み出す
    * done: % を表示する
    * done: 前回の記録が複数の物を cat した物の場合にも対応
    * done: PS4, bleopt の設定を待避・復元する → この為には ble/base/xtrace で
      hook する必要がある →

      a bleopt の設定については勝手に色々変わるのも変なので弄らない?

        PS4 はユーザーが使いたいかもしれないので待避するのは確定。bleopt の設定
        については xtrace/{adjust,restore} の度に動的に変わるのも変なので、やは
        り ble/debug/profiler/start した時に設定してそのままにしておくのが良い
        のではないか?

        →然しそうすると profiling 中にユーザーが間違って debug_xtrace{,_ps4}
        を設定した時に動作が変になるのでは。しかし、ble/debug/profiler を動かし
        ている最中にこれらの設定を勝手に変更するのがおかしいとも言える。特に
        ble/debug の同じ名前空間に属していると思えば ble/debug/profiler を介し
        て debug_xtrace{,_ps4} を動かしていると思っても良いのかもしれない。

      b 或いは profiler が設定されているかどうかの変数を ble/base/xtrace で見て
        処理を切り替える?

      c 或いは blehook xtrace_{adjust,restore} を追加する? →これは overhead が
        増えるし、もしこれで実装するとしても bleopt をその場で切り替える様な実
        装になって何だか変な気がする。其処までする必要もない。

      ble/debug/profiler で bleopt debug_xtrace_{,_ps4} を書き換える実装で良い。

    * done: blerc, wiki

2022-06-20

  * history: bind のエラーメッセージ in 非対話シェル (reported by wukuan405) [#D1823]
    https://github.com/akinomyoga/ble.sh/issues/200

    これは単に bash が警告を出しているだけである。念の為、確認してみたが、bind
    set 及び bind -v は共に動作している。

2022-06-19

  * history: erasedups を制限する機能 (motivated by SuperSandro2000) [#D1822]
    https://github.com/akinomyoga/ble.sh/issues/198

    * done: 初期化時の履歴の個数を記録しておく。

    うーん。これを実装する為には一時的な erasedups の除去がちゃんと history -s
    の動作に反映されている必要がある。そして反映されないという変な事がある様に
    は思われない→実際に動かして試してみたが特に変な振る舞いはしない。ちゃんと
    その時の HISTCONTROL に従って動作していると見て良いだろう。

    * done: history_erasedups_limit に従って探索の範囲を決定する。

    実装した。動作確認した。ちゃんと動いている様な気がする。意外と高速に動作す
    る。探索範囲が 20k/100k ぐらいになって漸く awk よりも遅くなる。現実的には一
    つの session で 20k もコマンドを打つ事はないだろうから気にしなくて良いだろう。

    2022-06-20 コードを眺めていたら無限ループのパスがある。関数名を書き換える時
    に修正し忘れていた。直す。

  * decode: ble-bind -P の出力で -c binding が変だ。引用符が余分についている [#D1821]

    ble-bind -m 'vi_nmap' -c C-z \'fg\'

    v0.3 では特に問題はない様だ。修正した。

  * decode (bind): inputrc に含まれる # の処理 [#D1820]

    % 変数によって処理したり処理しなかったりの様だ。特に文字列を受け取るオプショ
    % ンに関しては # 以降の削除はされない。一方で on/off のオプションの場合には
    % '#' 以降は無視されている様に見える。→と思ったが違った。単に最初の空白で
    % 切っているだけだった。

    Bash-5.1 以降では on/off オプションについては空白で区切った最初の単語だけを
    見る。Bash-5.0 以前は (# が含まれていたとしても) 全体を見る。うーん。ble.sh
    内部では勝手に '#' 以降を削除してから処理しているがこれは正しくない。後で修
    正する。これは 0.3 以前に遡って適用する。

  * util: rlvar enable-bracketed-paste off に対応する (motivated by ArianaAsl) [#D1819]
    https://github.com/akinomyoga/ble.sh/discussions/199

    rlvar を直接使う事にすると古い bash で設定を保持できないので bleopt で管理
    する事にして、bind enable-bracketed-paste は別名として取り扱う事にする。

    * done: bleopt 変数は rlvar とは独立に既定の値を持つ。初期化時に rlvar が既
      定と異なる値を持っている場合にはユーザーが設定したと見做してその設定を読
      み取る。

    * done: Bash が enable-bracketed-paste に対応している時には、bleopt の側の
      変数への設定時に同時に enable-bracketed-paste の値を調整する。

    * done: bind は既に上書きしているので enable-bracketed-paste に値を設定する
      のに介入するのも実装できる。enable-bracketed-paste に対する値の設定は
      bleopt への設定に読み替える事にする。rlvar は bleopt 経由で書き換える事に
      する。

    * done: この仕組を一般化して他の rlvar についても bleopt alias を作成できる
      様にする。これは一旦 enable-bracketed-paste に対応した後で考えれば良い。

    * done: wiki (skip-completed-text は更新)
    * done: blerc

2022-06-18

  * emacs: MULTILINE mode メッセージの改善 (motivated by ArianaAsl) [#D1818]
    https://github.com/akinomyoga/ble.sh/discussions/199

    * done: Q&A に書く。

    * done: MULTILINE モードの表示をしない様にする設定
      →keymap_emacs_show_multiline という設定変数名を追加した。

      * やはり MUTILINE モード名自体を設定する設定項目にする方が良い。
        keymap_vi_mode_string_nmap との一貫性により。設定変数名は
        keymap_emacs_mode_string_multiline に変更する事にした。

    * done: MULTILINE モードの表示メッセージを binding によって変える

    * rlvar enable-bracketed-paste の設定の alias bleopt を作成してそれを上書き
      する。この方法はその他の補完設定に対しても適用するべきなのではないか。独
      立した項目で全体的に対応する事にする。

2022-06-17

  * util: erasedups 高速化 (motivated by SuperSandro2000) [#D1817]
    https://github.com/akinomyoga/ble.sh/issues/198

    一旦ファイルに書き出して awk で処理してから読み出す方式を試してみた。然し単
    に配列を走査するよりも遅くなってしまった。

    計測してみると awk による処理自体は高速だが書き出しと読み取りの両方で滅茶苦
    茶時間がかかっている。printf '%s\n' "${arr[@]}" は遅いのだった。また、
    mapfile -d '' も内部では1文字ずつ読むモードに切り替わってしまうのか遅い。こ
    れは bash-5.2 以降でしか高速ではないのだった。

    過去に同様の事をした気がする → #D1522 が対応する議論であった。

    awk による処理は十分に高速の様だ (45ms)。読み取りは nlfix にすれば無視でき
    るぐらいコストを小さくできる筈 (改行が大量に含まれていない限り)。

    * done: 書き出しの高速化に関して。

      printf '%s\0' が遅いので writearray を実装した筈なのに
      writearray を確認してみたら遅い。これは別項目で考える事にする。

      或いは history の出力を改めて解析した方が余程早いのではないか。と思ったが
      history の出力が編集されていると微妙である。基本的には history の出力を使っ
      て _ble_history を作っているのだから (そして勝手に Readline の編集が起こっ
      ていなければ)、_ble_history の内容と history の出力結果は一致している筈で
      ある。一方で、_ble_history_edit の内容に関しては結局配列として出力しなけ
      ればならない。_ble_history の書き出しと _ble_history_edit の書き出しを並
      列で実行するのだとしたら、_ble_history の側だけを history の出力を使って
      高速化しても余り意味がない。

    うーん。どうにも書き込みは並列で書き込むとしても精々 170 (printf) までしか
    減らせない。更に bash-5.2 では printf は 455 もかかる。mawk でも 434 である。
    なので、bash-5.2 だと絶望的である。元々直接ループを回していた時で 790 であ
    る。高速化はしているが、結局大して高速化は期待できないのではないか。特に
    5.2 以降で高速化しないのであれば古い ver で頑張る意味もない。

    * done: 5.2 未満では nlfix で読み取らせる事にした。以下テスト用コード

      {
        ble/debug/stopwatch/start
        ble/debug/stopwatch/stop 'save-data' >/dev/tty
        ble/debug/stopwatch/start
        ble/debug/stopwatch/stop 'proc-data' >/dev/tty
        ble/debug/stopwatch/start
        ble/debug/stopwatch/stop "load-data (${#_ble_history[*]}, ${#_ble_history_edit[*]})" >/dev/tty
        # DEBUG
        local dup=$( ( ( time ble/builtin/history/option:s/erasedups "$cmd"
                         declare -p _ble_history _ble_history_edit | sha256sum)
                       ( time ble/builtin/history/option:s/erasedups.awk "$cmd"
                         declare -p _ble_history _ble_history_edit | sha256sum) ) | uniq -u)
        ble/builtin/history/option:s/erasedups "$cmd"
        if [[ ! $dup ]]; then
          echo "${#delete_indices[@]}: ok"
        else
          echo "${#delete_indices[@]}: ng"
          echo "$dup"
        fi >/dev/tty
      }

    * done: awk0 が使えない場合には書き出しも nlfix にしてしまう?

      →その様に実装してみた。nawk は遅くなる。mawk と gawk は十分な速度が出て
      いる。それでも \0 の時よりは遅くなる様である。というか、mawk と gawk は結
      局 \0 に対応しているので、この nlfix は実際の所使われる事はないという事に
      なる。

    * 別の可能性として erasedups で探索する範囲を制限するという事も考えられる。
      Bash の erasedups は一時的に off にして、手動で見つかった項目を Bash のコ
      マンド履歴からも削除するということ。探索範囲については、例えば起動時の
      history の大きさを記録しておいて、それ以降に追加された項目のみを検査する
      等。うーん。これは別項目として独立させる事にする。

  * util: ble/util/writearray 最適化 [#D1816]
    Ref. #D1817

    やはり巨大な配列になると書き出しが最も遅い。

      printf '%s\0' "${_ble_history[@]}"       ...  365ms
      ble/util/writearray -d '' _ble_history   ... 1387ms (mawk だと速い?)
      ble/util/writearray --nlfix _ble_history ... 1397ms

    と思ったら mawk を使っている場合には writearray も高速なのであった。nawk
    と gawk ではとても遅い。#D1522 を見たら多少改善したと書かれているがそうで
    もなかったという事だろうか。改めて注意深く計測してみる事にする。→うーん。
    単に mawk がコンパイルに失敗して動作していないだけだった。

      bash-5.1
      [  0.170960 sec] write by printf
      [  0.035244 sec] write by declare -p
      [  0.236600 sec] write by ${_ble_history[@]@Q}
      [  0.677771 sec] write by nawk
      [  0.428015 sec] write by mawk
      [  1.804527 sec] write by gawk
      [  0.689799 sec] write by nawk --nlfix
      [  0.421999 sec] write by mawk --nlfix
      [  1.806602 sec] write by gawk --nlfix

      bash-5.2
      [  0.455534 sec] write by printf
      [  0.023524 sec] write by declare -p
      [  0.690759 sec] write by nawk
      [  0.434321 sec] write by mawk
      [  1.810687 sec] write by gawk
      [  0.693987 sec] write by nawk --nlfix
      [  0.423758 sec] write by mawk --nlfix
      [  1.832763 sec] write by gawk --nlfix

    a writearray の awk 高速化?

      うーん。やはり writearray の awk を高速化できないだろうか。何処で時間が
      かかっているのかを確認する。

      % 先ず全ての文字列を連結しているがこれが遅い可能性は?
      %
      %   連結部分の時間
      %   [  0.041765 sec] write by nawk
      %   [  0.061284 sec] write by mawk
      %   [  0.032100 sec] write by gawk
      %
      % 無視できる訳でもないが全体の処理時間に比べればずっと小さい。これの最適化
      % も考えたい気がするが、これは後でも良い気がする。
      %
      %   declare除去終了時刻
      %   [  0.049391 sec] write by nawk → 8ms
      %   [  0.062445 sec] write by mawk → 1ms
      %   [  0.036025 sec] write by gawk → 4ms
      %   全体quote除去 終了時刻
      %   [  0.059244 sec] write by nawk → 10ms
      %   [  0.062717 sec] write by mawk → 0ms
      %   [  0.045702 sec] write by gawk → 9ms
      %   bashバグ調整 終了時刻 (Bash 5.1 では何もしない筈)
      %   [  0.059713 sec] write by nawk → 0ms
      %   [  0.062856 sec] write by mawk → 0ms
      %   [  0.045834 sec] write by gawk → 0ms
      %   変数名除去等 終了時刻
      %   [  0.079104 sec] write by nawk → 10ms
      %   [  0.078687 sec] write by mawk → 16ms
      %   [  0.136127 sec] write by gawk → 91ms
      %
      % この文字列の全体処理の時点で
      %
      %   [  0.079104 sec] write by nawk →  38ms
      %   [  0.078687 sec] write by mawk →  17ms
      %   [  0.136127 sec] write by gawk → 104ms
      %
      % だけ処理に時間がかかっている。うーん。これはもっと短くできる気がする。末
      % 尾の処理に関しては最後にならないと分からない。先ずは入力を結合せずに配列
      % に保持するなどして、結合する前に適用するのが良い様な気もする。これは何れ
      % にしても結合部分を最適化してから考えるのが良い気がする。
      %
      % →よく考えてみれば、そもそも declare -p は1行しか出力しないのでここで
      % 実際に連結が大量に行われるという事はない。なので、この最初の部分をもっ
      % と小さな文字列に分解して処理するという方向での高速化はできない。

        dq判定直前
        [  0.079104 sec] write by nawk
        [  0.078687 sec] write by mawk
        [  0.136127 sec] write by gawk
        dq判定直後
        [  0.089831 sec] write by nawk
        [  0.076440 sec] write by mawk
        [  0.146535 sec] write by gawk
        split直後
        [  0.211504 sec] write by nawk → 122
        [  0.091142 sec] write by mawk → 15
        [  0.230322 sec] write by gawk → 84

      うーん。後は普通に loop に時間がかかっているという事

        配列添字の除去直後でcontinueした場合
        [  0.443631 sec] write by nawk → 232
        [  0.130103 sec] write by mawk →  39
        [  0.348103 sec] write by gawk → 118
        matchループ直後でcontinueした場合
        [  0.657334 sec] write by nawk → 214
        [  0.412463 sec] write by mawk → 282
        [  1.758804 sec] write by gawk → 1410

      うーん。これの高速化は難しい様な気がする。正規表現をやめて一文字ずつ処理
      する様にしたら更に悪化しそうな気がする。

      * reject: 微妙に弄ってみる事にする。元々の時刻を測っておく。

        [  0.698775 sec] write by nawk
        [  0.424295 sec] write by mawk
        [  1.823190 sec] write by gawk

        うーん。split を /" / で実行したら良いのではないかと考えたが
        [1]=$'...' の形式等もあるので /" / だけで分割するという訳にも行かない。
        だからと言って /['"] / で分割してしまうと、其処にあった文字が ' だっ
        たのか " だったのかの情報が失われてしまう。なので、この案は駄目だ。

        一応、結果が変わってしまうが /" / で分割して処理した時の時間を見てお
        く。一応高速化はちゃんとする様である。

        [  0.391338 sec] write by nawk
        [  0.269026 sec] write by mawk
        [  1.267509 sec] write by gawk

      やはり writearray の awk をこれ以上高速化する方法はない様な気がする。既
      にほぼ最速の実装になっているという気がするのである。

      * 先に数十の単位で連結を行って多少復元してから処理を行う? それでも連結
        コストはかかるしうーん。どうなのだろうか。

        元のコード

          function analyze_elements_general(decl, _, arr, i, n, str, elem) {
            nlfix_indices = "";
            nlfix_index = 0;
            n = split(decl, arr, / /);
            for (i = 1; i <= n; i++) {
              str = arr[i];
              sub(/^\[[0-9]+\]=/, "", str);
              elem = "";
              while (1) {
                if (match(str, /'"$rex_dq"'|'"$rex_es"'|'"$rex_sq"'|'"$rex_normal"'|^\\./)) {
                  mlen = RLENGTH;
                  elem = elem unquote(substr(str, 1, mlen));
                  str = substr(str, mlen + 1);
                } else if (str ~ /^[$"'\''\\]/ && i + 1 <= n) {
                  str = str " " arr[++i];
                } else {
                  break;
                }
              }

              _process_elem(elem);
            }
            if (FLAG_NLFIX)
              printf("%s\n", nlfix_indices);
            return 1;
          }

          [  0.723085 sec] write by nawk
          [  0.430691 sec] write by mawk
          [  1.822919 sec] write by gawk

        N個ずつ処理する時

          function analyze_elements_general(decl, _, arr, i, n, str, elem) {
            nlfix_indices = "";
            nlfix_index = 0;

            n = split(decl, arr, / /);
            str = "";
            elem = "";
            first = 1;
            for (i = 1; i <= n; i++) {
              str = str " " arr[i];
              if (i % 5 != 0 && i != n) continue;
              while (1) {
                if (sub(/^ (\[[0-9]+\]=)?/, "", str)) {
                  if (first)
                    first = 0;
                  else
                    _process_elem(elem);
                  elem = "";
                } else if (match(str, /'"$rex_dq"'|'"$rex_es"'|'"$rex_sq"'|'"$rex_normal"'|^\\./)) {
                  mlen = RLENGTH;
                  elem = elem unquote(substr(str, 1, mlen));
                  str = substr(str, mlen + 1);
                } else {
                  break;
                }
              }
            }
            _process_elem(elem);

            if (FLAG_NLFIX)
              printf("%s\n", nlfix_indices);
            return 1;
          }

          5個ずつ処理する時
          [  0.729255 sec] write by nawk
          [  0.368347 sec] write by mawk
          [  1.642443 sec] write by gawk
          10個ずつ処理する時
          [  0.714652 sec] write by nawk
          [  0.347246 sec] write by mawk
          [  1.636028 sec] write by gawk
          100個ずつ処理する時
          [  0.727583 sec] write by nawk
          [  0.371555 sec] write by mawk
          [  1.678000 sec] write by gawk

        "]=" で分割する作戦

          "]=" で分割する時
          [  0.438765 sec] write by nawk 39% speedup
          [  0.303779 sec] write by mawk 30% speedup
          [  1.378912 sec] write by gawk 24% speedup
          "]=" で分割する時/2個ずつ
          [  0.443567 sec] write by nawk
          [  0.305656 sec] write by mawk
          [  1.368339 sec] write by gawk
          "]=" で分割する時/5個ずつ
          [  0.456370 sec] write by nawk
          [  0.306033 sec] write by mawk
          [  1.400369 sec] write by gawk

          ループの仕方を多少工夫
          [  0.385840 sec] write by nawk
          [  0.283110 sec] write by mawk
          [  1.295154 sec] write by gawk

          この方法で思ったよりは高速になった。

      * unquote_dq の最適化

          gawkでgensub を使う様に変更
          [  0.388626 sec] write by nawk
          [  0.282651 sec] write by mawk
          [  1.015230 sec] write by gawk
          gsubによる実装に変更
          [  0.356890 sec] write by nawk
          [  0.218238 sec] write by mawk
          [  1.016223 sec] write by gawk
          unquote判定の簡略化
          [  0.348118 sec] write by nawk
          [  0.213385 sec] write by mawk
          [  0.990123 sec] write by gawk
          [  0.367019 sec] write by nawk
          [  0.211183 sec] write by mawk
          [  1.001340 sec] write by gawk
          [  0.346388 sec] write by nawk
          [  0.211842 sec] write by mawk
          [  1.005543 sec] write by gawk

    b reject: ${_ble_history[@]@Q} を解析する可能性?

      うーん。或いは declare -p は諦めて ${_ble_history[@]@Q} の結果を解析する
      方が簡単で良い? と思ったがこれはこれで処理に時間がかかりそうな予感がする。
      何より split が非自明である。

      a 単に /' \$?'/ で split すれば良いのか、というと違う気がする。うーん。或
        いは実はそれで行ける? 落ち着いて考える…やはり駄目だ。これだと $ があっ
        たかどうかの情報が失われてしまう。

      b /' '/ で split して更にその後で /' \$'/ で split する? うーん。問題は関
        係ない物を誤って split してしまわないかという事。例えば 'a'\'' ' 'b' と
        なっていた場合違う所で split してしまう。結局繰り返し match が必要にな
        るので処理が重くなる気がする。

        或いは先に '\'' を適当に処理してしまう (置換して別の文字にするなど)? と
        思ったが今度は $'\n\'\'' 等に於いて関係ない '\'' をひっかけてしまう。

      更に ${_ble_history[@]@Q} の評価自体も別にそれほど高速という訳でもない。
      200ms かかっている。やはり declare -p の 35ms には勝てないのである。

    c 或いは高速化の為に C で処理するプログラムを書いてしまうのも手なのかもしれない。
    d もしそうするのであれば寧ろ bash loadable builtin にしてしまう?

      これらの処理を実装するのだとしたらもっと広範に渡って bottleneck を C /
      builtin 実装に置き換えたい気がする。

    以下テストに用いたコード

    {
      # 計測結果
      (
        ble/debug/stopwatch/start
        printf '%s\0' "${_ble_history[@]}"      >| "$itmp1"
        ble/debug/stopwatch/stop "write by printf" >/dev/tty

        ble/debug/stopwatch/start
        declare -p _ble_history >| "$itmp1"
        ble/debug/stopwatch/stop "write by declare -p" >/dev/tty

        ble/debug/stopwatch/start
        echo "${_ble_history[@]@Q}" >| "$itmp1"
        ble/debug/stopwatch/stop "write by \${_ble_history[@]@Q}" >/dev/tty

        ble/bin/awk() { "$_ble_bin_awk_type" -v AWKTYPE="$_ble_bin_awk_type" "$@"; }
        for _ble_bin_awk_type in nawk mawk gawk; do
          ble/debug/stopwatch/start
          ble/util/writearray -d '' _ble_history >| "$itmp1"
          ble/debug/stopwatch/stop "write by $_ble_bin_awk_type" >/dev/tty
        done

        for _ble_bin_awk_type in nawk mawk gawk; do
          ble/debug/stopwatch/start
          ble/util/writearray --nlfix _ble_history >| "$itmp1"
          ble/debug/stopwatch/stop "write by $_ble_bin_awk_type --nlfix" >/dev/tty
        done
      )

      #_ble_bin_awk_type=nawk
      #_ble_bin_awk_type=mawk
      _ble_bin_awk_type=gawk
      ble/bin/awk() { "$_ble_bin_awk_type" -v AWKTYPE="$_ble_bin_awk_type" "$@"; }
      ble/util/writearray -d '' _ble_history      >| "$itmp1" & local pid1=$!
      ble/util/writearray -d '' _ble_history_edit >| "$itmp2"
      wait "$pid1"
      cat "$itmp1" "$itmp2" | tr '\0' '\n' > 1.txt
      printf '%s\0' "${_ble_history[@]}"      >| "$itmp1" & local pid1=$!
      printf '%s\0' "${_ble_history_edit[@]}" >| "$itmp2"
      wait "$pid1"
      cat "$itmp1" "$itmp2" | tr '\0' '\n' > 0.txt
      command diff -u 0.txt 1.txt > 1.diff
      command rm 0.txt 1.txt
    }

  * [実装済] 2018-03-14 emacs: C-w を続けて実行すると kill-ring に追記にするべき [#D1815]

    古い項目。これは既に実装されている。

2022-06-15

  * github/workflows: nightly build (contributed by uyha) [#D1814]
    https://github.com/akinomyoga/ble.sh/pull/197

    色々勝手に建て増しした。nightly build のページに情報を載せた。nightly build
    の ble-update ではnightly build を取得する様にした。動作確認もした。
    file#hash の取得に使うコマンドは動的ではなくて初期化時に freeze する様にし
    た。序でに ble/util/getmtime -> ble/file#mtime に改名して初期化を遅延させる
    様にした (これで初期化時の fork/exec は一つ減っただろう)。

2022-06-13

  * util (fd#alloc): fd の上限に達した時にどうするか。無限ループになるのではないか [#D1813]

    取り敢えず 1024 の探索上限を入れた。探索範囲に見つからなかった時には、元々
    の _ble_util_openat_nextfd の上に開く事にする。

    2022-06-15 見ていたら誤りを見つけたので追加修正する。

  * test: CI にテストを載せる上で既知の false error は全て潰しておく必要がある [#D1812]

    今まで CI テストを実行すると clone stats に影響が出ると思って敢えて対応はし
    ていなかったが、最近では clone count が多くなって来たのでmasterへのpushにつ
    き1回程度のcheckout であれば特にclone stats に影響を与える事もないだろう。
    特に今回 nightly build の提案があったので同時にテストも実行してしまうのが良
    い気がする。

    macOS で今までテストした事はなかったし、そもそも macOS 上で動く様にテストを
    書いていなかった。macOS の上でも動く様に調整するべき。

    更に、make scan も一緒に実行してしまうのが良い。make scan については色々
    false error が出ているので潰す。

2022-06-10

  * [棄却] 2021-05-23 main: BASH_XTRACEFD による set -x 出力の抑制? [#D1811]

    | | 更に set -x についてもまた駄目になっているかもしれない。→試してみた所
    | | attach 部分で無駄なメッセージが沢山表示される様になっていたが実行自体には問
    | | 題はない様である。然し、BASH_XTRACEFD を使った方が良いのではないか。これに
    | | ついてはまた別の機会について考える事にする。
    |
    | 現在の抑制の手法だと必要なエラーまで抑制してしまうし、標準エラー出力を抑制す
    | る為に結構無理な事をしている。BASH_XTRACEFD を使って実装した方が綺麗になるの
    | ではないか。然し、また色々と実装上の不都合が生じるかもしれないので取り敢えず
    | 後でゆっくり対処する事にする。
    |
    | →改めて確認してみたが、BASH_XTRACEFD は代入すると元々設定されていた fd が勝
    | 手に閉じられてしまう。
    |
    | a なので元々設定されていた fd を保存する等の対処が必要になるがその為には様々
    |   なコマンドを呼び出す必要がある。だとすると結局現在の位置よりも上に
    |   BASH_XTRACEFD の書き換えのコードを移動することはできないので、現状使ってい
    |   る { ... } 2>/dev/null による set -x 対策を置き換えるには至らない。
    |
    | b BASH_XTRACEFD が設定されていなかった時にだけ BASH_XTRACEFD を使って set -x
    |   を抑制する
    |
    |   % この様にしても BASH_XTRACEFD が既に指定されていた場合の為に { ... }
    |   % 2>/dev/null の対策は外す事ができない? と思ったが、既に BASH_XTRACEFD が設
    |   % 定されているのだとしたら {} 2>/dev/null としても意味がない (つまり 2 に出
    |   % 力される訳ではないので結局全て BASH_XTRACEFD に書き込まれてしまう)。
    |
    |   うーん。然し、BASH_XTRACEFD を一時的に /dev/null に設定するとしても、どの値
    |   に設定するのかというのが結局問題になる。下手な fd を設定してしまうと変な所
    |   に書き込まれて問題になる。自分で fd を開くにしても空いている fd を探す必要
    |   がある。探す為には結局色々とコマンドを呼び出す必要がある。
    |
    | 色々考えると、単に BASH_XTRACEFD に値を設定するという話ではない。元々設定され
    | ている BASH_TRACEFD を待避するのにも、出力先の /dev/null を開くのにも、空いて
    | いる fd を探すのにコマンドを呼び出す必要がある。という事を考えると、結局現在
    | set +x を実行している位置までは { ... } 2>/dev/null に頼る必要がある。なので、
    | 現在行っている対策を減らす効果はない。
    |
    | 一方で必要なエラーまで抑制してしまっている事についてはどうか。例えば { ... }
    | 2>/dev/null を単に除去してしまう。そうすれば set -x の出力も通常のエラーも全
    | て表示される様になる。然し、結局 set -x の出力を抑制する方法が他にないので、
    | やはり現在の位置までは { ... } 2>/dev/null で対策しておくしかない。

    [結論] 当初使えるかもしれないと思ったのは BASH_XTRACEFD への設定が (設定に影
    響を受けない) 変数代入だけで行えると考えたからであったが、その前に空いている
    fd を探索して更にその fd に対して /dev/null を開く為に builtin を呼び出す必要
    がある。従って adjust-builtin-wrappers 以前は結局今までの対策を使う必要があり、
    それは現在の対策範囲と変わらない。

  * 2022-04-15 ble.sh 内部に対する xtrace (set -x) を有効にする方法 (requested by SuperSandro2000) [#D1810]
    https://github.com/akinomyoga/ble.sh/issues/186#issuecomment-1099696862

    うーん。取り敢えず無理やり実装してしまって良い気がする。

    * 設定 interface をどうするか

      と思ったが interface をどのようにするかが微妙である。取り敢えず提案された様
      に BLESH_DEBUG 等の環境変数経由で設定する事にするべきか。と思ったが、bleopt
      で設定するべきの気がする。例えば、以下の設定がある時には set -x をしないと
      いう事。

      bleopt debug_xtrace=ファイル名

    うーん。これに対応する為にはユーザーの設定した BASH_XTRACEFD を何処かに保存し
    ておく必要がある。そしてその為にはファイルディスクリプタの探索等を実装する必
    要がある。などなど色々考えると、ロードした瞬間に実行するには処理として複雑す
    ぎる。そう思うと BASH_XTRACEFD は切り替えずにそのままユーザーが設定した物に出
    力するというので良いのではないか。

    * というより元々の 2021-05-23 の項目の意図は set -x の抑制を BASH_XTRACEFD を
      使ってできないかという事だった様な気がする。つまり、今回の ble.sh に対する
      デバグの目的で BASH_XTRACEFD を設定するという話とは違う話なのではないか。

      とは言いつつ set -x を抑制する為に /dev/null に設定するのを、debug_xtrace
      が指定されている場合には代わりにそのファイルに BASH_XTRACEFD を設定するべき
      だろう。という事を考えれば全く関係ない訳でもない。

      取り敢えずこちらを先に対応してから、2021-05-23 の項目に対して set -x 対策で
      強制的に抑制している範囲を減らす事ができないか検討するという事で良い気がす
      る。

    取り敢えず簡単に作って試してみた。あっという間に数百MBに達するので実際にこれ
    を使って debug する事が現実的なのかは疑問であるが、本当にクラッシュする時など
    には便利かもしれない。然し、幾らか問題点がある。

    * fixed: 元々 BASH_XTRACEFD に設定されていた fd を別の番号に dup しておく必要
      がある。何故なら BASH_XTRACEFD が変更される瞬間にその fd は閉じられてしまう
      から。然しその為には空いている fd を確実に探し出す必要がある。

    * fixed: 現在 context を switch する度にファイルを開いているが、debug_xtrace
      が設定された時に fd を開いておいて以降はそれを dup するべきなのではないか。
      毎回開き直すのは大変だし、ファイル名が相対パスで指定されていた場合、ディレ
      クトリ毎にファイルが作られて面倒な事になる。

    x 実際に試してみると set -x した時の抑制に失敗している → 何かと思ったら
      adjust/restore options は入れ子で呼び出す事を許容しているのだった。対応した。

    もっと複雑化と思ったが上記に対応したら原理的な問題ももうない気がする。

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]
    https://github.com/akinomyoga/ble.sh/issues/193

    これは前から気になっていた事である。問題は何処に介入するのかという事である。
    補完関数全体を subshell で実行する様にしてしまうと 124 を返して再実行した時
    に無限ループになってしまう。他にも変数に対する修正が適用されない等の問題が
    生じる。なので、もっと内側で conditional-sync を実行する必要がある。

    _scp_remote_files を subshell で実行しようとも思ったがそうすると COMPREPLY
    を渡すのが面倒だ。というか scp, ssh 等に介入すれば良い。どうせこれらは他の
    プロセスを起動するのだから。実際に _scp_remote_files は ssh を呼び出してい
    る:

    https://github.com/scop/bash-completion/blob/6f1bbda3c66814befa8025d49363b4070ef20008/completions/ssh#L435

    と思って実装したが動かない。どうやら $(...) の中で conditional-sync をした
    場合、$() が結局本体のプロセスが死ぬまでブロックしてしまうのが原因の様だ。
    本当のプロセスを kill -9 しても駄目の様だ。どうも更に子プロセスが起動してい
    るのが原因だ。

      PGID を確認してみたが command substitution の中で & で呼び出しても固有の
      PGID を作成する訳では無い様だ。なので PGID に対して kill を実行すると外側
      も含めて予期しない所まで kill されてしまう。

      仕方がないので ps を使ってプロセス一覧を取得して其処から kill を実行する
      事にする。

    * dnf も遅い。dnf に関しては _dnf_commands_helper に介入すれば良さそうだ。
      然し、遅延ロードされる関数に確実に介入するには遅延ロードした時に上書きす
      る必要がある。うーん。一応 bash-completion に関しては 124 により一旦制御
      を返すので介入はできる気がする。

    2022-06-02 conditional-sync のミスを push する。暫く手元に置いていたがずっ
    とこのままにしておくのは好ましくない。

2022-05-01

  * 日本語を含むディレクトリに入ると化けてしまう事に気づいた [#D1806]
    Ref #D1798 a9551e5

    これは \w, \W, etc 対策の副作用である。修正した。

2022-04-10

  * BSD make で実行しようとする人対策 (question by lu9dce) [#D1805]
    https://github.com/akinomyoga/ble.sh/issues/184

    FreeBSD で make でコンパイルしようとしている人がいる。面倒なので BSD make
    用の Makefile も用意して make で実行しても代わりに gmake を呼び出す様にする
    事にした。

    shebang が #!/bin/bash であるのが原因だと勝手に言っていたが、これは関係ない。
    今後も似たような御節介の誤った報告が来るかもしれないので shebang 自体を削除
    してしまっても良いのかもしれない。或いは -*- mode: sh; mode: sh-bash -*- に
    する。然し、これだと自分の所の設定でしか Bash モードが有効にならないという
    問題がある。取り敢えずは現状のままという事にする。今後も何か指摘してくる人
    が居たら全部 shebang を削除する事にする。

  * blehook に引数が渡されなくなっている (reported by SuperSandro2000) [#D1804]
    https://github.com/akinomyoga/ble.sh/issues/185

    調べたら invoke.sandbox 経由で呼び出す時に引数が継承されていない。
    invoke.sandbox を導入したのは最近である。6fdabf32 が該当する変更である。
    https://github.com/akinomyoga/ble.sh/issues/179#issuecomment-1048416510

2022-04-05

  * progcomp: cobra で生成される補完が説明を混入させる (reported by SuperSandro2000) [#D1803]
    https://github.com/akinomyoga/ble.sh/issues/183

    正直 cobra は bash-completion でも問題を起こしているし。元よりとても質が悪
    いので余り対応したくないが、だからといって upstream に手を加えるのもまた対
    応が遅くてどうしようもないという事が分かっている。不本意ながらこちらで
    workaround を加える→取り敢えず対応した。一応動く。

    改めて V2 の実装を確認したがやはり bash スクリプトとして質が悪い。

    ? そもそも説明を候補に含めるのは hack に過ぎないし、これに依存していると
      bind 'set show-all-if-ambiguous' 等の時に正しく動作するのかも怪しい→と思っ
      て確認してみたが一応大丈夫の様だ。

      以前 bash-completion で make に対して起こったのは一体何だったのか。以下で
      ある。

      https://github.com/scop/bash-completion/issues/544
      https://github.com/scop/bash-completion/pull/546

      うーん。調べてみるとこの時とは条件が異なる。この時は COMP_TYPE が 9 or 37
      の時には候補を勝手に変更しない様にしていた。これは挿入される候補の始まり
      部分を省略できるかどうかの判定であり、少しでも挿入されたら困るので 9 も排
      除している。42 は手落ちであろう。一方で今回は始まり部分は変えないので曖昧
      の時には後ろに自由に勝手な文字列を追加する事ができる。という事により
      37|42 の時にだけ気をつければ良い。

2022-03-19

  * menu-complete: 補完候補に含まれる制御文字の反転は xor で行う [#D1802]

    prompt seq \w, \W, \s で制御文字の反転を toggle する様にしたが、補完候補の
    表示でも同様に toggle した方が良い気がする。#D1798, #D1801 のテストの最中に
    実際に制御文字を含むディレクトリを作成して補完を実行した時にやはり気になっ
    た。当初は #D1801 の一部として対応したが別項目に分けた方が良い様に感じるの
    で分ける事にした。

    * done: menu-complete: 特殊文字を含む候補の反転と選択時の反転が重なって見に
      くい。反転は重ね書きではなくて toggle にするべきなのではないか。

      新しい \e[9807m で対応できるかと思って実装を確認したが trace は使っていな
      くて直接画面に出力するのに使うシーケンスを sgr を直接指定することで構築し
      ていたので使えなかった。その代わりに反転に使う sgr などをそもそもその場で
      g|_ble_color_Revert 等として構築していたのでその | を ^ に置き換える事で
      簡単に対応する事ができた。

    一方で編集文字列に含まれる制御文字についても気になったがそもそも反転してい
    ないので関係ないのであった。

    * ok: 更に編集文字列本体についても同様に toggle するべきなのではないか? と
      思ったがそもそも現在の実装だと編集文字列に含まれる制御文字は特に反転など
      していないので関係ないのであった。

      今から新しく対応しようにも現状の実装だと反転の toggle を実装するのは簡単
      ではない様なので取り敢えずは対応しない事にする。もし今後必要性を感じた時
      に改めて対応する事にすれば良い気がする。一応項目として残しては置く。

2022-03-12

  * prompt: bash-5.2 では \w, \W に加えて \s についても escape する様だ [#D1801]
    Ref #D1798

    bash がなかなか実装しないと思ったらこちらが \w, \W に対する実装を push した
    4日後に対応が入った。どうも \s についても escape が入ったという様に commit
    message には書かれている。

    \s は "bash" という文字列の様だ。これに制御文字が含まれるとは一体どういう状
    況だろうか。これを気にするのであれば \h, \H, \u も気にするべきなのではない
    か。取り敢えず全てに大して対策を加える事にした。

    ? bash-5.2 では ${PS1@P} でもちゃんと \w, \W を escape してくれるのか→ちゃ
      んと escape してくれている。

    * done: bash-4.4 以上では escape が起こった時に @P を使わない自前実装に切り
      替える必要がある。

    * bash-5.2 の実装についても改めて確認する。\t はそのまま特殊文字のまま出力
      する様だ。その他については zsh の様に \n だとか \t の様な表現には置き換え
      ず一貫して ^X という形で表現している。改行は ^J になっている。

      \s 以外にも対応している物がないか確認する。

      bash-5.2 の対応では sh_backslash_quote_for_double_quotes に手を入れる事に
      よって対応が行われている。この関数は本来は eval する時に変な事が起こらな
      い様に $`"\ 等を escape するのが目的だったのだと思われるが、同時にエスケー
      プまで実行してしまうという算段である。

      特にこの機能が有効になるのは第二引数に bit 1 を指定した時で以下が該当する。

      ./parse.y:5745:         temp = sh_backslash_quote_for_double_quotes (temp, 1);
      ./parse.y:5822:           temp = sh_backslash_quote_for_double_quotes (t_string, 1);

      そしてこれは正に commit msg にある様にそれぞれ \s と \w\W に対する処理で
      あった。なので \s, \w, \W 以外に関しては対策は実装されていない。

      ? うーん。 ^\ に大して何か変な事が起こったりするのではないか…。例えば
        ^\$(echo hello) が実行されてしまう可能性はないのだろうか。試してみたら
        問題を再現できてしまった。

        $ mkdir $'\034$(echo hello)'
        $ cd !$

      ? これは shopt -u promptvars でもちゃんと実行されるのだろうか? →試してみ
        たがちゃんと動いている様だ。OK

      2022-03-19 これは bash に PATCH を送ったら今日適用されていた。OK

    * bash-5.2 では META_CHAR に対しても escape を実装している様だ。うーん。
      ble.sh でも対応するべきだろうか。と思ったがよく考えてみたら ble.sh ではそ
      もそも編集文字列であっても 80..A0 に対して特別な文字は割り当てていない様
      な気もする。これはそれも含めて再考する必要がある。

      →と思ったが改めて確認してみたところ
      _ble_unicode_GraphemeCluster_ControlRepresentation という配列にちゃんと登
      録しているのだった。この新しい実装でもこの配列を参照するべきである。

      と思ったが _ble_unicode_GraphemeCluster_ControlRepresentation は単にキャッ
      シュしているだけなので代わりに ble/unicode/GraphemeCluster/.get-ascii-rep
      を呼び出すべきである。その様に実装し直した。

2022-03-04

  * 2021-10-26 ble/builtin/read: status が表示されている気がする [#D1800]

    更新はされていないので実際に表示する時の問題である。然し、vi_cmap 等の時に
    表示されるのは特に問題ない動作である。という事を考えると、その意味で status
    が有効になっていると考えても良いのだろうか? 特に read を widget の中で使っ
    ている時には status の高さも考慮に入れて上書きしてしまわない様にするべきな
    のではないか。という事を考えると status を有効・無効にする条件を考える必要
    がある気がする。

    現状で既に read をどの様に表示するかを呼び出している状況で区別していなかっ
    たか。つまり、どの panel で表示するかを切り替えていた様な気がする。確認した
    所、特に切り替えてはいなくて常に _ble_textarea_panel=1 に表示している様だ。

    右プロンプトについても同様に問題が生じそうな気がするのにも拘らず問題は起こっ
    ていない。調べてみると右プロンプトに関しては _ble_textarea_panel=0 の時にだ
    け有効化されて、有効な時にだけ表示される様になっている様だ。

    * fixed: 一方で、prompt_xterm_title 等は read に対しても有効の儘になってい
      る気がする。これは出力しない様にするべきなのではないか。或いは、read の中
      で一時的に別の値に設定するべきだろうか。

      ble/textarea を read 以外の textbox 等に使う場合も考えると、xterm_title
      等についてもやはり _ble_textarea_panel=0 の時にだけ表示する様にするべきの
      気がする。

    * fixed: _ble_prompt_rps1_data[12]=$rps1_enabled という行があるが現在は
      [12] は使っていないのではないか。

      f6af802c で rps1_enabled を用いて update-textmap の計算を更新する様に変更
      したが、これは [12] とは関係ない様だ。

      元々 [12] に値を代入する様になったのは cf8d9493 である。此処では
      update-textmap で rps1 が有効になっているかどうかを参照する為に [12] に情
      報を格納している。然し、先述の f6af802c に於いて最早 rps1_data[12] は参照
      されなくなった。

      という事を考えると rps1_data[12] に今現在代入しているのは削除して良い。
      (或いは現在 rps1_enabled にしているのを rps1_data[12] に代入しても良い気
      はするが、一応決定している箇所が異なる様に思われるので現状の儘にする)

    うーん。実は status_line は ble/propmt/update とはまた別の管轄の様である。
    ble/canvas/panel/render から呼び出された時に表示している気がする。特に
    ble/prompt/status#panel::render が呼び出された時に、正しく表示されるべき時
    は表示し表示されない時は表示されない様に実装されているのか。特に getHeight
    で変な値を返していないかだとかが気になる。

    どうやら _ble_edit_layout が normal に戻ってしまっている様だ。本来
    _ble_edit_layout はずっと command のままであるべきであるのにも拘らず。何処
    で _ble_edit_layout が設定されるのは、特に command 以外の値に設定されるのは
    leave-command-layout だけである。確認してみるとどうやら
    ble/application/render で leave-command-layout が呼び出されている様子である。

    * できるだけ明示的に enter-command-layout と leave-command-layout を対にし
      て実行する事にした。

    * .insert-newline で enter-command-layout をしているが、それに対応する
      leave-command-layout を正しく記述する必要がある。

      .insert-newline の呼び出し元。確認してみたがとても沢山ある。

      ./src/edit.sh:1491:    _ble_edit_line_disabled=1 ble/widget/.insert-newline
      ./src/edit.sh:6687:  _ble_complete_menu_active= ble/widget/.insert-newline "$opts"

        ./src/edit.sh:6701:  _ble_edit_line_disabled=1 ble/widget/.newline keep-info
        ./src/edit.sh:6750:    ble/widget/.newline keep-info
          keep-info を指定している時には問題ない。

        ./src/edit.sh:6782:  ble/widget/.newline
          これはコマンド実行
        ./src/edit.sh:6865:    _ble_edit_line_disabled=1 ble/widget/.newline
          ble/widget/edit-and-execute-command.edit
          これは最終的に ble-edit/exec/register に至る。

      ./src/edit.sh:6760:    _ble_edit_line_disabled=1 ble/widget/.insert-newline
      ./src/edit.sh:6770:      _ble_edit_line_disabled=1 ble/widget/.insert-newline
      ./src/edit.sh:9219:      ble/widget/.insert-newline
      ./src/edit.sh:9221:      _ble_edit_line_disabled=1 ble/widget/.insert-newline
      ./src/edit.sh:9871:  _ble_edit_line_disabled=1 ble/widget/.insert-newline
      ./src/edit.sh:9880:  _ble_edit_line_disabled=1 ble/widget/.insert-newline
      ./src/edit.sh:9905:  _ble_edit_line_disabled=1 ble/widget/.insert-newline
      ./keymap/vi_test.sh:424:  _ble_edit_line_disabled=1 ble/widget/.insert-newline

      うーん。一旦 disable して出力して再び描画するというパターンが多い気がする
      のでこれは関数にするべきなのではないかという気がする。と思ったが、出力に
      用いるコマンドが色々なので、eval の様な形になるだろうか。少々面倒の気がする。

    * done: ble/edit/info refactor

      aplication/render で leave-command-layout を実行しているのは info をこの
      時点で表示させるのが目的だった可能性? 恐らく高さの計算は info/render を呼
      び出さないと分からないので先に計算させているのだろうという気がする。

      これは本来 getHeight の段階で正しく計算して返すべきである。現在の設計では
      info 自体は自身が有効化されているかどうかを把握していなくて外部から表示・
      非表示を制御する構造になっているのがいけないのではないか。

      というよりそれを言い出すと textarea も同様なのではないか。textarea の表示
      非表示はどの様に制御されているのだったか → _ble_textarea_panel が一致し
      ていれば更新する。もし一致していなければそのままにする。もしくは "0:現在
      の高さ" を返しているので潰れてしまう事は許容している (_ble_textarea_panel
      が復元した時に改めて再描画するという事なのだろう)。そういう意味で
      _ble_textarea_panel=-1 等にする事によって textarea を完全に off にする事
      も可能である。或る意味、自身で表示・非表示・(現在の状態を保持) の状態を保
      持していると言える。info についてもその様な状態を保持させて管理するべきの
      気がする。それは getHeight の段階でちゃんと参照する様にする。

      改めて確認したが問題はそんなに簡単ではない様な気がする。そもそも render
      の段階では info の内容は決定されない。そういう意味に於いて別に問題は起こ
      らない筈。問題が起こるのは、ble/edit/info/reveal を実行する事によって内容
      を改めて構築し直す必要があるという事の気がする。何故そうなっていたのかと
      いうと enter-command-layout に入る時に info の内容を消去しているから。

      * 現状では既に leave-command-layout が何処かで呼び出されている前提なんで
        改めて info/reveal を呼び出す必要はない。leave-command-layout が呼び出
        された時点で info の内容も再構築されている筈だから。

      x と思ったら起動時に info が表示されなくなってしまった。うーん。改めてど
        ういう条件で再描画が必要になるのか整理して、再描画が必要になった箇所で
        必ず invalidated を設定する様に修正する必要がある。

        うーん。何だか分かった様な気がする。高さが 0 だとそもそも invalidated
        のチェックすら来ないという事なのではないか? と思ったがそれも変である。
        例え invaldiated であっても panel::getHeight は呼び出される筈だから。

      改めて info が一体どの様にして状態を管理しているのか確認するべきである。
      或いは再設計する。_ble_edit_info はもし info が表示されていたとしたら表示
      されている内容である。_ble_edit_info_default は既定の内容であってこれは
      scene が default になる時に表示される内容である。現在はどうも info が表示
      されていないという状態も _ble_edit_info で取り扱おうとしているのが混乱の
      原因になっている気がする。

      * ok: ble/edit/info/hide を使っている箇所はあるか → 一箇所しかない。これ
        は info#collapse に置き換えたと思って良い。

    * うーん。構造的にもっと別の方法にした方が良いのかもしれないとも思われる。

      ! つまり、render の側でコマンド実行中かそうでないかで動作を切り替える。コ
      ! マンド実行中でない時には何れにしても leave-command-layout はコマンド実
      ! 行終了後に有効にする。

      コマンド実行中にだけ command-layout にするというのの方が正しいのではない
      か。とも思ったが、enter-command-layout の時点で実はプロンプトや status,
      info 等を削除して command-layout に入っている。という事を考えると、やはり
      現状の実装の方が正しい様な気もする。

      例えば、仮にその場でだけ command-layout になって、一旦はまた通常 layout
      に戻って、それからその後でまた command-layout になってコマンドを実行する
      とどうなるのだろうか。

    x 空のコマンドしか実行しない状態になっていると leave-command-layout の実行
      が抜けてしまうのではないか。

      a 空のコマンドがあるかどうかは呼び出し元でちゃんとチェックする前提として、
        gexec の側ではスキップは行わない。

      b 空のコマンドしかない場合でも leave-command-layout は必ず実行する様にす
        る。

        然し、そうするとこれは .end の後で実行するしかなくなるが、.end の中で
        .tail まで呼び出しているので、.end の後で leave-command-layout を実行し
        ても意味がない。改めて .tail 及び再描画を呼び出す必要があって無駄である。

        或いは、空のコマンドしか無い場合は特別扱いで leave-command-layout と
        .tail を両方呼び出す様にする?

      うーん。a の方法の方が良い気がする。

      結局 ble-edit/exec/register の側でもチェックを入れる事にした。一部でチェッ
      クが重複する事になるが、その方が安全であるし、論理的にすっきりしている。

    x fixed: と思ったが複数のコマンドを実行して一部は leave-command-layout を実
      行して一部は実行しないという状態になったら一体何が起こるのだろうか。。一
      番最後に実行した物が leave-command-layout を実行していると何だか変な事に
      なる気がする。

      或いは、_ble_app_render_mode として panel の他に command も用意して、
      command の時には reveal を実行せずに ble/canvas/panel/render を実行する?
      panel の時には leave-command-layout を強制的に呼び出す様にする。コマンド
      を実行している間は _ble_app_render_mode=command とする。その方が今迄の実
      装に近いしすっきりしている様な気もする。

      然し、論理的に正しい事をしているのかどうかというのは良く分からない。

      うーん。これに関しては enter/leave で単に既に command かどうかを判定する
      のではなくて、enter/leave の深さを数える様に変更する事にした。

2022-03-03

  * [解消] 2021-11-21 bash-3.2 で syntax highlighting がロードされるのが遅い [#D1799]
    もしかして遅延している?

    Ref #D1731 重複

  * 2022-01-19 PS1 のディレクトリ名に特殊文字が含まれている場合の取り扱い [#D1798]
    https://lists.gnu.org/archive/html/bug-bash/2022-01/msg00051.html

    これは不要な互換性の問題を防ぐために Chet がどの様に対処するのかを見てから
    それと同じ様に実装するのが良い。

    またその他の文字列についても同様に注意が必要なのではないかと思われる。
    と思ったが他に任意の文字列を出力する様な状況もない様な気はする。

    2022-03-03 これは結局何の修正も入らない様だ。うーん。勝手に ble.sh の側で対
    応してしまっても良い。

    zsh は ^J や ^I に対しても特別な表示にするのだろうか。それともこれらはその
    まま表示するのだろうか。と思って試して見た所、単に \n や \t に置換して表示
    する様だ。\001 に対しては ^A と表示する。ESC は ^[ と表示する。

    やはり反転する等して強調した方が良い様な気がする。本当にそういう名前を持っ
    たディレクトリ名と区別が付かない。新しく trace に SGR(9807) という反転状態
    を toggle する番号を追加する事にした。

  * main: ble/base/unload 後に ble/util/assign 一時ファイルが残留する [#D1797]

    ble/base/clean-up-runtime-directory で毎回 rm が実行されている。どうやら前
    回の session が最後に assign に実行をしてそれで一時ファイルが作成されている
    様だ。

    ble/base/unload を実行した後に trap/.handler で joblist.check を呼び出して
    いるのが原因である。或いは、joblist.check は unload 状態にある場合には実行
    しなくても良いのではないか。然し、改めて確認すると unload の状態にあるかど
    うかを記録している変数はない様だ。そう思うと EXIT の時だけの特別扱いとして
    joblist.check をスキップするという可能性? 或いは、unload を実行した時点で
    ble/util/assign を使わない実装に切り替える?

    a ble/util/unload は trap/.handler 以下で直接実行する。結局勝手に削除されて
      は困る物だし、最も重要な物の一部でありモジュールを疎結合にする必要性も薄
      い。という事を考えると、unload は特別扱いしても良いのかもしれない。

      然し、そもそもの問題として trap handler を jobs で囲んでいた理由を考える
      と、やはり unload であっても囲んで実行した方が良い可能性はあるのだろうか。

      ? というよりそもそも何故 jobs で囲んでいたのだったか。

        思うに、trap handler の中等で外部コマンド等を実行するとその分だけ job
        項目が累積してしまう問題を防ぐのが目的だった気がする。今正に終了しよう
        としている段階で jobs を表示する機会はない気がするので気にしなくても良
        いのではないだろうか → 2回目の joblist の呼び出しは正に
        ignore-volatile-jobs で呼び出しているので無視するのが目的である。

        問題が起こるとすれば user trap の中で jobs を呼び出した時にごみが沢山表示
        される可能性があるという事だが、其処で変な物が表示されても大した問題では
        ない様な気がする。というより、そもそも ble.sh がジョブ一覧を管理している
        時点で user が実行した jobs からは特定の項目が受け落ちている筈だから、な
        い筈の物があるぐらいならそれに比べれば大した問題ではないのでは? という考
        え方もできるかもしれない。

      ? user trap を jobs で囲む必要性はないのだろうか。

        これは本来は user trap の中で発生した余分な jobs entry も削除してしまっ
        て良い気がするが、もしかすると本当に job を投げるという事があるかもしれ
        ないので、その項目が意図せず消滅しない様に囲むのはやめたのだろうという
        様に思われる。何れにしても今回は関係ない。

      ? そもそも EXIT の中から終了をキャンセルする事は可能なのだろうか。或いは、
        他の要因によって終了がキャンセルされる可能性はあるのだろうか。考えて見
        るにその様な方法は存在しない気がする。という事を考えると、jobs の情報を
        収集しても仕方がないのではないかという気がする。

      o ユーザーが登録した何かが ble.sh に依存しているという可能性もあるのでは
        ないか。という事を思うと、やはり unload は外側で一番最後に実行するべき
        の気がする。

    b 或いは、EXIT の時だけは joblist.check はスキップする。或いは unload して
      いる事を何処かに記録するなどして、それに応じて joblist.check をスキップす
      る。

    c 或いは unload の際に ble/util/asign を書き換えてコマンド置換を使う様にす
      る → 然し、そうすると環境に影響を与える事を前提としている
      ble/util/assign の呼び出しに対して正しく対処できなくなる。特に今回問題に
      なっている joblist.check の呼び出しは環境に対する影響を前提としているので、
      この方法では正しい解決方法にはならない気がする。

      また、この方法だと結局 fork の回数が終了時に余分に増える事になるので合計
      では実行時間は減らない。寧ろ、複数回の ble/util/assign がある様なので、そ
      れによって合計時間は増えてしまっている。(但し、終了時なのでユーザー体験を
      損ねる事はない様に思われる。)

      現在の文脈を変える為に >/dev/null に繋いで現在の環境でも実行するという事
      もできるかもしれないが、もしそのコマンドがファイルシステム等に副作用を齎
      す物だった場合、二回実行する事によって結果が変わってしまうし、また実行時
      間も二倍になるし良い事は何もない。

    d 或いは unload している時には何か別のファイルを一時ファイルとして
      ble/util/assign を利用する? 然しもしその様なファイルを簡単に安全に作れる
      のであれば始めから ble/util/assign は必要ないのでは。

      或いは unload している時は ble/util/assign/.rmtmp に於いて rm を明示的に
      実行する様にする。然し、これだと結局 fork の数は増えるので意味がない。然
      し、少なくとも動作が変わってしまう c よりは現実的な方法である。

    # ? 所で here document 等を一時ファイルの代わりに使う事はできるのだろうか。
    #   と思ったが、最近の bash では here documents は一時ファイルではなく pipe
    #   になってしまっているので使えない。
    #
    #   試しに以下を試してみたらファイルの読み書きが出来てしまった。
    #
    #   $ bash-4.4 -c '{ echo check world > /proc/self/fd/0; cat /proc/self/fd/0; } <<< hello'
    #
    #   然し、bash-5.0 以上では失敗する。bash-5.0 以上でファイルにする為には大
    #   量のデータで初期化しなければならないので非現実的な気がする。その他に
    #   bash が一時ファイルを生成しそうな場合はない気がする。プロセス置換は
    #   pipe である。
    #
    #   更に本当にどのシステムで動くのかも定かではない。どうやら bash は一時ファ
    #   イルを早々に unlink してからコマンドを実行する様である為。

    結局 a の方法で、ble/base/unload は別枠で trap handler の最後で実行する事に
    した。

2022-03-02

  * 2022-02-03 edit: もしかしたら stty sane の頭に空白を置くと良いのでは [#D1796]

    先頭に空白を置いたコマンドの履歴登録をなしにする設定にしている人がいる。

    或いは勝手に stty sane を HISTIGNORE に設定するという手もある? と思ったが、
    それだとユーザーが本当に自分で stty sane を実行した時に履歴に残らないし、或
    いは HISTIGNORE を一旦保存して復元する仕組みを作ったとしても何かの拍子に実
    行できなかった時にやはり困るし、余り信頼性が高いとは言えない。

    これた簡単だが採用する。

  * 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

    chat では再現しない。bash-completion はロードされていない。

    うーん。これは 2365e09c によるバグである。今迄5ヶ月間ずっと mandb を正しく
    抽出する事ができていなかったという事になる。今迄何故気付かなかったのだろう。
    不思議である。或いは、また別の方法によって抽出できていたという事か? → そう
    いう事だ。つまり、Linux 等では man -w 等を使ってファイルを決定できていたの
    で問題がなかったのである。

  * edit (exec_elapsed_mark): やはり既定で時・日などの分解能の表示にも対応する [#D1793]

    長時間ログインしていた後等にはやはり長い時間経過している事がある。
    その時に常に分で表示されると分かりにくい。

  * canvas: BUG 何故か2回目の char_width_@=auto がちゃんと動いていない気がする [#D1792]
    Ref #D1669

    何故だろうか。後で確認する。

    改めて試してみたがゆっくりやれば何度やっても問題はない。auto を代入してから
    急激に RET 等を実行するとそれ以降は常に west, 7.0 にしかならなくなる。CPR
    応答の順序がずれてしまっている可能性? 何処かのタイミングでずれを修正したら
    治るのだろうか。

    * _ble_term_CPR_hook に何か変な物が残存している可能性を確認。

      →分かった。逆だった。timeout のコードが悪さをしていた。timeout 時刻の更
      新を行っていなかったので常に timeout する状態になっていてまともに CPR が
      受信できなくなっていた。 west, 7.0 というのは CPR 応答がなかった時の既定
      の値という事だろう。

    ! ? そもそもどの様にしてずれが起こるのか。初めのずれが起こらない様に調整でき
    !   るのではないか。

    結局 #D1669 の単純なバグだった。修正した。

  * blehook -+= は入力しにくいし見にくいので != を一意追加として対応する [#D1791]

    * done: !=  ... 未だ登録されていない時に追加する
    * done: -+= ... 後ろに持ってくるという意味に変える。
    * done: +-= ... 前に持ってくるという意味で追加する。

    * update wiki

  * complete: sabbrev を削除する機能がない [#D1790]

    削除の仕方としては以下の2種類が考えられる。

    ble-sabbrev -r a # bind, complete と同様
    ble-sabbrev a=-  # trap と同様

    後者は本当に "-" に展開させたい時 (実際そういう場合が存在するのかは謎だが)
    と衝突するので前者の方が良い気がする。

    また、前者を採用するとしたら -r に対して optarg を要求するのか、或いは -r
    に対して optarg を要求するのかで振る舞いが変わってくる。

  * progcomp: ble.sh 既定の候補を生成しない機能 (motivated by rsteube) [#D1789]
    https://github.com/rsteube/carapace/issues/431

    > prevent default file completion when no values returned

    このオプションを提供する事にする。

    現在 "候補が生成されていたら" という意味で生成候補数を参照している箇所を全
    て書き換える必要がある気がする。

    後 core-complete の中から公開 interface を決めてそれを説明する必要がある気
    がする。

    * 拡張 comp_opts をまとめる。prog-trim, syntax-raw, filter_by_prefix,
      no-mark-directories

      現在参照している comp_opts は以下の通り。

      $ grc '(comp_opts|DATA):? =='

      元から bash に存在しているオプションは以下の通り:
      bashdefault default dirnames filenames noquote nosort nospace plusdirs

    * done: 拡張オプション名は分かる様にした方が良いのでは。例えば ble- で始め
      る。或いは、- で始める。もしくは -ble- で始める。

      " a -prog-trim, -syntax-raw, -filter-by-prefix, -no-default
      "
      "   うーん。- だけだと結局ユーザー的には混乱の元であるというより、すぐにそ
      "   れが "ble.sh" 特有の機能であると理解しにくいのではないかという気がする。
      "   然し一方で "-" で始まっている時点で非標準の機能であるという事は明らかで
      "   ある。
      "
      " b ble-prog-trim, ble-syntax-raw, ble-filter-by-prefix, ble-no-default
      "
      "   ble- だけでも十分の気がするが、これだと名前空間的になっていて、もっと細
      "   かく分類したくなってしまう。
      "
      " c -ble-prog-trim, -ble-syntax-raw, -ble-filter-by-prefix, -ble-no-defualt
      "
      "   CSS の vendor prefix の様に -ms- だとか -moz-, -webkit-, -o- の様にして
      "   いる物を真似て -ble- だとか -mwg- だとかで良いのではないかという気がす
      "   る。-mwg- は今迄使った事がないので ble.sh には組み込まない様にしておき
      "   たい。
      "
      "   然し、一方で、他の compopt の枠組みが今後出てくる様にも思われないし、対
      "   応していない物を bash に渡したら何れにしてもエラーになるので、結局汎用
      "   の補完を作成するとしても呼び出し元で場合分けする事になる。なので vendor
      "   prefix の様な物を設定して場合分けに使える様にする必要があるのかも分から
      "   ない。この様に名前を分けるのは主にユーザーの側でこれが非標準であるとい
      "   う事が分かる様にする為の物である。
      "
      " どれにすれば良いか分からないが、長いものを採用する上で憚りになるのは、単
      " に無駄な prefix がついていると読みにくいという事、冗長になるという事であ
      " る。一方で、ユーザーや他の人の意見も聞いて最終的に決定するとなると、何れ
      " にしても "ble" は入れた方が良いという様に要請されるのは明らかである。
      "
      " 然し、既に様々の ble.sh の独自機能に使われている opts では ble- 等の
      " prefix は使っていないし、今後使う必要も全く無い。その様な物との整合性を考
      " えると、やはり特別な prefix は特につけなくても良いのではないかという気も
      " してきてしまう。一方で compopt はやはり本来は Bash の機能なので名前空間を
      " 乱すのも変である。
      "
      " うーん。面倒なのでやはり何も新しい prefix は付けずに manual で説明・注意
      " 喚起するだけで十分なのではないかという気がしてきた。うーん。本当だろうか。
      "
      " うーん。- で始まる prefix はそれ単体でオプションの様でもあるからやはり混
      " 乱の元の気がする。と思えば prefix を設定するとしても "ble-" 一択の気がし
      " てきた。
      "
      " d 或いは compopt -o prog-trim ではなくて compopt --bleopt prog-trim だと
      "   か、compopt -O prog-trim だとか、compopt -s prog-trim の様な形の別の指
      "   定の仕方をさせるという手もある。内部的には -prog-trim 等で良いのだろう
      "   という気がする。compopt は実質的に -o, +o だけしかオプションがない (一
      "   応 -DEI もある)。或いは prog-trim=on 等でも良いかもしれないと考えたが、
      "   これは compopt を適用する対象のコマンド名と区別がつかなくなるので駄目。
      "   飽くまでオプションの形をしていなければならない。オプションの形をしてい
      "   る物については仮にそのオプションが存在していなかったとしてもちゃんと知
      "   らないオプションとしてエラーになる様である。
      "
      "   compopt -s prog-trim; compopt -u prog-trim
      "   compopt -O prog-trim; compopt +O prog-trim
      "   compopt -o prog-trim; compopt +o prog-trim
      "   compopt -o ble-prog-trim; compopt +o ble-prog-trim
      "   compopt -o -prog-trim; compopt +o -prog-trim
      "
      "   うーん。やはり奇を衒った様な事をするのではなくて単に -o/+o を流用するの
      "   が自然の気がする。"-" で始まるのも混乱の元である様に思われる。
      "
      "   compopt -prog-trim; compopt +prog-trim
      "
      "   これは短オプションの集合と区別が付かないので却下。
      "
      " e もう少し異なる名前付けで区別する可能性
      "
      "   compopt -o _prog_trim
      "   compopt -o progTrim
      "   compopt -o ProgTrim
      "
      "   これらは Bash のオプションとは違うという雰囲気は出るかもしれないがやは
      "   り ble に関連するという事が明白ではないし、中途半端に違いを出しても仕方
      "   がない。
      "
      "   いっその事、関数名に倣って / で分けるというのも手である。
      "
      "   compopt -o ble/prog-trim
      "   compopt -o ble/filter-by-prefix
      "   compopt -o ble/syntax-raw
      "
      "   よくある設定の様に "." で名前空間を分けるというのも有効である。
      "
      "   compopt -o ble.prog-trim
      "   compopt -o ble.filter-by-prefix
      "   compopt -o ble.syntax-raw
      "
      "   うーん。contrib 等との整合性も考えると / で分けるのが良い気がしてきた。
      "   つまり、既に "名前 + /" を vendor prefix の様に使って来たのだからそれを
      "   踏襲するのが良い。新しい option は ble/no-default という事にする。

      結局 "ble/*" で統一する事にした。

    [実装]

    取り敢えず実装した。

    * ok: うーん。然し、もし source:argument をキャンセルしたとしても、結局また
      別の source が候補を生成するのではないかという気がする。全ての source を
      キャンセルする必要があるだろうか。或いは、また別の source は別の種類の補
      完に相当するので気にしない? うーん。気にしないで良い気がしてきた。

      それに、候補が複雑な場合には何れにしても source:argument は何も候補を生成
      しなくなるが、その時に意図しない別の種類の補完が起動したという記憶はない。
      従って、実際の所 source:argument をキャンセルするだけで大体補完は終わるの
      ではないか。つまり、argument を跨ぐ様な補完 source は現在はないので
      source:argument が一番最後の source であり、だとすると source:argument を
      キャンセルするだけで良い。

      もし argument を跨ぐ様な補完の可能性があれば、それはまた完全に独立した補
      完なので progcomp によって補完がキャンセルされる言われもない様な気がする。
      これは今後実際にそういう要望が (仮に) 出た時に考えれば良い。

2022-03-01

  * complete (action:command): function の description の quote が邪魔 [#D1788]

    最初の2行と末尾の } は削除して良い。また、quote ではなくて trace-text と同
    様の表示の仕方にしたい気がする。

    trace-text と同様の文字列に変換する関数は既になかったか?

    うーん。ble/unicode/GraphemeCluster/.get-ascii-rep という関数があるがこれは
    内部的にしか使用されていない。一方で、うーん。というか
    ble/canvas/trace-text をそのまま呼び出すべきの気がしてきた。そもそもその為
    の関数の筈である。

    或いはファイル名と行番号を表示した方が有益の気もする。取り敢えず両方表示す
    る事にした。ファイルパスは長くなるので最後の名前だけ表示する事にした。

  * complete: --optarg= に対して progcomp が走らない (motivated by rsteube) [#D1787]

    これは "--optarg=" 全体に対する引数補完よりも = の右辺 "" に対する優先順位
    が高いから。

    [導入経緯確認]

    然し、この様に引数の途中に = が含まれる時に rhs 補完も実行する様にしたのは
    何か別の理由があった様な気もする。その時の記録を確認する必要がある。遡る。

    da384044 #D1701 で変更されているがこれで導入された訳ではない。と思ったが
    #D1701 よりも前は以下の様になっていて argument でない時にのみ rhs を設置し
    ていた。

    local word=${text:istat:index-istat}
    if ble/syntax:bash/simple-word/is-simple-or-open-simple "$word"; then
      # 単語が istat から開始している場合
      local src
      for src in "${source[@]}"; do
        ble/syntax/completion-context/.add "$src" "$istat"
        if [[ $src != argument ]]; then
          local rex="^([^'\"\$\\]|\\.)*="
          if [[ $word =~ $rex ]]; then
            word=${word:${#BASH_REMATCH}}
            ble/syntax/completion-context/.add "$src" $((index-${#word}))
          fi
        fi
      done

    つまり、やはり #D1701 によってこの取扱が導入された事になる。

    * reject: と、思ったが上記のコードはそもそもおかしい。source には大体複数の
      文脈が登録されているので結局 rhs は argument の有無に関係なく大体複数生成
      される事になる。と思ったが、そうではない。 add rhs ではなくて add "$src"
      としているので、 argument 以外については = 以降からでも同様に生成するとい
      う取り扱いになっている。

    * #D1701 の議論を確認したが大した事は書かれていない。特にこの取扱の変更に関
      しては全く触れられていない。然し、実際に source 配列の中身を見ると option
      という物が追加されている。これが理由なのではないだろうか。つまり、option
      という項目を追加したが、option が = の続きから挿入されるのは変である。な
      ので、option も argument と同じく途中から文脈設定する必要性がない。他に
      variable:= という物もあるが、これも途中から挿入するのは変である。command
      も sabbrev も同様である。結局、途中からの挿入を許すのは source:file だけ
      である。という事を考えれば最初から file を固定して = の後の位置に補完開始
      点を設置するのは自然である。

    然し、そもそも unquoted な = の位置から補完を開始する選択肢を加えたのはどの
    時点だろうか。

    先ず 2f2f0eb6 (#D0941 eval の引数・変数代入の対応) の時点で既にあった。どう
    やら e9ba343f (#D0744 a=[TAB] が a=a=b になる問題に対する対処) で最初に導入
    された様だ。この時点でのコードは以下の形をしている。

      if [[ $source != argument ]]; then
        local sub=${text:wbeg:index-wbeg}
        if [[ $sub == *[=:]* ]]; then
          sub=${sub##*[=:]}
          ble-syntax/completion-context/.add "$source" $((index-${#sub}))
        fi
      fi

    この時は source は配列ではなかった。つまり、$source != argument は実際に
    source に argument が含まれていないという事の確認になっていたのだった。後の
    変更で source が配列になった時にこの条件がそのまま放置されたのは恐らくバグ
    である。

    [修正方法]

    a "virtual starting point" 的な物を導入してそれに基づいて補完文脈の優先順位
      を決定する。

    b rhs の補完開始点は飽くまで単語の先頭にして、しかし補完を実際に行う時に =
      以降について候補を生成する様に調整する。この時、source:file 等を内部から
      呼び出しているが、この source:file に中途半端な位置から補完を開始する仕組
      みを取り付ける? と思ったが、COMPV, COMPS 等既に計算済みの物をちゃんと正確
      に切り出せる事を保証しなければならないなど、暗黙の仮定を色々持ち込む事に
      なり余りすっきりしない。

    c 或いはこう言った物は argument の側で全て処理するべきなのではないか?

      実際に rhs をなくしてもちゃんと動いている様に見える。うーん。だとしたら完
      全に削除してしまっても良い? これについてはやはり導入経緯を確認する必要が
      ある→うーん。どうも現在 argument と rhs の両方が生成されているのはバグの
      気がする。バグと判断して良い。そもそも argument の側でもちゃんと同様の =
      生成を実行している。

    どうも rhs と argument の両方が生成されているのは歴史的に見て元々意図した物
    ではなかった様に思われる。従って、"c" の様に argument を生成している時には
    rhs は生成しない様に修正してしまって良い。

  * complete (requote): --prefix='a b c d e' の様に prefix 部分は requote から除外 [#D1786]
    Ref #D1787

    全体を quote し直す時にオプション的な部分・もしくは変数代入的な部分は除外す
    る様にする。例えば --option=hello\ 1\ 2\ 3 が '--option=hello 1 2 3' になる
    のではなく、--option='hello 1 2 3' になって欲しいという事。

  * edit: 古い terminator で表示が乱れる (reported by dongxi8) [#D1785]
    https://github.com/ohmybash/oh-my-bash/issues/314

    要するに Terminal 0.98 が使っている vte では DECSCUSR に対応していない。そ
    れにも拘らず TERM=xterm にしているので _ble_term_Ss に値が設定されている。

    https://bugzilla.gnome.org/show_bug.cgi?id=720821#c33
    此処によると DECSCUSR は vte 0.40 で導入された様だ。

    古い version の vte で DECSCUSR を無効化するコードを追加する事にする。所で、
    vte version と値の関係がどうなっているのか調べる必要がある。うーん。vte
    0.28.2 という事なのだろうか。。。そういう気がする。実際に一番最近の
    Terminator で vte:66xx になっていて、GitLab 上の最新版は 0.67.x なので、や
    はり vte 0.28.2 という事なのだろうという気がする。vte の番号を使って判定す
    る事にする。

2022-02-23

  * edit: bash-it から detach するとプロンプトが壊れた状態になる [#D1784]
    Ref #D1772

    # #D1772 に関係はしているが直接の原因ではない。元々 PS1 が退避された状態で
    # ble-detach になってしまうのだったが、(1) PROMPT_COMMAND は待避していなかっ
    # た (2) PS1 を "待避" した後も通常の場合は PS1 の元の値をそのままにしてい
    # たという二重の理由で問題が起こらなかったのである。#D1772 によって両方の振
    # る舞いを壊した為に問題として発現した。

    oh-my-bash から抜けても同じ状態になる。nix-shell の場合には大丈夫。

    どうやら PROMPT_COMMAND に何か設定されているとこうなる様だ。何故
    PROMPT_COMMAND があるかどうかで変わるのだろうか。因みに
    PROMPT_COMMAND も退避されたままになっている。

    うーん。何故か ble-detach/message の中から ble/textarea#render が呼び出され
    ている。この時に PS1 adjust が走ってそのままになっている。そもそも何故
    ble-detach/message の中で render が呼び出されているのか? うーん。恐らく
    stty の設定の為に Bash に制御を戻しても Bash が prompt を表示してくれないの
    が問題。その為に ble-detach/mesasge を介して態々プロンプトを描画しているの
    である。

    a eval-PROMPT_COMMAND の前後の PS1 adjust/restore は attached の時にだけ実
      行する? と思ってこれで実装したが…。

      そもそも textarea#render を detached 状態で呼び出して問題は発生しないのか。
      特に、既に様々の bash option 等を設定した状態で正しく ble-detach/message
      を呼び出す事ができるのかすら非自明である。

      と思ったが ble-detach/impl は実は restore option までは未だ実行していない
      状態の様だ。単に detached state に移行するだけである。

    b 或いは ble-detach/message を表示してから ble-detach/impl を実行するべきな
      のではないか。

      うーん。ble-detach/impl の中で何か出力されたりする可能性はあるのだろうか。
      エラーメッセージなど。確認すると、呼び出されているのは以下の 3 項目である。

      blehook/invoke DETACH
      ble-edit/detach
      ble/decode/detach

      後ろの2つはともかくとして最初の1つでユーザーが何かメッセージを出力したい
      という事があるかもしれない。うーん。という事を考えるとやはり後で
      ble-detach/message を実行するべきなのだろうか。

    やはり a の方針で修正する事にした。restore-PS1 は本来 ble-edit/detach から
    呼び出される物であって、其処で管理している状態は _ble_edit_attached 変数に
    格納されているので、この変数の値に基づいて PROMPT_ATTACH の周りで
    adjust/restore を行う事にした。

    修正した。PROMPT_ATTACH を設定した状態でも問題が生じない事を確認した。また
    bash-it, oh-my-bash による動作確認もした。

  * [棄却] bashrc: .bashrc.bash-it-minimal から実行するとエラーメッセージが出る [#D1783]

    PROMPT_COMMAND に ';:' という文字列が設定されて PROMPT_COMMAND を実行する度
    にエラーが発生する。或いは、ble.sh 自体の prompt-attach に失敗している?

    →と思ったらこれは単に .bashrc.bash-it-minimal の問題だった。このファイルを
    作成した当時は --attach=prompt の時、必ず PROMPT_COMMAND に文字列が設定され
    るという事を想定してよかった。現在は bash-5.1 以上では配列を用いて第2要素以
    降に設定するので、単に ';:' という文字列を付加するとエラーが発生するのだっ
    た。

2022-02-20

  * edit: work around exit called from EXIT trap (reported by SuperSandro2000) [#D1782]
    https://github.com/akinomyoga/ble.sh/issues/179#issuecomment-1046122787

    nix-shell の内部で exit を実行すると2回 [ble: exit] が表示される。これは
    nix-shell が設定する EXIT trap の中で再度 exit が呼び出される為である。
    ble.sh は独自に trap を処理しているし、また blehook EXIT も実行したいので、
    勝手に EXIT の中から本当に exit されると困る。なので、trap handler 実行中に
    ble/builtin/exit が呼び出された時には DEBUG trap を設定して、trap の呼び出
    し元まで制御を戻して続きの処理を実行することにする。呼び出し元まで戻った時
    に exit が trap handler の中で呼び出されたという事を記録しておいて、trap
    handler の処理の終わりに元々呼ばれた exit を呼び出し直す。

    * exit を trap handler の中で実行した時にはそのまま終了するのではなくて、
      trap の処理が完了するまで待ってから終了するべきなのではないか → その様に
      実装した。既存の TRAPDEBUG の枠組みにコードを追加して実現した。

    x fixed: exit 1 2 の様に余分な引数を指定した時、exit の準備をして [ble:
      exit] まで表示した後に exit: too many arguments のエラーが発生して exit
      がキャンセルされる。事前に引数の問題はチェックするべきである。

    取り敢えず実装して 3.0, 3.2, 5.0 で動作確認した。期待通りに動いている。以下
    のコマンドなどを使ってちゃんと全ての EXIT handler が実行される事を確認した。

    $ trap 'exit 5' EXIT; exit
    $ trap 'echo trap EXIT' EXIT; f1() { echo "$FUNCNAME $*"; exit "$1"; }; blehook EXIT+='f1 2 hello' EXIT+='f1 3 world';exit

    ? 関係ないが jobs がある時にユーザーが exit をキャンセルした時、後続の処理
      が実行されるのは問題ではないか? これに対しても何らかの対処が必要になるの
      ではないか?

    ? もし現在の TRAPDEBUG の枠組みが信用できるのであれば try/catch の枠組みを
      整備しても良いのかもしれないという気がする。その方が見通しも良いのでは。
      然し同じ commit でやるのは大げさな気がする。

      上記の exit キャンセルの際の振る舞いに関してはその枠組が整ってから対応す
      るのが良い気がする。

    →上の2つは別項目で処理する事にした。

    x bash-5.2 以降で EXIT trap の stdout が /dev/null になっている。これはどう
      したら良いのだろうか。うーん。EXIT trap の時だけ stdout/stdin を繋ぎ直す
      のが良いだろうか。

      調べてみた所 bash-5.2 以降では exit も EXIT handler も現在の関数の内部で
      行われる様だ。これは bash-5.1 までの top-level で実行されていたときと振る
      舞いが異なる。と思ったが、bash-4.4..5.1 の振る舞いが変だっただけの様だ。

      うーん。builtin exit を呼び出す時の redirection を削除するか? と思ったが、
      それだとやはり余分なエラーメッセージが出るのが心配である。という事を考え
      ると、元々の stdout/stdin を何処かに記録しておくべきなのだろうという気が
      する。

    2022-02-20 exit を DEBUG return で再現しようとしても　DEBUG trap の対象であ
    る "現在のコマンド" は必ず実行されてその後で return/continue 等の効果が現れ
    る。なので blehook 内での exit は意図した動作をしない。

    % blehook の中で exit をしても trap の実行が其処で終了しない。continue が実
    % 行されている筈なのに効いていないのは何故だろうか。うーん。eval の中から
    % continue を実行しても効かないのだろうか。
    % →それとも bash の特定の version を使っている事によるバグだろうかと思って
    % 振る舞いを確認したが、4.0..dev まで全て同じ振る舞いである

    →うーん。振る舞いを調べて分かったのは、DEBUG trap が呼び出された対象のコマ
    ンドは結局何れにしても実行される様だという事。例えば continue を trap 内部
    で実行すると、確かにその場で continue によって制御が変更され、trap 内の続き
    の処理も実行されない。そしてtrap の外側にあるループを抜ける。然し、その前に
    DEBUG trap の対象であるコマンドはちゃんと実行される様だという事。

    ? このコマンド実行をキャンセルする方法はないのだろうか。extdebug が設定され
      ていれば trap の戻り値によって振る舞いが変わるらしい。特に 2 を返せばその
      場で return を実行する事ができる。然し、continue をその場で実行する方法は
      不明である。continue が成功すれば戻り値は 0 になるので DEBUG 対象のコマン
      ドは結局実行される。逆にそれを阻止する為に戻り値を 0 以外にしようとすると
      continue を失敗させるしかなく、それだと次のループに移る事ができない。或い
      は BASH_COMMAND を書き換えたら実行するコマンドを書き換える事ができると言っ
      た事はないのだろうか。

      実際に extdebug を設定して試しても見たが、マニュアルから予想される通り、
      continue が成功すればコマンドも実行するし、コマンドの実行をキャンセルする
      には continue を実行する訳には行かない。continue 直前の終了ステータスを変
      更しても何の効果もなかった。つまり、continue 自体の戻り値が使われる。

      他に次のコマンドを無効にする手法はないのか? というか次のコマンドを無効に
      したとしても更にまた次のコマンドが実行されるというのだと際限がない。なの
      で、やはり extdebug を一時的に設定して 2 を返す事によって実行を中断させる
      しかないのだろうか。

    * extdebug を一瞬有効にして return (終了ステータス 2) でトップレベルまで戻
      るしかない気がする。

      ? extdebug は trap の中で無効化した場合でもその trap に対して失効するのだ
        ろうか。これについては振る舞いを確認する必要がある。→やはり trap の中
        で shopt -u extdebug すると即座に extdebug の動作はしなくなる様だ。ちゃ
        んとどの bash の version でも同様である事を確認した。

        だとするとどの時点で extdebug を off にするのかについて確認が必要になる。
        然し取り敢えずは sandbox の中で実行しているのであればその呼出元で解除す
        る様にすれば良い。※という事は、sandbox の中では未だ DEBUG trap は
        clear はしないという事になる。

      うーん。取り敢えず実装した。動いている。というかそもそも元々 continue を
      hook の中で実行する事を許していたのが変な気もする。或いは、continue 及び
      return を使って他の hook の処理に干渉したりできるというのも一つの機能だっ
      たかもしれないが、それならそれで別の枠組みを提供するべきの気もする。或い
      は、もし return continue を使うとしても trap sandbox の様に終了の仕方を検
      出して制御を決めるのが良いのだろうという気がする。

      現在は現状のままで良い気がしている。

2022-02-19

  * 2022-01-20 \C-x\C-v で bash-completion や terminal ID 等の情報も出力する [#D1781]

    bash-completion や oh-my-bash の version と terminal ID について C-xC-v で
    出力したい。

    * それを issue 報告に貼り付ける様にお願いする。

    * terminal ID / version をちゃんと検出する様にする。DA2R も一緒に出力するべ
      き。

    * bash-it には version 等は存在しないのだろうか。うーん。だからといっていき
      なり要求するのも違う気がする。

    2022-02-19 取り敢えず実装した。基本的には過去に ble.sh に対して問題を起こし
    た物を検出して表示する事にするのが良い。

    他の候補として oh-my-bash, bash-it, sbp, bash-preexec, starship 等がある。
    全てを検出して表示するのは変な気もする。oh-my-bash, bash-it については現在
    の theme (及び有効化しているモジュール) も表示すると良いのだろうという気が
    する。oh-my-bash については古い物だと version が存在していない。

    * done: bash-preexec は是非検出するべきである。

    * done: oh-my-bash の検出は upgrade_oh_my_bash 等を使うのが良い様に思われる。

    うーん。個別の設定を ble.sh 本体に入れるのも変なので contrib に含めようと思っ
    たが、然し、それはそれでどういうファイル名にしたら良いのかが分からない。こ
    れはユーザーが新しく設定を追加するという形の物ではなくて、逆に ble.sh から
    blesh-contrib に依存するという形になるので取り扱いが難しい。やはり取り敢え
    ずは ble.sh 本体に含めておくのが良いのだろうか。或いは init-*.sh の様に補助
    スクリプトとして保持するのが良いのかもしれない。うーん。

    →取り敢えずは ble.sh 本体に埋め込む事にする。肥大化してきたら
    blesh-contrib に新しくこう言った振る舞いの制御の為のディレクトリでも作って
    其処に登録する事にする。

    * done: starship
    * done: bash-it
    * done: sbp
    * git: gitstatus

    取り敢えず思いつく物は全て登録したのでOK。

2022-02-19

  * trap: 初期化時に既存の trap がある時にエラーメッセージが出る (reported by SuperSandro2000) [#D1780]
    https://github.com/akinomyoga/ble.sh/issues/179

    初期化時に以下のメッセージが出る。

    $ nix-shell -p hello
    bash: ble-edit/exec/save-BASH_REMATCH: No such file or directory
    bash: ble-edit/exec/restore-BASH_REMATCH: No such file or directory

    これは一番最近の commit で起こった事だった。新しく既存の trap　を保持する様
    に修正したが、その時に既存の trap は

    * そもそも trap の内部で使うのだから {save,restore}-BASH_REMATCH は移動するべきでは。

      →ble.pp に移動した。また同時に source ble.sh 直前の BASH_REMATCH を保持する様に修正した。

    * reject: ble/builtin/trap を実際に呼び出す必要はなくて単に値を代入すれば良
      いのではないか? その他にしなければならない操作などがあるだろうか。確認す
      る。と、思ったが解析するのも面倒である。という事を考えれば、やはりそのま
      ま実行する方が良いのではないか。一応 eval して配列に代入すればその3番目の
      単語として trap_string を取得する事はできる。

      うーん。やはり {save,restore}-BASH_REMATCH さえ移動すれば今の実装で良い気
      がする。下手に自前で実装するよりも既にある実装を使った方が (効率は悪いか
      もしれないが) コードの管理という点では良い。また、この部分は到底ボトルネッ
      クではないので速度を重視する必要も全く無い。

    * ble.pp でも BASH_REMATCH を保持する様に修正するべきでは。

    [動作確認]

    x fixed: source ble.sh の前後で BASH_REMATCH が保持される事を確認する。

      と思ったら保持されていない。どうやら restore-BASH_REMATCH の数がバランス
      していない様だ。元々 BASH_REMATCH の復元にはチェックが入っていなかった。
      という事は、これは意図的に重複して retore-BASH_REMATCH を呼び出す様になっ
      ていたということではないのか。gexec での使い方について改めて確認する。

      うーん。別に余分に実行しているという事もない。単に ble-attach で adjust
      し忘れているのが原因に思われる。

      →ble-attach に追加した。更に {adjust,restore}-bash-options と同じ箇所で
      ちゃんと呼び出す様に全体をチェックして追加した。

      →また _ble_bash_BASH_REMATCH_level が負になっていたので、負にならない様
      にチェックを追加する。

2022-02-18

  * command-help: 関数の help として関数が定義されたファイルを表示する [#D1779]

    関数の定義位置を DEBUG trap 等を使って抽出する事が可能なのではないか?

    これは bash_completion の debug の時にも便利である。というか、
    bash_completion の version を表示するのにも使える。

    と思ったら shopt -s extdebug; declare -F 関数名 で普通に取得できるのだとい
    う事が判明した。
    https://www.cyberciti.biz/faq/how-to-find-bash-shell-function-source-code-on-linuxunix/

2022-02-17

  * main, edit: 起動時に無駄に PROMPT_COMMAND が実行されるのを防げないか [#D1778]

    PS1 に含まれるコマンド置換も同様である。画面サイズが変わる等しない限りは再
    計算する必要はない筈である。

    今試してみたがそれほど無駄に実行している訳でもない様に思われる。

    * 但し、_ble_history_count が初期化される前と初期化された後で
      PROMPT_COMMAND が再計算されていたのは修正する事にした。これで恐らく起動時
      刻も短くなったのではないかと思われる。これで1回実行が減少した。

    * 実は #D1772 の時点で既に1回実行を減らしている筈である。PROMPT_COMMAND を
      待避した事によって減っていると期待する。しかし本当にこれで減ったのだろう
      か。怪しい → 試して見た所 manual attach の時に回数を一回減らす事ができて
      いると判明した。

    これで合計で4回実行されていた #D1772 の状況を再現できた。更に減らす事は可能
    だろうか。現在 prompt-attach を使っているが、ble-attach の時にはもっと減っ
    ても良いのではないか? → 確認してみると manual attach の時には
    _ble_history_count が bashrc の中で 1 で、その後で実際の数に増えるという事
    の様である。

    * うーん。そもそも PROMPT_COMMAND の決定に _ble_history_count が影響を与え
      るのだろうか。というのは疑問である。実は PROMPT_COMMAND に関しては
      _ble_history_count に関係なく version を決めて良いのではないか?

      →その様に変更する事にした。これで manual attach ならば唯1回の
      PROMPT_COMMAND の実行になった。

      一方で PS1 の評価に関しては history count が影響を与えるので
      _ble_history_count が変化したらちゃんと再評価しなければならない。これが二
      重に評価されるのは仕方がないと諦める事にする。

    * prompt attach の場合には依然として二重に PROMPT_COMMAND が実行されている。
      うーん。PROMPT_COMMAND が書き換えられて直接削除できない場合は仕方がないと
      して、内部で実行している場合には呼び出しを省略できないのか。と思ったが、
      PROMPT_COMMAND 配列の時には結局 bash は全てを実行するし、或いは、内部で保
      持している物についてはその場で実行しておかないと bash-preexec.sh の様に内
      部で PROMPT_COMMAND を書き換える様な物に対して矛盾のない動作を提供する事
      ができない。或いはもっと注意深く考察すれば何かできるのかもしれないが。

      或いは逆に ble-attach の中で実行している PROMPT_ATTACH の方を省略させる?
      と思ったが、

      x その場合 PROMPT_COMMAND 配列でより後にある PROMPT_COMMAND の実行結果が
        反映されない事になるし、ble-attach の処理が終わった後に続きで実行される
        PROMPT_COMMAND を阻止する事は結局できない。

      とは言いつつも scalar PROMPT_COMMAND (他によって修正されていない) または
      "配列 PROMPT_COMMAND かつ最終要素" の場合には、続きで別の処理が走らないと
      いう事は保証できるので、ble-attach の内部で走る PROMPT_ATTACH は省略でき
      る。

    2022-02-19 うーん。bash-it のプロンプトが prompt attach で初期化されなくなっ
    た。どうやら bash-preexec precmd 経由で bash-it は設定を行っている様で、
    bash-preexec が ble.sh によって置き換えられた事によって precmd が実行されな
    くなっているのが原因の様だ。うーん。precmd は実行しておくべきの気がしてきた。
    →取り敢えず PRECMD を呼び出す様にしたら期待通りに動く様になった。

  * 2020-09-01 trap: ble.sh を unload する時に復元する仕組みがあっても良いのではないか [#D1777]
    #D1775 と同時に対応した。

  * 2020-09-01 desolved: trap: ble.sh で上書きする時に元々存在していた trap はどうなっていたか [#D1776]
    Ref #D1775

  * util: DEBUG trap 以外についても元からあった trap を拾う様にしたい [#D1775]
    Ref #D1772

    RETURN と ERR 以外については中から普通に trap を見ることができる筈なので、
    そのまま中から値を抽出するというので良い。現在使用しているのは EXIT, WINCH,
    INT である。他に bash3 等で USR1 も使っていた筈。

    実際に trap を設定しているのは ble/builtin/trap/install-hook の一箇所のみで
    ある。ここで trap を読み取って ble/builtin/trap の枠組みで再設定すれば良い。
    対応した。

  * bash-3.0 でコマンドを実行するとプロンプトの前に変な文字列 '' が出力される [#D1774]

    うーん。家に帰ったら再現しなくなった。と思ったら再現の仕方が変化した。C-c
    でモードを変更すると '''' という無駄な文字列が表示される。これは一体何処か
    ら出てきている物だろうか。

    ようやく突き止めた。_ble_term_Ss が余分な引用符で囲まれている。然し何故だろ
    うか。調べると cache には含まれていない。だとすれば、blerc かもしくは内部の
    端末判定である。

    belrc を読み込まない様にしたら表示はされなくなったが、それは単にカーソルの
    設定をしていないのでカーソル切り替えシーケンスが出力されていないだけだった。
    実際に _ble_term_Ss の値を確認したら引用符が混入していた。という事は端末判
    定直後の代入の際に引用符が混入している事になる。

    分かった。 bash-3.0 には "${...#$'...'}" が '...' に展開されてしまうバグが
    ある様だ。これはチェックの対称に追加する事にする。

    ? そもそも他の "${pat#"..."}" 等も大丈夫なのだろうか? 動作を確認する必要が
      ある。以下は一応ちゃんと期待通りに動作する様である。

      $ v=1
      $ echo ${v//"1"/hello}
      $ echo "${v//"1"/hello}"
      $ echo "<${v#"1"}>"
      $ echo "<${v#'1'}>"
      $ echo "<${v#1}>"
      $ echo "<${v#"1"}>"
      $ echo "<${v/#"1"/hello}>"

      そんなに気にしなくて良い気がしてきた。

2022-02-15

  * 2022-01-23 [解消] 元々存在した DEBUG trap を保持する [#D1773]
    Ref #D1772

  * exec: 既存の DEBUG trap を保持する (motivated by ammarooo) [#D1772]
    https://github.com/akinomyoga/ble.sh/issues/176

    * 然し、上記で報告されている物を修正するには PROMPT_COMMAND の実行時にも
      DEBUG trap を有効にしなければならない。これは ble.sh の想定していない事で
      ある。うーん。面倒であるが有効化する事にした方が良いだろうか。と、思った
      が局所的に有効化して後で削除する事はできただろうか。同じ関数 scope 内で削
      除すれば良いのだったか。何れにしても既存の DEBUG trap は捕まえる事にする。

      速度を計測して問題なければ PROMPT_COMMAND 実行時に DEBUG trap を有効にす
      る事にする。その時には ble.sh の内部で直接実行している時にはユーザー trap
      は無効になる様に調整する。

      時間を計測して無視できないという判断の場合には bleopt で有効化できる様に
      する。

    →attach 時の既存 trap かそれとも ble.sh load 時の trap か。load した時には
    既に trap は置き換えられているので、それ以降 attach 迄に設定された物に関し
    ては気にしなくて良い。というか単に無視するしかない。なので、ble.sh load 時
    に設定されている trap を復元する方向で考える。

    * ble-reload した時にもちゃんと上書きして塗り潰さない様に注意する。一つの手
      は trap を復元する事の気がする。これは ble/base/unload で実行すれば良い。

    取り敢えずロード時の DEBUG trap を記録する事にする。他にもロード時の INT 等
    を保持する様にしたい。

    | うーん。trap -p DEBUG を実行すると最初のコマンド実行まではちゃんと存在して
    | いる。然し、コマンドを実行した時点で消滅してしまう。
    |
    | という事を考えると、何処かの時点で消えているという事になる筈だが、実際に
    | trap DEBUG を上書きする瞬間で trap -p DEBUG を実行しても何も表示されていな
    | い。或いは関数の中からだと外側の trap -p を読み取る事ができないという事なの
    | だろうか→試してみるとサブシェルの中からだと見えないが本体のシェルからは例
    | え関数内であったとしても読み出す事ができている。
    |
    | * うーん。何処で trap が削除されているかは分かった。一方で ble/util/assign
    |   の中だと DEBUG の trap string は正確に読み取れていないという事が判明した。
    |
    |   何故だろう。eval があると DEBUG が伝播しないという事なのだろうか。
    |
    | ? ble/util/assign で DEBUG trap の中身を取得できない理由について調べる。うー
    |   ん。

    色々試したがどうやらそもそも関数の中から trap DEBUG が取れるというのは幻だっ
    た様だ。一番外側で設定されている DEBUG trap を読み取る場合、全ての呼び出し
    階層の関数に -t 属性が予めついている必要がある (呼び出しの最中に -t 属性を
    付加しても無駄である。これは set -o functrace についても同様である)。

    これが意味する所は何だろうか。うーん。

    * ble.sh が最初に DEBUG trap を上書きしようとする時までに外側の DEBUG trap
      を読み取る必要がある。source ble.sh した瞬間には、ble.sh の一番外のレベル
      であれば ble.sh が source された文脈での trap DEBUG を取得できるかもしれ
      ないが、ble.sh 自体が関数内で source された場合には読み取る事ができない。

    a reject: という事を考えると、やはり一番最初に DEBUG trap を設定しようとす
      る機会に読み取るのが良い気がする。基本的に DEBUG trap を設定するのはコマ
      ンド実行の直前であり、コマンド実行は一番外側の文脈で行われるからである。
      (然し、将来的に line-editor のプロセスとコマンドを実行するプロセスを分離
      した時にどうしたら良いのかについては不明である。というか分離した時には
      trap 関連は全て再設計する必要があるので今ここで気にしても仕方がない気がす
      る)。

      と思って改めて調べてみたが、builtin trap DEBUG が初めて設定されるのは、ユー
      ザーが ble/builtin/trap DEBUG を呼び出した時かまたは C-c を押した時である。
      従って必ずしも通過するとは限らない。問題点は実際に DEBUG trap が設定され
      ているかどうかに拘らず .epilogue 及び .end で trap -- - DEBUG trap を除去
      しようとしている事である (但し、.epilogue / .end で実行している trap -
      DEBUG は結局何の効果もない)。

      a1 そう考えると例えば TRAPDEBUG/enter に関しては毎回コマンドが実行される
        前に呼び出されるので、初回にこれが実行された時点で、この中で trap -
        DEBUG を読み出すという事が考えられる。

      a2 でもそうなって来るとそもそもコマンド実行時に DEBUG trap を読み取る必要
        すらない。初回の ble-decode/.hook の直後か直前に読み出してしまえば良い
        のではないか?

        と思ったがそもそもコマンド実行直前である必要すらない。

    b reject: やはり ble.sh がグローバルで読み出された時にはその時点で既存の
      trap を読み取るのが安全である。もしグローバルでなかったら代替手段に頼る。

      実際に実装してみたが動かない。試しに ble.sh の先頭に以下を記述してみた所、
      実は source の中ですら DEBUG は伝播しないのだという事が判明した。

      | echo ble.sh:1
      | builtin trap -p DEBUG
      | echo ble.sh:2

      駄目だ。この方法はそもそも使えなかったのである。改めて man bash を確認し
      てみる。set -T の説明を読むと、これが設定されていなければ基本的には、関数
      もコマンド置換もサブシェルも DEBUG を継承しないと書かれている。然し
      source に関しては述べられていない。何故だろう。実際に改めて小さなスクリプ
      トを作って試してみると、やはり source の中では DEBUG trap は見えない。
      functrace を設定すると source の中でも見える様になる。functrace は man に
      は書かれていないけれども source についても DEBUG が継承される様になる。

      うーん。ble.sh の外側で set -T を実行させる様な方法は存在しないし、やはり
      source ble.sh の中から元々の trap DEBUG を読み取るのは困難である。

      結局一旦は実装した以下の変更はなかった事にする。

      | diff --git a/src/edit.sh b/src/edit.sh
      | index c32bed0..29c96c4 100644
      | --- a/src/edit.sh
      | +++ b/src/edit.sh
      | @@ -5769,6 +5772,17 @@ function ble/builtin/trap:DEBUG {
      |      ble-edit/exec:gexec/.TRAPDEBUG/trap
      |    fi
      |  }
      | +function ble/builtin/trap:DEBUG/.initialize {
      | +  builtin unset -f "$FUNCNAME"
      | +  if ((!_ble_bash_loaded_in_function)); then
      | +    local tmp=$_ble_base_run/$$.trap.DEBUG ret
      | +    builtin trap -p DEBUG >| "$tmp"
      | +    source "$tmp" # ble/builtin/trap に処理させる
      | +    ble/util/put '' >| "$tmp"
      | +  fi
      | +}
      | +declare -ft ble/builtin/trap:DEBUG/.initialize
      | +ble/builtin/trap:DEBUG/.initialize
      |
      |  function ble-edit/exec:gexec/.TRAPINT {
      |    local sig=130

      或いは functrace を on にしてもらうしかないのだ。然し常に functrace を on
      にする訳にも行かないし、だからと言って勝手に ble.sh の中から functrace を
      off にすると本当に functrace を on にしたい場合に使えなくなる。そうすると、
      ble.sh を呼び出す前後で set -T set +T を実行してもらう事になるが、其処ま
      でするぐらいであれば、普通に先に ble.sh を先に source してもらうべきであ
      る。また、一回でもキー入力をすれば治るのだが最初の一回だけは我慢してもら
      うしかないと諦めるのである。

      functrace を on にしてもらう様にお願いするのはおかしいとしても、ユーザー
      が偶 functrace を on にしていたらそれを利用するべきなのでは? そういう意味
      でやはり上のコードは一応含めて置いて良いのではないか?

    c 最初のキー入力の直後に解決するという手がある。

      グローバルで実行する必要があるので _ble_decode_bind_hook に指定する必要が
      ある。然し、他の箇所からも同時に _ble_decode_bind_hook を実行しようとした
      時に問題になる。うーん。確認してみた所 _ble_decode_bind_hook に値を設定し
      ているのは現在一箇所だけである。なので今までは何も気にする必要はなかった。

      c1 _ble_decode_bind_hook には追記式でコマンドを書いていく方式にする可能性。
        そして複数の箇所から書き込む事を許す。

      c2 _ble_decode_bind_hook を現在書き込んでいる箇所 (gexec/.setup) で処理す
        る。

      c3 reject: 或いは通常のコマンドとして最初に登録してしまう? と考えたがそう
        するとコマンドのカウントが余分に増えてしまうので駄目の気がする。

        % 他にも C-x C-v 等、コマンド実行として取り扱っている物があるのではなかっ
        % たか。そういった物についてはコマンドのカウントが乱れない様になっている
        % のか? と思って確認したがこれらは実は gexec で実行してはいなかった。その
        % まま関数の中で実行していた。その時に必要に応じてシェル状態の保存・復元
        % をその場で実行して処理しているのだった。

      上記 c2 の方法が現状で一番綺麗の気がする。今後、もっと様々な箇所から bind
      hook を設定したいという状況になったら c1 の様な方式にすれば良い。

    % 取り敢えず、上記の b と c の方法を組み合わせる事にする。先ずは b から実装す
    % る事にする→と思ったら b は不可能な事が判明してしまった。

    仕方がないので c の方針で実装する事にする。とにかく未だ DEBUG trap が存在し
    ていない時にそれをチェックするのが目的。

    というか最初のキー入力の時にようやく DEBUG trap を読み取る事ができるという
    のが意味する事は…最初のプロンプトの表示の時点では DEBUG trap を正しく動作
    させるのは無理という事になるのでは。うーん。もしそうだとすれば報告を受けた
    場合に関しては、結局 PROMPT_COMMAND を実行させるしかないという事になる。

    或いは、attach した時の DA2 等の返答の際に取得はできる。とは言いつつ DA2 の
    返答が戻ってくるまで PROMPT_COMMAND の実行を遅延させる訳にも行かない。とい
    う事を考えると、やはり最初の一回は必ず失敗するという事は認めてもらうしかな
    い。或いは、最初に ble.sh を source して貰ってそれから最後に attach すると
    いうのを徹底してもらうしかない。

    * done: 取り敢えず c の方針で早く実装する。実装した。というか b の実装で用
      意した関数をそのまま呼び出せば良いのだった。

    * done: PROMPT_COMMAND で TRAPDEBUG を有効にする。

    * done: functrace も待避・復元オプションに含める。

      追加した。これで特に問題が起こるとは思えない。DEBUG で余分に何か呼び出さ
      れるという事はあるかもしれない。

    ? [保留] bash-4.4..dev まで tmpenv の builtin eval の中から見える値が変。と。これ
      は実は既に知っている問題なのではないか。

      うーん。逆に bash-4.3 で問題が起こるという事は判明した。bash-4.4 以降では
      ちゃんと値が見える筈である。それにも拘らず実際の ble.sh の中では逆に 4.4
      以降で値が見えなくなっていた。これは一体どういう事だろうか。

      →うーん。これはどうもまた別のバグの様だ。再現した。以下で再現させる事が
      できる。これは trap 関連でしか再現しないのだろうか。分からない。

      | function print { echo "v=${v:-(not found)}"; }
      | function trapdebug { echo "$FUNCNAME:1:v=($v)"; }
      | builtin trap 'trapdebug' DEBUG
      | v=xxxx eval print
      | v=xxxx builtin eval print

      と、思ったが、もしかすると DEBUG trap の中からは意図的に tmpenv が見えな
      い様になっているのかもしれない。然し、builtin eval の時と eval の時の振る
      舞いを比べるとやはり異なるのでこれは意やはり意図したものではない。

      これは別項目にする事にする。今は取り敢えず Note だけ残して放置する事にす
      る。

    [動作確認]

    * C1 取り敢えず動作はしている。然し微妙な振る舞いが色々ある。

    x C2 fixed: 何故か起動した時に点滅する様になってしまった。一旦表示がクリア
      されている?  →これはコマンド実行をした時は bind/.tail をコマンド実行後に
      実行する為に bind/.tail を抑制するのが原因。今回 DEBUG initialize でも
      return 0 をする様に変更してしまったので、DEBUG initialize の時にも
      bind/.tail が省略されてしまってしかし DEBUG initialize の場合は自分で
      bind/.tail が呼び出されないので、bind/.tail が欠けて bash -x によるプロン
      プトの消去が発生して点滅していた。

      DEBUG initialize だけの時は return 1 を返す事にした。

    x C3 fixed: 後から ble.sh を source した場合、エラーメッセージが出る事も問
      題であるが、最初のコマンドの実行時間がシェル開始時刻からコマンド終了時刻
      までの時間になってしまっている。

      ble.sh なしだと期待通りに時間を計測する事ができている。先に ble.sh を
      source した場合でも特に問題は起こっていない。

      これは何故だろうか。先に trap を実行しているとどういう事になるかというと、
      bashrc の中で time_start されて timer が設定される事になるが最終的に
      PROMPT_COMMAND が呼び出されて timer は clear される事になる。然し、その後
      で様々の処理が走ってその過程で改めて timer が設定される? と思ったが何によっ
      て設定されるのかは謎である。ble-attach した段階で DEBUG は解除されている
      のではないのか。と思ったが、違う。実際に解除されていないのだ。それでは全
      然駄目だ。恐らく最初の ble-decode/.hook の瞬間に DEBUG trap が呼び出され
      て結果として時間にずれが生じているという事だろう。

      というか、trap - DEBUG で解除すれば良いのではないか?
      →OK. これで治った。

    x C4 fixed: 最初に ble.sh を source した場合でもエラーを検出している。これ
      はどういう事か。うーん。最初の PROMPT_COMMAND を実行する時点で未だ attach
      が完了していないから DEBUG trap の設定が省略されているという可能性? しか
      し、それだとエラーが画面ではなく vbell に出力されている理由が分からない。
      これは要するに bash が取り敢えず裏で実行した PS1 の評価によって引き起こさ
      れているのではないか。

      と思ったが、bash が裏で PROMPT_COMMAND を実行するという事があるのだろう
      か…。あー。分かった。PS1 については待避しているが、PROMPT_COMMAND につい
      ては待避していないのである。

      PROMPT_COMMAND が二重に実行されている問題は別枠で修正するべきの気がする。
      これは ble-0.3 にも適用する必要がある。と思って動作確認したが二重実行され
      るのは最初に呼び出した時だけなので内部で処理する事にする。これは軽微な差
      異なので 0.3 に適用する必要はない。

      * PROMPT_COMMAND が ble.sh と bash で二重実行される事について

        特に PROMPT_COMMAND を待避していた記憶はない。という事は PROMPT_COMMAND
        が裏で二重に実行されているのではないか。更に言うと、裏の PROMPT_COMMAND
        によって裏の PS1 が設定されてしまっているのではないか。

        現状で実際にその様になってしまっているかどうかを確認する事にする。→確
        認してみたが別にそういう困った事にはなっていなかった。よく考えてみたら
        PROMPT_COMMAND はコマンドが実行された後に実行されるのであって、bash の
        枠組みの方でコマンドを実行していないのだから余分に呼び出される事はない
        のである。

        但し、初回の PROMPT_COMMAND に限っては bash によって実行されるという事
        に留意しなければならない。PS1 を待避・復元している所で PROMPT_COMMAND
        も待避・復元すれば良いのではないだろうか。但し、初回だけで良い。否、
        ble-attach の時に何回 PROMPT_COMMAND が呼び出されるか分からないので、何
        回かは実行する必要があるだろうか。これは実際に試して何回実行されるか確
        認すれば良い。

        確認した所4回呼び出されている。これは確かに呼び出し過ぎである。その内の
        1回は bash から直接呼び出されている。残り3回が何処から来ているかは確認
        する必要がある。一番最後の物は端末テスト後の再配置だろうと思われるが、
        再配置の時に改めて PROMPT_COMMAND を呼び出す必要もないだろうという気が
        する。

        ? そんなに重い処理でなければ PS1 と一緒に毎回保存・復元すれば良いのでは?
          と思ったが、PROMPT_COMMAND 配列を保存・復元するのは面倒なのでやはり保存・
          復元は最初だけにするのが良い様に思われる。

          PROMPT_COMMAND 配列の場合には特に設定下側がどの key に対して設定した
          かを覚えているかもしれないので、key をずらしてしまうのは良くないので、
          特に key も一緒に記録する必要がある。

          保存・復元は ble/util/declare-print-definitions PROMPT_COMMAND を用い
          る方法と各要素を一つずつ保存復元する方法の二通り考えられる。前者は
          fork を沢山するので重い。後者も要素が大量になってくると大変である。

          うーん。取り敢えず各要素毎にコピーする事にする。

        取り敢えず対応した。ちゃんと動く様になった。

      * reject: 待避は bashrc の中から実行している時だけで充分なのではないか。

        そんなに重い処理でもないし PS1 を毎回待避している事を思うと
        PROMPT_COMMAND を毎回待避しても対した処理にはならないので、気にしなくて
        も良いのではないか。

        a 然し、bashrc の中から実行しているという事が分かるのであればその時にだ
          け待避するのは尤もな気がする。

          一方でその様な方法が存在するかどうかはまた別である。以前その様な方法
          を思いついた様な気もするし、結局動かなかった様な気もする。思い出せな
          い。bash のソースコードを覗いて、何かの振る舞いで interactive /
          non-interactive で振る舞いの変わる物があってそれを巧妙に組み合わせれ
          ば判定可能なのではないかと思ったが、結局異なる振る舞いを再現させる事
          ができなくて諦めた気がする。

        b もしくは attach 後の初回の PROMPT_COMMAND の評価の時だけ待避する? し
          かし、それだと複数回 attach もしくは reload を行った時に (そもそもそ
          の様な使い方は想定していないとは言え)、PROMPT_COMMAND が余分に実行さ
          れてしまう事になる。

          更にコマンドラインから直接 ble-attach した時や prompt attach した時に
          は初回でも PROMPT_ATTACH を待避する必要もない。という事を考えると初回
          かどうかというのは本質ではない様に思われる。

        c 或いはコマンドを既に一回でも実行していたら OK という考え方もある。こ
          れならば複数回 reload した時に PROMPT_COMMAND が重複して実行されると
          いうこともない。

          一方でやはり初回には余計に PROMPT_COMMAND を待避する事になるが仕方の
          ない事なのかもしれない。

        また条件によって待避したりしなかったりする場合、現在 PROMPT_COMMAND が
        設定されているかどうかを判定する方法が面倒になる。という事を考えると現
        状の様に常に PROMPT_COMMAND を待避する様にしておくのが無難の様な気がす
        る。或いは、退避はしなくて常にコピーだけはしておくという事にしても良い
        が、それだと結局コストは存在しているので中途半端な事をするよりは本当に
        待避した方が良い様に思われる。

        取り敢えずは現状の様に常に待避する事にして、後で問題になる様であれば条
        件を考える事にする。そもそもコマンド実行の時にだけ待避は起こるのだから、
        滅多に実行しない操作だし処理のコストが問題になるという事は考えにくい。
        もし問題が起こるとすればもっと別の何かのエラーが起こった時の状況復帰に
        関係する物だろうと思われる。

    ? C5 ok: PS1= とするのは bleopt_internal_suppress_output が設定されていない
      時だけになっているが、これも常に実行する様にした方が良いのでは。裏で毎回
      コマンド置換などが実行されている様な状態になっているのは無駄である。それ
      にもしユーザーが PS1= に何か破壊的な操作・副作用のある操作を実装していた
      場合やはり振る舞いが意図しない物になる気がする。なので PS1= を指定するべ
      き気がする。

      と思って振る舞いを確認してみたがそもそも PS1 は余分に評価されてはいない。
      確か端末の状態に応じて Bash はプロンプトの評価を控えるのだった。そしてそ
      れに伴って PS1 の評価も実行していない? と思ったが、そもそもコマンドを実行
      していないのだからプロンプトの内容も変わらず、従って PS1 の中のコマンド置
      換を再評価する機会もないというだけの事の気がする。PROMPT_COMMAND が二重に
      実行されない事と同様の事である。

      何れにしても PS1 を空にする理由も特にない気がするので PS1= を実行する。と
      思ったが、元々不意に ble.sh が落ちた時に不自然な振る舞いにならない為に
      PS1= を設定しているのだった。という事を考えるとやはりそのままにして置いた
      方が良い? と思ったが、現在中途半端な状態にあるという事が分かる様にした方
      が良い気もする。

      a 例えば PS2 を代わりに設定する?

        x と思ったが、PS2 は PS2 でコマンド置換を含んでいる可能性もあるし、そも
          そも異なる物なのでユーザーが意図的に何か PS2 に仕組んでいた時に変な事
          になる。

        x というか、将来的に PS2 を編集時の行番号等に用いるなどした時に棲み分け
          が改めて必要になるのでやはり変な利用方法はしない方が良い。

      b [press any key to continue] 等として変な状態にある事が分かる様にするの
        が良いのでは。

        →具体的に問題を起こしてみてどうなるか試そうと思ったが再現できない。うー
        ん。配列の添字関係で実行が停止していた気がするが…。

        echo ${_ble

        等の中途半端なコマンド文字列で無理やり実行してもちゃんと元の状態に戻る
        事ができている。コマンド実行がその場で終了してしまう様な設定が存在した
        気がするがどの様にすれば良いのだろう。

        * 例えば ${hello?world} などか → 問題なかった。
        * set -u だろうか → 問題なかった。
        * set -e だろうか → これはそもそもシェルを終了するので関係ない。
        * 算術式中の a[-1] だろうか → これも問題ない。

        何処かに記録として残っていないだろうか。

        * "for ((i=0;i<10;i++)); do sleep 1; done"<C-c> これだ

        然し試してみたがこちらで指定した PS1 が反映される訳でもない。

        ! 恐らく最初に PS1 を表示した時の計算結果がずっと残っているという事なの
        ! だろう。なので、実は中で PS1 を設定しようがどうしようが関係ないという
        ! 事。但し、bashrc で直接 attach する時に限ってはその時の PS1 に意味が
        ! ある。
        !
        ! →と思って bashrc で直接 attach する場合についても試したがそれでも駄
        ! 目だった。よく考えたら bash が変な状態になった時にプロンプトを表示す
        ! るとして、その時の PS1 の値を使って表示するのだとしたら、コマンド実行
        ! 中に失敗したのだとしたらコマンド実行中の PS1 を使って表示するのだから、
        ! 待避した PS1 が使われる事はない。という事を考えると待避中の PS1 が使
        ! われる事はない様な気がする。

        うーん。コマンド実行中の失敗の場合はコマンド実行中の PS1 が使われるので、
        待避中の PS1 の値に何を設定するかは関係ない。そもそも PS1 を待避する必
        要性があるのかどうかも何だか分からなくなって来た。

    * ok: WINCH の時に問題になるのではないか: ble.sh では WINCH した時に、
      PROMPT_COMMAND で現在の端末幅に合わせた内容を計算している可能性を考えて、
      PROMPT_COMMAND を再度呼び出す事にしている。これで問題が生じることはないか?

      →報告されたコードの場合には結局 PROMPT_COMMAND のコード自体に対して
      DEBUG trap が走る事によって問題が回避されているので、問題は起こらない筈。
      →実際に問題が起こらないという事を確かめた。

      一方で PROMPT_COMMAND が余分に呼び出される事で他の問題が生じる可能性はあ
      るだろうか。うーん。そもそも PROMPT_COMMAND がコマンド実行後に1回だけしか
      呼び出されないという想定は bash のマニュアルにも書いていないし、意味を考
      えればプロンプトの再表示時に複数回呼び出されてもおかしくはない気がする。
      具体的にそういう動作に依存している枠組みが現れる迄は気にしない事にする。

    ? C6 reject: 効率を考えたら実は TRAPDEBUG/enter の時には TRAPDEBUG ではなく
      て元のユーザーの trap を直接設定しておけば良いのでは?

      現在の TRAPDEBUG の処理 (sandbox でのユーザートラップの実行を含め) は複雑
      で重いので直接実行できるのであればその方が良い気がする。

      現在 TRAPDEBUG は ble.sh 的には INT の処理の為にしか使っていない。将来的
      にもっと別の事に使いたくなる可能性もあるが、取り敢えずは特別な処理は挟ま
      ないのだからユーザートラップを直接設定して良い気がする。

      一方で TRAPDEBUG は ble.sh の処理自体に対する DEBUG trap を阻止するという
      目的もあった。うーん。そうは言っても gexec/.{restore,save}-lastarg 及び
      epilogue 等に対する DEBUG trap 程度であれば許しても良い気がする。その直後
      に builtin trap - DEBUG で解除しているので、gexec/.end 以降に対してユーザー
      の DEBUG trap が実行される事は結局ないと思われる。

      .TRAPDEBUG/trap に於いて現在介入する必要がなければ介入しない様にする事にした。

      x と思ったら報告者の設定で問題が起こる。やはり ble.sh 内部での処理に対し
        ては TRAPDEBUG が発生しない様に制御が必要なのだろうか。

        うーん。PROMPT_COMMAND の実行の為の TRAPDEBUG に関しては DEBUG を
        filter する為に明示的に TRAPDEBUG で trap する事にした。

      * というか単にユーザートラップを実行するだけなのであれば、単に postproc
        にユーザートラップをしかければ良いだけでは? その様に実装した。但し、本
        来は user trap がなければそもそも DEBUG trap も存在しない筈ではある。但
        し、複数コマンドを実行していて最初のコマンドを C-c で殺した時に、次のコ
        マンドには TRAPDEBUG が残った状態で実行される。この時にそういう事が起こ
        る可能性がある。

      o C-c がちゃんと動くか確認する。OK 動いている。

      2022-02-16 うーん。やはり直接 trap すると問題が色々発生する。

      x 先ず初めに報告にあった物が動かなくなった。報告にあった設定だと
        PROMOPT_COMMAND より後に初めて実行した DEBUG trap で時刻が決まる。然し、
        直接 trap していると、ble-attach よりも前に設定した trap が
        ble-decode/.hook 等にも反応してしまって正しい時刻が決定できない。

        従って attach していない状態で ble/builtin/trap が受け取った DEBUG trap
        は結局 TRAPDEBUG 経由で実行するのが無難なのではないか。

      x 更に、コマンド実行で再設定している DEBUG trap についても今回は問題になっ
        ていないが、やはり問題になる可能性がある。直接 user trap を設定すると、
        exec:gexec/.* に対して軒並み発火してしまうが、本来これらに対しては発火
        して欲しくはないのである。

        なのでこの場合にもやはり user trap を直接設定するのは避ける。

    x C7 fixed: prompt-attach をした場合全く値が更新されない。これは何故だろう
      か。PROMPT_COMMAND が失われている可能性? 確認した。元からあった
      PROMPT_COMMAND が消滅している。→修正した。ble/idict#copy の引数が逆だっ
      た。

    x C8 fixed: 現在は先程まで動いていた物も動かなくなっている。何故?

      x fixed: 先ず、起動時に trap が削除できていない所為でコマンドを実行する前は表示
        される時刻が前のプロンプトを表示した時刻からの遅延になってしまっている。
        これは type=initial でも final でも起こっている。

        これの原因は簡単で user trap を直接 trap する様にした為に、ble.sh の内
        部 (具体的には最初の ble-decode/.hook) に対して DEBUG trap が動作してし
        まっている。

      x fixed: 次に、final で実行した場合にはそもそも user trap すら正しく抽出
        できていない。少なくとも2コマンド目以降には元々取得できていた筈だがそれ
        も動かなくなっている。

        これの原因は謎である。もしかすると TRAPDEBUG/.initialize が実行されてい
        ない? 先に adjusted が正しく動作しているとすると確かに
        TRAPDEBUG/.initialize は呼び出されなくなってしまう。現在の構成の場合に
        は TRAPDEBUG/.initialize と adjust は別々に処理する必要がある気がする。

        これは試しに attach で adjust を呼び出す様にした所に問題がある。attach
        の時点で user trap の初期化が終わっていないので、この時点で adjust を実
        行してしまうと user trap が失われてしまう。…と思ったが、それも何だか変
        な気がする。adjust では trap - DEBUG を実行していて ble-attach は
        declare -ft していないので、ble-attach 内部での trap 解除は外に漏れ出さ
        ない筈である。或いは、同じ文脈で TRAPDEBUG/.initialize が実行されてしまっ
        ている可能性はある?

        分かった、adjust で trap - DEBUG したのは外に伝播しないが、adjusted=1
        に設定する為に user trap 読み取りのコードが不活性化してしまっている。
        adjusted=1 になる為には user trap も読み取った後でなければならないので
        ある。

    x C9 fixed: prompt-attach (memo/D1772.bashrc type=initial-prompt) した後に
      user trap が設定されたまま残っている。うーん。ble-attach する時に削除する
      べきなのではないか。。と思ったが、それだと未だ user trap を読み取っていな
      い時に元から存在した設定を削除してしまう事になるので駄目である。

      うーん。つまり最初に読み取った時に取り敢えず trap を削除しておくべきとい
      う事なのだろうか。コマンド実行中でなければ。

      というより prompt-attach の場合、何処でユーザー trap を読み取っているのだ
      ろう。と思ったが、initial-prompt の場合には最初に trap DEBUG をユーザーが
      呼び出した時点でユーザー trap が読み取られる事になる。

      結局初回は必ず trap - DEBUG を実行する事になるという事なのだろうか。初回
      の判定はどの様にしたら良いのか。うーん。また新しく変数を増やすのか? 或い
      は既存の変数を用いて判定する事はできるだろうか。

      そもそも userTrapInitialized という変数はその場合必要になるのだろうか。こ
      の変数は実際 gexec/.setup で調整をする必要があるかどうかだけの為に用いら
      れている。という事を考えるとこの変数の意味を変えれば良い気がする。

      或いは TRAPDEBUG の adjust/restore の状態をちゃんと管理しておいて、一旦
      restore したのに未だ adjust していない状態になっていたり、未だそもそも
      adjust した状態になっていなかったら元に戻す等の対処が必要になるのではない
      か。

      →その様に修正した。これで無駄に DEBUG trap が内部で呼び出される事はなく
      なった筈。

      しかし報告された設定の場合に、初回のコマンド実行の実行時間が正しくない。
      これは一回でも無駄な DEBUG trap が PROMPT_COMMAND 実行後に実行されるとも
      う駄目なので、実は最初に現れた時点でもう正常動作しないのである。

      a そうなると attach の時点で trap を削除するべきなのだろうか。その為には
        attach で trap の削除に関係する全ての経路で declare -ft を指定しておく
        必要がある。一応どの様な経路で adjust が行われるのかについて確認してお
        く事にする。

        取り敢えず adjust-PS1 は以下の経路で呼び出されている。

          ble-edit/adjust-PS1
          ble-edit/attach/.attach
          ble-edit/attach
          ble-attach
          ble/base/attach-from-PROMPT_COMMAND

        うーん。ble-edit/attach の直下で TRAPDEBUG/adjust を呼び出してみる事に
        する。

        x 然し関数内や source 内部で ble-attach した時には結局元の trap を削除
          するのに失敗する事になる。一応一番外側が ble-attach かどうかで判定は
          できる。また set -T が有効になっている場合にも削除は可能だろう。

        他、ble-attach を呼び出す可能性のある関数は全て列挙する。

        - ble -> ble/dispatch
        - ble/base/attach-from-PROMPT_COMMAND
        - ble/base/process-blesh-arguments ... これはいきなり attach する時

        色々面倒である。ble/base/attach-from-PROMPT_COMMAND についても、これは
        PROMPT_COMMAND に設定して使う事を想定しているが、他の枠組みが何処かの変
        数に待避して関数内から呼び出した場合にはやはり trap が見えなくなってし
        まう。結局 attach の時点で確実に trap を削除しようとするのは困難である。

      b initial-attach の時に問題が起こらない様にするだけであれば、attach の外
        の状態であっても trap を実行した時には filter を入れる様にするという手
        もある。

      うーん。方針が定まらないとどの様に対処するべきか分からない。再度現状につ
      いて整理する事にする。

      "ble/builitin/trap ... DEBUG" が bashrc で呼び出された時はどの様に振る舞
      うべきか。取り敢えず、実際に ble-attach するまでは普通に DEBUG trap が動
      作するのが自然である。また、ble-attach した時に如何にして元から存在した
      DEBUG trap を不活性にするのかという事。

      ! a ble/builtin/trap でユーザーが DEBUG trap を設定した時は、未だ attach し
      !   ていなければ user trap を直接設置する。ble-attach を実行した問にそれを
      !   削除する。
      !
      !   然し、trap - DEBUG によって本当の意味で削除するのは条件が限られている。
      !   現在の関数呼び出し経路の全てに trace 属性がついているか、set -T が設定
      !   されていてかつ現在の関数呼び出し経路の全てが既知の (set -T を弄らない)
      !   関数であるという事が保証できる場合のみである。取り敢えず trap '' DEBUG
      !   とすれば削除はできる気がする。
      !
      !   従って、
      !
      !   1 ble.sh の枠組みの中で ble-attach を最終的に呼び出す可能性のありそうな
      !     関数の全てに declare -ft を付加しておく。
      !
      !   2 ble-attach が呼び出された時に既に user trap が既知の状態になっている
      !     時には trap DEBUG を削除する。
      !
      !     2a 経路上が全て DEBUG を継承していると判断できる時には trap - DEBUG
      !       を実行して直接削除する。
      !
      !     2b 経路上で DEBUG が途切れているかもしれない時には仕方がないので trap
      !       '' DEBUG を実行する。途中で別の DEBUG を設置したりしない限りはこの
      !       DEBUG trap は一番上の階層にまで適用される筈である。
      !
      !     然し面倒なので ble-attach した瞬間には常に trap '' DEBUG で良い気もす
      !     る。その様にしておけばわざわざ declare -ft 等の事を考える必要もない。
      !
      !   3 ble-attach が呼び出された時に user trap が既知の状態になっていない時
      !     は厄介である。
      !
      !     3a 経路上が全て DEBUG を継承していると判断できる時にはその場で user
      !       trap を読み取ることができる。その時には単に trap - DEBUG を追加で実
      !       行して trap を削除すれば良い。
      !
      !     3b それ以外の場合には user trap を取得できない。trap '' DEBUG で削除
      !       すると元の user trap を破壊してしまうので実行できない。
      !
      !   この方法で気になるのは様々な関数に trace 属性を設定して変な問題が起こら
      !   ないのかという事である。これは他の人が設定した DEBUG trap の侵入を許可
      !   するという事に他ならない。本来他の人が設定した DEBUG trap でその枠組の
      !   動作に干渉してはならない (したら保証外) なので気にしなくて良い筈という
      !   気もするが、DEBUG trap を使っている側がちゃんと動かない可能性は常に存在
      !   する。まあ余り気にしても仕方がないのかもしれない。
      !
      ! b ble/buitlin/trap は attach 状態にない時には TRAPDEBUG を設置する。つま
      !   り、ble.sh の外側でも TRAPDEBUG で filter しながら動作するという事。こ
      !   れはいざ ble-attach を実行した時に意図しない DEBUG を防ぐ目的がある。
      !
      !   然し、これは元から設置されていた DEBUG に対しては無力である。結局、元か
      !   ら設置されていた DEBUG に対しても対策をするのであればわざわざ DEBUTRAP
      !   経由にする必要もないのでは? → 然し、元から設置されていた DEBUG に対し
      !   ては完全な対策ができない。ble/builtin/trap 経由の時には完全な対策が可能
      !   な方法に切り替えるのは妥当である。従って、論点は元から設置されていた
      !   DEBUG に対してどれだけ完全な対策を行う事ができるかという事になる。

      c 結局 ble/builtin/trap 及び .TRAPDEBUG/restore では必ず TRAPDEBUG 経由で
        bind する事にしたので改めて整理し直す。また、現在形路上が全て DEBUG を
        継承しているかどうかを判定する関数を作成した。

        1 ble.sh の枠組みの中で ble-attach を最終的に呼び出す可能性のありそうな関
          数の全てに予め ble/function#trace を実行しておく。

        2a global DEBUG が見える状態にある時には、user trap が未知であればその場
          で読み取りを行う (__initialize)。そして DEBUG trap を削除する
          (__TRAPDEBUG_adjust)。

        2b それ以外で user trap が既に読み取り済みもしくは設定済みであれば
          DEBUG trap を削除する (__TRAPDEBUG_adjust)。

        2c それ以外の時には user trap を保持しなければならないので仕方がないが
          そのまま通過。

        この方針で行く事にする。実装した。取り敢えず動いている様に見える。後で
        制限について書く事にする。

    * C10 done: 元から設定されている trap が TRAPDEBUG の類だった時。これは無視
      する必要がある。そうしないと最悪無限ループになる。

    x C11 fixed: initial-prompt で core-dump する様になってしまった。。何故? 再
      帰 trap の可能性を疑って先に対応する事にしたが直らなかった。関係なかった
      様だ。

      取り敢えずどういう制御パスになっているかだけは確認する。

      と思ったら再帰 trap になっていた。再帰判定のコードが間違っていた。修正した。

      然し、そもそも何故再帰 trap になってしまうのかというのは謎である。あー分
      かった。ble/builtin/trap 経由で user trap を読み取ってもその後で
      ble-edit/attach から呼び出した _ble_builtin_trap_DEBUG__initialize で再び
      user trap を読み出そうとしてしまうのが問題なのである。これも修正した。

    x C12 fixed: bash-5.0 以下で PROMPT_COMMAND が消滅してしまっている。何故か。
      copy-state の使い方を間違えている?

      これは分かった。attach-from-PROMPT の時は PROMPT_COMMAND の書き換えをチェッ
      クしている。なので、中で attach して PROMPT_COMMAND を待避するとそれが保
      存されてしまう。

      と思ったがそれでも何だか変な気がする。ble-attach は何れにしてもその
      PROMPT_COMMAND の保存復元の外側で実施される筈だから。変だ。

      うーん。分かった。local PROMPT_COMMAND としていた為に異なるレベルの
      PROMPT_COMMAND を触っていて変な事になっていた様だ。unlocal をちゃんと実行
      する様にしたら問題なくなった。と、思ったがこれは本当に意図した動作なのだ
      ろうか? 新しい PROMPT_COMMAND を実行したくて lcoal PROMPT_COMMAND を実行
      していたのではあるまいか?

      改めてコードを確認する。うーん。多分大丈夫意図した振る舞いになっている筈。

    x C13 wontfix: bash-5.0 以下で type=initial-prompt (memo/D1772.bashrc) に対
      し attach 時に vbell で報告者の設定がエラーメッセージを出す。

      て、__initialize での DEBUG trap 読み取りに失敗している気がする。というか、
      initial なので直接 ble/builtin/trap を経由して trap を設定している筈で、
      間違う筈はない…。

      うーん。vbell でエラーが表示されるという事は attach した後に bash が
      PROMPT_COMMAND を実行しようとして失敗しているという事になる気がするが…。
      うーん。つまり? 外側の PROMPT_COMMAND の文字列を eval している時に、
      ble-attach の入った ble/function#lambda/0 を実行する所までは良くてその後
      に続いている timer_stop の呼び出しに於いて問題が生じているという構図であ
      る。うーん。これを回避するのは難しい。


      つまり何が起こっているかというと、本来は PROMPT_COMMAND の実行の最初に
      timer が設定されてその実行の終わりに timer_stop が呼び出されるのでそれで
      良いのだが、prompt attach の瞬間には bash の

        PROMPT_COMMAND='ble-prompt-attach ; timer_stop'

      の最初に timer が設定されるが、それは ble-attach 内部の PROMPT_COMMAND 呼
      び出しで消費される。その後で timer_stop を実行しようとするが、その時点で
      既に DEBUG trap は除去されているので対応する DEBUG trap が一度も呼び出さ
      れない儘に timer_stop が呼び出されてエラーメッセージが発生する。

      うーん。prompt attach は仕組みからして処理の実行順序を変更する事になるの
      でこれに対してどの様に処理するべきかは謎である。本当は PROMPT_COMMAND の
      最後に実際の attach 操作を持って来たいところだがそういう訳にも行かない。

      うーん。其処まで実行順序が厳密でなければならないというのは困る。というか、
      そもそも元々のスクリプトが DEBUG が必ず PROMPT_COMMAND よりも前に実行され
      る筈という前提で設計されているのがよくない。というか、そもそも DEBUG を用
      いた hack を使っている時点でよくない。然し、そうは言ってもうーん。

      例えば prompt-attach の時には DEBUG trap はその場では削除しないという事を
      考えたが、そうすると結局また問題が生じる。timer_stop が処理するまでは良い
      が、その後も DEBUG trap が有効のままなので、DEBUG trap が
      ble-decode/.hook 等に対して呼び出されて予期しない時刻になる。また、もし逆
      に timer_stop がその PROMPT_COMMAND の中で attach-fromp-PROMPT_COMMAND よ
      りも後に呼び出されなかったら結局それも DEBUG trap で設定された timer が残
      存してしまう。

      これは現状 vbell が出るだけで全く使えない訳ではないので無視する事にする。
      それに $timer ではなく timer と書いていれば特に問題もなく利用できる筈であ
      る。

    * C14 desolved: trap DEBUG より後に ble.sh を source した場合に対する対策

      最初の PROMPT_COMMAND 実行の時には特に問題にならない。然しその時に timer
      変数が削除される。2回目の PROMPT_COMMAND 実行までに trap が実行されれば問
      題は起こらないが、実際は未だ trap DEBUG は取得できていないので自前で設定
      することもないし、だからと言ってずっと関数を出ないので既に設定されている
      物が発火することもない。

    * C15 desolved: prompt-attach の場合の振る舞いについても確認する必要がある。

    x C16 ok: bash-3.2 で type=final (memo/D1772.bashrc) の時に初回のコマンド実
      行の時間がずれる

      他の 3つの attach 方法の場合には問題は生じていない。物によっては最初のプ
      ロンプトの時間が 0s になったり 1s になったり 2s になったりして、初期化の
      時間が含まれたり含まれなかったりしているがそれは対した事ではない様に思わ
      れる。

      これは何故だろうか。4.0 では特に何も起こっていない。final の時には
      ble-attach を直接呼び出して attach している。うーん。もしかして DEBUG
      trap を除去できていない?

      うーん。というか 4.0 でも 3.2 でも bashrc の内部では trap を取得できてい
      ない様だ。うーん? というか 5.1 ですらもできていない。何故だろう。
      is-global-traceable がちゃんと動いていないという事?

      →と思ったらこれは単にテスト用の rcfile の名前が .bashrc ではなかった為に
      棄却されていただけの事だった。棄却条件を緩めたらちゃんと期待通りに動く様
      になった。気にしなくて良い。

    x C17 desolved: bash-3.0, 3.1 で後に ble.sh を source した時、何回かコマン
      ドを実行してもエラーが出続ける。どうやら trap が消滅している。

      →これは今試したら再現しない。ちゃんと動いている。うーん。多分他の物を修
      正した時に一緒に直ったのだという事だと思われる。

    x C18 wontfix: bash-3.1 で後から ble.sh を source した時に最初のコマンド実行
      の時間がずれている。うーん。これは ble-attach 等が DEBUG を継承させられな
      いという事に由来する制限である。

      うーん。bash-3.1 以下で declare -ft を適用する方法はあるのだろうか。或い
      は set -T を設定するしかないのかもしれない。

      念の為先に source ble.sh したときについてはちゃんと動く事を確認した。OK

    * C19 別項目: その他の trap についても元からあった trap を拾う様にしたい。
      うーん。この commit は巨大になり過ぎたし、DEBUG trap 専用の物なので、他の
      trap に関しては別項目で対応するのが正解の気がする。

    x C20 別項目: bash-3.0 で変な文字列 '' が出力される。

      この変なエラーを直さない限り、そもそもちゃんと動いているかどうかまともに
      修正する事ができない。というかこの謎の出力は一体何処から来ているのだろう
      か。DEBUG trap 関係だろうか。

      うーん。これはそもそも今回の話と関係なく起こっている問題の様だ。これは別
      枠で修正するべき。そもそも master で、plain bash + plain ble.sh でも再現
      する事を確認した。

    x C21 fixed: bash-3.0 で結果が常に 0s

      調べてみると DEBUG trap が何故かコマンドが終了してからしか呼び出されてい
      ない様だ。更に調べると TRAPDEBUG は呼び出されている。と此処で分かった。原
      因は BASH_COMMAND が bash-3.0 で設定されていないという事だ。

      これは関数内で BASH_COMMAND を参照した時だけでない。trap string で直接
      BASH_COMMAND を参照しても同様に BASH_COMMAND には現在実行しているコマンド
      の文字列が格納されている (という事を確認した)。

      $ func() { echo heloo; }; declare -ft func; trap 'trapdebug "$BASH_COMMAND"' DEBUG; trapdebug() { echo "[$1]"; }

      これは仕方のない事である。bash-3.0 では不当に DEBUG trap が握りつぶされな
      い様にした。bash-3.0 では余分に DEBUG trap が呼び出される事になるが、これ
      は仕方がない。DEBUG trap をしかける側はいつでも大量の関係ない DEBUG trap
      を捨てる事が求められているので許容してもらう。

    x C22 fixed: bash-3.1 以下で type=final-prompt (memo/D1772.bashrc) に於いて
      trap が消滅している?

      先ず _ble_builtin_trap_DEBUG_userTrapInitialized によると初期化は実行され
      ていない。一方で builtin trap -p の時点でもう消えている。うーん。

      どうやら bash-3.0 では bind -x の top レベルでも何故か
      attach-from-PROMPT_COMMAND の中で実行している設定になっている様だ。謎。取
      り敢えず work around を加える事にした。ちゃんとトップレベルの trap を読み
      取る事ができているので OK

    * C23 done: refactor name ble/function/is-global-traceable

    取り敢えず何れの bash version でも少なくともコマンドを一回実行すればちゃん
    と動く様になった様に思われる。これで良しとする。


    * C24 一旦何処かに push して diff を観察する。

    [制限]

    最後に現状の実装の制限についてまとめる。これは何処かにまとめて置いた方が良
    い気がする。ソースコードの中に記述するのが最も分かりやすいのではないか。転
    記した。

    * 先に ble.sh を source した場合は殆どの場合動く。

      bash-5.0 以下で先に ble.sh を source して prompt-attach を行い、更に
      PROMPT_COMMAND を書き換えた場合には、PROMPT_COMMAND の中で
      attach-from-PROMPT_COMMAND よりも後に実行している処理は DEBUG trap が無
      効化された状態で実行される事になる。

    * 後に ble.sh を source した場合には以下の場合にロード直後は DEBUG trap が
      ble.sh 内部の処理に対しても有効になっている。

      - (set -T & --attach=attach の時の条件) rcfile が .bashrc でも
        .profile でも .bash_profile でもない場合 (これは現在 rcfile の
        中にいるかどうかを判定する方法が bash にはない事から、rcfile
        かどうかをファイル名と行番号だけから判定しなければならない事に
        由来する)

      - source ~/.bashrc 等の様にして手動で bashrc を読み込んだ時 (これは
        source が DEBUG trap を継承しないという Bash の制限に由来する)

      - rcfile から一旦別のファイルを source してそのファイルから ble.sh を
        source した時。または関数内から ble.sh を source した時 (これも DEBUG
        trap の継承に関する Bash の制限に由来する)

      - bash-3.1 以下の時 (これは declare -ft で trace を付加できる関数の関数
        名に対する制限に由来する)

    * というか結局報告者の提示した設定が不安定すぎるという事に尽きている様な
      気もする。この設定は例えば bash-preexec.sh と一緒に使ったとしても崩れる
      し (とはいいつつも bash-preexec.sh は他のあらゆるものを壊す気がする)、
      また、PROMPT_COMMAND+=$'\n'追加設定 を実行するあらゆる設定に対して脆弱
      である。その様ないい加減な設定を使っている時点で完全には対応しきれない。

2022-02-13

  * util: EXIT trap を設定していると実際に exit する時に return に空文字列が渡される (reported by SuperSandro2000) [#D1771]
    https://github.com/akinomyoga/ble.sh/issues/175

    これは明らかに最近書き直した trap handler 周りのの処理の問題である。と思っ
    たが return を呼び出している箇所では特に空文字列が渡されそうなコードは見え
    ない。再現はできているのでどうなっているか確認する事にする。

    →分かった ble/util/setexit に渡す引数が空になっている。と思ったら単に typo
    だった。というよりは変数名の変更漏れ。

  * [棄却] complete: ls ~/.c{onfig,1}/[TAB] としても候補が生成されない [#D1770]

    うーん。これは今迄ちゃんと候補が生成できるだろうと思っていたがそうでもない
    様だ。改めて振る舞いを調べてみるのが良い。やはり動かない。bash-completion
    の所為でもない。ble.sh の元々の機能を使っていてもやはり生成されない。

    というか寧ろ元々の機能を使っているから候補が生成されないという可能性もある?
    と思って改めて bash-completion を使って試してみたがそれでも駄目である。取り
    敢えず、bash-completion が介在しない場合について振る舞いを確認する。

    →と思ったらどうやらブレース展開の一番最後の要素を使って補完を実行する仕組
    みになっている様だ。なので、 ls ~/.c{1,onfig}/[TAB] とした場合にはちゃんと
    候補が生成される。これは単にそういう設計という事なので修正しなくて良い。

  * edit: いつの間にかに rps1 に接した時の計算が壊れてしまっている [#D1769]

    改行位置が正しく計算できていない? と思ったが、うーん。これは改行が継続する
    様にして欲しいという要望に応えた時に導入したバグの気がする。

    Ref #D1745

    改めて edit.sh で D1745 に関係している所を確認してみた所… rps1 があるかど
    うかのチェックを忘れている。→と思ったがそもそも CR を埋め込む時点でそれは
    処理していたのではないか? 確認してみた所 *:relative:* の時には CR は埋め込
    まれない様になっている筈。

    確認してみると relative が opts に指定されている時と指定されていない時が存
    在する。textmap#update の呼び出し元を確認してみると
    ble/widget/.update-textmap から呼び出している物については opts を指定してい
    なかった。実は結構な確率で ble/widget/.update-textmap 経由で更新が行われる
    という事だった様だ。何れにしてもちゃんと同じ引数で textmap#update を呼び出
    す必要があるのだった。

    * [経緯確認] というか今迄は rps1 が存在していても relative にせずに直接描画
      計算をしていたという事になるのではないか。そう思うと今迄動いていたのは偶
      だったという事になる。或いは、relative になる様にしたのは #D1745 だったの
      だったか。

      90a8915c src/edit.sh (Koichi Murase 2019-03-09 11:40:10 +0900 3009)   local render_opts=
      d84bcd8d src/edit.sh (Koichi Murase 2020-10-11 02:05:09 +0900 3010)   [[ $rps1_enabled ]] && render_opts=relative
      cf8d9493 src/edit.sh (Koichi Murase 2021-06-07 12:13:56 +0900 3011)   COLUMNS=$cols ble/textmap#update "$text" "$render_opts" # [ref] x y

      90a8915c src/edit.sh (Koichi Murase 2019-03-09 11:40:10 +0900 2483)   local render_opts=
      d84bcd8d src/edit.sh (Koichi Murase 2020-10-11 02:05:09 +0900 2484)   [[ $rps1_enabled ]] && render_opts=relative
      90a8915c src/edit.sh (Koichi Murase 2019-03-09 11:40:10 +0900 2485)   COLUMNS=$cols ble/textmap#update "$text" "$render_opts"

      90a8915c src/edit.sh (Koichi Murase 2019-03-09 11:40:10 +0900 2064)   local render_opts=
      b86709af src/edit.sh (Koichi Murase 2019-03-23 12:36:07 +0900 2065)   [[ $rps1_show ]] && render_opts=relative
      90a8915c src/edit.sh (Koichi Murase 2019-03-09 11:40:10 +0900 2066)   COLUMNS=$cols ble/textmap#update "$text" "$render_opts"

      90a8915c src/edit.sh (Koichi Murase 2019-03-09 11:40:10 +0900 1668)   local render_opts=
      90a8915c src/edit.sh (Koichi Murase 2019-03-09 11:40:10 +0900 1669)   [[ $flag_rps1 ]] && render_opts=relative
      90a8915c src/edit.sh (Koichi Murase 2019-03-09 11:40:10 +0900 1670)   COLUMNS=$cols ble/textmap#update "$text" "$render_opts"

      b2e2461a ble-edit.sh (Koichi Murase 2017-10-05 01:12:01 +0900 1669)   ble/textmap#update # text x y → x y

      これを見ると3年前からずっと relative 指定していたけれど、単に絶対移動でも
      問題が生じていなかったというだけの様である。確かに論理的には問題は生じ得
      なかったのかもしれない。ちゃんと改行は改行として処理していたので。

      因みに最初に opts を導入した時点で既に ble/widget/.update-textmap は rps1
      に拘らず opts なしで textmap#update を呼び出していた様である。同時に
      ble/widget/.update-textmap の textmap#update の呼び出しも修正しているのに
      opts を指定しなかったのは唯単に油断したからだろうか。

      opts を導入したのは #D0959 であった。そしてこれは確認してみた所、rps1 を
      最初に導入した commit だった。という事を考えると本当にずっと relative あ
      りとなしの両方で動かしていたという事になる。

  * [棄却] git submodule update は even の時にはしなくても良いのでは [#D1768]
    https://github.com/raccoonasdf/raccoonpkgs/commit/d7ec0af3db2cd473adcb12a0132e53d3c216dddf

    と思って改めて makefile を確認してみたが git submodule update は、
    contrib/.git 及び contrib/contrib.mk さえ存在していれば実行されない様な気が
    する。或いは、ble-update について話しているのかとも思ったがそれも変な気がす
    る。ble-update は結局本体の更新の為にインターネットに接続するのだから、同時
    に submodule update を実行しても特に問題になる様にも思われない。

    うーん。これはこの上のファイルを記述した人が勘違いしているだけという気がし
    てきた。つまり、makefile に git submodule init があるのを見つけて、これは
    make の時に必ず呼び出されるのに違いと思っているのではないか。実際には
    working tree に展開されていれば呼び出される事はないのだが。或いは、nix の設
    定だと submodule fetch するだけで working tree に反映しないという可能性もあ
    る。その場合には git submodule は make から呼び出される事になるが、しかし一
    方でこれは必ず呼び出さないと行けないものでもある。

    一方で現在の ble.sh gitmodules が指している commit と現在 HEAD が異なる時に
    は update を自動的に実行することもできる。と思ったが流石にそれは一時的に異
    なる物にして試したい時などにとても面倒である。という事を考えると、わざわざ
    その様な事はしなくて良い。結局 ble-update を実行した時にちゃんとした状態に
    調整される筈。

2022-02-12

  * complete: _fzf_path_completion 経由だと ~ で始まるパスのディレクトリの後に / が挿入されない (reported by SuperSandro2000) [#D1767]
    https://github.com/akinomyoga/ble.sh/issues/171#issuecomment-1030962166

    file: memo/D1760.fzf-completion.bashrc

    恐らく compopt か何かが関係しているのだろうという気がするが ~ で始まるかど
    うかで問題が再現するかしないかが変わるというのは変だ。~ は ble.sh の側で展
    開している筈。という事は ~ がある事によって問題が発生しているという事ではな
    い様な気がする。

    ? 例えば / で始まる事によって問題が発生するのではないか。或いは subdir/* の
      時に問題が発生するという事だろうか。

      → / で始めても問題は再現しない。サブディレクトリの下にあってもちゃんと動
      いている。本当に ~ で初めた時にだけ問題が起きている様に見える。更に、
      bash-completion と組み合わせた時にだけ問題が発生しているという事でもある。
      うーん。何が起こっているのだろうか。

      取り敢えず候補生成部分を確認するのが良い気がする。

    * うーん。実装を見るとやはり compopt が欠けているのが問題である様に見える。
      と思って実際に展開する部分を確認してみた所…

      CAND='~/.config' INSERT='~/.config' DATA=':noquote:filenames:'

      ちゃんと filenames は指定されている。という所で分かった…。"~/.config" と
      いう名前で候補が生成されている。これだと本当に '~/.config' という名前のディ
      レクトリが存在する時にしか / がつかない。うーん。何が起こっているのか。

    ? 先ず 何故 fzf でない場合にはちゃんと補完されていたのか? というか前から補
      完されていなかった可能性?

      そう思って bash-completion で試してみたがちゃんと動いている。そして以下の
      様にちゃんと具体的なディレクトリ名に展開されている。

      CAND='/home/murase/.config' INSERT='~/.config' DATA=':filenames:'

      うーん。勝手に fzf が ~ に置換してしまっているのが良くない。

    * 念の為、ちゃんと ble.sh の側で展開できているか確認する。

      COMP_WORDS=('cat' '/home/murase/.con')

      ちゃんと展開している。つまり fzf は勝手にこれを ~ に置換してしまっている
      という事。変な振る舞いをするものだ。一応確認する事にする。と思ったら、普
      通に fzf を起動した時にはそういう変な振る舞いは見られない。うーん。何故?

      もしかすると contrib/fzf-completion による介入が原因の可能性もある?

      うーん。これだ。

      COMP_WORDS=("${comp_words[@]}") COMP_CWORD=$comp_cword
      COMP_LINE=$comp_line COMP_POINT=$comp_point

      fzf は ** だとか展開前の特別なシーケンスを探す為、展開前の単語を要求して
      いる。従って、直接 ~/.config という文字列を渡す事になる。

      うーん。という事は fzf を使っている時には 'ba[TAB] 等に対して補完できない
      という事にはなるまいか? と思ったら勝手に quote を外された。うーん。仕方が
      ない。

    * 対策としては noquote が設定されている時にはディレクトリ名かどうかのチェッ
      クは CAND ではなくてそれの展開結果に置き換える。もしくは展開結果を用いて
      CAND に再代入する? INSERT の方に記録する。

      と思ったが、うーん。候補生成の時点では CAND の方しか記録しないのでは。
      と思って確認したがちゃんと生成時点で CAND も INSERT も決定していた。

    取り敢えず quote-insert で noquote が指定されていた時の CAND/INSERT の決定
    方法を修正した。

    x fixed: 動いていると思ったら全く候補が生成されなくなって fallback していた。
      quote-insert は終了ステータスに意味があるという事だった。

    x fixed: 改めて修正すると noquote による特別処理が動いていない、と思ったら
      count が空になっている。simple-word/eval で count を得る為には特別な条件
      が必要?  と思って確認したら opts に "count" を指定する必要があった。修正
      した。

    * OK: simple-word/eval は count も上書きする様だ → これは opts に count を
      指定した時だけの機能なので、一般の場合については変数汚染を気にする必要は
      ない。

    x fixed: メニューにフルパスで表示されてしまう。これは PREFIX_LEN の初期化を
      action:ACTION/initialize よりも後に移動すれば良いのだった。今 CAND も
      /initialize によって書き換えられる可能性があるので、書き換えられた後の値
      を参照して PREFIX_LEN を決定するべきなのである。

    x done: quote_fixed_comps に注意しなければならないのでは?

      取り敢えず quote_fixed_comps が設定されている時には CAND の書き換えは
      suppress する事にした。一方で、quote_fixed_comps が設定されている時でも上
      手にやる方法はあるだろうか。というか、quote_fixed_comps に抵触する場合に
      は今迄一体どの様に処理していたのだろうか。よく考えたらもっと後の段で候補
      を filter out しているのではないか。もしそうだとしたらここで何かしなくて
      も良いのではないかという気がする。

      と思ったが、値が先頭一致している場合にはそれに対応する部分まではちゃんと
      一致する様に生成しなければならないのではないか。

      quote_fixed_comps もしくは comps_fixed がどの様に処理されているのかを改め
      て確認する必要がある。

      うーん。brace 展開がある時に現在の実装でどう振る舞うのか不安になって来た。
      →取り敢えず簡単な場合にはちゃんと期待通りに動いている。然し何故動いてい
      るのかは謎である。と、思ったがそもそも fzf はブレース展開がある時に正しく
      候補を生成できていない。従って ble.sh の候補生成器に fallback していると
      いう事の様である。

      そもそも fzf には直接 comp_words を渡しているのだから、それでブレース展開
      を潰してしまったとしてもそれをそのまま受け入れて遡った書き換えを実行する
      のが自然の気もする。従って quote_fixed_comps を気にする必要はない。

      と思ったが fzf 以外が noquote を指定する可能性もあるのでやはり油断はでき
      ない。うーん。fzf 以外が noquote を指定した時にちゃんと comps_fixed を処
      理する様に修正する必要があるのでは。或いは fzf が指定されていたとしても
      comps_fixed を処理する。

      a うーん面倒だから quote_fixed_comps がある時は逆に reconstruct した CAND
        から INSERT を再度生成するのが良い気もしてきた。

      b と思ったが確認すると他にも色々しているのでやはり直接その場で
        quote_fixed_comps に関係する処理だけを実行する事にした。

      c 他に INSERT を解析して該当部分だけを抜き出すという事も場合によっては可
        能だが完全ではないし無意味に複雑になるし、そもそもブレース展開が存在す
        る様な文脈では quote の仕方を変化させても意味は変わらない筈なので、再度
        INSERT を CAND から再生成してしまっても問題ない気がする。

      上記の b の方法で実装する事にした。

    * done: progcomp-raw は別の名前にしたい。やはり最終的には ble.sh の拡張であ
      ると分かる様に blesh や ble.sh, ble- 等を付けるのが妥当という事になるだろ
      う。

      ble-progcomp-raw という事に取り敢えずしてみたが、そもそも compopt を設定
      するのは progcomp でしか起こらない事なので progcomp を含めるのは冗長であ
      る。然しそうすると ble-raw という事になるがこれだと一般的過ぎる気がする。
      もう少し絞る方法はないだろうか。

      類似の事を指定している箇所があった気がする。それは何でどの様に処理してい
      たか。→ "comp_type == *:raw:*" だった。reconstructed (COMPS で quote を
      閉じた物) を COMPV に設定していた。context:glob や
      context:dynamic-history の generate-sources で raw を設定していた。

      うーん。類似してはいるけれども微妙に異なる気もする。ble-syntax-raw にする
      か。然しそれだと syntax.sh 由来の物の様にも解釈できる (しかしそれはそれで
      実際正しいのではないか。extract-command の結果をそのまま渡す様に修正して
      いるのだから)。或いは単に syntax-raw にする?

  * 2022-02-02 main: やはり nix-shell の中でも有効にする [#D1766]
    Ref #D1747

    そもそも nix-shell で ble.sh が欲しい事もあるそうだ。報告がいい加減なので無
    駄な修正をした。
    https://github.com/akinomyoga/ble.sh/issues/169#issuecomment-1027096640

    * 改めて調べてみたら実際に実行するコマンドが exec になるのは ruby がコマン
      ド文字列に含まれている時のみの様である。

      # というか、ruby という部分文字列が含まれているだけで実装が切り替わるので
      # かなりいい加減な実装である。更に、単にこの四文字を探す為だけに
      # std::regex を初期化しているのもおかしい。

      実際にはユーザーによって指定された文字列 + exit を実行している様だ。なの
      で return をすると通常のシェルに入る事ができる、という事になっているのだ。

      https://github.com/NixOS/nix/blob/master/src/nix-build/nix-build.cc#L187

      # これも単に exit を付加するだけだと quoting の問題で何だか変な事になる気
      # がするが大丈夫なのだろうか。これ自体にセキュリティーの問題はないが、こ
      # れはセキュリティーの問題が起こるパターンの最たるものである。nix-shell
      # の実装はかなり怪しいと言わざるを言えない。

    うーん。これに対する対策はどうするのか? IN_NIX_SHELL が設定されている時には
    ble-attach を無効化して attach=none であっても prompt attach を強行するとい
    う風にするべきだろうか。。

    現在 bashrc の中にいるかどうかの判定はどの様にするのだったか。

    というか、もし rcfile の名前が固定なのであれば、BASH_SOURCE を使って検出す
    る事が可能なのではないだろうか。うーん。"一時ディレクトリ/rc" という形をし
    ているらしい。

    % そして一時ディレクトリは環境変数に設定されている。
    %
    % https://github.com/NixOS/nix/blob/73d5f38a47e7c3dea62994cfb8f962976194f767/src/nix-build/nix-build.cc#L428
    %
    % 例えば [[ ${BASH_SOURCE[${#BASH_SOURCE[@]}-1]} == $NIX_BUILD_TOP/rc ]] で
    % テストできるのだろうか。これは実際に nix-shell を入れてみない事には分から
    % ない気がする。
    %
    % →NIX_BUILD_TOP の中身を出力してみたがユーザーの run になっていて nix の
    % 一時ディレクトリではない。その他の一時ディレクトリも全てそうである。改め
    % て確認してみると tmpDir と TMPDIR は異なる変数だった。

    以下を観察すると nix-shell, nix-build という名前の一時ディレクトリになるらしい。

    https://github.com/NixOS/nix/blob/73d5f38a47e7c3dea62994cfb8f962976194f767/src/nix-build/nix-build.cc#L95-L101

    うーん。というか或いはそもそも IN_NIX_SHELL の時は ble-attach をしたら強制
    的に prompt attach で良いのではないかという気がする。と思ったが、そこまです
    る事もないので、取り敢えず BASH_SOURCE の末端が /rc だったら prompt attach
    を設定する事にした。

    これで一応動作はしている。

    x 2022-02-04 然し、今度は別のエラーが発生している。bind は builtin じゃない
      と出ている。誰かが無効化しているという事なのだろうか。或いは、もしかする
      と非対話シェルでは bind は常に存在していないのだろうか→うーん。確かめて
      みたが "行編集は有効になっていません" という表示が出るのみである。なので、
      nix-shell に於いては何だか怪しげな事がされている?

      調べてみると ble-attach の中で発生している。特に ble/decode/initialize の
      内部で発生している。不思議なのはちゃんと attach はできているという事。な
      ので bind が全く使えないという訳ではないという事。なのに何故 builtin は
      bind が存在しないという報告をするのだろうか。

      ble/builtin/bind/read-user-settings で問題が生じている。うーん。最初の
      builtin bind では何も問題が生じていない。という事は何処かから呼び出してい
      る builtin bind の綴を間違えているか或いは余分な文字が混入しているという
      事だろうか。

      と思ったら分かった。"$BASH" 云々 -c 'builtin bind -m emacs -p' 云々として
      既定の binding を読み取っている箇所で問題が起こっている。うーん。そうだと
      しても何故 builtin bind が使えないのか? 不思議である。

      →うーん。実際のバイナリは以下の様になっている。

      $ ls -la /proc/$$/exe
      lrwxrwxrwx 1 murase murase 0 2022-02-04 09:14:11 /proc/30092/exe -> /nix/store/xz3kkiscxh01yazxa1dk08q047mfl1fh-bash-interactive-5.1-p12/bin/bash
      $ echo "$BASH"
      /nix/store/2kh3c4v2vf6d6xg6c9n8zvfpwf3zzwca-bash-5.1-p12/bin/bash

      うーん。ちょっと何が起こっているのか分からなくなった。

      1 最初 (bashrc source 時): この時点で何故 BASH が現在のシェルではなくて
        /bin/bash になっているのか謎である。

        SHELL=/bin/bash
        BASH=/bin/bash

        うーん。SHELL に関しては外から export した物がちゃんと伝播している。
        BASH に関しては謎だ。もしかすると bash はビルド時に BASH を埋め込んでい
        る? と思ったがそうでもない様に見える。普通に

        $ /nix/store/xz3kkiscxh01yazxa1dk08q047mfl1fh-bash-interactive-5.1-p12/bin/bash

        としてログインした場合には何も変な事は起こっていない。ちゃんと自身の
        BASH が見えている。何か chroot 的な物をして bash をスタートしているのだ
        ろうか。bash のソースを見ると shell_name が相対パスでかつ login シェル
        ならばユーザー情報から BASH を初期化している。と思ったが、

        $ (PATH=/nix/store/xz3kkiscxh01yazxa1dk08q047mfl1fh-bash-interactive-5.1-p12/bin:$PATH; hash -r; bash --login -c 'echo $BASH')

        を実行してもちゃんと現在のシェルを見つけることができている。というか、
        shell_name の時点で正しく見つけることができているという事か。

      2 次に $stdenv/setup で BASH=$SHELL が設定されていると思ったが、そうする
        と最終的に BASH=non-interactive-bash になっている理由が分からない。

      3 更に最終的な SHELL の値は SHELL=interactive-bash になっている。つまり
        SHELL=non-interactive-bash になっている瞬間はない気がする。改めて SHELL
        の値について確認してみたが、これは stdenv/setup よりも後に設定されてい
        る様なので、最終的に interactive-bash にはなっていてもそれが BASH に反
        映されていなくても不思議はない。

      うーん。trace を得た。

      declare -x SHELL="/bin/bash"
      declare -- BASH="/bin/bash"
      /nix/store/xcy53qbjynin70g46w1nx011gr7jw8l1-stdenv-linux/setup:1: export SHELL=/nix/store/2kh3c4v2vf6d6xg6c9n8zvfpwf3zzwca-bash-5.1-p12/bin/bash
      /nix/store/xcy53qbjynin70g46w1nx011gr7jw8l1-stdenv-linux/setup:14: [[ -n "${BASH_VERSINFO-}" && "${BASH_VERSINFO-}" -lt 4 ]]
      /nix/store/xcy53qbjynin70g46w1nx011gr7jw8l1-stdenv-linux/setup:303: [ -z "${SHELL:-}" ]
      /nix/store/xcy53qbjynin70g46w1nx011gr7jw8l1-stdenv-linux/setup:304: BASH="$SHELL"
      /nix/store/xcy53qbjynin70g46w1nx011gr7jw8l1-stdenv-linux/setup:305: export CONFIG_SHELL="$SHELL"
      /nix/store/xcy53qbjynin70g46w1nx011gr7jw8l1-stdenv-linux/setup:309: export shell="$SHELL"
      /nix/store/xcy53qbjynin70g46w1nx011gr7jw8l1-stdenv-linux/setup:685: [[ -z "${NIX_SSL_CERT_FILE:-}" && "${IN_NIX_SHELL:-}" != "impure" ]]
      /nix/store/xcy53qbjynin70g46w1nx011gr7jw8l1-stdenv-linux/setup:689: [[ -z "${SSL_CERT_FILE:-}" && "${IN_NIX_SHELL:-}" != "impure" ]]
      /tmp/nix-shell-49112-0/rc:3: SHELL='/nix/store/xz3kkiscxh01yazxa1dk08q047mfl1fh-bash-interactive-5.1-p12/bin/bash'
      /tmp/nix-shell-49112-0/rc:3: [ -n "$PS1" -a -z "$NIX_SHELL_PRESERVE_PROMPT" ]

      うーん。setup.sh 1行目で SHELL を書き換えている。。。まとめると、

      1 何故か分からないが nix 環境では bash は BASH の初期化に失敗して
        /bin/bash を取り敢えず BASH に設定する。

      2 $stdenv/setup は非対話シェル用(特にビルド用)の環境であり、非対話用に特
        別にコンパイルされた bash の上で動作する事を想定している。なので中で
        SHELL と BASH に無理やり固定の値 (非対話 Bash) の値を設定している。

      3 更に nix-shell の呼び出し元では SHELL を対話シェルのパスに上書きしてい
        る。此処で BASH も同様に更新するべきではないか。

    * うーん。面倒になった来たのでやはり nix 用の workaround を追加する事にする。
      つまり問題は BASH が変な値になっているのが原因である。という事は無理やり
      BASH を補正してしまえば良い。

      a 環境の補正は ble.pp で集中して行っている箇所があるので其処で調整する事
        にする。と、思ったがよく考えたら nix-shell では setup の中で BASH を勝
        手に変更していて、更に、setup は bashrc よりも後で読み込まれるのだから、
        ble.sh の初期化時に BASH を補正しても仕方がない。うーん。

      b 一つの手は ble-attach の時に BASH を補正するという事。結局 "$BASH" を使っ
        ているのは、decode の初期化であって、decode の初期化は ble-attach で呼
        び出しているのだから。そして、現在既に ble-attach に nix 用の
        workaround が入っている。

      上記の b の箇所で BASH を上書きする事にした。

2022-02-09

  * edit: exit を実行すると時間計測結果が表示されてしまう [#D1765]

    これは何? 恐らく最近のコマンド時間計測と関連しているのだと思うが。そもそも
    exit を実行した後に time の結果が表示されうる物なのだろうか。

    うーん。以下を実行すると時間が実際に表示される。

    time { echo hello; exit; }

    以下を実行した場合には特に何も表示されない (exit と単に表示される)。

    time { echo hello; TIMEFORMAT=''; exit; }

    少なくとも workaround として TIMEFORMAT= は有効であるという事。
    以下の様にした場合でもちゃんと出力は抑制される。

    function f1 { local TIMEFORMAT=''; exit; }; time f1

    然し、この時の問題はユーザーが ble.sh の中で time { ... exit; } を実行した
    時に時間表示がされなくなってしまうという事。という事を考えると、やはり外側
    で設定する時に何か工夫して外で設定した time に関しては時間測定結果が表示さ
    れない様に修正するという事。

    うーん。然し、何故これが表示されてしまうのか。本来は別の所に出力されるべき
    なのではないか。。。これは bash に報告するべきなのではないか。

    * 取り敢えずおかしな現象が起こるという事をもっと簡単な場合で証明する事は可
      能だろうか。

      実際に振る舞いとしておかしいという事も以下のコマンドで確認する事ができる。
      つまり time の出力は 2>/dev/null に吸い込まれるべきであるのにも拘らず、
      exit が実行された文脈での 2 の接続先である 2>/dev/tty に出力されてしまう。

      $ bash-5.1 --norc
      $ function f1 { { echo hello; exit; } 2>/dev/tty; }
      $ { time f1; } 2>/dev/null

    * →と思ったらどうやら 5.2 では既に修正されている様だ。更に昔の version の
      振る舞いも確認してみた所、どうやら 4.4..5.1 で発生する問題の様である。

    これに関しては exit の側で workaround をする事にする。これによって 4.4..5.1
    では、ユーザーが time { echo hello; exit; } を実行した時に何も表示されなく
    なるが、それは仕方がない。

    そもそも 4.3 以前では time { echo hello; exit; } に対して結果は出力されなかっ
    た様である。という事を思うと、実は 4.4..5.1 は time の内部で exit を実行し
    た場合でも時間を表示する様に修正する上での壊れた振る舞いだったという事にな
    る。

    x 2022-02-13 動いていない。#D1771 をテストする時にで時間計測の結果が出力さ
      れてしまう問題が未だ残存している事に気づいた。うーん。既に対策した筈だが
      動いていないという事。

      うーん。改めて試してみたが確かに全然動いていない。

      ? reject: うーん。つまり… trap handler の側の stderr に出力されていると
        いう事だろうか。EXIT trap handler は ble.sh は常に設定している。

        一応 EXIT trap handler が呼び出されなかった・設定が消えている場合に備え
        る為に ble/builitin/exit での対策は残しておく事にする。

        と思って trap handler の側で TIMEFORMAT= にしたが効かない。というより
        trap handler が呼び出されるよりも前に時間測定結果が表示されている。因み
        に EXIT handler はトップレベルで呼び出されている。

      うーん。global の TIMEFORMAT を空にしたら表示されなくなった。取り敢えずは
      それで実行する事にする。と思ったが…うーん。exit に失敗したら元に戻さなけ
      ればならないのでは。因みに global の値を取得するのは少々面倒である。

      うーん。後 global の TIMEFORMAT を unset する手段がない。取り敢えず既定値
      を代入すれば良いのだろうか。既定値は man bash にあったのでそれをそのまま
      使う事にした。

2022-02-05

  * [棄却] 2022-01-31 nix-build -A の補完が効かないという問題 [#D1764]
    https://github.com/akinomyoga/ble.sh/issues/171#issue-1113799687

    取り敢えず nix は入れたが nix コマンドや nix-build コマンドは見つかるのだろ
    うか。また nix-shell コマンドも使えるのか気になる所である。

    動かない。そもそも通常の bash で動くのだろうか。実際に単に source するとエ
    ラーが出る。bash-completion を一緒にロードしないといけない様だ。然し結局通
    常の bash で実行しても nix-build -A [TAB] で補完がされる事はなかった。

    $ bash --norc
    $ source ~/.mwg/git/scop/bash-completion/bash_completion
    $ source _nix

    一体どの様にするのが良いのだろうか。

    →これは結局よく分からないが今は動いている様である。手元でもちゃんと動いて
    いる事を確認した。向こうの勘違いか或いは他の問題と関係していたかという事だ
    ろう。

  * 2021-12-18 ble/util/import でファイル名に関数名として許されない文字が入っていた時の対策が必要では [#D1763]

    関数名として許されない文字は実はそんなに多くはない気がする。Unicode 文字の
    殆どは関数名に使える。特殊な意味を持つのは ASCII の範囲内に限られるからであ
    る。

    $' \t\n;|&<>()$`"\'\\'

    履歴展開文字 !^ に関しては一時的に履歴展開を無効にして関数を定義すれば行け
    る気もしないでもないが面倒なので考えない事にする。

    特定の文字 (例えば _) に一律に置き換えてしまって衝突は已む無しとするという
    事を考えたが、実は % (url) encoding みたいな事をすれば良いのではないかとい
    う気がする。但しその為には沢山置換を実行しなければならない。新しい
    strreplace は使えない。置換前の文字を直接使える訳ではないので。

    | a 直接ハードコードする
    |
    |   a=' '   b=%20
    |   a=$'\t' b=%08
    |   a=$'\n' b=%0A
    |   ...
    |
    | b 次の様に pack してループを回す。然し何だか変な気がする。
    |
    |   '%25' ' 20' $'\t08' $'\n0A' ';3B' '&26' '|7C' '<3C' '>3E' '(28' ')29' '$24' '`60' '"22' \'27 \\5C
    |
    | c それよりは個別にした方がすっきりするのではないか。でも対応が分かりにくい。
    |
    |   $'% \t\n;|&<>()$`"\'\\'
    |   25,20,08,0A,3B,26,7C,3C,3E,28,29,24,60,22,27,5C
    |
    |   然しこれならファイル名にこれらの文字が含まれていないかどうかの確認も簡単
    |   である。改めて文字コード順に並べる事にする。
    |
    |   chars=%$'\t\n !"$&\'();<>\\^`|'
    |   rep=(%{25,08,0A,20,21,22,24,26,27,28,29,3B,3C,3E,5C,5E,60,7C})
    |   rep=(%{25,08,0A,2{0..2},24,2{6..9},3B,3C,3E,5C,5E,60,7C})
    |
    | d 或いは次の様にする。
    |
    |   '%':%25 $'\t':%08 $'\n':%0A ' ':%20 '!':%21 '"':%22 '$':%24 '&':%26
    |   \':%27 '(':%28 ')':%29 ';':%3B '<':%3C '>':%3E \\:%5C '^':%5E '`':%60
    |   '|':%7C

    c の方針で考える事にした。実装した。取り敢えず空白を含むファイル名で試した
    ら動いているのでOK.

2022-02-02

  * render: 処理途中に WINCH が来ると途中状態のデータに対して処理が走ってデータが壊れる [#D1762]

    以下のテスト中に描画の無限ループを検出した。
    https://github.com/akinomyoga/ble.sh/issues/173#issuecomment-1028479357

    更に色々やっていると tree_node に inconsistency が発生した。というところで
    分かった。恐らく描画処理の途中で SIGWINCH が走った所為で、中途半端な状態で
    新しい描画が始まる事によってデータを破壊している。処理の途中で描画は実行し
    ない様にする必要がある。

    特に PROLOGUE と EPILOGUE の間で SIGWINCH が来た時には EPILOGUE の末尾で改
    めて再描画を実行する様にする必要があるのではないか。

    後、描画処理が終わった後のサイズ変更検知も実行するべきなのかもしれない。と
    思ったが、それは実は通常の描画の際にも毎回実行するべき事なのではないか。

  * mandb: rsync --no-while-f[TAB] で説明が一緒に挿入されてしまう [#D1761]

    DATA を挿入しているのだろうか。。或いは、単一確定の場合に postprocess が走っ
    ていなくて直接補完されている。後で確認する必要がある。

    →どうやら ACTION progcomp で生成されている様だ。--no-whole-file に対しては
    問題発生するが、--whole-file に対しては問題は発生しない。どうも CAND の時点
    で大変な事になっている。

    →OK. --no-OPTION の説明を勝手に生成した時に mandb_count++ するのを忘れてい
    た為に、mandb 処理がスキップされていたのが原因だった。

  * complete: fzf と組み合わせている時に補完の再試行がされない問題 (reported by SuperSandro2000) [#D1760]
    https://github.com/akinomyoga/ble.sh/issues/171#issuecomment-1021326168

    fzf / bash-completion を両方組み合わせている時に ssh_config から読み取ったホスト名が正しく補完されない問題。

    | 先ず普通の bash で動く様にするまでが大変だった。取り敢えず以下の順序で初期化すれば動く。
    |
    | $ bash --norc
    | $ source ~/.mwg/git/scop/bash-completion/bash_completion
    | $ _ble_contrib_fzf_base=~/.mwg/git/junegunn/fzf
    | $ PATH=$PATH:$_ble_contrib_fzf_base/bin
    | $ source $_ble_contrib_fzf_base/shell/completion.bash
    |
    | 然し、同じ順序で ble.sh を初期化したらちゃんと動く。うーん。初帰化の順序に
    | 依存するのではないか。
    |
    | つまり、bash-completion を fzf よりも先に読み込んでいない為に起こっているの
    | ではないかと推測されて、例えば ble.sh を bashrc の最初で source していて
    | blerc の中で直接 ble-import を実行しているのだとしたら、その場で fzf
    | completion.bash が読み取られる。その後で bashrc に戻ってきて
    | bash_completion を初期化しているという可能性がある。
    |
    | 然し instruction では ble-import -d を使う様にお願いしている筈だ。という事
    | を考えると bash-completion を bashrc の後で source していても問題は起こらな
    | いのではないかという気がするが…。

    * done: fzf-completion は bash-completion よりも先に読み込んでおく必要があ
      るという事を何処かに記述しておく。

    [問題再現]

    嗚呼分かった。2回目以降で動くようになるというのは既にちゃんと報告を受けてい
    た。そして実際に報告通りに初回は失敗して2回目以降はちゃんと動くという振る舞
    いになっている。

    [原因]

    | これは補完再実行の仕組みに関係しているのだろう→うーん。戻り値 124 を期待し
    | ているのにそもそも 124 を補完関数が返さなくなっているのが問題の様に見える。
    |
    | →うーん。分かった。retry は default completion の時にだけ確認する様にして
    | いたが、実は任意の補完についてやり直しが可能という事なのだろう。bash のマニュ
    | アルを見ると 124 による再試行は -D と組み合わせると便利とは書かれているが、-D
    | と組み合わせた時にしか有効にならないとは書かれていない。つまり、
    | is_default_completion でなくても再試行は行うべきである。

    fzf completion はロード時に bash-completion を検出した場合、今後の補完で
    _completion_loader による補完を呼び出そうとする。初回の _completion_loader
    呼び出し時には 124 を返して Bash に対して補完の再試行を要求する。これはどの
    コマンドの補完に対しても同様である。

    一方で ble.sh は 124 に対する補完の再試行は complete -D による補完の時だけ
    しか許さない様になっていた。従って、fzf が予め設定している ssh に対する補完
    設定については、いざ _completion_loader によって内部的に bash-completion が
    呼び出されて 124 を返したとしても、補完の再試行が行われない。というのが問題
    であった。

    [過去の関連修正]

    | ? これに関係する修正を最近しなかったか。その時の都合で現在の様な実装になっ
    |   ている可能性がないかについて確認する。
    |
    |   98835b5a lib/core-complete.sh (Koichi Murase   2021-05-17 14:52:51 +0900 3036)   builtin eval '"$comp_func" "$cmd" "$cur" "$prev"' < /dev/null >&$_ble_util_fd_stdout 2>&$_ble_util_fd_stderr; local ret=$?
    |   58e1be46 lib/core-complete.sh (Koichi Murase   2020-02-10 00:42:04 +0800 3037)   ble/function#pop compopt
    |   4df15e1e complete.sh          (Koichi Murase   2017-10-12 00:52:41 +0900 3038)
    |   4df15e1e complete.sh          (Koichi Murase   2017-10-12 00:52:41 +0900 3039)   if [[ $is_default_completion && $ret == 124 ]]; then
    |   4df15e1e complete.sh          (Koichi Murase   2017-10-12 00:52:41 +0900 3040)     is_default_completion=retry
    |   4df15e1e complete.sh          (Koichi Murase   2017-10-12 00:52:41 +0900 3041)   fi
    |   cdd38598 complete.sh          (Koichi Murase   2015-11-23 23:58:01 +0900 3042) }
    |
    |   と思ったが該当部分の判定は4.5年間変化していない。つまり、関係ないはず。
    |   では最近の問題は何だったろうか。
    |
    |   →うーん。fzf で note.txt を検索しても特に何も出てこない。
    |
    | * 分かった。これだ bash-completion に対する PR の議論だった。
    |   https://github.com/scop/bash-completion/pull/653
    |
    |   bash-completion も他の補完が設定されている時にそれを呼び出すという処理を
    |   している。その時に、これまで bash-completion は 124 が返ってきても何もし
    |   ていなかったのをちゃんと再実行する様に変更するという PR だった。
    |
    |   結局最近何か処理した気がするというのは bash-completion の話だったので
    |   ble.sh は関係ない。つまり、現在の実装になっているのには何の理由もないので
    |   単純に修正すれば良いのだという結論。

    関連する修正があった様な気がしたがそれは bash-completion の話だった。

    問題の箇所を実装した時の議論 #D0534 を確認すると、「complete -D による補完
    の時に 124 が返されたら再試行」とはっきりと書かれている。つまり仕様を勘違い
    していた事になる。

    ? 一方で報告によると auto-complete を off にしたら問題が発生しなくなったと
     している。不思議だ。うーん。一節には auto-complete でメニューが初期化され
     てその中だけで補完しようとする事によって補完内容が減少してしまっている可能
     性。然し、auto-complete ではその様な事は起こらないし、或いは表示されている
     物に惑わされて補完候補が生成されないと勘違いしている?

     と思ったがもう一つの可能性として TAB に独自の auto-complete 用の binding
     を付加している可能性もある。うーん。然し過去に SuperSandro2000 そういう議
     論を開いた訳でもない。然しそれでも何処かの説明を見て TAB の設定を追加して
     いるという可能性はある。

     これは取り敢えず向こうの設定が原因になっている可能性があるので後回しで良い。

  * complete: / が symlink に対して付加されたり付加されなかったりする (reported by SuperSandro2000) [#D1759]
    https://github.com/akinomyoga/ble.sh/issues/171#issuecomment-1021326168

    bash-completion なしでも再現する → これは分かった。bind -v で
    mark-symlinked-directories が off になっているのが原因だった。元の bash だ
    とこれが off になっていたとしても2回 TAB を押したら結局 / を挿入する様だ。
    →もう少し調べてみると ins が空の時には mark-symlinked-directories がなくて
    も / を挿入するという事らしい。

    うーん。元の bash と同じ振る舞いになる様に調整する事にした。これの判定は手
    持ちの情報で既にできたのでその様にした。

  * term: wt で 描画中のカーソル移動が気になる [#D1758]

    flush する時か、或いは描画シーケンス自体にカーソル消去・表示のコードを埋め
    込むべきではないか。

    一方で現在の表示状態はまた別の箇所で管理していた筈である。うーん。現在のコー
    ドだと cursor-state/hidden は描画とは独立に管理している。なので描画に対して
    表示・非表示を埋め込もうとすると buffering によって順序が入れ替わっておかし
    な事になる。それよりは画面に出力する瞬間に一時的に hidden にするのが良い気
    がする。うーん。buffer.flush に介入するのが一番簡単の気がする。怖いので一部
    の端末だけで試験的に実行する? と思ったがテストという観点から考えると取り敢
    えず全部 on にして試す事にする。

    →実装した。取り敢えず変な影は表示されなくなった。それでも何だか点滅してい
    る様な気がするが仕方がない事である。contra/screen では特に問題はない。また
    mintty でも特に問題は見られない。mintty/tmux でも問題は見られない。これは採
    用する事にする。

    * 序でに Windows Terminal の identification も実装する事にする。調べるとど
      うも hardcode している様に見える。取り敢えずこれに対して判定する。カーソ
      ル形状の変更にも対応している様だ。

      https://github.com/microsoft/terminal/blob/bcc38d04cef39fe9d939bf5c10bca5e3bd0a9118/src/terminal/adapter/adaptDispatch.cpp#L779-L782

2022-02-01

  * util (trap): SIGWINCH を沢山呼び出した後にどんどん重くなる (reported by SuperSandro2000) [#D1757]
    https://github.com/akinomyoga/ble.sh/issues/173#issuecomment-1026891422

    これは _ble_builtin_trap_postproc を出力したら分かった。trap handler が走る
    度にどんどん $_ の中身が長くなっている。

    > ble/util/setexit 1 ''
    > ble/util/setexit 1 'ble/util/setexit 1 '\'''\'''
    > ble/util/setexit 1 'ble/util/setexit 1 '\''ble/util/setexit 1 '\''\'\'''\'''\''\'\'''\'''\'''

    この様になっている。先ず、builtin eval の中から $_ を再設定しようとしても
    eval に渡した引数が $_ になってしまうという事が問題である。これはどの様にし
    たら良いだろうか。一つの方法は eval "postproc" '#' "lastarg" と呼び出すという事。

    x postproc に文法的に壊れた物が入っていた時に変な事になるのではないか。と思っ
      たが、postproc を設定しているのは trap handler の枠組み自身なのでちゃんと
      した物しか入っていないというのは保証される気がする。

    x lastarg に改行が含まれている場合には復元できないのではないか。これはどう
      しようもない。

    というか今回の問題を除いても $?, $_ を正しく復元できている様に見えない。
    trap handler の各ケース done, return, break, continue のそれぞれについて
    $?, $_ を正しく保存しなければならない。

    先ず return/break/continue の時の $? $_ の振る舞いについて確認する必要がある。

    $ trap 'break 1' INT
    $ for ((i=0;i<1000000;i++)); do ((a++)); done; echo "_=$_"
    ^C
    _=1
    $ trap 'break' INT
    $ for ((i=0;i<1000000;i++)); do ((a++)); done; echo "_=$_"
    ^C
    _=break

    この結果を見ると loop の外で $?, $_ を見ることができる。更に言うと break,
    continue に渡された引数ですら取得できる。 for (()) は $? $_ を書き換えない
    様に見える。

    ? break/continue に引数として許される形式は? 普通の整数はOK 負の整数もOK +1
      などもOK 少数は駄目だった。空文字列も駄目だった筈。その様な判定にした。

    取り敢えず実装してみたが全然正しく復元できていない。

    x fixed: 次に setexit が結局 $_ に設定されてしまっている。何故。と思ったら
      '#' が本当に # になってしまっていた。これは直した→すぐに動く様になった。

    x fixed: 先ず $_ で取得した lastarg には gexec に使った begin ... end が入っ
      ている。これはそのままでも良いのかもしれないし、或いはコマンド実行中かそ
      うでないかで振る舞いを変更するべきなのかもしれない。コマンド実行中でない
      時にはユーザートラップを呼び出す前に復元してユーザートラップを呼び出した
      後に保存する?

      % 或いはそもそも保存しなくても良い気がする。本来 trap が別のコマンドに影響
      % を与えるというのも変な話である。→と思ったが或る handler の影響は次の
      % handler に残っていて欲しい気もする。つまり、ユーザーコマンドに影響が残る
      % のは変な気がするが一方で同じ handler の間で $?, $_ がちゃんと保持されてい
      % なければ変だという事。やはり保存するべきの様な気がしてきた。
      →ユーザートラップによって変更された $_ はちゃんと反映させるべきの気がする。
      →うーん。結局トラップ専用の lastarg,lastexit 変数に記録する事にした。

    x おまけで ble/dispatch のモード判定にミスを発見した。修正した。

    取り敢えず制限はあるがこれで大丈夫の筈。

2022-01-24

  * edit: コマンド実行時間計測 [#D1756]

    前から気になっていたので実装する。

    * time を用いた計測? 少なくとも msec の精度は存在する。prologue にかかる時
      間などは気になるが。prologue は含めずに計測するのが良いだろう。


      現在の gexec の構造を何処まで変更できるかについて確認しなければならない。
      現在の構造に修正したのは 014d17e6 (#D0465)である。うーん。eval を跨ぐと
      $_ が継承されない? と思ったが prologue に関しては同じ eval に入れなくても
      大丈夫に見える。以下のコマンドを各 bash version で試したがちゃんと動いて
      いる。

      $ { echo hello world; time builtin eval 'echo "[$_]"'; echo $_; }

      うーん。分かった。prologue を同じ eval の中に入れるのは set -v の時の出力
      を最低限に抑える為である → 書き換えた。一応ちゃんと $_ 及び $? が復元で
      きている事を確かめた。

    うーん。ble/util/clock だとか ble/bin/date +%s%6N だとかに頼る方法を考えて
    いたが、time の結果を読み取っている現状では tot をそのまま参照すれば良い気
    がする。開始時刻に関しては date または printf または SECONDS を用いて取得す
    れば良い → 最終的にはやはり ble/util/clock または date +%s%6N に頼る事にし
    た。それを tot を用いて補正する。

    * SECONDS, EPOCHREALTIME, EPOCHSECONDS を readonly するという事? EPOCH* に
      ついては流石に間違えて上書きしたりする事はないと思われる。SECONDS は
      ble/util/clock の初期化時に readonly する事にした。EPOCHSECONDS はどうせ
      使っていないので関係ない。

    * done: カスタマイズインターフェイスについて考えた方が良い気がする。現状で
      既存の errexit とどうくっつけるのかというのが問題である。というより、本当
      は色分けをしたりしたい所だが、現状 errexit の設計が固定文字列になっている
      ので、勝手に弄る余地がなくなってしまっている。

      或いは既定値の時にはくっつけるという操作をするというのでも良いかもしれな
      い? と思ったがそれも変である。或いは、もっと別枠の設定を用意するというの
      も手なのかもしれない→うーん。両方とも無効化して自前で書くというのが良い
      気がする。という事を考えたら、現状では exec_errexit_mark と同様に
      exec_elapsed_mark を定義すれば良い。

    * done: contrib README.md
    * done: ChangeLog
    * done: blerc: new bleopts
    * done: wiki: new bleopts

    x 外部コマンドの時間が計れていない? と思ったが単に cxxmatrix に対して端末が
      遅いだけなのであった。多分測れている。子シェルを合計するかしないかの設定
      があった気がしたけれど、それは多分 times であって関係ないのだ。一応 times
      を使えば real 及び sys の子プロセスの内訳も見られる気がする…が BG で動い
      ている物が加算されるのかは謎である。

      →うーん。times はジョブが終了した瞬間に加算されるので、bg のジョブが丁度
      終了したりすると、現在実行しているコマンドの shell/sys の値を評価できなく
      なる。そもそも time で取れている情報の筈なので関係ない気もする。。と思っ
      たが、シェル本体と子プロセスの時間を区別するのには使えるのかもしれない。
      つまり自プロセスの処理時間を取得するのには使える。

    x EOF marker が動かなくなっている。確認する必要がある。と思ったがこれは単純
      に 2 が /dev/null に繋がっていたというだけの話だった。OK

  * edit: bind -x 関数の呼び出しに際しての画面クリアの振る舞いについて (motivated by SuperSandro2000) [#D1755]
    https://github.com/akinomyoga/blesh-contrib/issues/6#issuecomment-1020165711

    GNU readline は 4.4 で振る舞いを変更した様だ。それ以前はただ単純に現在の編
    集位置にカーソルを置いたまま bind -x の関数を呼び出していた。4.4 以降ではプ
    ロンプトの終了点・編集文字列の開始点の行にカーソルを置いて bind -x の関数を
    呼び出す様になった様だ。実は

      https://github.com/junegunn/fzf/issues/490#issuecomment-184402254

    でもその事が説明されている気がする (何が書かれているかちゃんとは見ていない
    が)。というよりこの振る舞いについては前にも議論した事があるような気がする。
    →うーん。#D0915 (90ca3bea) の最後の動作確認の所で微妙に言及しているだけで
    ある。これ以降は .hide-current-line も対して更新されていないし振る舞いにつ
    いては変更はなかったと思われる。その時は手元で試して振る舞いを決定した気が
    するが詳細については記録に残っていないという事。

  * patsubWA: compat42 での振る舞い [#D1754]

    それとは別に compat42 の効果についても考察する必要がある。compat42 の時には
    結局問題が生じるのではないだろうか?? quote しても無駄である。という事を考え
    ると compat42 の時は単純に実装を切り替えるというのは動作しない。とは言いつ
    つ惨事を防ぐ為にはやはり配慮が必要である。

  * patsubWA: bash-dev で \q{} が動かない [#D1753]

    うーん。これも patsub が原因の気がする。或いは bash-dev の振る舞いの変化に
    よって引き起こされている? 取り敢えず調べる → やはり patsub WA によって動か
    なくなっている。bash 側の振る舞いの変化による物ではなかった。

    実際の動作を調べる。先ずそもそも \q{} が呼び出されているのか? うーん。呼び
    出されていない。つまり @P による展開になってしまっているという事だろうか →
    否、@P による展開にはなっていない。

    うーん。どうやら \q{} はいつの間にかに \\q{} に変換されてしまっている様子。
    何故だろうか。うーん。bleopt_prompt_rps1 の値の時点で \\q{} になってしまっ
    ている。つまり、bleopt が悪い。

    うーん。引数読み取りの時点で駄目になっている。

    $ ble/array#push specs "${var[@]/%/"=$value"}" # #D1570 #D1751 WA checked
    $ ble/debug/print-variables var value specs |& cat -v >/dev/tty
    var=('bleopt_prompt_rps1') value='\q{blerc/rps1}' specs=('bleopt_prompt_rps1=\\q{blerc/rps1}')

    うーん。不思議だ。bash-5.2 のバグだろうか。うーん。これはバグである。という
    か /% 等の様にパターンが空の時には escape は処理されないのである。

      $ var= rep='&'; echo "${var/%/"$rep"}"

    うーん。Bash に報告しようと思ったが思ったよりも複雑である。続きは
    bug-report/bash/report31 で議論する事にした。取り敢えず patch は作った。最
    終的にどうなるかは分からないが取り敢えずは patch 付きでコンパイルしていれば
    今の ble.sh の実装で大丈夫のはず。

  * patsubWA: bash-4.3 で \$ になる [#D1752]

    これもつい最近までは見られなかった問題である。bash-3.0 迄影響を受けている。
    これも patsub_replacement 対策が悪さをしていると見える。

    % うーん。_ble_prompt_const_root を出力している箇所から既に問題が起こっている
    % 気がするが、_ble_prompt_const_root の値は昔から変わらず "\$" だった様だ。
    % 然し、patsub 修正よりも前にはちゃんと単一の $ になっていた。
    %
    % $ declare -p _ble_prompt_const_root
    % declare -- _ble_prompt_const_root="\$"
    %
    % →これは declare の出力の quote であって、_ble_prompt_const_root の値自体
    % は常に単一の '$' だった。

    というよりそもそも ble/prompt/print は $ を解釈しないのではなかったのか。だ
    とすれば \$ の様にする意味がない。うーん。つまり以前の実装が間違っていたと
    いう事。

    うーん。分かった。確かに以前の実装は間違っている。escape-characters に渡す
    文字集合は '$\`"' ではなく '\$`"' でなければならない。つまり一番最初に '\'
    を置換しなければ他の文字の置換結果の '\' も二重に置換してしまう事になる。こ
    の様な実装に切り替えたのは patsub の事だと思ったが

    % よく考えたらそれよりも前から二重のバグによってたまたま動いていただけに過
    % ぎない → これも勘違い。以前は '$' を正しく quote して正しく最終的に '$'
    % になっていた。
    %
    % |  function ble/prompt/print {
    % | -  local text=$1 a b
    % | -  if [[ ! $prompt_noesc && $text == *['$\"`']* ]]; then
    % | -    a='\' b='\\' text=${text//"$a"/$b}
    % | -    a='$' b='\$' text=${text//"$a"/$b}
    % | -    a='"' b='\"' text=${text//"$a"/$b}
    % | -    a='`' b='\`' text=${text//"$a"/$b}
    % | -  fi
    % | -  ble/canvas/put.draw "$text"
    % | +  local ret=$1 a b
    % | +  [[ $prompt_noesc ]] ||
    % | +    ble/string#escape-characters "$ret" '$\"`'
    % | +  ble/canvas/put.draw "$ret"
    % |  }
    %
    % と思ったがこの編集を見ると以前はちゃんと動いていた筈なのである。という事は、
    % 先ず初めに '\$' が \\\$ になって、更に評価時に \$ になる筈。不思議である。
    % うーん。以前は \$ は \\\$ になって、更に評価された時に \$ になるという仕組
    % みだった筈。

    何れにしても問題の部分を修正したらちゃんと動く様になった。

    % 然し何故これで動くのかは未だに謎である。うーん。何故?
    %
    % →ずっと遡っていくと実はずっと単一の '$' である。。そして
    % _ble_prompt_const_root も単一の '$' である。declare の出力が double
    % quoted だから \$ と表示していたけれども実は単一の $ だったという事である。
    % つまり勘違いだった。

    結局これで万事大丈夫になった。

  * patsubWA: bash-4.2 で文法エラーが発生する (bind.delay 周り) [#D1751]

    何と、bash-4.2 では "${var//xx/"yy"}" の " は literal になる。テストで検出
    された物を少し修正したが他にも沢山ありそうだ。

    $ grc '"[^"]*\$\{[[:alnum:]_]+(\[[^][]*\])?//?([^{}]|\{[^{}]*\})+/[^{}"'\'']*"[^"]*([&$]|\\)' --exclude=./test
    done: ./keymap/vi_test.sh:44:    ble/util/print "  initial  = \"$i:${in//$nl/"$NL"}\""
    done: ./keymap/vi_test.sh:45:    ble/util/print "  expected = \"$f:${fin//$nl/"$NL"}\""
    done: ./keymap/vi_test.sh:46:    ble/util/print "  result   = \"$_ble_edit_ind:${_ble_edit_str//$nl/"$NL"}\""
    done: ./lib/core-complete.sh:3432:    [[ $progcomp_prefix ]] && cands=("${cands[@]/#/"$progcomp_prefix"}") # WA #D1570 safe
    done: ./lib/core-syntax.sh:4414:        b='\`' a='`'; str="${str//"$b"/"$a"}"
    done: ./lib/core-syntax.sh:4415:        b='\"' a='"'; str="${str//"$b"/"$a"}"
    done: ./lib/core-syntax.sh:4416:        b='\$' a='$'; str="${str//"$b"/"$a"}"
    done: ./lib/core-syntax.sh:4417:        b='\\' a='\'; str="${str//"$b"/"$a"}"
    done: ./lib/core-syntax.sh:4453:    a=\\   ; b="\\$a"; ret="${ret//"$a"/"$b"}"
    done: ./lib/core-syntax.sh:4454:    a=\'   ; b="\\$a"; ret="${ret//"$a"/"$b"}"
    done: ./lib/core-syntax.sh:4455:    a=' '  ; b="$_ble_syntax_bash_heredoc_EscSP"; ret="${ret//"$a"/"$b"}"
    done: ./lib/core-syntax.sh:4456:    a=$'\t'; b="$_ble_syntax_bash_heredoc_EscHT"; ret="${ret//"$a"/"$b"}"
    done: ./lib/core-syntax.sh:4457:    a=$'\n'; b="$_ble_syntax_bash_heredoc_EscLF"; ret="${ret//"$a"/"$b"}"
    done: ./lib/core-syntax.sh:4458:    a=$fs  ; b="$_ble_syntax_bash_heredoc_EscFS"; ret="${ret//"$a"/"$b"}"
    done: ./src/util.sh:118:          ble/array#push specs "${var[@]/%/"=$value"}" # #D1570 WA checked
    done: ./src/util.sh:777:    ARR=("${ARR[@]::$2}" "${sARR[@]/#/"$4"}" "${ARR[@]:$3}")' # WA #D1570 checked
    done: ./src/util.sh:1138:  a='!' b='"\!"' ret=${ret//"$a"/"$b"}
    done: ./src/util.sh:1165:    a=$'\n' b="\$'\n'" ret=${ret//"$a"/"$b"}
    done: ./src/util.sh:1401:  builtin eval -- "${_ble_local_script//opts/"$1"}"
    done: ./src/util.sh:1405:  builtin eval -- "${_ble_local_script//opts/"$1"}"
    done: ./src/util.sh:1413:  builtin eval -- "${_ble_local_script//opts/"$1"}"
    done: ./src/util.sh:1421:  builtin eval -- "${_ble_local_script//opts/"$1"}"
    done: ./src/util.sh:1574:    ret=("${ret[@]//$_ble_term_FS,/"$_ble_term_FS"}") # WA #D1570 checked
    done: ./src/util.sh:5371:  ble/util/put "${_ble_term_visible_bell_show//'%message%'/"$sgr$message"}" >&

    取り敢えず全て修正した。一応動作はしている。

  * prompt: wezterm shell-integration が PRECMD で何かを出力するがずれる [#D1750]

    先ず precmd を呼び出す瞬間のカーソル位置が前回のプロンプトの後になっている
    ので、この時点でずれが生じる。これは bash に倣って次のプロンプトの最初にカー
    ソルを移動してから呼び出すべきという事なのだろうか。

    x ok: 次に、precmd の直前で flush する様にしても座標位置がずれてしまう。特
      にコマンドを実行した直後の状態が怪しい。これは別の dock にいたりする事が
      原因なのだろうか。。と思ったが、うーん→これは分かった。info を表示してい
      る為に内部座標原点にいないのが原因であった。内部座標原点に移動してから
      flush したら、表示位置がずれる問題は解決した。

    x 然し依然として precmd の中から出力した事自体によってずれが生じる問題につ
      いてはそのままである。うーん。info を表示するよりも前に precmd は実行する
      べきという事なのだろうか。

    ? ok: そもそも precmd と prompt_command は分けて考えるべきなのかもしれない。

      コマンド実行ではなくて別の理由で (SIGWINCH などで) プロンプトの再計算が走
      る場合に本当に precmd や PROMPT_COMMAND も一緒に呼び出してしまって良いの
      かというのも疑問である。端末サイズに応じてプロンプトを更新したいという事
      を考えれば PROMPT_COMMAND は WINCH に対して改めて実行したほうが良い気もす
      る。然し、PRECMD の意味を考えたら本当にコマンド入力を開始した時にだけ呼び
      出したい様な気もする。然し、コマンド入力を開始したい時はやはり
      PROMPT_COMMAND なのではという気もする。

      その様に色々考えると PROMPT_COMMAND と一緒に実行する現在の設計で問題ない
      気もする。そして SIGWINCH でも呼び出して良い。前のプロンプトを捨てて新し
      いプロンプトを構築すると考えれば良い。

    * ble/prompt/update の呼び出しはより外側に移動しても良いのではないか。

      うーん。然し leave in opts のテストがある。これは textarea#render に渡さ
      れる引数である。呼び出し元は以下の二箇所。何れも
      ble/widget/.insert-newline からの呼び出しである。

      ./src/edit.sh:5713:    ble/textarea#render leave
      ./src/edit.sh:5724:    ble/textarea#render leave

      うーん。leave の時には改めてその場で ble/prompt/update を呼び出す。少し書
      き換えてみる。

    実装してみたは良いがよく考えたら現在の実装だとプロンプトの更新が滞る。

  * main: /dev/tty が割り当てられていない時にも ble.sh は初期化しない [#D1749]
    https://github.com/oilshell/oil/issues/1069#issuecomment-1017189089

    Docker でロードしようとしている時に失敗する。

    後、--test や --update 等の時には通常コマンドとして動作するので様々のチェッ
    クを無視して良い。更に言うとそもそも /dev/tty から端末を取得しようとする事
    自体が不要である。取り敢えずその様に実装した。

  * canvas: wezterm で DECSTBM のクリアに失敗している [#D1748]
    https://github.com/akinomyoga/ble.sh/issues/96#issuecomment-1019570983

    kitty もそうだったが \e[;r では DECSTBM をクリアできない模様。
    DECSTBM と同様にその場で端末をテストする事にした。修正した。
    この問題については解決した。

2022-01-23

  * main: IN_NIX_SHELL をチェックする (reported by SuperSandro2000) [#D1747]
    https://github.com/akinomyoga/ble.sh/issues/169#issuecomment-1019405936
    https://github.com/akinomyoga/ble.sh/issues/169#issuecomment-1019555462

    取り敢えず IN_NIX_SHELL をチェックする事にした。

    またチェックは rshell やその他のチェックよりも先に行うべきである。特に最初
    にエラーメッセージなしで抜けるのであれば、それは他の条件でエラーメッセージ
    が表示される前に一番最初にチェックするべきなのである。

  * util: _ble_term_TERM が空になっている問題 [#D1746]

    mintty で _ble_term_TERM が空になっている。何故か。unknown が設定されるので
    はないか。ちゃんと DA2R は受信できている。そして passthrough seq がちゃんと
    動いていない in screen. これは修正する必要がある→確認したら物凄く単純なミ
    スをしていた。これは恐らく置換か何かをした時の残りであろう。

  * 折返しがある時に実際に端末に改行が挿入される (reported by banoris) [#D1745]
    https://github.com/akinomyoga/ble.sh/issues/170

    これは元々は途中の列で折り返しをする為 (例えば prompt_rps1 の為) に導入した
    振る舞いだが、確かに報告にある様にコピー・ペーストしたいという場合もある。
    端末の全幅を使っている時には折返しの改行は明示的に挿入しない様にするべきな
    のではないか。

    全角文字が収まり切らない時に端末がどの様に振る舞うかについても何か仮定を置
    かなければならない。折返しの位置で改行は挿入しない。

    * うーん。全角文字が入り切らない時に挿入する空白は其処に元々存在した文字を
      消去して空白で上書きするという意味合いもあった。という事を考えると、実は
      ECH で代替できるのではないか。実は ECH を実行したとしても空白になってしま
      う端末も存在するだろうし、末尾の空白は空白とみなさない端末もあるだろうし
      実装は色々だろう。

    * 改行が挿入されるのが駄目という事であれば一旦 CR で先頭に移動してから LF
      を実行すれば良いのではないか? と考えたが多分そういうことじゃない。状況は
      逆で、既定では別の独立した行になっていて、然し折返しがあった時に限り２つ
      の行を接続するという振る舞いになっているのだと思われる。

      という事を考えるとやはり末尾で折返しを発生させる必要があるのである。

    ? rps が存在する時は relative になっているだろうか。うーん。xenl のない端末
      では改行を挿入していないという事を見ると、改行は挿入しなくてもちゃんとそ
      の場で折返しが発生するという事は想定している。

      →確認したら実際に rps1 が存在している時には relative になっていた。

      [[ $rps1_enabled ]] && render_opts=relative

      という事は relative でなければ常に全幅になっているという事を想定して良い
      様に思われる。

    ? slice してから出力した後のカーソル位置が予測不可能になるのではないか。全
      体を一気に出力する場合には次に文字があるかどうかで自動折返しが発生するか
      どうか分かる。自動折返しが発生しない時に限り改行を挿入すれば良い。然し部
      分更新をしている時には自動折返しが発生しない可能性が常に存在する。その時
      に座標が不定になってしまう。直後に行う操作 (CUU) 等によって端末に依って異
      なる結果になってしまう。うーん。

      というか此処まで来ると bash だってちゃんと動作しているかどうか怪しい物で
      ある。然し、readline の場合には基本的に着色はないので、文字の内容は変わら
      ないのに色だけ部分的に更新するという事もないのだろうと予想する。なので問
      題が発生するケースは存在しない。

    ? うーん。何と説明するか。全角折返しの空白や改行の挿入は端末の違いを吸収す
      る為に必要だという事を説明する? でも既存の readline は問題を起こしていな
      い。しかしそれは着色をしていないので部分更新でも必ず折り返しは発生するか
      ら。

      うーん。折返しを起こしてかつ後続の文字に干渉しない様な方法というのは存在
      するのだろうか。。うーん。存在しない気がする。だとすると、新しく slice 終
      端禁止点の様な物を導入して slice をする時には範囲を拡張するという具合にす
      る必要がある気がする。うーん。そういう方法しか存在しないだろうか。。。

    a 後続の文字によって自動折返しが期待できる時には改行は挿入しない。

      slice 禁止点の情報を記録する (実は既に grapheme cluster によって類似の仕
      組みが備わっていないのか)。

      xenl の端末とそうでない端末でちょうど行末に改行があった場合の振る舞いが変
      化するのではないか。それは大丈夫なのだろうか。或いは丁度行末にいる時に改
      行を実行する時には二重改行を挿入する? うーん。

      →色々考えたが b の方針に比べると考えなければならない事が多すぎる。これは
      やはり棄却する。

    b 一括出力時に自動折返しの改行文字は削除する。その為には自動折返しの改行文
      字として特別な文字を使う。例えば \r は ^M と encode されるので本来は
      textmap の中に含まれる事はないと思って良い。

      slice する際にまた \r を元に戻す処理をするのが良い気がする。うーん。この
      方針で行くのが一番安心の気がする。

      ? 丁度行末で改行がある場合の動作?

        この方針の際に丁度行末に改行がある場合はちゃんと動作するのだろうか。つ
        まり一番最後の文字の末尾に \r があって、それから次の文字の改行が \n と
        して来る。この時に slice 後の置換によって内部の \r は削除されてしまうの
        で単一の \n になってしまう。うーん。これは駄目だ。一方で \n\n にしたら
        良いのかと聞かれるとそれも何だか違う気がする。つまり改行が二重に複製さ
        れてしまう。うーん。然し、これは表示される時の表示と実際の内容のずれと
        して仕方がないのではないかという気がする。\n\n にするしかない。

        一応自動折返し位置に改行がある時に readline がどう表示するのかについて
        は確認する事にする。内容は一個の改行だけれども、コピーすると二個の改行
        に増えている。やはりこれは仕方がないのだという気がする。

      後は _ble_textmap_glyph を触っている所を全て確認すれば良い。うーん。この
      配列自体は ble/textarea#update-text-buffer からしか参照されていない様に見
      える。うーん。然しそれは変だ。と思ったが、やはりそれで良いのだ。というの
      も、通常の文字の端末上の表示は常に同じだからわざわざ textmap を参照する必
      要もないのである。最終的に "変更文字" である物だけ置き換えれば良いのであ
      る。そして実際自動折返しが発生している物については changed がマークされて
      いる。よってこの時点で _ble_textarea_buffer に反映されるのである。

      _ble_textarea_buffer を参照している箇所は以下しかない。

      ./src/edit.sh:2559:    IFS= builtin eval "ret=\"\$ret\${$_ble_textarea_bufferName[*]:i1:i2-i1}\""

    → b の方針で実装した。動いている気がする。

    x 2022-01-23 動いていると思ったら勘違いだった。丁度行末に改行がある時に座標
      がずれてしまう。何かと思ったら \r\n を \n\n に置換しようという所で、間に
      SGR がある為に置換しきれていないのが原因の様である。

      うーん。これはどうしたら良いのか。単純な置換だと無理の気がする。或いは間
      に来る SGR が既知であれば固定文字列として置換する事もできる。。と思ったが、
      そもそも不特定の \r\n の組を対象にして一括置換しようとしているのだから、
      固定文字列になっている筈がない。うーん。間に入るのは単一 SGR なのだろうか
      →実装を確認した所 sgr 決め打ちである。という事であれば extglob さえ使え
      ば置換はできる…と思ったが置換後が固定文字列になってしまうので駄目である。

      うーん。という事を考えるとやはり正規表現で \r を一つずつ一致させて処理す
      るしか無いのだろうか→うーん。その様にして実装した。CSI seq, ESC seq, 及
      び SI SO を跨いで改行を検出する様にした。

2022-01-21

  * bash-preexec に本格的に介入する事を考える事にする (motivated by SuperSandro2000) [#D1744]
    https://github.com/akinomyoga/ble.sh/issues/96#issuecomment-1016401487

    1. bash-preexec の機能を on/off する方法を探す。
      特に off にしている時には DEBUG trap は削除する様になっていて欲しい。

      そもそも __bp_install で一体何をしているのか等についてもちゃんと確認する
      必要がある。以前調べた感じだと PROMPT_COMMAND が他の枠組みに上書きされて
      も大丈夫な様に DEBUG を使って実際の登録を行う仕組みになっていた筈である。

    2. bash-preexec の機能を PRECMD / PREEXEC で再現できる様にする。

      PIPESTATUS を保存する → BLE_PIPESTATUS に記録する事にした。各 hook の中
      からはこれを参照すれば最後のコマンドの PIPESTATUS を取得できるという事を
      wiki にも書く。該当する hook は PRECMD, PREEXEC, POSTEXEC, ERR である。何
      故か CHPWD は該当しない。

    * そもそも現状の ble.sh に於いて、最初に bash-preexec をロードして置いて、
      後から source ble.sh を実行すると preexec 用の DEBUG trap が削除されてし
      まっている。

      この振る舞いについてちゃんと調べて解決する必要があるのではないだろうか。

    * done: 取り敢えず ble.sh の側で対策を実装する事にする。もし bash-preexec
      に適切な API があったとしてもなかったとしてもちゃんと動く様にする。

      ble.sh の側で実装するとなると何処かのタイミングで bash-preexec を検出しな
      ければならない。元から bash-preexec が存在している場合にはそのまま検出で
      きる。後から bash-preexec が読み込まれた時にどの様に対処したら良いのかは
      非自明である。

      a 一つの方法は precmd_functions 辺りに何か仕掛けておくという事。然し、
        bash-preexec が実際に読み込まれるかどうかも分からないのに汚染はしたくな
        い気がする。

      b だとすると POSTEXEC 辺りで bash-preexec 特有の関数が定義されていないか
        どうかチェックするという事になる気がする。これは overhead であるが、ま
        あ特に重い処理でもない気がするので気にしなくて良い。

      どの様に実装するのかというのも気になる。外部プラグインとして実装するのか
      ble.sh 本体に埋め込んでしまうのか。取り敢えず外部プラグインとして実装して
      置いて、後で本体に組み込むかどうか決定するのが良い気がする。

      →contrib/bash-preexec に実装した。更に読み込み用のコードを ble.sh に埋め
      込む事にした。

    [テスト]

    * テストの方法

      ロードの順序や attach の方法など色々考えられる。それらについて全部動作確
      認するべきの気がする。以下の場合を確かめる。

      % - bash-preexec  bashrc / interactive
      % - ble.sh        (bashrc / interactive) x (prompt / attach)
      % - どちらを先に source するか。
      % - 両方 interactive の時には同じコマンドの中で source するかどうか。
      % - bash-it       bashrc / interactive

      まとめると以下のロードの組み合わせが存在する。

      - done: bp blesh.prompt $
      - done: bp blesh.attach $
      - done: bp $ blesh.prompt
      - done: bp $ blesh.attach
      - done: $ bp $ blesh.prompt
      - done: $ bp $ blesh.attach
      - done: $ bp blesh.prompt
      - done: $ bp blesh.attach
      - done: blesh.prompt bp $
      - done: blesh.attach bp $
      - done: blesh.prompt $ bp
      - done: blesh.attach $ bp
      - done: $ blesh.prompt $ bp
      - done: $ blesh.attach $ bp
      - done: $ blesh.prompt bp
      - done: $ blesh.attach bp
      - done: bash-it $
      - done: $ bash-it
      - done: 更に detach した後もちゃんと動くかも確認する

    x done: 初回の実行時に trap DEBUG が残っている場合が存在する。特に bp が後
      にロードされた時にこれが起こる。後に bp がロードされた時には POSTEXEC で
      処理をしているのだから仕方がない。それよりも前の時点で検出する方法はない
      のだろうか→というか全パターンで trap DEBUG が初回実行で残ってしまってい
      る。これは何が悪いのだろうか。恐らく最初の PROMPT_COMMAND でから install
      string を削除できていない。

      と、ここで理由が分かった。そもそも contrib/bash-preexec が POSTEXEC から
      しか自動ロードされていない。ATTACH 及び ble.sh ソース時にもチェックするべ
      きである。

    x ok: "bp blesh.attach" 及び "$ bp blesh.attach" に於いて初回のコマンド実行
      では未だ contrib/bash-preexec による調整が有効になっていない。但し、動作
      に関しては問題ない。これはまあ仕方がないのだろうという気がする。

    DEBUG 周りを色々と修正し直す事にした。幾らか弄ったら色々動かなくなった。

    x resolved: C-c した時に変なエラーメッセージ (return に空の引数が渡されて
      いる) が発生している。これは一体何だろうか。うーん。bash --norc, source
      out/ble.sh --norc でも発生する。一旦発生するとその後もずっとコマンドを
      実行する度に発生している気がする。

    x resolved: C-c で実行をキャンセルできていない→これは正規表現の編集をミ
      スして正規表現が不正になっていた。修正した。直った。

    * done: ble/builtin/trap/invoke と ble/builtin/trap/invoke+ を統合する。
      ble/builtin/trap/invoke+ はもっと単純な戻り値に外で実行するべきコマンド
      を出力する。

    x resolved: detach した後に TRAPDEBUG が設定されていない。うーん。trap -
      DEBUG を実行した時点で builtin trap DEBUG が設定されるべきなのにされない
      という問題である。

      これは実際に builtin trap DEBUG がされていないのか、或いは実際している
      けれどもそれが関数呼び出しの為に途中で消えてしまっているのかどちらなの
      だろうか。動作を確認する事にする。

      →どうやら _ble_edit_exec_TRAPDEBUG_enabled によって明示的に無効化され
      ている様に見える。これは元々何の為の判定だろうか。gexec の中か外かで振
      る舞いを変えている様子である→分かった。ble.sh の内部にいる時に即座に
      DEBUG trap を有効にすると ble.sh の中で DEBUG が大量に走って不都合とい
      う事。

      % そういう事であれば _ble_edit_exec_TRAPDEBUG_enabled=1 にする瞬間に
      % trapdebug を実行するのが妥当なのではないだろうか。。→と思ったら既に
      % ble-edit/exec:gexec/.TRAPDEBUG/enter に於いて TRAPDEBUG をちゃんと実
      % 行していた。

      そもそも ble-detach した時に _ble_edit_exec_TRAPDEBUG_enabled=1 に最終
      的になるのかもよく分からない → 調べてみると空のままの気がする。detach
      の際に直接 trapdebug を設定すれば良いのではないだろうか。。と思ったがそ
      ういう訳でも無い様な。

      % →これは単なる変数名の変更漏れだった。修正した。

      うーん。detach の際に ble-edit/exec:gexec/.TRAPDEBUG/enter を実行すれば良
      い気がする。

      →これはちゃんと動く様になった。また detach した後でも INT が残っていて悪
      さをする問題に関しては、TRAPINT で return || break を実行して抜けられる様
      にする事にする。

    * [保留] "for ((i=0;i<10;i++)); do sleep 1; done" で C-c すると変な事になる。
      これは元から動いていなかった物なので今新しく動かなくなったという訳ではな
      い。

      →うーん。どうもこれは sleep が sigint で終了した時には、bash は trap
      handler は起動せずに完全に実行全体を終了してしまうみたいである。

        $ trap 'echo TRAPINT' INT
        $ for ((i=0;i<10;i++)); do sleep 1; done
        ^C
        $

      この様に trap が発動する事無く即座に終了してしまう。特に ble.sh の中から
      実行する際には実行が完全に終了した後も端末ハンドラーの設定がそのままになっ
      ているので、新しいユーザーの入力も RET が来るまでは受け取れないという状態
      になってしまっている。これは仕方がない。

    * done: wiki trap debug 更新

    * done: SIGINT message をもっと見やすく。これはこんな物だろう。

    * done: wiki に BLE_PIPESTATUS を記述する。

    取り敢えずコミットを作ってしまって良い気がする。

    * done: 後は contrib を修正する。

    * done: PRECMD は PROMPT_COMMAND よりも前に実行するべき。元々どちらでも良かっ
      たが、bash-preexec が最初に実行する様になっているのでそれに倣う。

  * global: protect overridden builtins against "set -eu" (reported by SuperSandro2000) [#D1743]
    https://github.com/akinomyoga/ble.sh/issues/169

    またもや set -uex でロードできなくなっているのでその修正を行う。同時に$- 及
    び $BASHOPTS (bash-4.0 以下では自前で再構築) を持ちて状態保存のコードを単純
    化した。これで以前よりは効率はよくなったのではないかと思う (nocasematch の
    検索は多少時間がかかるかもしれない)。

    次に各 builtin に対して対策コードを導入する事にする。

    - done: trap  (util.sh)
    - done: sleep (util.sh)
    - done: bind  (decode.sh)
    - done: read  (edit.sh)
    - done: exit  (edit.sh)
    - done: history (history.sh)

    そもそも set -eu をありがたがって使っている時点で余り分かっていない人が書い
    ているという気がする。何れにしてもその時点で一般には防御が難しいが、NixOS
    の用意したスクリプトでだけ set -eu を有効にするというのであれば、仕方がない
    のかもしれない。勝手に builtin を上書きしてそれで問題を起こすのは ble.sh が
    悪い。これによって状態保存・復元の overhead が生じるが仕方がない。

  * prompt: C-c で history_share が有効でない (reported by SuperSandro2000) [#D1742]
    https://github.com/akinomyoga/ble.sh/issues/96#issuecomment-1018101640

    うーん。確かにそうだ。確か以前もっと高頻度で更新する事についても考察したが、
    編集中に何か変な事が起こると大変だと思ってそれは棄却したのだった。然し、C-c
    で discard-line する場合には安全に履歴をロードする事ができる。対応する。

2022-01-20

  * prompt: cygwin で root prompt mark が正しく表示されなくなっている [#D1741]

    よく考えたら ${PS1@P} を使う様にしているからではないか。振る舞いを修正して
    いる物が含まれている場合にも ${PS1@P} の仕様は無効化する必要がある。

    つまり、cygwin, msys, etc において PS1 に \$ が含まれていたら駄目。
    これは簡単な修正だった。

  * prompt: bash-it や oh-my-bash で最初のプロンプトの座標計算がずれる [#D1740]

    ble.sh を読み込むと最初のプロンプトの表示がずれてしまう。これは ble.sh をロー
    ドして最初にプロンプトを表示した時には未だ char_width_{mode,version} が解決
    されていないので、既定の設定が使われて座標計算にずれが生じるのが原因である。

    本来は bleopt_char_width_{mode,version} が変化していれば再描画される筈なの
    であるが何故再描画が走らないのだろうか。取り敢えず
    ble/prompt/unit:_ble_prompt_ps1/update の時点で char_width_@ が解説された後
    に呼び出されていない。ble/prompt/unit#update _ble_prompt_ps1 は実行されてい
    る。という事を考えると、の間で更新が棄却されているという事になる。

    ohashref='$_ble_prompt_version::$prompt_ps1,$PWD' である。うーん。本来は
    $_ble_prompt_version と同じ所で char_width_@ も参照するべきの気がする。→結
    局 prompt_hashref_base に '$_ble_prompt_version' だけが入っていた所
    に'$bleopt_char_width_mode,$bleopt_char_width_version' も追加する事で解決し
    た。他にも LC_CTYPE が変わった時にも問題になるのではないか、と思ったが
    LC_CTYPE がコマンド実行以外で勝手に切り替わる事もないと思われるの
    で、_ble_prompt_version でカバーできていると考えるべきである。つまり、
    bleopt_char_width_{mode,version} は非同期で変化する可能性があるのでそれに応
    じて更新する必要があるという事。

    と思ったが、bleopt_char_width_{mode,version} が変化するのは検出できるのだか
    ら、其処で、_ble_prompt_version を更新すれば良いだけなのでは→その様に変更
    する事にした。実は bleopt_char_width_{mode,version} の他にも
    emoji_{opts,version} が存在した。これらも変化があればちゃんとプロンプトを更
    新する必要がある可能性がある。全て対応した。ちゃんと動いている。

  * bash-5.2 shopt patsub_replacement 対策 [#D1739]

    これは #D1738 の一環として発見されたバグであるが bash-0.3 も修正しなければ
    ならないので、独立した項目にする事にする。

    - util (ble/builtin/trap): $Q から $q へ逆方向で変換されていた。
    - util (ble/util/print-global-definitions): ${v//$q//$Q} の様になっていた為
      に置換後に余分な / が混入していた。

  * 2022-01-13 bash-5.2 shopt patsub_replacement 対策 [#D1738]

    % 取り敢えず危なそうな箇所を抽出しておく。うーん。やはり可也面倒である。
    % ble/string#replace 等の関数を作るべきなのかもしれない。
    %
    % $ grc '\$\{[[:alnum:]_]+(\[[^][]*\])?/' --exclude={memo,test,wiki}
    % $ grc '\$\{[[:alnum:]_]+(\[[^][]*\])?//?[^{}]*/[^{}]*[$&]'
    % $ grc '\$\{[[:alnum:]_]+(\[[^][]*\])?//?([^{}]|\{[^{}]*\})+/[^{}]*([$&]|\\)'
    %
    % done: ./keymap/vi.sh:6974:    ins=${ins//[!$'\n']/"$s"} ★
    % done: ./lib/core-syntax.sh:976:      a=${a//@h/$histc1}
    % done: ./lib/core-syntax.sh:977:      a=${a//@q/$histc2}
    % done: ./lib/core-syntax.sh:982:    a=${a//@h/$histc1}
    % done: ./lib/core-syntax.sh:983:    a=${a//@q/$histc2}
    % done: ./lib/core-syntax.sh:2255:    rex_event=${rex_event//@A/$A}
    % done: ./lib/core-syntax.sh:2266:    rex_quicksub=${rex_quicksub//@A/[$histc2]}
    % done: ./lib/core-syntax.sh:2267:    rex_quicksub=${rex_quicksub//@C/$histc2}
    % done: ./lib/core-syntax.sh:4453:    a=\\   ; b="\\$a"; ret="${ret//"$a"/$b}" ★
    % done: ./src/edit.sh:604:    a='\' b='\\' text=${text//"$a"/$b} ★
    % done: ./src/util.sh:118:          ble/array#push specs "${var[@]/%/=$value}" # #D1570 WA checked
    % done: ./src/util.sh:777:    ARR=("${ARR[@]::$2}" "${sARR[@]/#/$4}" "${ARR[@]:$3}")' # WA #D1570 checked
    % done: ./src/util.sh:806:  ret="${ret// /$1}"
    % done: ./src/util.sh:1083:      a=${chars1:i:1} b=\\${chars2:i:1} ret=${ret//"$a"/$b}
    % done: ./src/util.sh:5305:  ble/util/put "${_ble_term_visible_bell_show//'%message%'/$sgr$message}" >&2
    % done: ./src/util.sh:5622:  local ret=${_ble_term_Ss//@1/$state}
    %
    % ????: ./src/util.sh:1379:  builtin eval -- "${_ble_local_script//opts/$1}" # Note: 配列要素に変な文字が入っていると駄目
    % ????: ./src/util.sh:1383:  builtin eval -- "${_ble_local_script//opts/$1}" # Note: 配列要素に変な文字が入っていると駄目
    % ????: ./src/util.sh:1391:  builtin eval -- "${_ble_local_script//opts/$1}" # Note: 配列要素に変な文字が入っていると駄目
    % ????: ./src/util.sh:1399:  builtin eval -- "${_ble_local_script//opts/$1}" # Note: 配列要素に変な文字が入っていると駄目
    %   →うーん。これらについては元々配列要素を想定していない実装になっているのでここで改めて気にするのも変である。
    %   それに配列要素を想定している場合には添字は先に1回だけ評価するべきの気がする。なので、そんなに単純ではない。
    %   これは今回は見送り。
    %
    % ok: ./src/util.sh:1516:    builtin eval -- "${_ble_local_script//NAME/$1}"
    % ok: ./src/util.sh:1899:builtin eval -- "${_ble_util_gdict_declare//NAME/_ble_builtin_trap_n2i}"
    % ok: ./src/util.sh:2515:  builtin eval -- "${_ble_local_script//ARR/$_ble_local_array}"

    外部プロジェクトも気になる。うーん。これは悲惨な結果である。
    bashdb, bash-completion, etc. が大抵影響を受ける様に見える。
    -> bug-report bash/report31/affected.txt に移した。

    bug-bash に再度報告した。結局、当初の提案で実装し直して貰った。

    改めて新しい実装に合わせて ble.sh を調整する事にした。改めて丁寧にチェック
    を行って行ったところ、先の修正で見過ごしていた所も幾らか見つかった。自動検
    出しやすい様にスタイルを統一し、その上で自動検出を記述した。

2022-01-18

  * ble-measure の base がやはりずれる。より良い更新式を取得したい [#D1737]

    うーん。というより此処まで大きくずれるのであれば nest レベル毎に計測を実施
    するべきなのではないか。但し、ble-measure を自信から呼び出して使うと nest
    レベルが1だけずれてしまう。然し、それでも nest レベル毎に計測し直した方が遥
    かに良い値が出ている。

    一応 nest レベルの 1 のずれを補正する事にする。${#FUNCNAME[*]} 1..11 まで計
    測してそれを線形フィットする。

    | gnuplot> plot 'a.txt'
    | gnuplot> f(x) = a * x + b
    | gnuplot> b=4500;a=100
    | gnuplot> fit f(x) 'a.txt' via a,b
    | iter      chisq       delta/lim  lambda   a             b
    |    0 1.5114300000e+05   0.00e+00  3.22e+03    1.000000e+02   4.500000e+03
    |    1 3.2658557879e+04  -3.63e+05  3.22e+02    9.857978e+01   4.410413e+03
    |    2 1.9568027480e+04  -6.69e+04  3.22e+01    8.865848e+01   4.465751e+03
    |    3 1.9468872818e+04  -5.09e+02  3.22e+00    8.771000e+01   4.471467e+03
    |    4 1.9468872727e+04  -4.67e-04  3.22e-01    8.770909e+01   4.471473e+03
    | iter      chisq       delta/lim  lambda   a             b
    |
    | After 4 iterations the fit converged.
    | final sum of squares of residuals : 19468.9
    | rel. change during last iteration : -4.66698e-09
    |
    | degrees of freedom    (FIT_NDF)                        : 9
    | rms of residuals      (FIT_STDFIT) = sqrt(WSSR/ndf)    : 46.5103
    | variance of residuals (reduced chisquare) = WSSR/ndf   : 2163.21
    |
    | Final set of parameters            Asymptotic Standard Error
    | =======================            ==========================
    | a               = 87.7091          +/- 4.435        (5.056%)
    | b               = 4471.47          +/- 30.08        (0.6726%)
    |
    | correlation matrix of the fit parameters:
    |                 a      b
    | a               1.000
    | b              -0.885  1.000

    4471.47 + 87.71 * ${FUNCNAME[*]}

    現在のレベルが x の時、x+1 の計測結果は b+a(x+1) になっていると考えられるので、
    [b+ax]/[b+a(x+1)] 倍すれば補正できる。

    * うーん。最小時間を記録したらそれで更新する様にしたい。

      線形フィットを実測値から実施する。然しそうしたとしてどのタイミングでその
      値を使用するのだろうか? もし未知の場合には必ずその場で試行するのだとした
      ら線形フィットを用意しておく意味はあるのだろうか。

    * うーん。a=0 自体にも本来は実行コストが存在する筈である。それを計る事はで
      きないのか。例えば a=0;a=0 とやると 670ns ぐらいはかかる。という事は、
      600ns ぐらいは a=0 で消費している事になるが、一方でこれをどうやって自動的
      に補正するかが問題になる。関数を空にする事ができないのが問題である。

      計測する関数定義に return 0 を追加する事にした。これによって実際に計測時
      間が 1us 程度増加してしまう様だが仕方がない。3nest 分の遅延と同じなので余
      り気にしない事にする。→これで測ってみた所、a=0 の実行時間は最短で 666ns
      になった。事前の見積もりと一貫した結果である。

2022-01-11

  * def.sh にある設定更新メッセージが make install で削除されるのでは? [#D1736]

    # で始まる行は全て一律に削除している。

    色々考えたが init-msys2 にある様な変な回避方法はやはり不自然なのでやめたい。
    インストールスクリプトでコメント・空白行を削除している箇所を確認した所、意
    外と簡単に heredocument だけ出力する様にできそうなので、その様に修正した。
    それに伴って init-msys2 にある回避も削除した。ちゃんと正しくインストールさ
    れている。

2022-01-09

  * test: テストログをファイルに出力する [#D1735]

    osh で動くか見る上で出力の形式などが気になったので。

    * done: test-decode のテスト項目数がずれているのを直す。
    * done: ログをファイルに出力する機能もほしい。
    * done: テストの成功率を表示したい。

  * global: 算術式 10# が bash-5.1 以降エラーになる [#D1734]

    一度対策として書き換えを行ったが不十分だった。全ての箇所を個別にチェックす
    るのは大変だし、今後算術式を書く時にまた問題になっても困るので全て
    10#0$... と記述する事にした。この様にしておけば正規表現で 10#$ を検出して書
    き換える様に促す事ができる。

  * mandb: rsync の抽出 正しく抽出できていない [#D1733]

    % と思ったが今試したらちゃんと動いている?
    % →と思ったらやっぱり動いていない。

    ? うーん。gawk regex #D1729 の問題によって失敗していたというだけの事なのか
      もしれない。と思って今 gawk で試してみたら問題が再現した。うーん。gawk と
      nawk の振る舞いの違いという事か。と思って色々試したが nawk や mawk でも結
      局再現した。結局の所 gawk は多分関係ない。

    * done: " or " によるオプションの行内列挙
    * done: rsync の man の形式の解析 (.IP "--OPTION" \n desc .IP etc)
    * done: "--no-OPTION" の説明の自動生成 (for progcomp)
    * done: _parse_help における解析

  * prompt-git: source .bashrc で reload すると git-prompt のチェックが起動しなくなる [#D1732]

    何故だろうか。

    ble/contrib/prompt-defer/submit は実行しているが、
    ble/contrib/prompt-defer:_ble_contrib_prompt_git_dirty/worker が呼び出され
    ていない様だ。うーん。分かった。行番号や時計がクリアされてしまう為に、情報
    再取得の条件が満たされなくなってしまっている。

    また、ディレクトリのチェック自体は git にいる時にしか実行されないので、単に
    他のディレクトリに行くだけでは駄目で別の git repository に入ってから戻って
    こないと再計算が発生しない。

  * syntax: bash-3.2 で syntax-highlighting の初期化が起こらない [#D1731]

    [初期化されない問題]

    bash-3.2 で syntax-highlighting のロードが起こらなくなっている。元々どの様
    にロードしていたのだったか。ble-0.3 で確認するのが良い。

    ble-0.3 では core-syntax-def.sh に以下の様に記述されている。

    ble/function#try ble/util/idle.push ble/syntax/import ||
      ble/syntax/import

    それが現在は以下の様になってしまっている。

      ble/is-function ble/util/idle.push &&
        ble-import -d "$_ble_base/lib/core-syntax.sh"

    問題の変更は 321371fa #D1593 で行われている。その時の議論を再確認したが特に
    bash-3.2 について意識はしていない様に見える。というかこのコミットの変更は以
    下の様な物になっている。ble-import -d は idle.push が存在しなければその場で
    読み込む。恐らく余り意識せずに書き換えてしまったという事の気がする。

    -ble-import -d lib/core-syntax
    +ble/is-function ble/util/idle.push && ble-import -d "$_ble_base/lib/core-syntax.sh"

    →これは前の様に直すべき様に思われる。

    [初期化順序の問題]

    或いは bash-3.2 ではその場で ble-import lib/core-syntax を実行してしまうと
    問題が生じるのだろうか? 分からないので取り敢えずその場で import するとどう
    なるか確認する。うーん。bash-5.1 では特に問題は生じていないみたいだ。然し
    bash-3.2 で実行してみると着色が全くされなくなってしまった。後で ble-import
    を実行しても解決しない。文法エラーの着色は有効である。syntax_debug を入れて
    みると属性に依る着色が全くされていない様である。

    →これは独立した問題であるという事が判明した。

    ? ble/syntax/attr2iface/color_defface.onload が実行されていないという事なの
      だろうか → うーん。これを実行したらちゃんと動く様になった。

      つまり color_defface_load が発火されていないか、或いは eval-after-load の
      バグだろうか。うーん。実は上記の core-syntax.sh のードは関係なくて、単に
      eval-after-load の問題の気もしてきた。うーん。eval-after-load を見るとちゃ
      んと登録はされている。然し一方で発火されていない状態の様である。然し、
      blehook を改めて確認すると登録した hook は消去されている。何故?

      hook の呼び出し元で確認した所ちゃんと登録されている。どうも確認してみたら
      ble/syntax/attr2iface/color_defface.onload はちゃんと呼び出されている様だ。

      % 一方で ble/color/defface.onload が二回呼び出されている。特に
      % color_defface.onload の後に呼び出されている。もしかしてこれによって設定
      % がクリアされてしまっている可能性?
      %
      % と思ったら違った。 ble/{color,syntax}/defface.onload で二種類あるのだった。

    * 何れにしても初期化の順序による問題の様である。

      % と思って ble/syntax/attr2iface/color_defface.onload の実装を見ていて気づ
      % いたが、どうやらその瞬間の face の値を読み取っている? これだと駄目の筈。
      % 起動した後に着色を変えられない事になる。
      %
      % コマンド名はちゃんと変更される。然しこれはよく考えたら後付で取得している
      % から? 然し、それも変だ。結局属性から face に変換している筈 → よく考えた
      % らこれは iface に対する初期化なのだから、その場で整数値に解決してしまう事
      % 自体に問題はない。

      何れにしても問題は attr2iface/color_defface.onload は attr -> iface の対
      応付を記録しているが、iface が未だ初期化されていない為に全て iface=0 になっ
      てしまっているという事の様に思われる。

      結局 ble/syntax/defface.onload よりも後に attr2iface/color_defface.onload
      を実行しなければならないのにそれが逆転してしまっているのが原因だった。
      syntax-color-def.sh において ble/syntax/defface.onload の登録よりも後に
      ble-import -d lib/core-syntax を呼び出すべきだったのである。

  * util: bash-3.2 で alias 云々のエラーメッセージが出る様になっている [#D1730]
    これは単純に alias チェックの際に 2>/dev/null を忘れているのが原因。

  * complete: gawk regex warning (reported by telometto) [#D1729]
    https://github.com/akinomyoga/ble.sh/issues/167

    これは最近追加した ble/complete/action/quote-insert.batch/awk から出ていた。
    awk の bracket expression の中のエスケープシーケンスは解釈されるのだった。
    なので孤立した \ から警告が発生していた。普段 nawk を使っていたので気づかな
    かった。取り敢えず修正した。

    ? 他にも類似の問題が別の箇所にあったりはしないだろうか。念の為、全ての
      ble/bin/awk のスクリプトを gawk に食わせて見た方が良いのかもしれない。然
      しチェックするとしてもどうやってチェックするのか。個別にスクリプトを実行
      するのは面倒だし、スクリプトを実行する事によってファイルが作られたりして
      しまうかもしれない。また関連する変数などをちゃんと初期化しなければスクリ
      プトを正しく再現できないかもしれないし、実行時に正規表現が構築されている
      場合にも影響を与える (実行時に正規表現が構築される事はなかった様な気もす
      るが)。

      一応 bracket expression を含む正規表現を他から取得している箇所だけは再確
      認する。特に parse_help の辺り。

      * _ble_complete_option_chars は既にちゃんと対策されていて注記まであった。
      * 他にもう一箇所 [] の中に \ がある物があったが其処もちゃんと \\ になって
        いた。

      \ を全体に渡って検索してみたが core-complete の中には他には怪しい物はなかっ
      た。

      * benchmark.sh にはない。
      * history.sh にも沢山 [\\] や [^...\\] があったが、これらもちゃんとエスケー
        プされている。
      * decode.sh にも幾らかあった。綺麗に awk の中と外でちゃんと \\ と \ が使
        い分けられている。
      * util.sh もちゃんと使い分けられている。
      * edit.sh にはない。ble.pp もない。contrib/prompt-git.bash も大丈夫。

2022-01-08

  * complete: WA terminal glitch on xenl (reported by telometto) [#D1728]
    https://github.com/akinomyoga/ble.sh/issues/166

    再現できた。desc が一列表示でかつ一番最後の項目が丁度ぎりぎり収まるか、或い
    はおさまり切らない時に問題が生じるということの様だ。また、一列表示の時に
    ellipsis の位置がおかしい問題も見られる。これらは実の所同根ではないかと思わ
    れる。

    うーん。一つバグは見つけた。しかしこれは関係ない → #D1727

    ellipsis の位置と行の終端位置が一致していないが、調べてみると wcolumn は実
    際の端末の幅と同じにして trace が呼び出されている。結果を見ると、行の終端位
    置が誤っているのではなくて ellipsis を出力する位置が誤っているという事に見
    える。

    ble/util/c2w 8230; echo $ret としても実際に表示している通りの 1 になっている。

    →うーん。これは分かった。これは端末による振る舞いの違いだ。xenl 状態にある
    時に CUB をした時に、一番最後の列に移動するか或いは一番最後から二番目の列に
    移動するかである。vte は 2 番目になる。screen と contra は一番最後の列にな
    る。

    * これは一度まとめた事が contra にある筈。と思ったがこれは ech などの振る舞
      いについてだった。contra のモードに xenl_ech が存在する。

      # 行末にカーソルがある時に ECH, ICH, DCH は行の最後の文字に作用します。
      f---  mode_xenl_ech                 private     true

      CUB CUF についても調べた事がある筈だが、それは contra にはまとめられてい
      ない。

      $ printf '%*s\e[10DX\n' $COLUMNS 0123456789

      * CUD 前に最後の列に移動する
        - xterm, terminology, urxvt, alacritty
        - vte (GNOME, xfce4, terminator, lxterminal)
        - mlterm, RLogin

      * xenl の時は右端の境界にいるかの様に動作する
        - kitty, screen, tmux, termit, konsole
        - contra, Poderosa

    この振る舞いを吸収する様にシーケンスを構築する事はできるだろうか?

    % * この振る舞いの対処を過去にした事はあるだろうか。eol mark の場合には直後に
    %   \r をしているので関係ない。
    %
    % a CUU CUD などを使って強制的に一番最後の列に移動してから移動を開始する? 然
    %   し、高さが一行しか無い場合には信用できない。本当に端末の高さが一行しか無
    %   い場合には使えるが、実際にはどちらか一方にだけ移動できる様な状態になって
    %   いたとすると元の位置に戻ってくる事ができない。
    %
    % b BS を使ったら元の位置に戻る事ができるだろうか。試して見た所 screen は BS
    %   を使うと一番最後から 1 番目のセルに移動する。contra や vte は2番目のセル
    %   に移動する。うーん。なので BS を使った場合端末によって位置が異なるという
    %   事。一応この振る舞いは vttest にあるので、screen 等の一部の例外を除いて動
    %   くべきという事にしてしまっても良いのかもしれない。と思ったが tmux も
    %   screen の仲間だ。うーん。やはりこれは端末によって振る舞いが異なる。
    %
    % c 本来、本当の COLUMNS と現在の cols を区別するべきなのではないかという気が
    %   する。本当の COLUMNS と一致している時に限り特別な動作を行う。と思ったが、
    %   そうしたとしても現在の端末がどちらの振る舞いをするのか分からなければ、結
    %   局どちらの端末でも動く様に書かなければならない。或いは端末の振る舞いを事
    %   前にテストしておく必要がある。
    %
    % d 或いは CUB CUF を一回実行したら意外とどの端末でも同じになるのかもしれない。
    %   試してみる事にする。
    %
    %   - ok: wt, vscode (xterm.js), tmux, screen, xterm
    %
    %   と思ったが、これは本当に端末の一番右端にいる時には使えるけれども、それ以
    %   外の時には異なる結果になるから使えない。CUF CUB CUB CUF をするとどうなる?
    %   Class A -> 0 (-2), Class B -> 0 (-1). これだと全然駄目である。
    %
    % やはり以前も同じ考察をして無理と判断した様な気もする。しかしそれは canvas
    % の bottom dock の話だった様な気がしないでもない。

    うーん。そもそもそういう理由があるからこそ相対移動は右端に接しない様に設計
    していたという事の様な気もする。menu-style:desc も右端に接しない様に修正す
    る事にする。

  * complete (menu-style:desc): fix not working "bleopt menu_desc_multicolumn_width=" [#D1727]

    menu_desc_multicolumn_width= として multicolumn を無効化しようとするとゼロ
    除算のエラーになる。定義していない変数を誤って参照して ncolumn=0 になってい
    た。修正した。

  * decode: bind の古い形式が使えなくなっている (reported by returntrip) [#D1726]
    https://github.com/akinomyoga/ble.sh/issues/165

    これは #D1698 (b6fc4f0) の regression だろう。確認した。確かにこの時点で導
    入したバグである。テストもちゃんと追加する事にする。以前実験したケースも全
    てテストに追加する事にする。

    % どうも \C も解釈しなければならない様だ。と思ったが C で終わっていればどう
    % でも良いらしい。これは control で終わっていても良い。

    修正した。テストを追加した。テストも通っている。

    うーん。テストを作って安心したらまた regression 通常の大文字も全て小文字に
    して解釈されてしまう。追加修正する。

2022-01-01

  * util (ble/function): work around "shopt -u extglob" [#D1725]

    #D1723 で extglob が解除された状態で extglob を使って定義された関数を
    ble/function#advice した時に失敗するという問題が発生した。そもそも extglob
    が解除されてしまっている状態も問題だが、それとは別に extglob を使った関数も
    安全に待避して置き換える事ができなければならない。

    なので、更に advice 等で関数を再定義する時には extglob を一時的に有効化する
    べき → その様に修正した。

2021-12-30

  * 2021-12-20 README: oh-my-bash は流石に削除するべきだろう [#D1724]

    → oh-my-bash を引き継いだので流石にこれ以上は問題は起こらせない。追々実装
    もちゃんとした物に差し替えていく事にする。なので現状では変更しなくても良い
    という気がする。と、思ったがたかが 100 commits 程度しかない oh-my-bash を本
    当に推して良いのかというのも謎である。

    取り敢えずリンクは貼る事にした。

  * util (vbell): 外部コマンドを実行する前に vbell 消去はキャンセルするべきでは [#D1723]

    ble/term/visible-bell/.erase-previous-visible-bell で set -f が設定されてい
    る時にはどうするのか。うーん。ble/util/eval-pathname-expansion を拡張する事
    にする。canonical という opts を追加する事にした。

    キャンセルするというよりもその場で消去するというので良い気がする。単に
    ble/term/visible-bell/.erase-previous-visible-bell さえ呼び出して置けば良い
    様に思われる。ble/term/visible-bell/erase という関数を用意した。

    後は、これを何処で呼び出すのかという事。ble/term/leave の辺りで呼び出せば良
    いのではないかという気がする。

    実際に ble/term/leave の呼び出し元を見たが他に適切そうな介入点もない。また、
    ble/term/leave で erase するとしたら util.sh の中で閉じていて都合が良い。
    ble/term/leave の中で呼び出している個々の設定はどうだろうか。中を見ると
    stty, rl-convert-meta を呼び出している。更に leave-for-widget 経由で
    bracketed paste, modifyOtherKeys, cursor shape 等の端末の設定を復元している。
    うーん。leave-for-widget は fzf の呼び出しの時に使っている。うーん bind -x
    経由で何かプログラムを起動する事もあるだろうから、leave-for-widget の中で設
    定はするべき気がする →その様にしたら良い感じになった。

    ? 所で leave-for-widget,enter-for-widget を呼び出しているのが fzf だけなの
      は良いのだろうか。他の人が fzf 的な設定を用意した時に問題になるのではない
      か。bind -x の前後で毎回 leave/enter するべきだろうか?

      o 処理としては単にシーケンスを投げるだけなのでそんなに重くはないが、

      x bind -x した widget を呼び出す度に visible-bell の erase も含めて設定を
        変更するのもやりすぎな気がする。

      x それに同じ事が標準の ble/widget/* でも言える。ble/widget/* で毎回それを
        実行する訳には行かないので、結局は widget を書く人に注意点として提示す
        る必要があるのである。という事を考えれば bind -x の時にだけ注意しなくて
        良いという具合にわざわざする必要もない気がする。

      x もしこれが既存の bash 設定で頻繁に起こる問題であれば、何も考えずに移行
        できる様にするべきだったかもしれないが、実際の所余り問題も起こっていな
        い様なので現段階では少なくとも様子見というのが正しい気がする。

      →現時点では必要がある時にユーザーの側で正しく leave/widget を呼び出して
      貰う様にする。もし問題が発生するようであれば bind -x の時にだけは
      leave/enter を勝手に呼び出す事にする。

    x 2022-01-01 util (eval-pathname-expansion): extglob が勝手に解除される問題

      補完しようとした時に構文エラーが表示される問題。bash-completion をロードし
      なければ問題は発生しない。エラーが表示された後に ble/funtction#advice が
      original:_longopt が見つからないというエラーを出力している。
      original:_longopt の定義で失敗しているという事。

      実際に定義している部分で定義に使っている文字列を出力させてみたがちゃんと関
      数定義が抽出できている。とここで extglob が設定されていない事によるエラーで
      はないかと思ったらそうだった。extglob が解除されている。これは直前の変更
      #D1724 で設定を復元するのに失敗しているのが原因だろう。該当部分で shopt を
      出力して見たら空文字列になっている。ちゃんと canon=1 にはなっている。と、
      shopt=$BASH_OPTS ではなくて shopt=$BASHOPTS であるべきだという事に気づいた。
      これは修正する必要がある。

      然し、実はこの問題は未だ push していない commit の問題だったので実はそん
      なに急ぐ事はなかったのだと気づいた。

      (本当は関数のテストに際して shopt の設定が変更されていない事などもチェッ
      クするべきなのだろうという気がする。そしてそのチェックは実は BASHOPTS と
      $- を保存すれば良いだけなので簡単である。)

  * complete: echo $abc 迄入力すると progcomp から complete -p の内容が出力される [#D1722]

    調べると complete -p -- コマンド名 によって補完設定を読み込む時にコマンド名
    が空になっている。comp_words=('$abc') になっている。

    | ? そもそも何故 comp_words=('$abc') によって補完が呼び出されているのだろうか。
    |   コマンド抽出に失敗している気がする。
    |
    |   →これは ble/complete/progcomp/.compline-rewrite-command の問題であって
    |   extract-command の問題ではなかった。なので個別に気にする必要はない。
    |
    | ? 次に '$abc' が何故空の文字列に置き換わってしまうのだろうかという事。
    |
    |   →これは分かった。展開自体は complete -p -- $abc によって行われているが
    |   quote されていない所為で単語無しで設定が読み込まれているという事なのだろ
    |   う。コメントによると呼び出し元によって quote されている筈という事になって
    |   いるが何故 quote されていないのだろうか。
    |
    |   stackdump:
    |     @ /home/murase/.mwg/src/ble.sh/out/lib/core-complete.sh:1 (ble/complete/progcomp/.compgen)
    |     @ /home/murase/.mwg/src/ble.sh/out/lib/core-complete.sh:50 (ble/complete/progcomp/.compgen)
    |     @ /home/murase/.mwg/src/ble.sh/out/lib/core-complete.sh:93 (ble/complete/progcomp)
    |     @ /home/murase/.mwg/src/ble.sh/out/lib/core-complete.sh:55 (ble/complete/source:argument/.generate-user-defined-completion)
    |     @ /home/murase/.mwg/src/ble.sh/out/lib/core-complete.sh:18 (ble/complete/source:argument)
    |     @ /home/murase/.mwg/src/ble.sh/out/lib/core-complete.sh:21 (ble/complete/candidates/generate-with-filter)
    |     @ /home/murase/.mwg/src/ble.sh/out/lib/core-complete.sh:18 (ble/complete/candidates/generate)
    |     @ /home/murase/.mwg/src/ble.sh/out/lib/core-complete.sh:15 (ble/complete/auto-complete/.check-context)
    |     @ /home/murase/.mwg/src/ble.sh/out/lib/core-complete.sh:23 (ble/complete/auto-complete.impl)
    |     @ /home/murase/.mwg/src/ble.sh/out/lib/core-complete.sh:20 (ble/complete/auto-complete.idle)
    |     @ /home/murase/.mwg/src/ble.sh/out/ble.sh:1 (ble/util/idle.do/.call-task)
    |     @ /home/murase/.mwg/src/ble.sh/out/ble.sh:38 (ble/util/idle.do)
    |     @ /home/murase/.mwg/src/ble.sh/out/ble.sh:3 (ble-edit/bind/.tail)
    |     @ /home/murase/.mwg/src/ble.sh/out/ble.sh:22 (ble-decode/EPILOGUE)
    |     @ /home/murase/.mwg/src/ble.sh/out/ble.sh:81 (ble-decode/.hook)
    |
    |   うーん。行番号が全然当てにならない。
    |
    |   どうやら complete -p -D で呼び出されてその後に再実行によって変な状態になっ
    |   ている様だ。comp_words の状態は直前の呼び出しでは以下の様な形になっている。
    |
    |     orig_comp_words=('echo' '$abc') comp_words=('$abc') ucmd='echo' qcmds=('echo')
    |
    |   結局.compgen が参照するのは comp_words だけであるからこの際 ucmd や qcmds
    |   は関係ない。

    [原因]

    うーん。分かった。ble/complete/progcomp に於いて、

    1 最初のコマンド名の単語評価の際に複数単語に展開されたかまたは単語が変化し
      た時に、orig_qcmds にコマンド名の展開結果を再クォートした物を格納する。そ
      れ以外の時には orig_qcmds は空である。

    2 さて、最後に既定の補完 (complete -D) を実行する為に comp_words を書き換え
      る際に orig_qcmds に何か値が設定されていれば、コマンド名が変化していたと
      判定して、.complien-rewrite-command を用いて orig_qcmds を適用する様になっ
      ている。所が、その判定部分を間違えていて orig_qcmds が空の時であっても
      .compline-rewrite-command が呼び出されて、結果としてコマンド名が削除され
      るという状態になっていた。

    判定を修正したら echo $abc に対しては問題は発生しなくなった。

    然し此処で改めて疑問が生まれる。最初の単語の展開結果が空になる時には何が起
    こるのだろうか。例えば "$abc [TAB]" に対して何が起こるのか。orig_qcmds は空
    なので書き換えは起こらない。すると、$abc がそのまま補完対象になるのではある
    まいか。

    x fixed: コマンド名の展開結果が空の時には何が起こるのだろうか → 特に変な事
      は起こらない様子である。

      試してみると一見して問題は起こらない様に見えたが、それは空文字列に対して
      は complete -F _minimal '' という設定が存在している為に、そちらが呼び出さ
      れて complete -D が試行されないからだった。実際に complete -r -- '' をし
      て見たら問題が再現した。

    x fixed: うーん。改めて観察する。complete -D の時以外でも quote されずに
      complete -p に渡ってしまうケースが存在する様な気がする。.compgen は
      is-simple の時には必ず quote されている事を要求する。現在の実装だと
      is-simple であっても eval に失敗する等した時にはコマンド名が quote されず
      に.compgen に渡されてしまう。結果として .compgen 側で展開されて変な事が起
      こる可能性は否定できない (そもそも eval に失敗したりした時点で .compgen
      の中でも同様に失敗する様な気もするが)。

      →is-simple であれば必ず quote は最終的に実行する様に書き換える事にした。
      結果として orig_qcmds は is-simple の時には必ず設定される様になった筈なの
      で、complete -D の .compgen に際しては orig_qcmds が設定されているかどう
      かを確認するだけで良い筈。

  * 2021-12-22 highlight: 0 番目の要素の入っていない配列名の着色 [#D1721]

    直した。複数の属性がある時にどの着色にするのかというのは悩ましい所だが、そ
    れは今迄の実装でも同様であったので今迄の実装を踏襲する。

    ? 着色を合成するという可能性

      x 本当は着色を合成するという手もあるのかもしれないが、合成規則や優先順位
        を考えるのは面倒だし、結局どれかの属性は他の属性に上書きされるので意味
        がない気がする。

      o とは言えど、配列 (既定で太字) に関しては他と組み合わせても問題ない筈で
        ある様にも思う。

      x と思って対応しようとしたがどうも変数の着色は部分的に構文解析レベルで着
        色しているのでその場で生成した描画属性で着色する訳には行かない。

      x 更に太字は他にも x や luc にも付与している。array/dict の区別に色を使っ
        ている。などという事を考えると (太字かどうか) + (色) を使って配列かどう
        かと値の性質の両方を表そうというのは無理がある様に思われる。

  * readlink 対策: NixOS で皆が readlink 周りに修正を入れている [#D1720]
    https://github.com/peterzky/peterzky-overlay/commit/7b98f05e9b8f84f2d43d84db6b2d76c8e93a38df#diff-34e5f3d20be258f6630e6113d3e1409be74cae463b58eb52b5ebe493e9ee2309R20

    今迄は /usr/bin:/bin にある readlink しか信用しない事にしていたが、取り敢え
    ず readlink が存在さえしていれば単一のパスの読み取りには使えると想定する事
    にする。-f が使えるかどうかの判定に /usr/bin/readlink または/bin/readlink
    を使う事にする。

    readlink が存在しない場合にどうするかについて。

    https://qiita.com/ko1nksm/items/873cfb9c6ceb6ef32ec9

    このページを見ると ls -l を用いて link を読み取り、cd -P を用いてパスの解決
    を行っている。うーん。cd -P を実行した時にディレクトリが戻らなくなるのが心
    配だが、まあその様な事は基本的に起こらないと想定して良いだろうか。

    元々の実装では別に途中のディレクトリ名の解決はしなくても良いという態度だっ
    たが使い方によっては問題になるかもしれないと心配になって来たので、やはり cd
    -P を用いて解決する事にした。

    * readlink -f を使わない実装について簡単なテストを書いてみたが取り敢えずは
      動いている様子である。

      というか寧ろ readlink -f を用いて失敗した時にどう振る舞うのかというのが心
      配な気もする。

    x done: 解決対象のファイル名が - で始まる時に変な事が起こるのではないか? →
      これについては修正した。

2021-12-21

  * complete (action:mandb): brace の後は space ではなくて , にするべき [#D1719]

    ブレース展開の中にいるかどうかは simple_ibrace に非自明な物が設定されている
    かどうかで判定できる様に見える。然しこの simple_ibrace は公開されている変数
    ではないし途中で書き換わっているかもしれない。それよりは comps_flags 等に情
    報が反映されていないか確認する必要がある。実装を見ると x を comps_flags に
    追加している様に見えるが、この x はどういう意味だろうか。brace 展開以外の場
    合にも追加される可能性があるのだろうか。

    comps_flags の説明には含まれていない→と思ったらちゃんと含まれていた。

    既存の addtail の実装を見ると brace の中にいるかどうかは comps_flags x で判
    定している。なのでそれをそのまま真似すれば良いだろう。

  * contrib/git: index に全て登録しただけで非 dirty という事になっているがそれは変だ [#D1718]

    ? もっと詳細な情報を取得する為のコマンドは何か。

    ? プロンプトの更新を遅延させる一般の枠組みがあると良い気がする。ble.sh 本体
      がどんどん肥大化するのは良くないのでprompt-defer.bash 的なファイルに新し
      く定義するのが良い。単に現在の git の呼び出しの部分を差し替える事ができる
      様にしたら良い気がする。

      一つのプロンプト要素の中に複数の更新項目が含まれる場合にはどうするのか。
      依存を複数登録するのか、或いは、まとめて更新する事にするのか。

      うーん。現在の待ちはどの様に行われているのか確認する→idle経由で状態を更
      新している。 ble/prompt/unit/add-hash '$_ble_contrib_prompt_git_dirty' を
      通して変更を検出して更新をかけている。

      情報を格納する変数も指定するべきなのだろうという気がする。或いは version
      変数を作ってそれを参照させるか。或いは id か何かを指定させるというのでも
      良い。うーん。何が良いか。

    - より詳細な情報を得る為には git status --porcelain を読み出して使うのが良
      い。然し、それで本当に足りるのかどうかも分からない。実際にどういった情報
      を人々が求めているのかに依存する様な気がする。自分の為という意味であれば、
      取り敢えずは index に変更があるかどうかが分かれば良い。

    遅延に関係するコードを prompt-defer に分離した。意外とすっきりとできた。

    取り敢えずは staged な変更がある場合に色を変えて表示する事にした。実はもっ
    と詳しく表示する事を考えても良いが面倒なのでそのままにする。将来的には
    git-status だとか git-prompt のエミュレーションを作っても良いのではないかと
    いう気がするが、別に自分が使う訳でもないので今は実装しない事にする。

2021-12-19

  * menu (align): bleopt menu_align_{min,max} (motivated by banoris) [#D1717]

    これは別項目で議論する。というか幅に上限を作っても良いのかもしれないとも思
    う。

    - done: complete_menu_align -> menu_align_max : 並べる時の align の max
    - done: menu_align_min : 並べる時の align の min

    - reject: menu_align_item_maxwidth : 項目の幅の最大 → 対応しようかと思った
      が、現在の実装では項目の幅の計算には trace-text を使っていて、この
      trace-text は高速な代わりに truncate 等の機能がない。trace-text に
      truncate を実装するのも trace-text が高速である意義がなくなるし、或いは、
      trace にすると遅くなってしまうし、色々と面倒である。この項目についてはそ
      れ程積極的に実装する意義がある訳でもない気がするので取り敢えずは実装しな
      い事にする。

    * done: wiki
    * done: blerc

2021-12-18

  * complete: コマンド名に一致しない globchar が含まれるとエラーメッセージ [#D1716]

    '*' を含む alias を定義すると failglob のメッセージが編集中に現れる。という
    か、これは alias に関係なく今迄にも発生していた問題だった様だ。これは別項目
    で処理するべき問題の様に思われる。

    | bash-completion が有効になっている時に起きる問題の様である。然し、一方で、
    | ble.sh が有効でない時には特に問題は生じない。という事は bash が
    | bash-completion を呼び出す時にはその問題を自然に回避しているという事だろう
    | か。調べる。
    |
    | ? 何処からエラーが生じているのか?
    |
    |   うーん。そもそも bash-completion が呼び出されているのか怪しい気がしてき
    |   た。__load_completion を調べてみる事にする。
    |
    |   ble/complete/progcomp/.compgen の stderr を潰したら問題が発生しなくなった
    |   ので、bash-completion が悪かった訳ではなかった。
    |
    | ? bash から呼び出された時との違いは何か?

    これは分かった。progcomp/.compgen は最初の単語 (コマンド名) が quote 済みで
    ある事を想定していた。bash-completion などの関数を通して補完が実行される時
    には確かに compline-rewrite-command によって quote された単語に置き換えられ
    ていたが、何も補完設定が見つからなかった時の規定の progcomp/.compgen 呼び出
    しに対しては、qcmds への書き換えが実行されていなかった。その書き換えを実行
    する様に修正した (既定の補完は alias 展開する前の物に対してなので、初回の
    qcmds を別に保存しておく事にした)。

  * complete (source:command): quote していても alias が候補として生成されている [#D1715]
    その為に、menu の中でエラー着色されている。

    うーん。特に自分で alias を生成している訳ではなくて compgen -c -- s 等の時
    点で alias が生成される様だ。一方で、 compgen -c -- "'s'" 等とすると、何も
    生成されなくなってしまうので alias を除外した生成にする事は難しそうである。

    更に compgen -c は expand_aliases が off になっていても alias を列挙する様だ。

    一方で、for 等の keyword はどの様に判定しているのだったか。うーん。
    source:command で filter している様だ。同じ箇所で alias のチェックもする事
    にした。

    x fixed: 実装してみたら全て赤くなっている→ これは今回の編集ではなくて前回
      の commit の時点で既に駄目になっている。#D1714 で修正した。

    x fixed: alias は noquote を付加する必要があるのでは? → 修正した。その他に
      も ! や [[ 等は quote しない様にする必要がある。

    x fixed: alias が *? 等の文字を含んでいる場合コマンド着色でエラーになってし
      まう。修正した。

      と思ったが、考えてみれば、そもそも alias 名に一致している場合には展開を試
      みる前に alias に確定させるべきなのではないか。

  * menu-complete で 30s かかるという話 (2/2) yield quote-insert 高速化の試み [#D1714]
    https://github.com/banoris/dotfiles/issues/11

    #D1710 に於いて、設定を調整すれば以前より大分高速になるようにはしたが、それ
   でも yield の速度が気になる。別項目で yield の高速化ができないか考察する事に
   した。

    * 先ず計測してみる事にする。

      | * quote-insert をコメントアウトすると 0.63s かかっている。quote-insert
      |   があると 2.24s かかっている。うーん。3/4 ぐらいが quote にかかっている
      |   という事。一方で、quote 作業を gawk 等に任せたとして高速化の程度は限
      |   られるし、また、gawk が出力した結果を読み出す為に追加の処理が必要にな
      |   る事に注意する。その様に考えると gawk で quote 処理を実施する事に積極
      |   的な意味は見いだせないかもしれない。
      |
      | * 更に yield 関数の中身まで考えたらより高速化できる可能性もある。→然し
      |   文字数を数えたり等の操作が入っているので solaris などの駄目な awk 実
      |   装で対応するのが難しい様な気がする。更に filter 等、より様々の事を実
      |   装する必要が生じる気がする。
      |
      |   念の為 filter を抜いてみると 2.02s なので、filter のチェックに 0.22s
      |   かかっている。quote-insert にかかっているのが 1.61s だった。残りは
      |   0.4s である。成程、両方ともくっつけたら大分短くできるのではないかとい
      |   う気がする。
      |
      | * というか progcomp ばかり高速化しても仕方がない。全ての yield ループで
      |   共通している項目は高速化できるのではないかという気がする。何れにしても

      yield loop の処理時間の内訳
      ------------ --------------------
      filter       0.22s (fignore, etc)
      quote-insert 1.61s
      残り         0.40s

    * awk で実装してみて速度を比較する。

      % うーん。試しに実装してみて比べるのはありかもしれないという程度。そうだ
      % としても gawk を呼び出すのにかかる時間を計測して、ある程度以上の項目数
      % の時に呼び出す様に変更するのが望ましい。gawk を使ってすら重いという状況
      % については余り考えていない。というかそもそも '' 等で補完を開始しようと
      % する事が間違っている様な気もする。

      done: 先ずは各種の escape を awk で実装する必要がある。

      →最終的に awk で色々 quote-insert する所まで実装できた。然し、awk の内部
      で test -f file 及び test -e file を判定する事ができないので、必要になる
      場合 (progcomp) の場合には予めテストを実行してからそれを awk に渡す事にす
      る。

      外側でファイル判定する必要がない場合には 28ms であり、ファイル判定する必
      要がある場合には 129ms である。更に読み出しの速度も考える必要がある。然し
      そうだとしても速度的には十分速い。将来的には沢山の項目数の場合には awk に
      移行する事について考えて良いのではないかという気がする。

    * 現在の quote-insert の実装も、外側でできるだけ準備をしてから、中では最低
      限の判定だけで行ける様に修正する事ができる筈。

      その様にした方が現在の awk による実装とも近くなり、両者の一貫性を保ちやす
      くなる筈である。

      →実装した。然し大して高速化していない。元々 2260ms 程度だったのが 2090ms
      程度に減少しただけである。つまり bottleneck はやはり其処ではないという事
      だろうか。

      うーん。escape-for-bash-specialchars が遅いという事の気がしてきた。という
      のも ' を入力した状態で補完するだけで 1600ms にまで減少する為。

    * done: refact ble/complete/action/util/ ble/complete/action/? と思ったが色々
      の関数が既にある様だから、取り敢えずは現状を維持する事にする。と思ったが、
      やはり現在の action/inherit-from は action#inherit-from に改名して、代わ
      りに action/util/ を action/ に書き換えた。

    * done: 候補の数で awk を使うか使わないかを切り替える様にしたい

      ファイル数    従来   nawk    mawk    gawk
      100           24ms   10ms    10ms    12ms
      200           43ms   16ms    17ms    19ms
      500          106ms   35ms    39ms    41ms
      1k           212ms   67ms    76ms    78ms
      2k           424ms  128ms   147ms   150ms
      5k          1092ms  319ms   360ms   364ms
      10k         2094ms  626ms   720ms   723ms

      適当に 500 項目以上の時に awk に切り替える事にした。
      但し、cygwin/msys の場合には閾値は 2k にまで引き上げる事にする。

    * 一般の場合に適用しようとすると改行の取り扱いに気をつけなければならない。

      というか progcomp の場合だって \ を使って候補を繋ぐ事ができたという可能性?
      と思ったが試しに compgen -f を実行してみたが、改行が含まれるファイル名を
      そのまま出力してしまっていて、別々のファイル名の時との区別がつかない実装
      になっているので、progcomp に限っては余り気にしなくて良い様に思われる。

      一方で一般の場合には awk が \0 区切りに対応しているかどうかで実装方法が変
      わってくるのではないかという気がする。更に bash の version に依存して効率
      的に読み取る事のできる形式も変わってくるだろう。

      取り敢えずは progcomp の場合だけ意識して実装して、改行に関しては注釈を加
      えるべきだろうと思われる。

      * 改行が含まれている可能性があるかどうかの情報を渡してそれに応じて判定す
        る様に変更した。今、quote-insert.batch は終了ステータス 1 を返した時に
        何もしない事に注意する。

      * 更に quote-insert.batch が使える所ではできるだけ使える様にする→取り敢
        えず沢山の候補が生成されそうな場所は全て yield.batch に切り替える様にし
        た。

    * done: user-input で途中キャンセルできる様にする必要がある。
      →conditional-sync 経由で呼び出す様に変更した。動作確認した。

    * done: xpg4 の sed でちゃんと "\\\\\\\\&" 置換が期待通りに動くかどうか確認
      する必要がある → "\\\\&" としなければならない様だ。その様にした。

    x fixed: コマンド候補が全て赤く着色されている

      → conditional-sync にした時点で駄目になっている様だ。うーん。
      出力結果を確認してみたがファイルは空である。何も出力していない。
      A & で起動したコマンドは、どうも外側でリダイレクトした fd から読み出せていない様だ。
      A の内部でリダイレクトする様に変更したら動く様になった。

    2021-12-22 追加修正。"continue 0" という文が混入していた。

  * ble/string#escape-for-bash-specialchars で HT を SP HT に置換しているのは何故? [#D1713]
    manu-complete 最適化中に気づいた事。

    e344a156 ble-core.sh (Koichi Murase     2018-08-06 13:43:50 +0900 1135)     a=$'\t' b=$' \t'   ret=${ret//"$a"/$b}
    9629b9dd lib/core-complete.sh (Koichi Murase 2018-08-05 15:28:25 +0900   75)     a=$'\t' b="\\$a"   ret=${ret//"$a"/$b}

    うーん。これを見ると e344a156 のリファクタリング時のミスの様な気がする。該
    当する項目は #D0719 であるが、たった一行で済ませているという事を考えるとこ
    れは本当にミスであると判定して良い。というかそもそも元々の実装自体が間違っ
    ている。

    改行と同様に $'\t' に置き換えるという手と、恐らく現在・以前の実装で意図して
    いたと思われる \[TAB] という形に置き換えるという二つの方針が考えられる。本
    来意図していた筈の後者にする事にする。

  * main: root ユーザーで入ると the owner of '' is not correct と表示される (reported by zim0369) [#D1712]
    https://github.com/akinomyoga/ble.sh/issues/163

    _ble_base_run か _ble_base_cache のどちらかの初期化の途中で、ディレクトリ所
    有権の問題が起こっている。それからエラーメッセージにも問題がある。うーん。

    * 再現の試み

      取り敢えず手元で再現できないかどうかは試してからより詳細を求める事にする。

      うーん。root と user の両方にインストールしたとしているがどのように入れた
      のだろうか。取り敢えず root の home ディレクトリをチェックするべきなのだ
      ろうか。うーん。色々やってみたが特に問題は生じていない様だ。

      或いはインストールの方法に問題があるのかもしれない。ユーザーから root の
      .local/share/blesh にインストールした等。と思ったが、これだとインストール
      できない筈である。一方で、root からユーザーのディレクトリにインストールし
      た可能性? 然しそれだと root user に switch した時にエラーメッセージが出る
      という現象にはならない。

    分からないので取り敢えずエラーメッセージを修正して何が表示されるか問い合わ
    せる事にする。

    2021-12-19 分かった。'/run/user/1000/blesh' である。つまり、XDG_RUNTIME_DIR
    が su する前のユーザーのディレクトリのままになっているのが問題である。

  * complete: FIGNORE で全てが棄却されるバグ (reported by seanfarley) [#D1711]
    https://github.com/akinomyoga/ble.sh/issues/162

    これは極めて単純なバグだった。そもそも実は FIGNORE は今まで全く動いていなかっ
    たと思われる。

2021-12-16

  * menu-complete で 30s かかるという話 (1/2) construct-page のバグ (reported by banoris) [#D1710]
    https://github.com/banoris/dotfiles/issues/11

    確かに ble.sh は bash で書かれているし遅いが其処まで遅いかっただろうか。自
    分の手許でやってみた所、確かに bash-completion を有効にしていると 10k files
    に対して 15s かかっている。調べてみると良いだろうという気がする。

    ble/complete/progcomp/.filter-and-split-compgen は 0.1s

    うーん。_minimal 自体の呼び出しが 4 秒かかっている。ble.sh の外では 0.2s な
    のでこの違いは大きい。一体何処から違いが出てくるのだろうか。

    % →実際に _minimal の時間を計測しようとしたら _minimal 自体はそんなに遅く
    % なかった。実は、それよりは ble/util/assign の読み取りが遅いのではないかと
    % いう疑惑。と思ったらそうでもなかった。_filedir が実際に遅くなっている。

    * 何やら _filedir が勝手に置き換わっていると思っていたら
      /etc/bash_completion/redefine_filedir とかいう変なファイルによって実装が
      置き換わっていた。うーん。おかしな事をする物である。

      古い実装では while read -r line; do done で一つずつ行を読み出しているので
      遅かった。これを置き換えたら _minimal の呼び出しにかかる時間はほぼ 0 になっ
      た。然しそれでもやはり 13s ぐらいは待たされる様である。

    * その他の bottleneck は、2) yield ループが遅い、3) 一時ページに沢山表示し
      ようとしている為に menu 配置の計算が遅いという事がある。

      yield ループに関してはどうしようもない。絞り込みをする為には結局事前に実
      行しなければならないので、スキップする事はできない。とすると、awk 等を使っ
      て加速するという事も考えられるが、処理を重複して実装するのも面倒である。
      それでも場合によってはそれを考えても良いのかもしれないとは思う。

    * menu 配置で初期化遅延が効いていなかったバグ

      | menu 配置に関してもなかなか難しい所がある。C言語で書ければそれで終わりな
      | のかもしれないがそれも難しい。或いはより高速な Bash スクリプトのインター
      | プリタについても考えてみるが、そもそも制限された Bash の機能を使って実装
      | しているので不自然な実装になっている。劇的に早くなるとは思えないのが現状
      | である。
      |
      | 実際に測定する。
      |
      | [1639646039.075008]compgen:1
      | [1639646039.076485]compgen-helper:2 <_minimal echo  echo>
      | [1639646039.101227]compgen-helper:3
      | [1639646039.111599]compgen:2
      | [1639646039.111884]compgen:3
      | [1639646039.139718]compgen:4
      | [1639646039.139801]compgen:5
      | [1639646041.294533]compgen:6
      | [1639646041.464829]menu#construct:1
      | [1639646049.977139]menu#construct:2
      |
      | 1. compgen 呼び出しは現在は 0.04s
      | 2. filter-and-split は 0.028s
      | 3. yield に 2.15s かかっている
      | 4. construct-page には 8.5s かかっている。
      |
      | やはり一番重いのは construct-page である。
      |
      | complete_menu_style や complete_menu_maxlines を設定して1ページに表示する
      | 項目の数を制限するしかない気がする。念の為、1ページに表示する項目の数を制
      | 限した時に改善するかどうか確認はしておく
      |
      | →うーん。全然改善していない。8.3s である。もしかすると全項目スキャンして
      | いる可能性がある?
      |
      | 調べてみた所、何と全項目を処理している。しかも
      | .measure-candidates-in-page の時点で全て処理していて、これが最も時間を消
      | 費している。

      結局 menu 配置に関して頁毎に必要なだけ trace を実行しているつもりだったのが、
      実は毎回全項目に対して配置計算を実行していたという事が判明した (しかしそう
      だとしても、耐えられる速度の範囲だったというのは驚きではある)。

      以下の ncell_eol の式を間違えている。

      | 43bb0749 lib/core-complete.sh (Koichi Murase 2019-03-23 21:41:19 +0900  119)     if [[ $menu_style == align-nowrap ]]; then
      | 43bb0749 lib/core-complete.sh (Koichi Murase 2019-03-23 21:41:19 +0900  120)       # Note: nowrap が起こるのはすでに wcell == max_wcell の時なので、
      | 43bb0749 lib/core-complete.sh (Koichi Murase 2019-03-23 21:41:19 +0900  121)       # 改行処理が終わった後に wcell が変化するという事はない。
      | 43bb0749 lib/core-complete.sh (Koichi Murase 2019-03-23 21:41:19 +0900  122)       local x1=$((ncell%line_ncell*wcell))
      | 43bb0749 lib/core-complete.sh (Koichi Murase 2019-03-23 21:41:19 +0900  123)       local ncell_eol=$(((ncell+line_ncell-1)/line_ncell*line_ncell))
      | 43bb0749 lib/core-complete.sh (Koichi Murase 2019-03-23 21:41:19 +0900  124)       if ((x1>0&&x1+w>=cols)); then
      | 43bb0749 lib/core-complete.sh (Koichi Murase 2019-03-23 21:41:19 +0900  125)         # 行送り
      | 43bb0749 lib/core-complete.sh (Koichi Murase 2019-03-23 21:41:19 +0900  126)         ((ncell=ncell_eol+cand_ncell))
      | 43bb0749 lib/core-complete.sh (Koichi Murase 2019-03-23 21:41:19 +0900  127)       elif ((x1+w<cols)); then

      元を辿ると以下の様に一番最初に頁を実装した時から間違っていたという事の様だ。

      | commit a488e0193927b78ea2066c5d3118ff5a38c6872c
      | Author: Koichi Murase <myoga.murase@gmail.com>
      | Date:   Thu Mar 7 18:29:51 2019 +0900
      |
      |     complete: support pages of menu/style:{align,dense}
      |
      | a488e019 lib/core-complete.sh (Koichi Murase 2019-03-07 18:29:51 +0900 2117)     if [[ $menu_style == align-nowrap ]]; then
      | a488e019 lib/core-complete.sh (Koichi Murase 2019-03-07 18:29:51 +0900 2118)       # Note: nowrap が起こるのはすでに wcell == max_wcell の時なので、
      | a488e019 lib/core-complete.sh (Koichi Murase 2019-03-07 18:29:51 +0900 2119)       # 改行処理が終わった後に wcell が変化するという事はない。
      | a488e019 lib/core-complete.sh (Koichi Murase 2019-03-07 18:29:51 +0900 2120)       local x1=$((ncell%line_ncell*wcell))
      | a488e019 lib/core-complete.sh (Koichi Murase 2019-03-07 18:29:51 +0900 2121)       local ncell_eol=$(((ncell+line_ncell-1)/line_ncell*line_ncell))
      | a488e019 lib/core-complete.sh (Koichi Murase 2019-03-07 18:29:51 +0900 2122)       if ((x1>0&&x1+w>=cols)); then
      | a488e019 lib/core-complete.sh (Koichi Murase 2019-03-07 18:29:51 +0900 2123)         # 行送り
      | a488e019 lib/core-complete.sh (Koichi Murase 2019-03-07 18:29:51 +0900 2124)         ((ncell=ncell_eol+cand_ncell))
      | a488e019 lib/core-complete.sh (Koichi Murase 2019-03-07 18:29:51 +0900 2125)       elif ((x1+w<cols)); then

      取り敢えずこれについては修正した。

    * complete_menu_maxlines を設定したらもっと高速になるか?
      →恐らく高速になる。

      * 4.0s _filedir       -> 0.04s
      * 2.2s yield          -> -----
      * 8.5s construct-page → 2.50s (これは maxlines を設定する事でもっと減らせる)

      うーん。_filedir は外部の問題である。また construct-page は修正したが、全
      画面表示にしている場合には効果は限定される。yield に関してはまあ、仕方が
      ないのかもしれない。何れにしても construct-page の修正だけでも適用しても
      らって、それで様子見する。それでも改善しなかったら yield の高速化について
      も真面目に考える事にする。

      complete_menu_align
      complete_menu_maxlines
      complete_limit

  * complete: gawk-4.0.2 workaround (reported by Knusper) [#D1709]
    https://github.com/akinomyoga/ble.sh/issues/161

    これは gawk のバグだった。特定のパターンの正規表現に対して false warning を
    出す。影響範囲が大きいと思って一つ一つ対策するのは困難かとも思われたが、正
    規表現で問題の正規表現を検出できる気がするので、やはり個別に対策する事にし
    た。

2021-12-15

  * mandb: オプション候補生成で変な動作が幾つかある [#D1708]

    * ...] という謎の項目が生成されている at man.d/man

      どうやら以下の項目から生成されている様子だ。

      | -m system[,...], --systems=system[,...]
      |
      |        man を含めます。このオプションは $SYSTEM 環境変数を上書きします。

      うーん。オプションを分割する時に /,\s*/ ではなくて /,\s+/ で分割する事に
      した。スペース無しで記述するという事は考えにくいだろう。或いは
      --arg=(hello, world) みたいになっている可能性もなくはないが面倒なので考え
      ない。OK

    * fixed: declare で空の completion が生成されている。

      空の候補については集約の際に混入している様だ → これは修正した。
      nodesc のオプションを集める時に name[count++] としていたのを name[count];
      count++に分けた所、count を初期化していなかったので空文字列の添字に格納さ
      れる様になってしまっていたのが原因だった。

    * fixed: wget の man page 抽出で short option の desc が空になっている。
      これは man.d/man 由来である → 修正した。

  * progcolor: mandb_opts をキャッシュする様にする [#D1707]

    progcolor_optctx と同様に。これは declare のより詳細な実装で mandb_opts を
    参照したいから。

  * refactor: mandb_opts はコマンド一般用に転化しても良いのではないか [#D1706]

    その時には cmdspec に移動して、更にそれを core-complete から読み込む様にす
    れば良い。と思ったが help, help-usage 等は名前的には mandb_opts 専用の物で
    ある。名前を変更する必要があるかもしれない。

    或いは、help:help-usage 等 mandb 専用のオプションはそれ専用の配列に格納する?

    取り敢えず現在使われているオプションについて整理する。また、将来的に使い
    そうなオプションについても考える。

      mandb-disable-man
      mandb-help
      mandb-help-usage
      mandb-usage

      plus-options=xxxxx
      no-options
      stop-options-at=IWORD
      stop-options-on=REX_STOP
      stop-options-unless=REX_CONT
      stop-options-postarg
      disable-double-hyphen

      加えて no-options も追加するべきかも

    →cmdspec に移動して cmdspec_opts に名前を変更した。mandb 特有の項目には
    mandb- の接頭辞を付ける事にした。

    * done: 説明を書く

2021-12-12

  * highlight: declare のオプション名…変数名よりも後にあるのはエラー着色にするべき [#D1705]
    これは #D1704 で一緒に対応した。

  * complete: declare a -[TAB] でも候補が生成されてしまっている [#D1704]

    →調べてみた所、これは declare の引数 (変数形式) が extract-commands で抽出
    されていないのが原因であった。引数の種類を調べると ATTR_VAR である。然し色々
    と振る舞いを調べると ATTR_VAR はコマンドの前につく a=b の形の変数代入に使わ
    れている単語の種類である。

    もっと調べると declare a=b の場合には a=b の単語の種類はちゃんと ARGI になっ
    ている。また、a=b declare hello の時にも hello の単語の種類はちゃんと ARGI
    になっている。つまり、特定の条件で declare hello の変数名が変数代入であるか
    の様に単語登録されてしまっているのが原因である。

    wtype の決定経緯を調べる。ctx-command/check-word-end に入った時点で既に
    wtype == ATTR_VAR になっている。従って、word-begin の段階で ATTR_VAR になっ
    ているのが問題である気がする。然し、check-word-begin の段階では wtype =
    CTX_ARGVX の様である。つまり、何処かで wtype が書き換わってしまっているのが
    原因という事になるのだろうか。

    うーん。分かった。ble/syntax:bash/check-variable-assignment の中で ARGVI 及
    び ARGEI の時には = の有無に関係なく ATTR_VAR にしてしまっている。これは何
    故だったろうか。経緯を調べる必要がある。

    | 2f2f0eb6
    | @@ -2401,7 +2406,7 @@ function ble-syntax:bash/check-variable-assignment {
    |    # パターン一致 (var= var+= arr[ のどれか)
    |    local suffix='=|\+=?'
    |    ((_ble_bash<30100)) && suffix='='
    | -  if ((ctx==CTX_ARGVI)); then
    | +  if ((ctx==CTX_ARGVI||ctx==CTX_ARGEI)); then
    |      suffix="$suffix|\[?"
    |    else
    |      suffix="$suffix|\["
    |----------------------------------------------------------------------
    | commit 1823c540cfe25c952fc96d8e50ae7dab712aacaf
    | Author: Koichi Murase <myoga.murase@gmail.com>
    | Date:   Mon Nov 27 23:46:09 2017 +0900
    |
    |     syntax (tilde expansion): support ordinary words with variable assignment form
    |
    | @@ -2054,6 +2112,109 @@ function ble-syntax:bash/check-tilde-expansion {
    |      ((_ble_syntax_attr[i]=ctx,i+=${#BASH_REMATCH}))
    |    fi
    | [中略]
    | +
    | +## 関数 ble-syntax:bash/check-variable-assignment
    | +## @var[in] tail
    | +function ble-syntax:bash/check-variable-assignment {
    | +  ((wbegin==i)) || return 1
    | +
    | [中略]
    | +
    | +  # パターン一致 (var= var+= arr[ のどれか)
    | +  local suffix='=|\+=?'
    | +  ((_ble_bash<30100)) && suffix='='
    | +  if ((ctx==CTX_ARGVI)); then
    | +    suffix="$suffix|\[?"
    | +  else
    | +    suffix="$suffix|\["
    | +  fi
    | @@ -2577,51 +2760,6 @@ function ble-syntax:bash/ctx-command/.check-word-begin {
    |    return 0
    |  }
    |
    | -## 関数 ble-syntax:bash/ctx-command/.check-assign
    | -## @var[in] tail
    | -function ble-syntax:bash/ctx-command/.check-assign {
    | -  ((wbegin==i)) || return 1
    | -  ((ctx==CTX_CMDI||ctx==CTX_ARGVI)) || return 1
    | -
    | -  # パターン一致 (var= var+= arr[ のどれか)
    | -  local suffix='=|\+=?'
    | -  ((_ble_bash<30100)) && suffix='='
    | -  if ((ctx==CTX_CMDI)); then
    | -    suffix="$suffix|\["
    | -  elif ((ctx==CTX_ARGVI)); then
    | -    suffix="$suffix|"
    | -  fi
    |----------------------------------------------------------------------
    | 7d862418 (Koichi Murase 2017-03-01 06:29:55 +0900 2580) ## 関数 ble-syntax:bash/ctx-command/.check-assign
    | be5c4616 (Koichi Murase 2015-12-23 22:09:39 +0900 2581) ## @var[in] tail
    | 7d862418 (Koichi Murase 2017-03-01 06:29:55 +0900 2582) function ble-syntax:bash/ctx-command/.check-assign {
    | be5c4616 (Koichi Murase 2015-12-23 22:09:39 +0900 2583)   ((wbegin==i)) || return 1
    | be5c4616 (Koichi Murase 2015-12-23 22:09:39 +0900 2584)   ((ctx==CTX_CMDI||ctx==CTX_ARGVI)) || return 1
    | be5c4616 (Koichi Murase 2015-12-23 22:09:39 +0900 2585)
    | be5c4616 (Koichi Murase 2015-12-23 22:09:39 +0900 2586)   # パターン一致 (var= var+= arr[ のどれか)
    | 69bac74a (Koichi Murase 2015-12-24 21:47:15 +0900 2587)   local suffix='=|\+=?'
    | be5c4616 (Koichi Murase 2015-12-23 22:09:39 +0900 2588)   ((_ble_bash<30100)) && suffix='='
    | be5c4616 (Koichi Murase 2015-12-23 22:09:39 +0900 2589)   if ((ctx==CTX_CMDI)); then
    | be5c4616 (Koichi Murase 2015-12-23 22:09:39 +0900 2590)     suffix="$suffix|\["
    | be5c4616 (Koichi Murase 2015-12-23 22:09:39 +0900 2591)   elif ((ctx==CTX_ARGVI)); then
    | be5c4616 (Koichi Murase 2015-12-23 22:09:39 +0900 2592)     suffix="$suffix|"
    | be5c4616 (Koichi Murase 2015-12-23 22:09:39 +0900 2593)   fi
    |
    | commit be5c461693ddacd2acf581011c3decd1390641d5
    | Author: Koichi Murase <myoga.murase@gmail.com>
    | Date:   Wed Dec 23 22:09:39 2015 +0900
    |
    |     (ble-syntax:bash): special treatment of arguments of `declare'.
    |
    |     * (ble-syntax:bash): declare, typeset, local, export, alias コマンドの引数を文法的に特別に扱う。特に配列構文 =() を許容する。
    |       その為に新しい文脈値 CTX_ARGVX, CTX_ARGVI を追加する。
    |     * (ble-syntax:bash): CTX_ARGVI に対する補完候補は変数名。等号 '=' 以降の部分についてはファイル名の補完候補を列挙する。
    |     * (ble-syntax:bash): 通常の代入構文における配列構文の動作を変更。
    |     [以下略]
    |
    | +2015-12-23
    | +
    | +  * ble-syntax:bash declare 配列初期化構文対応
    | +
    | +    > * [2015-02-16] ble-syntax.sh: local a=(arr) a+=
    | +    >   これは declare や local typeset readonly 等を文法的に特別扱いしなければ対応できない
    | +
    | +    色々試してみた所、以下のコマンドの引数で =() を特別扱いする様である。
    | +      declare readonly typeset local export alias
    | +    alias に関しては他のコマンドと全然性質が違う様な気がするし、
    | +    export に関しては配列の初めの要素しか export されない気がするが、
    | +    文法的には両者とも =() の形式を許容する様である。
    | +    或いは、他にも同様の形式の引数を許容する組コマンドが存在するかもしれない。
    | +
    | +    (少なくとも echo などの組み込みコマンドや、外部コマンドに関しては
    | +    引数に =() 等という物が含まれていると失敗する。)

    これを見る限りは特別扱いは ARGVX, ARGVI を導入した最初の瞬間からあった様で
    ある。特に後付で ARGVI に対して特別扱いを実装したという訳ではなく、最初から。
    実装の経緯を観察する限りはどうも補完で変数名を生成させる為に特別な単語の種
    類を割り当てている様な気がする。一方で現在の実装に於いては、補完は特に
    wtype を参照している訳ではないのでこの様に特別に取り扱う理由もない気がする。

    * ARGVI, ARGEI の際の変数代入で = を要求しない振る舞いは修正する方向で考え
      る。

      x 然し、そうしたら単語着色が消えてしまった。うーん。ARGVI 及び ARGEI の時に
        は単語着色はするべきだろうか。

        先ず文法レベルで。それから引数レベルで。

        | うーん。先ず初めに、文法レベルでの着色については ARGVI だけで良い。
        | ARGEI の時には = 無しで単語が現れたとしたらそれは単語ではないので着色し
        | なくて良い。
        |
        | そもそも文法レベルの着色をするべきなのかという疑問も実は存在する。bash
        | の文法的には実は declare hello= は変数代入になっているが、declare hello
        | は変数代入になっていないと思われる。という事を考えると文法レベルの着色
        | はするべきでない。

        引数レベルの着色については declare 系列専用の着色を定義する必要がある。

        うーん。ble/cmdinfo/color: という名前も何だか微妙な気がするが、これは後
        でいくらでも変更できるので取り敢えずは実装する。既存の実装は存在してい
        ない様だ。ble/cmdinfo/chroma: に変更する。

        うーん。ファイルを分離しようと思ったが名前はどうしたら良いだろうか
        ... やはり cmdinfo は何だか名前として不自然な気がする。core-cmdinfo,

        | * core-help, core-man, core-mandb, core-info, core-whatis, core-which,
        |   これらは既存のマニュアル系のコマンドの名称を取ってきた物。
        |
        | * core-catalogue, core-manual, core-dictionary, core-book,
        |   corer-guidebook, core-map, core-cmdmap, core-reference,
        |   core-commandreference, core-cmdref (reference 系は別の意味になるので
        |   駄目), core-library, core-cmdlib, core-spelllib (library 系も別の意味),
        |   core-spellbook ... 或いはより現実的な物に例えてみる等の方針。
        |
        | * core-getopt これは、実際に cmdinfo を定義する主要な形態として getopt
        |   的な方法を考えている事から。然し、これだけが唯一の定義方法という訳で
        |   もないし、getopt は更にその上の階層の枠組みに名付けたい気がする。実際
        |   には、cmdinfo の中に定義する形になるのではないかと考えている。
        |
        | * core-cmddb, core-database (一般的過ぎる), core-commanddatabase,
        |   core-cmdspec, core-commandspec, core-cmdspec

        うーん。cmdspec の方が幾らかましの気がするので取り敢えず cmdspec という
        事にする。

        然し本当に cmdspec に定義するべきなのだろうかという疑問も残る。実は
        bash-completion でやっている様に contrib/cmdspec/* の下に個別のファイル
        として定義した方が良いのではないかという疑惑。うーん。然しそうだとして
        も取り敢えずの実験的な実装として cmdspec の中に色々記述して API が落ち
        着いてからファイルに分割するというので良い気がする。そう。それがしたかっ
        た事の気がする。

      o ちゃんと引数レベルでの着色で変数名着色ができている。

      o declare の通常引数の後のオプションをエラー着色する機能もOK

    * done: コマンドレベルで declare, etc. + alias の着色を行う。
      うーん。alias については今回は対応しなくて良い。

    * done: 変数代入も extract-command で列挙する。但し、extract command に影響
      がない様にしなければならない。

    x fixed: もう一つの謎は a=b declare a= の形式の時には変数代入が検出されない
      という事。そもそも、変数名着色だって無効化されている。これは一体どういう
      事だろう

      調べてみると "a=b declare@ " の時には @ の位置に stat ARGX が置かれている
      様である。一方で、 "declare@ " の場合には @ の位置には stat は置かれてい
      なくて、代わりにその次の位置に ARGVX が置かれている。この振る舞いは他の通
      常コマンド (echo など) でも同様であった。CMDXV の特別な振る舞いという事な
      のだろうか。

      →うーん。正にそれを実行するコードが check-word-end にある。これはどうい
      う事だろうか。→分かった。どうもこれは変数代入の直後にはキーワードは来な
      いという事を養成する為のコードの様だ。昔は単に ctx=ARGX を設定して抜けれ
      ば良かったが、その後の複雑化で只単に ARGX を設定すれば良いという訳ではな
      くなった。各文脈に応じた複雑な処理を CMDXV の時にも実行する必要がある。

    o ok: declare a -[TAB] での候補生成の抑制は動いている。

    幾つか残っているのを修正する必要がある。

    * ok: global -- が着色されていない。これは今確認したらちゃんと動いている。
      勘違いだったか或いは別の物を修正した時に一緒に直ったか。

    * done: blerc, wiki, 移動: argument_error

    * done: ble/syntax/progcolor は最早 ble/progcolor で良いのではないか。そも
      そも純粋な文法解釈から離れてきていて、bash 特有の実装になっている。

2021-12-11

  * [External] bash-completion: printf -v ... [#D1703]
    https://github.com/akinomyoga/ble.sh/issues/155#issuecomment-984619516

    これは bash-completion 側で対応するべき事の気がする。

    取り敢えず --help 対応が終われば、変数名の補完はできないにしても、オプショ
    ンの表示ぐらいはできる様になる。printf の場合には最初の引数には '' を指定す
    るのが良い気がする → 取り敢えずオプションは表示される様になった。

  * [External] bash-completion: better support for "test", "[" [#D1702]
    https://github.com/akinomyoga/ble.sh/issues/158

    これも bash-completion の側で対応するべき事の気がする。
    但しオプションの説明についてはちゃんと生成しなければならない。
    progcomp の枠組みで説明も一緒に生成できる仕組みがあっても良いのではないか。

    うーん。生成し切れていない物は別枠で指定する? うーん。getoptions 的仕様を確
    定する必要がある気がする。

  * complete: [[ 及び declare の補完 (requested by EmilySeville7cfg) [#D1701]
    https://github.com/akinomyoga/ble.sh/issues/155
    https://github.com/akinomyoga/ble.sh/issues/157

    | user-customization を許可? 或いは自前で実装しても良い
    |
    | うーん。declare に関しては a=(....) 等が含まれる場合の取り扱いが謎だし、
    | 自前で実装する方が良いのではないかという気もする。
    |
    | 一方で [[ についてはユーザーが指定できる様にする? と思ったが、それでも今度
    | は [[ (a == b && c== d)||x == y ]] 等の様な入れ子構造があった時に、ユーザー
    | に渡すコマンドラインを構築するのが大変である (実は現状の実装だとそんなに難
    | しくないかもしれないが、此処は将来的に改修する予定なので現段階で下手にユー
    | ザーインターフェイスを提供すると、将来弄る時に面倒な事になる)。また'[[' '('
    | 'a' '==' 'b' '&&' ... という具合に分割するのが自然だと思われるが、一方で勝
    | 手に空白を挿入しても良いのかだとか色々よく分からない (まあこれは実装を詳し
    | く観察して調整すれば済む話ではある)。
    |
    | うーん。結局、どちらも自前で実装した方が良い様に思われる。これは仕方がない
    | ので、取り敢えず自前の実装を提供する事にして customization については諦めて
    | 貰う事にする。

    将来的に自前で実装する事にする。

    取り敢えず declare 系統は簡単な気がするので先に実装することにする。

    * done: 現在 source:option に於いて ["--" 以降のオプションを解釈しない] や
      [非オプションよりも後のオプションを解釈しない] などの各コマンドの性質はほぼ
      ハードコードされている。これを外部から指定できる様にする。

    * ok: ble/complete/mandb/get-opts ... alias 展開もする? → refactor して、
      alias 展開なども全て処理して mandb が見つかった時点で初めて get-opts を呼
      び出す様に変更した。

    * done: 更に $_ble_complete_option_chars もちゃんと様々の箇所で使う様にする。
      →これは元々より緩いのを部分的に厳しくしているだけなのでそんなに気にしな
      くて良い様に思われる。

    x fixed: "declare [TAB]" で補完が開始されない。

    * done: +o に関しては一番最後の集計時に説明を適用に生成する。

    * done: mandb: 現在 + で始まるオプションは積極的に抽出していない。これにも対応したい。

      * ble/complete/mandb:help/generate-cache (--help|--usage 抽出用) については対応した。

      * generate-from-man は未だ → 対応した。微妙な修正しかしていないが多分これ
        で大丈夫。

    x "top -[TAB]" が正しく動作しない。

    取り敢えず declare については大体完了した。

    [[ に関しては文法も考慮したより正しい補完をすぐに実装するのは難しいが、取り
    敢えずオプションだけは生成できる様にするのが良い。

    * 文脈だけでも確認する → 部分的には対応していたみたいである。ファイル名を
      補完していた。其処に source:option を追加する。
    * それから空文字列からの補完の設定が欠けていたのでそれも追加する。
    * mandb_opts に複数の help=... を記述できる様にする。
    * オプション抽出で -a, --file=<...> や -b (this is test) 等の形式の物にも対
      応した。

  * complete: 沢山 quote が発生する場合には '' で囲むべきなのではないか [#D1700]

    然しこれだと、例えば 'a b c' と 'alpha' というファイルがあった時に前者は 'a
    b c' を生成して、校舎は alpha を生成する事になり、共通一致部分がなくなって
    しまう。共通一致部分をちゃんと求める為には、候補によらない quote の方法に頼
    らざるを得ない。そうすると、 a' b c' 等の様な不格好な物になってしまうという
    気がする。

    或いは最後の挿入時に、COMPS= の時に挿入文字列を修正するという事も可能かもし
    れない。

    うーん。今までの実装を見ると ACTION/complete で suffix を修正はしているが、
    挿入文字列本体 insert を変更している例は見当たらない。然し、呼び出し側の実
    装を見る限りは insert を自由に取り替えても問題は無いように見える。というの
    も insert 自体が、determine-common-prefix によって動的に生成されているから
    である。特に COMPS= だった時によりコンパクトな表現に変更するというのは十分
    に考えられる処置である。

    実装してみた。良い。置き換える時に違和感があるかもしれないと思ったが、実際
    やってみると "絞り込み用の表現" が最終的なコンパクトな表現に切り替わる瞬間
    というのは気持ちの良い物である、という感じである。

    * done: もう少し積極的になっても良いのではないか。例えば / や = の直後から
      補完を開始した場合等にも適用して良いのではないか → 対応した。

    x fixed: requote を実装したら頭の悪い auto-complete が表示されている

      cd tmp/filename_contains_symbols/'() () [] directory'/ [tmp/filename_contains_symbols/\(\)\ \(\)\ \[\]\ directory]

      これは bash-completion がなくても再現する現象である。うーん。
      auto_complete の候補表示に於いて ACTION/complete で insert が変更されない
      という事を仮定しているのかもしれない。

      うーん。ACTION/complete 前の状態を見ると以下の様になっている。
      COMPS="tmp/filename_contains_symbols/'() () [] directory'/"
      insert="tmp/filename_contains_symbols/\\(\\)\\ \\(\\)\\ \\[\\]\\
      directory" ACTION=file

      分かった。insert が COMPS を prefix として保持していないのが原因である。
      然し、何故その様な事になっているのだろうか。どうしたらこの様な候補が生成
      されるのだろうか。本来は COMPV が共通している筈だから除外されるのではない
      のか。

      →何故この様な事になっているか分かった。その実、この補完候補は単語を短く
      する (末尾の / を除去する) 事を提案しているのである。なので、遡った書き換
      えとなって quote が保持されないという形になっているのである。

      うーん。遡った書き換えの時にはどうせ全体が置き換わるのだと思えば、やはり
      全体を requote してしまっても良いのではないか?

    x fixed: そもそもスラッシュが除去される時点で変なのでは? どうやって候補が生
      成されているのだろうか → construct-ambiguous-pattern が誤っていた。今ま
      でに予期せず遡って置き換えが起こったりしていたが、それの原因の一端は此処
      にあるのかもしれない。

  * README: 一つのキーで複数の widget を呼び出す方法? (motivated by michaelmob) [#D1699]
    https://github.com/michaelmob/portable-config/commit/49f9566afd8b62d47a090328104ad803962e6d3f

    説明を書いた。設定例の動作確認もした。

  * bind: "" で囲まれていない keyseq \C-l を解釈できない (motivated by cmplstofB) [#D1698]
    https://github.com/cmplstofB/dotfiles/blob/master/_dffiles/.config/bash/bashrc#L170-L172

    うーん。bash の振る舞いを色々調べてみた所、"" で囲まれていない時にはやはり
    完全には解釈しないが、\C-x 等の形の時は解釈できる様だ。

    * \C-x\C-y の時には \C-y と解釈される。
    * xyz の時には x と解釈される。
    * \a も \ と解釈される。
    * \C-nop は \C-n となる。
    * \C-xC-y は C-y となる。
    * \C-axC-b は C-b となる。
    * helloC-b も C-b となる。
    * helloC-x,TAB も C-x となる。
    * C-xTAB も C-x となる。
    * TABC-x も C-x となる。
    * BC- は C-@ となる。

    つまり…最後の "C-文字" が採用される?

    * C-M-a および M-C-a は \201 となる。
    * C-aalpha-beta は C-b となる。
    * \C-a\M-c は \203 である。
    * panic-trim-c は \204 である。

    つまり、最初に - で split してそれから評価している。

    * C-- は C-@ になる。
    * C--x は C-x になる。
    * - は抑々指定できない (bind に対するオプションと解釈されてしまう)。
      inputrc に入れたら恐らく C-@ になるのだろうという気がする。

    取り敢えず bash と同様の振る舞いになる事を確認した。

  * util (cursor-state): tmux や screen の中では pass through シーケンスを用いる? (motivated by cmplstofB) [#D1697]
    https://github.com/cmplstofB/dotfiles/blob/3e41ac47f47cc7788215409a5c3f26635f02d6a0/_dffiles/.config/blesh/blerc#L193

    tmux: \ePtmux;%s\e\\ (中に含まれる \e は二重にする)
      また tmux; の部分は存在しなくても良い様である (https://gist.github.com/saitoha/4723390)
    screen: \eP%s\e\\

    対応した。

    * done: 本来は外側の端末の対応状況に応じて _ble_term_Ss を送るべきの気がする。

      | 然しそうするとユーザー設定または terminfo の _ble_term_Ss とどちらを優
      | 先するべきなのかという問題が生じる。うーん。実質的に _ble_term_Ss は対
      | 応しているとしたら一意なので、有限文字列かそうでないかだけが問題である。
      | だとすれば、ble.sh の側で外側の端末が Ss に対応していると判定したならば、
      | それに対応するシーケンスを送りつけてしまって問題ない気がする。

      _ble_term_Ss が空で端末multiplexerの外側の端末が対応していると判断できる時、
      独自の判断で外側の端末の対応する DECSCUSR を pass through で送信して良い。

      Note: _ble_term_Ss が空でない時には既に外側に pass through で送りつける様に
      なっている。但し、_ble_term_Ss に設定された値を尊重する。ユーザーが好みで設
      定しているかもしれないので。

      →外側の端末情報の取得も実装した。任意の階層だけ入れ子になった端末マルチ
      プレクサでもちゃんとカーソル形状の変更が伝播する様になった。

  * edit: self-insert の振る舞い [#D1696]

    * 一番最後のキーを挿入するべき。現在は一番最初のキーを挿入している。
    * C-l 等、対応する制御文字が存在する物については単に ctrl を外すのではなくて、その元々の文字に復元するべきである。

    或いは CHARS を直接挿入するべき? → CHARS を確認したが此処には escape
    sequence の文字列が入っているという事の気がする。うーん。何れにしても
    fallback なので気にしなくて良い様な気がする。

    * 類似の物が実は幾つかある。isearch や auto_complete で読み出す部分。
      他にも _ble_decode_MaskChar や KEYS[0] を参照している箇所は確認するべきである。

    o bind '"\C-t\C-l":self-insert'
    o ble-bind -f 'C-t right' self-insert

  * wiki: C-BS に対する binding について記述した (found by banoris) [#D1695]
    https://github.com/banoris/dotfiles/commit/f36b396c8de18159e9b5cf23974f789e3766d8ba

2021-12-08

  * complete: bind -[TAB] で bash-completion がオプションを生成してくれない [#D1694]
    ble.sh の外側ではちゃんと生成してくれている。

    これは分かった。上書きしている builtin が --usage オプションに対応していな
    いのが原因。というか unrecognized option と表示する時に、エラーメッセージと
    して usage を出力していて、それに従って usage が出力されているのであった。

    うーん。これに対してはどの様に対処するべきだろうか。つまり、bash-completion
    は敢えて誤った用法でコマンドを呼び出してその結果を解析している。上書きする
    builtin は誤った用法に対するエラー時の振る舞いに対しても同様に振る舞う必要
    があるのだろうか?

  * mandb: --help から読み出し? [#D1693]
    https://github.com/akinomyoga/ble.sh/issues/158

    少なくとも builtin に関しては (一部を除き) --help を使っても良いのでは?

    bash-completion で --help を呼び出している物に関しては --help を参考にして
    も良いのではないかと思われる。_parse_help 辺りに hook してしまえばこちらの
    物である。

    * というか、--help を使っても良いコマンドのリストを contrib に保持しても良
      いのではないかという気がする。

    * うーん。bash-completion の _parse_help に hook して、_parse_help が呼び出
      されたらそれに対応するオプションを使って db を構築しようとも思ったが、こ
      れだと bash-completion が呼び出される迄は更新されない。

      それよりは自前で --help が使えるコマンドの一覧を保持していた方が良いので
      は? と思ったが、それだと --help を呼び出すのに -h を使うコマンドや '/?'
      を使うコマンドなど、コマンド毎の変化を管理するのが面倒である。

      それよりは bash-completion 経由で必要な時に情報を読み取る方が良い?

      と思ったが、bash-completion で複数の異なるオプションで _parse_help を呼び
      出した時に、どの様にキャッシュを統合するのかというのが問題である。そもそ
      も man との統合でも問題になる。bash-completion を呼び出す前の時点で man
      から呼び出してキャッシュを作ってしまうと以後それを使う様になってしまう。
      なので、bash-completion で _parse_help を呼び出した時に man & --help で再
      生成しなければならないのではないだろうか。或いは、man から生成されたデー
      タと --help から生成したデータは別々に管理する事にして、後でそれを統合す
      るという形にするのかもしれない。その時には、_parse_help の他に
      _parse_usage だとか或いは _parse_help の異なるオプションの場合についても
      全て統合する必要がある。

    * man と --help のどちらを優先させるべきか?

      | かなり面倒である。後、man による説明と --help による説明のどちらを優先さ
      | せるべきなのかという問題も生じる。
      |
      | o man の方が詳しい説明がある?
      |
      | x 或いは --help の方が簡潔な説明になっているから menu の desc に表示する
      |   のに適している?
      |
      | x man 日本語は古い事があるのでコマンドの --help の方が良い?
      |
      | o 逆にコマンドには直接日本語の説明が対応されていなくても man では対応され
      |   ているという事があるのではないか? と思ったが逆のパターンもあるだろうし
      |   一概には言えない。
      |
      |   man の方は単にファイルを用意すれば良いだけなので対応は簡単である。一方
      |   で、翻訳量が多いという観点で --help よりは対応が遅れているのではないか
      |   という考え方もできる。
      |
      |   一方で --help の方の日本語対応については、そのコマンドが locale に依存
      |   して振る舞いを変えなければならないので、そういう意味で対応が遅れている
      |   可能性はある。特に python や go や rust 等、新しい言語で書かれた物につ
      |   いては i17n の標準的な方法が確立しているのか怪しい。とすると対応が遅れ
      |   ているという可能性があるのではないか。然し、そもそもそう言ったツールに
      |   至っては man ですら対応していないかもしれない。結局分からない。
      |
      | o man から抽出した物については太字や下線等の装飾がついている。--help で
      |   は装飾をしている事は滅多にない。あったとしても抽出の過程で削除しなけ
      |   ればならない気がする。

      --help を優先させるべきの気がする。つまり、同じオプションに関する説明があっ
        たら --help から抽出した物を優先させる。太字等の装飾については諦めるし
        かない。

    * コマンドによっては man を無効化する選択肢があっても良いのでは?

      然し、余分に man から生成したとしても余分な選択肢が表示されるだけで、ある
      べき物が欠けるといった形での不都合は生じない。また、man が有用な情報を含
      んでいなかったとしても man から何も抜き出せないという形になるだけの気がす
      るので気にしなくて良い気がする。

      うーん。と思ったが… declare や bind 等は bash のマニュアルからオプション
      を拾ってしまうかもしれないのでやはり抑制する機能があっても良いのではない
      か。

    * bash-completion でオプションを生成したとしても、内部的には _parse_help を
      呼ばない可能性はある。そう考えると --help を用いるコマンドのリストを管理
      して良い気がする。

    * todo: 存在しないコマンドについて mandb cache を生成するのは無駄なのではな
      いか。一応存在チェックをしてから mandb 生成を試みるのが良い気がする。

      然し、何処かのディレクトリに入っているコマンドの場合にはどうするのか?
      abc/def/hello.exe に対して mandb を呼び出す場合には結局 hello.exe が呼び
      出されるのではないか。

      然し、そもそも abc/def/hello.exe としなければ呼び出せないコマンドで普通に
      hello.exe では呼び出せない物が、man の中に説明があるとも考えにくい。とい
      う事を考えると、mandb はやはり存在するコマンドに対してだけ生成すれば良い
      気がする。

    [方針]

    * done: 存在しないコマンドに対しては mandb キャッシュは生成しない。

    * <del>man は常に有効。</del>

    * done: それとは別に --help を使えるコマンドのリストを保持する。printf 等は
      その最たる例。man を抑制するリストも用意する。うーん。リストよりは
      ble/set# の方が良いのかもしれない。うーん。ble/gset は実装していない。寧
      ろ ble/gdict の方が良い気がする。其処に opts 方式で色々格納できる。

    * done: _parse_help 及び _parse_usage に trap する。呼び出し方に応じて異な
      るファイルに保存する。その後で、既存の個々のキャッシュ (man, help, usage,
      ...)  を纏めて統合キャッシュを再生成する。

      Note: _parse_help は必ずしも補完したいコマンド名に対して呼び出される訳で
      はない。例えば gcc については prefix/share/libexec/cc1 的な物に対して
      --help が呼び出される。

      → _parse_usage をしてもオプションの一覧が取得できるだけで説明を生成でき
      る訳でもない。という事を考えれば、_parse_usage には対応しなくて良い気がする。

    * done: desc が一つもない場合には desc にする必要はないのではないか。

    * done: と思ったが _parse_usage からオプション引数を取るか取らないか程度の
      情報は抜き出せるような気もする。実装した。取り敢えずは動いている様な気が
      する。

    * fixed: hash-pjw の実装が怪しい

    * done: help 解析で -a, --aaaa=X は -a X, --aaaa=X に翻訳する必要がある。

2021-12-06

  * highlight: for の第一引数のファイル名着色はしない。変数名着色はする [#D1692]

    for - の word highlighting で option を除外。というか for の highlighting
    を普通のコマンドとして処理しているのはおかしい。

    for - in のエラー着色は - だからしていると考えていたがそうではなかった。唯
    単に for 文が不完全であることによるエラー着色だった。というか for の第一引
    数は変数名に合致しない物を指定した時にはエラー着色になる様にするべきである。

    うーん。どうやら for の変数名の部分は here-document の word と同じで、切り
    出しは文法的に行われる物の、実際にはコマンド置換もクォート除去も何も解釈さ
    れずに直接変数名かどうかの判定対象となる様である。

    取り敢えず arr[xxx] 等に対してはエラー着色が出る様にしたが、その他の入れ子
    構造 (例えば "for $(echo var)" など) に対してはエラー着色になっていない。

  * 2021-09-08 complete: 'fo で補完すると 'for' になってしまうが for はキーワードなので駄目 [#D1691]

    元々の compgen では対応しているのに ble.sh が勝手に quote を変更するから
    駄目なのだろうかと思ったが、元の compgen -c ではそもそも "'f" や "'f'" を
    渡しても何も候補生成されなかった。

    更に plain Bash の補完でも 'fo で補完すると 'for' が補完されてしまう。と
    いう事を考えると ble.sh だけの問題ではないのでそんなに気にしなくても良い
    のかもしれない。

  * ble.sh: complete check-here を制限 (reported by EmilySeville7cfg) [#D1690]
    https://github.com/akinomyoga/ble.sh/issues/156

    check-here を完全に消すと恐らくコマンド名を生成できない。

    実装を確認した。ARGX 系統は直前に必ず空白の類が存在して check-prefix で生成
    される。なので、ARGX 系統に関しては check-here から削除してしまって問題がな
    い様に思われる。

    元々、check-here に残していたのは、候補が全く生成できない時にその場で前の単
    語に続けて生成したい事があるかもしれないという事だったが、よく考えてみれば
    その様な使い方が有用な場合は意図的にその様に設計された限られた状況だし、そ
    の様な状況の場合には、前の単語の補完の一部としてその様な候補を生成するべき
    である。従って、check-here による ARGX 系統の補完文脈は寧ろ削除するべきであ
    る。

    x fixed: 2021-12-11 complete: 何故か空の引数から補完を開始する事ができない

      | と思ったが、これはもしかするとつい先日修正した物が原因なのかもしれない。
      | →うーん。そうだった。これは困る。どう判定するのが良いのだろうか。もう面
      | 倒なので空白で判定する。依然として "for \ " の直後で問題になりそうだが仕
      | 方がない。
      |
      | うーん。然し類似のケースとして "echo hello[TAB]" の時には何故問題にならな
      | かったのか? 或いは一つでも補完文脈が生成されていれば、check-here は有効化
      | されないという事? → と思ったらそうだった。.check-here 関数の一番初めで、
      | 既に source が存在していた時には何もせずに戻る様になっている。
      |
      | つまり、今回の問題点は何だったかというと…FARGI1 及び FARGX1 に対して正し
      | く補完を生成しなかった事? うーん。然し実装を見る限りはちゃんと生成しそう
      | な物である。

      "echo hello[TAB]" で問題にならないのは何れにしても check-prefix で引っか
      かって補完文脈が生成されるので、check-here が抑制されるからである。然し、
      "for -[TAB]" の時には - から始まる補完文脈を生成できないので、check-here
      が始まってしまう。本来、"-" が文法的に正しくないとしたら、その位置からの
      補完は存在しないという事で、何も生成しない補完文脈を此処に設置するべきな
      のである → 新しく source:none を作成してそれを使う事にした。

    x fixed: { echo; } 'f[TAB] を実行すると fi' の様に補完されてしまう。"fi と
      すると fi" になるし、$"fi とすると fi" になる。つまり、遡って書き換えが起
      こっているのにも拘らず、終端の quote が付加されてしまっている。

      これは action:literal-word のバグだった。修正した。

  * mandb: 空文字列の時にも mandb に基づくオプション生成を実行するべき [#D1689]

  * 2021-08-30 complete: オプションの説明と progcomp の integration を考える (motivated by Shahabaz-Bagwan, bbyfacekiller and EmilySeville7cfg) [#D1688]
    https://www.youtube.com/watch?v=YS1vxEhd2Pc
    https://github.com/akinomyoga/ble.sh/issues/132#issuecomment-908266634
    https://github.com/akinomyoga/ble.sh/issues/152
    https://github.com/akinomyoga/ble.sh/issues/155#issuecomment-984596470

    complete: 折角 option の説明を抽出する機能を実装しても
    bash-completion を使っていると説明が表示されない。
    だからと言って bash-completion を無効にするのも惜しい。

    やはり bash-completion のオプション生成に介入するべきだろうか。
    或いは bash-completion に限らず progcomp を使っている場合には、
    最後にオプション名の抽出を試みるというのも手である。

  * mandb: awk, sed の man ページからの抽出に失敗している (reported by bbyfacekiller) [#D1687]
    https://github.com/akinomyoga/ble.sh/issues/152

    当初は bash-completion との integration の問題かとも思ったが、それ以前に
    mandb での抽出に於いて awk, sed でそれぞれ異なる形で失敗していた。両方につ
    いて対応した。

    更に、awk の man page の中にある ".ig ... .." はコメントセクションの様だ。
    古いオプションや文章が含まれているらしい。

    2021-12-07 更に "wget" も補完されないという事が報告されていた。他にもあるか
    もしれないと思って色々動作を確認する。"bc", "mv", "fish" 等に対して追加で抽
    出コードの修正を行った。man のオプションの説明の形式には一貫性が全然ないの
    でコマンド毎に表現の仕方が異なるというのは問題である。それでも、典型的なパ
    ターンというのは有限である筈なので、それで大体カバーできると思うしかない。

    2021-12-08 更に "ping" もちゃんと man から抽出できていなかった。

    2021-12-09 man から抜き出す時に -c, --cookies=<cookies.txt> の引数が -c の
    側に適用されていなかった。help の方の実装を参考にして対応した。

    2021-12-12 "top" の抽出に失敗していると思ったら fmt4 の desc が終
    端できていなかった。空行がある場合には強制的に中断する事にした。

  * 2021-09-06 menu: fish の様に twocolumn 形式で表示する desc を作っても良いのではないか (motivated by Shahabaz-Bagwan) [#D1686]
    https://www.youtube.com/watch?v=YS1vxEhd2Pc
    https://github.com/akinomyoga/ble.sh/issues/132

    或いは任意の column の数に設定できる様にする。或いは、望ましい幅的な物 (最
    小幅でも良いかもしれない) を設定して column 数を自動で決定する。

    実装してみた。

    x fixed: 再表示の際に truncate した内容が表示されてしまう。今までの実装では
      候補は truncate されないという前提だったがそれが崩れているという事。

    x done: desc/guess についても実装を更新する必要がある。というよりそもそも
      guess とは何だったか。

    x fixed: カーソルキーによる navigation を再設計する必要がある。今までは Z
      型に走査する場合しか考えていなかった。

      a N 型に走査する選択肢と Z 型に走査する選択肢の二種類に場合分けして実装す
        るか、

      b 或いは一般的なアルゴリズムを考えるか (これは効率の良いアルゴリズムは困
        難の気がする。)

      c 或いは menu-style 側で振る舞いを変更できる様にするか。

      N型かZ型かに関してはページを構築した時に何処かの変数に補助情報として記録
      すれば良い。N型だとしても desc の場合には上下左右の操作は自明であるのでN
      型一般のアルゴリズムを用いるよりも、それ専用の処理を実装した方が良い気が
      する。

      menu-style 側でカスタムに実装できる様にする事にする。

    x fixed: 座標計算がずれる。_ble_b[TAB] において。

    x fixed: trace が無限ループになっている気がする。 _ble_[TAB] において。

      これは単に各列の行数の計算を間違えて全ての項目を一つのページに含めようと
      して巨大なページが出来上がっていたのが原因だった。

    * done: desc-raw -> desc に改名する?

      古い設定名は desc に移動する。

      新しく desc-text を用意する。desc-text はもっと良い名前はないか。
      desc-less, desc-esc, ... info が text, esc と言った名前を使っているのでや
      はり text で良い気がする。

      取り敢えず今は desc-raw は desc の synonym という事にしておく。ble-update
      等した時に不整合が起きると問題だし、そもそもそれぐらいなら別に対応してい
      ても大した問題にはならない。

    * 新しい bleopt の名称を固定する。ドキュメントに記述する
    * 新しい widget menu/{forward,backward}-column をドキュメントに記述する

  * 2021-08-30 complete: alias desc に alias の内容を表示するべきだろうか (motivated by Shahabaz-Bagwan) [#D1685]
    https://www.youtube.com/watch?v=YS1vxEhd2Pc
    https://github.com/akinomyoga/ble.sh/issues/132

    * reject: 或いはその場で展開してしまう様なオプションを提供しても良いのかも
      しれない。その場合には遡った書き換えが起こるので不可逆であるという事。そ
      して他の候補が表示されている場合には候補が表示されなくなるなどの問題があ
      る。

      取り敢えずその場での展開は考えない事にする。後で要望があれば実装するかも
      しれない。何れにしてもユーザーがそういう設定を書けば実現できるのだから
      ble.sh 側で一々設定しないという態度も考えられる。とは言いつつユーザー側で
      ちゃんと実装するには色々と細かい事があるような気もする。

    * done: そもそも job 名が補完候補に現れていない気がする。
      コマンド名の補完でジョブ名も列挙する事にした。

    * done: 変数 (action:variable) についても説明をちゃんと生成する。変数の中身
      でも展開すれば良い気がする。

    * done: 説明を着色する。現在は単に黒で表示しているが着色した方が分かりやす
      いのではないか。或いは種別の方を着色して、展開結果などの値については黒で
      表示した方が分かりやすいかもしれない。

      実行可能ファイルの着色に関してはパスをシンボリックリンクかどうかで各セグ
      メントを着色すると良い気もする。そう考えるとやはり値の方を着色する事も考
      えるべきの気がする。

  * 2021-09-06 trace: ellipsis の位置が relative の時にずれる [#D1684]

    menu_style=desc で説明が表示しきれない時に発生する問題。但し既存の処理にず
    れがないか後で確認するべき。これは relative の時の xlimit と実際に表示する
    範囲の制御のずれが原因だった。

    折返しも全て xlimit で行う事にする。

    然しそうすると relative の時の振る舞いが変わってしまう。改めてテストで振る
    舞いを確認する必要がある。うーん。やはりテストに失敗が発生している。
    relative の時には呼び出し元が気をつけていると想定して xlimit を減少させない
    様にするべきなのではないかという気がする。

    然しそうすると安易に relative を付けている箇所ではちゃんと COLUMNS を 1 減
    少させるという対策が必要になる。

    2021-12-05 改めてこれについてどう処理するのが良いか考察する事にする。当初の
    問題は ellipsis を relative で置く時に xlimit を元にして位置を決定している
    事。然し、relative の時であっても文字を置ける一番右の位置は xenl に依存して
    いる。

    % * というかそもそも xlimit はどう決定されているのだったか。 xenl または
    %   relative がある場合には cols でそれ以外の時には cols-1 になっている。

    * 改めて修正箇所について確認する。

      * 先ず HT の振る舞いについて。移動先が cols よりも先に行ったら cols-1 に
        戻すという処理だったのが、今回の修正で xlimit よりも先に行ったら
        xlimit-1 に戻すという処理に変更されている。然し、そもそも cols-1 が限界
        になっているのは xenl のある端末でもない端末でも同じ振る舞いの筈である。
        cols-1 までしか行かないのであれば xenl だろうと xenl でなかろうと、
        relative であろうとそうでなかろうと同じである。

        これについては元の実装に戻す事にした。

      * ASCII 文字列の連続に対する対策も見た感じは的外れの物に見える。というか
        これまでの実装でちゃんと xenl (_ble_term_xenl || opt_relative) の時の対
        策も行われている様に見える。

      うーん。前に行った修正点はやはり色々考えると変である。元々ちゃんと考慮に
      入れて作ってある様に見える。

    * そもそもの問題点は何だったか。ellipsis を出力するに当たって xenl のない端
      末だと、ellipsis を最後に出力しただけで行が変わってしまうという問題がある。
      その為、ellipsis の位置を1文字後退した位置に出力する様になっているが、そ
      れによってはみ出た文字が表示されてしまっているという事?

      然しそれも何だか変である。改めて menu の出力がどうなっているか確認する。
      relative:ellipsis で呼び出している。

      うーん。ellipsis が出力される状況を見てみたが変な事はない気がする。寧ろ、
      何故か xlimit を超えて文字が出力されているのかという事の方が問題である様
      に思われる。

      | -p file : True, if file exists and is a fifo special file or a p…e
      | 0123456789012345678901234567890123456789012345678901234567890123456

      xlimit=66, cols=67 になっているのに 67 まで文字が埋められてしまっている。

    * 改めて xlimit の決定部分を見て何が問題なのか分かった気がする。

      - xenl は _ble_term_xenl で初期化される。
      - opt_relative もしくは justify の時には 幅を縮めて xenl=1 に上書きする。
        この時の "幅" は xlimit=cols-1 である。

      因みに xenl が最初から 1 だった時には xlimit=cols のままである。

      うーん。そもそも xlimit は何のための変数だったのか。使用箇所を確認してみ
      ると overflow の判定と implicit-move で参照しているに過ぎない。

      前者に関しては最終行での幅が xlimit でそれ以外が cols という事になってい
      る気がする。

    ? done: ellipsis を出力する時にそもそも幅が足りない時にどうするか?
      → . の連続に置き換えるのが良い。

    ? done: process-overflow で最終行以外での処理は?
      →取り敢えず最終行かそれ以外かで xlimit or cols を切り替える事にした。
      →改めて考えたがそもそも行末以外での overflow で ellipsis を出力するのは変だ。
        という訳で ellipsis は最終行にいる時にだけ出力する事にする。

    ? fixed: そもそも xlimit の設定方法は正しいのだろうか。
      xenl が元々ある場合には xlimit=cols-1 にする必要性もないのではないか。
      →これは改めて考え直して修正した。

    ? ok: print+ における overflow 判定は正しいか?
      →xenl||wmax-- でちゃんと処理できている。現在の新しい実装では xlimit の減
      少は xenl だけで決定されているので。

    ? implicit-move で行われている以下の処理は一体何なのか

      L1164: ((y++,x=w<xlimit?w:xlimit))

      うーん。これは一応OK? xenl がない場合は一番右の列に移動すると考え、xenl
      がある場合には端末の右端に行くと考える。実は xenl がない場合には更に次の
      行に行くという考え方もあるかもしれない。何れにしてもコメントにある様に端
      末によって振る舞いが変わるのではないかと思われる。

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]
    https://github.com/akinomyoga/ble.sh/issues/147

    virsh completion を実行した直後にエラーメッセージが出るという事。これは
    virsh の補完が IFS=$'\n' と書き換えを行ってそのまま放置するのが原因である。

    libvirt に対して patch を送った。accept された。然しこれが実際に
    distributions に反映されるのには時間がかかるだろう。workaround として IFS
    及び word を tmpenv にする事にした。

  * util (modifyOtherKeys): kitty は modifyOtherKeys を廃止する (reported by kovidgoyal) [#D1681]
    https://github.com/akinomyoga/ble.sh/issues/110#issuecomment-975732850

    * ok: kitty のインストーラのリンクからダウンロードできない。証明書がおかし
      い。と思ったら単に vm の時刻がずれていただけだった。

    * Ubuntu 20 の VM に残っていた kitty 0.20.3 では既に CSI > 1 u には対応して
      いる様子である。DA2R は 1;4000;20 である。然し何だか C-S-? に対する振る舞
      いが分からなかったので kitty 0.23.1 に上げてしまった。DA2R は 1;4000;23
      である。

    * 然し、ctrl+shift+a などが全く効かない。と思って気づいたのだが、どうやら
      kitty がそれを解釈している様である。C-S-up, C-S-down はスクロールで C-S-h
      は clear-screen か何かだろうか。C-S-a は無反応で C-S-g はちゃんと制御シー
      ケンスが送られる。つまり、kitty に割り当てられていない C-S-? に関してはちゃ
      んと送信する事ができる。然し、試した感じだと殆どの C-S-? は kitty によっ
      て上書きされている様である。

    * kitty の ctrl+shift+a を無効にする方法はないのだろうか? うーん。結局一つ
      ずつ解除していくしかない様だ。取り敢えず全部解除したらそれっぽい感じになっ
      た。

    * どの version から CSI > u と CSI < u が存在するのだろうか。というかそもそ
      も現在の version でも CSI >4;2m は効くという事なのだろうか。

    https://github.com/kovidgoyal/kitty/issues/4075
    https://github.com/kovidgoyal/kitty/commit/d6a43a7729d50b6f452ccdb93c746b0e115ebd38

    どうやら kitty から modifyOtherKeys が完全に削除される運びとなった様だ。発
    端は vim から kitty の modifyOtherKeys の振る舞いが変だという指摘を受けて、
    逆上して全削除という事に相成った様だ。

2021-11-12

  * main: "alias set=export" としている人がいる (reported by eadmaster) [#D1680]
    これは単に退避リストに set を追加するだけで良い。

2021-10-30

  * edit: WINCH の際の再描画 (reported by Johann-Goncalves-Pereira, guptapriyanshu7) [#D1679]
    https://github.com/akinomyoga/ble.sh/issues/142

    * 前回よりも幅が小さい時には行数は同じか増える筈なので遡って削除する。

    それ以外で問題が起こるのは幅が増える時という事になる。

    * 幅が増えた時、前回 rprompt が表示されている時、またはプロンプトが改行され
      ていない時(右端まで到達していない時) には、恐らく右端を通り越して出力した
      事による折り返しは起こっていないので、配置に変化はないと仮定する。

      と思って実装を確認したが WINCH に対する処理は ble/application/render によっ
      て実行しているので、このレベルだと実際の描画内容に基づいて text reflow が起
      こったかどうかを判定する術はない。うーん。panel::hasLineWrap の様な関数を追
      加する必要がある気がする。

      その様に考えると現在の描画内容に応じて遡るかどうかを決定するのは余り綺麗
      でない様な気がする。やはり下手に予測しようとするよりもオプションなどで振
      る舞いを一括で変更した方が良いのだろうか。

    ----

    うーん。然し端末によっては折り返しが起こったかどうかに関わらず、一番右端に
    文字があるかどうかで折り返しを判断するという実装も可能かもしれない。そう言っ
    た場合にもちゃんと動く様な信頼できる方法があってそれが単純であればその方が
    良い。その実装が複雑に成るのであれば、実際その様な端末が確認された訳でもな
    いので、其処まで気にしなくても良い。

    * info の折返し判定について。うーん。menu は別の描画機構を用いているので、
      また別に処理する必要がある。試してみた感じだと menu_style=dense の時には
      折り返しになっている様である。

      というかこれを考えるとそもそも menu の再配置を先に実行するべきの気もする。

    ---

    * 取り敢えず暫定的にオプション

      段々と大掛かりになって来た気がする。折返しが発生しているかどうかの判定を
      用いて遡るかどうか判定するのは今後対応する事にして、現在は暫定処置として
      オプションで一括で対応するという方向も考えられる。

      bleopt prompt_erase_previous_on_winch=xxx
      bleopt textarea_winch_reposition=xxx
      bleopt canvas_winch_reposition=xxx
      bleopt canvas_winch_position=here|prev|
      bleopt canvas_winch_redraw=here|back|clear

    うーん。時間がかかっているので取り敢えずはオプションを提供する事にする。
    選択肢として redraw-here, redraw-prev, clear を用意する事にした。

  * edit: inputrc キャッシュの読み出しでエラーが発生する (reported by laoshaw) [#D1678]

    .bashrc から単純に source ble.sh を実行すると以下のエラーが出るという事。

    -bash: /Users/user1/.cache/blesh/0.4/decode.inputrc.adict.xterm-256color.emacs: No such file or directory
    -bash: /Users/user1/.cache/blesh/0.4/decode.inputrc.adict.xterm-256color.vi_imap: No such file or directory
    -bash: /Users/user1/.cache/blesh/0.4/decode.inputrc.adict.xterm-256color.vi_nmap: No such file or directory

    直接 source ble.sh を実行した時に問題になっていて、1.3 の方法で設定した時に
    問題が発生していなかったのは、source ble.sh を実行した瞬間に既にユーザー設
    定がされていたかされていなかったかの違いだろう。なので、この問題は
    attach=prompt に特有の問題ではない。

    不思議なのは $cache_prefix.settings が存在して中身が一致している事まで確認
    しているのにも関わらず $cache_prefix.$keymap が存在しないという事態になって
    いるという事。不思議な事である。

    うーん。変だそんな事起こらない筈なのに。

    * done: 調べてみると copyfile でファイルを読み出すのに失敗すると、ファイル
      が正しくコピーされていないのにも関わらず settings が作成される様である。
      取り敢えず、copyfile に失敗したら settings は作成しない事にする。

    * done: どうやら bash-3.? の時には readfile が実際に読み取れていたとしても
      失敗する様になってしまっている。read -d '' で読み取っているので、ファイル
      に NUL が含まれない限りは終了ステータスが 1 になってしまうのである。これ
      はちゃんと対策をした。読み取れるか読み取れないかの判定は事前にしておく。

    | 然し依然として何故報告された事が起こったのかは不明である。
    |
    | * 或いは書き込み時に問題が発生した可能性もある? 然し、どうやってそれが起こ
    |   るのか。settings はちゃんと書き込まれている (と思われる) 事から考えると、
    |   ディレクトリが存在しないだとか書き込み権限が存在しないだとかそういう話で
    |   はない気がする。copyfile の中でも clobber しているので上書き拒否されたと
    |   いう訳でもないだろう (というか上書き拒否されたのだとしたら既存のファイル
    |   が存在した筈なので上記の様なエラーは発生しない筈である。)
    |
    |   また、上記の read の問題かとも思ったがこれは bash-3.? での実装である。エ
    |   ラーメッセージを見ると 0.4 になっている。と思ったが分かった。0.4 はそもそ
    |   も bash の version じゃなくて ble.sh の version である。つまり、報告者は
    |   bash-3.2 を使っている。

    報告者は bash-3.2 を使っている為に問題が発生している。

    更に suggestion が出ないという問題についてもこれで説明がつく。

  * make: macOS make-3.81 で contrib/contrib.mk の依存関係が正しく解決されない (reported by laoshaw) [#D1677]
    https://github.com/akinomyoga/ble.sh/issues/145

    当初はどういうエラーかと思ったが 3.81 から 4.3 に update したら直ったという
    のでやはり make が悪いのだろう。実際に手元に 3.81 をインストールして試して
    みた所問題を再現できた。色々試して workaround できる事が分かったのでその様
    に対処する事にする。

    [make インストールログ]

    * make-3.81

      そのままだと古い version の make はコンパイルできない。

      | /usr/bin/ld: glob/libglob.a(glob.o): in function `glob_in_dir':
      | /home/murase/.opt/build/make/make-3.81/glob/glob.c:1361: undefined reference to `__alloca'
      | /usr/bin/ld: /home/murase/.opt/build/make/make-3.81/glob/glob.c:1336: undefined reference to `__alloca'
      | /usr/bin/ld: /home/murase/.opt/build/make/make-3.81/glob/glob.c:1250: undefined reference to `__alloca'
      | /usr/bin/ld: /home/murase/.opt/build/make/make-3.81/glob/glob.c:1277: undefined reference to `__alloca'
      | /usr/bin/ld: glob/libglob.a(glob.o): in function `glob':
      | /home/murase/.opt/build/make/make-3.81/glob/glob.c:575: undefined reference to `__alloca'
      | /usr/bin/ld: glob/libglob.a(glob.o):/home/murase/.opt/build/make/make-3.81/glob/glob.c:726: more undefined references to `__alloca' follow

      以下のページによると glob.c の #ifdef を書き換えたら良い。

      https://stackoverflow.com/questions/51675200/install-older-version-of-gnu-make-in-ubuntu-18-04

    * make-3.82

      ble.sh に対して make-3.82 しようとすると segfault する。3.81 で問題になっ
      ていた物を削除しても問題は解決しない。検索してみると上記のコンパイルエラー
      と同じく glob 関係のバグの様である。

      https://stackoverflow.com/questions/52618055/gnu-make-3-82-on-ubuntu-18-04-segfault-in-glob-call
      https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/thread/XCYUF5BQLICUAAI3OM7EORCNOKEYP2MF/

      3.82 は 3.81 で行った修正をしてもしなくてもコンパイルできるが、どちらでコ
      ンパイルしたとしても segfault する。make-4.0 でやった様に
      GLOB_INTERFACE_VERSION を 2 に書き換えても、やはりコンパイルはできるが
      segfault する。

      https://git.savannah.gnu.org/cgit/make.git/commit/?id=193f1e81edd6b1b56b0eb0ff8aa4b41c7b4257b4

      で紹介されている修正を適用したらちゃんと動く様になった。ble.sh の
      contrib.mk はちゃんと動作する事が確認できた。

    * make-4.0

      4.0 についても同じ箇所でコンパイルエラーになる。== を >= に書き換えるとい
      う作戦は通用しなかった。GLOB_INTERFACE_VERSION を 2 に書き換えてみたらコ
      ンパイルできた。ble.sh の contrib.mk もちゃんと動く。

    * make-3.80 も 3.81 と同じ様にしてコンパイルできた。然し、make-3.80 は
      $(.FEATURES) を持たないので ble.sh GNUmakefile はもっと新しい version を
      使ってくれと文句を出力する様になっている。3.80 は 2002 の version で 19年
      も前の version なので切っても仕方がないだろう。

2021-10-21

  * main: "ble.sh: This is not an interactive session." (reported by andreclerigo) [#D1676]

    恐らく non-interactive session に於いて bash_profile から bashrc が読み込まれている。
    bash_profile なので bashrc であると検出できなくてメッセージが表示されている。
    何れにしても non-interactive session で読み込もうとしているのがいけないといえば行けない。

    →推測で修正してみたが直っていないそうだ。画面を見ると原因が分かった。GDM
    が Xsession を source して、 Xsession が /etc/profile 経由で .bashrc を呼び
    出しているという事の様だ。つまり、non-interactive script が source .bashrc
    をしている可能性を考慮に入れなければならない。この場合には、どう対処するべ
    きか。

    a warning を表示するというのは違う気がする。ユーザーは [[ $- == *i* ]] を考
      慮に入れて bashrc を記述する事を要求されているのである。なので、ble.sh を
      source する時にユーザー側で [[ $- == *i* ]] をチェックするか、或いは
      ble.sh 自身でも *i* をチェックして silent に return するというのは妥当で
      ある。

    b 或いは warning は全く表示しないという可能性? しかし、直接 bash ble.sh を
      実行された場合や、まるでライブラリであるかの様にプログラムから直接 source
      ble.sh を実行した場合などは、明らかに使い方を間違えているのだから warning
      を表示しても良い気がする。

    c profile, bashrc など経由で ble.sh が source した時には、それが
      non-interactive であっても警告は表示しない様にする。何しろ、profile,
      bashrc は interactive でも non-interactive でも source され得るのだから、
      non-interactive であったとしても使い方を間違えているとまでは言い難い。

      Bash が source する可能性があるのは以下である。

      - /etc/profile
      - ~/.bashrc
      - ~/.bash_profile
      - ~/.profile

      /etc/bashrc などはその他のファイルから呼び出されるので、これらはチェック
      しなくても良い? と思ったが、もしかすると何らかのスクリプトが直接 source
      /etc/bashrc みたいな事をしている可能性も考えられる。という事を考えると
      bashrc も除外リストに入れて置いた方が良いのではないかという気もする。うー
      ん。やはり除外リストに入れる事にする。

      - /etc/bashrc

2021-10-04

  * blerc: 含まれていない face が存在する (reported by Prikalel) [#D1675]
    https://github.com/akinomyoga/ble.sh/issues/140

    blerc も wiki も共に以下の2つが抜けている。

      argument_option
      cmdinfo_cd_cdpath

    * core-complete-def.sh で ble-color-defface を使っている。
      →直した。他に ble-color-defface を使っている箇所はない。

  * cmap: find/select が TERM によって定義されていたりいなかったりする [#D1674]

    今思ったのだが TERM によって find/select が存在したりしなかったりする事によって、
    keymap.emacs や keymap.vi のキャッシュに不整合が生じるのではないか。うーん。

    これによって keycode が不整合を起こすのではないか。
    $_ble_base_cache/keymap.{emacs,vi} は特に TERM に依存せずに共通の物を用いて
    いるので問題が発生する筈である。

  * prompt: prompt_ruler で空文字列に展開される文字列を指定すると無限ループになる? [#D1673]

    これは直ぐに直った。

    x fixed: 但し、属性だけ設定して何も出力しないプロンプトの場合、背景色等も適
      用されない。これは trace が実際に文字を出力する迄着色を遅延する為である。
      trace に最終的な属性を反映させるオプションを用意しても良いのではないだろ
      うか?  或いは既にその様なオプションはあっただろうか。

      うーん。trace の実装を確認してみたが、sgr が遅延されるのは clip の時のみ
      であって、今回は clip は指定していない。

      と、思ったら実際に出力するものを間違えていた。trace で解析した物ではなく
      て解析前の物を直接出力する様になっていた。これは修正した。

  * canvas (c2w.*.sh): テーブルの初期化に於いて *_ranges は ${!table[@]} に実は置き換えられる? [#D1672]

    但し、table に飛び地も記録している場合にはこの方法は使えない。
    canvas.c2w.musl.sh を見ていて思ったのだが、他には短縮できそうな物はなかった。

  * canvas.emoji: version 毎のテーブルを統合 [#D1671]

    c2w.emoji.sh: version 毎にテーブルを作るのではなくて、合成したテーブルを使っ
    た方がスペースを節約できるのではないか。

    実装し直した。

    x fixed: 出力結果を比較してみたが全然違う値になってしまっている。何故だろう
      か。うーん。実際に出力されているテーブル自体が何だか違う結果になっている
      気がする。何かデータがスキップされてしまっている可能性?

      念の為元のデータを確認しておく。U+1F7E5 (128997) が以前は 1
      (fully-qualified) だったのが現在は 0 になってしまっている。元のデータには
      ちゃんとこれは含まれている。最新のテーブルを確認すると値が消滅している。

      →と思ったらミスが見つかった。修正する。

    x fixed: emoji_version=13.1 で比較した所、以下の code point の EmojiStatus
      が変わってしまっている。

      -U+0270F 3
      +U+0270F 1

      元のデータを参照するとこれは unqualified でなければならない。何故値が変化
      してしまっているのだろうか? 新しいテーブルの実装を確認する。270F = 9999
      である。

      % うーん。最新のテーブルを見るとそもそも 0 になるべきの気がする。何故 1
      % になっているのだろうか。と思ったが、分かった。範囲としては 9994-10000
      % に含まれていて、9994 は 1 という事になっている。

      つまりテーブル生成の時点で何故か 9999 (unqualified) が 9994 (270A) に属す
      る形になってしまっているのが原因である。

      →これは gawk の中で < による比較が文字列比較になっていたのが原因だった。
      int() で整数に変換してから処理する様にした。

    o 13.1, 14.0 で比較した。ちゃんと一致している。
    o 11.0, 5.0, 2.0, 1.0 でもちゃんと一致する事を確認した。
    o 0.6, 0.7 は以前は対応していなかったが対応する事にした。
    o 14.0 も新しく対応した。

2021-09-27

  * 2021-09-24 decode: 起動中に入力した文字が遅延する問題 [#D1670]
    https://github.com/akinomyoga/ble.sh/issues/135#issuecomment-919088879

    起動後に最初に文字が入力された時に初めて処理される。

    | 但し、これはちゃんと対策できるのかどうか怪しい。うーん。何れにしても現在ど
    | の様にしてこの遅延が発生しているのかを調べる必要はある。
    |
    | * 先ずは単純な bashrc で再現するのだろうか。という事。単純な bashrc だとちゃ
    |   んと bashrc が終わった段階でバイトを受信する事ができている。
    |
    |   # bashrc
    |   sleep 1
    |   bind -x '"A":echo A'
    |
    | * 次の実験は ble/.hook は受信できているのかという事。実際に次の内容を受信し
    |   ている:
    |
    |   [recv: 101] [recv: 99] [recv: 104] [recv: 111] # echo
    |
    |   [recv: 192] [recv: 155] [recv: 91] [recv: 50] [recv: 59] [recv: 49]
    |   [recv: 82] # \e[2;1R
    |
    |   [recv: 192] [recv: 155] [recv: 91] [recv: 62] [recv: 56]
    |   [recv: 51] [recv: 59] [recv: 52] [recv: 57] [recv: 57] [recv: 48] [recv:
    |   48] [recv: 59] [recv: 48] [recv: 99] # \e[>83;49900;0c
    |
    |   うーん。
    |
    | * ble-decode-char: うーん。同じものをちゃんと受信できている。
    |
    |   [char: 101] [char: 99] [char: 104] [char: 111]
    |
    |   [char: 27] [char: 91] [char: 50] [char: 59] [char: 49] [char: 82]
    |
    |   [char: 27] [char: 91] [char: 62] [char: 56] [char: 51] [char: 59] [char:
    |   52] [char: 57] [char: 57] [char: 48] [char: 48] [char: 59] [char: 48]
    |   [char: 99]
    |
    | * ble-decode-key: 到達している。
    |
    |   [key: 101] [key: 99] [key: 104] [key: 111]
    |
    | * call-keyseq: 何も到達しない。
    |
    |   何が起こっているか分かった…。ble-decode-key に "echo" が届いた時点では、後
    |   に CPR や DA2R が控えている為にその場では処理されない。然し、CPR や DA2R は
    |   ble-decode-key を呼び出さないので、そのまま処理が止まったままになる…。と思っ
    |   たが何だか変だ。改めて調べる。
    |
    |   うーん。やはり既に _ble_edit_str はちゃんと echo という文字列を含んでいる
    |   様に見える。という事は call-keyseq とは別の経路でちゃんと文字列が挿入され
    |   ているという事か。

    うーん。分かった。ble-decode-key/.invoke-partial-match の中で文字入力がある
    時に _ble_decode_key_batch に文字入力をキャッシュしている。なので次に何らか
    の widget が呼び出される迄、キャッシュされたままになってしまう。

    なので、何処かでユーザー入力がないと確かめられたら
    ble-decode-key/batch/flush を呼び出す必要がある。ble-decode/.hook で呼び出
    すのが最も確実だろう。

    →直った。syntax highlighting の遅延もちゃんと見える様になった。というより
    今迄見えていなかったのはやはりこれによる問題だったのだろう。

  * util: CPR に timeout を入れる可能性 [#D1669]

    偶々何らかの都合で端末が返答を無視した時などの為に、SECONDS 等を参照して古
    い CPR handler は削除してしまうというのが必要になる気がする。handler 毎に設
    定しなくても、最後に request を出してから一定以上時間が経過していればその時
    点で flush してしまうというのでも良い気がする。

    一方で現実的な疑問としてその様に途中で CPR が消えたり、或いは端末が贈り忘れ
    たりという事がありうるのか、というのはある。例えば ssh を用いている限りはちゃ
    んと stream が hash で繋がっているし、途中で内容が抜けるという事はありえな
    い。TCP でそのまま繋がっているとしてもちゃんと途中で抜けがないかチェックは
    入っている筈である。udp で接続しているという事はありえない。まして、ローカ
    ルの端末・パイプで繋がっている時にはやはり途中で抜けるという事は考えがたい。

    これは安全策の為に一応実装しておくという程度の物である。

    * もしかすると現実的に ssh 切断→再接続→debugger API で tty を再構築みたい
      な事をすると、CPR が抜けるという事が発生するかもしれない。

  * canvas (c2w): akinomyoga-emacs / musl-wcwidth の自動判定にも対応する? [#D1668]

    voidlinux にそういえば変な標準ライブラリを使っている version があった。改め
    て確認すると musl というそうだ。musl wcwidth で検索したらソースコードが出て
    きた。この musl-wcwidth について wcwidth の結果を出力してみた所、何だか滅茶
    苦茶な結果が返ってくる。musl-wcwidth は 2012 で更新が止まっているので頻繁に
    変わる物という訳でもないだろう。

    追加で 25b6 をチェックすれば emacs は判定できる。

    musl の判定は Unicode versions の判定用の幅も使えば判定できるのではないかと
    いう疑惑。どうせどの Unicode version にも合わない様な変な振る舞いの文字があ
    るのではないかという気がする。

    * その前に musl-wcwidth の実装をしなければならない。musl は元のコードと同じ
      様にすればコンパクトにできるが、ライセンス的に面倒なので振る舞いから再構
      築するのが良い気がする。やはり2分法で実装するか、或いは…

      musl が使っているのはどういう実装だろう。

      例えば 256x256 に分けて考えると、256のパターンを 8 整数 (64x8 = 512 =
      256x2bits) で表して、更にそれに対して同じ物を潰して higher 8bit から、パ
      ターンへの参照を作る。と思ったが、musl の実装を見る限りは曖昧な部分などを
      積極的に潰す事によってテーブルを小さくしている様な気がするので、一般のア
      ルゴリズムとしては可逆でそんなに簡単に圧縮できるとは思えない。musl がその
      様に圧縮されているという前提知識があるので同じ方法を取る事もできるかもし
      れないが、そうすると結局ソースコードをそのまま真似た形になってしまい、ま
      たライセンスの問題になる。

      やはり変な事を考えるよりも愚直に二分法なり何なりで実装するのが最もコンパ
      クトな気がする。一方で、効率を考えたら二分法よりも良い方法はあるだろうか。
      結局 trie の様な構造を考えることになるのだろうか。

      うーん。何れにしても二分法を使う事にする。U+XXXX width を出力した表からテー
      ブルを作成するコードがあれば今後も便利であろう。改めて make_command.sh の
      内容を確認する。

    * musl の判定に既存の文字が使えるかどうかの確認

      25bd 25b6 に対しては両方とも幅 1 になる。

      Unicode version 判定に用いているコードに関しては 2 2 2 2 0 2 1 1 1 1 1 1 2 という数列を返す。

              | -----Unicode EAW+GeneralCategory---------------|musl
      U+9FBC  | -1  2  2  2  2  2  2  2  2  2  2  2  2  2  2 2 | 2
      U+9FC4  | -1 -1  2  2  2  2  2  2  2  2  2  2  2  2  2 2 | 2
      U+31B8  | -1 -1 -1  2  2  2  2  2  2  2  2  2  2  2  2 2 | 2
      U+D7B0  | -1 -1  2  2  2  1  1  1  1  1  1  1  1  1  1 ? | 2 何故か動いていない?
      U+3099  |  2  2  2  2  2  2  2  0  0  0  0  0  0  0  0 0 | 0
      U+9FCD  | -1 -1  2  2  2  2  2 -2  2  2  2  2  2  2  2 2 | 2
      U+1F93B | -1 -1 -1 -1 -1 -1 -1 -1 -1  2  2  2  2  2  1 1 | 1
      U+312E  | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  2  2  2  2  2 2 | 1
      U+312F  | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  2  2  2  2 2 | 1
      U+16FE2 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  2  2  2 2 | 1
      U+32FF  | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  2  2 2 | 1
      U+31BB  | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  2 2 | 1
      U+9FFD  | -1 -1  2  2  2  2  2 -2 -2 -2 -2 -2 -2 -2 -2 2 | 2

    * 何故 D7B0 が動かなくなっているのだろう。現在これを出力しようとすると常に
      0 が表示される。

      と思ったら _ble_unicode_c2w_custom で上書きされてい
      た。_ble_unicode_c2w_custom を一旦削除して判定して、終わったら復元して
      _ble_unicode_c2w_custom に含まれるコードだった時に警告を出力する様に変更
      した。

  * 2021-08-31 wiki, blerc: import_path [#D1667]

    done: bleopt import_path の記述が抜けている。blerc にもない。

    他にも抜けている物がないか確認するべきなのでは。

    done: grapheme_cluster
    done: emoji_opts
    ok: menu_desc_multicolumn_width これは現在対応中で後で載せる。

    取り敢えず一つずつ説明を追加していくのが良い。

    * 一方で blerc で抜けている物はもっと沢山ある。

      done: keymap_vi_imap_undo
      done: keymap_vi_keymodel
      done: keymap_vi_operatorfunc
      done: keymap_vi_search_match_current
      done: term_vi_smap
      done: decode_macro_limit
      done: idle_interval
      done: syntax_debug

      これらについては wiki から説明を拾ってくれば良い。

    * done: vim_airline_* は全く説明書にない

      vim_airline_theme だけは blerc にある。

  * edit: powerlevel10k の prompt_add_newline を実装する (motivated by Barbarossa93) [#D1666]
    https://github.com/akinomyoga/ble.sh/issues/135#issuecomment-927284636

      prompt_ruler='empty-line'
      prompt_ruler='-'
      prompt_ruler=$'\e[38;5;242m-'
      prompt_ruler='---='

    等に対応する。これは実はそんなに難しくないかもしれない。対応した。

    対応する powerlevel10k に於ける設定名は以下の通り

      POWERLEVEL9K_PROMPT_ADD_NEWLINE=true/false
      POWERLEVEL9K_SHOW_RULER=true/false
      POWERLEVEL9K_RULER_CHAR=-
      POWERLEVEL9K_RULER_FOREGROUND=242

    ble.sh では prompt_ruler に ANSI seq を指定できる様にしたので色も一つの変数
    で済む。

  * [外部 bashrc] Void Linux で文字幅計算がずれる (reported by Barbarossa93) [#D1665]
    https://github.com/akinomyoga/ble.sh/issues/135

    と思ったがそもそもキャッシュしていない様に見える。という事は何を意味するの
    か。うーん。prompt 計算のキャッシュが残っているという事だろうか。そんな気が
    する。試してみる事にする。→プロンプトの trace_hash に char_width_mode も入
    れて置く事にした。char_width_mode=west にしても前の設定が残っている問題は解
    決した。

    * 2021-09-26 これは結局 Barbarossa93 の設定に含まれる getCPos で printf
      DSR(6) & read CPR していたのが原因だった。この為に ble.sh の遅延処理して
      いる CPR の処理と getCPos の CPR の処理が入れ替わって双方で誤った結果を生
      み出しているというのが原因であった。

      更に、もう一つの報告された問題である入力した文字列が失われるという問題に
      ついても、この getCPos が CPR 待ちで読み取っているが為に起こっている問題
      であった。この問題は ble.sh をロードしなくても、単に bashrc で時間がかか
      るだけで再現するという事が分かった。

    * 2021-09-26 PROMPT_COMMAND の中でこの様な事をしても大丈夫な様に対策する?

      そもそも技術的に可能なのか分からない。

      a PROMPT_COMMAND の呼び出し前の段階でユーザー入力があるかどうかを確認して、
        もしユーザー入力があるのであれば一旦その時点で抜けるという事が必要にな
        る気がする。然し、現時点で既にその様な実装になっている様な気もする。こ
        れは全然対策になっていない。

        つまり、textarea#render に入る直前までに返答が返ってくれば処理もできる
        が、そうでなければ PROMPT_COMMAND の中で stdin を読み取ろうとした時に、
        返答が来るまで待って其処で CPR が読み取られてしまうという事になる。

      うーん。やはりこれに対する対策は原理的に困難である様な気がする。

      b 或いは、terminal-test.buff を sync (timeout 付き) で処理する可能性もある。

        然し、端末が CPR に対応していない時に固まってしまう。

        timeout を入れたとしてもその分遅延が生じる事になる。ble.sh では初期化の
        遅延を可能な限り減らそうとしているので 50ms でも待つ等という事はしたく
        ない。それに timeout した時に、それよりもずっと後になって返答が返って来
        た時にまた問題が生じるかもしれないので、timeout はもっと長く設定しなけ
        ればならない気がする。もしくは、timeout してしまったら何らかのエラーと
        して処理を中断するというのが普通のシェルプログラムの動作として望ましい
        が、対話セッションの時にはセッションを抜けるという訳にも行かない。

        もし本当に位置を特定したいのであれば、やはり ble.sh の様に非同期で処理
        する事が必要で、その為には line editor の event loop に登録するしかない。
        ble.sh ではその為の枠組を用意しているので、本当にそういった処理を実施し
        たいのであれば、ble.sh の枠組みを経由でカーソル位置を取得してもらうしか
        ない。readline に至っては robust な方法はない様な気がする。一応、
        readline の動作は高速なので変な遅延が生じる可能性は少ないし、そもそも
        readline が返答を必要とする様な要求を出さないので問題が起こる事は余りな
        いのだろう。

      結局技術的に考えても困難であるし、これの対策はしない事にする。

      対策しないとするとどれだけの範囲で問題が生じるか調べておく必要がある。

        https://github.com/search?q=filename%3Abashrc+getcpos
        https://github.com/Barbarossa93/Muspelheim/blob/c9ea8ffd83ab5c85da47b5c36f39b3ec97b96230/.config/bash/bashrc

      検索すると以上の様に報告者の bashrc しか見つからないので、この getCPos を
      bashrc の中で使うという手法は報告者独自のものであると推察される。なので、
      そんなに多くの設定で使われている物という訳でもないのだろうという気がする。
      うーん。以下で検索すると PROOMPT_COMMAND で CPR を取得するのは実は沢山存
      在している様だ。

        https://github.com/search?q=filename%3Abashrc+PROMPT_COMMAND+%22%5B6n%22
        https://github.com/ScoreUnder/scripts-and-dotfiles/blob/f69f2f11739342a7c46fb38a9be2f5a5c803a438/dotfiles/.bashrc.m4
        https://github.com/safocl/safocl_profiles/blob/31ce40e9ff4619d1099c4f95c1f717e8a9b389fb/.bashrc

    * [再現不可] urxvt: C-l をした直後に何故か反応が遅くなる

      C-l の直後以外では問題はない様に見える。うーん。もしかすると C-l の直後以外
      ではプロンプトの更新がされていない? 単にプロンプトの計算に時間がかかってい
      るという事?

      以下の PS1 で再現する

      PS1=$'\[\e[38;5;1m\]┏━[\e[38;5;7m\]\w\[\e[38;5;1m\]]\n\[\e[38;5;1m\]┗━━ \[\e[38;5;8m\]■ \[\e[38;5;7m\]'

      というか更に以下の PS1 でも再現する

      PS1=$'\e[31mA '

      うーん。これは結局再現する事はできなかった。改めて urxvt で提供された
      bashrc を実行してみたがそれでも駄目だった。何か urxvt か或いは別の設定が
      壊れていたのかもしれない。

    * 2021-09-26 workaround を提示したら思っている動作と異なるとの報告が来た。
      改めて見てみると、元のコードでしたのは「一番左にいなかったら改行を追加す
      る」ではなくて「一番上にいなかったら改行を追加する」という物だった。

      少し考えてみたがよく分からない。困難の気がする。powerlevel10k にその機能
      があるというので p10k を 6n で検索してみたが、特にその様な文字列は含まれ
      ていない様だ。或いは、powerlevel10k はまた異なる手法を用いているのかもし
      れない。どうやら

        POWERLEVEL9K_PROMPT_ADD_NEWLINE

      というのが該当する設定の様である。うーん。これを使っている所を調べると

        [[ $P9K_TTY == old ]] && { unset _p9k__empty_line_i; _p9k__display_v[2]=print }

      というのを設定している。P9K_TTY は preexec で old に設定されている。

        if [[ $_p9k__preexec_cmd == [[:space:]]#(clear([[:space:]]##-(|x)(|T[a-zA-Z0-9-_\'\"]#))#|reset)[[:space:]]# &&
              $_p9k__status == 0 ]]; then
          P9K_TTY=new
        elif [[ $P9K_TTY == new && $_p9k__fully_initialized == 1 ]] && ! zle; then
          P9K_TTY=old
        fi

        if [[ $1 == (clear-screen|z4h-clear-screen-*-top) ]]; then
          P9K_TTY=new
          _p9k__expanded=0
          _p9k_reset_prompt
        fi

      うーん。これを見ると powerlevel10k は単に直前のコマンドを見ている様だ。具
      体的に座標を抽出している訳ではない様だ。これなら実装できなくもないが…。

  * canvas: 文字幅判定の為の CPR は internal 状態で実行したい [#D1664]

    CPR が画面に出力されてしまうのは stty echo の時に DSR(6) が出力されるから。
    ちゃんと internal state の時に CPR が出力される様にすれば防げるのではないか。
    後で何処から出力されているかを確認する。

    と思ったが、CPR の遅延があるのでそれによって表示されているだけかもしれない。
    その場合には対策できないかもしれないができるだけ早い段階で DSR を送信してお
    く事はできる。

    うーん。或いは、コマンド実行が終了した時点で char_width_mode=auto もしくは
    char_width_version=auto になっている時に初めて要求を出すというのは一つの手
    である。

    * done: refactor: 関数名を変更する c2w+ -> c2w:

2021-09-26

  * edit (command-help): use ble/util/assign/.mktmp to determine the temporary filename [#D1663]

    これは ble/util/readfile の用例を確認している時に気づいた事。
    修正した。ちゃんと動いている様な気がする。

2021-09-23

  * decode: [openSUSE] bash-it 側の検証に際して色々問題が生じている (reported by cornfeedhobo) [#D1662]
    https://github.com/Bash-it/bash-it/pull/1884

    https://web.libera.chat/?channel=#bash-it ここの議論はすぐ消滅する
    | [8:27:38] → akinomyoga has joined
    | [8:31:20] <akinomyoga> Hmm, it seems everything I wrote has been lost after I
    | restarted the web browser. I don't get used to IRC, so I didn't know this
    | behavior. So there is no log of the channel?
    | [9:55:21] <akinomyoga> I summarized the current situation at
    | https://github.com/Bash-it/bash-it/pull/1884#issuecomment-923489130
    | [12:07:33] ← akinomyoga27 has left (Quit: Client closed)
    | [12:08:01] → akinomyoga27 has joined
    | [12:08:07] ← akinomyoga27 has left (Client Quit)
    | [13:45:22] <cornfeedhobo> akinomyoga: hello again
    | [13:45:45] <cornfeedhobo> akinomyoga: yeah, irc doesn't keep history. but i
    | have a record of it
    | [13:46:02] <akinomyoga> Hello
    | [13:46:06] <akinomyoga> Ah, OK
    | [13:47:29] <cornfeedhobo> ah, okay, so maybe i can explain the PROMPT_COMMAND
    | situation at least
    | [13:48:30] <akinomyoga> I have summarized my situation in the GitHub issue
    | page. Maybe you can first take a glance at the comment and just explain the
    | difference of the setups.
    | [13:50:28] <akinomyoga> Unfortunately I will have a meeting 10 minutes
    | later. So I think I cannot respond for one or two hours after that.
    | [13:50:28] <cornfeedhobo> your comment from an hour ago sums up what I was
    | assuming was happening
    | [13:50:47] <cornfeedhobo> okay, no worries. sorry i couldn't reply
    | sooner. today was filled with meetings.
    | [13:52:09] <akinomyoga> OK! Nice! Then I will look for a workaround
    | [13:52:51] <cornfeedhobo> awesome! thanks for working through this. your
    | attention to detail is impressive.
    | [13:53:04] <akinomyoga> thank you!

    * done: home/end が効かない。これは結局 find/select を認識する事にした。本
      当に openSUSE の workaround の為だけの変更である。Ref #D1648

    * done: "preexec が壊れる" という文句について。Ref #D1650

    * done: set-mark 及び history-search-{for,back}ward が nmap で対応されてい
      ないというエラーメッセージに対する苦情 Ref #D1651

    * done: /etc/inputrc{,.keys} が大量に設定を行っている為に初期化が遅い問題
      Ref #D1652

    * done: error messages on openSUSE ... これは openSUSE における既
      知の問題である。これに関する対応は既に openSUSE の最新版には反映
      されているので気にしなくて良い。もし今後も openSUSE 15.2, 15.3
      のユーザーから報告があるのであれば、ble.sh の側で何らかの
      workaround を追加する必要があるかもしれない。

      うーん。結局これは openSUSE の問題だし、Tumbleweed では問題は発生しないの
      だからわざわざ対応しなくて良い気がする。これは無視する。

      うーん。或いは openSUSE 15.2, 15.4 を検出して inputrc を off にしても良い
      かもしれない。然し、これは他の WA がちゃんと動く事を確認してから対応する
      方が良い。そうしないと WA がちゃんと動くかどうかの feedback を得られない。
      これは最後に処理する。

    最終的に openSUSE /etc/inputrc.keys が存在して変な keyseq を含んでいる場合
    には bind の出力は参照せずに .inputrc を解析する様に変更した。

  * edit (widget history-search): support empty=emulate-readline (motivated by jainpratik163) [#D1661]
    https://github.com/akinomyoga/ble.sh/issues/139

    history-search-{for,back}ward は検索なので一致場所にカーソルを置くという仕
    様に今までしてきた。また、空文字列検索の時には空文字列による検索を継続する
    為に、敢えてカーソルを先頭に置く様にしていた。しかし、readline の振る舞いを
    改めて確認した所、空文字列の時には恰も通常の history-prev を使用して移動し
    たかの様に振る舞っていながら、空文字検索を継続しているのだという事が判明し
    た。仕方がないので ble.sh でもやはり空文字列検索であっても内部的には
    nsearch 状態に突入して、但しカーソル位置は末尾にするという具合に変更する事
    にした。

    改めて思うに Ref #D1517 https://github.com/akinomyoga/ble.sh/issues/101 で
    要望にあった"2. I would like the cursor to move to the end of line while
    searching with Up/Down." というのはこの振る舞いに関連しての事だったのではな
    いかという気がする。まあ、今となっては考えても仕方のない事なのかもしれない。

    [追加]

    * 対応したと思ったら動かない。と思ったが、prior に history-search-backward
      を束縛しても、nsearch keymap の中で prior が束縛されていないので、続けて
      prior が押されると一旦 nsearch を抜けて改めて nsearch が開始される為に、
      空文字列検索を続ける事ができないという状態になっていた。nsearch keymap に
      も prior/next を束縛する事にした。

    ところで、ble.sh は複数行編集に対応しているので、その意味での prior/next を
    解釈する方が本当は理に適っているのでは? と思ったが、複数行編集している時に
    はその複数行で履歴検索したいという事はないだろうし、代わりに現在カーソルが
    ある行の文字列を履歴から検索するとしても、折角複数行のコマンドを編集してい
    るのに別のコマンドに移動してしまう事になるので変な感じがする。という事を考
    えれば、実は「複数行の時にはページ移動で、単一行の時は履歴検索」という
    widget として実装すれば良い気がする。これはまた別項目として残す事にする。

2021-09-22

  * README: roadmap [#D1660]

    発音の部分が取ってつけた様なので紹介文を書いてみた。

    然し何だかふざけた感じになってしまった。特に日本語に関してはどのような言葉
    遣いで書いたら良いのか分からない。日本語では説明書にそういう話は書かない気
    がする。お菓子の説明にはそのお菓子がどのように成立したかなどの説明があった
    りする気がするのでそんな感じで書くのだろうか。真心込めて作りました的な説明
    になってしまってそれも何だか変な感じである。とにかく説明書に書くような内容
    ではない気がする。

    % 縁起: 端緒は二〇一三年三月の末、とある `zsh-syntax-highlighting` の記事に触
    % 発され `.bashrc` の片隅で始まった実験でありました。数百行の設定で不完全でも
    % 何か着色ができようという当初の安易な期待は即座に裏切られ、行エディタを全て
    % 再実装するより他にないことが露見したのであります。一個の独立したスクリプト
    % として開発することに改め、名を ZLE (Zsh Line Editor) から借り、シェルで書か
    % れたことを示す `.sh` を付して `ble.sh` としました。二週間の実験は、実用に堪
    % える完全な行エディタをスクリプトで実装することが可能との結論に終わりました。
    % 本格的な実装が始まったのは二〇一五年二月のことです。同年十二月には行エディ
    % タとしての機能は大方出揃い、これを以て最初のバージョンとしました。

    結局、新しく history and roadmap という section を README に加える事にした。
    発音に関する説明は結局 README の上部にそのまま残っている。

  * README: sabbrev の例で \word を薦めるのが良い気がする [#D1659]

  * README: zsh-abbreviations なる物は存在しない [#D1658]

    https://unix.stackexchange.com/questions/6152/zsh-alias-expansion
    https://qiita.com/matsu_chara/items/8372616f52934c657214
    https://github.com/olets/zsh-abbr

  * repo: ディレクトリ構造の整理。docs, make ディレクトリの作成 [#D1657]

    * done: make ディレクトリに Unicode 関係のテーブルの生成コードを移動する?

      現在は memo/ 以下にファイルを持っているが何だか違う気がする。他に leakvar
      の whitelist のファイルなども make 以下に移動した方が良い様な気がする。

      make ディレクトリという名前で良いだろうか。tool というディレクトリを一時
      作りかけた。うーん。或いは memo の下にサブディレクトリを作る? うーんやは
      り make で良い気がする。

    * done: ext/mwg_pp.awk も make に移動してしまって良い気がする。此処で問題になるか
      もしれないのは GNUmakefile の更新に失敗するかもしれないという事? 然し
      make の最中に checkout したりする事はないし、mwg_pp.awk が移動していれば
      既に GNUmakefile の方もそれに応じて書き換わっているし、GNUmakefile の方が
      書き換わっているのであれば mwg_pp.awk も移動している筈なので問題は起こら
      ない筈。

    * reject: docs ディレクトリに雑多のファイルを移動する?

      x GitHub のシンボリックリンクの問題

        色々のファイルを docs ディレクトリに押し込めようと思ったが、git clone
        した時に分かりにくいので LICENSE と README に関してはせめて symbolic
        link を置こうと思ったが…GitHubのインターフェイスだと symbolic link を
        開いても中身の文字列が表示されるだけで、その指し示している先にジャンプ
        する事ができない。これはかなり不便である。検索したが余りそういう要望は
        ない様である。以下に何やら要望があるが、そもそもこの repository を
        GitHub が見ているのかどうかも謎である。

        https://github.com/dear-github/dear-github/issues/156

      x GitLab など他のサービスだと docs 以下にファイルを置いても認識してくれな
        いかもしれない。

      これは一先ずは棄却する。後にもっとファイルが増えた時に気になれば対処する。

    * done: ChangeLog.md, Release.md ぐらいは docs に移動しても良いのかもしれない。

      多くのファイルは現在の場所に取り敢えず残すとしても memo/ChangeLog.md や
      memo/Relases.md に関してはまた docs/ 等の下にある方が分かりやすい筈である。
      此処での問題は ChangeLog.md を移動すると rebase がしにくくなるという事。
      まあ、これは一気にやってしまえば問題はない。

    * keymap の下にある物も何処かのタイミングで lib/* に移動したい。0.5 に変更
      する時に移動しようとも思っていたが、0.4 がいつ完成するか分からないし、コー
      ドの移動を一度に実行すると code frequency にまた大きな spike が立ってしま
      うので、release 等とは関係なく思い立った時に実行した方が良いのかもしれな
      いとも思う。

    何れにしても既存の物についてのディレクトリ構造の変更は、他の変更が pending
    になっていない綺麗な状態で実行するべきである気がする。現在は Unicode 関係の
    テーブル生成についても、中途半端である。少なくとも c2w 関連の実装が一区切り
    してから考えるべきことである様に思われる。

  * [棄却] util (readfile): bash-5.2 に $(< xxxx) without fork が実装された [#D1656]
    ble/util/readfile にはこれを使うのが良いのではないか。後で速度についても確認する。

    | bash-5.1
    |
    |    201.567 usec/eval: ble/util/readfile var sig.h (x500)
    |   1070.529 usec/eval: var=$(< sig.h) (x100)
    |   1078.159 usec/eval: var=$(< sig.h) (x100)
    |   1067.909 usec/eval: var=$(< sig.h) (x100)
    |   1078.159 usec/eval: var=$(< sig.h) (x100)
    |
    |   process-count ... 200位増えている
    |   $ echo $(echo $BASHPID)
    |   29617
    |   $ ble-measure 'var=$(< sig.h)'
    |   $ echo $(echo $BASHPID)
    |   29810
    |
    | bash-5.2
    |
    |    205.423 usec/eval: ble/util/readfile var sig.h (x500)
    |    205.131 usec/eval: ble/util/readfile var sig.h (x500)
    |    204.201 usec/eval: ble/util/readfile var sig.h (x500)
    |     29.551 usec/eval: var=$(< sig.h) (x5000)
    |     29.339 usec/eval: var=$(< sig.h) (x5000)
    |     29.491 usec/eval: var=$(< sig.h) (x5000)
    |     29.623 usec/eval: var=$(< sig.h) (x5000)
    |     29.535 usec/eval: var=$(< sig.h) (x5000)
    |
    |   $ echo $(echo $BASHPID)
    |   29985
    |   $ ble-measure 'var=$(< sig.h)'
    |   $ echo $(echo $BASHPID)
    |   30010

    現在の実装よりも圧倒的に高速である。但し、現在の実装と比べて問題があるとす
    れば改行を保持する事ができないという事である。

    うーん。readfile の仕様として自動的に末尾の連続改行は一つにまとめ、改行がな
    い時は改行を加えるという事にしても良いのかもしれない。と思ったが、
    test-util.sh に末尾改行を保持する事を要請するコードが存在している。

    後、互換性を考えると末尾の連続改行については未規定という様にしないと、古い
    version で逆に末尾改行を除去するのに逆に処理を追加しなければならなくなる。

    色々試してはみた物の速度的にも mapfile と比べてそれほど違うという訳でもない
    様な気がしてきた。そもそも readfile の時点でそんなに遅い訳でもない。という
    事を考えると、わざわざ改行が消えてしまう $(<) を使う必要はない様な気がする。

  * Makefile: 単なる git clone & make install でちゃんとインストールできる様にしたい [#D1655]
    https://github.com/Bash-it/bash-it/pull/1884#issuecomment-922615431

    特に --recursive をユーザーが指定しなかった時。
    現在の実装だと contrib が存在しなかった場合には一回の make だけだと
    contrib 以下のインストールするべきファイルが認識されずにインストールされない。
    contrib を checkout した時には改めてそれを読み直す様にさせる必要がある。

    うーん。これは GNUmakefile を contrib/.git に依存させれば良いのでは?
    という気がする。但し、何か変な事が起こるかもしれないので、
    何回か手元で実行して確認する必要がある。

    うーん。駄目だ最初からやり直してはくれない。実際に Makefile が書き換えられ
    る事がないと駄目という事だろうか。contrib の方に .mk を作成してそれを読み込
    む様にしなければならないのだろうか。取り敢えずその様に実験してみる事にする。

  * prompt: do not evaluate PROMPT_COMMAND for subprompts [#D1654]

    #D1654 で観察していて気づいたが現在のコードだと subprompt に対しても
    PROMPT_COMMAND を実行している。それは何だか変なので subprompt に対しては
    PROMPT_COMMAND は実行しない様に修正する。

    これは後で ble-0.3 にも適用したいので commit を分ける事にする。

  * vi: ? や / が動かなくなっている [#D1653]

    * 表示が滅茶苦茶になってしまう。
    * そもそもプロンプトも表示されていない

    一方で nsearch で入力させる機能はちゃんと動いている。両者で何かが違うという
    事だろうか。→と思ったら nsearch は read -ep を使っていたのだった。

    昔は確かに動いていた筈なので先ずは bisect する所から始めるべきの気がする。
    手動 bisect の方法について調べながら実行する事にする。
    手動 bisect の結果以下が問題の commit であると判明した。

    | commit cf8d94930af5a57e7ae9309a16eca7fc3e3479ad (refs/bisect/bad)
    | Author: Koichi Murase <myoga.murase@gmail.com>
    | Date:   Mon Jun 7 12:13:56 2021 +0900
    |
    |     prompt: track dependencies and detect changes

    プロンプト計算に失敗しているという事だろう。

    うーん。大きな変更すぎて原因はコードを見ても分からない。
    恐らく補助プロンプト関係で何か不整合が起きているという事。
    例えば prompt update ではスキップしているのに描画の際には考慮に入っている等。

    うーん。rps1, status を無効にしてみたがそれでも問題が発生する。

    * そもそも ps1 自体表示されていない。
      _ble_edit_PS1 は値としてはちゃんと ble/prompt/update の中から見えている。

      うーん。_ble_prompt_ps1 の更新は prompt_ps1 を参照している筈。それなのに
      subprompt の時と prompt の時で解析結果が異なる。subprompt の時には空の結
      果になってしまっている。何故?

      そもそも ble/prompt/unit:_ble_prompt_ps1/update が呼び出されていない。
      うーん。ohashref が literal 0 になってしまっている。

    * そもそもプロンプトを一切表示しない場合でも表示が乱れてしまっている。
      panel の高さ計算でミスしている可能性? 例えば復元した時に不整合が生じている等。
      というか subprompt に入る段階でも既に何だか変な事になっている。

    分かった。_ble_prompt_ps1_data の形式が変わったのに vi.sh の中での
    _ble_prompt_ps1_data の初期値をそれに合わせて変更するのを忘れていた。
    古い _ble_prompt_ps1_data の初期値が更新済みのデータとして解釈されて
    prompt の再計算が行われないまま誤ったデータとして座標計算などが行われていた。
    →この初期値の形式を修正するだけで全て動く様になった。

  * decode: 巨大 inputrc の翻訳内容をキャッシュする [#D1652]
    https://github.com/Bash-it/bash-it/pull/1884#issuecomment-923489130

    /etc/inputrc{,.keys} が大量に設定を行っている為に初期化が物凄く遅い問題に
    ついて。これは bash の既定の binding に対する cmap cache だけではなくて、
    前回の ble.sh 実行時の cmap cache も保持する事で解決する様な気もする。と
    いうか寧ろ前回の ble.sh 実行時の状態を使って cmap cache を保持するべきの
    気もする。

    [現状]

    現在どの様にキャッシュしているか確認する。

    例えば decode.readline.50108.vi-insert.txt 等に対して保存されている。これ
    に対してユーザーが保存した物も付け加えるのはどうだろうか。と思ったが
    emacs, vi-insert, vi-command で分けて保存しているのはどういう事だろうか。
    うーん。emacs/vi-insert/vi-command の三組で ble.sh の keybinding の状態が
    定まる。という事を思うと、ユーザーの inputrc の状態を保存するとしてもやは
    り三組を記録する必要がある。そして、それらの保存されたファイルと現在の状
    態に相違がない時に限り保存された keybinding の状態を復元するという振る舞
    いにする。

    --noinputrc で分岐している部分を確認する。noinputrc が指定されている時に
    は以下の変数に値を設定している。これらの変数に値が設定されていない時に限
    り現在の状態が読み取られる。

      _ble_builtin_bind_inputrc_done=noinputrc

        これは ble/builtin/bind/initialize-inputrc で参照される。ユーザーの
        inputrc を読み取る関数。

      _ble_builtin_bind_user_settings_loaded=noinputrc

        これは現在の bind -vetc の出力を元に keybinding を設定する関数
        ble/builtin/bind/read-user-settings 及び
        ble/builtin/bind/.reconstruct-user-settings で処理される。

    うーん。この .reconstruct-user-settings の中で呼び出している各ステップで
    どれだけ時間がかかっているのかを計測するのが先ずはする事の気がする。もし
    かすると bottleneck を見誤っているかもしれない。

    実際に時間を計測してみると、比較対象と現在の状態の両方を gawk に入力する
    為に集めるので 0.04s かかっている。gawk は 0.016s で終わっている。その後
    の ble-bind で 0.77s 消費している。

    [修正]

    * ok: 入力情報を集める部分については恐らく設定の量に依存しないし、入力情報
      が前回と一致しているかどうかというのを判定するのにまた時間がかかるだろう
      から、キャッシュの同一性の判定は gawk で処理した後に行うべきの気がする。

    * done: 後段の最も時間がかかっている部分について内容を確認する。bind -m xxx
      'xxx' というのが約200行続いている。これについてキャッシュできないか考える
      べきなのだろう。この時点での内容を何処かに保存しておいて…

      % うーん。そもそも初期化の順序がどうなっているのか分からない。この関数の
      % 呼び出しが初期化時の物であれば、この時点での keymap の状態は標準の状態
      % になっていると考えられるので、"$settings" の内容だけでこれを eval した
      % 後の状態が確定するのでキャッシュを読み込んで終わりにする事ができる。一
      % 方で、別の場所から呼び出された時には、更に別の設定が keymap に加えられ
      % ている可能性もあるので、不用意にキャッシュする事はできない。
      %
      % →という事を考えると初期化時の呼び出しの時だけキャッシュする様に、呼び
      %   出し元から特別な opts を指定する等して区別しなければならない。
      %
      % もう一つの事はユーザー設定をキャッシュする為には emacs.sh 及び vi.sh を
      % 読み込まなければならないという事である。そうすると keymap の遅延読み込
      % みが全く為されなくなり意味がない。
      %
      % * うーん。bind の遅延には対応していたのだったか。もし bind の遅延に対応
      %   していたとすると更に話はややこしくなる。遅延した物を最後にひとつにま
      %   とめてその上でキャッシュするという様な仕組みにする必要が出てくる。然
      %   し、それは複雑すぎる様に思われる。
      %
      %   →うーん。遅延されている。という事を考えると 0.7s かかっているのは実
      %   際の ble-bind ではなくて、それをキャッシュする段階でかかっている時間
      %   という事になる。
      %
      %   というかその前にそもそも遅延がどの段階で実装されているのかを確認する
      %   必要がある→うーん。内部関数の ble-decode-key/bind の呼び出しがキャッ
      %   シュされている。この関数は decode 済みの keys 値と実際のコマンド名
      %   (ble/widget/xxxx など) を受け取っている。という事を考えると、時間がか
      %   かっているのは decode の部分なのだろう。
      %
      % * 元の標準設定が切り替わった時にはどうするのか。その時にもキャッシュを
      %   更新しなければならない。

      どうも時間がかかっているのは bind -m xxx yyy の yyy に含まれる keyseq
      -> keys への翻訳の様に思われる。keymap は最初は初期化されていないと思わ
      れるので、翻訳結果は全て ble-decode-key/bind の中でキャッシュされる。そ
      のキャッシュ結果を何処かに保存しておけば良いという事になるのではないか。

      翻訳過程をキャッシュしているので cmap 及び rlfunc 表の更新だけを気にし
      ていればキャッシュの一貫性は保てる。

      確認: 本当に初回呼び出しでは全ての keymap が未登録状態か? →実際にそうなっ
      ている事を確認した。その条件が満たされている時にのみキャッシュを利用する
      事にする。

      取り敢えず実装した。動作確認した。inputrc を編集した時にちゃんと更新され
      る事も確認した。

    * done: 情報を集める箇所で ble/util/cat を3回実行している。これは readfile
      か何かに置き換えるべきなのではないか。
      →readfile に置き換えた。

    * done: というか reconstruct のパイプを assign で分解したら 0.12s から
      0.06s に短くなった。パイプは分解した方が良いのか…。

      →分解した。

2021-09-21

  * edit: set-mark 及び history-search-{for,back}ward を nmap で bind しようとしている [#D1651]
    https://github.com/Bash-it/bash-it/pull/1884

    これも結局は openSUSE の /etc/inputrc.keys が設定しようとしている設定である。
    或いはもしかすると bash-it のどれかの plugin が同様に何か設定しようとしてい
    る可能性もある。

    うーん。set-mark については単純に v と同一視してしまうのが良い気がする。

    一方で、history-search-{for,back}ward に関しては微妙である。

    a motion 的に実装するというのが一つの案だったが、history-search は opts に
      応じて現在の文字列を置き換える様に動作したり或いは実際に履歴を遡ったり振
      る舞いが変わる。前者の時には編集コマンドとして動作するし、後者の場合には
      移動コマンドとして動作する。どの様に実装するべきかは一定しない。

      x 各場合に対して適切に振る舞いを変更するのも面倒だし、

      x 更に、nsearch map の修正はしなくて良いのかという問題まで出てくる。つま
        り、nmap から呼び出しているのだとすれば jk で移動できる様にするべきなの
        ではないかという事になる。現状の設定では普通の文字列を入力したら普通に
        抜けて通常の文字入力をする設定になっている。

      よく考えたら opts については bind 経由だと何も指定できないので特定の opts
      である事を想定して history-search を nmap 上で動かしても良いのではないか??

    b うーん。vi_imap に一旦抜けてから実行してしまうというのが一つの手である。
      この場合の懸念は勝手に imap に移行した事によってユーザーに混乱を来さない
      のかという事である。

      然し nmap 専用に実装するとすると、実装の複雑さを考えると実装する価値が本
      当にあるのか怪しいし、更に振る舞いの複雑さを考えるとそもそもユーザーがちゃ
      んと使えるのかというのも怪しい。特に、bind で変な設定をした時にだけ利用で
      きる物なのでユーザーが使い方に慣れてくるという事は期待し難い。そう考える
      と、nmap 上で motion/edit として実装する方が余程混乱を来す様に思われる。

      そう考えると、imap に移行して通常の history-search として振る舞わせる方が
      良い様に思われる。

    うーん。実は history-isearch については直接束縛する様になっている。
    history-isearch は唯単に履歴項目を移動するだけなので問題ないという事なのだ
    ろう。

    うーん。振る舞いを固定してしまえば普通に edit として振る舞わせて良い気がす
    る。と思ったが、vi_imap, emacs の方で動作を履歴移動に変更しているので、やは
    り履歴移動として実装する。うーん。そうなると実は history-isearch と同様に修
    正無しで nsearch を実装してしまっても良いのではという気がしてくる。

    と思ったが、確認してみると nsearch を完了する時に eolfix が必要だし、また検
    索開始時もカーソルを一文字ずらす必要がある様な気がする。然し抜ける時にカー
    ソルが移動するとなると直感と異なる動作になる可能性もある。

    a うーん。一つの案は history-search の opts として新しく nmap を追加して、
      更に、history-search の選択範囲の抽出も nmap に依存する様に書き換える。

      →opts に設定する事にするとユーザーが自分で ble-bind した時に指定し忘れる
      事になる気がするので、直接 _ble_decode_keymap を参照して動作を決定する事
      にした。

      vi_nmap 及びその他の vi コマンドモードの中にいる時には、検索文字列を決定
      する時と一致時のカーソル位置を設定する時にカーソル位置の補正を行う事にし
      た。

    実装した。見た感じちゃんと動いている。

  * main: work around self-modifying PROMPT_COMMAND by bash-preexec (reported by cornfeedhobo) [#D1650]
    https://github.com/Bash-it/bash-it/pull/1884

    % preexec が動かないと言っている。うーん。そもそも PROMPT_COMMAND の内容が向
    % こうとこちらで異なる。こちらで色々試したが再現しない。ちゃんと
    % PROMPT_COMMAND には __bp_* が含まれているし、実際に preexec(), precmd() を
    % 定義すると期待通りに呼び出されている。
    %
    % preexec で lambda 経由の呼び出しになる様に無理やり設定した所、どうやら問
    % 題を発見した。コマンドを実行する度に preexec, precmd の処理がどんどん追加
    % されていく。調べてみると、bash-preexec は PROMPT_COMMAND に自身が含まれて
    % いない時、自身を其処に無理やり追加する様である。通常であれば
    % PROMPT_COMMAND がそれで修正されて問題は起こらなくなるが、ble.sh が
    % PROMPT_COMMAND を復元してしまう為に毎回処理が追加されるという事になってい
    % る。

    結局 cornfeedhobo は

      source bash_it.sh
      source ble.sh

    と bashrc に書いていた様だ。ble.sh の推奨する使い方からは外れているし、また
    blesh.plugin.bash を使って読み込む場合とも異なる。なかなか再現できなかった
    理由はこれだった。"minimal setup" としか言わなくて具体的な説明を一切しない
    のだから駄目である。minimal setup と言っても色々あるだろうに。

    [修正]

    これに関してはどうやら PROMPT_COMMAND の変更がちゃんと反映されればループ
    が停止する様であるから、PROMPT_COMMAND の変更をちゃんと記録するようにする。
    現在の実装だと lambda の関数本体に直接 PROMPT_COMMAND を記録しているが、
    やはり変数に記録する事にする。重複して記録されて上書きされて無限ループに
    なるのを防ぐ為に、配列にして lambda には配列添字を記録する事にする。

    取り敢えず実装して動作確認もした。

  * contra oldbug: どうも新しい c2w が問題を起こしている [#D1649]

    一番怪しいのは幅の自動判定である → 取り敢えず char_width_version を別の値
    に設定すればずれは生じない事を確認した。最悪の場合には既定値を適当に設定す
    る事にすれば良い。

    % contra では問題は発生しない。という事は受信時の処理で何かがずれているという
    % 事だろうか。というより contra も DSR(6) に対応した筈なのに反応していないの
    % は何かと思ったら、実はそもそも最新版の contra に入れ替えていなかった。
    % 2020-10 の contra を使っていた。contra を差し替えたら問題が消えてしまった。
    %
    % つまり screen と contra の不整合によって行がずれていただけという事だろうか。
    % 取り敢えずこれは無視する事にする。

    どうも Linux 上で動かしている時には問題は起こらないが、Cygwin 上で動かして
    いると問題が生じる様である。screen / contra で発生する。contra, mintty,
    screen / mintty では発生しない。うーん。tmux / contra でも発生しない。

    screen で C-a C-a C-a C-a で一旦別の window に行って戻ってくると内容が変わっ
    ている。つまり、これは screen の中の端末状態と contra の端末状態がずれてい
    るという問題である。特に、screen に於いて変な濁点のような物が行末で出力され
    ていて、contra は改行していると思っていて、screen は改行していないと思って
    いる気がする。改めて座標計算を弄って調整する必要がある気がする。

    どうやら問題の文字を出力すると発生するという事は確かだが不思議な現象が発生
    している。問題の文字を出力しない様に ble.sh を修正すると、次の一回は未だ問
    題が再現するが、それ以降は再現しなくなる。どういう事だろうか。。うーん。こ
    れは単に画面上に問題の文字が残っていて既存の文字の振る舞いを見出していると
    いう事の気がする。

    また CPR を要求しなくても問題が発生しているので、これは DSR や CPR の問題で
    はなくて純粋に文字列を出力した時の振る舞いが問題になっている。

    うーん。0x3099 が問題の文字である。もしかすると行頭で 0x3099 を実行するとカー
    ソルが前の位置に移動してしまうという事なのかもしれない。[] で囲んで出力する
    様に修正したら問題なく動く様になった。

    * char_width_{mode=auto,version=auto} とすると重複して要求が走ってしまう。
      要求を省略する事はできないか。一つの方法は test-terminal.buff (旧
      update.buff) を呼び出す前に未だ処理中であれば test-terminal.buff を呼び出
      さないという物。というか、test-terminal.buff の側で処理中かどうかを検出す
      れば良い気がする。

      取り敢えず DSR を送った回数を記録しておいて、同じ数だけ CPR を受信した時
      点で処理完了という事にする様に修正した。

      動作確認もしておきたい。先ずは VoidLinux の各端末で version 判定できてい
      るか確認する。OK. urxvt, st は version=13.0 で gnome-terminal は
      version=14.0 になった。Fedora の上で実行した urxvt は 11.0 になった。ちゃ
      んと区別できている様だ。

    x 2021-09-26 と思ったら auto が1度処理されると二度と処理されない。

      そもそも request が送信されていない気がする。
      →これは簡単なミスだった。修正した。

  * cmap: home/end が openSUSE で効かない (reported by cornfeedhobo) [#D1648]
    https://web.libera.chat/?channel=#bash-it

    home/end が効かない。これもまた openSUSE の問題の可能性はある。
    これは /etc/inputrc.keys の以下の行が原因であった。

    https://github.com/openSUSE/aaa_base/blob/master/files/etc/inputrc.keys#L233-L234

    そもそも find/select は terminfo にも存在しないし、terminfo を参照している
    だけでは判定する事は不可能である。つまり TERM を直接見て判断しないと
    find/select を検出するのは不可能である。一方で openSUSE inputrc.keys は直接
    term を参照している。

    また openSUSE に対して問題を報告しようと思ったが、xterm 決め打ちならば 1~,
    4~ は find/select とする事に明確な問題がある訳でもない様な気がする。問題が
    発生するとすれば screen の xterm-256color emulation であるが、どうも確認し
    た感じだと手元の screen.xterm-256color と向こうの screen.xterm-256color で
    khome, kend の内容が異なる様である。openSUSE の screen は khome, kend は
    \e[H, \e[F になっているが、手元の screen.xterm-256color だと khome=\e[1~,
    kend=\e[4~ になっている。

    もう面倒なので find/select に対応する事にする。結局誰も使わないキーの様な気
    もするが、単にトラブルを避ける為に無視するキーの名前という事になる。
    →実際に openSUSE で試してみて動作する事を確認した。

2021-09-16

  * decode: failglob で cmap 初期化時にエラーになる問題 [#D1647]

    Solaris で試している時に気づいた。bashrc の中で ble-bind を実行して、cmap
    initialization が其処で走ると failglob の時に cmap cache の読み取りに失敗す
    る。

    原因は _ble_decode_csimap_kitty_u に直接 keyname が格納されていて、中でも
    '*' が悪さをしているという事だった。cache は declare -p による dump で生成
    しているので本来は quote されている筈だが、容量を節約する為に quote を外し
    ていたのが原因だった (kitty_u 以外は整数なので quote の必要はなかった)。

  * edit: stdout.off で stderr だけ suppress という案について (motivated by rashil2000) [#D1646]
    https://github.com/akinomyoga/ble.sh/issues/133#issuecomment-910543950

    試してみたら普通に動く様である。つまり bash は stderr にしか物を出力しない。
    他の環境でも同様に動くか確かめてから適用する事にする。

    * Cygwin: OK
    * Void Linux: OK
    * Ubuntu: OK
    * Solaris: OK
    * Haiku: OK
    * Minux: OK
    * BSD: OK

    うーん。置き換えてしまって問題ない気がする。

2021-09-15

  * canvas: c2w の再設計 [#D1645]

    幅の計算は端末によって全然異なる。

    更に UAX 11 は可也適当で実際にこれに完全に準拠するという訳には行かない。
    多くの端末は wcwidth を参照している。一部の端末は wcswidth を参照するとし
    ている。これらの関数が内部で一体どの様なアルゴリズムを用いているか不明で
    ある。そもそも locale によっても異なるし、システムによっても異なるかもし
    れない。wcwidth のデータベースが一体何処で管理されているのかも分からない。
    もし特定の文字の幅について変更の必要があるという判断に至ったら何処に要求
    を出せば良いのかすら不明瞭であるし、例えだしたとしてもそれが末端まで波及
    するのかどうかも不明である。それらを管理している人たちがちゃんと端末の専
    門家であるのかというのも怪しい。wcwidth が整数値を返す事からこれは主に端
    末の為の関数の様に思われるから wcwidth のデータベースは TWG が少なくとも
    端末に詳しい人が管理するべきなのである。

    [これまでに分かった事のまとめ] Ref #D1619

    * UAX 11 によればこれが指定するのは実際の幅ではなくて、その文字が属する言
      語の典型的な幅なのであって、例えば制御文字について幅2 や A が与えられて
      いたとしてもその文字自体が本当に幅2 や A に割り当てられた幅を持つという
      訳ではないという事。

      結局 UAX 11 は well-defined ではないのである。

    * Fedora 31 の wcwidth を参照すると、これは Unicode 11.0 を元にしている様に
      見える。また A の文字は幅 1 としている。Cn (未使用) については -1 を返す。
      Cc, Cs, Zl, Zp についても -1 を返す。但し例外として NUL は 0 になる。Mn,
      Me, Cf は基本的に 0 を返す。以下に掲げる通り Cf の一部は例外として 1 を返
      す。

      00ad       wcwidth=1 width(eaw=3,gencat=Cf)=0 SHY(soft-hyphen)
      0600..0605 wcwidth=1 width(eaw=1,gencat=Cf)=0 アラブの数字らしい。何故Cfなのかは謎
      06dd       wcwidth=1 width(eaw=1,gencat=Cf)=0 ARABIC END OF AYAH (アラビア語?)
      070f       wcwidth=1 width(eaw=1,gencat=Cf)=0 SYRIAC ABBREVIATION MARK (シリア短縮記号?)
      08e2       wcwidth=1 width(eaw=1,gencat=Cf)=0 ARABIC DISPUTED END OF AYAH (アラビア語)
      110bd      wcwidth=1 width(eaw=1,gencat=Cf)=0 KAITHI NUMBER SIGN
      110cd      wcwidth=1 width(eaw=1,gencat=Cf)=0 KAITHI NUMBER SIGN ABOVE

      他の文字については基本的に UAX 11 に従った幅になっているが、以下の3つの範
      囲に関しては例外として UAX 11 とは異なる幅になっている。

      1160..11ff wcwidth=0 width(eaw=1,gencat=Lo)=1 ハングル字母 (160字)
      3248..324f wcwidth=2 width(eaw=3,gencat=No)=1 囲み文字10-80 (8字)
      4dc0..4dff wcwidth=2 width(eaw=1,gencat=So)=1 易経記号 (6字)

    [実装]

    大体様相が分かったので c2w の新しい実装を構築する事にする。現在の実装と
    形式を変更する必要があるかもしれない。現在は条件式を使って簡単に判定で
    きる所までは絞り込んでその後で二分法に持ち込んでいる。

    1 そうではなくて最初に孤立している文字は先に判定する。ASCIIもテーブルで
      直接判定する。
    2 code >> 8 を使ってすぐに判定できる物はその場で返すそれ以外の物につい
      ては次のステップで使う二分探索テーブルの範囲を指定する。
    3 二分探索で絞り込み。

    という具合にするのが良い気がする。

    * done: 問題点は、code>>8 を実行したとしてもUnicode の範囲を考えると 4352
      の区間が存在するという事。だからと言って2分木や patricia を実装するのも大
      袈裟な気がする。何より2分木や patricia は遅い。code>>16, code>>8 の2段構
      成にするという手も考えられるが、0,1,2,3,E,F,10 が使われているので、結局
      1792要素は存在するという事。もう一つの手は code>>8 で加速するのは BMP だ
      けにして、それ以外のものは初めから2分探索を実行するという事。うーん。見て
      みたが SMP も結構細かいので SMP も最初の判定に含めて良い気がする。

      →これについては最終的には BMP, SMP に関しては c>>8 にして、それ以降の物
      については c>>12 で振り分ける事にした。

    * done: wcwidth が -1 を返す様な物に対してはどの様に対応するべきだろうか。
      例えば、一つの方法は他の端末がやっている様に幅 1 を適当に割り当てるという
      物。また別の方法は EastAsianWidth に従って割り当てるという物。或いはまた
      別の方法としては -1 は保持した儘でテーブルを参照する時に補正する方法。然
      し補正する為には EastAsianWidth 特性の値もちゃんと覚えて置かなければなら
      ない…等と考えていくとやはり EastAsianWidth と GeneralCategory を別々に管
      理する必要があるのではないかという疑惑も出てくる。

      % うーん。取り敢えずは EastAsianWidth だけでもスクリプトから参照できる様
      % にするべきではないか。GeneralCategory のテーブルサイズも巨大になりそう
      % ではあるがそれは仕方がないと思って諦めるか。。

      →これに関しては -1 を返す代わりに -1 -2 -3 で、幅1, 幅2, 幅A を区別でき
      る様にする事にした。

    * reject: もう一つ気になるのは、EastAsianWidth, GeneralCategory から幅に対
      応付ける方法には他の可能性はないのかという事である。Unicode は中途半端に
      しか指定していないので何らかの方法を決める必要があるが、その方法は固定で
      良いのだろうか。そうではなくて、スクリプトの側でより柔軟に設定できる様に
      した方が良いという事はないのだろうか。

      やはりただでさえ EastAsianWidth だけで巨大なのに GeneralCategory まで入れ
      ると大変な事になるので、これは却下する事にする。ライブラリとしてユーザー
      が使える様に GeneralCategory のテーブルを作成するという可能性は未だ残って
      はいる。

    * done: もう一つの問題は Unicode version 依存性をどの様に取り扱うかという事。
      全ての Unicode version について情報を纏めて一つのテーブルにするという手と、
      Unicode の version 毎にテーブルを用意するという手がある。

      ? wcwidth 用の例外措置が必要になる文字の集合も version によって異なるかも
        しれず色々面倒である。例外処置について Unicode version 毎に管理するか、
        或いは、一括で管理するか。或いは端末ごとに管理する必要があるか。うーん。
        wcwidth はシステム等に依存するだろうと思われるので Unicode 由来のデータ
        に統合するのは始末が悪い様に思われる。やはり例外は別枠で管理するべきで、
        その折には Unicode version 等と紐付けて管理するのは悪手である。それより
        は locale/system 毎に管理するべきである。

        →wcwidth が Unicode とずれている分については別枠で管理するのが良い。少
        なくとも Unicode の version と紐付けて管理するのは悪手である。

      version 毎のテーブルにするか或いは一つのテーブルに統合するかは実際に両方
      の方式でテーブルを作成してサイズについて比較しかない様な気がする。実の所、
      サイズとしてどちらの方が小さくなるのか予想が付かない。

      取り敢えずテーブルを作成するコードを書くことにする。どうせなのでもう C++
      で書いてしまう事にしようか? →うーん。formatting などが色々面倒なのでやは
      り gawk で実装したのを適当に加工するのが良い気がしてきた。

      - 全てを統合したファイルのサイズは 426行 45KB である。単一だと 283行 36KB
        である。こうなって来るとやはり統合した物を埋め込むべきの様に思われる。

    * ok: 以下は例外処理をしていた物だが新しい c2w でもちゃんと半角になっている
      だろうか?

      [0x303F]=1 # 半角スペース

      →実際に ble/unicode/c2w で確認した所、周辺は2になっているのに関わらず
      0x303F は 1 になっているという事が確認できた。なのでこの例外処理はもはや
      不要である。

    [追加実装]

    * done: char_width_version 自動判定

      そもそも現在の設定インターフェイスで良いのかという疑問もある。他に、
      wcwidth=-1 になるが UAX 11 では幅を指定している物の取り扱いをどうするか
      (_ble_unicode_c2w_invalid) の振る舞いの制御等も設定対象の可能性の一つである。

      自動判定に関しては実は UnicodeMapping を参照すれば良いという気がする。
      target の version で切り替わる文字を使って判定する。然し、端末が微妙に変な
      振る舞いをしていたりする場合にはこの方法だと一番近い version を判定できなかっ
      たりする可能性もある。例えば、undefined な文字であっても元から幅 2 である事
      を予想できた場合には古い Unicode version であったとしても初めから 2 を返し
      ていた等という事が考えられる。色々考えると robust に判定する方法は無い様な
      気がする。更に絵文字の可能性がある文字については判定に使う事ができない。

      何れにしても取り敢えず UnicodeMapping を拾ってみる事にする。

      * 4
      * 9
      * 10
      * 12

      よく考えたら 負→正 になった等だと wcwidth < 0 に対して 1 を割り当てている
      端末での判定ができなくなる。という事を考えると、幅2の文字を使って判定するべ
      きなのではないか。

      * 42 ... ver1 以降で 2
      * 30 ... ver2 以降で 2
      * 45 ... ver3 以降で 2
      * 63* ... ver4 以降で 1, ver9 以降で 2
      * 33 ... ver5 以降で 1
      * 15 ... ver6 で 1, ver7 以降で 0 (元々-1)
      * 41 ... ver7 以降で 0 (元々2)
      * 24 ... ver8 以降で 0 (元々-1)
      * 63* ... ver9 以降で 2 (他に56も同様)
      * 43 ... ver10 以降で 2
      * 44 ... ver11 以降で 2
      * 57 ... ver12 以降で 2
      * 47 ... ver13 以降で 2
      * 46 ... ver14 以降で 2

      63 は emoji　だった。63 になっている全ての範囲の先頭文字について確認して、
      何れも emoji であるという事を確認した。うーん。プログラム的に確認するべきの
      気がしてきた。

      ver1 U+9FBC(40892) 龼 1->2 (-1 2 2 2 2 2 2 2 2 2 2 2 2 2 2)
      ver2 U+9FC4(40900) 鿄 1->2 (-1 -1 2 2 2 2 2 2 2 2 2 2 2 2 2)
      ver3 U+31B8(12728) NA 1->2 (-1 -1 -1 2 2 2 2 2 2 2 2 2 2 2 2)
      ver4 判別不能
      ver5 U+D7B0(55216) ힰ 2->1 (-1 -1 2 2 2 1 1 1 1 1 1 1 1 1 1)
      ver6 判別不能
      ver7 U+3099(12441) NA 2->1 (2 2 2 2 2 2 2 0 0 0 0 0 0 0 0)
      ver8 U+9FCD(40909) 鿍 1->2 (-1 -1 2 2 2 2 2 -2 2 2 2 2 2 2 2) うーん。古い ver でも幅1に注意
      ver9 U+1F93B(129339) NA 1->2 (-1 -1 -1 -1 -1 -1 -1 -1 -1 2 2 2 2 2 1)
      ver10 U+312E(12590) ㄮ 1->2 (-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 2 2 2 2 2)
      ver11 U+312F(12591) ㄯ 1->2 (-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 2 2 2 2)
      ver12 U+16FE2(94178) 翢 1->2 (-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 2 2 2)
      ver13 U+32FF(13055) ㋿ 1->2 (-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 2 2)
      ver14 U+31BB(12731) ㆻ 1->2 (-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 2  2)
      ver15 U+9FFD(40957) 鿽 1->2 (-1 -1 2  2  2  2  2  -2 -2 -2 -2 -2 -2 -2 -2 2)

      実装した。設定を直接上書きする方式に変更する事にした。例えば
      char_width_mode=auto にしていると、幅の判定を終えた時には
      char_width_mode=west か char_width_mode=east に書き換える。同様にして
      char_width_version についても決定した値で上書きする事にする。

    * done: blerc, wiki: bleopt char_width_version

      対応した。

2021-09-14

  * prompt: $? is not properly set in ${PS1@P} (reported by nihilismus) [#D1644]
    https://github.com/akinomyoga/ble.sh/issues/136

    setexit をしていなかった。

    他にも何か影響があったりするだろうか。例えば、その他のシェル設定は復元しな
    くても良いのだろうか。PROMPT_COMMAND の前後では何か調整していた気がする…
    と思って改めて確認した所 PROMPT_COMMAND は単に PS1 を復元していただけだった。
    その他の設定は待避した儘になっている。なので気にしなくて良い。

2021-09-11

  * global: resolve leak variables [#D1643]

    - fixed: CHARS=([0]="13")
    - fixed: git_base=/home/murase/.mwg/src/ble.sh
    - fixed: git_base_dir=/home/murase/.mwg/src/ble.sh/.git
    - fixed: nhash=$'10:10,10,10,337,10,10,10:justify=\r,\\q{lib/vim-airline}'
    - fixed: wattr_buff=([0]="5:72057594037930244")
    - fixed: wattr_g=d
    - fixed: wattr_pos=101
    - fixed: _data=([2]="")

    - BASH_REMATCH: これは bleopt 等をユーザーから実行すると書き換わってしまう。
      然し、local BASH_REMATCH を実行しようにも readonly でエラーになってしまう。
      書き換わるのは問題ないと諦めるしかない。

      read, bind, history, etc. 等では保存復元した方が良いかもしれない。
      →read, exit, bind, history, trap で保存復元する様にした。

      他に初期化時にも問題になるかもしれない…が、そもそも soruce xxx としたら
      中で BASH_REMATCH を使っている可能性は排除できないので、これは気にしなく
      て良い気がする。

2021-09-08

  * width: char_width_mode を変えた時にキャッシュがクリアされていない気がする (reported by Barbarossa93) [#D1642]
    https://github.com/akinomyoga/ble.sh/issues/135

  * syntax: "\"" が正しくエスケープ着色されない [#D1641]
    対応した。

2021-09-01

  * util (bleopt, bind): fix interfaces [#D1640]

    * bleopt の unknown option のエラーメッセージでオプション名が '-c' 固定になっている。

    * 2021-07-20 bind --help の exit status が 1 になっている。2 であるべき。

  * complete: 古い bash における -D, -I の対応 [#D1639]

    どうやら -D, -I はそれぞれ内部的には _DefaultCmD_, _InitialWorD_ という名
    前のコマンドに対する補完として実装されている様である。だとすれば、古い bash
    の version で -D, -I に対応するとしたらこれらの単語に対して検査すれば良いの
    ではないか。

    というか現在の実装で古い bash ではどの様に振る舞うのだったか。
    確認した。 -I に関しては version を確認して処理している。
    -D に関しては complete -p -D が成功するかどうかで動作を変更している。

  * 2021-05-03 edit: support bash-5.2 READLINE_ARGUMENT [#D1638]

    5.2 新機能: READLINE_ARGUMENT: 調べてみると引数が存在している時にのみ定義さ
    れる様である。また今気づいた事だが -x 属性が入っている。他の READLINE_* も
    全て同様である。よく考えてみれば、bind -x で外部コマンドを呼び出す事もある
    のだから -x 属性が入っていないと困る。

  * 2021-08-23 mandb: manpath コマンドを使っても MANPATH は得られる [#D1637]

    また、MANPATH に空パスが含まれている場合にはそれは標準の manpath と解釈される様だ。

    manpath の emulation についてちゃんと考える。

    MANPATH が設定されていない時または空パスが含まれている時は/etc/man_db.conf
    及び ~/.manpath を読み取る必要がある。MANDATORY_MANPATH 及び MANPATH_MAP を
    解釈すれば良いだろう。更に PATH 中の bin を share/man に置き換えてディレク
    トリが存在するかどうか確認する。

    →その様に実装した。

    * MANDB_MAP についても実装するべきなのではないか。というか MANDB_MAP とは何
      か。説明を見ると MANPATH から CATPATH への対応表の様だが、CATPATH とは何
      か。検索してみると整形済みの物をキャッシュしておく場所の様だ。つまり、cat
      するだけで説明が読める様な状態でファイルを保存しておく場所という事なのだ
      ろう。

      実際に指定されている /var/cache/man の下を見ると index.db という 500kB の
      ファイルが一個あるだけで、cat するだけという状態ではない様な気がするが、
      然しデータベースとして記録しているのだろうと思う。

      何れにしてもこれは ble.sh の関知する所ではない。気にしない。

  * auto-complete: idle.sleep で異なる時計を参照していた事による無限ループ (reported by rashil2000) [#D1636]
    https://github.com/akinomyoga/ble.sh/issues/133

    msys2 で auto-complete が特定の状況で実行されないという報告だったが、自分の
    手元で complete_timeout_auto= にしてみたらどうやら無限ループになっている気
    がする。調べてみると idle.sleep しているのに sleep していない。と思ったら、
    どうやら異なる時計を参照していた為に msleep が skip されて、無限に msleep
    の要求をし続けている状態になっていた。

    これを直したらちゃんと補完候補が表示される様になった。

    然しこれについては過去に修正した様な気がする。過去に修正した時の修正漏れか
    或いは逆方向に間違えて修正したか。再度確認する必要がある。

    * ble/complete/auto-menu.idle の #D1597 での修正

      53dd018e で他の箇所を類似の問題により isleep から sleep に切り替えている。
      #D1597 である。一方で今回問題になっている箇所は最初から sleep だった様だ。
      #D1597 に詳しく説明が書かれている。

      改めて実装を確認する。auto-menu.idle は _idle_clock_start を元にしてい
      る。_idle_clock_start は ble/util/idle.clock を元にしている。
      ble/util/idle.clock は色々実装を切り替えているので環境によって異なる。ま
      た、idle.sleep もまた ble/util/idle.clock を元にしている。

    * 今回の ble/complete/auto-complete.idle に関しては、唯単に idle.sleep を要
      求しているだけの様に見える。但し、最後にユーザー入力があって以降の経過時
      間を考慮に入れる為に ble_util_idle_elapsed を用いている。この
      ble_util_idle_elapsed は _ble_util_idle_sclock-_idle_sclock_start を元に
      していて、更にこれらは ble/util/idle/.sleep で積算される。

      うーん。つまり、ble_util_idle_elapsed を参照する限りは isleep を使う必要
      があるという事。一方で auto-complete の delay を処理するのは isleep に基
      づくべきか sleep に基づくべきかという疑問もある。

    * また macOS の 100% も関係しているかもしれない。報告によると履歴のロードに
      関係しているという事だが、nawk が走っている間ずっと CPU が動いているとい
      う状態になっている可能性もある。と思ったがそうでもなかった。そもそも履歴
      の初期化では sleep は行っていない。

2021-08-30

  * edit: command-help が効かなくなっている [#D1635]

    どうやら以下の commit で external-command を書き換えた時に、内部で使用して
    いる変数名 command と command-help で使用している変数名が被ってしまって問題
    が起こっている様だ。

    7b63c60d src/edit.sh (Koichi Murase     2021-05-06 16:04:39 +0900 8755)   local command=$1

    一旦は command-help の側でコマンド名を他の変数に待避する様に書き換えてみた
    が、うーん。そもそも external-command は呼び出し元の変数名に影響が無い様に
    特別な変数名を使うべきである。

  * README: やはり ble.sh の読み方を与えるべきかもしれない [#D1634]
    https://www.youtube.com/watch?v=YS1vxEhd2Pc

    動画の最初で読み方に戸惑いが見られる。やはり発音しやすい発音として blesh を
    呈示しておいた方が良い様な気がしてきた。別に正しい読み方がある訳でもないし、
    寧ろ個人的には bee-elle-yee-dot-ess-eightch と読んでいるが、やはり膾炙する
    のは発音しやすい読み方だろう。

    或いは両方提示する。

      /blɛʃ/ or /biːɛliː dɑt ɛseɪtʃ/

    うーん。後者は態々 IPA で書く迄の事もなく、くどい感じがする。

    少しずつ push した方が GitHub の suggestion に現れる様なので、
    試みに今日から一日に 1 commit ずつ push する事にする。check の意味も兼ねて。

    他の README に関連する編集も纏めて一つの commit にする事にする。

    * README: @oc1024 がリンク切れになっている。やはり質問しているとは言え他の
      人をどんどん README に追加していくのは出過ぎた真似だろうか。huesche の件
      が偲ばれる。然し一方でこちらが正体を当てた事から oc1024 ではなくてちゃん
      と capezotte という名前にアカウントを変更したのかもしれない。何れにしても
      capezotte に変えるべきだろうと思われる。

    * README: Wiki -> wiki?

      Wiki ではなくて wiki なのではないか。README の他にも文頭でないのに Wiki と
      書いている箇所があるかもしれない。

      改めて検索してみると日本語の記事だと wiki を Wiki と書いている様である。つ
      まり、Wiki と capitalize するのは日本語の習慣という事なのだろう。

    * README: 各機能の無効化について記述する
      https://github.com/akinomyoga/ble.sh/issues/134

  * 2021-08-19 st: insert で CSI 4h を送るなど色々変な key sequence を送ってくる [#D1633]

    他に以下の物が見られる。

      CSI L (C-insert)
      CSI J (C-end)

    他にも色々ありそうなので一つ一つ既に実装されている物と見比べて調べる必要が
    ある。幾つか追加した。ESC[M は他とかちあっている。

2021-08-19

  * st: unknown csi error message (reported by Shahabaz-Bagwan) [#D1632]
    https://github.com/akinomyoga/ble.sh/issues/132

    * 先ず st は DA2 に応答しない。DA1 に対して CSI ?6c を返答する。

      何れにしても古い st が一掃されるまでは CSI ?6c を st と解釈するなどの処置
      で良い気がする。

      と思ったら何と st は TERM に st-256color を設定する様だ。なので先にこれを
      見て st と判明したならば DA2 は送信しなくて良い。modifyOtherKeys に関して
      も現在の st の構造を見る限りは将来的に実装すると思われない。完全に無効化
      するという事で良い気がする。

    * ok: 然し報告によると stderr が slave の stdrr に書き込まれると言う…。不
      思議な事である。と思って改めて報告を見たら違った。エラーメッセージは起動
      元の terminal に表示されているのだった。つまりこれはそもそも期待通りの振
      る舞いであり問題はない様に思われる。その旨説明する。

    * ok: st で prompt_status_line を有効にしていると座標計算がずれるどうやらこ
      れは雷絵文字の幅計算がずれているのが原因の様である。これはまあ仕方の無い
      ことである。もしちゃんと対応するのだとしたらまずは st をちゃんと検出でき
      る様にしなければならない。

    2021-08-26 minux になっている箇所がある。
    2021-08-30 #D1633 で一緒に直した。

2021-07-19

  * edit: support TMOUT for session timeout [#D1631]

    またそれと並行して session TMOUT についても実装したい。うーん。振る舞いにつ
    いて確認する。恐らく最後にコマンドを実行してからどれだけ時間が経ったのかで
    timeout を実行するという仕組みになっている。これはどの様に実装すれば良いの
    だろうか。

    動作確認をして見た所、新しいコマンドを実行したタイミングというよりはやはり
    accept をしたタイミング、或いは newline を挿入したタイミングでリセットされ
    るという事の気がする。

    例えば insert-newline に於いてログアウト時刻をセットするという仕組みにする
    のが良い気がする。ログアウト時刻が設定されていたらそれまで sleep するという
    事にする? 然し、それだと十分に長い timeout にしてたくさんコマンドを実行する
    と、実行したコマンドの数だけ待ちタスクが増えて大変な事になってしまう。ユー
    ザー入力または sleep で時間を測るというタスクが必要になる気がする。または、
    後で外部からタスクの待ち時間を書き換える仕組みが必要になる気がする。

    うーん。外部から既存のタスクの待ち時間を書き換える仕組みにするのが良い。

    タスク番号を指定して書き換えられる様にする。その為にはタスク登録時に登録し
    たタスクの番号が分かる様にするべきである。

    ? それから bash-4.0 未満で idle.push が使えない場合にはどうするのか…? これ
      は諦めるしかない様な気がする。bash-3.2 以下では TMOUT は動かない。

      # 或いは bash-3.2 以下でも read -t 0 もしくは select に対応する様な物を
      # loadable builtin 等で用意できればそれはそれで良いのかもしれないが、実の
      # ところライセンスなどの問題から loadable builtin で実装するかどうかは悩
      # ましい所である。代わりに外部コマンドとして実装するという手もあるが。何
      # れにしてもこれは散々別の場所で議論してきた所であるから今ここでは議論し
      # ない。

    ? どのタイミングでタイマーをリセットするのが良いのか? insert-newline で実行
      しようかと考えていたが、insert-newline はコマンド実行前に実施される。本来
      はコマンド実行後にプロンプトが最初に表示された時点から実行するべきの様に
      思われる。

      うーん。という事を考えると POSTEXEC で実行するべきだろうか。また、この場
      合には一番最初のプロンプトに対して timeout が設定されないので、ble-attach
      に際しても同様に設定をするべきの気がする。

      POSTEXEC だと複数回のコマンドが実行される時に余分に timeout が再計算され
      る事になる。それよりは /.end 辺りで設定した方が良いのではないかという気も
      する。うーん。

      或いは、insert-newline で何か行番号等を更新して、PS1 の表示時にその行番号
      が変化していたら更新するという具合にするのが良い気がする。

    取り敢えず実装した。動いている。表示を多少調整した。

  * global: "TMOUT: readonly variable" というエラーメッセージが表示される (reported by farmerbobathan) [#D1630]
    https://github.com/akinomyoga/ble.sh/issues/129

    問題のエラーメッセージは ble-edit/io/check-stderr から出てきている。

    これは /etc/profile.d/ 辺りに readonly TMOUT=xxxx 等という設定が書き込まれ
    ているサーバーが存在する事があってその時に発生する。うーん。正直な所そうい
    う設定を行うサーバーの方が悪いとしか言いようがない。然し勝手に読み込まれる
    のはユーザーとしては仕方がない。


    a TMOUT に変な値が設定されている時には -t 巨大な数 というのを指定して誤魔化
      すしかない。一方で、毎回 TMOUT の値をチェックするのは効率が悪い。

    b 或いは常に -t 巨大な数 を指定するという手もあるのかもしれないが、それだと
      read を実行する度に alart/select が設定される事になって効率が悪い。

    c 或いは TMOUT に有限の値を設定されている時に限り -t 巨大な数 を設定すると
      いう手もあるのかもしれない。

    d 或いはユーザー空間に入る時に TMOUT が readonly になっていないか確認して、
      TMOUT が readonly になっていたら workaround の必要性を示す変数を設定する
      という手がある。取り敢えず TMOUT が readonly の時にだけ振る舞いを変えるの
      だとすればこの方針を貫くのが良い。

    e 或いは enter する時に TMOUT を未設定にするという手もあるのだろうか? と思っ
      たが、それだと session timeout としての TMOUT が動かなくなってしまうので
      駄目→と思ったが、確認してみた所、そもそも session timeout としての TMOUT
      は ble.sh ではちゃんと動作していなかった。となると、TMOUT は自前で実装す
      る必要がある。自前で実装するのだとすれば ble.sh 内部では TMOUT= になる様にして、
      read を実行する箇所で TMOUT= を実行する事はない様にすれば良いのである。

      _ble_builtin_read_tmout_wa=(-t 巨大な数) 等でも適当に設定してこれを read
      の引数に指定する事にする。

    [修正] e の方針で実装した。取り敢えず動いている。

  * history: ble-attach に使ったコマンド履歴が欠けている。履歴番号にもずれが生じている [#D1629]
    Ref #D1120

    bashrc から attach した時には欠けているコマンドは存在しない様だ。

    % source ble.sh で新しく読み込んだ時にも欠けているコマンドは発生しない。と
    % 思ったらこれは気の所為だった。

    うーん。然し ble-attach を実行した時点ではちゃんと履歴が登録されている筈だ
    から後になって履歴が変化していると考えるべきだろうか→やはり確認してみた所、
    一旦履歴項目が追加されているのにも関わらずその後で削除されている様に見える。

    履歴を初期化する時点での最後の項目はどうなっているのかについて確認する必要がある気がする。

    分かった。これは ble/builtin/history/is-empty で history -p を使っている為
    に履歴項目の数が減少している。この関数では BASH_SUBSHELL を参照して
    subshell の中にいる時には対策をしない様にしているが、実は subshell の中であっ
    ても履歴項目が減る時には減るし、後で履歴データを参照する場合にはちゃんと
    subshell の中で history -p を実行しなければならない。

2021-07-13

  * 2021-06-28 main: set -Bk 等の場合に対しても対策する [#D1628]

    set -B に対してはブレース展開を使っているコードが影響を受ける。ブレース展開を使っているコードは以下で抽出する事ができる。

    $ grc '[^$]\{[^[:space:]]*,[^[:space:]]*\}' --exclude={wiki,memo,test,ext} --exclude={lib/test-\*.sh,make_command.sh}
    ./keymap/emacs.sh:21:  copy{,-forward,-backward}-{c,f,s,u}word
    ./keymap/emacs.sh:22:  copy-region{,-or}
    ./keymap/vi.sh:220:  delete-backward-{c,f,s,u}word
    ./keymap/vi.sh:221:  copy{,-forward,-backward}-{c,f,s,u}word
    ./keymap/vi.sh:222:  copy-region{,-or}
    ./keymap/vi.sh:2799:  local _ble_keymap_vi_single_command{,_overwrite}= # single-command-mode は持続させる。
    ./keymap/vi.sh:2813:  ble/util/unlocal _ble_keymap_vi_single_command{,_overwrite}
    ./lib/core-complete-def.sh:78:                  ble/complete/menu-style:{align,dense}{,-nowrap}/construct-page \
    ./lib/core-complete-def.sh:80:                  ble/complete/menu-style:desc{,-raw}/construct-page
    ./lib/vim-airline.sh:114:  for name in {a,b,c,x,y,z,error,term,warning}{,_normal,_insert,_replace,_visual,_commandline,_inactive}; do
    ./lib/vim-airline.sh:343:  for unit in _ble_lib_vim_airline_section_{a,c,z,b,y,x}; do
    ./src/benchmark.sh:231:  for n in {1,10,100,1000,10000}\*{1,2,5}; do
    ./src/decode.sh:3944:  'M&&E,A[i++]=_ble_decode_Erro|'{254,255}
    ./src/edit.sh:7793:                  ble-decode/keymap:vi_{i,n,o,x,s,c}map/define
    ./src/util.sh:2667:    builtin unset -f ble/function#advice/{before,after,around,original}:"$name" 2>/dev/null
    ./src/util.sh:4218:    ble/array#push dirs "$_ble_base"{,/contrib,/lib}
    $ grc '[^$]\{[0-9.]+\}' --exclude={wiki,memo,test,ext} --exclude={lib/test-\*.sh,make_command.sh}
    ./lib/init-bind.sh:153:  for i in {128..255} {0..127}; do
    ./src/decode.sh:3937:  'M&&E,A[i++]='{0..127}
    ./src/decode.sh:3938:  'C=C<<6|'{0..63}',--M==0&&(A[i++]=C)'
    ./src/decode.sh:3939:  'M&&E,C='{0..31}',M=1'
    ./src/decode.sh:3940:  'M&&E,C='{0..15}',M=2'
    ./src/decode.sh:3941:  'M&&E,C='{0..7}',M=3'
    ./src/decode.sh:3942:  'M&&E,C='{0..3}',M=4'
    ./src/decode.sh:3943:  'M&&E,C='{0..1}',M=5'
    ./src/decode.sh:3985:  for i in {0..255}; do

    それほど多い訳でもないが代替手段がある訳でもない様な物が多く含まれる。
    うーん。これも ble.sh の内部では解除するオプションとするべきの気がする。

    set -k に対しては bleopt a=b 等が影響を受ける。他にも影響を受ける物は多く存
    在するかもしれない。何れにしてもこのオプションは非現実的である様に思われる
    のでやはり ble.sh 内部では解除する事としたい。

  * kitty, fzf: modifyOtherKeys で問題が生じている (reported by Nudin) [#D1627]
    https://github.com/akinomyoga/ble.sh/issues/126

    うーん。fzf が modifyOtherKeys で動かなくなっている。
    というか補完全般で問題が生じるのだろうという気がする。

    x 何故か知らないがまた kitty で動かなくなっている。うーん試して見た所、いつ
      の間にかに \e[>4;0m ですら効かなくなっている様だ。\e[>4m としなければなら
      ない。もう面倒なので kitty の時だけ異なる sequence を出力する様に修正する。

      以前は確かに修正したと思ったのだが…。確認すると以下で動作する事を確認している。
      ということはまた kitty の振る舞いが変わったという事である。
      https://github.com/akinomyoga/ble.sh/issues/110#issuecomment-841839605

      取り敢えず修正した。動作確認した。OK と思う。

  * kitty: keypad enter が変なシーケンスで送られてくる (reported by Nudin) [#D1626]
    https://github.com/akinomyoga/ble.sh/issues/127

    取り敢えず以下に挙げられているキーの番号を kitty 専用に判定する事にした。
    https://sw.kovidgoyal.net/kitty/keyboard-protocol.html#functional-key-definitions

  * compat: terminal dnkl/foot は DA2 で 010801 などの文字列を返すようだ (reported by GorrillaRibs) [#D1625]
    https://github.com/akinomyoga/ble.sh/issues/128

    これが DA2 の判定で8進数と解釈されてしまって問題が発生している。
    escape sequence に含まれる数字は全て明示的に10進数で解釈するべきである。

    因みに dnkl/foot は DA3 で FOOT という文字列を返すそうだ。

    * dnkl/foot を認識する様にした。
    * CSI の解釈で 0 が前置されていても良い様に書き直した。
      一部の CSI については既に対策されていたが今回全てに対して処理する事にした。
    * DA2 の解析はまた別の箇所で行われていた。これも対処する事にした。
    * ble/canvas/trace の諸々の制御機能についても対策した。
    * SGR の解析部分 (ble/color/read-sgrspec) は既に対処済みだった

    https://github.com/akinomyoga/ble.sh/issues/128#issuecomment-878670622

    追加修正。10# で後ろに何も数字が続いていないと 5.1 ではエラーになる。
    これは修正した。多分大丈夫。

2021-07-12

  * emacs モードで vi-bword 使う (requested by SolarAquarion) [#D1624]
    https://github.com/akinomyoga/ble.sh/issues/125

    調べると vi-bword vi-Bword があって、内部的にはそれぞれ vword uword として
    いる。それなら edit.sh に既に定義されている vword, uword を代わりに呼び出し
    たら良いのではないか、と考えたが、vword は定義されていない。実装を具体的に
    観察すると単純に単語決定に使う文字集合を edit.sh に引き込めば良いという訳で
    もない。

    観察する限りでは別に emacs mode でこの vi-bword 等を呼び出しても特に問題は
    生じない様にも見える。念の為どの変数を参照していてどの変数が emacs mode で
    期待している値になっているのかについて確認する。

    単語単位の移動は ble/widget/vi-command/forward-word.impl 等で実行されている。
    特別な動作をするかどうかは渡された引数 flag で判定している。取り敢えず flag
    が空だと仮定するとそのまま ble/widget/vi-command/exclusive-goto.impl
    "$index" "$flag" "$reg" が呼び出される。そしてそのまま exclusive-range.impl
    に渡される。ble/keymap:vi/needs-eol-fix "$dst" && ((dst--)) が呼び出されて、
    移動して、 ble/keymap:vi/adjust-command-mode が呼び出さる。

    * 最初の flag に関しては ble/keymap:vi/get-arg 経由で _ble_keymap_vi_reg の
      値を読み取っている。これは get-arg を呼び出していれば clear されている筈。
      一方で、set -o emacs 等を実行した時にちゃんとクリアされるだろうか。少なく
      とも vi-command/accept-line の中では clear-arg が呼び出されている。

      vi_imap の中にいる時にちゃんと clear されているのかというのは気になる。一
      応 ble/widget/vi_nmap/.insert-mode を呼び出す時にはちゃんと
      ble/keymap:vi/clear-arg が事前に呼び出される様に書いてある様である (見落
      としはあるかもしれないが)。

      emacs-editing-mode 経由で切り替えた時にちゃんと arg が clear されるのかど
      うか。見た所は全く考慮に入れていない様に見える。

      a reject: keymap に attach する時に clear する? 然し emacs 側で始末するの
        も変である。本来独立に実装されているべきである。

      b という事を考えると detach 時に処理できる様にするべき? 然しその場合には
        新しく __detach__ という特別キーも定義する必要が出てくる。もし定義した
        とすると、それを処理するのは何処で行うべきだろうか。
        ble/decode/reset-default-keymap を弄れば良い様な気もするが、初回呼び出
        しの際には既定で 'emacs' が代入されている為、detach が無意味に呼び出さ
        れてしまう気がする。それは変だ。

        a 或いは初期値を emacs 以外 (例えば safe) などにするという手もあるだろ
          うか。

        b 或いは初期値は空でも良いのかもしれない。例え emacs であっても初期化な
          しに使える訳ではない筈だから、現状の実装で必ず初期化は実行されている
          と見做すべきである様に思われる。

        c 或いは safe を代入しておくのでも良いのかもしれない。然し確認してみた
          所、safe であっても初期化なしには使えない様である。なので結局
          _ble_decode_keymap の初期値は空文字列で良いのではないかという気がする。

      もっと全然別の方法で clear される事を保証する事はできないのか。

      c 例えば、emacs-editing-mode widget 自体に clear-arg を呼び出すコードを付
        加しておくなど。

      d それよりは change-editing-mode hook でも定義しておくのが良い様な気もす
        る。然し、それだと結局 __detach__ の劣化版にしかならないので、それぐら
        いならば b の __detach__ に対応するべきの気がする。

      今の所 b が最有力の対処方法である。

    ble/keymap:vi/needs-eol-fix については現在の keymap が vi[on]map でなければ
    false になるので記にしなくて良い。

    ble/keymap:vi/adjust-command-mode については

    * _ble_keymap_vi_search_activate が非空の時に何か処理している。

      これは様々の検索で使われている気がする。例えば単語検索等の一致で使われて
      いる? この状態で vi_imap に入ったりすると値が残る気がする。と思ったが別に
      値は代入されていなかった。改めてどの状況でクリアされるか確認する。

    * _ble_edit_mark_active == vi_search の時にも何か処理している。

      これはどうやら $_ble_keymap_vi_search_activate 経由で代入される様だ。

    * _ble_keymap_vi_search_matched が何か有限の整数値を持っている時にも処理がある。

      その他は特に何も無いように見える。これらの変数についてそれぞれどう設定さ
      れてどう clear されるのか確認する。

    うーん。上記に関しては .insert-mode の中で
    ble/keymap:vi/search/clear-matched を呼び出す事にした。また、emacs mode に
    対しては clear-arg の処理に際して同時に clear-matched も呼び出す事にした。

    [動作確認]

    o 取り敢えず __detach__ は実装して思い通りに動く事を確認した。

    o また vi-bword が動作する事も確認した。テストが面倒なのでこれ以上の細かい
      動作確認は省略する。

2021-07-08

  * nullglob が勝手に on になってしまう現象 (reported by Lun4m) [#D1623]
    https://github.com/akinomyoga/ble.sh/issues/123

    nullglob を保存復元している ble/complete/util/eval-pathname-expansion が怪
    しいと考えたが実際に動作を確認してみるとどうやらこの関数の外側で状態が書き
    換わっている様である。また、補完の最中に設定が書き換わる事に違いない。と思っ
    たが分かった…。148 で抜ける時に dtor を実行せずに eval-pathname-expansion
    を抜けていた。修正した。

2021-07-04

  * bash-completion (_find): error message (reported by oc1024) [#D1622]
    https://github.com/akinomyoga/ble.sh/issues/121
    https://github.com/scop/bash-completion/issues/509
    https://github.com/scop/bash-completion/commit/f1ddf810e4ee6693acb9fab1be1794586aa111a0

    これはどうしようもない。bash-completion が悪い。

  * ble-0.3: bashrc で bind '"\e[D": backward-char' を実行した時にエラーメッセージ [#D1621]
    https://github.com/akinomyoga/ble.sh/issues/122#issuecomment-872690396

2021-06-19

  * term: どうも GNOME terminal が terminal identification を変更した様だ [#D1620]

    65;600x;1 になっている。

    | 6cd4713c5 src/vteseq.cc (2018-03-27) int const version = (VTE_MAJOR_VERSION * 100 + VTE_MINOR_VERSION) * 100 + VTE_MICRO_VERSION;
    | 6cd4713c5 src/vteseq.cc (2018-03-27) reply(seq, VTE_REPLY_DECDA2R, {65, version, 1});
    |
    | fde88ef7f src/vteseq.cc (2018-03-27) if (version != NULL) {
    | fde88ef7f src/vteseq.cc (2018-03-27)         for (i = 0; version[i] != NULL; i++) {
    | fde88ef7f src/vteseq.cc (2018-03-27)                 ver = ver * 100;
    | fde88ef7f src/vteseq.cc (2018-03-27)                 ver += atol(version[i]);
    | fde88ef7f src/vteseq.cc (2018-03-27)         }
    | fde88ef7f src/vteseq.cc (2018-03-27)         g_strfreev(version);
    | fde88ef7f src/vteseq.cc (2018-03-27) }
    | fde88ef7f src/vteseq.cc (2018-03-27) g_snprintf(buf, sizeof (buf), _VTE_CAP_ESC "[>65;%ld;0c", ver);
    |
    | Behdad Esfahbod
    | 3b22bcc86 src/vteseq.c (2009-01-06) g_snprintf(buf, sizeof (buf), _VTE_CAP_ESC "[>1;%ld;0c", ver);
    |
    | f3d79059c src/vteseq.c (2006-02-10) version = g_strsplit(VERSION, ".", 0);
    | f3d79059c src/vteseq.c (2006-02-10) if (version != NULL) {
    | f3d79059c src/vteseq.c (2006-02-10)         for (i = 0; version[i] != NULL; i++) {
    | f3d79059c src/vteseq.c (2006-02-10)                 ver = ver * 100;
    | f3d79059c src/vteseq.c (2006-02-10)                 ver += atol(version[i]);
    | f3d79059c src/vteseq.c (2006-02-10)         }
    | f3d79059c src/vteseq.c (2006-02-10)         g_strfreev(version);
    | f3d79059c src/vteseq.c (2006-02-10) }
    | f3d79059c src/vteseq.c (2006-02-10)   ret = g_strdup_printf(_VTE_CAP_ESC "[>1;%ld;0c", ver);
    |
    | Nalin Dahyabhai
    | ddad9e00e src/vte.c (2003-06-27) ret = g_strdup_printf(_VTE_CAP_ESC "[>1;%ld;0c", ver);
    |
    | 3c6d81bf0 src/vte.c (2002-08-22) version = g_strsplit(VERSION, ".", 0);
    | 3c6d81bf0 src/vte.c (2002-08-22) if (version != NULL) {
    | 3c6d81bf0 src/vte.c (2002-08-22)         for (i = 0; version[i] != NULL; i++) {
    | 3c6d81bf0 src/vte.c (2002-08-22)                 ver = ver * 100;
    | 3c6d81bf0 src/vte.c (2002-08-22)                 ver += atol(version[i]);
    | 3c6d81bf0 src/vte.c (2002-08-22)         }
    | 3c6d81bf0 src/vte.c (2002-08-22)         g_strfreev(version);
    | 3c6d81bf0 src/vte.c (2002-08-22) }
    | 3c6d81bf0 src/vte.c (2002-08-22) ret = g_strdup_printf("1;%ld;0c", ver);
    |
    | commit 3c6d81bf06becda3f9ab005c7310b2343588115e
    | Author: Nalin Dahyabhai <nalin@src.gnome.org>
    | Date:   Thu Aug 22 23:27:31 2002 +0000
    |
    |     * src/vte.c: Implement send-primary/secondary-device-attributes.  Bind
    |             shift+insert to "paste PRIMARY".  Guard against NULL window/icon title
    |             when telling the child app what they are.

    この歴史を観察すると一番最初に vte に実装された時 2002-08 から 1;version;0 であったが、
    2018-03 に 65;version;0 に変更された様である。VERSION は何処で定義されているのだろうか。

    | 現在の version は meson.build の中に定義されている。
    |
    |   project(
    |     'vte',
    |     ['c', 'cpp'],
    |     version: '0.65.0',
    |
    | meson に移行したのは 7566ad673 (2019-04-14) である。この時は 0.57.0
    |
    |   7566ad673 (Christian Persch 2019-04-14 21:11:43 +0200  20)   version: '0.57.0',
    |
    | それより前は configure.ac に定義されていた様だ。
    |
    |   m4_define([version_major],0)
    |   m4_define([version_minor],57)
    |   m4_define([version_micro],0)
    |
    | fde88ef7f の時点での version は 0.53.0 の様だ
    |
    |   137e16630 configure.in (Behdad Esfahbod      2010-06-30 15:27:30 -0400   1) m4_define([version_major],0)
    |   6f330cc1a configure.ac (Christian Persch     2018-03-12 21:44:43 +0100   2) m4_define([version_minor],53)
    |   b4b2eb2ce configure.ac (Christian Persch     2018-03-05 21:58:12 +0100   3) m4_define([version_micro],0)

    従って 1;5300;0 から 65;5300;1 に移行したという事。

    * 他の端末についても確認してみると konsole は 0;115;0 に固定である。
      (src/Vt102Emulation.cpp Vt102Emulation::reportSecondaryAttributes)

2021-06-18

  * 2021-02-05 canvas: 絵文字シーケンスや grapheme cluster (motivated by huresche) [#D1619]

    今まで対応は不可能と思って割り切って考えてきたが実は可能なのではないかとい
    う気がしてきた。ゼロ幅の文字が存在しても特に変な事は発生しない気がする。注
    意しなければならない事としては dirty 範囲を広げなければならないという事と、
    文字の途中で SGR 等を挿入したりする事はできないという事。

    一方で端末の側でもこれに対応している必要があるのでテストという観点からは微
    妙。contra は対応していないし screen も恐らく対応していない。tmux はどうな
    のだろうか。

    tmux はこれに対応しているターミナルがないから未だ対応しないという事を言って
    いる。一番最近では 2020-05 https://github.com/tmux/tmux/issues/1605

    2021-05-30 書記素で動かないという話が来た。
    https://github.com/akinomyoga/ble.sh/issues/117

    というか逆に動くアプリケーションは一体どれ程あるというのだろうか。振る舞い
    を調べてみると、bash は ハート+VS に関してはそれぞれ一文字と解釈している事
    によってたまたま良い感じに振る舞っている。

    a 対応方法の一つは grapheme cluster を一つの私用文字に置き換えて取り扱う方法。
      この方法を取ればカーソル移動や文字の削除等は自然にできる様になる。

      後は入力時と出力時に変換を実行すれば良い。入力時に関しては文字挿入時に変
      換を実行すれば良い。出力時 (コマンド実行時) には逆方向に変換すれば良い。
      入力時に関しては ble-edit/content/reset で変換を行えば良いのではないかと
      いう気がする。

      問題は履歴検索である様な気がする。検索する時には文字列を変換してから検索
      する必要がある。その時にカーソル位置なども変換しなければならない。更に、
      検索して一致が見つかった時にまたカーソル位置を復元する必要がある。

      ? 此処で問題になるのが検索に於いて書記素の部分的な一致を許すのかという事。
        本来の文字列に復元して検索するとすると中途半端な位置で一致する事になる
        気がする。

      * 或いは逆に履歴の方を変換して保持するという手もあるだろうか。然し、その
        時に問題になるのは履歴の全項目について変換を実行しなければならないので
        重いという事。更に awk で処理するにしても私用文字と書記素クラスタとの対
        応表をどうやって bash と共有するのかという問題が生じる。

        a 既に登録されている物に関してはその codepoint を利用したいし、まだ登録
          されていない物がある場合には新しい項目を bash に反映させる必要がある。
          この方法を採用すると可也面倒な処理が必要になる。

        b 或いは、予め対応表を固定しておくというのも手であるが ZWJ sequence 等
          も考えると無限にある。ZWJ sequence は対応しないというのも手である。然
          し将来的な事を考えると中途半端な手法で無駄に複雑にはしたくない。

      * vim のバイト数による移動に関しては注意が必要になる。私用領域の代替文字
        のバイト数で換算される事になる。この方法を採用した場合にはその程度の不
        都合については我慢する必要がある。

    b また別の対応方法は emoji sequence をそのまま文字列として保持して、textmap
      やカーソル移動、一文字削除 etc の側で正しく処理するという事。然し、エラー
      着色なども考えると中途半端な箇所で SGR を挟む訳にも行かないので着色や構文
      解析のレベルでも grapheme cluster を意識する必要が出てくる。

      * 全ての widget について注意深く grapheme clusters に対応する必要がある。
        カーソル移動、一文字削除、etc. 然し、これらに関しては実は codepoint 単
        位の操作になってもまあ許せるのではないだろうか。

        ? readline について: 然し、readline は上手にその辺りを処理できている様
          にも見える。ただ、これは OS の mb 実装が上手に面倒を見てくれているの
          だという見方もできる。恐らく "一文字進む" とかそう言った処理を行う時
          に grapheme cluster 単位で処理してくれているという事なのではあるまい
          か。

          然し、そうすると "一文字を表現するのに要するバイト数" の過程に狂いが
          生じるのではないかという気もする。その辺りがどうなっているのかは気に
          なる所である。

        Readline が Unicode の要求通りの動作を実行できているという事を考えると
        codepoint 単位の操作というのは余り良くないかもしれない。一方で zsh はそ
        の辺りを適当に処理する事ができている様な気もする。

      * 再描画に際しては dirty range の端点が書記素クラスタの内部の中途半端な位
        置に発生すると厄介な事になるので拡張する必要がある。

      * コマンド実行や履歴検索に関しては特に細かい事を気にする必要はない。然し、
        カーソル位置の設定に関しては依然として注意が必要である。

      * カーソル移動について。

        a 移動する度に位置を cluster boundary に調整する必要があるのではないか。

          x よく考えたら、調整するにしてもどちらの端に調整するのかという問題が
          ある。例えば、左から右に一文字進んでそれが cluter の内部にある時に、
          また左端に調整してしまうとカーソルを移動する事ができなくなってしまう。

        b 或いはカーソル移動をする時には (例えば文字数で)、一文字ずつ進んでいか
          ないと cluster を認識した移動にはならない。

        c 調整する方向を前にいた位置を参考にして決めるという実装も可能かもしれ
          ないがその様な ad hoc な方法で自然な動作になるのかは不明である。

        d そもそも調整する必要があるのかという話。カーソル移動は文字単位で良い
          のではないか。しかしそうすると書記素の真ん中に文字を新しく挿入した時
          の処理が非自明になる。取り敢えず textmap の配置再計算に際しては前後の
          cluster 境界まで dirty range を拡張して処理する必要がある。その他の構
          文解析などの dirty range も同様である。という事を考えれば dirty range
          拡張は別に textmap で行う必要はなくて、reset の段階で実行しておけば良
          い。

        うーん。この手法で行くとしたら d の方針が現実的である。カーソル移動の文
        字を書記素単位に変更するのはあらゆる所に影響が出るので大変である。

      * textmap に於いて grapheme cluster をどの様に取り扱うのかというのは非自
        明である。先ず dirty range を grapheme cluster boundary にまで拡張する。
        その上で grapheme cluster の2文字目以降には0幅を割り当てる。といった具
        合になるのだろうか。座標から文字を特定しようとした時にどのような振る舞
        いになるのかも非自明である。

        着色に関しても textmap に於いて土台の文字の方に全て記録する様にして、0
        幅になった物には空文字列を設定する事にすれば問題は発生しなくなる。其処
        まで考えていくと実は構文解析ですら中途半端になっても大丈夫なのではない
        だろうか。つまり textmap に対する修正だけで全部行ける?

        残る問題はゼロ幅の文字があっても座標決定等で無限ループなどにならないか
        という事。

    [実装]

    grapheme clusters について真面目に考える前に UAX を改めてまとめるのが先の気
    がする。UAX は最初から順に読んでいったが実のところ重要なのは 3.1.1 だけだっ
    た。他は全て御託である。

    * done: Grapheme_Cluster_Break 表の作成

      さて、実装するに当たって一番最初にする必要があるのは、
      Grapheme_Cluster_Break プロパティの表を入手するという事。
      http://www.unicode.org/Public/UCD/latest/ucd/auxiliary/GraphemeBreakProperty.txt
      にあるそうだ。これを加工して使える様にする。加工するスクリプトは何処に置
      くのが良いだろうか。emoji_version の時にはどうしたろうかと思って 3f6c9b9
      を確認したがテーブルの生成に使ったスクリプトは見当たらない。
      git@github.com:akinomyoga/unidata にも何もなかった。と思ったが
      emoji_version の開発 commit は d1f8c27 だった。そして生成スクリプトは
      make_command.sh の update-emoji-database にあった。./make_command.sh のリ
      ストの一番下にあった所為か見逃していた。

      どの様な表現にするのが最も良いだろうか。単一のコードポイントで或る
      Grapheme_Cluster_Break を持っている時には単に配列に格納するのが良い気がす
      る。それ以外の範囲で値を持っている物に関してはどの様にするのが良いだろう
      か。何しろ様々な値を取る可能性があるので、単に境界を並べた配列から検索す
      るだけでは済まない。一つの方法は、範囲の先頭については直接配列に値を入れ
      る事にする。二分探索で範囲の先頭を求めて、その後で配列を参照して値を取り
      出す。というのが良い気がする。取り敢えずどの様な分布になっているのかを確
      認する必要がある気がする。

      * 孤立 Property は 664 個存在した。更に範囲先頭も含める。範囲は 487 である。
        配列項目の数は 664+487*2 = 1618 になる。

        因みに二個連続迄を孤立と見做す事にすると 980 個の孤立があり、範囲は 304
        にまで減少する。配列項目の数は 980 + 304*2 = 1588 になる。

        3個連続迄直接登録にすると 1157 個の直接登録と、239 の範囲登録がある。配
        列項目の数は 1157+239*2 = 1635 になり大きさが多少増える。4個の時は
        1321/191 になり、配列の大きさは 1703 になり益々増える。5個の時は、
        1426/173/1772。10個にすると 2067/80/2217 という具合に増えていく。例えば
        配列項目を最小の2倍まで許すとすると、実は可也の物を直接登録しても良いの
        ではないかという気がしてくる。50にしたら15818/18なので駄目。30でも
        14291/33なので駄目。20にしたら2676/45 なので丁度よいぐらい。

        然しまあ速度をそんなに重視しても仕方がない気がする。取り敢えず最小であ
        る 2 個連続までを直接登録する事にする。

      * \p{Extended_Pictographic} に対する判定も追加しなければならない。という
        か\p{Extended_Pictographic} は Grapheme_Cluster_Break の細分になってい
        るのだろうか。つまり、全て Other だと良い。Extended_Pictographic が変な
        性質を持っているとは思い難い。何か持っているとしても Regional_Indicator
        程度であると期待したい。

        うーん。Extended_Pictographic 属性は emoji-data.txt に含まれている様だ。
        これも emoji version 毎に管理するべきなのだろうか。取り敢えずの実装とし
        ては最新版を使う事にする。

        調べた限りに於いては Extended_Pictographic は全て Other の様である。な
        ので何も気にしなくて良い。取り敢えず最初の boundary を特定するコードに
        ついては書いた。

    * done: find-previous-boundary のテストも追加したい。

      →テストを追加してみたところ見事にミスが見つかった。やはりテストをつけて
      よかった。然し、まあ結局はテストを追加したような気もする。更に
      find-previous に関してもテストを追加するべき気がする。テストを追加した。
      やはり色々ミスが見つかった。そもそもデータの生成にも誤りが見つかった。

    * done: Unicode のページにテストケースが見つかった。沢山ある。これらを
      import する。行数が沢山あるので圧縮したい。→OKテストケースが 2000 行あっ
      たのを 100 行程度にまで小さくした。

      またこれらのテストケースにより間違いも発見されたのでそれを後で修正する必
      要がある。

      x 2件は CRLF の規則を変更した事による物。

      x Pictographic Extend* ZWJ Pictographic で位置の決定に失敗している気がす
        る。ZWJ:Pictographic の処理に於いて local ret を宣言してしまっていた所
        為で戻り値が反映されなくなっていたのを修正した。

      x 未だ問題が発生している。Extend を Extended と間違えていた。

      x 他はハングルに対する規則が欠けていた。

      OK これでテストも全て通る様になった。

    * ok: 次の問題は如何にして効率的に文字幅を実装するかという事である。
      うーん。効率はさておいて取り敢えず実装する事にする?

      Prepend さえ無ければ前の文字に付加していくだけで十分の筈である。絵文字で
      ない文字に Emoji_Modifier がついた時に文字の幅を変更するのかというのは謎
      である。更に Variation Selector によって幅が変化する場合についても考える
      必要がある。うーん。然し…Variation Selector で絵文字かそうかを切り替える
      という話ならば Variation Selector の値を見て幅を変更すれば良い。然しこれ
      は幅が遡って修正されるという事を意味する。やはり Grapheme_Cluster を特定
      して処理する必要があるのだろうか。然し、全ての文字について
      Grapheme_Cluster を特定して処理していたら面倒な事この上ない。ASCII だけに
      ついて処理をスキップすれば良いだろうか。日本語の文章についてはどうする?
      実は Other だけスキップする様にする事が可能だったりしないか? と思ったが、
      やはり Encoding に依存しない実装になっている限りは難しい様にも思われる。
      UTF-8 の時にだけ特別扱いするのも変な気がする。

      やはり Grapheme cluster を特定して実装する必要があるだろうか。

      * 最初の文字が非ASCIIの場合には Grapheme_cluster を特定して処理する。最初
        の要素に全ての文字を投入するというので良い気がするが、実は core の部分
        に指定しても良いのかもしれない。然し、カーソルを移動した後の操作などを
        考えるとやはり最初の要素に全ての文字を入れる様に実装しないと処理として
        一貫しない感じになる。因みにこの実装の時にはカーソル上下移動した直後に
        は、零幅文字の"後"に index を配置するべきである。

      * ASCII文字の場合には最後の文字について Grapheme extension を計算すれば十
        分である。

      処理を開始する境界の特定ができた暁にはこの手法が最も良い気がする。
      Grapheme cluster とその幅を計算する関数を実装してそれを呼び出す様にする。
      また、対応する文字列と codepoint の数も計算する様にする。xenl のない端末
      の場合に行末で Grapheme cluster を構築した時にどうなるかは謎。受信時に
      Grapheme cluster を構築してから挿入するタイプの端末ならちゃんとくっつく
      (然し timeout などで離れる)。前の行に何があるか見てくっつける実装でもくっ
      つく (その時行末が Folding とマークされている時に限りくっつく実装と関係な
      くくっつく実装とが存在しそうである)。何も考えていない端末だと離れてしまう。
      うーん。取り敢えずくっつくと思って実装しておくのが良い気がする。Grapheme
      cluster の対応まで考えたら端末は xenl にせざるを得ない気がする。

    * reject: 使わないかもしれないが実装の確認の為に next boundary を実装するの
      が良い気がする→結局より高機能な match を定義したので next boundary を個
      別に実装する必要は全くなくなった。

    * done: GraphemeClusterBreak/match という関数を実装

    * done: textmap を最初に修正する。

      * done: 取り敢えず非ASCII printable については実装した。

      * done: 次は ASCII の末尾で extend する事について考える。

      * done: variation selector について考慮に入れる。調べると U+FE0E が TPVS
        で FE0F が EPVS である。それぞれ非Emoji/Emojiの切り替えを行う。

      取り敢えずはこれで良い気がする。動作確認を先ずは行う。

    * 余談: Unicode は 11x64k の文字が原理的に存在する。bit で表現するとすれば
      88kB のデータサイズになる。50 の Property を考えるとすると 4.4MB のデータ
      サイズになる。小さいとは言えないがそれほど大きいとも言えない。然し、考え
      るに漢字などの領域は自明な値になっている筈なので容量は削減できる筈である。
      例えば、256文字ずつ組みにして考えるとすれば、最初のインデックスで選別すれ
      ば最低でも 1/10 程度には圧縮できるのではないだろうかという気がする。まあ、
      余り考えても仕方のない事かもしれないが。

    * ok: 位置から文字を特定する関数をちゃんと修正する。特にその位置の最後の文
      字に移動する様に修正したい。

      現在の ble/textmap#get-index-at の実装について確認する。基本的に f(l) <=
      x < f(u) を保つように範囲を狭めていっている。最終的に l と u の間隔が 1
      になる迄続ける。この時に l==u になる事はない。l と u は実の所境界に対応し
      ていて、f(u) は対応する文字開始位置を返す。

      例えば今 A E E E B (A, B は幅 1 で E は幅 0) という具合になっていて位置 1
      に対応する index を見つけようとすると… u=4 l=5 しか条件を満たす位置は存
      在しない。つまり、期待通りに Extend の後の位置が求められる筈。

      これについてはテストでも作成して確認するのが良い気がする。
      →OK ちゃんと動いている。

    * ok: Emoji sequence を grapheme cluster とは別に処理する必要があるか

      Emoji sequences に関してはまた別に表を保持して合成する等しなければならな
      い。Emoji sequence は incremental だろうか。つまり ABC が Emoji sequence
      であれば AB も Emoji sequence だろうか。まあ、それらの差異については気に
      しなくて良いというか、一般にはそうではないとした実装にしておくのが安全な
      気がする。何れにしても Emoji sequence の表の形式を考えておく必要がある気
      がする。

      Emoji_modifier については Grapheme cluster の考慮に入っているのだろうか。
      →確認した所、ちゃんと考慮に入っていた。うーん。然し…普通の半角文字に対
      して Emoji_Modifier が適用されていたりする場合には一体どういう事になるの
      だろうか。気になる。

      実は定義済みの Emoji seuquences は全部 Emoji_Modifer による実装で、既に
      Grapheme cluster に組み込まれているのではないかという気がしてきた。これに
      ついてはまた後で確認する事にする。

      定義済みの Emoji sequence について2文字目以降の文字種について確認する。

      $ for code in $(awk 'sub(/;.*/,"") {$1="";print}' out/data/unicode-emoji-14.0.txt |
          grep -Eo '\b[[:xdigit:]]+\b' | sort -u); do
          ble/unicode/GraphemeCluster/c2break $((16#$code)); echo $ret
        done | sort -u
      12 .. Emoji
      2 .. ZWJ
      4 .. Extend
      6 .. RI

      うーん。これだけだと Emoji が ZWJ で接続されているのかそうでないのかが分
      からない。やはりちゃんとスクリプトを書いて変換して確認する必要がある気が
      する。どう言った属性値のシーケンスが存在するのか確認する。以下の種類のシー
      ケンスが存在する。4 は単に無視して良い。1 1 1 1 というのは気になる…。他
      は全て Grapheme Cluster の形式をしている→これは単に凡例を拾っているだけ
      だった。

      seq: 0 4
      seq: 0 4 4
      seq: 12
      seq: 12 2 12
      seq: 12 2 12 2 12
      seq: 12 2 12 2 12 2 12
      seq: 12 2 12 4
      seq: 12 2 12 4 2 12
      seq: 12 2 12 4 2 12 2 12
      seq: 12 4
      seq: 12 4 2 12
      seq: 12 4 2 12 2 12 2 12 4
      seq: 12 4 2 12 2 12 4
      seq: 12 4 2 12 4
      seq: 12 4 2 12 4 2 12 2 12 4
      seq: 12 4 2 12 4 2 12 4
      seq: 12 4 4 4 4 4 4
      seq: 4
      seq: 6 6

      という訳で孤立した Extend を除き全て grapheme cluster である。なので
      emoji sequence については grapheme cluster に加えて気にする必要はない。

    * done: unqualified は既定では Emoji presentation ではなく Text presentation にする

      kitty で動作確認した所、文字によって既定で text presentation か emoji
      presentation かがまちまちの様である。うーん。どの様にするのが良いか。。
      EPVS で初めて絵文字になる物に関しては実は単に "絵文字ではない" という事に
      して良い気がする。現在の設定ではユーザーが個別に絵文字か絵文字でないか指
      定できるような設計になっていただろうか。

      というよりそもそも問題の U+2660 が既定で text か emoji かというのが規格化
      されていたりはしないのだろうか。emoji のデータベースを確認すると
      fully-qualified, unqualified 等というのがある様だ。

      うーん。端末を確認してみた所、絵文字にまともに対応しているのは kitty/vte
      系列の様であるからこれの動作に倣う事にした。他の端末の動作に関しては追々
      対応していく事にする。そして kitty/vte では unqualified は絵文字ではない
      様なのでそれに倣う事にする。

    * done: trace-text の実装。

    * done: trace の実装。

      うーん。lc は困る。基底文字だけを指定すると lc によって装飾が全て消えてし
      まう。一方で、一番最後の文字を指定したとしても、端末によっては連続してい
      ない出力に関しては前の基底文字を削除してしまうかもしれないし、またそうで
      なかったとしても Extend が余分に追加されてしまう事になる。なので、書記素
      クラスター全体を出力し直さなければならない筈だが lc (整数値) では表現でき
      ない。

      これに本当に対応しようと思ったら lc lg の組ではなくて lcs lw lg の組に拡
      張するしかない。然し、そもそも lc lg は現在ではデバグ用としてしか意味を為
      さないので其処までちゃんと対応する労力を割く必要があるかというと、ない。
      一応項目として残しておく事にする。

    * done: 制御文字を ^X 等の形に変換するのは GraphemeClusterBreak/match の側
      でやった方が良い気がする。然し本当にそうだろうか。これから match を
      trace, trace-text でも共有しようと考えている。trace, trace-text での実装
      をしてから制御文字を変換するかどうか判断するという方が良い。

    * done: 零幅文字: 完全に零幅の単一文字 (Control Character) に関してはやはり
      ASCII rep で置き換えるべきの様に思われる。これについてはまた別項目で取り
      扱うべきなのだろう。core の欠けている Extend chars に関しては台字として
      space か或いは専用の○が存在した気がする。

      trace に於いては直接出力したい。なので取り敢えず Unicode 制御文字について
      はゼロ幅で出力する事にする。

    * ok: 関数名を再考。GraphemeClusterBreak はプロパティ名である。それよりは
      ble/unicode/GraphemeCluster/* の形で様々の機能を提供するべきではないか。
      もしくは ble/unicode/grapheme-cluster/*. うーん。変数名等を考えると
      ble/unicode/GraphemeCluster/* の方が良い気がする。変数名も一緒に考え直す
      と良い。

      ある程度置き換えたがまた後で改めて考える。特に変数名を
      GraphemeClusterBreak のままにするか GraphemeCluster_Break と分けるか。うー
      ん。分けずに今のままで良い気がする。

    [修正]

    * done: kitty は fully-qualified, minimally-qualified, component については
      肌の色は幅0で髪については幅2にしている様だ。実際の Unicode の例を見ても髪
      は単一の文字で肌の色は Extend の様に見える。

    * done: screen, mlterm, terminology 辺りは unqualified も参照している気がす
      る。unqualified のテーブルも作るか、或いは、現在のテーブルを拡張して
      qualified, unqualified の区別もできる様にするか。うーん。下手にメモリ使用
      量が増えるのも否なので一つの配列で qualified/unqualified の両方に対応でき
      る様にするのが良い気がする。序に skin/hair の区別もできる様にする?

      もし unqualified も判定できる様にしようと思ったら現在の実装を変更する必要
      がある。現在は境界に +1 をして行って、奇数の値を持つ境界のみを抜き出す事
      によって emoji の範囲を取得している。然し、複数の種類の要素を区別する為に
      は、同じ方法は使えない。うーん。種類毎に bit を用意して xor して行けば、
      境界はちゃんと抜き出す事ができる。然し問題はそれが始まりの境界なのかそれ
      とも終わりの境界なのかを判定する事ができないという事にある。という事を考
      えると、始まりである事を表す marker も作った方が良いのでは。うーん。その
      様な事をするぐらいであれば、普通に始まりと終わりの bit を用意しておけば良
      いだけの気がする。

      うーん。始まりを設定する時にその属性値を別の配列に記録する事にするという
      事。また、境界を検知する為には xor で記録するという事。より良い方法はある
      だろうか。単に前回の属性値を覚えておいてそれと同じかどうかを確認するだけ
      で良いのではないか。終端に関しては何も記録しない。

      unqualified にも対応して取り敢えず試した全ての端末で絵文字の幅計算が一致
      する様になった。

    * 0x1F3FB..0x1F3FF や 0x1F202, 0x1F237 は振る舞いが異なる実装が多い。実は古
      い Unicode では属性が違ったという事だろうか。確認する必要がある気がする。
      と思って unicode.org からファイルを持って来ようとしたがどうも unicode.org
      が停止している。

      Internet Archive から GraphemeCluster について各 version をダウンロードし
      て diff して見ると破壊的変更がない訳ではない様だ。

      Unicode 6.0.0 で以下の属性が削除されている (別の属性が割り当てられた可能性もあるが確かめていない)
      -06DE          ; Extend # Me       ARABIC START OF RUB EL HIZB
      -0E30          ; Extend # Lo       THAI CHARACTER SARA A
      -0E32..0E33    ; Extend # Lo   [2] THAI CHARACTER SARA AA..THAI CHARACTER SARA AM
      -0E45          ; Extend # Lo       THAI CHARACTER LAKKHANGYAO
      -0EB0          ; Extend # Lo       LAO VOWEL SIGN A
      -0EB2..0EB3    ; Extend # Lo   [2] LAO VOWEL SIGN AA..LAO VOWEL SIGN AM

      うーん。見た感じ結構書き換わっている。やはり各 version について対応するべ
      きか。取り敢えず問題の 1F3FB が各 version でどうなっているか確認する。ど
      うやら 1F3FB は 9.0 で E_Modifier として導入されて 11.0 で Extend に変更
      になった様である。うーん。これは当時の規則を参照する必要があるのだろうか。

      1F202,1F237 に関しては GraphemeCluster 的には特に何もないようである。これ
      は Emoji の規格の側の取り扱いの変化だろうか。うーん。規格の各 version の
      記述を観察してみたが、1F202 は最初から一貫して unqualified である。もっと
      ちゃんと書くと 4.0 ではそもそもリストに載っていない。5.0 では
      non-fully-qualified という名前。12.0 から unqualified という名前に変更さ
      れた。という事は単に OS の locale の wcwidth が変な値を返しているという事
      なのだろうという気がする。

      実の所、1F3FB の振る舞いに関しても OS の wcwidth が怪しいのではないかとい
      う気もしてくる。

      wcwidth (C.UTF-8) の振る舞いを確認すると 1F202,1F237 は 2 を返している。
      1F3FB..1F3FF も 2 を返している。これらが変な風に振る舞う原因なのだろうか。

    * done: urxvt についても確認する
    * done: mintty についても確認する

    * fixed: 2021-06-21 複数行編集でプロンプトの末尾が消去される? rprompt 関連の可能性

      →これは grapheme cluster の対応によって発生する様になった問題の様だ。つま
      り何らかの文字列の幅計算に失敗しているという事になる。然し、プロンプト自体
      は ASCII だけで構成されている筈で幅計算に問題が発生するというのも不思議であ
      る。或いは、一緒に変更した別の部分が問題の原因になっているのかもしれない。

      もしかして改行が ^J の幅である 2 で計算されている可能性? だとすると rps1 や
      status_line は関係なくどの行でも2文字ずつ内容が削られてしまう筈である。実際
      に試してみた所、確かに rps1 や status_line がなくても問題が発生する。更にど
      の行も次の行に行く瞬間に2文字右にずれて表示されて、更に次の行の内容を入力し
      ようとすると左に2文字ずれて再描画される。何れにしても2文字のずれが生じてい
      るのは確かである。

      textmap の問題である事を確認した。開業直後の x の位置が 2 になっている。

    * UAX 11 を再確認した所、何と combining marks や nonspacing characters に関
      しては実は実際の幅に関係なく言語に応じて N, Na, W 等が割り当てられるとい
      う。なので、素直に UAX11 の表だけで文字幅を決定するのは危険という事である。

      取り敢えず grapheme clusters の中に於いて combining や nonspacing につい
      てもちゃんと文字幅を計算できる様にしたい。その為に c2w は
      combining/nonspacing に対して 0 を返す様に変更したい。基本の文字幅テーブ
      ルも他の物と同様に実装したい。と思ったが最初に下8bitを落としたテーブルで
      判定するのが妥当の気がする。SMP に関しては全体に対して適用するという事に
      する。

      | うーん。取り敢えず wcwidth が返す結果を再現するのが一つの方法の気がする。
      | General Category と UAX11 の組み合わせで再現できるだろうか。取り敢えず
      | GeneralCategory のテーブルを作成してみたが、可也サイズが大きい。然し、個
      | 別に属性を切り出すよりは良い気がするので取り敢えずこれで色々調べてみるの
      | が良い気がする。というか、実際には c2w のテーブルさえ持っていれば良いので、
      | 最終的にはこの GeneralCategory のテーブルは ble.sh には含めなくても良いの
      | かもしれない。
      |
      | さて、それぞれの category について見ていく。Mn は nonspacing mark, Mc は
      | spacing combining mark (??), Me は mark enclosing である。Cc は制御文字で
      | Cf は hyphen, ZWJ, ZWNJ 等色々。Cs は surrogate で Co は私用領域。Cn は未
      | 使用・予約文字。この中で特別な値を割り当てる必要があるのは Mn, Cc 及び一
      | 部の Cf だろうと思われる。Me は一体何だろうか。うーん。grep で見てみると
      | これらも combining の様である。Mc も combining の様な気がする。
      |
      | 0488;COMBINING CYRILLIC HUNDRED THOUSANDS SIGN;Me;0;NSM;;;;;N;;;;;
      | 0489;COMBINING CYRILLIC MILLIONS SIGN;Me;0;NSM;;;;;N;;;;;
      | 1ABE;COMBINING PARENTHESES OVERLAY;Me;0;NSM;;;;;N;;;;;
      | 20DD;COMBINING ENCLOSING CIRCLE;Me;0;NSM;;;;;N;ENCLOSING CIRCLE;;;;
      | 20DE;COMBINING ENCLOSING SQUARE;Me;0;NSM;;;;;N;ENCLOSING SQUARE;;;;
      | 20DF;COMBINING ENCLOSING DIAMOND;Me;0;NSM;;;;;N;ENCLOSING DIAMOND;;;;
      | 20E0;COMBINING ENCLOSING CIRCLE BACKSLASH;Me;0;NSM;;;;;N;ENCLOSING CIRCLE SLASH;;;;
      | 20E2;COMBINING ENCLOSING SCREEN;Me;0;NSM;;;;;N;;;;;
      | 20E3;COMBINING ENCLOSING KEYCAP;Me;0;NSM;;;;;N;;;;;
      | 20E4;COMBINING ENCLOSING UPWARD POINTING TRIANGLE;Me;0;NSM;;;;;N;;;;;
      | A670;COMBINING CYRILLIC TEN MILLIONS SIGN;Me;0;NSM;;;;;N;;;;;
      | A671;COMBINING CYRILLIC HUNDRED MILLIONS SIGN;Me;0;NSM;;;;;N;;;;;
      | A672;COMBINING CYRILLIC THOUSAND MILLIONS SIGN;Me;0;NSM;;;;;N;;;;;
      |
      | そうすると Mn/Mc/Me は全て combining として幅0にする? うーん。SpacingMark
      | を確認してみるとどうも Mc になっている。うーん。という事は Mc については
      | EAW による幅をそのまま与えるべきだろうか。分からないので wcwidth の結果に
      | 従うというので良い様な気もする。という事は何れにしても wcwidth を自前で再
      | 現するという試みが必要である。
      |
      | うーん。EastAsianWidth を確認してみた所、実は既に此処に General Category
      | も附記されている。単にこれを元にして幅を決定すれば良いだけなのでは?
      | EastAsianWidth 及び General Category を元にして求めた比較を実装した。
      | Mn|Me|Cf を幅 1 にして Unicode 11.0 を使うと最も差分が小さくなる。然しそ
      | れでも Cf に関しては wcwidth は 0 だったり 1 だったりまちまちの結果を返す
      | 様である。
      |
      | 2021-09-14 取り敢えず文字幅に関してはちゃんと決着を付けなければならない。
      | 改めて現状について確認する。GenCat 及び EAW を元にした幅は
      | out/data/c2w.eaw-*.txt に出力してある。このデータは range で出力している
      | ので、それぞれどの文字についてずれが発生しているのかは確認しにくい事に注
      | 意する。
      |
      | 先ずは違いを分かりやすく取り出す様に修正しなければならない。うーん。ずれ
      | のある各文字について GenCat や文字の名前について確認したいという事を考え
      | ると、C++ から EAW のデータを読んで処理する方が良いのだろうか。
      |
      | 取り敢えず時間を区切って実装することにするのが良い。先ずは形式を確認する。
      |
      | % * Co については -1 の時と 1 の時がある。
      | %
      | %   調べてみると wcwidth が 1 を返すのは以下の領域のみである。
      | %   これらに文字が割り当てられているとは思えないが…
      | %
      | %   e000..f8ff wcwidth=1 width(eaw=3 gencat=Co)=-1
      | %   f0000..ffffd wcwidth=1 width(eaw=3 gencat=Co)=-1
      | %   100000..10fffd wcwidth=1 width(eaw=3 gencat=Co)=-1
      | %
      | %   →と思ったが unassigned に誤って Co を割り当てていたのが駄目だった。
      | %   unassigned に対して Cn を指定して Cn に対して -1 を返す様にしたら、
      | %   残る Co は上の領域だけでしかも全て A であり、これは cjkwidth west と
      | %   一貫している。
      | %
      | % * wcwidth は EAW=W の領域の Co に対しても -1 を返す。なので、-1 を単純に
      | %   1 にすれば良いという訳でもない。
      |
      | * Cc に関しては NUL 以外は wcwidth で -1 になる。
      |   ble.sh では NUL は取り扱えないのでこのずれは無視して良い気がする。
      |
      |   0000 wcwidth=0 width(eaw=1,gencat=Cc)=-1
      |
      | * Cf については wcwidth は殆ど 0 を返すが一部の物について 1 を返す。
      |
      |   00ad wcwidth=1 width(eaw=3,gencat=Cf)=0       SHY(soft-hyphen)
      |   0600..0605 wcwidth=1 width(eaw=1,gencat=Cf)=0 アラブの数字らしい。何故Cfなのかは謎
      |   06dd wcwidth=1 width(eaw=1,gencat=Cf)=0       ARABIC END OF AYAH (アラビア語?)
      |   070f wcwidth=1 width(eaw=1,gencat=Cf)=0       SYRIAC ABBREVIATION MARK (シリア短縮記号?)
      |   08e2 wcwidth=1 width(eaw=1,gencat=Cf)=0       ARABIC DISPUTED END OF AYAH (アラビア語)
      |   110bd wcwidth=1 width(eaw=1,gencat=Cf)=0      KAITHI NUMBER SIGN
      |   110cd wcwidth=1 width(eaw=1,gencat=Cf)=0      KAITHI NUMBER SIGN ABOVE
      |
      |   うーん。これらは emoji とは関係ない気がする。ので、emoji 関係の
      |   property を参照しても仕方がない気がする。個別に設定するしかないのだろうか。
      |
      | * Lo は以下の範囲のみ wcwidth が予測と異なる物になっている。
      |
      |   1160..11ff wcwidth=0 width(eaw=1,gencat=Lo)=1 ハングル字母
      |   3248..324f wcwidth=2 width(eaw=3,gencat=No)=1 囲み文字10-80
      |   4dc0..4dff wcwidth=2 width(eaw=1,gencat=So)=1 易経記号
      |
      |   うーん。一体誰が wcwidth のデータベースを作っているのかは謎だが…。
      |
      | 取り敢えず Fedora の wcwidth に合わせる形で実装することにして将来的に不都
      | 合があればその時に改めて環境依存性について考える事にする。また、将来的に
      | 別の環境の locale でも wcwidth の振る舞いを調べる必要が生じた時の為に、
      | これに使ったコードも残しておく事にする。

      → #D1645 にまとめ直した。

    段々と大掛かりになって来たので一旦現状で commit を作っておくべきな気がした。
    現在の状態は幾つか未だ課題があるものの中途半端な状態という訳でもない。課題
    についてまとめて別の項目で議論するべき気がする。

    [残っている課題] 別項目で議論

    * #T0008 SpacingMark, Prepend は grapheme cluster の修飾でありながらそれ自
      体が幅を持つ。つまり、grapheme cluster の幅を拡張する。従って、grapheme
      cluster の Extend についても width を grapheme cluster の幅の計算に加算す
      る必要がある。その為には c2w をちゃんと設計する必要がある。具体的には幅 0
      の Extend に対してはちゃんと 0 を返す様にする必要がある。

    * #D1645 上の為に c2w をちゃんと再設計する必要がある

2021-06-13

  * 2021-06-06 complete: auto-menu の振る舞いの調整 [#D1618]

    * ok: auto_menu に於いては empty_completion の抑制もするべき。というか一般
      に auto に対して抑制するべきの気がする。と思ったが、実際に実装を確認する
      と既にその様な実装になっていた。no-empty opts を指定していた。

    * reject: うーん。auto-menu を既定で on にする事も考えたがこれは流石にうる
      さい様な気がする。やはり好き嫌いが出るだろうから既定で on にするのは避け
      た方が良い様に思われる。然し、on にした時にはできるだけ自然な動作になる様
      に努めたい。

    * complete_limit_auto_menu?

      導入した。然し、complete_limit_auto_menu を導入すると複数の source から候
      補を生成した時に一部の source からの結果だけ抽出してしまう。その時点では
      それで良いかもしれないが menu-filter が走ると直ぐに候補の数が少なくなって
      候補がなくなってしまう。此処で改めて候補を生成したい所だが、

      a complete_limit に引っかかったら全体をキャンセルして中途半端な候補による
        menu は表示しない。

      b (no items) になったら改めて候補を再生成する。然し、これは何処に実装する
        べきだろうか。実装するとしたら menu-filter.idle の気がする。然し、その
        menu がどの様に start したかによって振る舞いを変えるべきではないか。例
        えばユーザーが明示的に source を指定して候補を生成した場合には勝手に再
        生成すると元々のユーザーの与えた絞り込みが消えてしまう。

        或いは候補の生成に要した設定を何処かに記録しておいて同じ設定で補完を開
        始するという事。入力内容が増えた事によって絞り込み候補が少なくなったり
        して曖昧補完に移行するなどの事が考えられる。

      同様に menu-filter.idle の開始点よりも前に移動した場合も候補を再生成する
      べきなのではないだろうか。

  * 2021-06-10 prompt: [最適化] 単純なプロンプト内容は ${PS1@P} で展開? [#D1617]

    プロンプトが単純な内容しか含んでいない時には ${PS@P} で計算を省略できるので
    はないか。つまり、\X で特別な物を含んでいない限りは bashに任せる事ができる。
    (一方で \w の追跡などについては個別に判定する必要がある気もする。)

    然しそんなに速度向上には寄与しないのではないかという気もする。結局 trace は
    しなければならないからである。

    取り敢えず PS1 が単純化どうかの判定をどうするか。\ の後に "安全" でない文字
    が続いている物は全て除外するのが良い様に思われる。"安全" な文字を列挙する。

    - 0-7aenrdtAT@DhHjlsuvV[]!$\
    - wW ... これらには add-hash を付加したい様に思われる。
    - # ... これは駄目。ble.sh 的には内部の bash の番号をちゃんと更新できていない。

    意外と簡単に実装できた。動いている。\# も大丈夫。\w の更新も大丈夫。

  * 2021-06-06 prompt: エラーはまとめて出力するべき? [#D1616]

    現在の実装だとエラーを直接その場に出力する仕組みになっている。然しそうでは
    なくて、例えば新しい行を表示する直前等にエラーメッセージを出力するべきの気
    がする。その場合にはプロンプトの類を一旦仕舞うなどの工夫が必要である。或い
    は、trace 等で計測して出力する事になる。trace で計測したとしても画面の範囲
    よりも大きい場合には表示しきれないという事等色々考えるとプロンプトの類を一
    旦仕舞うのが妥当な気がする。

    特にプロンプトに関連するエラーはプロンプトの表示直前にまとめて表示するのが
    良いのではないか。と思ったが、プロンプトの部分更新でもエラーは発生する。と
    いう事など考えていくと微妙。というかプロンプトの処理に関しては、
    visible-bell で良いのではないかという気がする。

    というかそもそもエラーメッセージを表示する意味はあるのだろうか。認識してい
    なかったら単純に \q{...} のまま出力すれば良いのではないか。うーん。取り敢え
    ずは \q{...} の形でそのまま出力すると共に、visible-bell でも表示する事にし
    た。

2021-06-12

  * benchmark: ble-measure が bash-4.4 未満で結果を返さなくなっている [#D1615]

    これは local TIMEFORMAT= を指定したのが原因だった。
    TIMEFORMAT が unset の時には既定の結果になるが、
    TIMEFORMAT が空文字列の場合には既定の結果にはならないのだった。
    この際なので TIMEFORMAT に単純な文字列を指定して計測する事にした。

    この問題は割合最近に埋め込んだ物の気がする。確かめてみる。bbc2a904
    src/benchmark.sh 2021-05-19 11:25:18 +0900 である。うーん。この commit は雑
    多の物をまとめた commit である。特に ble.pp のロード時間計測コードを
    TIMEFORMAT を使って見やすくした時にその序として benchmark.sh で TIMEFORMAT
    が書き換えられていた時の対策のコードをちゃんとテストせずに書き加えたのが原
    因であった。

  * 2021-05-15 util: ^A, ^? を含む排列に関連するテストが失敗している [#D1614]

    % ^A 及び ^? に対する declare -p 補正が動かなくなっている @ bash-3.2
    %
    % #D1522 に於いて bash-3.2 以下では配列表記で ^A が ^A^A^A^A になる事を発見
    % したと思ったが、何故か今手許で試してみると ^A^A にしかなっていなくて以前
    % のコードでも良かったという事になる。再現するための条件が何かあるのだろう
    % か。例えばスクリプト内部では declare -p の結果は ^A^A^A^A になるなど。
    %
    % うーん。ble/util/assign を介すと確かに ^A^A^A^A になるがそれは scalar も
    % array も同様になっている。然し、#D1522 で対処した問題は配列の時にのみ起こっ
    % ていた問題の筈なのでこれは関係ない。
    %
    % 関数内のみで起こる問題の可能性? と思ったがそれも変である。実際に ^A^A^A^A
    % にならず ^A^A になっているのは関数内で実行している時である。対話でも ^A^A
    % にしかならない。
    %
    % 元々は memo/D1522.large-array-passing.sh に於いて発生していた問題だった。
    % 今となっては writearray の実装を使う様に変更した為に再現していない。うー
    % ん。分からないので、取り敢えず改めて各 version での振る舞いを整理してそれ
    % で OK とする事にする。
    %
    % 以下が実際にスクリプトを書いて実行してみた結果。
    %
    % * bash-3.0, 3.2, 3.2
    %   declare -- s="x^A^Ay^A^?z"
    %   declare -a a='([0]="x^A^A^A^Ay" [1]="z^A^A^A^?w")'
    % * bash-4.0, 4.1, 4.2, 4.3
    %   declare -- s="x^A^Ay^A^?z"
    %   declare -a a='([0]="x^A^Ay" [1]="z^A^?w")'
    % * bash-4.4, 5.0, 5.1
    %   declare -- s="x^Ay^?z"
    %   declare -a a=([0]=$'x\001y' [1]=$'z\177w')
    % * bash-dev
    %   declare -- s=$'x\001y\177z'
    %   declare -a a=([0]=$'x\001y' [1]=$'z\177w')
    %
    % うーん。やっぱり二重にエスケープされている気がする。
    % 発生する条件があるのだろうか。
    %
    % a 関数の中で実行すると発生しなくなる? そういう訳でもない様だ。
    % b interactive session で実行すると発生しなくなる? →そうでもない
    % c ble.sh をろーどしていると発生しなくなる? →そうでもない
    % d サブシェルで実行すると発生しない? →そうでもない
    %
    % うーん。これは寧ろチェックコードの方の問題だろうか?
    %
    % a コピーに関しては問題ない
    % b 出力に関しては
    % c 比較対象の "正解" を生成する時に "正解" が化けている。
    %   あー。これだった。修正した。というか正解はハードコードする事にした。


    結局問題は arr=(...) の形式でテスト用の配列を用意した時点で ^A や ^? が
    ^A^A や ^A^? に化けてしまっていた事にあった。それなのに、配列の中には ^A や
    ^? が正しく格納されているという前提で declare -p arr の結果だけに着目してい
    たのが混乱の原因だった。

    * 何と $'\c?' は Bash-4.4 と 4.3 以下で振る舞いが違う様だ。最近書いた関連
      するコードを fixup した。

    * 他にも類似の問題が生じている。これもテストの問題なのだろうか。

      L1482 で発生している問題。うーん。これもやはりテストの側の問題だった。
      というかどうやったら正確にテストする事ができるのか?

      色々試したが何だか変だ。これは出力する時の問題ではなくて、変数に代入する
      時の問題だろうか。特に配列に代入する時に発生する問題?

      →うわー。やっぱりそうだった。という事は今 writearray でやっている処理は
      正しくない。writearray でやっている処理は arr=() で代入した事によって壊れ
      ている内容を正しい物に修正するという様な処理を行っている事になる。


      * done: writearray 修正 (^A^A^A^A 対策コード除去)
      * done: print-definitions 修正 (^A^A^A^A 対策コード除去)
      * done: print-definitions の出力で arr=() の形式を避ける。
        print-definitions はどの様に修正したら良いのか非自明である。というのも
        ^A 及び ^? を含む時にどの様な内容を出力しても arr=() の形式を使っている
        限りは正しい値を代入することができないからである。

      取り敢えずこれについては修正した。OK

  * 2021-05-15 test: BUG 失敗する様になっている [#D1613]

    * quote-command の test に失敗している @ bash-4.3 直した

    * ^A, ^? を含む排列に関連するテストが動かなくなっている → #D1614
    * ble-measure が bash-4.4 未満で結果を返さなくなっている → #D1615

      これらについては別項目で処理する事にする。

  * main: DEBUG version の bash で警告を表示する [#D1612]

    relstatus が alp*|bet*|dev*|rc*|releng*|maint* の時にはロード時に "遅い" と
    いう事を警告するべきではないか。同時に wiki か README にも注意書きを書く必
    要はあるだろうか。

  * complete: "complete -p" 解析の修正 + 細かい修正 [#D1611]

    complete に対する細かい修正が溜まっているのでいい加減に push する。

    * 一つは quote された progcomp　が正しく unquote されずに続く complete -p
      の関数名抽出に渡っている問題の修正。

    他は m scan に関連する軽微なミスである。

    * local "${_ble_complete_cand_varnames[@]}" の localvar_inherit に対する対
      策が間違っている問題。

    * 文字数を数えるのに ${#ret[0]} の形式を使ってしまっている問題 (bash-3.0
      bug)

  * util: bleopt の unknown option の表示が空になる [#D1610]

    bleopt で誤ったオプション名を指定した時のエラーメッセージでオプション名が空
    文字列になっている。

  * prompt: \g{...} [#D1609]

    将来的に Bash が \g に対応するとしても \g{...} の形になるとは限らないし、ま
    た、\g 単体であれば \g と \g{...} を区別する事によって処理を分ければ良い。
    偶々 \g の次に {...} を書きたいという事もそうあるまい。

  * reject: idle: 時々自動的に表示更新をかけるべきではないか [#D1608]

    裏で処理が走っている間に状態が変化してそれを表示に反映させたい時にはどうす
    るのか。現在の実装だとその様な仕組みにはなっていない筈。例えば
    textarea#invalidate を実行した時にその場で反映されるだろうか。

    処理が一巡したら、もしくはn巡したら更新するのも良い気がする。否、時間を決め
    て置いてある程度時間が経ったら更新するというのでも良い。しかしそれならば、
    普通の task として n 秒置きに更新をかけるというので良い気がする。その様にし
    ておけば idle の他の処理が終わった後でも更新を確認し続ける様になるし自然な
    実装であるように思われる。

    それとは別に idle 内部の動作によって表示を更新する必要があるのであれば、そ
    の動作を起こした側でその場で更新をかけるか或いは新しく task を投入するかす
    るべきなのである。

  * util (bleopt): 遅延定義された設定項目の check [#D1607]

    airline: ble-reload する時に状態が書き換わってしまっているのに bleopt
    vim_airline_theme=light の儘なので初期化が正しく為されない。うーん。既定値
    から再設定される筈なのだがそれも正しく処理されていない? と思ったがそれは
    ble.sh のロード時に処理される事なので遅延ロードされるモジュールの設定には当
    て嵌まらないという事。遅延ロードされる時にはその場で "設定" を再現する必要
    があるのではないか? 然し、そうすると関連する関数が既に定義済みでないと正し
    く動作しない事になる。或いは bleopt -I vim_airline_@ 的な関数を最後に呼び出
    して最初期化を強制するという可能性もある。

    現在遅延定義される設定項目は恐らく vim_airline 及び vim_surround に限られる。
    complete, syntax は ble.sh に設定項目を定義しているので問題にならない。

    * done: vim-airline で bleopt -I vim_airline_@ を実行する

    * done: 他にも影響のある場所がないか確認する。特に bleopt/check:
      を定義しているオプションで、ble.pp の "bleopt -I" よりも後に実行
      される可能性のある物が対象である。

      確認した所 core-syntax.sh で定義されている check:filename_ls_colors が怪
      しい。と思って実際に確認してみた所ちゃんと対策は為されていた。今回のこの
      対策を bleopt -I を使う物に置き換える事にする。

    * ok: update wiki と思ったが、元々 bleopt はそんなに詳しく説明していなかっ
      た。bleopt -u　も bleopt -r も wiki には説明が書かれていないので、bleopt
      -I について今すぐに追加しなければならないという事はない気がする。一方で、
      bleopt のもっと詳しい説明についてはいつか書かなければならない。

  * prompt-git: bash 3 では async にできない→修正した [#D1606]

  * history: cygwin に於いて arg_offset を処理していない気がするが大丈夫なのか [#D1605]

    ble/builtin/history/.load-recent-entries から append:count=$delta という形
    で呼び出されている。Cygwin の時でも同様である。count により追加分だけが
    background で dump される様子である。arg_offset が使えない時には arg_count
    をクリアする等の工夫もされていない。つまり、Cygwin 上では正しく動かないとい
    う事? これを実装した時にどう考えていたのか後でログを確認する必要がある気が
    する。或いはもしかして何か ToDo に項目が残っていたりするだろうか。

    * 現在の実装について記録を確認

      うーん。何か ToDo に残っていないか探してみたが cygwin/Cygwin　では引っかか
      らない。次に arg_offset を導入した時のログを確認してみる。

      a 1bfc8ebe 2019-07-09 16:42:26 +0900 が怪しい。うーん。当時の記録を確認して
        みたが offset 等の実装の詳細に関する議論は全く残っていない。これは
        history.sh を導入した時の議論であって、恐らくこの時に現在の実装の様に
        history コマンドの模倣も実装してその過程で offset を導入した。

      b と思ったが、その前の f204bc73 src/edit.sh 2019-06-27 20:38:34 +0900 の段
        階で既に arg_offset は導入されていた様である。一応 offset がどうのこうの
        という議論はあるみたいだが、これはまた別の機能の offset の話の様である。
        この時の実装の arg_offset に関係する議論ではない様に見える。更に明示的に
        arg_offset で検索をかけてみたが done.txt の中には何も残っていない様である。

      c 更にその前の commit に行ってみたらもう arg_offset は残っていない。履歴の
        読み取りも直接 mapfile を呼び出しているに留まっている。

      うーん。或いは cygwin　では offset は使わない様になっていたという可能性はあ
      るだろうか。何故 Cygwin の事を考えずに変更を行ったのかかなり理解に苦しむ。
      うーん。それとも += を使う事にしていた可能性? うーん。然し再度確認してみて
      もその様な雰囲気は見られない。

    或いは実はちゃんと実装されていて Cygwin の時には arg_offset があっても問題
    ない様になっている可能性? うーん。そんな風になっている雰囲気は見られないが。。
    取り敢えず、Cygwin でもちゃんと途中からの追記になる様に修正する必要はあるだ
    ろう。

    * history: mapfile -O offset で読み取り始めると既存の項目がクリアされない様
      だが良いのか? これは Cygwin での実装をどの様にするのかという事にも関連し
      ている。

      現在の実装を見ている感じだと offset は任意に指定できる訳ではなくて常に末
      尾を指定する様になっている気がする。もしそれが正しいのだとしたら既存の項
      目の truncate 等について悩む必要はないという事になる。

      * ok: 一方で、_ble_history_edit に関しては一番最後に要素が追加されている
        可能性があるという事を考えると、やはり truncate しておくべきの気がする。
        と思ったが、_ble_history_edit に関しては Cygwin では単に _ble_history
        からコピーしているだけなので気にしなくて良い。

      * done: 末尾以外の offset を指定できる機能は削除するべきだろうか

        別の問題として特に末尾以外の offset が指定された時に後ろに続いているデー
        タを削除するべきか或いは保持するべきかという事。やはり offset を指定し
        ている箇所がないか確認が必要な気がする。という訳で '\boffset=' で検索し
        てみると。

        > $ grc '\boffset=[^=]' --exclude=ext | grep -v 'local offset='
        > ./keymap/vi.sh:2973:  local ind=${1:-$_ble_edit_ind} offset=$2
        > ./lib/core-complete.sh:2221:  local word1 index=0 offset=0 sep=
        > ./lib/core-complete.sh:4411:##     offset=NUMBER
        > ./lib/test-edit.sh:11:  local _ble_edit_str=$1 index=$2 offset=$3
        > ./lib/test-edit.sh:16:  local _ble_edit_str=$1 index=$2 offset=$3
        > ./src/edit.sh:1880:  local index=${1:-$_ble_edit_ind} offset=${2:-0}
        > ./src/edit.sh:1914:  local index=${1:-$_ble_edit_ind} offset=${2:-0}
        > ./src/history.sh:283:  ##     offset=NUMBER
        > ./src/history.sh:301:    elif local rex=':offset=([0-9]+):'; [[ :$opts: =~ $rex ]]; then
        > ./src/util.sh:617:  # Note: Bash 4.3 以下では ${arr[@]:${2:-1}} が offset='${2'

        やはり誰も　offset は指定していない。この機能は削除する。

      結局 truncate はしなくて良いと判断する。何故なら offset が指定されるとし
      ても常に末尾に対する追加だからである。

    * 次の問題は Cygwin に於いてどの様に追記を実装するのかという事である。

      % += を使うと 3.0 で使えない。然し ble/array#push は遅そうである。うーん。
      % 複雑になるが opt_source と arg_offset に応じて分岐する事にする。という
      % 訳で offset==0 の時には今まで通りにして、それ以外で bash-3.1 以上の場合
      % は += に置き換える。bash-3.0 の場合には _ble_history[10000]='str' とい
      % う具合に直接 index を指定して出力する事にする。
      %
      % →結局 arr=() arr+=() は遅いという事が分かったので、arr[ind]=str 一本で
      % 実装する事にする。

      ? 然し改めて思ったのだが、そもそも array=() や array+=() は arra[]='...'
        よりも高速なのだろうか。実験してみる価値はある。

        $ for a in {0..3}; do history; done | sed 's/'\''//g;s/^[[:space:]]*[0-9]\{1,\}[[:space:]]*//' > h.txt
        $ < h.txt awk 'BEGIN{apos="'\''"}{print "_dbg_history[" NR - 1 "]=" apos $0 apos}' > a.txt
        $ < h.txt awk 'BEGIN{apos="'\''";print "_dbg_history+=(";}{print apos $0 apos}END{print ")";}' > b.txt
        $ time source a.txt
        0.222
        $ _dbg_history=(); time source b.txt
        0.211

        うーん。Cygwin で試してみた限りでは大して変わらない様に見える。若干
        arr+=() の方が速いぐらいである。でも bash-3.0 では試していない。Cygwin
        には bash 3.0..3.2 は入れていない。然し、一応 Linux で bash 3 でどちら
        かが致命的に遅かったりという事がないかを確認する事にする。

        $ bash -c 'TIMEFORMAT="%Rs"; time source a.txt'
        0.454s
        $ bash -c 'TIMEFORMAT="%Rs"; time source b.txt'
        0.483s
        $ bash-3.0 -c 'TIMEFORMAT="%Rs"; time source a.txt'
        0.886s
        $ bash-3.0 -c 'TIMEFORMAT="%Rs"; time source b.txt'
        b.txt: line 1: syntax error near unexpected token `newline'
        b.txt: line 1: `_dbg_history+=('
        0.002s
        [ble: exit 1]
        $ bash-3.1 -c 'TIMEFORMAT="%Rs"; time source a.txt'
        0.770s
        $ bash-3.1 -c 'TIMEFORMAT="%Rs"; time source b.txt'
        物凄く時間がかかるので中止した
        $ bash-3.2 -c 'TIMEFORMAT="%Rs"; time source a.txt'
        0.757s
        $ bash-3.2 -c 'TIMEFORMAT="%Rs"; time source b.txt'
        ^C
        [ble: exit 130]
        $ bash-4.0 -c 'TIMEFORMAT="%Rs"; time source a.txt'
        0.782s
        $ bash-4.0 -c 'TIMEFORMAT="%Rs"; time source b.txt'
        ^C
        [ble: exit 130]
        $ bash-4.2 -c 'TIMEFORMAT="%Rs"; time source a.txt'
        0.613s
        $ bash-4.2 -c 'TIMEFORMAT="%Rs"; time source b.txt'
        0.929s
        $ bash-4.4 -c 'TIMEFORMAT="%Rs"; time source a.txt'
        0.474s
        $ bash-4.4 -c 'TIMEFORMAT="%Rs"; time source b.txt'
        0.911s
        $ bash-5.0 -c 'TIMEFORMAT="%Rs"; time source a.txt'
        0.457s
        $ bash-5.0 -c 'TIMEFORMAT="%Rs"; time source b.txt'
        0.494s
        $ bash-dev -c 'TIMEFORMAT="%Rs"; time source a.txt'
        0.322s
        $ bash-dev -c 'TIMEFORMAT="%Rs"; time source b.txt'
        0.383s

        この結果を見ると arr+=() は古い bash では致命的に遅い。arr=() について
        も確認して置いた方が良いのではないか?

        $ < h.txt awk 'BEGIN{apos="'\''";print "_dbg_history=(";}{print apos $0 apos}END{print ")";}' > c.txt
        $ bash-dev -c 'TIMEFORMAT="%Rs"; time source c.txt'
        0.385s
        $ bash-4.4 -c 'TIMEFORMAT="%Rs"; time source c.txt'
        0.901s
        $ bash-4.2 -c 'TIMEFORMAT="%Rs"; time source c.txt'
        0.915s
        $ bash-4.1 -c 'TIMEFORMAT="%Rs"; time source c.txt'
        1.098s
        $ bash-4.0 -c 'TIMEFORMAT="%Rs"; time source c.txt'
        1.099s
        $ bash-3.2 -c 'TIMEFORMAT="%Rs"; time source c.txt'
        1.091s
        $ bash-3.1 -c 'TIMEFORMAT="%Rs"; time source c.txt'
        1.111s
        $ bash-3.0 -c 'TIMEFORMAT="%Rs"; time source c.txt'
        1.155s

        うーん。この結果を見る限りは arr=() に関しては問題は存在しなかった様で
        ある。但しそうだとしても、arr[]=() の方式の方が安定して高速な結果を出し
        ている。これは完全に arr[]='...' に切り替えた方が実装もすっきりするので
        はないか。

      * ok: 一応 #D0701 に議論がある様なので確認しておく。確認した。この時の記
        録を見る限りは "_ble_history[index]='...'" 的な方法については速度を計測
        していないのだという気がする。なので、この方法自体に何か問題があったと
        いう訳ではなく、当時は一顧だにしなかったという事なのだろう。

      arr[index]=str を使うように切り替えた。awk 内部での hindex の取り扱いも変
      更した。これに伴って nlfix の時の修正インデックスの解釈も変更。nlfix につ
      いてはちゃんと変更後も動いている事を確認した。

      x fixed: 後は Cygwin で問題なく動くかを確認する。と思ったら動かない。フリー
        ズしてしまう。何故だろう。

        * うーん。どうも動かない様に見えたのは _ble_history_edit の方をロードし
          ていなかったからの様だ。

        * C-r でフリーズするのも _ble_history_edit に有限の内容が含まれる様に変
          更したら直った。然し、だからと言ってそれだけでフリーズするというのも
          解せない。

          それだと履歴が全く無い時にはどうなるのだろうか。試してみたが特に問題
          は生じなかった。どうも履歴項目で引数が多い物があってそれで遅くなって
          しまっているという事の気がする。これはまた再現したら対処するという事
          で良い事にする。

    これで offset 問題は解決だろうか。trunate に関しては arg_offset が有限の時
    は常に末尾に対する追記という事にした。arg_offset=0 の時には配列をクリアする
    事にした。その上で offset については Cygwin　の場合には直接 arr[index]=str
    の形式で初期化する事にしたので問題ない。他の環境では mapfile -O を今まで通
    り使う。大丈夫な気がする。

  * 2021-05-04 折を見て simple-word/eval のデータ授受にも mapfile -d '' を使う [#D1604]
    Ref #D1522

    mapfile -d "" が buffered になったら
    ble/syntax:bash/simple-word/eval/.print-result (lib/core-syntax.sh) を修正する。

    2021-05-08 もう bash の側では修正されている。然し、Cygwin に対しても動作を
    変更できないかどうか尋ねてその上で改めて一緒に修正するのが良い気がする。

    2021-06-12 未だ Cygwin についても修正できないかの問い合わせはしていないが、
    代わりに history のロードの側でも mapfile -d "" を使う様に変更したので、こ
    の際一緒に変更を適用する事にする。先に修正のある simple-word/eval を差し置
    いて history の方で利用するのは変だし、だからと言って history の方に対する
    変更も pending にするのには変更が大きすぎる。

    * reject: read -t ... についても同様に bash-5.2 以降で実装を切り替えて良い気がする。

      2021-06-12 今改めて考えると read -t の何の振る舞いを切り替えるのか分から
      ない。今まで unbuffered になっていた事によって read -d "" を使いたくても
      使えなかったのを控えていた箇所はあっただろうか。後、read -t というのは
      timeout の指定の事だが、今回の buffered/unbuffered の変化が timeout の振
      る舞いにどう影響を与えるのかは不明である。"read -t" の "-t" は唯単に手の
      癖で入力した物の様な気がする。

      これに関しては取り敢えず棄却で良い気がする。

  * history: [最適化] 初期化に新しい mapfile -d '' を使えないか [#D1603]
    Ref #D0681

    これは ble/util/readarray -d '' で実装されている。と思ったが…そもそも
    builtin mapfile を直接使えば良いのではという疑惑もある。一応、他の version
    の bash でも使える様にしてあるという利点はあるが。

    | というよりそもそも現在の実装になっているのは mapfile -d '' が遅かったからと
    | いう解釈は正しいのだろうか。ログを調べてみる必要がある。うーん。適当に検索
    | してみたが難しい。git blame で観察してみると
    |
    | 1bfc8ebe src/history.sh に移動
    |
    |   現在の実装は 2019-07-09 に大きく書き換えられている。と思ったが…これは単
    |   にコードを移動しただけの話かもしれない→うーん。やはりそうだった。
    |
    | f204bc73 src/edit.sh: history -nr の対応
    |
    | 18fdaf2a Cygwin 対策
    |
    | c0c7f13e 2018-03-14 これ。この時点で mapfile & nlfix を実装している。まと
    |   まった議論があるのもこの時のログである。#D0681 である。

    うーん。当時のログを確認してみるとそもそも mapfile -d '' で NUL 区切りのデー
    タを読み込めるという事を認識していなかった様な節がある。今回改めて実験及び
    実装をして見る事にする。Bash version 毎の配列コピー時間についても確認する。

    - 取り敢えず実装した。ちゃんと読み込めている。やはり配列コピーよりも
      mapfile の方が高速の様である。

    * done: 後で printf '[[%s]]\n' "${_ble_history[@]}" > a.txt 等として出力し
      た結果を比較して正しいかどうかを検証する。

    * done: Cygwin に於ける動作も変更したので動作確認の必要がある。

      Cygwin では awk 側で unescape をする様にしたので nlfix は不要である。

      動作確認の結果 mapfile -d '' の為に書いたコードでやったのと同じミスを修正
      するのを忘れていた。それを修正したらちゃんと動く様になった。OK

  これを機に以前の mapfile の修正も適用してしまう事にする。

2021-06-11

  * 2021-05-16 edit: BUG とても長いプロンプトにした時に列計算が壊れている (reported by telometto) [#D1602]
    また右端から入力を始めた時の折返しが正しくできていない。

    2021-06-11 stackoverflow で報告されていた (by telometto)
    https://stackoverflow.com/questions/67917673/odd-long-space-in-bash-when-writing-commands

    | うーん。ble.sh のバグが stackoverflow で報告されている。これは自分でも気
    | づいていた筈の問題である。何故忘れていたのだろう。割合最近気づいた事だっ
    | た筈である。調べたら 2021-05-16 の項目を見つけたのでそれに移動する事にす
    | る。

    取り敢えず修正する。抑々 trace が怪しいという事なので計算結果について確認する。

    $ x=0 y=0; LINES=10 COLUMNS=10 ble/canvas/trace 'HelloWorld'; declare -p x y ret
    x=10 y=0
    $ x=0 y=0; LINES=10 COLUMNS=10 ble/canvas/trace 'HelloWorldH'; declare -p x y ret
    x=2 y=2

    物凄く意味不明な間違い方をしている。うーん。implicit-move が悪いという所ま
    で特定した。と思ったら分かった。折返しが発生すると分かった場合に x+=w を二
    重に実行している。2回目の x+=w を削除したら普通の振る舞いに戻った。調べてみ
    るとこれは 4fa139ad 2021-03-21 に複数行 "rps1" に対応した時に埋め込んだバグ
    であった。

2021-06-10

  * prompt: 最適化 git の現在の dirty 状態は background で取得できる様にしたい [#D1601]

    prompt-git.bash に実装したい。という事を考えると、
    prompt-git.bash は早晩に lib に移動するべきなのではないかという気がする。

    これはどの様に実装するか。先ず初めに background で git を起動する。timeout
    を指定して直ぐに制御が戻らなければ取り敢えず放置する事にする。その後で結果
    が分かったらそれを取り出す。既に git を起動していて未だ結果が分かっていない
    時には何もしない。最後に結果が分かってから X 秒経過する迄は以前の結果を参照
    する。ディレクトリを移動した場合には、起動中の git はキャンセルして新しいイ
    ンスタンスを起動する。と言った位。

    一から実装する事も可能だが既存の枠組みに沿った形で出来るだけ実装したい。git
    の結果待ちは idle プロセスとして実装する。うーん。history 初期化のコードを
    観察した。正にこれと同じことをしたいのである。

    うーん。ライブラリにしようと思ったが微妙…。実は ble/util/idle.push -F
    tmpfile を使うだけで行ける話ではないか。履歴の場合にはデータが大量だったの
    で各ステップを分割して少しずつ処理する必要があった。然し、今回の場合には
    git の実行を待つという操作が1回存在するだけである。

    実装した。動いている。と思ったが何だか遅い。うーん。ble/util/msleep 20 を入
    れるか入れないかで大分変化する。ble/util/msleep 20 なら1秒で50回捌ける様な
    気がするがそうでもないのだろうか。うーん。取り敢えず一定時間経過する迄は
    version が変化しても無視する事にする。

    - 改めて計測してみると vim-airline を有効にしている時ですら一秒間に20プロン
      プト表示する事ができている。そもそも一つのプロンプトを表示するのに 50ms
      しかかかっていない。なので其処に 20ms 追加するのは 1.5 倍の時間がかかる様
      になる事を意味していて体感としてとても遅くなるのだという事。

    - 取り敢えず前回の結果からそんなに時間が立っていない時、かつ、前回の要求か
      らプロンプト更新が10回以内の時には git の呼び出しは控える事にした。

    # 単純な PS1 の時だけの場合のプロンプトの計算速度はどの程度だろうか。試して
    # みた所、29,26回/秒 だった。平均で 36.4ms かかっている。14ms の短縮である。
    # 此処で　PS1 の処理をなくしたとしてもそんなには変わらないのだろうという気
    # がする。プロンプトの計算は実はそんなに重くないのだろうという事。

    - また Linux では可也高速に git diff --quiet の結果を得る事ができる様なので
      ble/util/msleep の時間も 5 まで減らした。これでも大きすぎるかもしれないが、
      まあ、頻繁に更新はしない事にしているし特に問題にはならないだろう。

  * [dissolved] 2021-05-28 prompt: 最下行で ble-reload すると statusline が重複してしまう [#D1600]

    ble-detach してその後に ble-attach した時には問題は発生しない。
    →これは確認した所再現しなくなっていた。恐らく #D1592 で解決した問題だろう。

  * [reject] 2021-05-24 prompt: プロンプトの変数展開の更新検出 [#D1599]

    プロンプト更新検出に於いてプロンプトに含まれて
    いる変数展開 $XXXX も自動検出する? 然しエスケープや $() 等も拘ってくると複
    雑である。適当な方法で解析できたりしないだろうか。というか、終端を処理する
    為に parse していた様な気もする。その辺りについてはまた後で確認する。

    $RANDOM や $EPOCHREALTIME 等については除外するべきである。これらの変数への
    nref の検出は困難である。という事を考えるとやはりユーザーに任せるという可能
    性も考えられるが。

    然し一方でプロンプトを計算した瞬間の値を参照したいという需要も考えられる。
    例えば $BASH_COMMAND, $LINENO 等がプロンプトに含まれていたとして、その内容
    が変わったからといってユーザーはプロンプトの表示を更新する事を想定はしてい
    ないのではないか。という事を考えるとやはりユーザーが明示的に要求しない限り
    はプロンプトに含まれている変数展開を改めて評価する必要はないのではないかと
    いう気がする。

  * [ok] 2021-05-24 prompt: 現在のモードの算出の共有化・最適化 [#D1598]

    ble/prompt/.get-keymap-for-current-mode やble/keymap:vi/script/get-mode に
    関しては一旦計算値を別の変数に格納してそれを参照して値を計算するべきの気が
    する。これは git 等の最適化と一緒に新しく枠組みを考える事にする。

    取り敢えず枠組みは整えた。そしてこれらの関数では関連する変数に対して
    add-hash を実行している。新しい unit にする程の物でもないだろう。一つにはこ
    れらの関数はそんなに思い関数でもないという事。そして幾つも何度も実行する様
    な物でもないのでキャッシュしても仕方がないのではないかという事。大抵の場合、
    依存関係を追跡するコストの方が大きそうである。なので add-hash をして、これ
    らを含むプロンプトを再更新させるぐらいで良いだろうと思われる。

  * auto-menu: ubuntu20 で auto-menu を有効にしても動いたり動かなかったりである [#D1597]

    auto-menu の起動条件 (直前の widget) に対する判定で失敗しているのだろうか。
    或いはもっと別の要因だろうか。うーん。或いは idle.sleep に失敗しているとい
    う可能性もあるのかもしれない。

    どうやら ble_util_idle_elapsed が常に 0 になってしまって時間が経過しない
    という事で無限ループになっている様子だ。調べると _ble_util_idle_sclock が
    0 の儘で全く動いていない。_ble_util_idle_sclock は ble/util/idle/.sleep
    によって増える手筈になっている。ble/util/idle/.sleep は .sleep-until-next
    から呼び出される事になっているが、この関数の振る舞いを見るとどうやら
    sleep_amount が微妙に負になっている。現在時刻と次のタスクをする時刻を比較
    しているが、次のタスクを実行する時刻が何故か現在時刻よりも前の時刻になっ
    てしまっている。

    現在時刻は ble/util/idle.clock で取得されていて内部的には ble/util/clock
    になっている。ble/util/clock は中で EPOCHREALTIME を参照している。一方で
    次の時刻 _idle_next_time は何処から来るのかというと task の SXXXX という
    エントリーから読み出される。この SXXXX というエントリーは
    ble/util/idle.sleep で設定されていて、その関数の中で ble/util/idle.clock
    が呼び出されている。整理すると

    1 最初に ble/util/idle.sleep が呼び出されてその時の時刻を元にして待ち時刻
      が設定される。何らかの処理がなされてその回のループが終了する。

    2 次のループに入る前に次の待ち時刻まで sleep する。しかし、この時迄に時刻
      が経過して次の待ち時刻を超えてしまうので、スリープ無しで次のループが始
      まる。

    3 再び auto-menu.idle が開始するが auto-menu.idle は合計 sleep 時間を使っ
      て経過時刻を確認する。然し、実際には sleep は行われていないので
      auto-menu.idle は時間が経過していないと勘違いして再び sleep を設定して
      抜ける。

    此処での問題は auto-menu.idle は絶対時刻による待ちを設定しているのにも関
    わらず、判定及び残り sleep 時間の算出に sclock つまり sleep 合計時間を使っ
    ている事である。どちらかに統一するべきである。裏で重い処理が走っていよう
    ともそれはユーザーには見えないのでできるだけ定刻通りに処理を開始するべき
    であると思うと、絶対時刻を使用する方に揃えるべきである。

2021-06-09

  * 2020-09-07 complete: メニュー絞り込みの着色が残ったままになってしまう事がある [#D1596]

    menu_filter が off にならない状況が分かった。auto-complete による単純挿入で
    継続した時、menu_filter が更新されない。更に別の機能によって menu が削除さ
    れてしまった時にも更新されない?

    | と思って実装を確認したがそうでもない様な気がする。実装を確認すると現在の
    | keymap が menu-complete でもない限りは menu-filter の処理を走らせている。
    | 領域抽出などに失敗した時にも単に menu を clear するだけでそれ以外の特別な
    | 解除処理は行っていない。だとすると、menu-filter の着色の側で処理を行って
    | いる?
    |
    | 然し ble/highlight/layer:menu_filter/update を見る限りは現在 menu が表示
    | されている場合にのみ着色を行う様になっている。うーん。或いは dirty range
    | がない限りはそもそも layer が呼び出されない可能性? と思ったがそれも変であ
    | る。何か文字列を入力してもやはり着色が残ってしまうという現象が見えていた
    | 筈である。

    - やはり振る舞いを見るとちゃんとキャンセルはされている様である。この時に
      layer が更新されないのが問題なのだと思われる。
    - 更に layer の実装の方も確認してみると、これもちゃんと動いている気がする。
      ちゃんと update-dirty-range が呼び出されている。此処で改めて表示が更新さ
      れるべきなのである。うーん。勝手に後で表示が変化しているという事なのか。

    - 或いは、上の layer が更新を無視してしまっているのか。layer の list を確認
      すると plain syntax menu_filter region overwrite_mode disabled になってい
      る。 overwrite_mode と disabled は不活性になっていて region は
      auto_complete によって設定されている。つまり region が変更を握りつぶして
      いるという事。再構築の部分を確認してみると、既存の内容は全て捨てて下層と
      現在の範囲着色で完全に再構築している。

      うーん。分かった。選択範囲の変更がない場合に、例え下層で何か変更があった
      としてもスキップしてしまう様になっている。

    ? ok: layer:menu_filter は layer:region を参考にして作られた同様の問題点は
      ないだろうか→確認したがその問題はなさそうである。PREV_BUFF を上書きして
      返す場合にはちゃんと PREV_UMIN<0 である事を確認している。layer:region が
      問題になったのは PREV_BUFF を上書きしているのにも拘らず、元の PREV_BUFF
      に起こった変更を拾わなかったのが原因である。

    ? ok: さて、今回の修正では選択範囲が存在する時に menu_filter 着色が残ってし
      まうという話だったが、実際のコマンド実行に於いても menu_filter の着色が残っ
      てしまう様な場合が存在する気がする。と思ったが、実際にコマンドを実行する
      段階まで行けば menu_filter の着色は解除されていた様な気もする。これは選択
      範囲と関係ない様な気がするが、何故問題がそのまま発声していたのであろうか。
      うーん。

      というか今回の場合も何故問題が生じていたのかよく分からない。というのも
      auto_complete による選択範囲は変わっている筈だからである。うーん。DMIN<0
      なのは良い。そして、select[*] と osel[*] が一致している時に限りスキップが
      起こっている筈なのである。それなのに、実際に発声している状況を見ると sel
      <- osel で変更が起こっている筈なのに着色がスキップされてしまっているとい
      う事。どういう事なのだろうか。

      →確認してみた所、何といきなり osel が変化している。うーん。DMIN に変更が
      あってそれでスキップされていたという事だろうか。うーん。分かったそういう
      訳ではない。

      何が起こっているかというと…

      (1) auto_complete で空白文字が入力されて、カーソル位置と region の開始点
        が一文字後ろにずれる。この時点で一旦描画が呼び出される。この時は未だ
        menu_filter.idle が走っていないので menu は表示した儘で menu_filter の
        着色も有効の儘である。そうすると e[cho ][予測内容] の前半の [] を
        menu_filter 着色にして、後半の [] を region 着色した状態になる。
      (2) その後で menu-filter.idle が走って menu を削除する。この時、内部的に
        はecho [予測内容] の様に書き換わるが選択範囲に変更がない為に、
        layer:region が下層の変更を拾わずにその儘になっていた

      という事。今まで時々見られた物もこれで説明が着くのではないか。取り敢えず

    [まとめ] layer:region が、選択範囲が存在して前回と変更がない時に、下層で変
    更があったとしてもそれを反映しない設計になっていたのが原因であった。

  * 2021-05-29 bleopt: wildcard を使った時に obsoleted な物も列挙されている [#D1595]
    複数単語に展開された時にはフィルタする様にしたら良い。

  * blehook: -a を指定しないと直接 hook を指定しても表示されない [#D1594]

    % blehook -a face_name による結果の表示も一緒に遅延されている気が
    % する。というかそもそも blehook に遅延機能があったのだろうか。。
    % そしてその理由は? うーん。見た感じは遅延機能等ない。と思ったが分
    % かった。blehook 自体が faces にアクセスしようとして、それで初期
    % 化が発生している。

  * color: initialize-faces の遅延に関する問題 (motivated by jmederosalvarado) [#D1593]
    https://github.com/akinomyoga/ble.sh/issues/96#issuecomment-813185300

    * vim-airline: theme を blerc で設定しても何故か暫くすると dark の配色が読み
      込まれている気がする。改めて設定し直すと問題は起こらない。theme を変えた瞬
      間の配色が何だか変になる。

      うーん。調べてみると initialize-faces が2回呼び出されている気がする。何故だ
      ろうか。ble/syntax/attr2g 経由である。うーん。分かった。core-syntax.sh が定
      義している関数で ble/syntax/attr2g の初期化を遅延しようとしている。然し、最
      初にプロンプトを表示した時点で既に initialize-faces が実行されるので、その
      後で ble/syntax/attr2g { initialie-faces && ble/syntax/attr2g "$@"; } 等と
      すると二重に初期化される様になるのである。eval-after-load 的な仕組みで登録
      する必要があるのではないか。

    * また、initialize-faces が実行されたら実行した hook はクリアする事にする。

    * この際なので GitHub #96 のコメントで指摘されている遅延についても対処する。

      沢山の setface 設定を仕込んでいると最初のキーストロークの反応が遅いという
      話。これに関しては initialize-faces を idle で実行すれば良い。

      idle の登録順序はどうなっているだろうか。ロードした直後の idle の順序を確
      認する。complete を絶対パスでロードするように変更して、また syntax より後
      にロードする様に変更した。変更後の様子は以下の通り。

      [0]="R\\ble/history:bash/resolve-multiline async"
      [1]="R\\ble/util/import '/home/murase/.mwg/src/ble.sh/out/lib/core-syntax.sh'"
      [2]="R\\ble/util/import '/home/murase/.mwg/src/ble.sh/out/lib/core-complete.sh'"
      [3]="R\\ble/util/import '/etc/profile.d/modules.sh'"
      [10000]="R\\ble/util/msleep/calibrate"
      [10001]="R\\ble/textarea#render-defer.idle")

      うーん。syntax よりは前に faces は initialize して良いのではないか。とい
      う事を考えると、実は一番最初に登録してしまっても問題ない。登録した。

  * vim-airline を blerc からロードする様にすると余分な行が表示される [#D1592]

    | 調べると \q{lib/vim-airline} の中で問題が発生している。更に調べると
    | ble/prompt/unit:_ble_lib_vim_airline_mode/update の中の
    | ble/history/get-entry により何かが出力されている。出力内容を調べるとエスケー
    | プシーケンスを出力している。エスケープシーケンスの出処を調べる。
    |
    | | ble-attach
    | |   ble/term/initialize
    | |     ble/term/test-DECSTBM
    | |       ESC7
    | |       ESC[1;2r
    | |       ESC[2;1H
    | |       ESC[1B
    | |       ESC[6n
    | |       ESC[;r
    | |       ESC8
    | |   ble/decode/attach
    | |     ESC[>c
    |
    | 上記の出力内容は単に buffer に残っていただけ。
    | これらは特に何も問題を起こさない。
    | 以下の内容が問題を起こしている。
    |
    | | ESC(BESC[m^MESC[2KESC[1M
    | | ESC(BESC[mESC[30C
    |
    | もっと分かり易く書くと以下の形になる。
    |
    |   SGR0 CR
    |   EL(2) DL(1) ... put-dl.draw
    |   LF SGR0 CUR(30)
    |
    | EL(2) DL(1) の組み合わせは put-dl.draw が使っている物である。put-dl.draw に
    | 仕掛けて FUNCNAME[@] を出力してみると以下の結果になった。
    |
    | | ble/canvas/put-dl.draw
    | | ble/canvas/panel#set-height.draw
    | | ble/canvas/panel/reallocate-height.draw
    | | ble/edit/info/.render-content
    | | ble/edit/info/show
    | | ble/edit/info/immediate-show
    | | ble-edit/history/history-message.hook
    | | blehook/invoke
    | | ble/history:bash/load
    | | ble/history:bash/initialize
    | | ble/history/initialize
    | | ble/history/get-entry
    | | ble/prompt/unit:_ble_lib_vim_airline_mode/update
    | | ble/prompt/unit#update
    | | ble/prompt/backslash:lib/vim-airline
    | | ble/prompt/backslash:q
    | | ble/function#try
    | | ble/prompt/.process-backslash
    | | ble/prompt/process-prompt-string
    | | ble/prompt/.instantiate
    | | ble/prompt/unit:{section}/update
    | | ble/prompt/unit:_ble_prompt_status/update
    | | ble/prompt/unit#update
    | | ble/prompt/update
    | | ble/textarea#render
    | | ble/textarea#redraw
    | | ble-attach
    | | ble/base/attach-from-PROMPT_COMMAND
    | | ble/function#lambda/0
    |
    | つまり、ble-attach から呼び出したプロンプト再描画の中で vim-airline が呼び
    | 出されて、その中での modified の判定の為に get-edited-entry が呼び出されて
    | いるという事。get-edited-entry は内部で ble/edit/info/immediate-show を呼び
    | 出して居て、結果として何らかの不都合が生じて計算がずれる。
    |
    | a reject: 一つの可能性として DRAW_BUFF に出した出力が中途半端になっている事
    |   によって問題が生じているのではないかと思ったが、DRAW_BUFF を覗いた感じだ
    |   と特に何も登録はされていない。なので出力のバッファリングが輻輳していると
    |   いう可能性は考えなくて良い。
    |
    | b reject: 或いは buffer に既に入っている内容が問題になっている? と思ったが
    |   そうでもない。その場で buffer.flush して、get-edited-entry の出力だけ潰し
    |   ても特に問題は生じない。
    |
    | c reject: 或いは端末に繋がっている時だけしか問題のある出力をしない可能性は
    |   あるだろうか。つまり e.log に出力された内容を今は観察しているが、実際には
    |   端末に繋がっている時に限りもっと色々な出力をしている。具体的には非端末の
    |   時にはble/history/initialize は info で何も表示しない可能性。一旦
    |   get-edited-entry の直後で sleep を入れて何か表示されるのか確認してみる事
    |   にする
    |
    |   →特に何も表示されない。恐らく端末に繋がっているかどうかの違いで振る舞い
    |   が変わるという訳ではないと思われる。
    |
    |   →実際に非端末の出力先として 2> >(cat) を使った場合にも問題が再現する。と
    |   いう訳なので観察している出力で確かに問題が発生しているのだという事。
    |
    | d reject: もう一つの可能性は後で遅延して履歴読み込みが完了した時に info を
    |   削除する時に問題が生じているという可能性。
    |
    |   →これは関係ない。実際に get-edited-entry の stderr を潰せば問題は生じな
    |   くなっているし、その imbalance が生じる事によって表示が偶々正しくなってい
    |   るという様には考えがたい。
    |
    | e reject: 或いは get-edited-entry を呼び出した直後に buffer に入っている内
    |   容が後になって問題を起こしている可能性? → 確認したが、get-edited-entry
    |   直後には buffer は何も入っていない。これは関係ない。
    |
    | f もう一つの可能性として全体更新が中途半端になっている事によって座標計算が
    |   ずれているのではないかという事。然し、問題が生じているのは ble-attach か
    |   ら直接 ble/textarea#redraw を呼び出した時であって、これは panel/render で
    |   はないので、textarea と info の描画は独立の筈である。
    |
    | となって来ると、info から呼び出した set-height の実装か、或いは位置計算に問
    | 題が生じているという事になる気がする。出力内容と _ble_canvas_x,y の状態につ
    | いて確認する必要がある。
    |
    | | _ble_lib_vim_airline_mode
    | | declare -- _ble_canvas_x="30"
    | | declare -- _ble_canvas_y="0"
    | | declare -- _ble_canvas_excursion=""
    | | ^[(B^[[m^M^[[2K^[[1M
    | | ^[(B^[[m^[[30Cdeclare -- _ble_canvas_x="30"
    | | declare -- _ble_canvas_y="0"
    | | declare -- _ble_canvas_excursion=""
    |
    | うーん。これを見る限りは canvas 的にはカーソル位置は動かしていないつもりな
    | のである。改めてこのシーケンスがどの様に生成されているか確認する。
    |
    | | _ble_lib_vim_airline_mode
    | | declare -- _ble_canvas_x="30"
    | | declare -- _ble_canvas_y="0"
    | | declare -- _ble_canvas_excursion=""
    | | declare -a _ble_canvas_panel_height=([0]="1" [1]="0" [2]="0")
    | | [delta=-1,opts=]
    | | ^[(B^[[m^M^[[2K^[[1M
    | | ^[(B^[[m^[[30C[delta=0,opts=]
    | | declare -- _ble_canvas_x="30"
    | | declare -- _ble_canvas_y="0"
    | | declare -- _ble_canvas_excursion=""
    | | declare -a _ble_canvas_panel_height=([0]="0" [1]="0" [2]="0")
    |
    | うーん。どうやら panel#0 の高さが潰れてしまっている様子。然し、高さが潰れて
    | しまっているからと言ってカーソルの位置が変わるのは変である。うーん。
    | set-height までは別に座標計算が変な事にはなっていない様だ。set-height を抜
    | けた後で座標位置を復元している箇所があって、其処で計算がずれているという事
    | の気がする。
    |
    | うーん。分かった。以下の様な状態になっている。x=0 y=0 content=$'\n' になっ
    | ている。content に改行が入っているのだから、本来は y=1 でなければならない筈
    | である。何故この様な内容が生成されるのか確認する必要がある。
    |
    | declare -a _ble_edit_info=([0]="0" [1]="0" [2]=$'\n')
    |
    | 更に調べると ble/edit/info/.construct-content text 'loading history...' の
    | 構築結果がその様になっている。
    |
    | % 更に辿ると ble/canvas/trace-text がまるで動かなくなっている。何故。。。
    | %
    | %   x=0 y=0; ble/canvas/trace-text 'ABC'; echo "($x,$y)[$ret]"
    | %
    | % とすると x=0 y=0 ret=$'\n\n' 二重改行になってしまっている。これは大事。
    | % いつからこの様な事態になっていたのだろう。今まで気づかなかったのも不思
    | % 議である。というより、殆どの機能で着色を使っているので trace-text は余
    | % り使われてこなかったのである。更に遡って調べてみると v0.3.0 の時点で既
    | % に trace-text は動作していなかった様だ。0.2 系列では
    | % ble-edit/info/.construct-text という関数で現在の実装とは全く異なる物凄
    | % く単純な実装だった。この時は勿論問題はなかった。
    | %
    | % まとめると ble/canvas/trace-text は可也昔から壊れていた。v0.3.0 の時点
    | % で駄目。一方で v0.2 の段階ではその前身である
    | % ble-edit/info/.construct-text だったが、これはとても単純な関数でまた問
    | % 題も存在しなかった…と思ったが微妙に関数の仕様を勘違いしていた。
    | % trace-text は領域の大きさを外部から与える必要があったのである。

    結局何が起こっていたのかというと、ble/edit/info/.construct-content に於いて、
    ble/edit/info/.initialize-size が lines=0 を返して、それに対して
    ble/canvas/trace-text が変な振る舞いをしていたという事。

    問題が3つある。

    x fixed: ble/canvas/trace-text は lines が限界に達しているのにも関わらず改
      行を末尾に付加してしまう。これは個別に対応した。

    x ok: 改行を付加したのにも関わらず y を増やしていない。これは trace-text を
      ほぼ再実装した結果発生しなくなった。何故元の実装でこれが発生していたのか
      は分からない。そもそも改行 \n ですら trace-text では ^J と表示される。

      →これは分かった。ble/canvas/trace-text/.put-nl-if-eol が put-simple の中
      と終了時の2回呼び出されている。cols=0 の時には一回実行したとしてもまだ行
      末にいると判定されるので二回実行されるのである。

    x fixed: ble/canvas/trace-text を初期化する前に、何故か
      ble/edit/info/.initialize-size が lines=0 を結果として与えている。

      中では ble/canvas/panel/layout/.get-available-height を呼び出している。

      % 中で戻り値を確認すると ret=9730ret という謎の値が生成されている。と思っ
      % たがこれは debug コードのミスだった。

      改めて調べるとこの時点で 0 が生成されている。

      declare -a mins=([0]="1" [1]="0" [2]="0" [3]="0")
      declare -a maxs=([0]="1" [1]="0" [2]="1" [3]="0")
      declare -a heights=([0]="0" [1]="0" [2]="0" [3]="0")
      declare -- index="2"
      declare -- ret="0"

      うーん。この時点で maxs に LINES が設定されて欲しいが 1 になってしまって
      いる。うーん。原因が分かった。プロンプトの処理を行っている最中は LINES
      COLUMNS を通して描画範囲の大きさを指定しているが、これだと本来のレイアウ
      ト処理に影響を与えてしまう。

      取り敢えずは ble/canvas/trace は引き続き LINES COLUMNS を参照する事にして
      おいて、その外側の instantiate 等については LINES/COLUMNS は別変数経由で
      指定する事にする。

      書き換えた。これで現在 LINES= 及び COLUMNS= を設定している箇所は全て
      ble/canvas/trace の呼び出しか、または ble/textmap#update の呼び出しに限ら
      れる事となった。

    x fixed: 何故 panel#0 の高さが潰れてしまうのか。本来は此処で高さを変更する
      必要はないのではないか。というより高さ 1 の儘であるべきなのではないのか。
      特に ble/prompt/update の段階では。

      これは LINES=1 を設定していた為に visible-bell 専用の行が引き算されて 0
      になってしまっているという事だろう。LINES=1 の時には visible-bell も表示
      しない様に修正する必要がある。もしくは visible-bell の表示方法を変更して、
      即座に行送りにする。と思ったが、visible-bell を表示した時点で現在の表示内
      容を保持する事ができないので、やはり LINES=1 の時には visible-bell は表示
      しない様に変更するのが適切だろう。

    * done: この問題とは独立に get-edited-entry に於いて最新の値を参照している
      時には履歴をロードせずに済ませる様に実装する様にした方が良い。実装した。
      取り敢えず vim-airline の modified はこれでもちゃんと動いている。

    * done: trace-text のテストを拡充

    x 2021-06-08 airline: ロード時に keymap_vi_mode_show=1 に再設定すると表示が
      ずれてモード行の位置にプロンプトの残像が残ってしまう

      →これは #D1592 を修正したら再現しなくなった。

    x 2021-06-08 airline: status 行を表示している時の空コマンド行による改行がス
      ムーズではない。

      →これも #D1592 の修正で再現しなくなった。LINES/COLUMNS によりレイアウト
      再構成が毎回走っていたという事なのだろうか。何れにしても空コマンド行によ
      る改行で status line を出した儘にしているかどうかだけ、実装について確認す
      るのが良い。

      →確認した。textarea (panel#0) の再描画しかしていないので statusline 等に
      ついてはその儘の筈。但しプロンプトの再計算が入るので結局再描画はされる様
      な気もしないでもない。うまく cache が働いていれば dirty にもならずに再描
      画もなくそのまま前の表示が使われるのではないかという気がする。

2021-06-07

  * prompt: [最適化] 依存関係追跡の整理・最適化 [#D1591]

    x .instantiate の section update で git 情報や現在の vim モードに依存してい
      るが、一方で自動的な依存解決による section update が git 情報や vim モー
      ドを初期化する前に呼び出されている。

    これに関しては本来は git の情報は ble/prompt#update _alpha '' prompt-data
    等として初期化する必要があるのではないかという気がする。というか
    ble/prompt#update を流用する必要があるのかは謎である。実はデータ専用の関数
    を用意しても良いのではないだろうか。そしてデータは好きな様に利用する。

    ? そもそも配列を共有している理由はあるのだろうか。。。

      version hashref hash に関しては依存関係の管理に関係している。
      これは一つ上の枠組みで管理される物なので切り離しても良いのではないか。
      一方で (instantiate 7つ組) 及び (tailor データ) はプロンプト情報固有の物である。

      但し、version 更新の条件として (instantiate 7つ組) または (tailor データ)
      による更新が実際にあったかどうかを使っている。然し、version は一般に外から
      その内容が変更されたかどうかを判定する為に用いているから、やはり version
      hashref hash の組で管理するべきである。

      取り敢えず veresion hashref hash の順序を変更する事にする。

    うーん。何だか分からなくなってきた。そもそも現在の構造に欠陥がある様な気が
    する。hash を見て更新する必要があるかどうかを観察する事になっているが、依存
    関係がある時には hash で参照している先を初めに更新しておかなければ反映され
    ない。なので、依存先を先に更新しようと考える訳だが更新に使用する引数が分か
    らないという問題が生じる。

    a 依存先の hashref を展開して長大な hash で更新確認をする案

      % これは version で参照しているから行けないのであって、依存先の hash 本体を
      % 依存元が取り込んでしまえば問題ないのでは? とも思われるがそれは変数の時だ
      % けである。history index や git の情報など何らかの処理によって確認を取って
      % 値を計算してから出ないと分からない物に関してはやはり変数で参照していても
      % 駄目である。

      依存の更新がグローバル変数の変化を通してのみ発生する場合にはこれで良いが、
      実際には git 等の様に現在の値をその都度更新する必要がある物もある。

      history index/count に関しても既存のコードを大きく変えたくないので、同様
      の仕組みを使って実装したいと考えている。と思ったが、history に関しては変
      数経由にした方が良い様な気もする。描画(カーソル移動も含めて)の回数と履歴
      移動の回数を数えたら断然描画の回数の方が多いだろうから。

    b そもそも各 unit に外から引数を与えられる様になっているのが変である。外か
      らプロンプト文字列を与えられなくてもそれ単体として更新をできる様にする。
      これはそんなに難しくない筈である。というより、今まで外から引数を指定でき
      る形で更新していた事自体が変なのである。

      この場合に真面目に考えなければならないのは特定の条件で on/off される様な
      プロンプトの存在である。うーん。特定の条件で表示非表示を切り替える様な物
      の場合には、消去のコードも自分で生成するか或いは消去は外に任せる事にして、
      自身は表示している時の状態を保持し続けるという事か。うーん。これについて
      は外からの支持で動作するというので良い気がする。つまり、今までの振る舞い
      で良い。特に rps1, xterm_title, etc. に関しては他から参照される事もないの
      で、外から呼び出された時にだけ更新すれば良い。更新する必要がないのに古い
      依存関係経由で呼び出されるという様な事はないので大丈夫。

      1 先ず更新は全て unit#update 経由で実行するという事。現在は class 等とし
        て {section}/update を定義しているがこれは廃止する。個別にちゃんと
        /update で実装するという事。unit#update には引数は渡さない

        prompt-expand-{gbox,bbox} は廃止する。必要ならば呼び出し元で抽出を行う。
        と思ったが、helper 関数として存在しても良いのではという気がしないでもな
        い。何れにしてもこれは後回し。先ずは大きな構造の方を整理する事にする。

    * done: ble/prompt/section#update 廃止

    * done: vim-airline-mode は unit として実装する。

    * done: ble/prompt/unit:UNIT/section::tailor 削除

      これは明らかに実装を複雑化させている。そして tailor だけを invalidate す
      るというのも元々は効率の為だったが、既に様々な無駄がある中で余り意味のあ
      る最適化である様にも思われない。従って tailor は削除する。

    * done: history index/count は変数にする

      取り敢えず _ble_history_INDEX 及び _ble_history_COUNT

      ? _ble_history_prefix が謎である。設定している箇所は見つかるが解除してい
        る所が見つからない。local で宣言している訳でもないし textarea vars に設
        定されている訳でもないから復元される事もない様な気がする。

        例えば vi.sh で _ble_history_prefix=_ble_keymap_vi_filter_ を設定してい
        る。これは ble/keymap:vi/async-commandline-mode から
        ble/textarea#save-state _ble_keymap_vi_cmap を呼び出した後に実行されて
        いる。と思ったらこれについては _ble_keymap_vi_cmap_history_prefix に手
        動で保管して、その後で手動で復元している。vi.sh の中にある物は全てこれ
        だった。

        ./src/edit.sh:7857:  _ble_history_prefix=_ble_edit_read_
        これに関しては subshell で実行しているので戻さなくて大丈夫。

        他に設定している箇所はない。

      他の ble/history/get-{count,index} に関しては明らかに history を
      initialize しなければならない所以外は現状のままで関数経由で取得する事にし
      た。直後に history を initialize する場合にはその場で
      ble/history/initialize を呼び出して直接 _ble_history_{COUNT,INDEX} を参照
      する様に書き換えた。

    x 2021-06-09 textmap が更新される前に表示しようとすると col がずれてしまう。
      これはその場で更新してしまっても問題ないのではないか。特に textmap の更新
      が必要になるという事は dirty という事なので。

      →うーん。此処で気づいてしまったが。textmap で使用する文字幅を決定する為
      には rps1 の幅が必要で、一方で rps1 の中に配置情報を表示しようとするとそ
      の前に textmap を計算しなければならない。取り敢えず rps1 の中に含まれる情
      報は 前回の rps1 の幅に基づく textmap の情報と解釈する事にする。

      後、もう一つの問題は ble/widget/.update-textmap の内部で呼び出している
      textmap が rps1 の幅を考慮できていないという事。
      ble/widget/.update-textmap の実装をちゃんと rps1 の幅を考慮に入れる物に書
      き換えて、更に backslash:position 等の中から ble/widget/.update-textmap
      を呼び出す様に修正した。

  * prompt: [最適化] 依存関係の追跡と部分更新の対応 [#D1590]

    ble/prompot/clear については各プロンプト毎に設定できる様にするべき。
    再描画部分についても dirty かどうかを保持して更新するかしないかを判定するべ
    きの気がする。

    各プロンプト毎に何に依存しているかのリストと依存している物に対する hash を
    自動で生成する様な仕組みが欲しい気がする。仕様としては各プロンプト内部で情
    報を参照した時に ble/prompt/add-dependency xxxx を呼び出す。プロンプトの実
    体化を司る側ではこれをリストにして管理する。hash を生成する時には、
    ble/prompt/data:xxxx/hash を通して関数を呼び出し hash+=:xxxx=$hash を実行す
    る。然しこれだと hash のインスタンス化自体に split, for, += が必要になって
    重そうである。それよりは、直接 eval できる形にした方が良いのかもしれない。

    % つまり
    %
    % _ble_prompt_version_ref+='$LINENO'
    % eval "_ble_prompt_version=$_ble_prompt_version_ref"
    %
    % という具合にする。invalidate する時には各変数について ((LINENO++)) する等し
    % て処理を行う。各プロンプト要素を個別に invalidate できる様に各プロンプト固
    % 有の変数も用意する。コマンド実行後には全て更新する様にしたいので共通の更新
    % 条件としてそれも含めて置くことにする。
    %
    % 実際には ble/prompt/add-dependency は重複して呼び出す可能性もあるので [[
    % :$version_ref: == *:'$LINENO':* ]] 等を用いて重複を排除する。

    vim-airline の様に複数のサブプロンプトを組み合わせる形の場合には、サブプロ
    ンプトの version_ref を集めて判断する必要がある気がする。然し、そうすると長
    大な version 文字列になってしまうがそれで良いのだろうか。或いは無条件にサブ
    プロンプトを巡回して、その後で全体更新が必要かどうかについて判断するという
    のでも良い。その場合にはサブプロンプトの version 番号だけを参照する事にすれ
    ば良い。プロンプトのリストに登録する順序に注意する必要がある。

    _psx_hashdef  ... eval をすれば _psx_hash を計算できるパラメータ展開のコロ
                      ン区切りのリスト。
    _psx_hash     ... _psx_hash を eval して得られた文字列。更新を要求する場合
                      (invalidate) にはこの変数を空にすれば良い。
    _psx_version  ... プロンプト描画内容が変更された時に増加する番号。
    _psx_gdirty   ... プロンプト描画内容が更新された時に 1 に設定。

    同様に共通 hash を保持する。これが変化した時は全てのプロンプトは強制的に更
    新する様に仕組まれる。つまり、全てのプロンプトはこの共通 "prompt" に依存性
    を持つとする。この共通 "prompt" には実体が存在しない。PROMPT_COMMAND 及び
    PRECMD はこの仮想プロンプトに対して更新する。

    _prompt_hashdef
    _prompt_hash
    _prompt_version

    for p in prompt-list; do
      local _hash=${p}_hash _hashdef=${p}_hashdef
      eval "local new_hash=${!_hashdef}"
      [[ ${!_hash} == "$new_hash" ]] && continue

      hashdef='$_prompt_version'

      update....

      内容に変更があった && ((${p}_version++))
      eval "$_hash=$hashdef $_hashdef=\$hashdef"
    done

    hashdef の定義は更新時に毎回行う。最初は依存対象として $_prompt_version か
    ら始める。

    function ble/prompt/reference-prompt { hashdef+=:\$${1}_version; }
    function ble/prompt/reference-variable { hashdef+=:\$$1; }

    ? 全てのプロンプトを巡回しているとすると使われていないのに更新される物が出
      てくるのではないか。そう思うと使う物から順番に要求して、深さ優先順序で更
      新していく様にするべきなのではないか。その為には依存先のプロンプトの一覧
      を個別に保持する必要がある様な気もする。

      hashdef=$_prompt_version:$ps1_version,$ps2_version,...:$var1:$var2:$var3

      の様な形にして : で区切った二番目の要素を , で split して其処から依存先を
      抽出する様にするというのはどうだろうか。

    ? 現在の履歴項目内部の位置など一部の物は事前に関数の実行等が必要になる気が
      する。その場合にはどの様に対応するのか。$(ble/history/get-index;echo
      $index) を埋め込むのは遅そうである。では評価の前に関数を実行するのかと問
      われるとそれもよく分からない。そもそも更新の必要性はプロンプト毎に固定と
      いう訳ではなくて、現在表示している内容に依存している。

      或いは現在の履歴項目内の位置を常に変数で参照できる様にするべきなのだろう
      か。というか何故その様になっていないのだったか。

      うーん。history コマンドの使用によって不意に履歴がロードされたり、或いは、
      初期化によって history がロードされたりという事を想定しての事の気がする。
      実の所、この手のチェックは prologue か何処かで行ってしまえば良いのだとい
      う気がする。

      うーん。というか現在の履歴項目の位置というのも、read 等によって別の履歴に
      切り替わっている時にそれを反映するべきかというのも議論の余地がある。うー
      ん。_ble_history_prefix を設定する時にその辺りの更新処理も実行する必要が
      ある気がする。

      後、共通の変数名をどうするのかというのも困る。_ble_history_ind 及び
      _ble_history_count は既にメインのコマンド履歴の為に使われてい
      る。_ble_history_count を例えば _ble_history_cnt に解明して、その上で新し
      く_ble_history_{count,index} を現在の index/count の変数とする事にすると、
      今度は cnt,ind との区別が分かりにくい。やはり名前空間を分けたい気がする。
      然し一方でコマンド履歴は特別なので _ble_history, _ble_history_edit に格納
      されているというのも妥当である様に思われる。

      - reject: _ble_hist_index, _ble_hist_count というのも変である。
      - reject: _ble_history_current_index, _ble_history_current_count
      - reject: _ble_history_cur_index, _ble_history_cur_count
      - reject: _ble_history_prefix_index, _ble_history_prefix_count
      - reject: _ble_history_i, _ble_history_c
      - reject: _ble_history_cindex, _ble_history_ccount (common)
      - reject: _ble_history_gindex, _ble_history_gcount (global)
      - reject: _ble_history_pindex, _ble_history_pcount (prefix)
      - reject: _ble_history__index, _ble_history__count
      - reject: _ble_history_Index, _ble_history_Count
      - _ble_history_lineno, _ble_history_lines
        これだと繋がりが分かりにくい。
      - BLE_HISTORY_INDEX, BLE_HISTORY_COUNT
        これは一つの手な気がするがこれをユーザーへの公開変数とする意義はあるのか。
        慎重になった方が良い気がする。
      - _ble_history_INDEX, _ble_history_COUNT
        後でまた仕様変更できるのだという事を考えるとこれぐらいで良いのかもしれない。

    ? 設定を新しく変更して別のプロンプトに依存する様になったらどうするのか。うー
      ん。そう考えるとプロンプト更新は順番に呼び出すというよりは、必要になった
      時に不定期に何度でも更新すれば良い気がする。循環参照にならない様に注意さ
      えしておけば特に問題はないだろうという気がする。

    [実装]

    * done: プロンプト周りの整理が必要になる

      先ず ble/prompt/update はプロンプト全般の情報更新に努め、PS1 の結果は呼び
      出し元で必要になった時に読み出す様に変更する。

      ble/prompt/update の結果の内 x y lc lg は後で使用されている。一方で、g 及
      び ret に関しては使われていない気がする。特に ret は直後に別の物で上書き
      されているので関係ない。

      * ok: 変数 g を削除しても問題ないだろうか。

        g に関しては本当の所はどうだろうか。昔の実装では、trace を実行する時に
        入力していた様な気もするが…うーん。やはり違うかもしれない。結局 trace
        は使っていないし専ら textmap, slice, etc. で使っているのみである。もし
        使う事があるとすれば、一番最初の文字の着色だけである。然し、着色に関し
        てはに layer に任されている。layer では最初の g を認識して着色を省略す
        る等の事はしていただろうか。と考えるとしていない気がする。そもそも
        prompt の終端で g を sgr0 以外にしておく必要も分からない。

        実際に出力する場所を確認してみると必ず textarea#slice-text-buffer を使
        用している。そしてこの関数では必ず端点の g を読み取ってそれに対して sgr
        を生成して付加している。なので、prompt 終端の g が表示に影響を与えると
        は考えにくい。それとも highlight/layer の実装で g の値を参照する可能性
        はあるだろうか。うーん。外の g がどういう値になっているかは定義されてい
        ない筈なので参照していない筈。

      * reject: PS0 の最後の g をコマンド列の既定着色として用いる可能性:

        と思ったが、ユーザーがコマンドに色をつけようとしてわざと g として変な値
        を残しておくという事も考えられるだろうか。まあ、それに関しては余り考え
        ない事にする。少なくとも現在の実装では考慮に入れていないし、考慮に入れ
        るとしても別項目で考察するべき内容である。

        それに既定着色を指定できる様にするとなると SGR を生成する段階で様々の修
        正が必要になってくる。変更として大きくなってしまうし有用性がよく分から
        ないのでこのままにする。そもそも色を設定したいのであれば、ble-face を用
        いて設定するべきであって、PS1 経由で着色をするというのは避けてもらうべ
        きである。

      lc lg の計算は現在 ble/textarea#update-text-buffer 内部で実行しているがこ
      れは別の関数にする方が自然なのではないか→別の関数にした。

      ble/prompt/.load は最早誰も使っていないので削除しても良いのでは→削除した。
      引数の詳しい説明については ble/prompt/.instantiate に移動した。

      これ以上の整理に関しては枠組みが完成してからにするべきという気がする。

    * 試験的に新しい枠組みを作成する

      プロンプトを指定する番号はどの様にしたら良いだろうか。というか番号で指定
      できる必要はあるだろうか。考えてみればどうせ色々の変数は指定した prefix
      の下で変数を複数作って管理するのだった。という事を考えると実は prefix で
      指定すれば良いだけなのではないだろうか。取り敢えず prefix で指定する様に
      する。

      一番最初は依存関係の解決等は考えずにただ単純に更新するだけの関数にしてみる。

      * done: control-string 系全てに _data を付加する

      * ok: dirty が個別に設定されていなくても全て再描画する必要が生じる場合も
        ある。というか新しいプロンプトを表示する時は常にそう。invalidate の際に
        全てに dirty を設定する必要がある?

        % 普通に hashref_base (_ble_prompt_version) を確認するだけだと、プロン
        % プトの再計算までは行われるが内容が以前と一致した場合に再描画迄は行か
        % ない可能性がある。今迄は内容を再計算した時には必ず dirty が代入されて
        % プロンプトまで再描画していたが、今回は内容を再計算して更に変化があっ
        % た時にだけ dirty が設定されているので、再描画が実施されるとは限らない。

        と思って確認したが ble/textarea#invalidate が呼び出された時には全体描画
        になって、その時には改めて全て描画される様である。dirty が参照されるの
        は一部だけ更新されている時だけである。なのでこれについては気にしなくて
        良い。

      考えるに dirty は参照される時には参照されるが、参照されない時には参照され
      ない。何れにしても全て再描画される場合には dirty は見ずに常に再描画する仕
      組みになっているので問題ない。

      * done: 変数を参照した時にそれを登録する為の関数を定義する。

        関数名は何が良いだろうか。

        - reject: ble/prompt/add-variable var
        - reject: ble/prompt/add-variable-reference var
        - reject: ble/prompt/add-varref var
        - reject: ble/prompt/reference-variable var
        - reject: ble/prompt/listen var
        - reject: ble/prompt/listen-variable var
        - reject: ble/prompt/hook-variable var
        - reject: ble/prompt/depend-on var
        - reject: ble/prompt/add-dependencies var...
        - reject: ble/prompt/cite-variable var
        - reject: ble/prompt/cite-var var
        - ble/prompt/ref var
        - ble/prompt/onchange var
        - ble/prompt/detect var
        - ble/prompt/cite var
        - ble/prompt/cite-vars var...
        - ble/prompt/reference var

        a 将来的に変数以外の物を参照する可能性があるかどうかという事で var を関
          数名に入れるかいれないかが決まる気がする。考えて見るに eval して fork
          を伴わない物と言えば変数展開以外には算術式展開しか考えられない。とい
          う事を考えるとやはり reference で良いのではないだろうか。

        b 或いは、"変数" である事を示唆する様な動詞が存在すればそれを使うのが良
          い。例えば reference と言えば変数である。

        c というか良く考えたら追加する式を直接指定すれば良いだけの話の気がして
          きた。つまり、

        - ble/prompt/reference '$var'
        - ble/prompt/hash '$var'
        - ble/prompt/add-hash '$var'
        - ble/prompt/add-hashref '$var'

        うーん。add-hash が一番無難な気がする。結局内部で何をするかがこの関数名
        だけで分かるので。もっと分かりやすくするならば、add-update-hash 等にな
        るだろうか。然し短いほうが良いので add-hash にする。

      * done: うーん。vim-airline で子プロンプトを参照する様にしたが、よく考え
        ると、チェックを行うのは子プロンプトを更新する前なので、子プロンプトの
        更新による変化を検出できない。子プロンプトの更新を実施してからチェック
        を行う必要がある。

        然しここで問題になるのは、子プロンプトに渡すオプションやプロンプト文字
        列は事前には分からないという事。子プロンプトが存在する場合には先に子プ
        ロンプトを更新してから更新判定を実行する必要がある。うーん。或いは。や
        はりプロンプト毎に更新を行う関数を事前に登録しておくべきなのだろうか。

        プロンプト section_a を更新する為の関数を登録することにした。

      * done: ble/prompt/clear は個別に invalidate または自動検出にする

        というか実は更新の必要すらないかもしれない。今となっては必ず全ての
        prompt について hashref のインスタンス化を試す様になっている。ここに ps
        も含めるべきなのではないか。

        と思ったが、現在の実装だと ble/textarea#redraw は何も変更がないと即座に
        抜けてしまう様になっている。少なくともプロンプトに関しては更新を行わな
        いと駄目なのではないか。

        * ble/prompt/clear の使用箇所を改めて確認する

          ./ext/.../fzf-marks.plugin.bash:317:    [[ $PWD != "$pwd" ]] && ble/prompt/clear
            これは \w または \W を参照している時に呼び出す事にする。
            他に埋め込まれている変数の場合の可能性もあるが気にしない。

          ./keymap/vi.sh:468:    ble/prompt/clear

            これは show-mode-in-prompt の時に呼び出す物。これは変数に変える事が
            できるのでは。

          ./src/edit.sh:169:      ble/prompt/clear

            bleopt_prompt_status_align の変更に伴って更新を行う。うーん。これに
            関しては実は prompt#update の hash に値を含めても意味がない。最終的
            に生成される esc が同じである以上は dirty と判定されないからである。
            特に left と right の切り替えに対してちゃんと処理できない。という事
            を考えると hash をクリアするしかない気がする。

            結局、ble/prompt#update の内部から ble/prompt:"$prefix"/tailor とい
            う関数を呼び出させてその中で加工処理を行う事にした。tailor だけの
            invalidate として、ble/prompt#clear _ble_prompt_status tail を呼び
            出させる事にした。

          ./src/edit.sh:1275:    ble/prompt/clear

            これは ble/prompt/notify-readline-mode-change である。更にこの関数
            の呼び出し元も調べる必要がある?

          ./src/edit.sh:7568:  ble/prompt/notify-readline-mode-change

            これは ble/widget/safe/__attach__ から

          ./keymap/vi.sh:7649:  ble/prompt/notify-readline-mode-change

            これは ble/widget/vi_imap/__attach__ から

          というか本当にちゃんと更新されるのだろうか。と思った
          が、./keymap/vi.sh:468: ble/prompt/clear は実の所
          ble/prompt/notify-readline-mode-change に変えるべきなのでは? と思った
          が、vi.sh:468 は show-mode-in-prompt だけでなくプロンプトの表示を切り
          替えるのに使う物の気がする。うーん。

      * done: ble/prompt/notify-readline-mode-change に関しては自然に変数経由で
        更新を検知できる様にする。関数自体を削除した。

    x fixed: 何か入力した場合に何も表示されなくなってしまっているこれは何だろう
      か。恐らくこれは単に更新した時に expand gbox,bbox が解釈されていないのが
      原因だろう。

      修正した。問題は発生しなくなった。

    x fixed: 2021-06-09 history: isearch 検索を中止した時に履歴の先頭に移動する
      様になってしまっている。検索を開始する前の初期化に関係するのだろうか。と
      思ったがそうでもない様だ。履歴がロードされた後でも同様に問題が再現する。

      これは最近発生する様になった問題である。明らかに prompt の改良に伴っ
      て_ble_history_INDEX の記録関係に失敗する様になっている。うーん。
      get-index ではちゃんと大きな値を取得する事ができている。逆に復元する時の
      様子を見てみると…。

      _ble_edit_isearch_arr=([0]="29801:-:0:0:" [1]="29769:-:22:23:f" [2]="29305:-:6:8:fd" [3]="29305:-:6:9:fds")
      step=([0]="29801"

      うーん。ちゃんと正しい値を読み出す事ができている気がする。という事は現在
      の履歴位置が間違っているという事になるのだろうか。うーん。何と、
      history/goto の直後に _ble_history_INDEX は空欄になってしまっている。どう
      いう事だろうか。

      これは分かった。ble/history/set-index の実装で存在しない変数 (削除した変
      数) を参照していた。修正した。

  * 2021-05-24 airline: 説明書を書く。theme の枠組みを整える [#D1589]
    https://github.com/akinomyoga/ble.sh/issues/114 (2)

    * done: themes の枠組みを整えたい気がする。現状だとユーザーがそれぞれ対応し
      なければならない。面倒である。うーん。取り敢えず contrib に適当に加えてみ
      るというのも良い気がする。

    * done: _modified には対応していない。

      履歴項目については現在の内容とずれている時に modified にできる。最新項目
      については何か文字列があれば modified にできる→これは対応した。

    * done: themes は自動的に変換する様にできたら良いが調べてみると面倒な気がする。

      自動変換は vim スクリプトを書いて行った。取り敢えず themes は現状で良い気
      がする。mode_map も抜き出そうと思ったが実は atomic.vim しか設定している物
      はなかった。

      contrib に一括で追加しようと思ったが止めて置く事にした。もっと普通のファ
      イルが増えてからにするのが良い気がする。或いは要求したら自動的に何処から
      かダウンロードするというのも手なのかもしれない。

    * reject: テーマ用の bleopt を用意する

      bleopt vim_airline_theme=xxxx

      を設定したら自動で ble-import contrib/airline/xxxx を読み込む様にしたい。
      或いはよく考えたら直接 ble-import contrib/airline/xxxx と書けば良いだけな
      のではないか。

    * 説明に関しては theme を用意してそれを見てもらえれば十分の気がする。但し、
      辞書に関しては theme は bash-4.1 以下でも動く様に gdict を使わなければな
      らずややこしい。

      何れにしても huresche に対する返答で説明するので、その内容を後で Wiki に
      転記すれば良い。

    * done: というか、考えてみたら ble-import する時に毎回 contrib まで指定する
      必要があるのは変な気がする。source path を指定したら其処から自由に source
      してもらうべきなのではないのか。

      ble-import vim-airline
      ble-import core-syntax
      ble-import keymap-vi
      ble-import prompt-git
      ble-import fzf-bingings
      ble-import fzf-completion
      ble-import airline/landscape

      別にこれで良い気がする。寧ろこちらの方が良い。

      local user=${XDG_DATA_HOME:-$HOME/.local/share/blesh}
      BLE_IMPORT_PATH=$user:$user/lib:$_ble_base:$_ble_base/contrib:$_ble_base/lib

    x emacs mode にいる時に vim-airline を呼び出すと真っ黒になって何も表示され
      ない。と思ったらこれは inactive face が使われていて、この inactive の設定
      が物凄く見にくいという事だった。微妙に色が見える。じれが dark.vim の設定
      という事なのでそのままにする事にする。

    x 2021-06-10 ble-import の search path として ~/.local/share/blesh を追加し
      たが、これだと異なる version の設定ファイルが混在する原因である。そうする
      と不整合を生んで変な事になる。特に keymap/vi や keymap/emacs は致命的な問
      題を引き起こし得る。という事を考えると、 ~/local/share/blesh は直接は追加
      せずに ~/.local/share/blesh/local 等から読み取る様にするべきである。

2021-06-05

  * locale によっては正規表現の [a-z] でも駄目 (reported by huresche) [#D1588]

    a 一つの方法は全ての文字を [abcdefghijjklmnopqrstuvwxyz] と言った具合にして
      並べるという事。これは冗長である。0-9 に関しては C 言語の要求で連続に並ん
      でいる事が保証されているので書き出す必要はない。

    b もう一つの方法は必要な箇所で LC_COLLATE=C を設定するという事。然し、必要
      になる箇所が多岐に渡る。

    c 或いは、もう ble.sh の処理を全て LC_COLLATE で囲んでしまうというのも手な
      のかもしれない。と思ったが、LC_COLLATE を解除する場所でエラーメッセージが
      出るのを抑制しなければならない。とは言え、それはそんなに難しくない。問題
      は何処で LC_COLLATE で囲めば良いのかという事。ユーザーコマンドを実行する
      前後で切り替えれば良いのだろうか。或いは、PROMPT_COMMAND や hook を呼び出
      す時にも配慮しなければならないのだろうか。

    * 取り敢えず必要な箇所がどれだけあるかについて確認する。

      $ grc -i 'a-fa-f|a-za-z' --exclude=ext

      で検索すると流石に沢山ある。さて、もし LC_COLLATE=C を設定するのあれば実
      は [:alpha:] や [:alnum:], [:xdigit:] も使えるのではないだろうか。

      然し、何れにしても全ての箇所について個別に対応するのは難しい気がする。

    * reject: 正規表現を使っている各箇所で LC_COLLATE=C を設定する方針

      少し変更してみたがどうにも限界がある様な気がする。この方針は諦める事にす
      る。修正は memo/D1588.stub-LC_COLLATE-1.patch に残す。

    * reject: bind/.{head,tail} 内部で LC_COLLATE を設定する方針

      locale の設定をする時にはユーザーのロケールが壊れている場合に備えて、
      stderr を抑制している。然し、無闇に全体を囲んでしまうとエラーメッセージが
      全て隠蔽されてしまう。局所的に stderr を抑える事はできないだろうか。試し
      に実験してみると以下の様にすれば問題ない様だ。bash-3.0..dev まで全て確認
      した。

      $ bash -c '
        { LC_COLLATE=alpha; } 2>/dev/null
        unlocal() { unset -v "$1"; }
        fun() { local LC_COLLATE=fsa 2>/dev/null; unlocal LC_COLLATE 2>/dev/null; }
        fun'

      この方針でも全てをカバーしきれる訳でもないので微妙である。

    うーん。LC_COLLATE=C にする事にするか。取り敢えず内部環境では LC_COLLATE=C
    を強制する事にする。LC_ALL の状態も調整する。

    * LC_ALL 待避の取り扱いについて

      と思ったが現在の実装では LC_ALL も含めて文字コードの振る舞いを決定してい
      る。待避した _ble_bash_LC_ALL を使って振る舞いを変更するべきだろうか。或
      いは、現在の LC_ALL を使って振る舞いを決定するべきだろうか。うーん。

      ここで問題になるのは、LC_ALL を空にしてしまうと LC_CTYPE 等他の設定に影響
      を及ぼすという事である。現在、local LC_ALL= LC_COLLATE=C という形で様々な
      箇所で待避を行っているが、これだって LC_CTYPE カテゴリの値に影響を与えて
      しまう。

      a LC_ALL= を設定すると共にその他のカテゴリについても全て LC_ALL を適用す
        る。例えば ble/util/locale/project 的な関数を用意して、LC_ALL に有限の
        値が設定されている時にはそれを各 LC_* 変数に適用する。然し毎回それを実
        行するのは遅くなる原因である。特に変数の数だけ locale の設定が行われる
        と考えるとこれは避けたい。

      b そもそも LC_ALL は ble.sh の内部では無視するという可能性。LC_ALL は何ら
        かのユーティリティーの振る舞いを強制する為に使う物であって、対話環境で
        の locale を無理矢理に変更する為に用いる物ではない。寧ろ、そういうのは
        LANG を通して変更するべきである。

      c LC_ALL が振る舞いに影響を与えたとしても関知しない。これは一つの手である。
        LC_ALL を設定している時点で変な振る舞いをしたとしても文句は言えないとい
        う立場。然し、そうだとしても例えば Bash は LC_ALL を変更したからと言っ
        て変数名の規則が変わる訳でもないし、一貫しない動作になるのは避けたい気
        がする。

      d 逆に LC_ALL の効果が ble.sh 内部で中途半端に消えたりしても文句は言えな
        いという立場。これは現在の振る舞いに近いと言える。

      f 或いは射影を adjust の段階で実行するというのも手である。うーん。その方
        が現実的な気がして来た。

        LC_COLLTE=C に固定してしまっても問題ないだろうか。ユーザーの側で何か気
        になる事が発生する可能性はあるだろうか。例えば [a-zA-Z] の振る舞いが
        ble.sh 内部 (PROMPT_COMMAND, etc.) で変化してしまうという影響が考えられ
        るが、問題になる事は少ない気がする。例えば fzf の振る舞いが変わってしま
        うという事も考えられるが、実のところ LC_COLLATE=C ではなくてそのロケー
        ルにおける collation を使う必要があるという状況が思い浮かばない。これに
        ついては、ロケールに従った振る舞いにしたければ実際に呼び出す側が fzf に
        LC_COLLATE を設定するなどしてもらうという形で良い様に考える。

      うーん。f の方針で行く事にする。待避するとしたらどの変数を待避する必要が
      あるだろうか。Bash は LANG, LC_ALL, LC_COLLATE, LC_MESSAGES, LC_NUMERIC,
      LC_TIME に対して変更を検知している。これらに対して全てチェックを行う必要
      があるだろうか。

      ? ok: ble/variable#copy-state 関数を使おうと思ったがこの関数は対象が配列
        や辞書である時に問題になる。要素 [0] が存在していないと配列・辞書全体を
        削除してしまう事になる。然し、だからと言って配列・辞書の状態も保存する
        となると大変である。

        どうも bash-4.4 以降であれば unset -v 'a[0]' という具合にすれば、配列変
        数であれば該当要素だけ削除して、通常変数であればその変数を丸ごと削除す
        るという動作にする事ができる様である。うーん。という事は、

        unset -v 'a[0]' || unset -v a とすれば良いのではないだろうか。

      ? reject: (余談) 実は配列かどうかの判定に unset -v 'a[巨大な数]' を使う事
        ができる可能性?  と思ったがそもそも変数すら存在していない時にも unset
        -v 'a[xxx]' は成功する様である。なので、変数が存在している事の確認と共
        に判定を実行する必要がある。然し、空配列に対して変数が存在しているかど
        うかをどうやって判定するのか。declare -p a として確認する必要があるので
        はないか。然し、宣言されているだけで unset な状態になっている場合もあっ
        て、その場合には declare -p a も成功してしまう。

        * declare -p a
        * ((${#a[@]})), [[ ${a[@]} ]] , [[ -v a[@] ]], etc.

        色々考えると余り有用ではない様に思われる。特に bash-4.0 以降では辞書と
        の区別もしなければならないので unset -v だけでは不十分である。

      取り敢えず新しい ble/variable#copy-state を使って実装した。

    既存の LC_ALL= LC_COLLATE=C に対する対策等はもう不要になった様な気もするが、
    ユーザー環境から呼び出される可能性もあるのではないかなど色々考えると、既存
    の対策に関しては今は残しておいて良いのではないかという気がする。

  * vte の paste で LF が CR に化けるという話 (reported by alborotogarcia) [#D1587]
    https://github.com/akinomyoga/ble.sh/issues/120

    最初の報告で自分の手許で試してみても再現しなかったが、端末について確認を取っ
    てみると vte であって、更に LF の代わりに CR が送信されて来ているという事が
    分かった。

    いざ修正しようと思ってコードを確認したら既に workaround は入っている様に見
    える。と思ったが、これはあれだ。連続する CR が入っていると変換しきれていな
    い。修正した。多少速度が下がったかも知れないが仕方がないだろう。

2021-05-30

  * util: stdin, stdout が継承されて新しい端末を開いても元端末に表示される [#D1586]

    これは問題だ。取り敢えず inherit は基本的に止める方が良いのだろうか。
    指定した fd が別の fd と一致しているかどうかを判定する方法は存在するだろうか。
    というか端末 tty の結果が変わったら継承しないという具合にするのが良い気がする。
    端末 tty を取得する方法はコマンド tty を実行するしかないのだろうか。

    というか別に現在の 0 が端末であれば普通に上書きすれば良い気がする。
    その様に修正した。

  * decode: Kitty の modifyOtherKeys でまた問題が生じている (reported by lyiriyah) [#D1585]
    https://github.com/akinomyoga/ble.sh/issues/118

    報告によるとコマンドを実行する前には ESC は ESC としての用を為さないという
    事の様である。そしてコマンドを実行すると動く様になるという事。

    手許で Kitty で試してみた所再現した。modifyOtherKeys を internal/external 0
    に設定すると問題は再現しない。internal 2 にすると再現する。internal 1 に設
    定すると問題が発生してしかもコマンドを実行しても直らない。

    どうも Kitty で 2 に設定すると一回は modifyOtherKeys が有効になるが、それ以
    降は modifyOtherKeys は無効化される? 或いは 2 に設定しようとしても何も起こ
    らないという事だろうか。うーん。2 に設定しようとしても何も起こらないという
    事の様である。然し、それならば不思議なのは ble.sh は 4;2 を設定する前に 4;1
    を送信する様にしているという事。それなのに 4;2 の効果がないというのは不思議
    な事である。実際に手許で試してみても 4;1 に設定して 4;2 に設定すると、4;1
    に設定したのと同じ状態になる。

    問題は二種類ある

    * Kitty で \e[>4;1m の時に送信されるキーシーケンスが ble.sh で認識されてい
      ない。実際に試してみると ESC を押した瞬間に何かしら送信はされている様であ
      る。

      これに関しては具体的に何が送信されているのかを確認する。

      keylog で調べてみると "ESC [ 2 7 u" を送信して来ている。decode.sh を確認
      したがちゃんと認識している。と思ったが isolated ESC ではなくて modifier
      ESC として認識されている気がしてきた。調べてみた所、以下の様な流れで処理
      される事になり、modifier ESC になってしまう。

      ble-decode-char
        ble-decode-char/.getent
          ble-decode-char/csi/consume
            ble-decode-char/csi/.decode
              csistat 設定
          csistat を ent にコピー
        ble-decode-char/csi/clear
        ble-decode-char/.send-modified-key "$ent" "$seq"
          此処で $1 == 27 の時に
          ble-decode-char/.process-modifier Meta を呼び出している。

      csi で受信した文字が 27 の場合には IsolatedESC として処理する事にした。特
      に CSI シーケンスの処理結果として得られた 27 が modifier ESC になる事はあ
      り得ない気がするので csi/.decode の戻り値に対して一括で処理する事にした。

    * Kitty で 2 に復帰した時に \e[>4;0m の状態になっている気がする。
      \e[>4;1m\e[>4;2m で 2 に設定している筈なのに不思議である。手許で自分で設
      定するとちゃんと 4;1 の状態になっている。

      次の問題はこれである…。実際に確かめてみると、そもそも有効化の 4;1; 4;2
      の所に入っていない様だ。確認してみると
      ble/term/modifyOtherKeys/.supported が false になっている。更に調べると
      _ble_term_TERM が vte になってしまっている。

      DA2R を見て判断する事にする。Kitty の DA2R は一体どういう形式なのだろう。
      調べると以下が該当するコードである。

        ./kitty/screen.c:1460: write_escape_code_to_child(self, CSI, ">1;"
        xstr(PRIMARY_VERSION) ";" xstr(SECONDARY_VERSION) "c"); // VT-220 +
        primary version + secondary version

      そしてこれらの値は setup.py に於いて

        constants = os.path.join('kitty', 'constants.py')
        version = tuple( map(int, re.search( r"^version: Version =
          Version\((\d+), (\d+), (\d+)\)", constants, re.MULTILINE ).group(1, 2, 3)
          ))
        cppflags.append('-DPRIMARY_VERSION={}'.format(version[0] + 4000))
        cppflags.append('-DSECONDARY_VERSION={}'.format(version[1]))

      という具合にして初期化されている。kitty/constants.py には以下の様な行がある。

        version: Version = Version(0, 19, 3)

      どうも Kitty の version は永年 0 の様だ? 取り敢えず適当に kitty 用の判定
      条件を追加する事にした。

2021-05-29

  * syntax: \? を着色したい [#D1584]

    色は magenta で良い。\q が現れる箇所はコマンド、"..." である。それぞれ規則
    は異なる。特に後者については規則が分かりにくいので色を付ける対象にしたい。

    $'...' も別枠で着色する様にしたい。これもちゃんと実装した。これで
    $'...' を書く時にどのようなシーケンスが有効でどの様なシーケンスが
    無効か分かる。所で bash version 依存性はどうなっているのか確認する
    必要がある。

  * complete: quote されているコマンド名に対しても補完関数を適切に探索 [#D1583]

    quote していると補完関数が認識されない。例えば git co とすると OK だが
    'git' co とすると反応しない。然し実の所、これは普通の bash でも同様である。
    普通の bash でも 'git' としている時には git の補完関数は呼び出されない。

    unquote した上で補完を探索するべきである気がする。但し、alias 展開などに関
    しては quote された物で実行するという事。comp_line, comp_words に入っている
    のは展開前の quote された物であるので余計な事は考えなくて良い。

  * [reject] complete: そもそも -F に指定する事のできる文字列には制限がある筈である [#D1582]

    これを満たさない場合には強制的に其処で終端させる等の対策が必要なのではない
    か。

    然し、;&| 等が含まれていた場合にどの様に取り扱うべきかは不明である。明らか
    に何かが間違っているけれども、だからと言ってその直前までを関数名と捉えるの
    にも無理がある様な気がする。然し、それ以外に解釈のしようがないとも言える。

    或いは途中に空白がある場合には ble.sh の拡張として関数に余分の引数を渡す事
    にする? 然し、これは最新の bash-5.1 では使えない事なので古い Bash だけで使
    える機能として提供しても仕方がない。結局これは失敗するべきなのではないか。
    そして失敗するのだとしたら現状の動作のままで良いという事の気がする。

  * complete: alias の展開結果で変数代入を除去するべきではないか [#D1581]

    というより実の所 simple-word でできるだけ解析していくべきの気がする。と思っ
    たが、 ; や変数代入があった時の振る舞い、文法エラーがある場合の振る舞いなど
    は用途によってまちまちなのでこんｋ内は core-complete.sh の側で実装する事に
    した。

    simple-word の終端しない版というのはあっただろうか。なかったが
    simple_rex_element をそのまま使えば良い。

    * __load_completion を呼び出すと -D に相当する処理が勝手に入ってしまう。
      complete が駄目な気がする。自前で補完定義を探してロードする関数を作ってみ
      たが、その後で気づいたのは __load_completion は別に見つからなかった時に勝
      手に既定の定義を使う訳ではないのだという事。

      以下の自前の定義は結局使われる事はないのだった。

      | _ble_complete_progcomp_bashcomp_initialized=
      | _ble_complete_progcomp_bashcomp_dirs=()
      | function ble/complete/progcomp/.bashcomp-initialize {
      |   if [[ ! $_ble_complete_progcomp_bashcomp_initialized ]]; then
      |     _ble_complete_progcomp_bashcomp_initialized=1
      |
      |     local user repo bin
      |     user=${XDG_DATA_HOME:-$HOME/.local/share}/bash-completion/completions
      |     [[ $BASH_COMPLETION_USER_DIR ]] && user=$BASH_COMPLETION_USER_DIR/completions
      |     ble/string#split repo : "${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
      |     bin=./completions
      |     [[ $BASH_SOURCE == */* ]] && user=${BASH_SOURCE%/*}/completions
      |
      |     local path
      |     for path in "$user" "${repo[@]}" "$bin"; do
      |       [[ -d $path ]] && ble/array#push _ble_complete_progcomp_bashcomp_dirs "$path"
      |     done
      |   fi
      | }
      | function ble/complete/progcomp/.load-bash-completion {
      |   local cmd=$1
      |   ble/is-function __load_completion || return 1
      |   ble/complete/progcomp/.bashcomp-initialize
      |
      |   local dir file
      |   for dir in "${dirs[@]}"; do
      |     for file in "$dir"/{"$cmd","$cmd.bash","_$cmd"}; do
      |       [[ -s $file ]] || continue
      |       source "$file"
      |       return 0
      |     done
      |   done
      |
      |   ((_ble_base>=40000)) || return 1
      |   ble/is-function _filedir_xspec &&
      |     [[ ${_xspecs[$cmd]+set} ]] &&
      |     complete -F _filedir_xspec "$cmd"
      | }

  * complete: "\a" 等のコマンド名の補完で問題が起こる (reported by huresche) [#D1579]
    https://github.com/akinomyoga/ble.sh/issues/116

    [原因]

    | bash_completion との関連でまた問題が起こっている。最新の bash_completion で
    | 再現する事ができた。
    |
    | 何れにしてもこれは bash とのインターフェイスの違いなので修正されるのは
    | ble.sh の方であろう。そして文面を読む限りは "minimal ''" という名前のコマン
    | ドを呼び出そうとしている?  これは parse の問題の様な気もするが…。取り敢え
    | ず何が起こっているのか調べる。

    結局これは ble.sh の側の問題であった。再現条件は bash-5.1 である。
    bash_completion では何故か空文字列に対するコマンドでも complete -F _minimal
    '' を登録する様で、しかも bash-5.1 から complete -p の出力の形式が変化した
    事によって ble.sh が -F の解析に失敗して問題が露呈したという事になる。

    | * "a" では発生しない。"\a" や "$$" では発生する。
    |
    | 取り敢えず再現しているので何が起こっているのか調べる事にする。
    |
    | % うーん。どうやら。simple word じゃない時にコマンド名を決定できず、結果と
    | % して空のコマンド名に対して補完が呼び出されているという形になる。うーん。
    | % この場合にはどうするのが良いだろうか。もう直接 simple-word でない内容を転
    | % 写する?  うーん。それも一つの手である。
    |
    | と思ったが、そうでもない様である。例えば "$$" というのは simple-word である。
    | 改めて何で空になるのか確認する必要がある。
    |
    | "\a" は展開されて \a になるがそれにより補完は最終的に失敗する様だ更に引き続
    | き \\ による補完が呼び出されてそれが evaluate されて \ になる等している。然
    | し、"$$ の場合には数字に展開されて、その後で曖昧補完の為に一文字目 "1" の数
    | 字を使って補完されるという事が起こっている。それでもエラーは発生している。
    |
    | 不思議なのは普通に 1 として入力しても問題が生じないという事。というか、やは
    | り COMP_WORDS が空になってしまっているのが問題なのだという気がする。
    |
    | ? そもそも最初のコマンド名でない場合でも、simple-word でない場合には補完は
    |   どうなっていただろうか。
    |
    | →少し分かった。generate-subwords が5回実行されていて '$$', '', '1', '1',
    | '' となっていて問題のエラーは空文字列で呼び出された時に発生している様である
    | という事。遡って見るとそもそも compgen-helper-func 自体もその様に呼び出され
    | ているという事が分かった。ble/complete/progcomp/.compgen もその様に呼び出さ
    | れている。
    |
    | ? うーん。不思議なのは "a" 等の普通の表記の時にはその様な事がないという事で
    |   ある。何故だろうか。調べてみると普通の場合でもちゃんと空文字列による補完
    |   が呼び出されている。そもそもこの空の状態での補完の要求が一体何故呼び出さ
    |   れているのかという疑問は残るが、現在発生しているエラーメッセージとは関係
    |   がないという事だろうか。
    |
    |   然し空の文字列になる場合を除外してみるとちゃんとエラーメッセージなく補完
    |   が実行される様である。
    |
    | ? ok: 何故空の文字列で補完 compgen が呼び出されているのだろうか。
    |
    |   これは曖昧補完で -I による補完を試みているからである。
    |
    | ? done: 何故普通のコマンド名の場合には空の文字列で補完が呼び出されても問題
    |   が発生していないのか。何故特定の文字列の時にのみエラーメッセージが発生す
    |   るのだろうか。
    |
    |   | うーん。不思議な事だ。どうも調べると compdef に変な文字列が入ってくる。つ
    |   | まり complete -p 自体が予期しない内容の文字列を出力しているという事だろう
    |   | か。
    |   |
    |   | うーん。どうやら空文字列で呼び出されるのは曖昧補完の為に -I でコマンド名
    |   | を保管しようという時の話であって。然し、何故か文字列の種類に応じて -I で
    |   | 呼び出されたり或いは直接コマンド名で呼び出されたりというのが変化している
    |   | という様子。もっとちゃんと書くと何故か文字列の種類によって initial が付け
    |   | られずに compgen が呼び出されるという事。
    |   |
    |   | やはり initial なしで呼び出されるというのは変だ。initial がないという事は
    |   | コマンド引数としての補完を要求している事に他ならない。然し、空文字列での
    |   | 補完なのにそれは起こり得ない筈である。呼び出し元を確認する必要がある。調
    |   | べてみると何故か "$$ の時には source:argument が生成されているのだという
    |   | 事が判明した。一体どういう事なのだろうか。source:command は一切生成されて
    |   | いない。うーん。syntax の context 生成が怪しいという事になるだろうか。
    |   |
    |   | 生成された source を確認してみると declare -a sources=([0]="argument 0")
    |   | が生成されている。うーん。つまり、core-syntax.sh に於いて単語内部の nest
    |   | した文脈からだと argument が生成されてしまうという事である。

    "..." の内部の nest した文脈ではそれがコマンド名か引数内部かに関係なく
    argument が生成されてしまうのが原因だった。

    確認してみると以下の関数で argument 決め打ちにしている。
    ble/syntax/completion-context/.check-prefix/ctx:quote/.check-container-word

    判定の為に nest に登録されている単語情報を確認しているが不思議である。 CMDX
    や ARGX になっている。CMDI や ARGI ではないのだろうか。特に nest が始まった
    のが単語の途中であっても CMDX や ARGX になっている。

    > function ble/syntax:bash/ctx-command/.check-word-begin {
    >   if ((wbegin<0)); then
    >     local octx
    >     ((octx=ctx,
    >       wtype=octx,
    >       ctx=_ble_syntax_bash_command_BeginCtx[ctx]))

    うーん。この部分を見ると wtype は単語が始まった瞬間の文脈を保存している。

    > function ble/syntax:bash/ctx-command/check-word-end {
    >   # 単語の中にいない時は抜ける
    >   ((wbegin<0)) && return 1
    >
    >   # 未だ続きがある場合は抜ける
    >   ble/syntax:bash/check-word-end/is-delimiter || return 1
    >
    >   local wbeg=$wbegin wlen=$((i-wbegin)) wend=$i
    >   local word=${text:wbegin:wlen}
    >   local wt=$wtype
    >
    >   [[ ${_ble_syntax_bash_command_EndWtype[wt]} ]] &&
    >     wtype=${_ble_syntax_bash_command_EndWtype[wt]}

    更に此処で _ble_syntax_bash_command_EndWtype を用いて最終的に記録する wtype
    に変換している。という事は実際の判定でも _ble_syntax_bash_command_EndWtype
    を参照するべきである。

    [修正]

    * done: compcmd が空文字列の時に bash は '' を出力する。つまり微妙に quote
      するという事。

      $ complete -o bashdefault "''"
      $ complete -o bashdefault ''
      $ complete -p

      試した見た限りでは空文字列の時にだけ '' と出力してそれ以外の場合には直接
      出力する様である。これについては一つ対策を入れる必要がある。これは他の問
      題を修正してから取り掛かる。

  * util (assign): Cygwin で assign 一時ファイルの衝突が発生している様だ [#D1578]

    assign 一時ファイルに BASHPID を付加する様にしたら特に問題は発生しない様子。
    なのでやはり assign 一時ファイルの衝突なのだろうと思われる。実際に保存され
    たファイル名を観察するとやはり衝突が起こっているかも知れない。

    特に頻繁に起こるのは background シェルと親シェルに於ける
    ble/function#getdef なのだろうという気がする。取り敢えず、ble/util/assign
    におけるファイル名の確保を関数に纏める事にする。

    呼び出し元を出力して調べてみた所、そもそもサブシェル内部から呼び出しが発生
    しているのは ble/bin/awk の初期化のみの様であった。ble/bin/awk を、
    ble/util/assign が設定されてから即座に初期化する様に修正してみた所、
    subshell 内部からの ble/util/assign は全く発生しなくなった。

    * 他に気になることとしてはファイルの中身が残ってしまっているという事。

      dec する場所で一緒に clear する事も考えてみたが、実際に実装を見てみると一
      時ファイルの中身を呼び出す前に dec している。読み出し中にエラーがあって中
      断した時の事を考えてだろうか。然し、実行が中断してしまう程のエラーが起こ
      る状況が分からない。set -ue は off にしているし failglob は起こりようがな
      い。なので、dec の位置を変更して dec と一緒にファイルのクリアも行う様にす
      るというのは一つの手である。

      特に大量のデータがある場合にはやはりファイルの中身をクリアするのが望まし
      い。これで多少パフォーマンスが落ちてしまうかもしれないが、問題になりそう
      なのは初期化ぐらいの物であって、初期化の場合には色々他にも bottleneck が
      あるだろうという事で余り気にしない事にする。いざ初期化時間を縮めようと思っ
      たらまた何か別の初期化を遅延させる事にするのが良い。何れにしてもプロファ
      イリングした上で決める事である。

      取り敢えず今の所はファイルの中身は消去する事にする。

    対策は取り敢えずそれでよしという事にする。

2021-05-28

  * ble-reload した時に alias が無効になってしまう [#D1577]

    何故だろうか。そもそもshopt -u する様な事はない…と思ったが、うーん。これは
    単純なミスである。

  * history: bash-3.0 で履歴の数が減少していく問題が再発している [#D1576]

    これは対策をした筈なのに何故だろうか。

    取り敢えず対策コードにちゃんと進入しているのかどうかだけでも確認する。

    再現条件が分かった。bashrc からロードしていると発生しないが、コマンドから
    source して attach すると発生する。bash-3.1 では再現しない。

    該当箇所で確認したがちゃんと復元できている様な気がする。history -p で検索し
    てみたらもう一箇所別の場所で呼び出している。其処の判定条件を確認すると
    bash-4.0 未満の場合には無条件でサブシェルで実行している様に見える。と思った
    がよく見たら _ble_bash となるべき所が _ble_base になってしまっている。

    然し、そもそもサブシェルの判定は ((BASH_SUBSHELL)) で判定できるのでこんなに
    複雑な式を用いる必要はない。

    * done: 算術式の中で誤って _ble_base を使ってしまうという事が余りに多いので
      これも make_command.sh に登録しておくのが良い気がする。登録した。

      $ grc '\(\(.*\b_ble_base\b.*\)\)'

      他には同じミスをしている箇所は存在しなかった様である。

  * main: set -u で壊れていないか久しぶりに確認する必要がある気がする [#D1575]

    試してみたら沢山のエラーが発生している。というか本来 set +u で待避している
    筈なのに何故こんなに沢山のエラーが発生しているのだろうか。不思議である。
    一通り attach する迄の部分を修正していったが実は必要なかった。

    何故 set +u できていなかったのかというとそもそも adjust-bash-options 自体の
    guard で未定義の変数を触っていた為に、adjust-bash-options が実行されていな
    かったのが原因だった。それを直したら普通に動く様になった。

  * main: expand_alias の設定を変えるのはやはり良くない [#D1574]

    現在 ble.sh の内部では完全に alias を無効化しているが、そうすると blerc の
    中で alias を使っている場合に対して影響が出るのではないかという気がする。そ
    の場合には関数を使う様に指示する事もできるが、やはり alias が使えないという
    のは特殊な気がする。

    特に何らかのフレームワークを介して意図的に alias を使って様々の事を実現して
    いるという場合も考えられる。そういう事を考えると alias を何もかも動かなくし
    てしまうのは違う様な気がする。

    うーん。expand_aliases が影響を与えるのは主に ble.sh のロード時であって、ロー
    ドが完了した暁には殆ど影響はない? 然し、実際には沢山の eval を使っていて
    eval は影響を受ける。特にキーワードや builtin に名前が一致する様な alias に
    関しては対策を行っている。その他に影響を与える様な変な alias を設定している
    人がいたとしたらそれはその人が悪いのであって、ble.sh の関知する所ではないの
    ではないか。という事を考えるとやはり alias は有効のまま処理するべきの様な気
    がする。

    一応 expand_aliases の adjust を導入した時の議論を確認して問題がないか考え
    る。該当する議論は #D1519 にある。関連する問題として #D1526 があった。改め
    てこれについて考え直すのが良い。

    * 少なくとも adjust builtins をした後には expand aliases は必要ないのではな
      いかという気がする。或いは、adjust builtins で待避する alias の数を増やす
      必要がある気もするが。

    これの修正は簡単だった。他に影響が現れるとも思いにくいが一応確認はしておく
    事にする。

    と思ったらやはり単純ではない様だ。どうやら alias の状態が bind -x を跨いで
    戻ってしまうのは shopt -u expand_aliases している時だけの問題ではなくて、
    shopt -s expand_aliases だった時にも同様の様である。なので、やはりユーザー
    の側でどういう状態になっていたのかという事を記録・復元する必要がある。

  * ble-sabbrev の初期化遅延で内容出力迄も遅延されている (bash-3.*) [#D1573]

    ble-sabbrev の初期化を遅延しているが、内容確認の為の ble-sabbrev ですら遅延
    されて、ロードした時になってから内容が出力される。この振る舞いは修正するべ
    きである。然し、これを検出する為には、ble-sabbrev の一時実装の側で引数を解
    析する必要がある。

2021-05-27

  * canvas: 変数リークしている (buff, trap, {x,y}{1,2}) [#D1572]

    buff, trap は直ぐに見つかったが x1,x2,y1,y2 は使っている所が多いと思われる
    ので探すのは面倒である。とは言え特にプロンプト関係が怪しいと思われる。

    結局 x1,x2,y1,y2 は trace 自体が駄目だった。justify の初期化位置よりも後で
    local x1 x2 y1 y2 が宣言されていたのだった。然し、この justify の初期化位置
    は此処でなければならなかったのか。そういう理由があった様な気もするがこれに
    ついてはテストで確認する必要がある様に感じている。contra によるテストを設定
    して確認する必要がある。contra でテストを実行してみた所、特に問題なくテスト
    が通った。なのでこの部分の順序変更については気にしなくて良いだろう。

  * 新しい ble-face, blehook, bleopt で問題が起こっている [#D1571]

    * fixed: blehook で新しい hook を作成できなくなっている。何故だろうか。これ
      は引数解析のバグである。

    * fixed: ble-face --hel でエラーにならずにコマンドを実行することができてい
      る。これは修正した。他にも '-' に対する処理を blehook, bleopt と共に修正
      した。

    * fixed: ble-face --color=xxxx のエラーメッセージ表示時にエラーが発生する。
      直した。blehook, bleopt についても --color=xxxx と指定した時のエラーメッ
      セージを改善した。

    * done: ble-face の使い方を wiki にまとめる
    * done: --help に color の説明を含める。

  * bash-3.0 の初期化時に bleopt が出力されてしまっている [#D1570]

    % bash-3.1 では特に問題は起こっていない。という事はまた何かの bash bug に嵌っ
    % ているのか或いは場合分けのコードで bash-3.0 専用の部分に問題があるのか。
    %
    % --norc で source すると問題は起こらない。後で source ~/.blerc すると再現
    % する。同じセッションで再度呼び出せば再度発生する。これも解析のバグである
    % 様な気がする。不思議な事に一回目と二回目で起こる bleopt の位置が異なる。
    % 或いは、起こる回数が変わっているという事か。
    %
    % どうやら bleopt a:=1 という形で呼び出すと read-arguments の結果が空になる
    % 様だ。調べるとスカラーに対して ${var[@]/%/=value} 等とすると失敗する様だ。

    これはまた bash-3.0 のバグである。うーん。調べた限りだと、
    ${scalar[@]/xxxx} の形式は全て空になる。

    $ grc '\$\{[a-zA-Z_0-9]+\[[*@]\]/'

    で検索してみるとそんなに沢山は存在しない。取り敢えず全て確認 or 対策をする
    必要がある。また、m scan に含めるべきである。

    * 確認した所、既存のコードは全て配列に対して異実行していたので問題ない
    * m scan にも含めた。

    x local i "${vars[@]}" に変更漏れがあった。これも後で修正する。

    * 後これは遡って適用するべき項目である。なので独立した項目にする事にする。

  * util: gdict 再考 [#D1569]

    gdict について質問された。説明しようとして思ったのだが、現在の gdict の実装
    は ble.sh の中で直接 global dictionary を作る時を想定していて、module の中
    から global dict を作る場合は想定していないのだった。bash-4.0 で関数内から
    source した時には問題が生じる事になる。

    gdict はもっと一般に使う事ができる様にしたい。つまり、必ずしも直接 source
    した所から使うのではなくて、一般のスクリプトから使える様にしたいのである。
    そう思うと gdict は bash-4.2 以上でのみ使う事にして、それとは別に ble.sh 内
    部から使う為の gdict を定義するべきなのではないか。

    うーん。でもグローバルに何かを定義するのは常にグローバルであるという想定は
    妥当な仮定だという気もする。という事を考えると gdict は現在の実装でも良い気
    がする…と考えたが、もしグローバルな文脈でちゃんと定義できるのであればわざ
    わざ gdict を使わなくても dict を使えば良いのだという事になる。

    * 此処で改めて gdict の存在意義について考えてみると、"関数内で source され
      た場合にもグローバルに辞書を宣言したい" という事にある。

      a 一つの方法は何処から source された時にも使える様に 4.2 以上でのみ本当の
        辞書にしてそれ以外では配列実装に切り替えるという方法。

      b 然し、何処かに辞書ごとの実装の種別を記録しておいて、その種類に応じて辞
        書実装を切り替えるというのも一つの手である。然し、そうすると複数の変数
        に記録する事になってしまうので何だか変な感じがする。

        現在の辞書の実装ではキーを x$key にしているので、他の要素は特殊用途の為
        に使う事ができる。つまり、要素 0 に種別を格納しておくという事も可能であ
        る気がする。然し、配列実装の側では要素 0 はちゃんと意味のある要素として
        使っているので其処を変えるのは変な気がする。

        或いは、毎回 is-array を呼び出すという手もあるのかもしれないと考えたが、
        問題の bash-4.0, 4.1 では is-array の判定に assign を使っているので、辞
        書のアクセスの度にファイルの読み書きが発生する事になって気分が悪い。

      c 或いは、bash-4.0, 4.1 の時にだけ実装種別の判定を行う様にすれば良いので
        ある。

        またこの方法の場合には宣言時に [[ $FUNCNAME ]] 等を確認して宣言を切り替
        える必要がある。

        % if [[ $FUNCNAME ]]; then declare -gA X;
        %
        % x もう一つこの方法の弱点。この方法では FUNCNAME が期待通りに動く事を想
        %   定している。然し、ユーザーが unset FUNCNAME をしてしまっていると
        %   FUNCNAME は常に存在しない事になってしまい、誤判定してしまう。実は
        %   FUNCNAME がちゃんと動作しているかどうか確認する為には一回関数を呼び出
        %   して要素数が変化するか見れば良い。
        %
        %   % 類似の変数として FUNCNAME, BASH_LINENO, BASH_SOURCE が存在する。で
        %   % は、これらの変数が全て使用不能になっていたらどうすれば良いのだろう
        %   % か。(改めて確認した所、BASH_LINENO 及び BASH_SOURCE は関数呼び出し
        %   % でなくても常に存在している様である。そして source の場合にも要素の
        %   % 数が変化する。という事を考えると関数内かどうかの判定には使えない気
        %   % がする)
        %
        %   b BASH_LINENO/BASH_SOURCE を使って判定する事は可能だろうか。実際に呼
        %     び出してみてどの様に動作するか確認する必要がある。うーん。両者とも
        %     ファイル名と行数しか表示しないので関数かどうかの判定には全く使えな
        %     い。
        %
        %   c その場合には、caller builtin を使う事ができるだろうか。と思ったがこ
        %     れも駄目の気がする。これは関数であるかどうかに拘らず実行することの
        %     できる関数なので、結局関数内にいるかどうかを判定するのには使えない。
        %
        %     caller の出力を確認すれば一応 "関数名" or "source" を確認する事がで
        %     きる。此処で、"source" 以外の関数名があった時には関数内にいるという
        %     事は確定する。逆に全て "source" だった時にはどうだろうか。取り敢え
        %     ず自分がトップレベルから source されている場合には caller 0 が失敗
        %     する。この場合には "関数内にはいない" という事が確定する。
        %
        %   d reject: 或いは実際にその context で変数を定義してみたら良いのではな
        %     いだろうか。と思ったが、それも駄目である。関数内でもし呼び出されて
        %     いるのだとしたら、結局その関数の文脈にローカル変数が作られるので、
        %     確認する立場からすれば何れにせよ変数が見える事になる。問題は現在の
        %     文脈 (外側の関数) を抜けた時に自分の手元で定義した変数がちゃんと残
        %     存するかどうかという事なのである。
        %
        %   e declare xxxx としてから local で変数が存在するかどうか確認したら分
        %     かるのではないか。
        %
        %   f よく考えたら local が成功するか失敗するかで確実に判定可能なのではな
        %     いか。これだ。これで判定する事ができる…。local が別の理由で失敗
        %     する可能性としてその変数名が特殊変数であったり読み取り専用だった
        %     り型が変換不能だったりという事が考えられるが、_ble_... に選んで置
        %     けば特に問題はない。
        %
        % [source スクリプト内で関数内にいるかどうかの判定方法]
        %
        % 先ず初めに FUNCNAME が特殊な意味を保持しているかどうかを確認する。これ
        % は実際に関数を呼び出してその中で FUNCNAME の要素数が増えているという事
        % を確認すれば良い。もし特殊な意味を保持している場合には、FUNCNAME が定義
        % されていれば関数内にいるし、或いは FUNCNAME が定義されていなければ関数
        % 内ではない。
        %
        % 次に caller の出力を確認する。caller 0 が失敗すれば即ちトップレベルから
        % 直接 source された事を意味しているので、確実に関数外に存在する。caller
        % 0,1,2 を失敗するまで逐次呼び出して行って、途中で source 以外の関数名に
        % 出会ったら関数内部にいる事が確定する。

        local _ble_local_test とでもしておけば関数内部にいるかどうかの判定は可
        能である。というか、現在 FUNCNAME を使って実行しているテストもこれに切
        り替えるべきなのではないか。

        bash-4.2 以上の場合、常に -gA を使う。
        bash-3.2 以下の場合、常に配列を使う。
        bash-4.0, 4.1 の場合は条件分岐する。

        if local _ble_local_test 2>/dev/null; then
          NAME=() NAME_keylist=
        else
          declare -A NAME; NAME=()
        fi

        その様に書き換えた。

      * done: 既存の連想配列に依拠しているコードも、実際に配列が連想配列かどう
        かで判定するべきの気がする。

        現在は _ble_bash_loaded_in_function で判定を行っている。というか面倒な
        ので一部の物に関しては完全に gdict を使った実装に切り替える事にした。3
        つ書き換える事になった。

        - _ble_decode_kbd__k2c
        - _ble_builtin_history_rskip_dict
        - _ble_builtin_trap_n2i

        _ble_bash_loaded_in_function を使っていても gdict による宣言を使ってい
        ない物に関してはそのままにする事にした。

        残っている物は以下の物である。うーんこれらも書き換えてしまうべきだろう
        か。そちらの方が正直な所メンテナンスしやすい。問題は書き換えでバグが入
        らないかという事と、速度的に遅くならないかという事である。特に、現在の
        主なターゲットは bash-4.4 以降であると考えると、古い実装に対して配慮し
        なくても良い様に思われる。

        - ./lib/core-complete.sh:6102:if ble/is-assoc _ble_complete_sabbrev; then
        - ./lib/core-syntax.sh:6290:if ble/is-assoc _ble_syntax_highlight_filetype; then
        - ./lib/core-syntax.sh:6403:if ble/is-assoc _ble_syntax_highlight_lscolors_ext; then

        取り敢えず使われている箇所で速度が気になるかどうかを確認する。結局全部
        新しい実装に置き換える事にした。bash-4.2 以上であれば単に関数呼び出しコ
        ストと、要素が実際に存在しているかどうかの判定コストが増えるだけである。
        結局 s2c のテーブル以外については全て完全に gdict を使う事にした。

      * done: sabbrev の書き換えの際に ble/gdict#keys を使った。
        実装する必要がある。実装した。

    * done: 現在の辞書の中身を表示する為の関数、key の列を取得する為の関数もあっ
      た方が良いのではないかという気がする。

      ble/gdict#keys については既に上で実装した。
      ble/gdict#print については既存の関数を使って実装する事にした。

    * 後、bash-4.0, 4.1 で既に連想配列として宣言されている場合にはそれを流用す
      るべきなのではないだろうか→その様に書き換えた。OK 簡単に確認も済ませた。

2021-05-25

  * util: 設定インターフェイスの細かい修正 [#D1568]
    * ble-face 導入
      * done: ble-color-setface の出力で ref: を認識する
      * done: ble-color-setface で @ の形式に対応する?
      * done: ble-face -r で元に戻せる様にしないと themes の切り替えに困る
      * done: ble-face -u で変更された face を表示する。
    * done: bleopt xxx@xxx=xxxx で一括設定ができる様にする
    * done: bleopt 既定値からずれている物だけ出力する機能
    * done: bleopt 既定値に戻す機能
    * done: blehook internal hook は既定では表示しない機能

2021-05-24

  * global: gA をその場で代入しなければ 4.2 でも大丈夫 [#D1567]

    共通なコードも多くあったので整理して纏める事にした。大分すっきりした。

2021-05-23

  * contrib/git-prompt.sh の変数達は localvar_inherit で駄目なのではないか [#D1566]
    というか他にも同様の変数宣言の仕方をしている箇所は色々ある気がする。
    →検索して修正した。

  * keymap/vi: vim モード表示に関して (reported by huresche) [#D1565]
    https://github.com/akinomyoga/ble.sh/issues/114

    また vim のモード表示に関連する提案・質問が来ている。何処かに纏めておくべき
    であろうと思われる。取り敢えず後で vim mode の wiki ページに少なくとも説明
    かまたは説明へのリンクを載せておく必要がある。

    * done: 取り敢えず keymap_vi_mode_name_xxxx を変更したら mode name の更新を
      予約する様にしなければならない。と思ったが何処で呼び出す様にしたら良いの
      だろうか。現在の実装を確認するとモード変更時に update-mode-name を呼び出
      している。そしてこの関数は即座に表示を行っている。然し、他の関数から mode
      name の設定を変更する場合には、その場で info を表示してしまうと変な事にな
      る。

      a info pane を表示していない時は内部的に変更するに留める? 内部的に入れ替
        えるだけという機能を info に実装する必要がある。また、これだと一連の設
        定を変更した時に各項目ごとに info を表示し直すという事になって効率が悪
        い。

      b やはり更新は遅延させるのが望ましい。然し、遅延させるとしてもどのタイミ
        ングで更新を行うのだろうか。やはり info reveal の瞬間に内容を更新するの
        が良いのではないかという気がする。

      新しく info_reveal hook を追加して b の方針で実装する事にした。

    * vim-airline の API を調べてそれをできるだけ再現するようにするという可能性
      も考えられる。但し、厳密に再現できる訳でもないと思われるが。vim-airline
      の README にはそんなに customization の情報は書かれていない。

      * 単に各フィールドの内容が指定できるというだけの事である。

      * それから、truncation は ble.sh では実装されれていない機能である。うーん。
        これの対応は面倒だ。現在の実装だと trace の中で各フィールドについて計測
        を行って、その上で出力を行っている。なので、truncation も原理的には実装
        可能であるが、(1) 各フィールドの優先順位はどうやって指定するのか (2)
        separator 毎の最大・最小幅をいよいよ実装する必要が出てくる (3) 自動改行
        を抑制する など色々修正が必要である。特にどういう仕様にするのかというの
        が一番面倒である。自然なインターフェイスで separator 毎の最大・最小幅を
        指定できる物だろうか。

      よし。vim-airline を真面目に実装する事にする。

      ? 各セクションが空の時にセクションを潰したい。然し、一方で各セクションの
        内容はプロンプトシーケンスとして実装したい。これの両立は可能だろうか。
        うーん。何だか難しそうな気がする。実際に実体化するまでは各セクションが
        潰れるかどうかは判断できない。という事は先に各セクションを実体化するし
        かない。

        * 二重に処理する事になるがそうすると端末固有の SGR を二重に処理する事に
          なるのでは。うーん。一旦 ANSI 形式で出力するオプションを実装する必要
          がある気がする。

      * done: auto-truncation の実装

      * done: gitstatus に関しては後で vim-airline を実際に入れて動作を確認する
        必要がある。どうも vim-airline は tpope/vim-fugitive を使っている様であ
        る。また、dirty 状態かどうかは出力されない様である。取り敢えずよしとす
        る事にする。

        と思ったが改めて確認したらちゃんと出力されていた。機能を追加した。

      * done: ble/color/g2sgr-ansi を実装する
      * done: trace ansi の実装

      x fixed: prompt_status_line の再描画の時に前回の内容がクリアされない (g=0
        の時)

        うーん。不思議なのは直接 printf するとちゃんとクリアされるのに、
        ble/util/buffer 経由で出力しようとするとクリアされないという事。何故だ
        ろう。内容が消滅している可能性? 或いは、DRAW_BUFF か何処かに出力内容が
        残っている可能性もあるのかもしれない。

        調べてみると ble/util/buffer の中に excursion しているコードが入ってい
        る。うーん。どういう事だろうか。誰が ble/util/buffer に内容を入れている
        のだろうか…。不思議である。と思ったら enter-command-layout で info や
        status を消していて、その為に excursion 状態になっているという事の様だ。

        うーん。そもそも WINCH が起こるとこれまでの panel height も全て消えてな
        くなる訳だから、panel height に対する差分修正では駄目の筈である。高さを
        全て確保し直さなければならない。という事を考えると… height を全て空に
        すれば良いのだろうか。或いは。

        | →これは結局様々な問題が複合した結果だった。高さの完全再配置が実装され
        | ていないのが主な問題。そして LINES COLUMNS が反映される迄にどうやら時間
        | がかかる様だというのがもう一つの問題。後者については仕方がないので待ち
        | 時間を入れる事にした。
        |
        | と思ったがこの後者の問題はウィンドウサイズを変更する時に contra がリア
        | ルタイムに大量の WINCH を発生させるのが原因の様である。bash trap はシグ
        | ナルの回数を覚えていないので単に一回だけ発生している様に見えただけだっ
        | た。contra の実装が悪いとも言えるが、然し滑らかにサイズ変更をする端末で
        | は普通に起こって良い事なのでこれに対する対策を入れるのは良い事である。

        問題は最後の WINCH を捕まえる事ができないという事である。trap handler
        を実行している間は実行がブロックされている。WINCH の処理の最後で再度
        LINES COLUMNS が変化していないか確認すれば良いのではないか。
        →その様に変更したら可也振る舞いが改善した。

      x fixed: SIGWINCH で乱れる問題。実は tput で端末の大きさを取得すれば良い
        のでは。というか (:) 等を実行しても checkwinsize で更新されるのではない
        か。と思ったが tput で取得しても LINES COLUMNS で取得してもずれがある様
        である。

      x fixed: prompt_status_line が WINCH で再描画されていない?
        none になっている時に塗りつぶしを省略しているのが原因である。
        huresche にも改めて指摘されたのだった。

      x fixed: menu-complete が動かなくなっている。trace に手を入れたのが原因だ
        ろうか。

        あー。多分、合成がうまく行かなくなっている。改めて実装を確認する。と思っ
        たら動く様になっている。これも WINCH をした後に生じる問題だろうか。うー
        ん。その様だ。WINCH によって何故動かなくなるのが…謎である。

        menu#render-item はちゃんと呼び出されている。ちゃんと出力も構築されてい
        る気がする。出力までもちゃんと行っている気がする。ああ。分かったかもし
        れない。これは info が invalidate された儘になっているという事なのだろ
        う。直した。

      * done: https://itchyny.hatenablog.com/entry/20130820/1376978742
        此処で紹介されている landscape という配色がなかなか良いのではないか。
        と思って確認してみたがコードはなかなか面倒な事をしている。
        後でどういう結果になるのか調べてみる事にする。

        設定を抜き出しては見たが実際にやってみると白背景だと微妙な感じだ。

      * done: theme の設計を考えると eval-after-load ができる様にするべきでは。
        うーん。現在の実装だと eval-after-load は def.sh に登録している。然し、
        そうではなくて ble-import の枠組みの側で提供するべきなのではないだろう
        か。

        これは大きな変更になりそうな気がするので後回しにする。
        →結局そんなに大きな変更ではなかった。簡単だった。

2021-05-22

  * main: set -e の時にロードできない [#D1564]

    またロードできなくなっている。これは本当は定期的にテストしなければならない
    事の気がする。

    * adjust-builtins で失敗している。alias 定義を読み取る時の alias ... と、
      alias を削除する時の unalias に於いて存在しない alias を取り扱おうとする
      と exit status が 1 になって駄目の様である。

    * prompt attach の際にも問題が生じていた。二箇所条件の書き方を変更した。

      * blehook でも失敗している。中に於ける if builtin eval ... ; then ... が
        駄目の様だ。試してみると

        false || true # OK
        eval false || true # OK
        builtine eval false || true # 駄目

        という具合の動作になっている。bash-4.4, dev で確認した。3.0, 3.2 でも同
        様の振る舞いである。これは後でバグ報告に持っていく事にする。

        問題の箇所は eval を使わない形式に書き換える事にした。

    これでまたロードできる様になった。本当は blehook, ble-bind その他のインター
    フェイスについても set -e に対する対策をするべきの気もするが取り敢えず何も
    設定しない限りに於いては動くので良しとする事にする。そもそも set -e で対話
    シェルを使おうとする事自体があり得ない想定なので余り深く考えなくて良い。

  * 2021-05-16 complete: tar xf groff-1.19.2.ta[TAB] でエラーが発生する [#D1563]

    と思ったらこれは bash-completion だった。また確認してみたところ、これは5週
    間前に既に修正されていた様だ。

2021-05-20

  * 2021-05-13 tmux-resurrect により vi_imap が empty になる問題 (reported by RakibFiha) [#D1562]
    https://github.com/akinomyoga/ble.sh/issues/109

    "ble.sh: The keymap 'vi_imap' is empty." というエラーメッセージが出るとの事
    だが他には何もメッセージは出ないのだろうか。試しに keymap.vi を空にしてロー
    ドしてみると…再現した。

    * bash ble.sh --clear-cache オプションを実装した方が良い。

    * ファイルが存在するかどうかのチェックをしている箇所は、全て有限の大きさを持っているかどうかを確認した方が良い。

    * 空の keymap になっていたらキャッシュ無しで初期化し直す機能を付けた方が良いかもしれない。

    うーん。何と再現しなくなってしまった様である。
    こうなるとコードを見て憶測で修正するしかなくなる。

    # {
    #   ble/decode/keymap#load isearch dump
    #   ble/decode/keymap#load nsearch dump
    #   ble/decode/keymap#load vi_imap dump
    #   ble/decode/keymap#load vi_nmap dump
    #   ble/decode/keymap#load vi_omap dump
    #   ble/decode/keymap#load vi_xmap dump
    #   ble/decode/keymap#load vi_cmap dump
    # } 3>| "$fname_keymap_cache"

    あー。もしかすると原因が分かったかもしれない。そもそも前に自分が問題を経験
    した時にもそうだったが、ble/decode/keymap#load を改名した事が原因なのであっ
    た。此処で、ble.sh が部分的に更新されていたりすると問題になるという事なのだ
    ろうという気がする。tmux-resurrect が一体何をしようとしているのかは結局謎な
    のであるが、うーん。

    そもそも報告者が最新の物でも再現するとかしないとか言っていた時に、毎回 make
    をしていたのかというのも疑問の一つである。と思ったが rebuilding と言ってい
    るので、其処の所はちゃんとやっているのだろうという気がする。

    a あー。もしかすると複数の異なる ble.sh を使っていて cache が混合していると
      いうのは十分考えられる可能性である。と思ったが本当にそれで問題が発生する
      だろうか。何れにしても呼び出す vi.sh は同じディレクトリにいる ble.sh から
      呼び出される筈で中途半端に更新されていない限りは不整合は起こらない筈なの
      である。

      或いは tmux-resurrect が下手に関数等を保存しているのだとすると変な事が起
      こっても仕方ない → 試しに関数を定義して保存・復元して見たが関数は消滅し
      ていた。つまり、そういう事は関係ない。

      或いは vi.sh の timestamp が偶然未来に設定されてしまったりする様な場合に
      も問題が起こったりするかもしれない。

      うーん。やはり timestamp が壊れない限りはこれによって変な事が起こったりす
      る可能性は低い気がする。

    b 後タイムスタンプが nfs などによってずれていたりするとそういう事があったり
      するかもしれない。timestamp が信用できない時にはどうしようもない。これは
      個々の使用者の側で注意して時刻を合わせてもらうしかない。

    * done: 失敗したとしても端末の状態が壊れない様にする。

    ? コードを見てみると初期化に失敗した時には完全に空 map になってロードされな
      いのではなくて safe keymap に fallback する筈なのだが何故そうなっていない
      のだろうか。

      これは再現できるので修正はそんなに難しいことはない筈。

    2021-05-20 もう返事もないし再現もできないし、向こうでも何だか解決した様な雰
    囲気を出しているので取り敢えず対症療法を push する事にする。

    * 他にも似たような現象が起こる可能性があるのでキャッシュファイルについて全
      て -s を用いてチェックする事にする。
    * この際なので _ble_base_cache 内の構造・ファイル名についても整理する事にし
      た。

  * syntax: ${a~} に対応していない [#D1561]

    何れ消えると思っていたがどうも未だ消える気配はない様だ。取り敢えず使える環
    境ではちゃんと着色した方が良い様に思われる。

    後気付いたのだが実は ${a^^} や ${a,,} も bash-4.0 から使えた様だ。tolower,
    toupper の実装に使えるのでは。と思って確認した所、既に 4.0 以上ではこれらを
    使う様になっていた。

    軽微な修正だがこれだけ放置していても仕方がないのでもう push する。

  * prompt: update "PS0" between multiple commands (motivated by tycho-kirchner) [#D1560]

    複数のコマンドが一度に実行される時に、それぞれのコマンドについて PS0 が呼び
    出される。然し其処から参照される $# の値が更新されない様だった。調べてみる
    と、PS0 の更新をチェックする時に、更新の必要があるかどうかの判定をする hash
    値が複数のコマンドの間で変化がない為に更新が省略されていたという事。
    →hash に $# ($_ble_edit_CMD) も含める様にして対処する事にする。

  * decode (ble-bind): ble-bind -m KEYMAP で全ての keymap が出力されている (fixup 750ca38) [#D1559]

    これは指定した keymap を表示する様にした方が良い。というか元々そのつもりだっ
    た筈で単に対応を忘れていたという事の気がする。

  * main: bash ble.sh --test の終了ステータス (fixup bbc2a90) [#D1558]

    subshell からのロードを検出する様にした変更に於いて終了ステータスが意図しな
    い物になっていた。これは return $? || exit $? に於いて二個目の exit が
    return の $? を拾う様になってしまった為。

    a 面倒なので、_ble_init_exit は削除しない様に変更して見た。

    b しかし別の修正方法として eval を使う物を思いついた。うーん。eval を使う事にする。

    棄却した a の修正は此処に供養する。
    | diff --git a/ble.pp b/ble.pp
    | index c9a11d8..d172c7d 100644
    | --- a/ble.pp
    | +++ b/ble.pp
    | @@ -1398,9 +1398,9 @@ function ble/base/initialize/.clean-up {
    |    # 一時グローバル変数消去
    |    builtin unset -v _ble_init_version
    |    builtin unset -v _ble_init_arg
    | -  builtin unset -v _ble_init_exit
    |    builtin unset -v _ble_init_command
    |    builtin unset -v _ble_init_attached
    | +  #builtin unset -v _ble_init_exit
    |
    |    # 状態復元
    |    if [[ $_ble_init_original_IFS_set ]]; then
    | @@ -1444,18 +1444,17 @@ ble-import -f lib/_package
    |  if [[ $_ble_init_command ]]; then
    |    ble/base/sub:"$_ble_init_command"; _ble_init_exit=$?
    |    [[ $_ble_init_attached ]] && ble-attach
    | -  ble/util/setexit "$_ble_init_exit"
    |  else
    |    ble/base/process-blesh-arguments "$@"
    | +  _ble_init_exit=$?
    |  fi
    |
    |  #%if measure_load_time
    |  ble/debug/measure-set-timeformat Total nofork; }
    |  _ble_init_exit=$?
    |  echo "ble.sh: $EPOCHREALTIME load end" >&2
    | -ble/util/setexit "$_ble_init_exit"
    |  #%end
    |
    |  ble/base/initialize/.clean-up 2>/dev/null # set -x 対策 #D0930
    | -{ return $? || exit $?; } 2>/dev/null # set -x 対策 #D0930
    | +{ return "$_ble_init_exit" || exit "$_ble_init_exit"; } 2>/dev/null # set -x 対策 #D0930
    |  ###############################################################################

  * global: v0.3-master へのパッチ適用の際に気付いた細かい修正 [#D1557]
    細かい修正が溜まって来たので此処で一つずつ修正を適用してしまう事にする

    * Makefile で run ではなくて tmp を作っていた。ディレクトリ名を変更した時
      に一緒に変更するのを忘れていた。
    * ble/function#suppress-stderr に不要なごみ引数 { を渡していた。
    * C-w M-w の振る舞いを変更したが、blerc に以前の設定に戻す設定例を入れた。

    * IFS の異なる環境に対する対策としてできるだけ _ble_term_IFS を local IFS
      にコピーする様に変更していたが、この際なので直接 $' \t\n' と記述してい
      る部分をできるだけ全て $_ble_term_IFS に置き換える事にした。
    * src/benchmark.sh は独立したファイルとしても使える様にしてきたつもりだっ
      たが、ble/util/print, ble/util/print-lines を使う様になっていたので、こ
      れらの関数が定義されていない時には定義する様に修正した

2021-05-19

  * README: 様々な機能へのリンクを貼った方が良いのではないかという事 [#D1556]

  * 現在の初期化だと ble.sh session で source --test 等すると [#D1555]

    変な事になるのではないか。これは取り敢えず独立した項目として取り扱う事にする。

  * main: subshell 内部で source/reload したら何が起こるのか [#D1554]

    source した場合には何も起こらない。うーん。これは単に attach 戦略が prompt
    だから attach する前に終了しているという事の気がする。

    reload については reload が実際に実行されて色々と _ble_base_run のデータが
    破棄される。この状態で ble-detach を実行すると制御できなくなる。tty 状態は
    別に問題はない様だ。

  * main: AUR blesh-git について [#D1553]

    * ok: requirements: ble-update の為に git, gawk があった方が良いのかもしれ
      ない? 然し、最終的に AUR helper を呼び出すのであれば余り関係ないのかもし
      れない。特に package としては fallback になる事は想定していないので。

    * ok: (("$helper_prog" != 0))
      https://aur.archlinux.org/cgit/aur.git/tree/blesh-update.sh?h=blesh-git#n29

      (()) の中の quote のルールは変更されている。然し何故か PKGBUILD はそのま
      ま何事もなく動作しているどういう事だろうか。shopt が調整されているのだろ
      うか。或いは bash の version が違うのだろうか。適当な PKGBUILD を作ってそ
      の辺りを出力させたらはっきりするのかもしれない。何れにしても将来的に変更
      されるかもしれないという事などを考えると修正した方が良い。

      と思ったが改めて試してみたが問題はない様だ。単に手許で試す時に
      (("$xxx"!=0)) が ((!=0)) に展開されてエラーになっていただけなのであった。
      bash-5.1 で振る舞いが変更されたのは '' による quote の方であった。

    * local variables
      local PRE_VERSION
      local POST_VERSION

      恐らく他の所で使うという訳ではないだろう。というか、この関数は PKGBUILD
      で使われるのではなくて ble.sh から呼び出しているのであるから他の場所から
      使っているという事はない気がする。

    * _package.sh は実の所 source するだけなので実行属性は必要ない。唯、source
      path を経由して source したい時には実行属性がついている必要があるのだった
      か? man bash を確認したがちゃんと実行可能である必要はないとの事が明記され
      ている。

      というか今知ったがカレントディレクトリよりも PATH の方が優先されるのだそ
      うだ。だとすると結構変な事が起こるの可能性もあったのでは。今試しに ~/bin
      に ble.sh を登録して、bash --norc から ble.sh ディレクトリの外で source
      ble.sh を実行したらちゃんとロードされた。うーん。

    * done: contributing に lib/_package.sh を追加する

    取り敢えず残っている物については簡単に纏めてこの項目はOKとする。

2021-05-17

  * util: inherit special file descriptors [#D1552]

    #D1549 で setsid をしたら /dev/tty が見つからなくなって動かなくなった。
    /dev/tty が壊れてしまうという事態に対応する為に最初に確保した
    _ble_edit_io_std{out,err} を他の場所でも積極的に使う様にするのはどうか。

    * 更に考えると毎回 bash を起動する度に新しく fd を確保するのは無駄である。
      なのであれば、export して共有してしまえば良いのではないかという気がする。

    * また、ふと思ったのだが毎回 /dev/null を開いているのはどうなのだろうか。
      dup の方が軽かったりしないのだろうか。然し、/dev/null を dup できるのかと
      いうのも疑問である。然し、fork した途端に使えなくなるというのも変なので
      /dev/null は dup しても大丈夫なのだという気がする。

        $ ble-measure 'echo hello >/dev/null'
        7.439 usec/eval: echo hello >/dev/null (x10000)
        $ exec {fd}>&14; echo $fd
        14
        $ ble-measure 'echo hello >&14'
        5.035 usec/eval: echo hello >&14 (x20000)
        $ ble-measure 'echo hello >&$_ble_base_fd_null'
        5.821 usec/eval: echo hello >&$_ble_base_fd_null (x20000)

      やはり dup の方が高速である。然し、そもそもの処理時間が短いので気にしても
      仕方がないレベルではある。Cygwin でも同様の結果になるだろうか。

        $ exec {fd}>/dev/null
        $ echo $fd
        16
        $ ble-measure 'echo hello >&16'
        24.920 usec/eval: echo hello >&16 (x5000)
        $ ble-measure 'echo hello >/dev/null'
        41.100 usec/eval: echo hello >/dev/null (x2000)
        $ ble-measure 'echo hello >&$_ble_base_fd_null'
        28.320 usec/eval: echo hello >&$_ble_base_fd_null (x5000)

    →Cygwin でも dup の方が高速である。変数に入れると少し遅くなる。然し本当に
    置き換えてしまっても問題が生じないのかというと分からない。例えば
    _ble_base_fd_null がユーザーによって削除または書き換えられてしまったら何が
    起こるだろうか。大量のエラーメッセージが出て色々と悲惨な事になる気がする。
    後、/dev/null への redirect は可也基本的な事なので、もし置き換えるのだとし
    たら何よりも先立って初期化したい気がする。実装を確認すると ble/fd は
    ble/array を使用している。

    * 取り敢えず fd#alloc のコードや stdin/stdout/stderr のコピーのコードを整理
      して、

      (1) stdin/stdout/stderr は常にコピーを保持する様に変更する。

      (2) bash-4.1 以上では {fd}> ... を使う様にしていたがこれだと
      10,11,12,... という番号を使ってしまい、間違って上書きした時に大変な事にな
      るかもしれないので、昔の様に 30,31,32,... を使う様に戻す。但し以前はなかっ
      た上書き確認を行う。此処で問題になるかもしれないのは、他のフレームワーク
      が上書き確認をせずに 30,31,32,... を使おうとした時の事であるが、それは仕
      方がない。比較として考えれば 10,11,12,... よりは安全として差し支えないだ
      ろう。

      (3) openat_base 等のオプションは ble.sh ロード時のオプションから指定でき
      る様にする。

    * done: wiki で openat_base の項目を編集する

  * macOS で groff のエラーが出る (reported by killermoehre) [#D1551]
    https://github.com/akinomyoga/ble.sh/issues/112

    groff -k というオプションが使えないという事。macOS の groff は v1.19 らしく
    これは 2004 の version である。実に17年前の groff である。このオプションは
    UTF-8 の man を処理する為に追加した物。実質的に preconv | groff と同じらし
    い。しかし、そもそも macOS には preconv がないそうだ。というか。そもそも
    groff 1.19 は Unicode に対応しているのだろうか。

    取り敢えず groff をインストールして確かめてみる。うーん。全然駄目。そもそも
    utf8 device が存在していない様である。何か別の物をインストールすれば良いと
    いう訳でもなさそう。device として ascii, latin1, cpxxxx しかない。ascii に
    するしかない。man は LANG=C で探す。

    然し英語の man を探したとしても本当に groff -man が使えるのかも怪しい。と思っ
    たが検索してみると一応 -man には対応している様な気がする。と思ったが -man
    ではなくて -m man としなければならない?
    https://www.unix.com/man-page/osx/5/groff_tmac/

    どうも試してみたら最新版でも -m man で動作している気がする。 -man と -m man
    は synonym という事だろうか。取り敢えず groff -T ascii -m man <<< X | uniq
    が動くかどうかを確認する。

    と思ったが返信がない。取り敢えずこれで良いのかどうか分からないが #D1550 と
    一緒に変更を加えてみる事にする。それでも治らなかったら使う事にする。何か変
    更し残している事はあるだろうか?

    2021-05-17 と思ったら返事が来た。どうも macOS の groff で -T utf8 も一応は
    使える様子である。うーん。という事は \[uXXXX] も取り扱えるのだろうか。

    * もし \[uXXXX] が取り扱えるのであれば適当に \[uXXXX] に全て置換してしまえ
      ば良い。。。と思ったがどうやってやるのか微妙である。awk で変換しようにも
      awk では文字コードを取り出せないので uXXXX の形式に変換するのにも苦労する。
      うーん。od を使って binary に変換してそれから nawk で色々処理して、それか
      らまた od で元に戻すという様な面倒な処理を実装しなければならない。

      % と思ったが binary に戻す方法は不明である。うーん。調べると bash の
      % printf \x??  経由で出力するという事になっている? awk の printf は NUL
      % が出力できないとしている。他の文字は大丈夫だろうか。というより何故 NUL
      % が出力できないのだろうか。

      awk の printf を使うとしたらテストが必要? と思ったが macOS で動けば良いの
      だから BSD awk で動けば十分である→今試した限りだと nawk, mawk, gawk で何
      れもちゃんとできる。NULもちゃんと出力できるのでOK。

    * もしそのまま通過してくれるのであれば特に気にする事はない。が恐らくそうい
      う事はないのだろうという気がする。

    * 或いは結局全然駄目の可能性もある。うーん。どうなんだろうか。

    返事があった。\[uXXXX] で行ける様である。取り敢えず .preconv を実装した。手
    許で試してみる限りは動いている気がする。まあ、実際に動かして変な事が起こっ
    たらその時にまた考え直せば良い。取り敢えず遠隔で実装できるのは此処までであ
    る。

  * complete: ssh -option の後の補完が固まる (reported by rlanore, riblo) [#D1550]
    https://github.com/akinomyoga/ble.sh/issues/98

    $ alias ssh='TERM=xterm ssh'

    で再現するとの情報を得た。他に man -w が現れたり消えたりするという情報も。
    つまり、一つの man -w が 100% になっているのではなくて man -w が繰り返しルー
    プで呼び出されている? また、cache dir に大量のファイルができているという話
    も。つまり、ble/util/assign で無限ループを起こしている可能性がある。

    $ complete -r
    $ source ~/.fzf.bash
    $ TERM=xterm ssh -w[TAB]

    TERM=xterm ssh -bash: 一致しません: /home/murase/.ssh/config.d/*

    ble/complete/source:argument/.generate-from-mandb を見ると alias で展開され
    る限りは無限ループする可能性のあるコードがある。但し、重複判定はしている筈
    なので alias が有限である限りは無限ループにはならない気がするが…。うーん。
    分からない。或いは alias 展開で空文字列になった時に問題が生じる可能性?

    OK! 再現できた!

    - 自分の手元で再現できなかったのはどうも何か別の設定が勝手に
      bash-completion を読み込んでしまうからだった様である。一体何の設定が勝手
      に読み取るのかは謎だが、complete -r を実行しても何故か設定が読み込まれて
      しまう。と思ったが… ble.sh が __load_completion が存在している時には勝手
      にそれを呼び出す様にしていたのだった。そういう設計も考え物といえば考えも
      のである。但し、これも unset -f __load_completion すれば解除する事ができ
      る筈なのである。

    * fixed: 分かった。 ble/complete/source:argument/.contains-literal-option が
      variable leak して ret を書き換えしてしまっている。直した。

    * done: 更に alias で TERM=... としていても対応できる様に読み飛ばし機能も追
      加した。

    x fixed: 然し ssh のオプションを抽出するのに失敗している。何故だろうか。改
      めて振る舞いについて調べる事にする。ble/util/assign を ble/assign と書い
      ていた。修正した。

    x fixed: 未だ駄目。と思ったら man を探索する部分で $command とするべき所が
      $man になっている。

    x fixed: それでも駄目。調べると ssh の man を gzcat する所まではできている。
      其処から関係のありそうな物を抽出する所で失敗している。うーん。man から
      mdoc に変化するという場合もある様だ。どちらでも良い様に色々書き換える。然
      し、それでも nroff の形式がよく分からないので行き当たりばったり的な実装に
      なってしまう。取り敢えず Dd, Nm, Xo-Xc に対応した。また後段で __ble_key__
      と __ble_desc__ が同じ行になってしまった場合でも動く様に修正した。

    x fixed: エラーが出る groff -[TAB] ... これは nawk に日本語のコメントを渡し
      たのが行けなかった。日本語のコメントは除去する様にした。

    x fixed: 空白が沢山表示される。連続する空白は1つに縮約する様にしたい。

2021-05-16

  * work around Kitty bugs (reported by NoahGorny) [#D1549]
    https://github.com/akinomyoga/ble.sh/issues/110

    | bash-it に追加する事について考えると言っているがどの様な形で追加するのだろ
    | うか。コードを直接追加するのだろうか。その場合には色々と微妙。
    |
    | * 先ず ble.sh の codebase は bash-it よりも巨大だ。どかんと入れる事が良い事
    |   なのか分からない。
    |
    | * ble.sh 自体巨大だし UX 自体を大きく書き換える。それ単体として Issue/PR が
    |   頻繁にある。もし単純にスクリプトを追加すると、bash-it に issue が沢山立つ
    |   事になる。それよりは ble.sh の側に Issue が来て欲しい。
    |
    |   * 実は結構好みが別れる様であるという事。autosuggestion を off にしたいと
    |     いう人もいたりするし、syntax-highlighting が遅いという人もいる (これは
    |     完全なる思い込みだと思うが…)。
    |
    |   * 独立した設定ファイルが存在するという事から、ユーザーにちゃんと説明する
    |     必要があるという事。
    |
    | * 自分勝手な事だけれども、bash-it の一部として普通になってしまうと star が
    |   こっちに来なくなる。bash-it の方がメインだと思われるのは嫌である。
    |
    | * bash-it 自体にパッケージマネージ機能などがあればそれを通してインストール
    |   して貰うのが良いという気がする。それがなくても単に git clone etc. を内部
    |   的にして貰うのが良いという気がする。
    |
    | * theme の充実を図りたい。これは渡りに船なのではないか。然し、bash-it にも
    |   theme があるのだという事。
    |
    | * gitstatus.plugin.bash を見ると別に他のプロジェクトをそのまま追加している
    |   という訳ではない様である。存在が確認できた時に追加の設定を行っている様に
    |   見える。

    何だかそういう雰囲気でもなくなったので気にしない事にする。

    未だ Kitty で変な状態になるそうである。例えば setsid 関係で何か変な事が起こっ
    ている可能性? と思ったがもしそうだとするともっと滅茶苦茶な事が起こる様なの
    でこれは多分関係ないのだと思う。

    ble-detach をした後でも問題が再現しているという事を述べている。うーん。試し
    てみたら分かった。これは modifyOtherKeys の解除ができていない。\e[>4;0m が
    効いていないという事なのだろうか。と思ったら、どうもそういう訳でもない。
    printf $'\e[>4;0m' を送ったらちゃんと動く様になる。

    改めて詳しく見てみると…どうも external の既定は 1 の様である。取り敢えず
    workaround を追加する。

2021-05-15

  * package: AUR package (suggested by huresche, help by oc1024) [#D1548]
    https://github.com/akinomyoga/ble.sh/issues/108
    Ref #M0020 PKGUBUILD の書き方

    AUR の PKGBUILD の提案を受けた。PKGBUILD の内容を確認してみる。

    | > arch=('x86_64')
    |
    | arch=('any')
    |
    | > makedepends=('git')
    |
    | makedepends=('git' 'gawk')
    |
    | > pkgver() {
    | >     cd "${srcdir}/${_pkgname}"
    | >     printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
    | > }
    |
    | >     install -Dm644 ./note.txt "${pkgdir}/usr/share/doc/${_pkgname}/note.txt"
    |
    | `note.txt` is just a private note but not a part of the documentation.

    というか既にパッケージにしている人がいる。
    https://aur.archlinux.org/packages/blesh/
    https://aur.archlinux.org/packages/blesh-git/

    PKGBUILD の説明は此処にある
    https://wiki.archlinux.org/title/VCS_package_guidelines
    https://wiki.archlinux.jp/index.php/PKGBUILD
    https://wiki.archlinux.jp/index.php/%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%81%AE%E4%BD%9C%E6%88%90#.E9.96.A2.E6.95.B0_pkgver.28.29

    * fixed: 自分で試しに install を実行してみた所 644 になっていない。うーん。
      644 もしくは 755 になる様に umask 022 とした。

    ble-update を実行すると何が起こるのだろうか。
    取り敢えず複数の方法を組み合わせて対応するのが良い。

    a /usr/* /opt/* etc であって、
      ファイルが存在するけれど書き込み権限がないという時には、
      sudo bash "$_ble_base/ble.sh" --update を実行する。
      sudo の存在チェックも一応する必要がある気がする。

      (a) repository の書き込み権限がない場合と、(b) install 先の書き込み権限が
      ない場合の二つがある。(c) それから repository が見つからなくて、install
      先の書き込み権限がない場合もある。(a) と (c) の場合には全体を sudo で実行
      し直せば良い。但し、(a) の場合には他のユーザーのディレクトリを sudo で更
      新してしまうと変な事になるのでユーザーのチェックは必要である。権限昇格し
      た後に [[ -O file ]] でチェックすれば良いのだろうか。取り敢えずその方針で
      行く。

      この為に ble.sh --update に対応する必要がある。

    そもそも勝手にアップデートして良いのだろうか。複数のユーザーが勝手にアップ
    デートしたらどうなるのだろうか。と思ったが sudo 権限を持っているユーザーが
    勝手に物を実行するのが悪い。sudo を使ってインストールするのだからそれなりに
    他の人に気を遣うべきである。

    b アップデート用のスクリプトを作って sticky bit を付けて無理やりアップデー
      トを実行するという手もある。これは他のユーザーが同時にアップデートしたり
      する危険性が高いし、管理者権限で現在の ble.sh の状態を管理する事が不可能
      になるので駄目。

    c package manager が存在したらそれを使うという手を安易に提案されたが、それ
      だと package manager を使わずにインストールされたのに勝手に package
      manager 経由で再インストールされてしまうという事になりかねない。まあ、
      /usr/share に入っている時点で何らかの package manager を経由しているとい
      う事は明らかなのだから、余り気にしなくて良いのかもしれない。

      と思ったが現在の所は AUR ぐらいしか存在しない。そして AUR ではどの様にアッ
      プデートしたら良いのかよく分からない。単に再インストールすれば良いのだろ
      うか。或いは一旦削除してそれから入れるのだろうか。

    d done: package maintainer の用意したファイルを source するという提案。これ
      も確かに一つの手である。例えば lib/init-package.sh を使う。

      * 名称について: もしくはlib/init-PACKAGE.bash 等の方が良いかもしれない。
        もしこれらのファイルが存在したらそれを source する事にする。PACKAGE と
        大文字にしていると PACKAGE の部分を package manager の名前に置き換える
        のだと勘違いする人がいるかもしれない。やはり此処は init-package.sh にす
        るべきだろうか。然しそうすると今度は他の普通のファイルとの見分けが付か
        ない。或いは単に lib/package.sh とするか。或いは、lib/_package.bash と
        いう形にするのが良いだろうか。

        うーん。lib/_package.bash もしくは lib/_package.sh という事にする。内部
        で、ble/package/update なる関数を定義してもらう事にする。

    * README にリンクを貼る。README が長くなるのも面倒だし、そもそも普段使って
      いる人はコマンドを見なくても分かる筈。という訳で取り敢えずはパッケージ名
      だけ分かる様にしておく。

      一つ一つのコマンドについては Wiki にページを作る事にすれば良いだろうか。
      然し、Wiki のページに跳ぶのも面倒である。それにリンクが沢山あるのも変な感
      じがする。或いは、リンクは Wiki のページだけに向かわせる事にする。パッケー
      ジ名は単なる文字列とする。それが良い気がする。

    2021-05-23 oc1024 に間違いを指摘された。修正する。

2021-05-11

  * bind: 無引数 ble-bind で現在の binding を表示。現在の binding の着色 [#D1547]

  * complete: ble-sabbrev の出力の着色 [#D1546]

  * edit: やはり \C-x\C-v で ble.sh の version を表示したい気がする [#D1545]

    ble.sh, version 0.4.0-devel3+c89aa23 (noarch)

    Issue template での要求項目も簡単になる。現状だとユーザーに長いコマンドを入
    力させている。

  * 2019-02-09 うーん。git や bash-it の様に ble.sh でも ble コマンドの様な物を提供するべき? [#D1544]
    cf #D1543

    % と思ったが既に何処かには ble という名前のコマンドが存在していて、
    % これらは Bluetooth のサービスの開始・終了などを実行するのに使われている様子である。
    % もしこれらが広範に用いられている物なのだとしたら使いにくい。
    %
    % また、ble の名前の由来である zle コマンドの事を考えると、
    % ble widget の様な使い方を想像してしまうのではないかとの問題もある。
    %
    % 混乱を防ぐためには ble ではなくて ble.sh または blesh の様な名前が良いだろう。
    % しかしそうすると現状の ble-import だとかの機能を呼び出すのに余り適していない気がする。
    % つまり、blesh import ... で ble-import が呼び出されるというのは分かりにくい。
    % 或いは現状の ble-import を blesh-import に改名するという手もあるかもしれないが、
    % そういう事を考え始めると全ての関数を ble から blesh に改名したくなる。
    % それは面倒だし、元の zle という名前から離れていくので余りやりたくない。
    %
    % 実のところ、現状のまま ble-* の方が自動的に補完が効くので嬉しい。
    %
    % bash.env は bash.env という名前のコマンドを提供する様である。
    % https://github.com/midwire/bash.env
    % そういう事であれば ble.sh でも ble.sh という名前の関数を提供すれば良い気がする。
    % しかし ble.sh が入力しやすいのかというと微妙ではある。
    %
    % bash-it の場合には bash-it-update だとか bash-it::update だとかだと
    % 格好が悪いので bash-it update という形の関数名になるというのは分かる。

    結局 ble という名前で定義する事にした。既に同名のコマンドが存在している場合
    には、引数を認識できない時に限り元のコマンドを呼び出す事にした。

  * main: BLE_ONLOAD [#D1543]
    https://github.com/akinomyoga/ble.sh/issues/107

    shournal という plugin の作者が PS0, PS1 を使ってコマンド開始・終了を検出し
    ようとしている。それはそれで良いのであるが、ble.sh は PREEXEC, POSTEXEC と
    いう物を用意している。考えてみれば他の枠組みで使ってもらう為には、ble.sh の
    ロードの順序に関係なく PREEXEC, POSTEXEC が存在すればそれに attach できる様
    に記述したい。

    % ble.sh がロードされた時に呼び出す配列も用意した方が良いのではないか。
    % ble.sh がロードされた段階では blehook コマンドは使えないし、blehook の内
    % 部形式を上書きしようにも _blehook_h_... だとか様々な配列があって直感的で
    % ない。ロードした時に関しては特別に BLE_ONLOAD 的な配列を用意しても良いの
    % ではないだろうか。

    という事を考えると ble.sh が後からロードされた時の為に

      BLE_ONLOAD

    という配列を用意して其処に初期化用のコードを登録させるというのが手である。

    然し、ble.sh をロードしているからと言って attach しているとは限らない。
    plugin が動作を切り替えるのに使える関数を用意するべきなのではないか。現在
    ble.sh がロードされていてかつ attach していて更にユーザーコマンドの実行中で
    ない時という判定をする必要があるのではないか。

    取り敢えず zle を真似て ble という関数で現在の状態を検出できる様にしようと
    したが…。ble.sh がロードされていない状況にも対応する為には結局変数に頼るべ
    きなのではないか。実のところ特に ${_ble_attached-} をチェックすれば良いので
    はないかという気がする。問題は _ble_attached は明らかに内部変数といった形に
    なっていて公開に躊躇するという事。

    a _ble_attached を BLE_ATTACHED に改名する?

      値を設定している箇所は ble.pp 内部の5箇所のみである。なのでこの部分の変更
      はそんなに大変ではない。然し参照している物の内には fzf-marks も含まれてい
      る。うーん。

    b _ble_attached と共に BLE_ATTACHED も使える様にする?

      変更している箇所が 5 箇所なので連動して変更するのは簡単である。

      また、bash-4.3 以降では nameref を使える。唯、nameref 属性を追加する為に
      は -g が必要である。と思ったが -g は 4.2 から使えるので問題はない。

      そうは言っても version 毎に連動して変更するコードを実行するしないというの
      を切り替えるのも面倒なので、やはり常に明示的に連動して変更する様に書く方
      が楽である。

    * done: BLE_ATTACHED を公開変数にする。

    * done: ble コマンドで現在内部にいるかどうかを判定できる様にする?
      [[ $_ble_attach && ! $_ble_edit_exec_inside_userspace ]]

      0neGal が ble という名前のコマンドを作っていた。勝手に他の人がコマンドを
      作成する前に ble コマンドを予約しておくのが良い気がする。然し、他のコマン
      ドと被った時の為に本当の関数名は別にしておく? だとすると何が良いだろうか。
      調べると blesh というのも既に Bluetooth Low Energy の CLI ツールとして存
      在はしている様である。然しだからと言って blectl だと更に Bluetooth Low
      Energy の制御に使うコマンドの様である。ble-cli だとか blecli も同様である。
      或いはユーザーから直接使って貰う可能性は考えずに ble/dispatch にするとい
      う考えもある。然し、ユーザーに使われる事を想定しないのであれば、抑々別名
      として退避する意味もよく分からない。

      名前に関しては 2019-02 に既に議論が存在している。ble.sh という名前の関数
      を定義するという手についても示唆されている。bash.env や bash-it はそのま
      まプロジェクト名がコマンド名になっている。然し、ble.sh は既に沢山の関数を
      ble... としているのでやはり ble が最適である様に思われる。

      うーん。やはり ble -> ble/dispatch という事にする。と思ったが面倒なのでも
      ういきなり ble を定義している。後で問題になった時に処理すれば良い。と思っ
      たがやはり ble/dispatch を定義した。

    * done: blehook ATTACH, DETACH 対応した。

  * 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]
    https://github.com/akinomyoga/ble.sh/issues/107

    一体何をしたいのか謎だがまあ元の bash で動く以上はその動作を利用する設定も
    あるだろう。元々その様に実装していたのは set -x の出力を防ぐ為だったが、よ
    く見たら PS0 の出力は restore-bash-options の前だったのでこの段階では 2 を
    端末に出力しても OK.

  * 2021-03-21 gitstatus.plugin.sh の alias builtin で builtin eval 他が破壊されている [#D1540]
    https://github.com/akinomyoga/ble.sh/issues/93
    https://github.com/romkatv/gitstatus/pull/235

    * 取り敢えず暫定的な対策として source ble.sh の時に unalias builtin 等を実
      行する事にした。

    * 他に source ble.sh した後に gitstatus.plugin.sh が実行されて、更にその後
      になって ble-attach した時の事も考える必要がある。

    gitstatus.plugin.sh の側で対策できないのか。
    34e21707

    https://github.com/romkatv/gitstatus/issues/154
    ここで本人が builtin を置き換えるのは良くない事だという事を述べている。

    > It's generally not a good idea to redefine builtins. If you also redefine
    > things like true, local, unset, etc., gitstatus won't work. Please don't
    > file a bug in this case but rather fix your config.

    eval ... pos parameters
    source ... pos parameters
    source ... function scope or not (declare var の振る舞い)
    unset ... previous-scope dynamic-unset or value-unset
    exec ... persistent redirections
      これは実際に問題になるという事を確認した。

    これは報告したらもっと別の方法で exec bash を検出する方法について議論が始まっ
    た。幾つか結構怪しい方法も含めて紹介した。その内の一つの方針で実装してテス
    トしてみるそうである。

    これも返信が来て色々議論して alias を全く使わない様に向こうが修正してくれた。
    しかも後で気づいたのだが gitstatus の作者はあの powerlevel10k の作者でもあっ
    た。powerlevel10k は ble.sh と同じく zsh ではあるがシェルで色々と複雑な処理
    をゼロから真面目に実装している奴である。

  * highlight: 1>&a.txt のファイル名着色 [#D1539]

    着色だけでなく補完にも一緒に対応する。

    x fixed: 実装してみたが動かない→2箇所 RDRD2 になっていた。CTX_RDRD2 に直す。

    x fixed: 3<&- や 3<&4- 等の redirection に対してエラー着色になっている。

    x fixed: 1>& 1 に対して補完が効かない→check-prefix に登録していなかった。

    x fixed: 1>& に対して補完が効かない。ファイル名だけが生成される。check-here
      でもしかすると別の ctx になっている?  →調べたらそもそも ARGX になってい
      て其処から RDRD2 等に変わっていないので ARGX だと思って補完が開始されてい
      るのが原因である。何が問題かというと、次の単語がない時に redirection で
      stat を設置していないのが行けない。然し、そもそも RDRD2 等は単語の種類で
      あって解析の状態ではないのではないか? と思ったが別にそういう訳でもないら
      しい。ちゃんと RDRD2 という ctx になって解析されている。

      ここで問題になるのは RDRD2X 的な文脈が存在しないという事にある気がする。

      a 或いは一文字も入力されていなくても勝手に RDRD2 を開始してしまうべきなの
        だろうか。と思ったが RDRF, etc は nest の中にいるという事を前提とした実
        装になっているので、そのまま ctx を設定する訳には行かない。然し、そうは
        言っても空の nest を生成する事もできない。

      b 或いは stat か何処かの配列に次に来るべき者についての情報を記録するとい
        う事にする? 他の所ではその様な事をしていないのに此処だけでその様に処理
        するのも変である。

      c というかそもそも check-prefix で ARGX の時に redirection を検出するべき
        なのではないだろうか。

      最終的に c が正しい実装である。そもそも check-here は fallback 的な位置づ
      けであり此処に来た時点で実は変な補完になってしまう事は運命づけられている。

    * 他に << 及び <<- の後の補完も定義されていなかったのを定義した。適当に
      EOF:END:HERE 等としたがもっと別の物を追加するべきかもしれないし、あるいは
      ユーザーが設定できる様にするべきかもしれない。

    * 全般に fd の補完もできる様にした。

  * MSYS2 patch .inputrc [#D1538]
    https://github.com/akinomyoga/ble.sh/issues/104
    https://sourceforge.net/p/msys2/mailman/msys2-users/thread/CAFLRLk-UX7S%3DTAerNix7HvxDAv4aY2FwZuFZz%3DU%2BTLBAWxCLEg%40mail.gmail.com/#msg37275646
    https://github.com/msys2/MSYS2-packages/pull/2490
    https://github.com/git-for-windows/build-extra/pull/341

    Ref #D1534

    特に問題の行は削除するべきであると考えているが返信は未だない。
    強い口調で書き過ぎたから無視されているのかも知れないし、
    単にこの mailing list には誰もいないという事なのかもしれない。
    archive を遡ってもこの mailing list は活発であるとは言い難い。

    GitHub にソースを見つけたので PR を出してみた。
    こちらも直ぐには返事が来ない。
    一応ちゃんと変更の要求は取り込まれた。

    https://github.com/msys2/MSYS2-packages/pull/2490

    然し本当に git bash の msys と msys2 は一緒なのだろうか…。MSYS2 をインストー
    ルして、それから Git Bash もインストールしてみる。Git Bash の方は個人のディ
    レクトリには .inputrc はなくて、/etc/inputrc が読み取られている様である (実
    際に /etc/inputrc を編集して影響を与えている事を確認した)。そして、実は
    /etc/inputrc の内容と MSYS2 の .inputrc の内容は異なるという事も確認できた。

    ? ok: MSYS2 の /etc/inputrc はどうなっているのだったか→MSYS2 では
      /etc/inputrc は存在していない。なので、今回の変更だけで大丈夫のはず。

    ? ok: Cygwin の方にも inputrc があるのではないか→調べたら
      /etc/skel/.inputrc があったが、これはちゃんと変な binding は削除されてい
      た。検索した感じだとそもそもこの壊れた binding は cygwin の inputrc から
      来ていた様な気がする (違ったかもしれないが面倒なのでもう確認しない) ので、
      Cygwin の側では誰かが何処かの時点で気づいて削除したという事だろうか。

    ? done: Git Bash の /etc/inputrc にも変更要求を出さなければならない

      https://github.com/git-for-windows/git-sdk-64/blob/main/etc/inputrc
      https://github.com/git-for-windows/git-sdk-64/blob/main/etc/skel/.inputrc
      https://github.com/git-for-windows/git-sdk-32/blob/main/etc/inputrc
      https://github.com/git-for-windows/git-sdk-32/blob/main/etc/skel/.inputrc

      以上にファイルを見つけたがどうも違う様な気がする。これらのリポジトリのコ
      ミットを見ると自動的にアップデートされている。なので、これは別の場所に
      upstream があるという事を示唆しているのではないか。然し検索してみても関連
      する物は見つからない。

      https://github.com/search?q=org%3Agit-for-windows+%22msys2+mailing+list%22&type=code

      /etc/skel/.inputrc は MSYS2 から継承されるのだと考えたとしても、では
      /etc/inputrc は何処から来ているのだろうか。謎である。うーん。もしかして
      msys1 が起源になっている? というか Git Bash の MSYS は MSYS2 ではなくて
      MSYS1 なのだろうか。MSYS の version は何処でチェックできるのだろうか。

      改めて色々読んでいると build-extra も言及されている。適当にディレクトリを
      覗いたら inputrc があった。どうも GitHub の検索はファイル名本体には全く一
      致しないようだ。

      https://github.com/git-for-windows/build-extra/blob/main/git-extra/inputrc

      https://github.com/git-for-windows/git/issues/62 では PR は OK と言ってい
      るが何処に出したら良いのかについては何も言及していない。msysgit という物
      も存在する様だ…そちらにも PR を出す必要があるだろうか、と思って確認した
      ら msysgit は Git for Windows の前身であり同じ人が管理していて既に
      archive されていた。

    ? ok: MSYS-1.0 にも出した方が良いだろうかと思って活動を確認したが Mailing
      list は 2013 から動いていないし、最新版も 1.0.12 の 2016 年なので、此処で
      修正しても仕方がないと判断する。そもそも、ble.sh の側でも対策を入れたので
      実質的に問題は発生しない筈。

2021-05-08

  * decode: 初期化時にエラー (reported by RakibFiha) [#D1537]
    https://github.com/akinomyoga/ble.sh/issues/106

    一番最近の commit を観察したが特に怪しい所はない様に思われる。

    キャッシュが壊れている可能性? 然し、キャッシュをクリアしてしまうと問題が再
    現しなくなる可能性があるので後回し。
    もし ble-update を実行する過程でキャッシュが壊れるのだとしたらどれかの
    version から最新版に更新した時に問題が再現するかもしれない。そう思って
    026432d 9125795 79d671d 0506df2 032f6b2 からのアップデートを試したが再現は
    しなかった。

    どの commit で問題が起こる様になったのだろうか。改めて怪しい変更がないか
    commit を眺めて見る。試しに bind '"hello":"world"' としたら再現した。改めて
    decode-char の呼び出し部分を確認する。もしかするとここを "${chars[*]}" にし
    ていたり変数に代入したりする過程でその様に加工してしまっているかもしれない。
    と思ったら、本当に "${chars[*]}" にしてしまっていた。一文字の修正である。

2021-05-07

  * bind: fix a problem that "bind '"seq":"key"'" causes a loop macro "bind -s key key" (reported by thanosz) [#D1536]
    https://github.com/akinomyoga/ble.sh/issues/105

    これはどうやら OpenSUSE の inputrc にある、テンキーの / のエスケープシーケ
    ンスを / に翻訳する keybinding の問題だった。ble.sh は左辺をキー列に翻訳し
    てから bind する。という事なので、

      "escape-sequence": "key"

    の様な binding が存在すると、key: "key" という形に翻訳されてしまう。そうす
    ると無限ループに変換されてしまうという事である。

    これの対策は単に左辺と右辺が一致している時に binding を無視するというだけで
    良いのだろうか。或いは、それだけでは駄目なケースが存在するだろうか。例えば、

      "escape-sequence-long": "escape-sequence-short"

    という形になっていたとすると、

      key: escape-sequence-short

    という形になってしまって結局無限ループになってしまうのではないだろうか。現
    在の実装について改めて確認する→やはり左辺が keys で右辺が chars になってい
    るので単純に keys と chars を比較するのでは駄目である。結局 chars を keys
    に翻訳してから比較する事にした。実装した。テストした。動いている。OK

2021-05-06

  * progcomp: aws_completer が呼び出されない (reported by Archehandoro) [#D1535]
    https://github.com/akinomyoga/ble.sh/issues/102

    これは原因は分かった。complete -p の出力結果が quote されているのに、ble.sh
    はそれを直接解釈しようとしているのが原因であった。"'aws_completer'" という
    名前のコマンドを実行しようとして失敗している。

    そもそもこれは complete -p の出力結果が quote されていたりされていなかった
    りするのが原因である。version 毎にどうなっているか確かめてみる事にする。

    * コマンド名: コマンド名に関しては現在に至るまで一切 quote されない。

    * -C の引数について: bash-3.2 までは裸で引数が出力されるだけであった。

    * -F の引数も一切 quote されない。と思ったら bash-5.1 以降で -F を設定する
      時にチェックが入る様になった。然し、それでもブレース展開や履歴展開、変数
      展開も含める事ができるのでそのまま eval する訳には行かない。

    * -WGXPS の引数: 常に quote される

    * 引数が出力される順番は固定の様である。問題の -F func -C callback cmd はこ
      の順序で必ず最後に出力される。と思ったが、bash-4.0 以降では -C c -F f cmd
      の順序に変更になった。

    まとめると、

    * bash-3.2まで: complete [OPTIONS] -F str -C str    cmd
    * bash-4.0以降: complete [OPTIONS] -C 'str' -F str  cmd
    * bash-5.1以降: complete [OPTIONS] -C 'str' -F func cmd
      5.1 で安全になったかと思いきや func に !${} を含められるので駄目。

    うーん。コマンド名に関しては末尾から削除すれば良い。quote をちゃんと辿って
    行けば -F が現れた時点でこれは確実に本物の -F である。更に -F の引数に関数
    名として不正な物を指定する理由もないので、-F の直後は一つの単語だけ読み取れ
    ば良い。すると残るのは (もしあれば) -C callback 名という事になる。

    どの様に実装するか。結局どの bash version であっても -F func が quote され
    ないので eval するのは危ない。そもそも callback を設定する時点でその補完が
    呼び出された時点で駄目な訳だけれども、取り敢えず滅茶苦茶な事が起こらない様
    にする為には真面目に parse するのが良い。

    a 後ろから parse するのは問題ないだろうか? ... これは危険である。例えば -F
      が見つかったとしてもこれが本当に -F なのかは分からない。偽物の -F で、実
      は其処よりも前にも quote されていない引数が潜んでいる可能性がある。

    うーん。手順としては先ず初めに末尾にコマンド名が一致していればそれを除去す
    る (一致していなかった場合はどうするのかは謎)。次に正規表現で読める所まで読
    んで、それを eval する? 読みきれなかった部分については変数に残して置く。読
    めた部分を解析する。途中で -F に行き当たったら残りの文字列を特定して、続き
    は真面目に parse する事によって結果を得る? というか残りについては " -C " が
    含まれているかいないかで取り扱いを変更すれば良い気がする。然し、何らかのオ
    プションが -F の後に続いているという事もあるかもしれない。

    取り敢えず実装した。動いている。もう一つの問題として aws の補完結果は末尾に
    空白を含めているのにも関わらず noquote 等の処置をしていないという事。うーん。
    これに関しては…。仕方がないので aws_completer 用の WA とする事にした。また、
    コマンド名なのに偶然でディレクトリ名に一致して suffix がついてしまう事につ
    いても workaround とした。但し、考えて見るに -F もしくは -C で生成した候補
    に対して suffix を付けるのも変な気がする。これについては改めて考えても良い
    のかもしれない。

  * MSYS2 で Backspace で行全体が削除されるという話 (reported by n1kk) [#D1534]
    https://github.com/akinomyoga/ble.sh/issues/104
    https://sourceforge.net/p/msys2/mailman/msys2-users/thread/CAFLRLk-UX7S%3DTAerNix7HvxDAv4aY2FwZuFZz%3DU%2BTLBAWxCLEg%40mail.gmail.com/#msg37275646

    取り敢えず MSYS2 の .inputrc が怪しいという事で msys2-users に報告した。そ
    れとは別に ble.sh の側でも対策する事は可能だろうか。

    a 例えば MSYS2 にいる時には .inputrc は読み取らない (--noinputrc) 様にする?
      然し .inputrc だけ読み取らない様にしても仕方がない。ユーザー設定も読み取
      らない様にしないと bind で自動的に読み込まれた設定を読み取ってしまう事に
      なる。

    b INPUTRC=/dev/null を設定してから bind で初期化する事により bashrc で設定
      されたユーザー設定だけを読み取るという手もある気がするが、これも source
      ble.sh よりも先に bind 関連の設定にユーザーが触れていると駄目である。

    c 上記の問題は inputrc にある他の設定も全て潰してしまうという事である。それ
      ならば、C-? に対応する設定だけ ble.sh default に強制的に設定する様にすれ
      ば良いのではないだろうか。

    取り敢えず c の方針で実装する事にした。この様にしたとしても C-x C-r で
    inputrc を再読込するとまた変な状態になってしまうが、これは仕方がない。

  * complete: bash-completion bug workarounds (reported by oc1024) [#D1533]
    https://github.com/akinomyoga/ble.sh/issues/97

    自分の手許でも色々エラーメッセージが出てうるさい。

    bash-completion で修正を掛けるのは面倒だし時間がかかりそう。更に、各種
    distribution に波及する迄に更に時間もかかりそうなので取り敢えず暫定的に、
    ble.sh の側で bash-completion の実装を上書きする事にしてしまう。

    * 2021-05-06 bash-completion
      https://github.com/akinomyoga/ble.sh/issues/97
      https://github.com/scop/bash-completion/pull/492
      Ref #D1533

      python のテストを自分で実装したりしなければならず面倒である。
      実装した。PR を update した。これは向こうの反応待ち状態である。

  * 2021-04-06 localvar_inherit で動かなくなっている  [#D1532]

    或いは元から動いた事はなかった可能性も?

    * localvar_inherit をしていると local -r a した変数に対して、
      内側の関数で同名の変数を定義できなくなってしまう。

    うーん。それでも未だ色々動かない。というか、バグというかちゃんと書
    かれていないコードを洗い出すのに使えるかもしれないとは思う。

    * どうやら localvar_inherit になっていると local BASH_COMMAND としても
      BASH_COMMAND の値が変化する性質は受け継がれてしまう様である。

      | RANDOM でも同様の現象が発生している。
      |
      | $ f1() { local RANDOM=hello; echo $RANDOM; RANDOM=world; echo $RANDOM; }
      | $ shopt -u localvar_inherit; f1
      | hello
      | world
      | $ shopt -s localvar_inherit; f1
      | 20034
      | 20034
      |
      | 何が起こっているのだろう。元の変数がそのまま見えているという事だろうか。
      | と思ったがそうでもない。unset RANDOM して見たが元の変数が消えるという事は
      | なかった。恐らく localvar_inherit の時には値が受け継がれるのではなくて、
      | setter/getter が引き継がれてしまっているのが原因なのだろうと思われる。
      |
      | bash を確認すると subst.c (expand_declaration_argument) では
      | localvar_inherit が設定されている時には declare は declare -I と同様の振
      | る舞いになる。 declare -I の説明を declare --help で確認すると値と属性を
      | 継承すると書かれている。
      |
      |   if creating a local variable, inherit the attributes and value of a
      |   variable with the same name at a previous scope
      |
      | と思ったが実装をよく見ても inheriting の値が一切使われていない気がする。
      | 不思議である。未実装なのだろうか。或いは何かを見落としている? どうもこの
      | 関数は arr=() の形式の引数を処理する時にだけ使われているという事だろうか。
      |
      | 実際に localvar_inherit の処理を具体的に処理しているのは variables.c の方
      | である様に思われる。特に以下の部分 (variables.c:2738) が setter/getter を
      | 継承するコードである。
      |
      |   if (localvar_inherit || (flags & MKLOC_INHERIT))
      |     {
      |       /* It doesn't make sense to inherit the nameref attribute */
      |       new_var->attributes = old_var->attributes & ~att_nameref;
      |       new_var->dynamic_value = old_var->dynamic_value;
      |       new_var->assign_func = old_var->assign_func;
      |     }
      |
      | 明示的にコピーしているという事を考えるとこれを覆すのは難しいかも知れない。
      | 具体的に変な振る舞いをする例を作ってそれを呈示すれば何か考えて貰えるかも
      | しれない。getter/setter が関わっている関数は他にあるだろうか。
      |
      | INIT_DYNAMIC_VAR で検索するとそういった関数の一覧が得られる。
      |
      | - "SECONDS", (v ? value_cell (v) : (char *)NULL), get_seconds, assign_seconds
      | - "FUNCNAME", (char *)NULL, get_funcname, null_assign
      | - "BASH_ARGV0", (char *)NULL, get_bash_argv0, assign_bash_argv0
      | - "BASH_COMMAND", (char *)NULL, get_bash_command, (sh_var_assign_func_t *)NULL
      | - "BASH_SUBSHELL", (char *)NULL, get_subshell, assign_subshell
      | - "RANDOM", (char *)NULL, get_random, assign_random
      | - "SRANDOM", (char *)NULL, get_urandom, (sh_var_assign_func_t *)NULL
      | - "LINENO", (char *)NULL, get_lineno, assign_lineno
      | - "BASHPID", (char *)NULL, get_bashpid, null_assign
      | - "EPOCHSECONDS", (char *)NULL, get_epochseconds, null_assign
      | - "EPOCHREALTIME", (char *)NULL, get_epochrealtime, null_assign
      | - "HISTCMD", (char *)NULL, get_histcmd, (sh_var_assign_func_t *)NULL
      | - "COMP_WORDBREAKS", (char *)NULL, get_comp_wordbreaks, assign_comp_wordbreaks
      |
      | TERM の場合はどうなっているのだろうか。これは special_vars という事になっ
      | ていて、値が変更した時に特別の関数が呼び出される様になっている。他に
      | TERM* や LANG, LC_* 等様々な変数がこれに相当する。これらは local に関係なく
      | 常に値が変更したら何か処理する事になっているので今回の振る舞いには関係ない。
      |
      | やはり勝手に上書きするのが悪いという結論になりそうな変数しか存在しない。
      | 敢えて言うならば RANDOM か LINENO ばかりだろうか。LINENO の方も確認したが、
      | やはり LINENO に対する代入は無視されて現在の行数が常に表示される様になっ
      | ている。因みに LINENO=1234 eval 'echo $LINENO' に関しては
      | localvar_inherit を設定しても特に変わりなく同名の tempvar が作成される。

      bash のバグか或いは confusing behavior かどうかは別として、古い version
      に対しては取り敢えず修正しなければならないので、対策は行う事にする。時間
      があれば bash に報告・相談もする事にする。

    * もう一つの問題は local -a buff とした後に ble/array#push としていると、前
      の配列の内容が既にあった場合にそれの続きとして値を push してしまうという
      事。こう言った使い方をしている箇所はないと思っていたが、確かめてみると古
      いコードを中心にして沢山あった。と思ったがそんなには無かった。合計で4箇所
      だけだった。

    上記の事を直したら取り敢えず動いている様に見える。残りは具体的に問題が生じ
    てから対処する事にする。

  * 2021-04-28 keymap 初期化に失敗した時にそれを検出しているのにも拘らず操作不能になる [#D1531]

    $_ble_base_cache/keymap.emacs が空の時、The keymap 'emacs' is empty 等の様
    にメッセージが表示されて空かどうかのチェックが為されている筈なのに、その後
    に何も操作できなくなる。

    ble/decode/attach の中でチェックが起こっている気がするが、その場合には
    attach せずに終わって操作不能にはならない筈なので関係ないかもしれない。

    今試しに keymap.emacs を空にして bash --norc から ble.sh をロードしてみたが、
    stty の状態が変になる物の操作不能になる訳ではない。set -o vi でスタートさせ
    てset -o emacs で切り替えようとすると問題が再現する。つまり、detach して
    attach した時の問題である。

    調べてみるとどうもコマンドは実行されている様である。stdout.off の状態になっ
    ている事によって操作できなくなってしまっているという事の様である。そしてそ
    れは、ble/decode/attach の呼び出し元の .check-detach の更に呼び出し元におい
    て、bind/.tail 経由で改めて stdout.off が実行されているという事になる。これ
    を抑制する為に、.check-detach の中で rebind に失敗した時には改めて
    .check-detach を呼び出して抜ける処理を実行する事にした。

    →然しそれでもやはり stdout.off が呼び出されてしまう。と思ったが、どうも
    .check-detach の戻り値を使って実際に detach が起こったかどうかを伝達してい
    る様である。ちゃんと再帰的に呼び出した .check-detach の終了ステータスを外に
    伝播させる。これで問題なく抜ける様になった。

  * 2021-04-06 main (--rcfile): 通常ファイルしか許可していないが [#D1530]

    <() や /dev/null を食わせたい事もあるだろう。後、ファイルが見つからなかった
    時に結局 ~/.blerc を読み取ってしまうのは不便。ファイルが見つからなかった場
    合には何も読み込むべきではない。

    --norc オプションにも対応した。

  * syntax: eval() { echo yes; } が構文エラーになっている [#D1529]
    local, declare も同じ。

    これは意外と簡単だった。処理順序を変えるだけで良かった。builtin の処理と
    keyword の処理が結合しているから切り離すのに時間がかかるのではないかと思っ
    たが、実際には builtin の処理は独立にしても問題ない様な実装になっていた。

  * main: freeze-utility-path が一時実装を置き換えなくなっている [#D1528]

    ble/bin/sleep を初期化する前に sleep の機能についてテストしている気がする?
    と思ったが最初に ble/bin/sleep を絶対パスではなくて command sleep で定義し
    ているので問題は起こらないのだった。というより、最近 freeze-utility-path で
    既存の関数がある時には上書きをしない様に変更したが、これは駄目だ。元々上書
    きする様になっていたのはこの一時的な実装を置き換える為であったのである。

    然し、上書きする様に変更してしまうと freeze-utility が ble/bin/awk を上書きしてしまう。

    a そうすると一時的な実装とそうでない実装を区別できる様に、関数か変数をマー
      カーに使う?

    b 或いは初めからもう定義してしまって呼び出した時点でパスを決定する事にする。
      初期化の順序によっては fork コストがかかる可能性もあるが、
      それも少しだけなので余り気にしなくても良いかもしれない。

      問題は ble/util/assign がちゃんと動作する迄に時間がかかるという事だから、
      ble/util/assign が準備できたかどうかを変数に記録しておけば良いのでは。

    c 或いは ble/util/assign が準備できた時点で .freze-utility を改めて呼び出す
      事にする。直接呼び出しても良いし、それだと密結合になるというのであれば、
      hook か何かを準備しても良い。

    d 或いは今まで通り freeze-utility は上書きをしてしまう様にする。awk に関し
      ては上書きしない様にリストから削除しておくか (然し削除の為にまたコードを
      書かなければならない。初期化時点では ble/array#remove もない)、或いは
      ble/bin/awk.protected か何かの様にして上書きをしない様に関数を定義する。

    うーん。大きく変更するのも面倒なので ble/bin/awk.protected を定義するという
    方針にする。と思ったが関数が存在するかどうかのテストはやはり util.sh を待た
    なければならない。

    ? ok: alias が定義されている時に freeze-utility は正しく動作するだろうか?
      →これは大丈夫。type -P としているから。

2021-05-04

  * util: bleopt/check-all で obsolete な設定も読み取ろうとしてエラーになっている [#D1527]
    obsolete なオプションに対しては初期設定のチェックは行わなくて良い。

  * syntax: 着色決定時に expand_aliases 設定が退避されている (reported by 3ximus) [#D1526]
    https://github.com/akinomyoga/ble.sh/issues/103

    0860be0 に於いて内部では alias が展開されない様に shopt -u expand_aliases
    を設定していた。然し、よく考えてみたら構文着色等に於いて expand_aliases が
    有効かどうかによって処理を変えていた。つまり expand alias の処理の際にちゃ
    んと退避した設定を確認する必要がある。

    実際に修正しようとしたら話はそう単純ではない様である。そもそも自分で shopt
    -s/-u expand_aliases を変更しようとしても完全に無視されてしまう。次のユーザー
    状態になる頃には勝手に元の値に戻ってしまっている。何故? 例えば
    POSIXLY_CORRECT を手で弄っている所為だろうか。或いは expand_aliases の保存
    復元の呼び出しタイミングが混ざっているからだろうか。それとも bind -x の中で
    変更した expand_aliases の状態は抜けると消えてしまうという事なのだろうか。

    やはり自分では何も操作していないのに expand_aliases の設定が変わってしまっ
    ている。うーん。という事は…どうすれば良いのか?

    * 内部で shopt -u expand_aliases にしたいというのは…。毎回 bind head で設
      定し直すぐらいしかできない→ bind/.head で再設定する様にした。

    * ユーザーが設定した設定が保持されないという事に関しては。これは明示的に自
      分で保存復元する必要がある。特に restore する時には shopt -u
      expand_aliases も明示的に実行する。→これは bind/.head で設定する様にした
      ので、わざわざ自分で実行しなくても良い。

    * エイリアスを展開する時に一時的に shopt -s expand_aliases 状態を復元する。
      と思ったが、それでは駄目だった。様々な所で ble/util/type を呼び出していて、
      その結果が alias にならないとそもそも expand-alias 関数自体が呼び出されな
      い。修正するべきは expand-alias ではなくて ble/util/type の方である。こち
      らを修正したら動く様になった。

  * util: test-canvas.sh ext/contra 依存性の解消 [#D1525]

    test-canvas.sh がエラーを出す様になっている。試すとテストを取り入れた時から
    既にエラーになっている。どういう事だろうか。と思ったが、テスト自体が
    ext/contra もしくは contra を前提としていた為に起こっていたエラーだった。存
    在しない時には通る様に書いたつもりだったがそうなっていなかった。

  * awk で {m,n} は使えないという事 [#D1524]
    https://unix.stackexchange.com/questions/354553/awk-repetition-n-is-not-working
    Ref #D1522

    更に nawk, mawk では十六進表記 0xHHHH も使えない。規格的には optional に対
    応しても良いという事になっている様だ。

    更に mawk は match("AAA", /AA?A?/) としても2文字しか一致しない。/A(AA?)?/
    という具合にしなければならない。

    過去の互換性の為であると言っている割に POSIXLY_CORRECT=always を指定しても
    対応するという気配はない。

    →特にこれらに引っかかりそうな箇所は今の所は見つからなかった。然し、
    今後の為にちゃんと記録しておく必要がある→ #M0019 に残す事にした。

  * nawk の方が軽いので既定で nawk を使う様に変えてみる [#D1523]
    Ref #D1522

    gawk 特有の振る舞いに依存している部分を洗い出す為にもこの変更は有用だろう。

    x nawk を使う様にして試してみた所、初期化時に "function" というメッセージが
      沢山表示される → これは nawk とは関係なくて freeze-utility で追加したコー
      ドで既存の ble/bin/??? が定義されているかどうか確かめる type の出力を
      /dev/null に繋いでいなかったのが問題であった。

    x また、use-solaris-xpg4 が他から参照されている。mshex にも
      akinomyoga.dotfiles にも use-solaris-xpg4 はない気がする。何処由来だろう
      か? →これは単に ble.pp に古いコードが残っていただけだった。

    他にも様々な問題が発生した様に思われたが全て最近行われた別の変更によるバグ
    だった。一通り修正できたので改めてテストを行う。取り敢えず動いている様な気
    はする。

  * 2021-03-15 巨大なディレクトリで TAB 補完が遅い (2) (reported by timjrd) [#D1522]
    https://github.com/akinomyoga/ble.sh/pull/65#issuecomment-798551355
    Ref #D1512

    修正したと思ったが依然として時間がかかっている。

    (1) 調べてみると、どうもconditional-sync が終わった後の
      builtin eval -- "$def"
      を実行する時に時間がかかっているという事。

      これを高速化する方法はあるだろうか。というか assign-array では駄目なのだ
      ろうか。と思ったが、ファイル名に改行が含まれている可能性などを考えると駄
      目という事?

    後気付いたのだが、ファイル名に改行が含まれている場合には何が起こるのだろう
    か。source:file はファイル名のチェックをしない様に今回書き換えたが実はこれ
    によって改行が含まれているファイル名の断片も生成される様になってはいないか。
    然し、eval-pathname-expansion で変な分割のされ方をしない限りは問題は起こら
    ないはずである。また、eval を経由して親に結果を渡す事によって、改行を含むファ
    イル名でも対応できる様になっている。

    うーん。eval の中でも時間がかかっている様に思われたが、これも eval するため
    の文字列を構築するのに時間がかかっているという事なのだろう。

    $ files=(*)
    $ time eval ': "${files[@]@Q}"'
    280ms
    $ time eval ': "${files[@]}"'
    216ms
    $ time for a in "${files[@]}"; do break; done
    235ms
    $ time echo ${#files[@]}
    0ms

    これらの結果を見るに、インデックスでアクセスする様にするべきという事か。

    $ time data=("${files[@]}")
    300ms

    a ${files[@]:offset:length} を使って切り分ける?
      →これは遅い。

      $ time : "${files[@]:0:100}"
      72ms
      $ time : "${files[@]:0:1000}"
      77ms
      $ time : "${files[@]:0:10000}"
      89ms

      うーん。これ自体にも時間がかかっている。然し、1000 単位で分割しようとする
      と 200k の場合には全て処理するのに 20s かかる。10000 単位ならば 200k ファ
      イルに対して 2s 以下で処理できるが、元から 200ms かかっていたのが 2s に増
      えるのは微妙な気がする。等の事を考えると、これにかかる時間は仕方がないと
      諦めるべきか。

      →単に ${arr[@]:xx:yy} が遅いというだけの様だ。

    b 直接要素にアクセスする。

      以下の様に直接アクセスすれば、全体を一気に置換した時と比べて遜色のない速
      度が出る。約2倍程度の速度低下で済んでいる。

      $ time for ((i=0;i<200000;i++)); do v=${files[i]}; done
      500ms
      $ time for ((i=0;i<10000;i++)); do v=${files[i]}; done
      29ms


    ? 高速な配列の初期化と言えば history.sh である。結局どの様な方法を用いてい
      たのだったか。やはり eval だったような気もする。確認する。

      うーん cygwin かそうでないかで場合分けしている。Cygwin 以外では mapfile
      を使って読み出している。改行を含む要素に関しては後で補正処理を行うという
      方法を用いている。Cygwin に於いては source している。中では恐らく直接巨大
      な配列のリテラルを指定している。

    $ time x=$(declare -p files)
    72ms

    実は declare -p 自体はそんなに低速ではない。
    現在の実装では quote を ${file[x]@Q} を用いて処理しているが、
    declare -p を用いれば多少の改善はできるかもしれない。

    $ time eval "$(time ret=(*); time declare -p ret)"
    real    0m0.326s
    real    0m0.071s
    real    0m1.345s

    $ cd /path/to/big-directory
    $ time files=(*)
    $ time def=$(declare -p files)
    $ time def=ret=${def#*=}
    $ time eval "$ret"

    具体的に timjrd に計測してもらったがやはり eval "$def" で結構な時間がかかっ
    ている様子である。特に 33k の項目に対して 0.87s かかっている。手元では 200k
    項目に対して 0.40s かかっている。(線形時間を仮定すれば自分の手元では 33k に
    対しては 0.066 で処理できるので余り気にならなかったのだろう。)

    因みに手元では配列のコピーも 0.27s かかっている。これはそんなに長くはないが、
    向こうでは 0.6s ぐらいかかるのだという事を示唆している。つまり、配列コピー
    も気安く行う事はできないのである。

    手元でより高速な方法を模索してみる事にする。

    a eval "$def" の処理時間は 200k 項目に対して 0.40s である。展開と読み取りに
      は 0.67s かかっている。total では 1.07s である。

    b printf '%s\0' "${ret[@]}" で出力した結果を mapfile -d '' で読み取る方法を
      試してみた。結果、読み取りに 0.74s かかっている。実は eval による手法より
      も時間がかかっているという事になる。展開も含めた total の時間は 1.17s で
      ある。total で考えれば手法 a とそんなに変わらないが、中断できないという事
      が問題である。

      更に mapfile -d "" は 4.4 以降でしか使えないので、4.3 以下でも使える様な
      read -d '' による方法の速度を計測してみた所、75s かかった。

      | if ((_ble_bash>=40300)); then
      |   printf '%s\0' "${ret[@]}"
      | else
      | fi
      | if ((_ble_bash>=40400)); then
      |   time ble/util/assign-array0 ret 'ble/util/conditional-sync "$sync_command" "" "" "$sync_opts"' &>/dev/null; local ext=$?
      | else
      | fi 2>/dev/tty

    c source にしたら total 時間を減少させる事ができるだろうか。

    2021-05-01 時間が空いてしまったので改めて現状を整理する。問題は subshell で
    得たファイルリストをどうやって親シェルに伝達するのかという事。500k の文字列
    配列を現実的な時間内に親シェルに伝達し、更に中断も可能である必要がある。

    例を交えて説明するとしたい事は以下の事である。現状で、eval "$(< a.tmp)" が
    遅いというのが問題である。合計時間が長いというのは未だ良いのだが問題はユー
    ザーからの interrupt があった時に中断できないという事にある。

    (
      a=({000000..500000})
      declare -p a > a.tmp
    ) &
    wait $!
    eval "$(< a.tmp)"

    declare -p a の実行自体はそんなに時間はかからない。また mapfile も比較的高
    速である。問題は declare -p a だと eval (遅い) で読み出す必要があって、
    mapfile にする為には要素を printf で出力する必要があるという事。

    a printf '%s\0' / mapfile -d '' (2.5 + 1.6)

      そうだとしても printf '%s\0' で出力して mapfile -t -d '' で読み出すのが一
      番高速でかつ中断可能の気がする。と思って試してみた所、mapfile は -d '' を
      指定した瞬間に遅くなってしまった。どういう事だろうか。最新版 bash でも同
      様である。

    b echo / mapfile -t (3.2 + 0.1)

      この方法は高速であるが代わりに改行を含む様な要素について特別な対処が必要
      である。また時間のかかっている部分での中断も容易である。

      特別な対処を実装したら合計で 3.2+0.1 になった。それでも他の方法よりは高速
      である。これが現実的な解であるような気がする。合計の処理時間は2倍以上になっ
      てしまうが。

    c declare -p a | awk ???

      declare -p を awk で処理する事を考えたが awk には行に含まれる文字数の上限
      があるのではなかったか。本当にそれを正しく処理できるのだろうかという懸念
      は残る。もしそうだとしても物凄く長い行を処理しても処理能力の低下は起こら
      ないのだろうか→文字数の制限が厳しいのは sed 実装だった気がする。POSIX 的
      には awk も制限があったけれども実際の実装ではそんなに問題にならなかったの
      だという気がする。

      読み取りの速度を考えると mapfile-nfix で読み取れる形式に変換するのが良い。
      つまり、declare の parse を awk で行うという事である。declare の形式は
      version によって異なっていたりバグがあったりするが…。

    やはり速度という観点で一番良いのは declare -p a | awk して mapfile-nfix で
    読み取るという物の様に思われる。それとは別に何故 mapfile -d '' が遅いのかと
    いうのは気になる所ではある。

    ? 何故 mapfile -d '' は遅いのだろうか。

      | 確認してみると delim が \n 以外の場合には unbuffered read に切り替える様
      | になっている。何故だろうか。zgetline の実装を見ると delim を引数に受け取
      | る様になっている。更に、zgetline は zread もしくは zreadc を呼び出してい
      | る。最終的に buffered の場合には read(fileno, buf, bufsz) を呼び出して、
      | unbuffered の場合には read(fileno, buf, 1) を繰り返し読む様になっている。
      | 実装を読む限り \n かそうでないかで振る舞いを変更する理由もない様な気がす
      | る。不思議である。理由について尋ねても良いだろうか。
      |
      | Greg に最終的な目標は何なのか。不適切な事を Bash で実行しようとしているの
      | ではないか、という様に文句を言われるかもしれない。その時の為に説明を書く
      | のが良い気がする。
      |
      | get_file_list() {
      |   (files=(*); declare -p files > tmpfile) & bgpid=$!
      |   while :; do
      |     if has_background_completed "$bgpid"; then
      |       eval -- "$(< "$tmpfile")"
      |       return 0
      |     elif has_user_interrupted; then
      |       cancel_everything "$bgpid"
      |       return 1
      |     else
      |       my_sleep 0.1
      |     fi
      |   done
      | }
      |
      | $ a=({000000..500000})
      | $ printf '%s\n' "${a[@]}" > tmp
      | $ mapfile -t a < tmp
      |
      | $ printf '%s\0' "${a[@]}" > tmp
      | $ mapfile -d '' a < tmp
      |
      | builtins/mapfile.def L187..L194
      | > #ifndef __CYGWIN__
      | >   unbuffered_read = (lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE);
      | > #else
      | >   unbuffered_read = 1;
      | > #endif
      | >
      | >   if (delim != '\n')
      | >     unbuffered_read = 1;

      これは報告した。

    さて declare -p | awk を実装してみたが遅い。実装している内に気づいたが、awk
    では文字列の途中から一致させる事ができないので、一致範囲を毎回切り出す必要
    があって、これを巨大な文字列に適用すると大変な事になる。今迄の実装で
    declare -p | awk が使えていたのは正規表現で一気に全体を置換するという様な簡
    単な処理しかして来なかった為である。

    →これについては split(s, a, / /) で分割して各要素について処理する様にした
    ら改善した。

    然しそれでも unescape の処理によって格段に時間がかかっている事は確かである
    様な気がする。もっと手っ取り早く変換する事はできないだろうか。例えば "..."
    と $'...' の何れかしか使われないという仮定で単純化できないか等。しかし、例
    えば空白一文字取って見ても " " の内部と、要素と要素の間の " [...]=" を明確
    に区別できる様な正規表現はない様に思われる。或いは "..." 全体に一致する様な
    正規表現を書ければ、特定の文字列を []="..." の直後に挿入して、更にその後に
    その特定の文字列を使って分割する事が可能だろうか。然し、その為には & または
    \1 等による後方参照で元々の文字列を置換後に参照する必要がある。gawk の
    gensub を使えば可能かもしれないが、その儘の awk では難しいのではないだろう
    か→改めて確認した所、

    ? 今試している awk 実装では問題になっていないが、この様な巨大な処理をすると
      なると awk 実装によってはとても遅くなる可能性があるのではないだろうか。

      | →試してみたらそもそも動作していなかった。動かないと思ったらそもそも nawk
      | は {m,n} に対応していない?
      |
      | $ echo '000' | nawk '/[0-9]{3}/'
      | $ echo '000' | mawk '/[0-9]{3}/'
      | $ echo '000' | gawk '/[0-9]{3}/'
      | 000
      |
      | この様な事態になっている。これは大変な事である。つまり、ERE は使えると思っ
      | て書いていると痛い目を見るという事である。更に調べると gawk-3.0 でも
      | --posix または --re-interval オプションを指定する必要があった様だ。
      |
      | https://unix.stackexchange.com/questions/354553/awk-repetition-n-is-not-working
      |
      | gawk であれば --posix または POSIXLY_CORRECT=always を指定すれば良いそう
      | だが、どの道他の実装では使う事ができない。という事を考えると一概に使えな
      | いと思っておくべきである。
      |
      | * 更に 0xHHHH もエラーメッセージなく勝手に 0 と解釈されていた。
      |
      | * また printf("%s\0",line) は普通に \0 が null-terminated と見做されて 0
      |   は出力されない。これは gawk の振る舞いの方が特殊である様に思われる。
      |   printf("%s%c", line, 0) で出力する事にする。
      |
      | * mawk は /[0-9][0-9]?[0-9]?/ としても /[0-9][0-9]?/ になってしまう。

      色々互換性の問題を修正した。見た感じだと nawk も mawk も gawk よりは高速
      である。余り気にしなくても良さそうである。

    ? 更に変な内容がなければもっと高速化できるのではないだろうか。

      例えば全て []="..." の形式だったならば、最初に " []=" を全て他と当たらな
      い様な物 (例えば ^A) に変換して、その後で "" の中身の unescape 処理をして
      から分割すれば良いのではないか。unescape は \\ -> ^B, \" -> ", \$ -> $,
      \` -> `, ^B -> \ とすれば良い。

    取り敢えず新しく実装した ble/util/{read,write}array を使う様に変更してみた。

  * main: ble-reload するとプロンプトの計算の箇所で問題が生じる [#D1521]

    これは当初 nawk のテスト時に気がついた問題なので nawk に関連して生じている
    のかと考えたが、gawk で試しても同様の問題が生じた。

    遡って調べてみると実は 82c5ece で発生する様になった問題の様である。
    取り敢えず bleopt/check-all でエラーが発生しているのかもしれない。
    →これが原因だった。これは独立な問題として commit する事にする。

  * set -o posix の時、ユーザーが read -e を呼び出すと [#D1520]
    何にも動かなくなるのではないか。

    a 然し、read -e 自体が posix の範囲外なので仕方がないという見方もできる。

    b 或いは、set -o posix の時には set -o emacs / set -o vi の切り替えを利用して
      read が使える様に調整するという事も原理的には可能である。その場合には実際に
      bind する対象の keymap が反転するので大幅な改修が必要かもしれない。

      x 然し、vi mode 及び emacs mode に切り替える機能も存在した筈である。これを
        呼び出されると結局 ble.sh の管理下の keymap が前に出てきて問題になる。
        read の中から呼び出された事を検出してどうにかその場で取り繕う事は可能だろ
        うか。

    c 別の方法で read が呼び出される瞬間を検出できないだろうか。或いは read -e に
      よって最初に widget が呼び出された瞬間に POSIX を始めとする様々の設定を回復
      する? その場合には C-c で read をキャンセルした場合にまた元に戻す事を忘れて
      はならない。

    d ユーザーがコマンドを実行する度に realine 設定を完全 unbind して、終わったら
      再度 bind し直す。でも、これは文法エラー等によってコマンド実行が中断された
      時に、ble.sh session に復帰せずに通常の readline の状態に落ちてしまう。

    →どうやら set -o posix でも本来の意味を取り戻す builtin とそうでない
    builtin が存在する様で、read の場合には set -o poix であっても関数が定義さ
    れていればそちらが呼び出される様である。なので気にしなくて良い。本当に問題
    が起こるのは builtin read -e が実行された時になるが、これは元から動いていな
    かった。

    実の所、builtin read -e に対しても制御を全く失う様な事態にならない様にした
    いが、それはまた別に考えた方が良いのでは? と思ったが、此処での考察はその場
    合にも同様に適用できる→別項目に残す事にした。

2021-04-30

  * 2021-03-21 set -o posix してから source ble.sh すると失敗する [#D1519]

    先に source ble.sh してから set -o posix する分には即座に問題は起こらない。
    然し ble-attach に失敗するという可能性は存在する。うーん。
    関数を新しく定義するという事をしなければ特に問題は発生しない?

    POSIX モードに対する処理は関数の外で実行する事にした。同時に順序を変えて一
    番最初に POSIX モードを ble.sh 内部状態として調整する事にする。

    ? done: 実のところ、enter/leave でユーザーの設定した同名の alias/function
      を保存し、それからまた後で復元するという事も原理的には可能なのではないか

      …と思ったが、果たして其処までの事をする必要はあるだろうか。保存の為にま
      た色々コマンドを走らせなければならなくなるが重くはならないだろうか。と思っ
      たが、alias ... declare -pf ... を呼び出すだけなので実はそんなに処理とし
      て重い訳ではない。問題は alias や declare が勝手に置き換えられていた時に
      ちゃんと動作するのかという話である。

      結局実装する事にした。

    ? done: 現在二段階に分けて unset -f しているが POSIXLY_CORRECT しているのだ
      から、builtin も unset も本来の意味を取り戻している筈で、それならば一回の
      unset -f で十分なのではないか。

    x fixed: 現在 set -o posix, +o posix を使ってモードを切り替えているが、これ
      は setを上書きされていた場合に使えない。直接変数に代入するべきである。更
      に言うと、local ... も使えるとは限らない。local が上書きされているかもし
      れないから。という事を考えると、これも直接グローバル変数の値を変数代入で
      変更するべきである。

      →これは確認した所、元から殆どその様になっていた。新しく追加したコードだ
      けで set を使っていたので、これを全て POSIXLY_CORRECT=y 及び \builtin
      unset -v POSIXLY_CORRECT に書き換えた。また、unset は -o posix の時にだけ
      実行する様に変更した。-o posix の時には \builtin unset は本来の意味で解釈
      される事が保証されているからである。

      ? と思ったが、unset を使って解除する場合には見えている一番上の
        POSIXLY_CORRECT が解除されるだけで、更に呼び出し元のスコープで定義され
        ている POSIXLY_CORRECT が存在した場合には依然として set -o posix のまま
        になるのではないか。

        $ f1() { local POSIXLY_CORRECT=y; f2; echo f1:$SHELLOPTS; }
        $ f2() { local POSIXLY_CORRECT=y; f3; echo f2:$SHELLOPTS; }
        $ f3() { set +o posix; }
        $ f1
        $ f2

        試して見た所、unset POSIXLY_CORRECT だとやはり、更にその上の階層の状態
        が見える様になるだけである。そして、set +o posix も全く同じに作用すると
        いう事が分かった。

        但し考えて見るに ble.sh はトップレベルで動いていてその途中で
        POSIXLY_CORRECT を設定して動作するという事もないので、unset が途中の関
        数スコープの POSIXLY_CORRECT に当たるという事もない。従って、普通に
        unset -v POSIXLY_CORRECT を一回実行するだけで問題ない。

        何か問題が起こるとすれば、ble-attach もしくは source ble.sh を実行した
        時に複数の local POSIXLY_CORRECT=y の中で実行された時である。然し、この
        場合にはどうにも対策の仕様がない。unset -v を繰り返し呼び出す事によって
        POSIXLY_CORRECT を解除する事はできるが、然しこれを実行すると呼び出し元
        で実行した local POSIXLY_CORRECT の意図を壊してしまい呼び出し元で問題が
        生じる可能性がある。

        実はこの事まで考えると set +o posix や set -o posix で POSIX 状態を操作
        するのは不味いのではないかという気がする。呼び出し元で設定した
        POSIXLY_CORRECT の動作を破壊してしまう。

    x posix にしていても eval の中の alias 置換を防ぐ事はできないのでは。
      alias 展開をオプションで無効にする必要があるのではないか。
      そして alias は割とあらゆる箇所で影響が出る。
      これは大丈夫だろうと思っている if や [[ 等も対象である。

      | a builtin に関しては危ない所を全て \builtin 等に書き換えてしまえば問題ない。
      |
      |   grc '(^|[[:space:];|&('\''"])builtin\b' --exclude={wiki,ext,memo}
      |
      | b 或いは shopt expand_aliases を off にして処理を行う? うーん。ble.sh の内
      |   部では expand_aliases を off にするのが良い気がしてきた。
      |
      | c と思ったが ble.sh に影響を与える様な alias だけを off にすれば良いので
      |   あって全ての alias を off にする必要性もない。そして ble.sh に影響を与
      |   える様な物に関しては、ble.sh の処理中には unalias してしまっている筈な
      |   ので殆どの場合は大丈夫な筈なのである。
      |
      |   ユーザー実行環境で ble.sh 関数が呼び出されて、その ble.sh の中で eval
      |   をした時に alias 置換が発生するという状況は考えられるが、まあ、その様な
      |   場合にまで気を配る必要は今の所ないと考えている。
      |
      |   取り敢えず、adjust-builtin-wrappers が呼び出される所までは \builtin の
      |   様にして escape する必要がある。後、adjust-builtin-wrappers 自体の処理
      |   でも対策が必要になる。
      |
      |   * 特に、adjust-builtin-wrappers の中で eval を実行しているが、其処で
      |     alias 展開が起こると問題である。特に ble/util/assign によって実行され
      |     る eval が問題になるのではないか。
      |
      |   後、ble/util/assign の中でも

      結局 expand_aliases を off にする事にした。ble.sh を読み込んで
      expand_aliases を無効にする迄の部分を \builtin の様に quote すれば良い。
      一旦関数を定義してしまえば実行時に書き換わる事はないので、気にしなくて良
      い。気にするべきは eval で実行される文字列 (新しく解析される文字列) であ
      る。

    * resolved: 保存・復元の時に sed を使っているがこれを置き換えられないか。

      | これは ble.sh 読み込み時の最初の最初の部分なので sed が PATH に含まれてい
      | ない可能性も考える必要がある。sed の代わりに使える物はないだろうか。
      |
      | a 例えば extglob を有効にしてパラメータ展開で置換を実行するというのは一つ
      |   の手である。
      |
      |   この方法だと一回 type の出力を変数に格納する必要がある。従って、余分に
      |   $(subshell) を実行する事になってしまって非効率的である。と思ったが、パ
      |   イプにする事によっても subshell が 2 つ余分に生成されるのだから、$() に
      |   しても特に overhead にはならない気がする。
      |
      |   然し extglob を on/off するのはそれはそれでまた面倒である。
      |
      | b どうにかして sed の binary を見つけてそれを先に ble/bin/sed に登録して
      |   しまう? 然し、その為に色々の処理が必要で、その処理を不明な環境で安全に
      |   実行するのもまた面倒である。
      |
      | 後、最初の実行時には注意深い実装が必要かもしれないが、一旦初期化が終わっ
      | てしまえば、ble/bin/sed を使っても良いし、ble/util/assign も軽い実装を利
      | 用する事ができる。いっその事、初めから初期化前用の実装と、初期化後用の実
      | 装に分けても良い気がする。

      汚いが extglob で処理する事にした。

      実際に動かしてみると bash-3.0 で滅茶苦茶遅い。何故だろうか。bash-3.1 では
      特に問題は起きていない。調べてみた所、+([[:lower:]]) とすると遅い。
      +([a-z]) は遅くない。直接書く様に修正した。

    * 現在の待避コードの順序について考える。

      posix だとそもそも ble/* という関数自体定義する事ができない。一旦関数さえ
      定義できてしまえば関数呼び出し自体はできる。

      FUNCNEST の設定。関数定義はできるが関数呼び出しができないという状態だと駄
      目なので。

    * 一応各 builtin について動作確認をしておく。

      builtin, unset, eval はOK
      return, break, continue, local もOK

      % declare は駄目だった。というのも関数定義を抽出するのに使っているから。set
      % -o posix していても declare は回復できないのだという事。うーん。つまり
      % builtin か declare のどちらかは必ず先に unset しないと動かないという事。
      %
      % local の方を諦める事にした。local を上書きしてもローカルに変数が作られる
      % 事になる為、期待した効果を再現する事は不可能になる。なので敢えて上書きし
      % ようという人はいないだろう。declare だと機能を勘違いしている人が上書きし
      % ている可能性がある。また最初の local POSIXLY_CORRECT が効果を失うのも避け
      % たい。

      やはり他にも色々動かない物があるので local を諦めるだけでは済まない。やは
      り builtin の復元を諦める事にする。そもそも builtin を置き換えようとする
      事自体が異常である。何か一つ置き換えを禁止するのだとしたら builtin にする
      のが自然ではある。

      x fixed: : は保存できていない。もしかすると set -o posix の時には declare
        -pf で定義を出力できないという事? 確かめてみたが別にそういう事はない様
        である。という事は逆に定義する時に失敗しているという可能性?

    x fixed: ble-reload 後に ble-detach を実行すると以下のメッセージが出る。

      | bash: builtin: is: シェルのビルトイン関数ではありません
      | bash: enable: is: シェルのビルトイン関数ではありません
      | bash: enable: a: シェルのビルトイン関数ではありません
      | bash: enable: shell: シェルのビルトイン関数ではありません
      | bash: unalias: is: 見つかりません
      | bash: unalias: a: 見つかりません
      | bash: unalias: shell: 見つかりません
      | bash: unalias: builtin: 見つかりません
      | bash: return: is: 数字の引数が必要です

      これを見るに何らかのエラーメッセージがコマンドとして実行されている?

      然し、ble-reload の後に履歴が可笑しくなっているのも、ble-detach の後に変
      な状態になっているのも治っていない。これらはまた別の問題という事か。

      どうも _ble_bash が変な値になっていて、それによって別のコードが呼び出され
      ていたという事。そしてそのコードはちゃんとテストされていなかったので元々
      バグを持っていて、それが発現していたという事の様である。そもそもそのコー
      ドは set -o posix でも動く関数定義取得の為に declare -pf と type を切り替
      えて使っていた物だったが、そもそも関数名が通常の識別子である限りは
      declare -f を常に使っていれば特に問題はない。基本的には declare -f を使っ
      て、: だけは bash の version で切り替える事にした。

      以前使っていた declare -pf / type の切り替えによるコードは以下に残して置
      く。

      | if ((_ble_bash>=40300)); then
      |   builtin local defs
      |   ble/base/adjust-builtin-wrappers/.assign '
      |     \builtin declare -pf "${builtins1[@]}" :
      |     \builtin alias "${builtins1[@]}" "${keywords1[@]}" :'
      | else
      |   builtin local fname
      |   ble/base/adjust-builtin-wrappers/.assign '
      |     \builtin declare -pf "${builtins1[@]}"
      |     \builtin alias "${builtins1[@]}" "${keywords1[@]}" :'
      |   defs=$'\n'$defs
      |
      |   # Note: bash-3.0 だと何故か extglob +([]) の中で [:alnum:] や [:lower:]
      |   #   を使うと滅茶苦茶遅い。何れにしても locale 依存になるのは避けたいので、
      |   #   直接 a-z と書くのが良い。
      |   builtin local pattern=$'\n+([][{}:a-z]) is a function\n'
      |   if builtin shopt -q extglob; then
      |     defs=${defs//$pattern/$'\n'}
      |   else
      |     builtin shopt -s extglob
      |     defs=${defs//$pattern/$'\n'}
      |     builtin shopt -u extglob
      |   fi
      | fi

      さて、これで問題は "何故 _ble_bash が消えて無くなるのか" という事に集約さ
      れる。(履歴の振る舞いが変になるのも古い bash の history -s の振る舞いが変
      だという事と関係しているのだろう。また、C-d の反応が悪いのも関係している
      だろう。)

      実際に _ble_bash が空になっているという事が確認できた。

      そしてそれは何故かというと ble/base/unload-for-reload で _ble_bash を
      unset しているのが原因だった。つまり、unload-for-reload を呼び出す迄は
      _ble_bash 等の初期化は遅延した方が良いという事なのだろう。builtin に対す
      る対策は _ble_bash には頼らずに version 判定するべきなのである。→結局ど
      の bash version でも動作する様に常に type を使って関数定義を得る事にした。

    x fixed: ble-reload すると何故か履歴項目が最後の項目に対する追記の様になっ
      てしまっている。ble-reload ではなくて source ble.sh しても同様の問題が発
      生する。bash --rcfile out/ble.sh としても発生している事を考えると mshex
      等の他の設定との組み合わせで起こっている問題ではなくてそれ自体として発生
      している問題である。

      遡って見ると #D1519 の問題であるという事が判明した。これは #D1519 の下で
      議論するべきであろう。然し、そうだとしても何が原因になっているのかは謎で
      ある。構文着色も動いている様に見えて何だか不思議な動作をしている。原因を
      特定する為に幾つか振る舞いを変えて試してみる必要がある。

      * 保存していた builtins を復元しない様に変更したが特に変化はない。依然と
        して変な振る舞いを続けている。

      * adjust/restore-builtin-wrappers を使わない様にしても変な振る舞いを続け
        ている。

      うーん。コードを見ても怪しい所は見つからない。明らかに機能不全を起こして
      いる箇所があるのだから其処を手掛かりに原因を探る方が懸命である様に思われ
      る。

      ble-detach で発生するエラーについて調べようとしたが原因の設定では再現しな
      い様である。再現する為の条件があるという事か? 或いは ble-detach で発生す
      るエラーに関しては実は adjust/restore-builtin-wrappers が関係しているとい
      う事だろうか。

      これの原因は前の項目で判明した _ble_bash の消滅だという事が分かった。一緒
      に治った。

2021-04-28

  * blerc にユーザーが使いそうな ble-bind を載せても良いのではないか (motivated by Alyetama) [#D1518]

    ble-bind -f up 'history-search-backward immediate-accept'
    ble-bind -f down 'history-search-forward immediate-accept'

    やその他の Vim の説明に書いた ble-bind など。
    magic-space の効果をなくす為の ble-bind も。

  * nsearch の再設計について (motivated by Alyetama, rashil2000, carv-silva) [#D1517]
    https://github.com/akinomyoga/ble.sh/issues/101
    https://github.com/akinomyoga/ble.sh/issues/80

    一旦は bleopt オプションを追加すると書いたが、ここは widget の引数として
    opts を受け取る様にして、readline settings を読み取る時の振る舞いは適当に
    Bash に合わせる様にする方が良いのではないかという気がする。或いは、多少はユー
    ザーが期待する様な振る舞いに調整しても良い。

    * 実際に history 内部を移動するかどうか。現在の振る舞いは history の中から
      "load" するという振る舞いになっているが、本当は isearch と同様に history
      の内部を "移動" するという振る舞いの方が分かりやすい。

      action=load
      action=move

    * 空文字列の時に唯の行移動に fallback するかどうか。
    * 空文字列の時に前回と同じ文字列で検索するという手もある。

      empty=line-move
      empty=graphical-line-move
      empty=logical-line-move
      empty=history-move
      empty=previous-search

      空文字で検索する事はない様に変更する。

    * カーソル位置を何処に置くか。
      point=end
      point=begin
      point=preserve

    * nsearch status を表示するかどうか。
      hide-status
      % hide-status-on-empty

    * 下を押し続けた時にまた元の状態に戻る様にする。
      これはオプションにしなくて良い。

    C-x p 等の時には以下の設定で実行する。

      action=move:point=preserve:empty=line-move

    readline function 経由での呼び出しではできるだけ Bash の振る舞いを再現する?

      action=load:point=preserve:empty=line-move

      % うーん。実は Bash も空文字列の検索に対しては特別の挙動をしている様だ。
      % つまり、今まで議論で一貫性のある振る舞いについて考えていたが、これは既
      % に Bash が自然な形で破っているので Bash に従うべきなのである。

      →改めて Bash を試してみた所、やはり単純に行を移動しているだけではない様
      に見える。カーソルを行末に移動しているが、それによって次の検索内容が変化
      するという訳でもない。実際、ble.sh の実装に於いて、空文字列に対して単に行
      移動の widget に委譲してしまうと、次の up の呼び出しの時に新しくロードし
      た文字列全体に対して再度検索が走ってしまう。

    point=end をリクエストされたが正直これはデフォルトにしなくて良い。
    変更したければ自分で nsearch に point=end を指定して ble-bind して貰う。

    色々考えると実は hide-status-on-empty は実装しなくても良いのではないかとい
    う気がしてきた。理由付けとしては空文字列検索を行うオプションはそもそも存在
    しないから。というか、hide-status 自体表示する必要がないのかもしれないとも
    思った。然し、一応実装しても良い気がする。


    [疑問]

    * ok: isearch に対する疑問。現在履歴位置の古い内容に一致しないのか。

      % よく分からないのは現在履歴項目を遡った状態であった時に、現在の履歴の内容
      % に一致したらどうするのかということである。うーん。isearch はちゃんと遡っ
      % ている時にはその内容に一致している気がする。が、それは何でかというと他の
      % 場所に周遊している時にはその時の編集している内容は履歴に反映させている為
      % である。此処での疑問は、cyclic で検索している時に、現在の編集内容では消え
      % ているが、現在位置の履歴に残っている文字列に一致する場合に何が起こるのか
      % という事
      %
      % →うーん。試そうとしたが isearch で入力している内に最初の方に入力した文字
      %   に一致する項目にジャンプするので実の所、この様な状況が発生する事は滅多
      %   にない。
      %
      % しかし原理的には現在位置の古い内容に一致してしまう事がある気がする。これ
      % を回避するには検索を開始する前に現在の編集内容を履歴に反映させておくか、
      % 或いは、cyclic で検索するにしても現在位置には一致しないようにしておくか。
      % 現在の実装ではどちらかになっているのだろうか。
      %
      % コードを確認した所、気になる部分を見つけた。#D1025 で同様の問題があって部
      % 分的な修正が行われた様に見える。何れにしても基本的には isearch は非
      % cyclic な検索になっているので、そもそも巡回して現在の位置が検索対象になる
      % 事がないので気にしなくて良かった。

      →isearch は現在履歴位置については自分でテストして、それ以外については非
      cyclic な検索で次の項目から検索する様にしているので、現在履歴位置の古い内
      容に一致する事はない。

    [実装]

    * ok: 先ず初めに down を続けた後に元のコマンドライン文字列を回復する機能に
      ついて考える。

      ? そもそも既に history の途中に移動している状態で nsearch を始めた時はど
        うなるのか? →変な振る舞いになっている。#1 から更に down を押したら元に
        戻るべきなのに、改めて上方向に検索して #2 という状態になっている。更に
        付け加えるならば "echo" という文字列には一致しない。

      うーん。元のコマンドライン文字列に戻った時に、nsearch 状態が継続している
      とするか、或いは、nsearch 状態から抜けるか。again または input の時には、
      元のコマンドライン文字列に戻ってしまうのは変である。元のコマンドライン文
      字列に必ずしも一致するとは限らないので。(然し、逆に言えば元のコマンドライ
      ン文字列に一致する場合にはどの様に動作するのが自然だろうか?)

      | ? 現在のコマンド文字列から検索対象を拾った場合には、元の位置まで戻って来
      |   たら nsearch 状態を抜けるのは自然である。と思ったが、それはそれで変であ
      |   る。例えば C-x up で検索を初めて、その後は up/down で移動していた時に突
      |   如として nsearch から抜けてしまうと不便である。という事を考えると
      |   nsearch 状態から抜けるというのは変な話である。
      |
      |   そういう観点から考えると、やはり勝手に nsearch 状態から抜けるのではなく
      |   て、現在文字列に一致している状態にするのが自然である。一方で、stack の
      |   先頭に記録しているのは、現在の一致状態ではなくて、nsearch 開始前の状態
      |   である。
      |
      |   例えば、現在のコマンドラインから検索対象を拾った場合に
      |   は、_ble_edit_nsearch_stack に初めから余分に record を追加しておくのが
      |   良いのではないだろうか。つまり、検索開始時に最初に
      |   _ble_edit_nsearch_stack に検索開始前の状態を保存すると共に、カーソル位
      |   置を point=* で指定したのに対応する位置に初期化してしまう。
      |
      |   と思ったが空文字列で empty=previous-search によって検索開始した時には現
      |   在のコマンドラインに一致しているとは限らない。など考えると明示的に現在
      |   のコマンドラインに一致するかどうかはチェックするべきである。
      |
      | ? input/again の時に元のコマンドライン文字列に一致する場合にどの様に取り
      |   扱うか。これは action=load にしているか action=goto にしているかでも振
      |   る舞いを変えるべきかもしれない。
      |
      |   →input/again でなくても現在のコマンドラインに一致しない可能性があるの
      |   で、これは input/again かどうかの問題としてではなくて、検索が初期コマン
      |   ドライン文字列に一致するかどうかの問題として捕らえるべきである。


      検索開始時点で現在の状態は _ble_edit_nsearch_stack に記録しておく。次に現
      在の行に対して一致するかどうかをチェックして、一致していたらそれも記録に
      残す。そしてその次の一致を調べる。

      うーん。何だか分からなくなってきた。もし現在のコマンドラインだけに一致す
      る時に nsearch をそもそも開始するべきかどうか? という話にもなる。現在の実
      装を確認してみた所、一応 nsearch は開始する様だ。然し、highlight も何も起
      こらない。うーん。これは実は highlight しても良いのではないだろうかという
      気がする。

      じゃあ、input 等で指定された検索対象が現在の内容にも履歴にも見つからない
      場合にはどの様に振る舞うべきなのだろうか。この場合には、選択範囲も何もな
      い状態で nsearch に入るという事の気がする。

      振る舞いとしては (1) 何処にも一致しない場合には現在の内容から少しも動かな
      いが、それでも nsearch 状態には入る。(2) 現在位置に一致して他に一致しない
      場合は、現在位置に一致した状態で固定。 (3) 現在位置にも他の位置にも一致す
      る場合には、他の最初に見つかった位置に移動するが down 等で現在位置に戻っ
      てくる事ができる。(4) 現在位置に一致せず他の位置に一致する場合には、他の
      最初の位置に移動するが down 等で現在位置に戻ってくる事はできない。という
      ので良い気がする。

      この振る舞いにするのであれば別に難しい事はない気がする。単に最初に現在位
      置に一致するかどうかをテストして、一致していたら stack に記録して状態を書
      き換えれば良いのである。

      実装を確認した感じでは現在のコマンドラインの内容は検索で参照しないし、中
      で実際に呼び出している検索処理である isearch も履歴の内容しか参照していな
      い。つまり、現在のコマンドラインの内容に対する一致は呼び出し元でちゃんと
      処理するという前提になっている。という事を考えると、この実装でも現在の内
      容に対する一致は呼び出し元でチェックすれば良い。というより古い内容に一致
      しない様に現在位置の一致は自前でする必要がある。

    * ok: 実装を確認した所、既に opts は受け取る様になっていた。これに色々とオ
      プションを追加すれば良い。

    * done: 空文字列の振る舞いとして単に行移動するだけの実装だと再検索で問題が
      起こるという事が判明した。これの対処方法は二種類ある。

      a 一つは行移動した時に必ず行頭に移動するという事。但し、その場合には検索
        文字列は改行を含まない物として、行頭から抽出するという様に振る舞いを変
        えなければならない。

        問題が起こるのはカーソル位置から検索文字列を取り出す時だけである。でも
        一貫性を考えれば、別に常に先頭に移動するという実装で問題ない気がする。

      b もうひとつの方法はやはり hide-status-on-empty で対処するという事。或い
        は empty=hide-status で良いのかもしれない。

      取り敢えず二種類をオプションで指定できる様にした。

    * done: opts hide-status

    * resolved: 検索対象の文字列を行頭迄にして見たが、実際の検索にはコマンドラ
      インの一番最初からの一致しか考えていないので、自分自身に一致することがな
      い。これは何だか変な気がする。或いは、現在行だけ置換するという手も考えら
      れなくもないが、それはそれで機能として複雑すぎる気がする。やはり、検索対
      象はコマンドライン先頭から抽出する事にして、更に、空文字列 up down の移動
      後もコマンドライン先頭に移動するべきである。という事を考えると、line-move
      というのは変である。history-move しか nsearch とは相容れない気がする。

      →line-move は機能として削除する事にする。

    x fixed: 今気づいたのだが read -e が動かなくなっている。どうも 856cec2 がい
      けない気がする。と思って確認したが別に read -e が動かなくなる様な要因はな
      い気がする。或いはもっと最近の修正が原因だろうか。どうも調べてみた所、最
      新の ble-bind --cursor の commit によって動かなくなっている様である。何故
      だろうか。refactoring で変更漏れがあっただろうか。

      refactoring 関連を確認してみたがぱっと見た感じでは変更漏れはない気がする。
      だとすると何が変わったのだろうか。何処で失敗しているのか read の中に入っ
      て行くべきだろうか。

      →分かった。これは ble/decode/keymap/push が 1 を返す様になってしまってい
      たのが原因だった。push の一番最後の行に [[ $cursor ]] && do something を
      入れた所為で、カーソルが設定されていない keymap/push が失敗する様になって
      しまっていた。カーソルの設定に関係なく 0 を返す様に修正した。

    x fixed: C-x up/down で移動する内に履歴が書き換わっている気がする。これは
      goto と load が入り混じっているからの気がする。ちゃんとその辺りを修正して
      からテストするべきである。

    x 下方向に検索できない状態になっている。というか goto-match で常に backward
      になっているのは変である。

      そもそも検索開始位置は現在の履歴位置とするか或いは末端とするのかという問
      題がある→確認してみた所、一応検索開始位置は現在の履歴位置になっている様
      である。

      ? 検索方向を反転する時に古い履歴内容に一致してしまうのではないか。

        検索開始位置の履歴項目には含まれていた単語を、編集でそれを消した後に検
        索すると、最初の一致が当初の検索方向に離れた箇所で起こる。その時に検索
        方向を反転させようとすると、過去の履歴に一致してしまう可能性がある。

        この時にはどの様に対処すれば良いか。先ず、検索方向の反転は stack の内容
        が1個しか残っていない時に起こる筈である。この時には、検索再開位置は現在
        項目か或いは検索開始項目でより検索再開方向に進んだ物を採用する必要がある。

    * 既定の動作をどの様にするのが良いのかよく分からなくなってきた。そもそも何
      故 nsearch という表示を隠す必要があるのかという事。

      特にカーソル位置を末尾に移動するという設定と組み合わせると、連続して同じ
      コマンドを実行した時には "カーソル前の文字列を検索する" という動作は最初
      の一回だけであり、それ以降には最初の一回で使った検索文字列を繰り返し使う
      という動作になっている。つまり、連続で実行している時には通常と異なる状態
      になっているというのは明らかである。という事を考えるとその事が分かる様な
      表示が必要になる筈である。単に上下で履歴内部を移動するのとは訳が違うので
      ある。

      zsh の振る舞いを調べてみた所、別にカーソル位置を変な所に移動するという事
      はしていない。と思ったが、どうやら history-search-end というモジュールが
      あって、それに history-beginning-search-backward-end 等の様な、末尾にカー
      ソルを移動する様な同じ機能の物が存在する様である。
      https://unix.stackexchange.com/a/97844/121088

      取り敢えず C-x up 等によって使える物については自分の思う様に実装する事に
      する。先ず action=load ではなくて移動。nsearch status は表示する。point
      は現在位置。explicit に呼び出しているのだから空文字列でも普通に nsearch
      に入る。

      readline 経由で up に割り当てている時には。

      a やはり2回 RET して実行されるというのは、保持する。そうすると nsearch
        status も表示して置くのが良い。Bash の元々の動作と思うと action=load は
        保持した方が良い様な気もする。空文字列の時に空文字列で検索するか、とい
        うと微妙。うーん。空文字列の時は history-move が良い気がする。うーん。

      b 或いは bash と完全に同一の動作を目指すのであれば、
        action=load:hide-status:immediate-accept 等と指定すれば良い。が、それは
        それでユーザーが便利にならない。ble.sh の便利さを押し出していきたいので
        あればやはり便利な動作を既定の動作とするのが良い気がする

        hide-status:immediate-accept:action=load:empty=empty-search:point=end

    [Note]

    * 空文字列移動: 行指向の通常移動に fallback する選択肢を考えたが、コマンド
      ラインの途中に移動すると、カーソル前の文字列が非空になるので、続けて移動
      しようとすると予期しない nsearch が始まってしまう。代わりに常に行頭に移動
      して検索文字列を行頭から抽出する様にすると、今度は自分自身に一致しなくな
      るので動作として分かりにくい。

    * C-x up で始めた時は empty=previous-search で良い気がする。うーん。ユーザー
      に入力させた時には空文字列を指定したのに前の文字列で検索が始まったら変で
      ある。なので既定の動作を previous-search にするのは変である。然し、コマン
      ドラインから検索文字列を抽出した時にだけ empty=previous-search にするのも
      分かりにくい気がする。

    [修正]

    x fixed: 描画で一番最後の文字が欠けてしまう。何らかの座標計算が間違っている
      という事だろうか。

      どうも point=end を指定すると振る舞いがおかしくなる。然し、可笑しな事が起
      こる余地などない様な気がする。或いは、_ble_edit_ind の値を勝手に此処では
      変えてはいけないという事なのか、或いは、${#_ble_edit_str} の値がここでは
      大きな値になっているか。

      どうも get-selection によって発生している様な気もする。もしかして空の
      selection range を指定すると発生する現象なのだろうか。試してみると、空の
      range の数だけカーソル位置がずれるという事が分かった。

      分かった。buffer を構築する時に空 range があると "SGR${buff[@]::0}" になっ
      て、これが 0 要素に展開されれば良いが、SGR がある為に 1 要素に展開されて
      しまって、結果として buffer の要素数が増えてしまっているというのが原因で
      あった。そもそも空 range については要素の追加自体を実行しないという形で対
      処する事にした。

      それとは別に空文字列で検索している時には _ble_edit_mark_active を設定する
      必要もない。判定条件を見たら、_ble_edit_ind==end だった時の条件がそのまま
      になっていたのが悪かった。これも修正した。

    x fixed: 最新行が空文字列の時、最新行に空文字列検索で移動できない。これは
      isearch の実装の問題だろうか。或いは最新行が空文字列の時は移動しても登録
      されないという事なのか。或いは isearch の検索範囲の判定で有限文字列化空文
      字列かで振る舞いが変わるという事か。

      →分かった。最新行が空文字列の時に移動しても登録されない事態になっていた。
      dirty かどうかの判定で文字列比較を行って同じであれば処理をスキップしてい
      たが、そもそも登録されていない時にも "空文字列" になってしまうので、"空文
      字列" を登録しようとしても登録されずに終わってしまうというバグであった。
      これは修正した。

    * done: wiki: widget についての説明を書く。これは rasheil2000 への説明を調整して
      乗せれば良い→書いた。

    * done: wiki: Q&A から説明へのリンクを書く→書いた。

    * done: wiki/Q&A: リンクが間違っている物があった→修正した。

    * done: wiki: key bindings について RET, TAB, ESC 等についての説明をちゃん
      と書く。
      https://github.com/akinomyoga/ble.sh/issues/101#issuecomment-828340592

    * done: blerc に何か書いても良いのかもしれない? 或いは Alyetama の言う様に
      wizardを作って其処から設定を選択できる様にする。取り敢えず今は blerc には
      書かない事にする→やはり書いた。

2021-04-26

  * util: 既定の cursor-shape の時には DECSCUSR は出力しない (motivated by jmederosalvarado) [#D1516]
    https://github.com/akinomyoga/ble.sh/issues/95

    % cursor shape を変更しない場合には external/internal の切り替えでも
    % DECSCUSR は出力しない様にするオプション?
    →オプションではなく固定でその様な動作に変更した。

    そもそもその様な実装になっていると思っていたが…。恐らく一番最初の状態が
    unknown になっているのが原因? もし最初の状態が 0 になっていたとして emacs
    mode の場合にはそのまま DECSCUSR が全く呼び出されずに済んだ可能性はあったろ
    うか。

    →実際に試しに最初の状態を unknown から 0 に変更した所、ちゃんと最初のカー
    ソル状態が保持される様になった。

    ? no: 然し、コマンドを実行した後にカーソル形状を元に戻すという操作が強制で
      入っている可能性はあるだろうか?

      →確認してみたが、特に external/internal は意識していなくて、また外部コマ
      ンドがカーソル形状を変化させてしまうという可能性は考えていない。外部コマ
      ンドが停止する時にカーソル形状を戻しておくべきであるという前提に基づいて
      いるのであろう。

      取り敢えずその前提は仮定する事にする。

    条件判定を変更したが、実は初めから値を 0 に設定しておけば同じ動作になるので
    はないだろうか…。此処で実装するべきは空文字列だった時と 0 の区別ではないか。
    と思ったが、0 を意図してブロックとして指定するユーザーがいるかも怪しい。ブ
    ロックであれば 1 を指定すれば良いからである。

    諸々考えると単に初期値を unknown から 0 にすれば良いという気がする。

  * term/edit: keymap 毎のカーソル形状 (motivated by jmederosalvarado) [#D1515]
    https://github.com/akinomyoga/ble.sh/issues/95

    現在の実装では auto-complete, menu 等の mini mode 等でカーソル形状は変わら
    ないと仮定して、emacs, vi_?map の間の変更だけでカーソル形状の再設定を行って
    いる。然し、今後 mini mode におけるカーソル形状の変更も考えると、もっと統一
    的にカーソル形状を管理する必要がある気がする。

    例えば keymap 毎にカーソル形状を設定できる様にして、keymap の切替時に設定さ
    れたカーソル形状に変更する様にする。指定した keymap にカーソル形状が設定さ
    れていない場合は、keymap stack 内の前の keymap を参照する。

    * この時、既存のカーソル形状の設定はどうするのか。

      現在の vi におけるカーソル形状の設定: imap,nmap,omap,xmap,smap,cmap
      ... これらの設定に応じてカーソル形状を変化させる様になっている。然し、実
      際の実装ではこれらの map は参照せずに設定している気がする… と思ったが確
      認したらちゃんと keymap を参照してカーソルを切り替えていた。

      設定の方法は bleopt keymap_vi_?map_cursor を介して行っているが、もし
      keymap 毎にカーソル形状を管理する様にするという事だと、(1) 既存の設定は翻
      訳しなければならない (2) 新しい方法に移行する様に情報を提示する必要がある。

      或いは、bleopt keymap_KEYMAP_cursor を一般に使える様にするという手もある
      が、これはこれで bleopt 内に名称の構造を作成する事になるので避けたい。

    * emacs に対応する。

    ? ok: cursor-state を decode.sh から参照しても依存関係的に問題ない
      か。cursor-state は何処で実装されているか? → util.sh で定義され
      ている様なので大丈夫。

    [変更]

    * done: 設定の変数名を決める ... _ble_decode_KEYMAP_kmap_cursor

      取り敢えずは bleopt_keymap_KEYMAP_cursor を参照して実装する? と思ったが後
      の調整が色々面倒になりそうなので、もうこの時点で変数名も決めてしまう事に
      する。

      元々の keymap の設定は _ble_decode_KEYMAP_kmap_@ に保持している。同様に
      _ble_decode_KEYMAP_kmap_cursor を使おうと考えたが、これだと dump/save で
      記録されてしまうので微妙である。また、どういう設定コマンドで設定するべき
      かという問題もある。

      a ble-bind を使って設定を行う? と思っても直感的に変である。例えば
        ble-bind -m KEYMAP --cursor 5 とか設定する事になる。うーん。そんなに変
        ではないかもしれない?

        後、これの呼び出しも遅延する事にすれば実は dump で記録されてしまう問題
        も気にしなくて良い気がする。KEYMAP に紐付いているという事を考えても、直
        観的に特に問題はない様な気もしてきた。

        この場合には ble-bind -P で出力する時にカーソル設定も出力する様にする必
        要がある。

      a 新しくカーソル設定だけの為のコマンドを用意する? というのもユーザーが覚
        える事が増えるだけで余り良くない。

      c 或いはやはり bleopt keymap_cursor_KEYMAP という感じにして、多少構造化さ
        れた名前の bleopt に変更するに留めるか。

      今は取り敢えず a の方針で考える事にする。

    * done: ble-bind にオプションを追加する。
    * done: ble-bind に於ける遅延初期化について確認する。
    * done: refactor: ble-decode-key/dump 其他。

    * done: 実装する。keymap/push, pop の際に cursor shape を再設定すれば良い。

      % 遡ってもカーソル形状が指定されていない場合には何もしない? 今までに何も
      % 設定されていなければ何もしない。今までに何か特別な物が設定されていた場
      % 合には 0 または空の文字列で DECSCUSR を呼び出してカーソル形状の設定をク
      % リアする。これは実は cursor-shape の側で設定を行っている筈なので気にし
      % なくて良い。

      遡ってもカーソル形状が指定されていない場合はカーソル形状をクリアする。

    * done: keymap_vi_?map_cursor の設定を翻訳する。

      書き換えの指示を表示する事にした。然し、遅延ロードで設定が読み込まれる為
      に表示が乱れてしまう。これに対応する為にはメッセージを受け取った時に表示
      する様にしなければならない。どの様にするのが良いか。或いは invalidate す
      る? と思ったが座標計算のずれまでは解決しない。

    * reject: term_vi_?map についても keymap 側に設定を移行するべきなのではないか。

      然しこれに関しては大して系統的に管理しようとはしていないし、もし何かしよ
      うと思う場合でも __attach__ で実行すれば良いのではないか。ただ
      し、__attach__ はその keymap を push した時にしか実行されない。一方で、
      term は pop して表に出てきた時にも実行する必要があるという点が異なる。そ
      ういう意味で ble-bind --cursor と同様に取り扱っても良いのではないか。とい
      うより、ble-bind --cursor を止めてもっと汎用的な hook を用意する可能性?
      と思ったが、やはり cursor は cursor で管理するのが良い気がする。

      term_vi_?map についてはユーザが設定したい時に利用する物なので、現状の儘
      naive な実装をするままで良い。複雑な仕様にするとユーザーが混乱する。

    * done: vi における動作テストを行う。

    * done: wiki: ble-bind に追記
    * done: wiki: 既存の keymap_vi_?map_cursor を廃止。
    * done: update blerc

  * 2021-04-04 keymap/emacs: emacs mode でも cursor shape を設定できる様にする [#D1514]
    https://github.com/akinomyoga/ble.sh/issues/95

    % keymap/vi と同様に実装した。本来は auto-complete や menu 等の mini mode の
    % 中でカーソルの形が変化することも考慮に入れて、もっと統一的な枠組みでカーソ
    % ルの形状を管理するべきな気もするが、現在は external/internal 及び major
    % mode の切り替えのみでカーソル形状を変更する取り決めにして、直接カーソル形状
    % の設定を各 major mode の切り替えで記述している。
    %
    % 2021-04-26 設定を変更した時に直ぐに反映する様にするには? →取り敢えず
    % keymap/vi と同様にカーソルの形状はトップレベルで決まっていると考えて、基底
    % keymap　が emacs かどうかだけで変更を適用する様にした。然し、既に上の段落で
    % 記述した様に、mini mode 毎にカーソル形状を変更する為にはちゃんと構造化して
    % カーソルを変更する仕組みを整備しなければならない。
    %
    % * 今の暫定実装だと、emacs モード内で vi に移行している時に意図しない動作に
    %   なる。vi は毎回自分の状態に応じてカーソルを設定しようとするとので、emacs
    %   の中で vi に移行していたとしても関係なくカーソル形状を変更してくる。なの
    %   で、emacs 内の vi でも vi のカーソル形状の設定は有効であると考えるべきで
    %   ある。
    %
    %   暫定実装では基底が emacs かどうかで判定しているが、そうではなくて、keymap
    %   stack の内部でカーソルが設定されている一番上の keymap を使って判定するべ
    %   きなのではないだろうか。
    %
    %   これも keymap ベースの判定方法なので、やはり keymap を基準にした実装に切
    %   り替えるべきの気がしてきた。

    この変更は結局 #D1515 の実装に伴ってキャンセルした。一応変更は
    memo/D1503.stub.patch に残しておく。

2021-03-15

  * 2021-03-03 syntax: 実は "${v#...}" の中身も tilde 展開の対象の様である [#D1513]
    https://lists.gnu.org/archive/html/help-bash/2021-03/msg00003.html

    bash-1.14 から bash-dev まで一貫して再現する。
    bash -c 'v=/home/murase/test; echo "${v##~/}"'

    : の後は特に展開対象という訳ではない様だ。変数代入形式の単語でも特に展開は
    しない。つまり本当に先頭に ~ がある時にのみ展開が発生する。

    $ bash -c 'v=x:/home/murase/test; echo "${v##x:~/}"'
    $ bash -c 'v=a=/home/murase/test; echo "${v##a=~/}"'
    $ bash -c 'v=a=x:/home/murase/test; echo "${v##x:a=~/}"'

    序でに、この振る舞いについては実はマニュアルにちゃんと記載されている。

    > In each of the cases below, word is subject to tilde expansion,
    > parameter expansion, command substitution, and arithmetic
    > expansion.

    対象は ${v-w} ${v+w} ${v?w} ${v=w} ${v#w} ${v%w} である。他は関係ない。

    * 他に posix モードに於いては変数代入形式の単語についてチルダ展開は起こさな
      い→これの対策も実装した。OK

  * 巨大なディレクトリで TAB 補完が遅くなる (reported by timjrd) [#D1512]
    https://github.com/akinomyoga/ble.sh/pull/65#issuecomment-798551355

    再現する事ができたので対応する事にする。200k のファイルまたはディレクトリが
    存在する所で TAB を押して少ししてから別のユーザー入力を押した時に直ぐにキャ
    ンセルされない。時には数秒待たされる事もある。現在の実装では補完時に別のプ
    ロセスを使っているので展開自体に時間がかかっているとしてもすぐにキャンセル
    される筈?

    ? 然し、本当にユーザー入力に対して即座にキャンセルするという事にして良いの
      だろうか。ある程度の interval は置くべきなのではないだろうか。と思ったが、
      実際の所、現在の実装で既にユーザー入力がある時にはすぐにキャンセルする動
      作になっていて、単にキャンセルが成る迄に待たされてしまうという動作になっ
      ているという事を考えるとこれは気にしなくて良い。

      →元から即座にキャンセルになる。ただ現状の実装ではキャンセルに時間がかかっ
      ているだけ。

    どうも TAB 補完の時には conditional-sync による実行がされていないのではない
    かという気がする。取り敢えず何処で時間がかかっているかを確認する。

    →絞り込みをかけていった所、ble/complete/source:file に於いて、生成したファ
    イルの存在確認とディレクトリかどうかの確認に時間がかかっていた。

    ? 然しそもそもこの確認は必要なのだろうか。現在の実装では nullglob を設定す
      る様にしているので存在しないファイル名が生成される事はないのではないか。
      やはり確認してみると nullglob を設定しているので改めてファイルの存在確認
      を行う必要はない筈。-e または -h で確認を行っているがこれは全ての生成され
      たファイル名に対して真であると考えられる。従ってこの処理は不要である。

      →特にファイル名の生成の時にはチェックはしない様に変更する事にした。ディ
      レクトリの場合にも予めパターンに / を含めているので、ディレクトリ以外が混
      入するとも考えられない。従って、全て使う事にする。但し、末尾の / は除去す
      る。

    然し、これまでの処理ではファイルの存在確認を全てのファイルに対して再実行し
    ていた。つまり、-d -e -h を実行していた。stat を何度も繰り返す事になるし、
    そもそもループで 200k ものファイルを回していたという事になる。なのに、手元
    の計算機ではかなり短い時間で処理できていた。bash は意外と遅くないという事な
    のだろうか。何れにしても環境によってはこれらのファイルアクセスに時間がかか
    るというのは理解できる。

    実のところこれが本当に報告された問題に関係しているのかは分からないが、少な
    くとも性能の改善はあるだろう。他にも bottleneck があるかもしれないがこれで
    良い事にした。

  * 2021-03-07 bleopt 初期化時に最初から存在する設定をチェックする? [#D1511]

    というのも ble-update や version up に従って設定名が変わるかもしれないから。
    ただ、今までに設定を破壊的に変更した事はないので余り気にしなくても良いのか
    もしれない。

    % その場でチェックをする為にはチェック用の関数が bleopt/declare の時点で存在
    % している必要がある。check 関数が定義されている時にはそれが bleopt/declare
    % よりも前になる様に書き換えていく。
    %
    % x 以下の関数は定義時にちゃんと関数群が存在しているか確かめているが、その関
    %   数群は未だ定義されていなかったりする。これらの初期化順序についてちゃんと
    %     再考する必要があるのではないか。
    %
    %   - canvas: bleopt/check:char_width_mode
    %   - util: bleopt/check:input_encoding
    %
    % 或いは値の設定に関しては ble.sh の基本的な初期化が終わった後に一括してチェッ
    % クを行う様にする? そうすると既定値を何処かに記録しておく必要があるのでは
    % ないか。

    その場でチェックする様にすると dependency injection 的に用意される設定値の
    場合に (オプションを宣言した時点では設定値が登録されておらず、後で各設定値
    が補助関数の定義などを通して登録される場合) 問題が起こる。

    結局、様々のモジュールを読み込んだ後で最後に一括してユーザによって指定され
    た値のチェックを行う事にした。既存の設定に関してチェック用関数の順序を変更する必要はない。

2021-03-09

  * README: uninstall に .cache の事が書かれていない [#D1510]
    書いた。

  * README: 0.3 に関しては release note の側に書いておくべきなのでは [#D1509]
    記入した。0.1..0.3 の情報を書いた。各 Release ページに使い方を記入した。

  * COMPAT complete vs fzf: システムによってロードされた fzf で固まる [#D1508]

    これは . /etc/bashrc を読み込むと強制的に読み込まれている設定である。ユーザー
    が自分で入れた fzf に関しては contrib/fzf-completion を ble-import して貰う
    事によって問題が起こらない様にしているが、システムによってロードされる fzf
    に関しては内容を上書きする隙がない。仕方がないので、core-complete.sh で
    _fzf_* が呼び出された時に contrib/fzf-completion を自動的にロードする様にす
    る事にした。元より bash-completion を勝手に呼び出したりする様にしているので
    他の framework ありきのコードがあっても気にしない。

    これは正直 fzf が tty ではなくて stderr になにか出力しようとするのが行けな
    い。/dev/tty に出力する様にして欲しい物である。

    うーん。 fzf のページを見てもそれらしい物は存在しない。環境変数などで指定で
    きれば良いのだが。man fzf を見てもそれらしい物は存在しない。そういう機能を
    request して見ようと思ったが、考えてみれば自分で fzf を呼び出す時には
    2>/dev/tty をつければ良いだけなので新しい機能として実装する意味がない。ユー
    ザー経由で呼び出しているのであればユーザーにその様に指定する様にお願いする
    べきなのである。

    然し、ble.sh がやっているのは bash progcomp の模倣である。bash の方で問題が
    ないのであれば、ble.sh の方で問題が起こるのは余り良くない。うーん。fzf につ
    いて関数などで上書きして振る舞いを変える? うーん。それだと fzf-xxx の様な派
    生コマンドを使われた時に対処できない。結局 bash progcomp を真似て 2 は tty
    に繋いだ儘にしておくべきなのだろうか。うーん。

    というかそもそも fzf が tty に出力する様にしたとして auto-complete に際して
    期待通りに動くかどうかというのは非自明である。取り敢えず試してみる。
    →試してみた所期待通りに動作しない。やはり fzf の設定をそのまま使うのは駄目。

    ? うーん。実行しても結果が反映されない。COMPREPLY をちゃんと設定しているか?

    ? redraw-line が正しく呼び出されていない。

      % これは恐らく ESC [ が M-[ になって bind されているのが原因。CSI の構築に
      % 失敗した時に M-[ と解釈するべきか或いは ESC [ と解釈するべきかは微妙な所
      % である。然し、CSI を構築する ESC は isolated ESC ではなくて他の文字と一緒
      % に受信した ESC であるべきと考えれば、やはり M-[ と解釈するべきだろうか。
      % そうすると、CSI に失敗した時に 1 byte だけ切り取って ESC を key として生
      % 成しているのを修正するべきである。

      改めて確認した所、そもそも CSI 0 n は認識できないシーケンスとして捨てられ
      ているという事が判明した。

    ? その他の問題として fzf を実行している間は modifyOtherKeys の設定によって
      fzf の操作ができなくなっているという事がある。うーん。実際に端末に作用す
      るかどうか分からないのに補完関数を呼び出す度に端末の状態を変更するという
      のも変な感じがする。

    面倒なので fzf が補完関数の名前に入っている時に限り特別の動作をする様にする?
    取り敢えず、固まったりしない様に調整した。

    % x fixed: CSI 5 n が候補の文字列に結合してしまっている。これは何故だろうか。
    %   COMPREPLY にはちゃんとした候補が入っている…気がする。
    %
    %   →これは compgen の標準出力を読み取って候補としているのが原因。元の
    %   progcomp の -F の場合には標準出力はそのまま端末に繋がっている。それに倣う
    %   様に修正した。
    %
    % x fixed: 候補が生成されない…と思ったら実は CSI 5 n に対する返答 CSI 0 n に
    %   よってユーザー入力に依る中断が入って処理がキャンセルされている。fzf の時
    %   にはどうにかしてこれに対する対策を行う必要がある。
    %
    %   a CSI 0 n を受信しても処理を続行するというのは難しい。何故ならば受信した
    %     段階ではそれがユーザー入力なのか応答なのか判定する方法がないので。受信
    %     して読み取ってから違ったら書き戻すというのも処理としては汚い。
    %
    %   b それなら CSI 5 n がそもそも伝播しない様に抑える必要がある。うーん。幸い
    %     にして CSI 5 n は標準出力に、それ以外のメニューの描画は標準エラーに出力
    %     されている。従って、_fzf* に対しては標準出力を潰す様にするのが良い気が
    %     する。

    色々対策してみたが実はこれらの対策は contrib/fzf-completion.bash と本質的に
    同じであった。fzf-completion.bash を自動で load する方が良いのではないか。

    x fixed: progcomp で単一候補を生成したとしても progcomp 以外に sabbrev も表
      示されてしまって単一確定にならない。うーん。これは _fzf_* で成功して単一
      確定の場合には既に生成した候補は全て削除するという事にすれば良いのでは。
      →既存の候補は消去する様に実装した。

    x そもそも既に入力済みの内容を無視している。normal bash で試してみると、既
      に何か入力済みの物がある場合には fzf による completion は起動しない。空の
      文字列の時にだけ fzf による選択が開始される。

      →これは曖昧補完の為に空文字列で補完候補生成を要求するのが原因であった。
      曖昧補完の時にはそもそも fzf を呼び出さない様に修正した。

  * BUG progcomp: 現在 read に介入して中断する様にしているが [#D1507]

    現在の実装だと

    while read || [[ $REPLY ]]; do ... done

    の様になっていると、無限ループになってしまう。
    中断する時にも引数に指定した変数は全て空にしておく必要がある。

    というより、現在の read の実装は普通に呼び出した時であってもちゃんと変数を
    空にしてくれるのか?

    % そもそも元の read の振る舞いが良く分からない。read line とした時にもう読み
    % 取る内容がなかったとして line が空になるのかと思いきやそうでもない? と思っ
    % たがこれは勘違いだった。試す時に : | read ... とすると subshell の中で値を
    % 設定するので、外側の変数には影響が出なかっただけ。

    うーん。取り敢えず中断の時には内部で </dev/null を builtin read に食わせて
    処理する事にした。option -e が指定されていても /dev/null に繋がっている時に
    は特に readline も起動せずに期待通りに動作する筈。

  * [OK] edit: read -a ARRAY に対応していない? [#D1506]

    と思ったが実はちゃんと対応していた。抑 -a ARRAY は bash-4.0 の時点でちゃん
    と存在している。調べたら bash-2.0 で配列に対応した当初から存在している様で
    ある。

    対応していない様に見えたが実のところ read -e で読み取った結果を改めて
    builtin read で解釈されているので特別に実装しなくてもちゃんと振る舞いを再現
    できているのである。

  * wiki: bleopt openat_base [#D1505]

    現在は実は積極的には使われていないという事。
    また、既に重複して開かない様に対策が為されているという事。

    →どの時点で対策が導入されたか確認しようとしたら実は ble-0.1 の時からちゃん
    と或る程度の衝突回避はある様だった。問題が発生するのは ble.sh が fd を使い
    始めた後でユーザーがそれを上書きしてしまった場合である。この問題は今も依然
    としてある。従って、現在の文章はそのままにする。但し、Bash 4.0 以下でしか使
    われないという事は書いておいて良いだろう。

    wiki を編集した。

2021-03-07

  * progcomp: やはりファイルが大量にあるシステムで遅い (reported by timjrd) [#D1504]
    https://github.com/akinomyoga/ble.sh/pull/65#issuecomment-791932281

    試しに complete -r して見ると発生しなくなる。

    という事は bash_completion が悪さをしているのだろうか。

    * fzf completion も勝手にロードされている。fzf completion の実装が悪いのか
      と思って fzf の completion をロードしない様にしたがそれでも問題は発生する。

    * highlight_filenme= としても特に問題は改善しない。逆に
      complete_auto_complete= として highlight_filename=1 のままの場合には特に
      問題も生じない。着色もそんなに時間をかけずに実行できている。という事を考
      えるとやはり progcomp 特有の問題である様に思われる。

    * bash の progcomp の場合には特に問題は生じていない。という事は -F で呼び出
      した関数を強制的に中断する機能があるのか、或いは -F の関数の呼び出し自体
      にはそんなに処理時間がかかっていなくて後の処理で時間がかかっているという
      事なのか。何れにしても計測が必要になる。

    実際に処理をブロックしているのは以下の関数の呼び出しの様だ。

    $ _minimal 'echo' '' 'echo'

    然し普通に呼び出してもそんなに時間がかかる事はない。

    ----

    _minimal の呼び出しに時間計測をかける。結局 _filedir の中にあるループがいけ
    ないのだという事。うーん。ble.sh の中で実行すると 20 秒も待たされるが、bash
    progcomp から呼び出すと 1.2 秒で終了する。何故だろう。

    実際に候補を bash progcomp 内で生成しているのか確認してみるとちゃんと候補は
    生成されている。

    もしかして read で変な処理をしているのが行けないという事だろうか。でもそん
    なに重い処理はしていない。うーん。オプションの処理をしているが、bash
    progcomp の時にも現在 attach しているかどうかのチェックは行っている。そんな
    に差が開く物なのか。

    実際に unset -f と read() { ble/builtin/read "$@"; } で囲んでみたら 0.6s に
    縮まった。1/60 の時間になった。

    ----

    これに対する対策はどのようにするのが良いか。

    a progcomp で compgen する時だけは unset -f read する? と思ったが、この状態
      で read -e を内部で呼び出されるなどすると変な事になってしまう。

    b decode-detach/attach するのは処理量的に好ましくない気がする。特に
      auto-complete で何度も呼び出されるのに、実際に時間がかかるかどうか分から
      ない処理のために毎回 detach/attach するのは大変。

    c 或いは _filedir 等の各関数に対して .advice around で unset -f read を行う?

    d 或いは read の中に complete_polling_cycle を仕込む。うーん。これが一番
      smart な気がしてきた…。

  * canvas: Kitty が CSI ; r に対して何もしない (reported by timjrd) [#D1503]
    https://github.com/akinomyoga/ble.sh/pull/65#issuecomment-791932281

    抑 CSI ; r にしていたのは DECSLRM CSI ; s に合わせる為であり、DECSLRM を
    CSI ; s にしていたのは、SCOSC と区別する為に引数の数に基づく heuristics を
    用いている為である。CSI r 自体については SUNSCRL と conflict が存在している
    が、SUNSCRL を実装している端末は Solaris console ぐらいしかないだろう。なの
    で、CSI r をそのまま出力しても問題ないと判断する。

    然し、引数の省略をすると動作しないというのは Kitty のバグなのではないのか。
    まあ Kitty の全体的なデザイン等について知らないので、もしかすると Kitty は
    全体的にそういう感じなのかもしれない。何れにしても Kitty の端末エミュレーショ
    ンは元より滅茶苦茶なので気にしても仕方がない。

2021-03-03

  * 2021-02-28 canvas/trace: align=right,center に対応する [#D1502]

    高さについても同様に対応しても良いのかもしれないがそれは必要になってからで
    良い。

    rps1 の各行右揃えに対応しようと思ったが問題がある。範囲計算がちゃんとできな
    いという事。rps1 が横幅一杯に広がれる様にする為には trace の計測開始点は
    x=0 でなければならない。然しこれで measure-bbox すると範囲が x=0..COLUMNS
    になって横幅一杯になってしまう。一方で、rps1 を表示する時には実際に文字が出
    力される範囲を取得したい。これはどの様にするのが良いか。

    a 描画開始点を実際に文字が出力される範囲の bbox の左上になる様にする? 然し
      それは最後まで範囲計算をしないと求められない。一番最後に、出力シーケンス
      の先頭に移動シーケンスをつけ加えれば実装できるが実装が汚くなる。特に右寄
      せしていない場合でも同様の機能を提供する等の事を考えると変である。

      更に、bbox の左上の位置というのが分かりやすいのかも不明である。何故なら呼
      び出し元は配置の結果として何処が bbox の左上になるのかという事を知らない
      からである。これは、呼び出し元で bbox の中身の配置について全く関知せずに、
      一つの blackbox として取り扱うという場合にのみ妥当である様に思われる。

    b 或いは描画開始点を右上にするという手も考えられる。右寄せの場合にはその方
      が自然に思われる。

      b1 計測の時には取り敢えず x=0 にして計測を行って、その後でユーザーが指定
        した (x,y) を起点とした描画シーケンスを構築するのである。然し、その時に
        は左に向かうシーケンス等が何処で壁に当たって止まるのかという振る舞いが
        変わってしまう。

      b2 代わりに unbounded な空間で計測をしてから再配置をするという事を考える
        と、今度は折角計測した内容が実は一行の中に収まらなかったという様な自体
        が生じる可能性もある。然し、これに関しては現在の実装でも似たような物で
        ある。しかし、少なくとも一つのフィールドの幅が行内に収まっていればOK。
        一つ一つのフィールドについて絶対範囲ではなくて幅や高さで制限をかける事
        になるが、それはまた実装が無駄に複雑になってしまう。

    c 或いは measure-bbox で文字列の範囲とカーソル移動の範囲の二種類のどちらを
      計測するか指定する事ができるようにする?

      両方の情報が欲しい場合も考えられるので、x1 x2 y1 y2 に加えて、x1c x2c y1c
      y2c 等を用意する? 少なくともカーソル移動は文字列を包摂するべきである。変
      数が増えるのも面倒なので x1[1] x2[1] y1[1] y2[1] 等の様に配列にしてその第
      二要素以降に値を格納するという考え方もある。然し、これはインターフェイス
      として分かりにくい。

      measure-bbox の振る舞いを切り替えられる様にするというのはやはり問題がある
      気がする。何れにしても両方の情報が必要になるからである。justify で配置を
      する時に出力された文字列の範囲を元にして配置を行うと、端にぶつかった時に
      座標計算がずれてしまう可能性がある。一方で、right align の大きさを調べる
      為には right を表示する必要がある。

    d 行毎に ret x1 x2 y1 y2 x y を算出する。これらの変数を全て配列にする。各行
      の bbox の左上 (x1,y1) を ret の出力開始点とする? (x1,y1) への移動に関し
      ては自前で実行する。その他の align も全て自分で処理する。

      これは微妙。これならそもそも trace に実装する必要もない様な気がする。
      (一応 sc/rc で囲んでいる部分やシーケンスを跳ばすという処理が非自明だが)
      そもそも trace に渡す前に分割して指定していれば良かったのである。

    % 調べて見た所、実は現在の実装は既に文字を出力した範囲の bbox を使う様になっ
    % ていた。という事は…。現在の実装で既に right を指定した時の範囲も表示して
    % いる物の範囲になっているという事?
    % →勘違いだった。ループの最後で記録しているが、これは制御機能によって移動
    % した後でも通過する場所に書かれている。

    表示が乱れる場合の事を考えると right の時には一旦右端に移動してから其処から
    の相対移動で描画するのが良い気がする。これは right の時の特別な取り扱い。

    * 現在の範囲追跡のコードを整理するという可能性。現在は移動を伴わないエスケー
      プシーケンスであっても記録を行う様になっている。これは無駄な気がする。

      また、全てに対して一律に範囲追跡を行っているので、文字列出力のみに対して
      計算する等の事ができない。と思ったが、結局最終的に文字列範囲とカーソル移
      動範囲の両方の情報が必要になるのであれば、文字列出力範囲に関しては独立し
      たコードで実装を行う筈で、これは気にしなくて良い。

    opts measure-gbox として出力した文字列の範囲を計算する事にした。

    * justify の時に最後に jg[xy][12] から g[xy][12] に転写する

    * main-loop の下部の ((w>0)) の処理について

      * 何故折返し処理を此処でしているのだろうか? w として有限の幅を設定する制
        御機能は限られている。調べた所、print+ と単一文字の時の二通りしか無い。
        単一文字に関しては行に収まらない場合には事前に改行を実施している。行に
        ぎりぎり収まる時の振る舞いはどうなっているか。うーん。

      * gbox は此処で処理するべきの気がする。有限幅の文字列がある時には此処に来
        るのだから。というよりこの処理自体を関数にしても良いのではないかという
        気もする。

      * そもそも此処で行っている処理は put-ascii や put-atomic で行うべきなので
        はないだろうか。

      →全て各制御機能及び print の内部で measure-bbox, gbox の処理を行う様に変
      更した。

    取り敢えず rps1 の複数行も実装して動作確認した。OKだと思う。

2021-02-28

  * 2021-02-06 render-defer.idle の優先順位を下げたい [#D1501]

    現在の実装では ble/textarea#render-defer.idle が menu-filter, auto-menu,
    auto-complete よりも先に来ているが、これは後に来るべき。特に menu-filter よ
    りも先に来ないと絞り込み状態の着色がずっと残ってしまう。

    menu-filter を render-defer.idle よりも前に挿入するべきである。どの様にすれ
    ば良いか。

    a 特定の要素の前に挿入するという操作を実装しても良いと思ったが、その為だけ
      に関数を用意するのも変である。それよりはオプションで指定できる様にする方
      が実装としては自然である。その時に挿入点よりも後に詰まって存在している要
      素はシフトする。

    b 或いは初めから各 background の優先順位を指定して登録してしまうという手も
      ある。というよりその方が自然である。どうせ決め打ちになるのでその方が柔軟
      に対応できる。

      現在 background idle (10000+) に登録される処理は以下の通り
      - ble/util/msleep/calibrate
      - ble/textarea#render-defer.idle
      - ble/complete/menu-filter.idle
      - push-background ble/complete/auto-complete.idle
      - push-background ble/complete/auto-menu.idle

    うーん。単に menu-filter を 9999 に登録すれば良い? これが単純で分かりやすい
    対応であろう。

  * 2021-01-31 complete: change bleopt complete_limit default [#D1500]

    実は今回の subshell による実行でしなくても良くなったのではないか。と思った
    が、元の報告だと別にグロブパターンと関係なく遅いという話だった気がする。と、
    思ったが補完の話だったのでやはりグロブパターンというかファイル名補完に関係
    がある。

    うーん。やはり 500 というのは上限としては小さすぎる様な気がする。
    auto-complete の 200 というのも小さすぎる様な気がする。もっと増やしても良い
    のではないかという気がする。5000 vs 2000 ぐらい。というか tab 補完に対して
    制限する必要があるのだろうか。

    ? globpat を含んでいるかのどうかの判定は実は failglob を使った方が早いかも
      しれない。現在の正規表現に基づく実装と速度を比較する価値はあるかもしれな
      い。しかし、../../.. みたいなパスが含まれている可能性等も考えると下手な事
      はできない。

  * [自然解消?] 2021-02-01 complete: slow tab completion after globstar words (reported by 3ximus) [#D1499]
    https://github.com/akinomyoga/ble.sh/issues/82#issuecomment-770390986

    パス名展開を compvar 構築時に全ての単語に対して実行しているのが原因かと思っ
    て#D1457 で compvar 用の timeout を導入してみたがどうも関係なかった様だ。報
    告に依ると globstar の着色が終わった後でも遅いという話だ。これはこちらの手
    元では再現しないという事が分かった。恐らく cache が働いているのだろうと思う。

    2021-02-04 新しい commit で改善したそうであるが、それでもパターンがない時よ
    りも遅いそうである。

2021-02-27

  * canvas/panel: set-height で高さ拡張時にその時の sgr0 が bce で適用されてしまう [#D1498]

    < /dev/tcp/..../80 で赤色になっている時に実行すると赤い行ができてしまう。
    これは sgr0 をせずに set-height を実行する事によって発生している事態である。
    そもそも赤い状態をそのままにして放置している事自体が変なのかもしれないが、
    取り敢えず set-height をする前に sgr0 をする必要はある気がする。

    $_ble_term_sgr0 を出力する様にしてみた。

    しかし、どうも ble/canvas/goto.draw する時にまた $_ble_term_sgr0 を出力する
    様なので、重複してしまう。問題が発生するのは、ble/canvas/goto.draw の時に既
    に目的地にいる場合で、その時は既定では sgr0 の出力も省略されてしまう。
    goto.draw の opts=sgr0 は、例え移動が起こらなくても sgr0 の出力を行うという
    物であった。→方針を変更して goto.draw に sgr0 を指定して其処で強制的に
    sgr0 を出力するという事にした。

  * エラーメッセージ "bash: ((: '0': syntax error:" (reported by rux616) [#D1497]
    https://github.com/akinomyoga/ble.sh/issues/92

    [状況]

    bash: ((: '0': syntax error: operand expected (error token is "'0'")

    * 最近発生する様になったという事。

    * 一度発生し始めると色々なキーを入力する度にメッセージが出るという事。

    * RET TAB BS 及び function keys が全滅。0-9 や numpad key も駄目。
      何故か # や & 等の記号は OK

    これは decoder が関係している気がする→2021-02の変更点を探してみたが特に怪
    しい所はない。

    * 連想配列が配列に化けてしまって発生しているという可能性もある。
      然し、連想配列の添字に quote 付きの文字列を指定する事があるだろうか。
      そもそも連想配列の添字に指定した '' が除去の対象だったかどうか怪しい。
      →試してみた所、どうやら展開の対象の様である。

    最初は発生していなくて途中から発生する様になるというのも不思議な事である。

    再現できた。というか空の blerc でも再現できた。どうも set -o vi だと発生し
    なくて set -o emacs だと発生する様だ。

    bleopt default_keymap=vi でも起きなくなる。
    bleopt default_keymap=emacs; set -o vi だと起きる。
    bleopt default_keymap=safe でも起こらない。

    うーん。emacs.sh の問題かとも思ったが最近変更した内容に関係のありそうな箇所
    は存在しない。だとすると別の場所で発生した問題が emacs.sh の中でたまたま見
    える様になっただけと考えるのが自然だろうか。

    取り敢えずなにかエラーメッセージが出ているという事はその場所を特定するとい
    うのは簡単の筈である。

    | 取り敢えず PROLOGUE と EPILOGUE の間だという事は分かった。decode byte 関
    | 連ではない。home を押しても一組しかエラーメッセージが出てきていないという
    | 事と、keymap safe, vi では発生していないという事から考えるに。だとすると
    | 残っているのは widget 実行辺りなのだが、様々な widget で発生している事か
    | ら __before_widget__ が怪しい。
    |
    | →確かに __before_widget__ だった。特に ble-edit/undo/add の中でエラーが
    | 発生している。
    |
    | % 更に ble-edit/undo/.get-current-state の内部で実行が途絶えている。と思っ
    | % たがそうでもなかった。その次の行の辺りだった。
    | %
    | % _ble_edit_undo_index に整数が入っている筈なのに history という文字列が入っ
    | % ている。と思ったら勘違いだった。_ble_edit_sttr に history という文字列が
    | % 入っているだけだった。
    |
    | やはり .get-current-state だった。調べると _ble_edit_undo_index の中に
    | '0' という文字列が設定されている。これは何処から来るのか調べる必要がある。

    分かった。配列を保存・復元する時に quote-words 的な処理で囲んだ要素を eval
    で評価するべき所が単に split-words で評価していたのが原因。最初は
    quote-words 的な処理にに書き換えたのが原因かと思ったが、逆で eval していた
    所を split-words に書き換えてしまったのが原因だった。つまり、犯人は 5f9adfe
    だった。IFS の調整として分割を全て split-words に置き換えた時に余分に書き換
    えてしまったのが原因。

    修正した。

    * ok: 他に似たような書き換えミスがなかったかどうか確認してみたが大丈夫の様
      である。

    後で改めて見てみたら修正によって破壊している。最近どうも全然駄目だ。毎回修
    正する時に新しいミスを導入にしている。改めて修正した。

2021-02-24

  * Makefile: keymap/*.txt に対する規則を削除してはいけなかった (reported by nihilismus) [#D1496]
    https://github.com/akinomyoga/ble.sh/issues/91

    f25a6e8 が悪い。22日15時過ぎに push したと思うから大体1.5日の間壊れていた事
    になる。これは良くない。修正した。動作確認もする必要がある。

2021-02-23

  * util: vbell で座標計算がずれる [#D1495]

    [状況]

    | 座標計算がずれる様になっている。ble.sh のディレクトリで空コマンドラインで
    | TAB 補完を実行しようとすると、complete_limit に達すると同時に sabbrev 候補
    | の \ が一次挿入される。この時に座標が一つ左にずれる。
    |
    | 8856a04 では問題は起こっていない。3cadd54 では問題が発生している。37363be
    | でも発生している。3cadd54 は ecb8888 に対応する。
    | 取り敢えず問題の commit は 69228fa にあると分かった。
    |
    | * bleopt edit_vbell= にすると問題は発生しなくなる。
    | * visible-bell の先頭で return して実際の処理を行わない様にすると発生しなく
    |   なる。
    |
    | 問題の commit では vbell に対する修正も色々入っている。やはりこの辺りが怪し
    | い。
    |
    | これは sc/rc による問題だろうか。然し、_ble_term_sc= _ble_term_rc= としても
    | 問題は再現している。fork の直前で return 0 すれば問題は生じない。つまり
    | .show 自体の問題というよりは出力が混ざる事による問題の様な気がする。
    | 然し buffer.flush を fork 直前に挿入しても何も効果はない。
    |
    | うーん。タイミングが丁度悪いという事なのだろう。

    あー。分かった。save-position/restore-position しているが、この時に
    _ble_canvas_{x,y} を参照している。然し、これらの値は subshell の中では更新
    されない。これが理由で座標計算がずれてしまうのである。

    [解決法]

    どの様に対策すれば良か。何が問題かと言うと…bottom-dock に対応する為に
    SC/RC を使っていて、それが visible-bell の使っている SC/RC と衝突していると
    いう事。コマンドライン上に居る時には visible-bell の為に SC/RC しても良いが、
    bottom-dock にいる時には visible-bell が SC/RC すると本来のコマンドライン上
    の位置が失われてしまって問題になる。これを防ぐ為に visible-bell では一旦コ
    マンドライン上に復帰してから visible-bell を表示する事にしている。

    どの様に解決するべきか。

    a IPCか何かを使って vbell の状態変化を親シェルに伝達して描画は親シェルで行
      う様にする? 然しどの様に伝達するのが良いだろうか。

      - シグナルは bind -x の内部ではチェックされない (もしくは bash の内部的に
        はチェックされているのかもしれないが対応する trap handler の呼び出しが
        遅延される)。然し、或いはそれでも良いのかもしれない。例えば現在
        bash-3.0 における C-d の読み取りは外部プロセスに行わせていて、C-d を検
        出したらファイルに書き込んでシグナルを送信する仕組みになっている。

      - tty に文字を挿入する事ができれば decode の枠組みに自然にイベントを組み
        入れる事ができるが、実際の所 tty に文字を外部から挿入する事はできない。
        シグナルを

      - FIFO か何かを使って通信するというのはよくある方法だが、現在の実装では
        visible-bell を実行する度に新しくプロセスを立ち上げているので、pipe を
        沢山管理しなければならないので非効率的である。

      - ファイルを使って処理をするという手が考えられる。bash-3.0 C-d でやってい
        る様にファイルに書き込んでからシグナルで通知する。然し、複数のプロセス
        が走っている場合には出力が混ざりあった時に問題が発生する。mkdir 等を使っ
        て同期するという手も考えられなくはないが益々処理が重くなってしまう。

        プロセスごとにファイルを作って処理するという手も考えられる。そして、読
        み取り用のプロセスは一つに絞る事にする。というか実は親プロセスで読み取
        りを実行すれば良いだけの気もする。ファイル書き込み中の同期に関しては、
        現在既に visible-bell でやっている様に複数の状態通知様ファイルを作って
        ファイルが空かどうかで判定する様にすれば良い。

    b そもそも別のプロセスを作る必要があるだろうか。全て親シェルで実行すれば良
      いのではないだろうか。折に触れて状態をチェックしつつ sleep して時間が来た
      ら親シェルが書き換え・消去を行う。

      然し、この方法の問題点は Bash 3.0 である。read -t 0 がないので、ユーザー
      入力が来た事の判定ができない。ユーザー入力があると想定してすぐ抜ける様に
      していると、実際にユーザー入力がなかった時に bind -x による制御が戻ってこ
      ないので、次にユーザー入力があるまで vbell の処理をする事ができなくなって
      しまう。ユーザー入力がないと想定して処理を続けると、vbell が表示されてい
      る間ユーザー入力が処理できなくなって固まった様になってしまう。

      そうするとやはり別プロセスに任せてそれをシグナルで処理するという事になる
      のだろうか。実際の所、シグナルハンドラーの中での処理は色々と怪しい事が起
      こるのでやりたくない。

      複数のサブシェルとメッセージをやり取りする様な一般的な枠組みを整えるのも
      手なのかもしれないと思う。

    c 取り敢えず今まで通り sc..rc が自由に使える前提で処理する

      今まで問題が起こっていなかったのは SC したまま放置される様な状況がなかっ
      たからである。その為いつでも SC...RC を気兼ねなく用いる事ができて親シェル
      の _ble_canvas_{x,y} の状態に依存せずに実装する事ができていた。本当の所、
      タイミングが悪ければ SC...RC が overlap して描画が乱れる可能性は 0 ではな
      いが確率的にはとても小さい筈。というのもシーケンスの書き出しは buffer に
      貯めてできるだけ atomic に行っているので。

      実は現在の所は SC/RC によって bottom-dock を実現しているとは言え、カーソ
      ルを bottom-dock に放置する様な事はしていない。なので、visible-bell の書
      き換えを行う時には常に SC..RC は閉じていると想定して良いのではないか。

    取り敢えず現在は c の方針で回避する事にする。

  * tui: trace に align/justify 機能を実装する [#D1494]

    prompt_status_line に右寄せの内容と左寄せの内容を表示するという需要はある。
    原理的にはユーザーの側で自前で実装してもらう事は可能である。然し、文字幅を
    考慮に入れる等すると実は非自明である。

    * prompt_status_line の中で適当に文字列を分割・計測したりして処理する方法も
      考えたが非効率な気がするし、エスケープシーケンスの中に justify の文字が含
      まれていたり、或いは prompt 展開の結果として justify の文字が現れる場合な
      どにも対応したいと思うとより下流で処理するべきである。

    * また、prompt_rps1 に於いても現在の実装では描画内容全体を一塊として右寄せ
      しているが、各行について右寄せをする様にしたい。

    その様に考えると trace の中で一括して実装した方が理に適っている気がする。

    * justify のデザイン

      | justify 用の文字の幅を保持するかしないかという問題が存在する。空白で
      | justify する場合にはどんなに狭くても空白一個分は開けなければならない。そ
      | うでないと英単語が互いにくっついてしまう事になる。他の制御文字等でフィー
      | ルドを区切る場合にはどうするか。うーん。その場合でも空白一個分は開けて置
      | きたい気がするが、しかし一方で | 等の様な記号を含める場合にはフィールドセ
      | パレータの分の空白があると邪魔なのではないか。
      |
      | 後、間を埋める文字についても指定できて良いのではないかという気がする。つ
      | まり、...... で埋めたり ------ で埋めたりするという事。実際に Emacs は
      | ---- で余分な部分を埋めているし、TeX の目次の様に .... で埋める様な機能が
      | あっても良い様な気がする。
      |
      | 指定方法について考える事にする。例えば、図形文字を sep に指定した場合には
      | 少なくとも 1 文字は其処にあると想定する。間を埋める場合にはその図形文字を
      | 繰り返す。制御文字を sep に指定した場合には幅が狭い時には零幅になる事を許
      | 容する。sep として複数の文字を指定できる様にし、それぞれの sep に応じて振
      | る舞いを変える。
      |
      | この方法の問題点は本文の中に fill 文字と同じ文字がある時に困るという事。
      | そう考えると fill 文字はやはり外部から指定できる様にした方が良いのではな
      | いか。でもそうすると間隔毎に異なる fill を使う事ができない。必ずしも sep
      | と fill を同じにしなくても良い。各 sep 毎に fill を指定できる様にするとい
      | うのも手である。但し、その場合にどうやって引数を指定するのかは謎である。
      |
      | というか空白の時にだけ特別扱いすれば良いだけなのでは。空白で justify する
      | のは英文の場合である。似たような文脈で空白以外で justify するという状況は
      | 考えにくい。

      仕様: 連続する同じ SEP がある時、その数はその SEP によって挿入される間隔
      の weight を表す。同じ SEP が離れて複数ある場合は、その SEP の間の文字列
      をその SEP に対応する FILL と解釈する。例えば SEP SEP -- SEP の場合はこの
      SEP の間隔の weight は 2 で fill は "--" と考える。

      最小間隔は通常 0 であるが SEP が空白の時は特別で 1 である。これは通常の英
      文の様なものを想定した特別規則である。

    実装方法について考える。やはり put-atomic, put-ascii を修正する事になる。
    clip とは相容れない。clip も処理しようと思ったら先に配置を決めておいて、
    その後で再び trace に入れて clip を実行する等という具合にする必要がある。

    clip と同様に出力する文字だけちゃんと配置できれば問題ない。
    その上で気にする必要があるのは "現在の塊" の範囲と、
    span weight である。

    うーん。measure についても justify が設定されている場合には注意が必要である。
    これも clip と同様に最初の実行では justify 用に使用して、後の実行に於いて改
    めて計算し直すのが適切である用に思われる。

    はみ出そうになった場合はどうするべきか。これは confine 等の取り扱いにも依る
    のではないかという気がするが、それらの処理は put-atomic, put-ascii の外側で
    為されている気がするので後で個別に考えれば良い。

    うーん。put-atomic 等の中では実は何も気にしなくて良い気がする。

    * reject: というか sep が図形文字の場合には、最初の各セグメントの幅計測時に
      は取り敢えず sep の幅も考慮に入れても良いのではないだろうか。うーん。やは
      り考慮に入れない方が自然の気がする。

    * done: xI yI を記録する。変数名は jxI jyI 等の方が良いのかもしれない。
      →jx0, jy0 という名前にした。

    * resolved: 現在の実装だとはみ出る場合にどうすれば良いか想定していない。という
      よりはみ出る場合に対して対策する必要はあるのだろうか。そもそも最初の点と
      最後の点だけ記録して、measure-bbox の内容は反映しなくても良いのではないか。
      その方が柔軟に設定できる様な気がする。

      →各フィールドについて初期位置と最終位置だけを元にして配置を決定する様に
      変更する事にした。

      然し、これだと右端を超えて描画されてしまう可能性が排除できない。うーん。
      その場合には適切に shift か clip を行う必要がある気がする。やはり初期位置
      と最終位置ではなくて幾何的に位置を決定する必要があるだろうか。でも、x1:x2
      が初期位置・最終位置の範囲外にはみ出ているという事は元からフィールド間で
      overlap があるという事に他ならないのだから、overlap してしまう事自体は問
      題ないのではないか。

      範囲外に収まらない時にのみ位置を shift するという処置を導入する事にする。
      →その様に修正した。

    * resolved: xenl の問題について。

      一番右端に寄った時に改行してしまう様な端末の場合、下手に一番右まで fill
      してしまうと描画が壊れてしまう。一番最後に出力した文字が右端に接触してい
      る時に改行が起こると想定しても良いかもしれないが、もし描画の途中で複数回
      右端に接触するという様な事があった場合、やはり描画が崩れてしまう。

      xenl のある端末の場合には一番右端まで領域を使ったとしても問題がないのかと
      思いきや、実は相対移動で左に移動しようとした時に結局ずれが生じてしまう。
      基本的に relative で移動している時には右端は使えないと考えるべきなのであ
      る。

      [実装] 然し、status line ではやはり右端まで使いたい。やはり一番右端に接触
      するのは、それぞれの行に於いて唯一回最後だけという想定をして良いだろうか。
      うーん。一応一番最後の位置と x2 が一致しているか確かめて、もしそうであれ
      ば一番右端に一番最後に接触したと想定する事にする。

      →そうするとやはり結局 measure-bbox は有効にする必要がある。

    x ok: ble/canvas/trace/.process-overflow に関しては justify に対して
      opt_relative を入れる事にすれば問題ない筈だが…。うーん。

      これは微妙だ。xenl cap のない端末ではそもそも最後の文字を出力しない様にし
      なければならない。というかそういう観点で言ったら実は、現在の
      opt_nooverflow の実装は駄目なのでは…。xenl のない端末で改行が発生してし
      まう。でも、opt_relative の時には OK である。

      少し xenl の取り扱いについて調整した。

    x ok: 現在の実装では !xenl の時に ble/canvas/trace で無駄な改行が入ってしま
      うのではないか。少し確認が必要である。どの様に検証するか。うーん。

      と思ったが問題の計算をしている所では opt_clip || opt_relative を仮定して
      いたので、そもそも端に接触するという事はないと考えている。なので、勝手に
      新しく改行が挿入されてしまうという心配は要らないという話だった。一方で、
      新しく導入した justify が関係して来る時には何が起こるだろうか。うーん。す
      ぐに .NEL を実行していて、更に .NEL の中では x==cols かどうかについてチェッ
      クしている訳ではないので大丈夫の筈。というか、justify の時には最初に仮想
      的な領域に書き込んでいて、右端で改行してしまう事に関しては後の再配置の時
      に処理する事になっているので気にしなくて良い。そういう意味では、後の xenl
      の処理に関しても同様。

    * done: 他に改行が必要になりそうな箇所を一つずつ探していく事にする。

      * ble/canvas/trace/.put-ascii.draw は justify の時には途中で改行する可能
        性のある動作はしない様にしてある。大丈夫の筈。

      * その他の通常文字(全角)の挿入の場合も範囲に入る時のみに文字列を出力する
        様にしてあるので勝手に改行が発生する事はない筈。

      * done: VT, CR, IND, RI でどの様に処理するのが良いかは微妙。別の行に移っ
        たと見做すのか或いは、また同じ行に戻ってきたら align するのか。というか、
        行った先でまた出力など起こす事を考えると、うーん? でも CR 以外は列番号
        は保持される。という事を考えると水平配置は途切れないと考えるのが自然な
        のではないか。

        VT/IND/RI に関しては何も処置はしない事にする。

        CR に関しては微妙である…。新しいフィールドという事にするか? 然しそれだ
        と指定もしていない sep が有効になっている感じで変である。うーん。jx0 に
        戻るというのが自然な振る舞いの気がする。

      * ok: CUU,CUD,CUF,CUB に関しては相対移動なので同じフィールド内での移動と
        解釈する事にする。

      * ok: HPA,CUP,CHA 等に関しては列番号を直接操作するので水平位置が途切れる
        様な気がする。然し、だからと言って別の行に移る訳でもないし…。これで移
        動しても同じフィールドの中にいるという事にする。

      * done: SC/RC に関してはどの様に取り扱うのが良いか。SC/RC についても
        SC/RC の内部にいる間はsep・改行も含めて特別な処理はしない様にするのが良
        い気がする。

      * done: \1..\2 による保存・復元。これに関しては field を跨いで復元される
        と微妙な感じだが…。うーん。或いは \1..\2 の内部では field の処理は無効
        化する?  それが自然な気がする。これは後で実装する事にする。

    * done: 空白文字の sep については特別扱いする。前の要素に空白文字を含めてし
      まって良い→と思ったがそれだと行折返しが発生した時に行末に余分な単語が含
      まれてしまう。

      ここは単に右に一文字ずらす事で span を最低限保つという方式にした。

      然し、この時の問題点は、他の種類の sep と混合していた時に、必ずしも空白に
      対応する sep に確保した span が割り当てられるとは限らない事。うーん。各
      span に対して "最低限これだけの幅は確保する" という制御は必要になるだろう。
      最初の計測の時点でその情報を参照するのだから、その情報も sep の記録に一緒
      に記録することにするのが良い気がして来た→その様に書き換えた。

    * ok: opt_relative を imply する。opt_measure も imply する。これらは判定を
      flags を用いて行う様にしたい。

      →これらは適当に実装した。

      1 現在の実装では opts=relative -> R, opts=measure-bbox -> M, opts=justify
        -> J を割り当てた。
      2 更に、char flags だと算術式の中で使えないので、別に変数 opt_relative (R),
        opt_measure (M or J) を用意した。
      3 他に、xenl についても opt_relative の時には自動的に imply する様にした。

    * done: $trace_flags == *M* が設定されている時に、範囲を改めて計算する。
      →実装した。

      特に center align している時に範囲を正確に抽出できているか確認する。でき
      ている。OK

    * done: test: フィールドの x1:x2 が範囲外にはみ出る時に正しくシフトできてい
      るか。

      →うーん。右端に一文字余裕を残した実装になっている。これは意図的な物だっ
      たか。確認する。うーん。xlimit が 29 になっている

      % →と思ったらこれは意図的な物だった。範囲を右端にはみ出ているので xenl
      % のない環境では xlimit を一文字減少させている。

      しかしよく考えたら、シフトを実装した今この取り扱いは不要な気がする。つま
      り、xenl のある端末では別に一番右端まで行っても良い。シフトがあるので右端
      を超えてしまう事はない。一方で、xenl のない端末の場合には常に駄目。

    * ok: 行末で begin-line してその後に改行が入るとどうなるのか。
      即座に end-line して空で終われば良し。そうでなければ対策が必要。

      →うーん。その様な状況があるのだろうか。元々何故このような事を考えたのか
      思い出せない。要するに $'\nhello' 等の様になっている時にどうなるかという事?
      この時は空の文字列が作られて終わるだけの気がする気にしなくて良い。

      と思ったが、現在の実装だと空の行に対しても無駄に処理をしている。この辺り
      は最適化の余地がある。取り敢えず justify_fields と DRAW_BUFF の中身を確認
      して空ならそのまま戻る様にした。

    * done: clip している時にも対応する。これの対応はどの様にするべきか。

      a 内部で再帰的に trace を呼び出して二回処理を行う。この時 opts を構築する
        のが面倒そうである。

      b trace の中身の中心部分を別の関数に分けてそれを二回呼び出す様にする。

      思うに殆どの opts は一回描画内容を決定したら継承しなくて良い気がする。
      寧ろ clip 処理は clip だけに徹するべきの気がする。という観点から考えると、
      方針 a に従って後で clip 用に trace を一回実行するのが良い気がする。

    * reject: 改行をしても別のフィールドには移らないオプション? 同じフィールド内で改行
      を行う。その時には xI:y+1 に戻る。

      また、フィールド内での CR はそのフィールドの開始位置に戻るべきでは。と思っ
      たが元からそういう実装になっていた。

      うーん。そういう事をしたければ \r\v 等とすれば良いのではないか。実際それ
      で動く筈。

    x justify:confine が変な動きをしている。一方で justify:truncate は動いている。
      →これは confine の側のバグだった。修正した。

    * done: 空白の時は空白で fill する。

    [追加修正]

    x \r が含まれている時に振る舞いが変である。→これは \r でフィールドの先頭に
      移動した時に追跡座標 x を正しく設定していなかったのが原因だった。修正した。

    o \v の動作については確認した。恐らく大丈夫。IND/RI も試していない
      が大丈夫だろう。

  * 2021-02-06 tui: trace に clip 機能を実装する [#D1493]
    Ref #T0007

    Note: これは元々 tui 計画の一部として実装した物だったが prompt_status_line
    や prompt_rps1 の為の align 実装に使う為に、trace を大幅に拡張したいという
    事で、独立な commit として適用する事にした。

2021-02-22

  * prompt: status line が最初の起動時に表示されていない [#D1492]

    | 何故だろうか。。。うーん。プロンプトが初期化される前だから? でもプロンプト
    | が初期化されたら…うーん?
    |
    | screen の中だと遅れて statusline が表示されるが、contra の中にいると次に何
    | か新しく表示されるまで何も表示されない。そもそもこの違いは何処から来るのだ
    | ろうか。screen の場合には誰かが invalidate しないと再描画がなされない筈なの
    | である。
    |
    | * screen で何故再描画が実施されるのか。調べてみると何らかのデータを受信した
    |   折に screen の中での再描画が走っている。
    |
    |   DA2R を受信した時に再描画が走っているのだろうと思ったがそうでもない様だ。
    |   contra でも DA2R は受信している。また、DA2R を受信してから一拍置いてから
    |   再描画が走っている様に見える。
    |
    |   もう少し詳しく受信しているバイト列を確認する事にする。
    |
    |   % うーん。分かった気がする。screen が CPR に応答した時に char_width_mode
    |   % が変わって invalidate が起こっているのではないかという気がする。contra
    |   % については CPR に応答していないが為に char_width_mode による invalidate
    |   % が起こっていない、という事なのだろう。
    |   %
    |   % →と思ったがやはり CPR ではない様である。先ず contra は一切 CPR に返事を
    |   % しないのは予想通り。一方で、screen はそもそも char_width_mode についての
    |   % CPR 要求はしていない。何故なら char_width_mode に emacs を指定しているか
    |   % ら自動判定にはなっていないのである。代わりに DECSTBM の判定に使っている
    |   % CPR を受信している。然し、その受信した CPR を完全に無視する様に書き換えて
    |   % もやはり再描画は発生しているのである。
    |
    |   再描画が起こっている理由について調べる。$caret_state が変化している事によ
    |   る再描画の様子である。
    |
    |   ? yes: というより本当にこの dirty の判定の所まで到達しているのだろうか。
    |     もっと前の段階て撥ねられていないだろうか。と思ったが、大丈夫の様だ。こ
    |     の判定の部分までは到達している。
    |
    |   caret_state の値について出力して確認してみる。
    |
    |     contra 内部       screen 内部
    |     ----------------  ------------------
    |     old=0:0:0:::      old=0:0:0:::
    |     new=0:0:0:::      new=0:0:0:::
    |     dirty:2           dirty:2
    |     old=0:0:0:::      old=0:0:0:::
    |     new=0:0:0:::      new=0:0:0:::
    |     dirty:clean       dirty:clean
    |     old=0:0:0:::
    |     new=1:0:0:::
    |     dirty:3
    |     chars=(DA2R...)   chars=(DA2R CPR)
    |                       CPR ble/term/t
    |     old=1:0:0:::      old=0:0:0:::
    |     new=1:0:0:::      new=0:0:0:::
    |     dirty:clean       dirty:clean
    |     old=1:0:0:::      old=0:0:0:::
    |     new=1:0:0:::      new=1:0:0:::
    |     dirty:clean       dirty:3
    |
    |   起動の振る舞いを見ると contra の場合には、CPR DA2R の応答を貰うよりも前に
    |   再描画の機会がある様だ。うーん。
    |
    |   ? 不思議な事に keymap_vi_load の実行は比較的最初に済んでいるという事であ
    |     る。もう一つの不思議な事は contra の内部でも dirty:3 が発生しているのに
    |     も拘らず prompt update が実行されていないという点。prompt の update の
    |     条件についても確認するべき気がする。
    |
    |     どうやらプロンプトが更新されたりされなかったりするのは history を読み込
    |     んだり読み込まなかったりする事による物のようである。何故端末が異なると
    |     history の読み込みに影響が出るのかは謎である。しかも、確率的にではなく
    |     て確実にそれぞれの端末で異なる一貫した動作になっているのも不思議な事で
    |     ある。

    [状況]

    最初に描画する瞬間は未だ keymap も読み込んでいない状態なので keymap_vi_load
    を経由して設定される prompt_status_line も表示されない。その後で
    keymap_vi_load が実行され、更にその後で再描画がかかる。

    違いは再描画がかかるタイミングが contra の中と screen の中で何故か異なる事
    によって出てくる様に見える。

    * keymap_vi_load との前後関係は実は関係ない。再描画がかかるのは何れにしても
      既に prompt_status_line が初期化された後の話なので、もしプロンプトの更新
      がかかるのであればどちらの場合でもちゃんとステータスラインが表示される筈
      である。

    * 代わりにコマンド履歴の読み込みのタイミングとの前後関係が問題になっている。
      screen の中では DA2R, CPR を受信した後に再描画が起こるが、この段階でコマ
      ンド履歴が読み込み済み状態になっている。これにより再描画に際してプロンプ
      トの再計算が実施される。一方で contra の場合には DA2R を受信する前に再描
      画がかかって、この時には未だコマンド履歴が読み込まれていない。この為に、
      プロンプトの更新の必要がないと判定されてプロンプトの更新無しで再描画だけ
      が行われている。

    何れにしても設計としてはプロンプトの設定を変更したら ble/prompt/clear を実
    行するべきで、更に、ble/prompt/clear を実行する時には
    ble/textarea#invalidate も実行するべきという事。

  * global: IFS 対策 [#D1491]

    多くの関数は IFS が普通の値になっているという事を前提にして書かれている。
    ble.sh の中では一時的に IFS を設定して動作する様になっているが、
    ユーザーから使用された時に IFS に変な値が設定されている可能性は排除でいない。

    * 引数を $* で渡された時の対策は取り敢えず grc -F で ${* もしくは $* に一致させて確認した。
    * 配列に対する単語分割 =($...) に関してもチェックは行った。

    * 他に配列を結合する処理に関しても注意が必要になる可能性がある。
      つまり、aa="${arr[*]}" の形の処理である。

      grc '\$\{[[:alnum:]_]+\[\*\]' --exclude={test,ext,wiki}

      取り敢えずこれも大体対応した。

    * builtin read も IFS に依存して振る舞いが変わる。

    他にも IFS が影響を与える様な状況はあるだろうか。恐らく他にもあると思うが、
    すぐには思い浮かばないので取り敢えずこれぐらいで良いだろう。

  * global: 現在様々な関数が引数として text... を受け取っているが [#D1490]

    実の所複数の引数を受け取る事に意味は余りない。
    実際に複数の引数をこれらの関数に渡している箇所があるとは思えない。
    現在は毎回 IFS を設定してこれらの引数を結合する様にしているが、
    そもそもその様な処理すら必要ないのではないか。

    * done: (main) ble/util/put
    * done: (main) ble/util/print
    * done: (util) ble/string#escape-*
    * done: (util) ble/string#{toggle-case,toupper,tolower}
    * done: (util) ble/string#[lr]?trim
    * done: (util) ble/string#capitalize
    * done: (util) ble/util/buffer
    * done: (util) ble/string#split-lines
    * done: (util) ble/util/idle.push
    * done: (vi) ble/keymap:vi/string#encode-rot13
    * done: (complete) ble/complete/cand/yield
    * done: (canvas) ble/canvas/put.draw
    * done: (edit) ble-edit/hist_expanded.update
    * done: (edit) ble/widget/(in|ex)ternal-command
    * done: (edit) ble/widget/execute-command

  * global: ロード時にエラーが出る (reported by 0neGal) [#D1489]
    https://github.com/akinomyoga/ble.sh/issues/85

    bash: ((: 4 0: syntax error in expression (error token is "0")

    うーん。 "4 0" という文字列が何処から混入するのかという事。
    "4 0" という文字列があるという事は何処かにそういう変数が存在しているという事?
    と思って declare -p の結果を grep で検索して 4 0 の組み合わせを探そうとしたが見つからない。
    配列に、要素を跨ってその様な値が格納されているのかとも思ったが、そうでもない。

    だとするとグローバル変数ではなくて内部で一時的に生成された文字列に問題が起きているという事?

    ((${#aaa[*]})) となるべき所を ((${aaa[*]})) にしてしまっているというのが怪しい。
    と思ったが m scan で引っ掛からない。
    sub:scan/array-count-in-arithmetic-expression でちゃんとチェックしている。

    3588158 で発生している。前に動いていた時はいつの version かと思ったが、
    どうも 0.3.3 を動かしていた様なので実は 0.4 でも前からずっと問題があった可能性もある。

    うーん。エラーメッセージから察するに "4 0" が完全な算術式として評価されよう
    としているという事。これにより ((...)) の形のコマンドで発生しているとすると
    かなり発生箇所を制限する事ができる。

    | ./lib/core-complete.sh:2847:      ((${simple_ibrace%:*})) && comps_fixed=1
    | ./lib/core-complete.sh:3282:      if ((${simple_ibrace%:*})); then
    | ./lib/core-complete.sh:3293:      if ((${simple_ibrace%:*})); then
    |
    |   simple_ibrance に値を設定している箇所は限られている。そしてその何れの場所
    |   でも確実に 数字:数字 の形になっているので、変な事が起こる余地はない。
    |
    | ./src/canvas.sh:1725:    (($3)) && ((x=0,y++))
    |
    |   ble/textmap#hit/.getxy.cur の第三引数…ではなかった。ここでは textmap 配
    |   列に含まれる単語を分割している。もしかして IFS に変な値を設定されていると
    |   いう事? と思ったがその影響が残っているのだとしたらもっと色々な大変な事が
    |   起こってしまう筈。そして実際に IFS= にして起動してみたが特にエラーメッセー
    |   ジは出ていない。
    |
    |   もう一つここが違いそうな理由は、報告によると起動時のみに問題が起こるとい
    |   う事であった。然し、もしここが本当に問題になるのだとしたらそれ以降もずっ
    |   と危ない感じになる気がする。
    |
    |   何れにしてもこの部分はもっとまともな実装に置き換えて良い気がする。
    |
    | ./src/color.sh:955:    (($name)) && return 0
    |
    |   name=_ble_faces__$1 としているので此処からは '4 0' という値は出てこない。
    |
    | ./src/util.sh:3244:    (($2))
    |
    |   これは ble/util/test-rl-variable の第二引数である。使用箇所を確認したが第
    |   2引数はそもそも指定していないか指定していたとしても 1 か 0 である。なので、
    |   これも違うだろう。

    然し、変数に alpha='4 0' 等の値が入っていてそれを ((alpha)) 等として実行し
    た場合にも同じエラーメッセージが発生するので本当にこの部分で発生しているの
    かというのは分からない。一方で $(()) の中で実行した場合にはエラーメッセージ
    が異なる物になるので、やはり (()) の中で発生しているというのは確定して良い。

    もしかすると bashrc の内部で ble-attach すると問題が発生する可能性?

    できた。再現できた。IFS= を ble-attach の直前に記入すると問題が生じる。

    どうやらコメントに依ると unset IFS にしている様である。という事は…。ble.sh
    をロードした時に unset 状態の IFS を保存して復元する時に空文字列になってし
    まうのが問題の原因になっている。

    * done: IFS の unset 状態も復元する様にする。復元する様にした。

    更にその後で空文字列の IFS が問題を引き起こしている。掘り下げていくと
    textarea#redraw の中で問題が発生している。

    * done: 空の IFS でも単語分割ができる様に個々の関数を書き換える。

      * 結局 ble/textmap#getxy.cur の問題だった。先に上で修正したと思っていたが
        修正漏れがあった。これで動く様になった。

      * 他にも IFS=$' \t\n' でないと動かない様なコードはないだろうかと調べると
        ble/canvas/trace の sc/rc がそれだった。修正した。

      * 他にも ble/textmap#update の中でも単語分割を使っている様子だったが、こ
        れは関数の先頭で IFS を設定しているので問題にならない。
        ble/string#split-words で書き換えようと思ったが performance の問題だろ
        う。そのままにしておく事にした。

      * 他のファイルも探したら沢山あったのでこの際全て修正する事にした。他にも
        IFS の値で振る舞いが変化する物は沢山あるのでこれだけで local IFS=$'
        \t\n' しなくてよくなったりはしないが、念の為変な動作を起こさない様にし
        ておく。

    x fixed: 全部直した筈だと思ったが ble-bind がエラーを出力している。
      →"$*" の類も全て IFS を気にする必要がある。取り敢えず util.sh の関数については
      IFS の値に拘らず動作する様に修正した。

  * keymap/vi: vim mode strings の設定をもっと柔軟にできる様にする (motivated by 0neGal) [#D1488]
    https://github.com/akinomyoga/ble.sh/issues/85

    Note: 0neGuyDev は名前が 0neGal に変化した様だ。

    * done: wiki vim のページ hook の説明で := の : が余分。
    * done: wiki vim の設定のページで全ての項目に注意書きを書く。

    何れにしても Cygwin での IL/DL の問題 (#D1482) に取り敢えずの決着をつけてから。
    →IL/DL の問題を解決したが未だ status line の問題 (#D1487) は残っていた。
    その後 status line の問題も解決した。

    どうやら Vim では mode() を用いて現在のモードを表現する文字列を取得する事が
    できるらしい。然し、mode() だけでは表しきれない情報も存在する様である。取り
    敢えず似た関数を用意さえすれば既存の枠組みを使って mode を status ilne に表
    示する事ができるのではないか。

    | Mode                                                                                          | `mode()` |
    |:----------------------------------------------------------------------------------------------|:---------|
    | INSERT                                                                                        | i        |
    | REPLACE<br/>VREPLACE                                                                          | R        |
    | NORMAL<br/>(insert)<br/>(replace)<br/>(vreplace)                                              | n        |
    | VISUAL<br/>(insert) VISUAL<br/>(replace) VISUAL<br/>(vreplace) VISUAL                         | v        |
    | VISUAL LINE<br/>(insert) VISUAL LINE<br/>(replace) VISUAL LINE<br/>(vreplace) VISUAL LINE     | V        |
    | VISUAL BLOCK<br/>(insert) VISUAL BLOCK<br/>(replace) VISUAL BLOCK<br/>(vreplace) VISUAL BLOCK | ^V       |
    | SELECT<br/>(insert) SELECT<br/>(replace) SELECT<br/>(vreplace) SELECT                         | s        |
    | SELECT LINE<br/>(insert) SELECT LINE<br/>(replace) SELECT LINE<br/>(vreplace) SELECT LINE     | S        |
    | SELECT BLOCK<br/>(insert) SELECT BLOCK<br/>(replace) SELECT BLOCK<br/>(vreplace) SELECT BLOCK | ^S       |

    これらは基本的にはそのモードに入る為に使うコマンドが使われる。
    然し、normal の n や select の s は名前から来ている。

    これに倣えば。拡張するとしたら VREPLACE は gR になるだろうか。
    insert, replace, vreplace は それぞれ i^O R^O gR^O になる。
    でもどうせ組み合わせるのであれば、実の所 ^O は必要ないのではないか。

    つまり、/(i|R|gR)?(n|v|V|^V|s|S|^S)?/ - ε (4x8-1=32-1=31種) という事になる。

    うーん。サンプルを見ると Rv というのが存在しているが実際に試してみると R に
    なっている。何故だろうか。後、やはり gR というのは都合が悪い気がする。
    vreplace の文字はまた別に考えたい。小文字の r を考えたがどうやら既に PROMPT
    というのの為に使われている様だ。だとすると ^R という事になるだろうか。うー
    ん。取り敢えず ^R という事にする。そもそも制御文字を使うとうのが良い事なの
    か微妙だが。RSTUV で何れも近い値というのも比較的良い事の気がする。

    * テストに用いた vimrc を移動する。

  * edit: prompt_status_line の表示が崩れる [#D1487]

    | prompt_status_line を試しに組み合わせて見たら表示がおかしくなっている。うー
    | ん。status の報告する文字列の高さが間違っているのが原因かとも思ったがそうで
    | もない。常に高さ1を強制する様に書き換えてみたがそれでも同じ問題が発生してい
    | る為である。
    |
    | という事はスペースを確保する時のコードが間違っているという事だろうか。これ
    | は丁度 stub branch で議論している物と関係する。というより stub branch の方
    | で何か修正を入れた気がする。その修正を適用してからこの問題が未だ継続してい
    | るか調べてその上で対処するべきだろう。
    |
    | →どうやら問題は継続している様だ。何故だろうか。なぜか知らないが高さを確保
    | できていないのが原因である。

    [再現]

    prompt_status_line を表示してかつ keymap_vi_mode_show= を使って vim mode
    string を表示しない設定にすると、一番下の行でコマンド実行した後に status
    line が消去されずに複製されて残ってしまう。

    振る舞いを調べると高さの確保は一応している様子である。毎回 1->2 に増やして
    いる。コマンドを実行した直後には高さ 1 という事になっている為であろう。然し、
    問題点が幾つかある

    * コマンド実行中にはステータス行は消去する筈なのに消去されていない。うーん。
      実装によるとコマンドを実行する前に ble/prompt/status#collapse を呼び出す
      事になっている。そして其処では set-height を用いてステータス行を消去する
      事になっている。然し消去できていない。

      調べてみるとそもそも status#collapse が呼び出されていない?? いや、これは
      呼び出されている。という事は set-height の途中で消えているという事であり、
      それはつまり元から高さが 0 だったという事。高さが増える事なく status line
      が表示されていたという事である。

    うーん。何かと思ったら reallocate-height.draw が呼び出されていない。現在の
    実装では他のパネルの高さが不整合になっていない限り reallocate-height.draw
    は呼び出されないのである。うーん。取り敢えず status#panel::render の中で
    reallocate-height.draw を試みるべきだろうか。

    status#panel::render の中で現在の高さを確認して足りなければ再配置を要求する
    様に変更した。これで OK の筈。これによって textarea の方に皺寄せが行く可能
    性もあるが、取り敢えずはこれで良い事にする。また後で reallocate-height につ
    いては考え直すのが良い→別項目を立てた。

  * decode: rlfunc.txt ファイルを移動する [#D1486]

    * .srcoption の中身も更新した。
    * GNUmakefile も書き換えた。
    * decode.sh も書き換えた。
    * 他に make_command.sh と vi.sh の中で言及していたファイル名を書き換えた。
    * 序でに散らばっていたテスト用のファイルをリポジトリに追加しておく。

  * term: screen で attach した時に時々 _ble_term_* が壊れる現象 [#D1485]

    screen で attach すると何故か色々壊れる現象があったが、どうも contra からの
    DA2R がそのまま screen の内部の shell に伝播しているという事の気がする。
    DA2R を受信した時に最初に受信した時の値を保持する様にするべきではないか。
    もしくは一旦受信したら blehook で削除しておく。

2021-02-21

  * decode (rlfunc): vi-replace in imap, vi-editing-mode in nmap (reported by onelittlehope) [#D1484]

    それから vi-replace in imap 及び vi-editing-mode in nmap は未実装である。

    * vi-editin-mode in nmap: 先ずは vi-editing-mode を vi-command で使うと何が
      起こるのかについて確認する。→どうやら vi_nmap を抜けて imap に戻る様であ
      る。うーん。これは単に vi_nmap/insert-mode にすれば良い気がする。

    * vi-replace はどうやら replace-mode に入る為のコマンドの様だ。そしてこれは
      insert と同じで良いのではないか?? と思ったがうーん。vi-command では "R"
      に割り当てられている。つまり、文字幅に応じた replace-mode に入るべきであ
      る。

      | vi_imap でも同等の replace-mode に入るための widget を追加するべきだろう
      | か。と思って、vi_imap/normal-mode-without-insert-leave &
      | vi_nmap/replace-mode を組み合わせて新しい widget を作りかけていたら、どう
      | やら既に存在していた様だ。vi_imap/overwrite-mode である。というより、既定
      | の insert がこれになっていた。
      |
      | なので作りかけた以下の関数は廃止。
      |
      | function ble/widget/vi_imap/replace-mode {
      |   ble-edit/content/clear-arg
      |   _ble_edit_mark_active=
      |   _ble_edit_overwrite_mode=R
      |   _ble_keymap_vi_insert_overwrite=R
      |   ble/keymap:vi/update-mode-name
      | }

      所で、既存の vi_imap/overwrite-mode は ble-edit/content/clear-arg がない
      が良いのだろうか。と思ったが、よく考えたら vi_imap では引数を指定する方法
      が存在しない。という事を考えたら別になくても良いという事なのだろうか。ま
      あ、ble-edit/content/clear-arg して困る事はない。もしかすると誰かが
      vi_imap でも arg を設定できる様に binding を追加するかもしれない。

    結局二つとも既存の widget を辞書に登録するだけで済ませる事にした。

  * decode (rlfunc): 既存の束縛の読み取り時にエラー (reported by onelittlehope) [#D1483]
    https://github.com/akinomyoga/ble.sh/issues/89

    二種類の問題がある。

    * 一つは LC_CTYPE であろう。現在のエンコーディングに一致しないバイト列が文
      字列に含まれている場合、bash の正規表現は一致に失敗する。もしくは何か変な
      一致の仕方をする。

      $ alpha=$'"\x9B": self-insert'
      $ rex='^"[^"]*$'
      $ [[ $alpha =~ $rex ]]

      然し実際に試してみたがそんな事は起こっていない。susu-linux の regcmop は
      振る舞いが違うという事なのだろうか。これについては no closing ... という
      メッセージを出している部分をもう少し詳しく見る必要がある。

    * もう一つは vi_imap/vi_nmap で vi-replace/vi-editing-mode に対応していない
      という事。これは単に対応していないというだけの事なのでできるだけ対応する
      様にする。

      然し、以下は期待通りに動いている。

      rex='^"([^\"]|\\.)*$'
      [[ $'"\x9B": self-insert' =~ $rex ]]; echo $?

      できた。再現できた。

      bind '"\x9b1;2H": beginning-of-line'
      source ble.sh

      更に良くメッセージを見ると正規表現でテストを実行する前に既に文字列が削れ
      て '"' だけになっている。

      →これについては修正した。

    https://github.com/akinomyoga/ble.sh/issues/89#issuecomment-782824259
    追記: 簡単なミスをしていた。修正する。

    https://github.com/akinomyoga/ble.sh/issues/89#issuecomment-782827987
    追記: まだ駄目だった。何度でも同じミスをしている…。ちゃんと実際にテストしなければならない。

2021-02-20

  * term: Cygwin console で最終行で IL/DL すると画面消去されるバグ [#D1482]

    Solaris に加えて Cygwin console も何だか変な振る舞いをしている。
    どうも一番下の行で .insert-newline をすると画面の内容が全て消える。
    分かった。どうやら一番下の行で IL すると問答無用で画面クリアされる。
    これは明らかにバグである。Cygwin をアップデートしてみる事にする。

    →cygwin を update して見たが修正されていない。なので、結局 ble.sh の側で対
    策をしなければならない。この様な壊れた IL に対して対策を実行する事は可能な
    のだろうか。

    * 取り敢えず現在位置が分かっていれば対応は可能である様に思われる。一番下の行
      にいる時には IL の代わりに CSI 2K を実行すれば良い。それ以外の行にいる時に
      は特に問題は起こらない様だ。

      うーん。最下部にいるかどうかで振る舞いを変えるのは難しい気がする。取り敢
      えず複数行の IL, DL の時にはちゃんと計算ができていれば最下行になる事はな
      い。問題は単一行の IL 及び DL で以下に最下行での IL/DL を避けるかという事。

      最下行にいない時には以降の内容を下に一行ずらす役割がある。うーん。それよ
      り下に内容があると分かっている場合には IL/DL を実行し、それより下に内容が
      ないという場合には DL を実行するというのが可能な対策方法である。

      うーん。かなり面倒臭い。というより CYGWIN の側で修正してもらえばこの様な
      面倒な事はしなくても良い筈なのである。取り敢えずこの workaround の為に本
      体の描画アルゴリズムを変更する事はしない事にする。

      IL/DL の中だけで対策可能であればそれを実施する。そうでなければ何もしない。

      例えば IND CUU を実行して一番下の行にダミー行を挿入して、その上で DL/IL
      を実行してから、RI かスクロールを実行してまた元に戻すという実装は可能だろ
      うか。→ SD,SU を実行してみたが消えてしまった行は戻ってこない様である。RI
      も同様に一度消えた内容が戻って来る物ではない。うーん。現在最下行にいるか
      どうかを判定して動作を切り替えるしかないのか。

    | a 結局 DSR(6) で現在位置を問い合わせて一番下の行にいる時には CSI 2K で行
    |   消去する事にした。
    |
    | x これで以前よりも全画面消去が起こる場面は減ったが、それでもやはり全画面消
    |   去が依然として発生している。何故だろうか。IL/DL を実行している箇所は既に
    |   全て抑えてある。とすれば IL/DL とは別に未だ全画面消去を引き起こす物が存在
    |   しているという事。
    |
    |   問題が発生している場所での出力内容を確認すると
    |
    |   ^[(B^[[m^[[1B^M^[[2K^[[1M^[(B^[[m^[[1A^[[31C^[(B^[[m
    |
    |   printf '\e(B\e[m\e[1B\r\e[2K\e[1M\e(B\e[m\e[1A\e[31C\e(B\e[m'
    |
    |   うーん。全消去が起きそうな気配は何処にもない気がする。と思ったが、よく見
    |   たら DL(1) が含まれている。これは一体何処から現れたのだろう…。あー。分かっ
    |   た。。DSR(6) で問い合わせする前に flush しないと駄目だ。
    |
    |   そして各スタックにある DRAW_BUFF にアクセスして出力予定の内容を全て集めて
    |   flush しなければならない。然し、DRAW_BUFF の中には取り敢えず内容を構築し
    |   て保存する為の物だったり、後で再解釈する為の物だったりする可能性もあり、
    |   一律に出力して良い内容7日どうかも分からない。という事を考えると put-il,
    |   put-dl の中で現在位置を検出して出力するという対策は全然駄目である。
    |
    |   | if ((_ble_bash>=40000)) && [[ ( $OSTYPE == cygwin || $OSTYPE == msys ) && $TERM == xterm-256color ]]; then
    |   |   # Cygwin console (pcon) では最終行で IL/DL すると画面全体がクリアされる。
    |   |   function ble/canvas/.put-il.workaround {
    |   |     local count=$1
    |   |     ((count==1)) || return 1
    |   |
    |   |     # Cygwin console 以外なら対策不要
    |   |     [[ ! $_ble_term_DA2R ]] || return 1
    |   |
    |   |     # 現在のカーソル位置の取得
    |   |     local reply=
    |   |     printf '\e[6n' >/dev/tty
    |   |     IFS= read -r -d R -t 0.1 reply </dev/tty
    |   |     local rex='([0-9]*);([0-9]*)'
    |   |     [[ $reply =~ $rex ]] || return 1
    |   |     local l=$((10#${BASH_REMATCH[1]}))
    |   |     local c=$((10#${BASH_REMATCH[2]}))
    |   |
    |   |     ((l==LINES)) || return 1
    |   |
    |   |     DRAW_BUFF[${#DRAW_BUFF[*]}]=$_ble_term_el2
    |   |     return 0
    |   |   }
    |   |   function ble/canvas/put-il.draw {
    |   |     local value=${1-1}
    |   |     ((value>0)) || return 0
    |   |     ble/canvas/.put-il.workaround "$value" && return 0
    |   |     DRAW_BUFF[${#DRAW_BUFF[*]}]=${_ble_term_il//'%d'/$value}
    |   |     DRAW_BUFF[${#DRAW_BUFF[*]}]=$_ble_term_el2 # Note #D1214: 最終行対策 cygwin, linux
    |   |   }
    |   |   function ble/canvas/put-dl.draw {
    |   |     local value=${1-1}
    |   |     ((value>0)) || return 0
    |   |     ble/canvas/.put-il.workaround "$value" && return 0
    |   |     DRAW_BUFF[${#DRAW_BUFF[*]}]=$_ble_term_el2 # Note #D1214: 最終行対策 cygwin, linux
    |   |     DRAW_BUFF[${#DRAW_BUFF[*]}]=${_ble_term_dl//'%d'/$value}
    |   |   }
    |   | fi
    |
    | b 別の手段を考える。一番上の行を犠牲にする事になるが SU/SD を組み合わせる。
    |
    |   DRAW_BUFF[${#DRAW_BUFF[*]}]=$'\e[S\e[A\e[M\e[B\e[T'
    |
    |   うーん。一応動いている様な気がするが、この対策法の問題点は DA2 を返さない
    |   端末で SU/SD に対応してない物があると描画がずれてしまうという事である。
    |
    |   あとちらつきが激しく出ているという事。やはり対策を実施するのは最
    |   低限にしたい。
    |
    | c また別の手法。一番下の行は諦めて DL/IL をする前に必ず IND/CUU を実行して
    |   一番下の行は使わない様にするという作戦。これは実際に試してみた所レイアウ
    |   ト崩れるので使えない。

    改めてそれぞれの方法の問題点について整理する

    a DSR(6) で問い合わせて判定する方法。

      o この方法は出力をキャッシュしていなければ確実に最終行を判定できる。

      x 然し実際にはカーソル移動なども含めて出力内容を複雑にキャッシュしている
        ので、その場で現在位置を取得したとしても全く意味がない。キャッシュを
        flush するにしても、それぞれのキャッシュがその場で画面に出力する事を想
        定した物でない場合もあり困難。

    b SU/SD の組み合わせを用いる。

      x 一番上の行の内容が犠牲になる。
      x 画面がちらつく。

        o これについては panel 内部で動作している限りは panel の最終行にいる時
          にだけ対策をする。これでちらつきはある程度抑える事ができる。それでも、
          panel の最終行にいる時にはちらつきが出るが、そもそも本当に最終行にい
          る時のちらつきは抑える事ができないので、我慢する。

      x Cygwin console であると誤判定した時に、その端末が SD/SU に対応していな
        いと悲惨な事になる。

    c 一番下の行は常に空になる様にしておく。

      x 使える領域が一行減ってしまう。
      x 今までの座標計算が狂ってしまうので注意深く全体を書き直す必要がある。

    d panel で一番下の行にいると分かっている時は単に EL(2) で良い。

      panel で一番下の行にいるという事が分かっている場合には、IL を一番下の行
      で実行する代わりに単に端末の最上部で DL をすれば良いのではないだろうか。
      と思ったが全然違う結果になるので駄目だ。

      或いは panel で一番下の行にいるという事が分かっているのであれば何処か別
      の行で IL/DL すれば良いのではないか。と思ったが、それだと端末最終行にい
      なかった時にずれるべき内容がずれずに残るのではないか。と思ったが、そも
      そも panel 外の内容に関しては関知しなくて良い。

      整理すると panel で一番下の行にいる時、panel の最上部で IL/DL を実行す
      る。その上で panel の最下部で EL(2) を実行すれば良い。うーん。実は最下
      部で EL(2) を実行するだけで良い気がしてきた。

    結局 b に d を組み合わせて実装した。どうも既存の IL/DL は全て panel 管理下
    にある様だ。という事なので実は実質的に d だけでうまく行くという事。

    x fixed: と思ったがどうも SU/SD の対策がコマンドを実行する度に発動している
      様子だ。と思ったがこれは単純ミスだった。opts=$2 を忘れて opts を使ってい
      た。

    ? IND を \n にして見たが微妙かもしれない。端末によっては現在の x の位置をずらしてしまうから。
      然し、現在の設計では ind によって位置がずれてしまう事も想定しているのではなかったか。

      と思ったが IND に対応していない物も沢山ある様だ。なのでやはり \n に頼るべきなのだろう。

      IND を使っている箇所について改めて確認する必要がある。ちゃんと x=0 にしているか?

      →どうも _ble_term_ind の使用は canvas.sh の中で閉じている様子である。
      put-ind.draw も内部でしか使われていない。殆どの箇所で既に対策済みか或いは
      元から column 0 にいる状態で使っている。

      問題に成るのは ble/canvas/put-move-y.draw の内部での使用で、mc の中で動作
      している時には CUU の代わりに IND を使っている。put-move.draw が何処で使
      われているか確認すると相対移動・noscrc で使っている。_ble_term_{sc,rc} も
      使えないし、相対移動なので後で絶対位置を指定して補正というのも使えない。
      ここは IND/LF で col が移動しない状況で使われていると期待するしかない。

      →うーん。現在の init-term だと LF が優先されてしまう。IND に端末が対応し
        ている事を期待して $'\eD' を使った方が安全に思われる。

  * term: sum (Solaris console) IND/RI が使えない。他色々動いていない [#D1481]

    * RI が使えない時にどの様にすれば良いか。

      * 使っている箇所の一つは vbell である。

        例えば prompt の上の行に一行 IL するという方針だと…。vbell を表示する度
        にずれてしまう。今ここで欲しいのは "上に一行も余裕がない時限定で一行確保
        する" という機能である。

      * ble/canvas/put-ri.draw

        これは2箇所から使われている。両方とも
        ble/canvas/panel/ensure-tmargin.draw という関数の中から使われていて、この
        関数は vbell から使う為の物である。

      * ble/canvas/panel#clear-after.draw
        これは単に cuu に置き換えれば良い気がする→置き換えた。

      結局 vbell が問題になる。_ble_term_ri が空の時に別の手法で vbell を表示す
      る?

      a 例えば xterm_title を使って表示するか。

        元から設定されている値を保存・復元したりするのが面倒である。push/pop の
        エスケープシーケンスも存在するかもしれないが、それに対応しているかどう
        かの判定も面倒である。というより RI を対応していない端末が xterm title
        等に対応しているとは思えない。この手法は追求しても余り意味がない。

      b 或いは、一番下の行に表示するというのは可能だろうか。

        この方法を取る場合には現在の canvas の tmargin の取り扱いを工夫しなけれ
        ばならない。というか RI が使えない場合には canvas の tmargin も振る舞い
        が微妙な気がする。

      c もしくは _ble_term_ri を使わずに被っても良いので先頭行を使う。

        然し、やはり内容が上書きされてしまうというのは都合が悪い様に思われる。

      d もしくは毎回一番上に行を挿入する。

        この方法だと bell が表示される度に行がどんどん下の方に移動してしまって
        余り嬉しい事にはならない。一応 IND を使って下に行きすぎない様に調整する
        事はできる。top/bottom dock に分かれている場合には制御が面倒である。

        現在の ble/canvas/panel/ensure-tmargin.draw の実装について確認する。
        DECSTBM が存在する場合には、スクロール領域を設定して bottom dock を固定する。
        その上で RI を実行して canvas 原点の上に tmargin 行だけスペースを確保する。

        それ以外の場合には即座に RI で canvas 原点の上にスペースを確保する。
        bottom に関しては破壊されてしまうのは我慢して invalidate する。

        さて、RI が使えない場合にどの様に内容をシフトするのか。場合分けして考え
        る。DECSTBM が使える場合にはやはり bottom dock を固定して於いて、その上
        で、top_height+tmargin だけ IND を実行する。これで少なくとも top dock
        の下に tmargin だけのスペースができる。その後で IL を一番上で実行すれば
        良い。

      うーん。完全ではないが d の方針で何とか誤魔化す事にした。

    * done: modifyOtherkeys がそのまま出力される。

      これは linux や minix と同様に出力しない様に変更。

    * done: home csi 214 z / end csi 210 z

      これは contra の escseq.html にまとめてある物に一致する気がするので確認する。

    * done: OSC がそのまま出力されている

      面倒なので xterm_title の所で直接 term の判定を行って切り替える。
      OSC を無視できるかどうかを各 OS のコンソールで確認する。
      freebsd, linux, haiku ではちゃんと無視できている。
      minix 及び sun は失敗している。

    * prompt_eol_mark 関連のカーソル移動に使われているシーケンスにも問題のある
      物がある。_ble_term_sc, _ble_term_rc の既定値が \e[s, \e[u になっていたが、
      これらは寧ろ少数派なので \e7, \e8 に切り替える事にした。Solaris では
      terminfo に \e7, \e8 は載っていないが実際には使える。

      また _ble_term_xenl に関しても terminfo になかった事から既定で 1 になって
      いたが、Solaris では 0 にする必要がある。修正した。序でに xenl がない時に
      は 0 ではなくて空文字列にする事にする。

    x ok: RI がない時の vbell の振る舞いが駄目。再度実装を確認する。
      うーん。幾らか修正して、更に必要な時にだけ高さを確保する様に変更した。

      そもそも sun console は下から出ていくと上に戻るという変な振る舞いをするの
      でまともに対応するのが難しい。適当な所で良しとするのが良い。

    * done: delete キーで ^? (DEL) が送信される。これについては TERM=sun* の時
      に ^?  を delete に変換して対策する事にした。実は既に infocmp kdch1 が ^?
      の時にはこの対策が実施されていたが、sun* の terminfo に kdch1 が登録され
      ていなかったのが原因だった。

    x 文字 x が入力できない。emacs にするとちゃんと入力できる。.blerc を別名に
      すると入力できる。と思ったがこれは set -o vi が実行されなくなるからだった。
      更に時々 segfault もする。またランダムな文字列を実行しようともする。

      これは恐らく "x?" で bind が形成されてその後でそれが削除される事により、
      x 単体の入力に対して出鱈目な文字列が実行されているという事なのだろう。
      では誰が x に bind しているのだろうか。。不思議である。

      うーん。inputrc は存在していないし、bind は特に直接呼び出されてはいない様
      だし、という事を考えると ble.sh で呼び出している builtin bind が問題を起
      こしているという事なのだろうか。

      generate-source-to-unbind-default の出力を保存してそれを読ませてみたら
      問題が発生するという事が分かった。特に問題のある行もない…と思いきや、

      builtin bind -r 'x1c' (bash-4.1)

      という変な行が混入している。これは一体何処から出てきた物だろうか。普通に
      動いている環境で実行してみると

      builtin bind -r '\x1c' (bash-4.4)

      という結果になっている。つまり、これは bash-4.1 特有の処置ではなくて一般
      に行われている処置である。

      問題の箇所を確認してみると awk で sub(/.../, "\"\\x1c\"") としている。
      つまり Solaris awk はこの \\ を消してしまうという事。と思っていたら、
      既にその問題点についてコメントに書かれていた。'\'' に対しては対策されていたが、
      直接 \ が現れる場合については対策されていなかったのが原因。
      特に \x の組み合わせが x に変換されてしまうという問題の様である。
      \x についても対応すると共にコードの整理を行った。

  * complete/mabdb: man awk の内容を抽出しきれていない [#D1480]

    先ず .PD という行が挿入されている事が原因の様である。
    .PD という行は皆無視しても良い様な気がしたので無視する。
    更に、複数のオプションに対して一つの説明がなされている場合に対応した。

    キャッシュファイルは LANG 毎に別にするべき気がする。特に LC_MESSAGES に従って
    設定するべき。

  * edit: "echo " の状態で \C-x\C-v するとバージョン情報が灰色 [#D1479]

    これは外部コマンドを実行する時に sgr0 をちゃんとしていないのが原因。何処で
    sgr0 をすれば良いのかと悩んだが取り敢えず insert-newline は新しい行に行くと
    いう意味なのだから sgr0 するのが自然である。他に外部コマンドを実行する瞬間
    にも sgr0 を実行する。

  * bash-4.4 で emacs mode で C-x * が効かなくなっている [#D1478]

    vi から emacs モードに切り替えると emacs モードで C-x が効かない。
    keyseq-timeout が長い時には問題は起こらない。

    [状況]

    | これは keyseq-timeout が関係している様だ。更に、一度 emacs モードにしてしま
    | うと、vim モードに戻しても依然として効かない状態が続いている。
    |
    | keyseq-timeout を長く設定してみたところ問題は発生しなくなったので、これはつ
    | まり "C-x ?" の組み合わせで 登録してキーを読み取ろうとしている事自体に何ら
    | かの問題があるという事なのだろう。という気がする。
    |
    | 然し vi に戻しても問題が持続しているのは不思議な事である。詳しく調べてみる
    | と vi に戻すと C-x 一回の入力に付き C-x が2回入力されている様子である。不思
    | 議な事である。
    |
    | * 普通に emacs モードから始めた場合には問題は起こらない。
    | * 同じモードで detach/attach しても問題は起こらない。
    | * 一回のコマンドで ble/decode/detach; ble/detach/attach しても問題は起こらない。
    | * ble-detach して set -o して ble-attach すると再現する。
    |
    | % 問題の一部は分かった。unbind cache に於いて "C-x ?" の組み合わせについて
    | % emacs モードの時にしか unbind していない。然し、これはモードに拘らず
    | % unbind するべきではないのか。つまり、set -o でモードを切り替えた時には元々
    | % と異なる keymap になっている為に [[ -o emacs ]] で判定したのと異なる
    | % keymap に作用する可能性がある? と思ったがそれは変だ。[[ -o emacs ]] になっ
    | % ているのであれば実際にその keymap になっている筈だし、unbind する時には一
    | % 旦元の keymap にしてから戻す様にしていた筈である。実際に
    | % ble/decode/detach においてその様に処理している。
    |
    | * ble-bind -m emacs -P で確認した限りは特に違いは見られない。という事を考え
    |   るとやはり bind の側の問題であろう。何故違いが生じるのだろうか。
    |
    | 全く同じ binder を用いていても問題が生じる物なのだろうか。何より異なる
    | keymap に対して作用しているのに影響が出るのは何故だろうか。うーん。
    |
    | うーん。builtin bind の呼び出しを全て検査すれば大丈夫だろうか。
    | と思って builtin を置換する実験をして見たら滅茶苦茶になる。
    | 何かと思ったら eval を通して $* を参照する場合には、
    | 関数の中から実行すると $* が変わってしまって駄目という事。
    | なので、builtin を置き換えて bind の呼び出しを監視する作戦は使えない。
    |
    | 直接 bash のソースを弄ってデバグする? うーん。
    | そもそも一体どういう状態になっているのかというのが謎である。
    | vi の時には何故二回連続で C-x が受信される事態になっているのか。
    | 本当に C-x が二回連続で受信されているのだろうか。。
    | 或いは C-xC-x の entry が xmap にされていると
    | C-x に対しても勝手に C-x C-x のマッピングが呼びされてしまうという事なのか。
    | もしそうだとしたら再現は簡単で良い。

    というより version 毎にちゃんと動いているか確認する。

    bash-4.4 vi: 動いている
    bash-4.4 vi->emacs: 駄目(何も受信されない) #1
    bash-4.4 vi->emacs->vi: 駄目(C-x が二回受信される) #2
    bash-4.3: 全部OK
    bash-4.2 vi: 動いている
    bash-4.2 vi->emacs: 動いている
    bash-4.2 vi->emacs->vi: 駄目(何も受信されない) #3
    3.0..4.1 は 4.2 と同じ振る舞いである。

    取り敢えず 4.4 の振る舞いだけは修正したい。

    うーん。#2 については何が起こっているか分かった気がする。以下で再現できる。

      $ bash-4.4 --norc -o vi
      $ bind -x '"\C-x":echo X'
      $ bind -x '"\C-x\C-x":echo XX'
      $ bind -r '\C-x\C-x'
      kbd <C-x><500ms> → XX と表示される

    #1 についても何が起こっているか分かった気がする。

      $ bash-4.4 --norc
      $ bind -r '\C-x'
      $ bind -x '"\C-x\C-x":echo XX'
      $ bind 'set keyseq-timeout 1'

    この状態だと C-x を押して timeout すると何も起こらない。
    keyseq-timeout を短く設定してしまうのが問題という事。

    問題 #3 では何が起こっているのだろうか。何も受信できていないというのが気に
    なる。emacs に移動した時に既に \C-x\C-x の bind -x & bind -r は終わっている
    筈である。この時点で cmd_xmap は問題がない筈。

    #3 に関しては以下の様にして再現する事ができる。

    $ bind -x '"\C-x\C-x":echo XX'
    $ bind -r '\C-x\C-x'
    $ set -o vi
    $ bind -x '"\C-x":echo X'
    kbd <C-x>

    [対処]

    | 敢えて \C-x\C-x の場所に何か変な値を設置しておく?
    | というかこれは元々の \C-x を検出する時の問題に関係するのではないか。
    | 実は以下のようにおけば問題ないのでは。
    |
    |   bind -x '"\C-x\C-x":C-x 用の文字列'
    |   bind -r '\C-x\C-x'
    |   bind -x '"\C-x":C-x用の文字列'
    |
    | 少し実験してみる事にする。
    |
    | 取り敢えず問題の再現から。bash-4.2 で以下で落ちる事を確認した。
    | bash-4.1,4.0,3.2 でも同様に落ちる。bash-3.1,3.0 では変な文字列を実行しよう
    | として失敗する。以前の実験で 3.2 だけ無限ループになったのは偶々だったのでは
    | ないかと思われる。
    |
    |   bind -r '\C-x\C-b'
    |   bind -x '"\C-x":echo X'
    |   kbd <C-x><C-b>
    |
    | さて、これの WA として \C-x\C-x を一回 bind してから unbind すると
    | いうのは有効か確認する。うーん。
    |
    | o 一応この対策をして置けば何れの場合にも crash はしなくなる。
    |
    | o bash-4.4 の場合にはこれで完全にOK。- 但し、bash-3.0..4.2 の場合にはこれを
    |   実行すると shadow binding timeout が発生しなくなってしまうので、-o emacs
    |   の時にだけ実行する様にした方が良い。
    |
    | 0 bash-3.0..4.2 の場合には vi->emacs->vi とした時に C-x で何も受け取れなく
    |   成る問題 #3 は持続している。然しそれでも、従来行っていた "C-x ?" に全て
    |   bind する作戦と同等の振る舞いを一つの binding で実現できているので、これ
    |   だけでも新しい手法に移行する価値はある。
    |
    | vi の側でも bind -x & -r を実行すれば検出できる様にはなるが、C-x 単体での検
    | 出ができなくなってしまう。でもそれは emacs keymap を一度でも使うのであれば
    | 避けようがないので、受容するしかない。或いは、emacs でも vi の上で動作する
    | 様にすれば良いのかもしれないが…。
    |
    | 取り敢えずこれがどの bash version でも再現するのかを確かめる。Bash-4.0 以下
    | では C-x を押すと行が新しくロードされる。これが意味する所は、 bind -x によっ
    | て unix_execute_command は呼び出されているが、対応する文字列の探索に失敗し
    | ているという事の気がする。
    |
    | ? 或いは一度は却下した bind -s '"\C-x": "\xC0\x98"' を用いる方法について再
    |   検討しても良いのかもしれない。遅延が生じるという事が述べられているが、ど
    |   の bash の version で起こるのか等について記録が残っていない。
    |
    |   * 先ずは遅延を再現しなければならない。そしてどの様な状況で問題になるのか
    |     を確認しなければならない。
    |
    |     →うーん。bash-4.4 で bind 'set keyseq-timeout 500' にしたら再現できた。
    |     これは何故発生しているかと言うと C-x ? が (過去に) 存在していた時に
    |     '"\C-x":"\xC0\x98"' を実行する為には結局 timeout/mismatch が必要だから
    |     である。
    |
    |     然しこの遅延に関しては "C-x ?" 全バインドの手法を取ったとしても共通であ
    |     る。特に問題になるのは C-x C-x と連続で入力した時に、この C-x C-x の組
    |     で認識されれば即座に反映されないという事である。"C-x ?" なら即座に反映
    |     される。'"\C-x":"\xC0\x98"' だと
    |
    |       C-x C-x
    |       \xC0 \x98 C-x
    |
    |     の様な形になるので余った C-x が残ってしまう。
    |
    |   x 更に、bash-4.2 で '"\C-x":"\xC0\x98"' を適用してみたが、結局遅延が存在
    |     する事には変わりがない様で、意味がない。bash-4.3 以降は現在は問題なく動
    |     作するので、対策は bash-4.2 以下に対してになるが、bash-4.2 以下では
    |     keyseq-timeout を指定する事もできないのでこの遅延をどうにかする事はでき
    |     ない。
    |
    | ? というかこの単一 bind 手法だと結局 C-x C-x とした時に遅延が生じるのではな
    |   いだろうか→確かめた。実際にそうだった。やはり単一 bind は駄目である。
    |   bash-4.4 ならば keyseq-timeout を短くすれば未だ何とかなるが bash-4.2 以下
    |   では次の操作をしない限りは C-x C-x に対して結果を受信する事ができない。

    [対処法比較]

    単一C-x (C-xC-xを一旦設定)

      4.4 ... keyseq-timeout の分だけ遅延が生じる。keyseq-timeout を 0 にすれば
        問題ない。何故 timeout 遅延が生じるのかと言うと、元々 emacs keymap には
        C-x ? の組み合わせが登録されていて、それらが全て削除されていたとしても
        (或いは削除しきれていないのかもしれない)、確定状態にならないからなのだ
        と言う気がする。

        ※C-xC-xを一旦設定する措置をしないとコマンドが登録されていない旨のエラー
        が発生する。

      4.2 ... timeout がないので key 一個分だけ遅延してしまう。keyseq-timeout
        を 0 にする訳にも行かない。

        ※C-xC-xを一旦設定する措置をしないとそもそも、次の key が来ていざ確定し
        た時にクラッシュしたりランダムな文字列を実行したりして問題になる。

    全 "C-x ?" の束縛 (C-x は unbind しておく)

      4.4 ... keyseq-timeout により timeout が発生すると "C-x" 単一で確定が為さ
        れるが、その時に何も実行されない。keyseq-timeout を十分長くすれば気にな
        らなくなる…かもしれないが、それでも振る舞いとしては微妙。

        ※C-x にも bind する様にしておくと今度は C-x に対して C-xC-x に対応する
        コマンドが実行されてしまう。

      4.2 ... key 一個分の遅延はない。emacs では特に何も問題は発生しない。但し、
        一旦 emacs で "C-x ?" の組み合わせに対して全 bind を実行していると、vi
        の側で単一 C-x に対して bind しようとした時に支障が出る。

        これを防ぐ為には "C-x ?" の組み合わせについて直接 -x を設置するのではな
        くて、文字列マクロ経由で読み取る様にするべきではないか。という事。この
        時の問題は…。やはり \C-x が再び現れると key 遅延が発生する事。つまり、
        bind '"\C-x\C-x":"\xC0\x98\x18"' 等とすると、\x18 (\C-x) に対して再び
        key 一個分の遅延が発生する。なので、'"\C-x\C-x":"\xC0\x98\xC0\x98"' と
        する必要がある。

        * 一方で、"\xC0" や "\x98" に関しては複数バイトの束縛は行わないので、
          "\xC0" の timeout/key 遅延について問題が新しく発生する事はない筈。

    Bash 4.4 では単一 C-x を採用する。Bash 4.2 以下では今まで通り "C-x ?" を全
    束縛するが、vi に影響が出ない様にマクロ経由で束縛する事にする。

2021-02-18

  * syntax: !; 及び time; の後の文脈 [#D1477]

    !; 及び time; の後の文脈で } fi done esac を要求しているが実際は任意のコマ
    ンドの筈である。少なくともそうなっている様に見える。問題の部分では #D0592
    を参照しているが、これは大きな書き換えなので特にこの部分で何故この様にした
    のかは謎。コメントには明示的に CTX_CMDXE と書かれている。そんな事はない筈な
    のに不思議である。

    よく #D0592 を見てみたら "time ; echo" でエラーになると書かれている。
    うーん。bash の version かと思って試したらそうだった。bash 4.3 以前は
    "time ; echo" がエラーになるのであった。一方で 4.4 以降は OK

2021-02-15

  * 2017-10-01 syntax: case $x in (a b) : ;; esac のパターン "a b" はエラー [#D1476]
    これも #D1474 で対応した。此処に挙げられているテストケースは有用だった。

    どうやら一個の単語までしか駄目な様子?

    更に case aaa in ((aaa)) echo;; esac 等の様に () の入れ子もエラーになる。
    shopt -s/-u extglob に拘らずエラーになる。
    一方で extglob の @() に関しては中で () の入れ子が可能である。
    つまり、case の中の (...) と extglob @(...) の文脈は異なる。

    他にも違いはある。@(<>) は許されるが、in (<>) は許されない。
    @(&&) は許されるが in (&&) は許されない。
    in (a|a|a) は許されるが in (a||a) や in (||) は許されない。
    in (&), in (|), in (;), in (<), in (>) は何れも駄目。
    in (a&b), in (a;b), in (a<b), in (a>b) も何れも駄目。

    どうも全然違う文脈の様に思われてきた。

    現在の実装では ble-syntax:bash/ctx-case から CTX_PATN に突入している。
    (他に CTX_PATN に入っている箇所を探すと、
    関数の引数の括弧に何か変な物が入っている場合と、
    コマンドの途中で突然括弧が現れた場合である。
    これらはエラーに対する復帰としての CTX_PATN なのでそんなに気にしなくて良い)

    どうも振る舞いを観察すると ctx-conditions と ctx-globpat の中間のように思う。
    単語を設置しなければならないという観点で言うと ctx-conditions に近い。
    一方で対応している構文の集合という観点で言うと ctx-globpat が幾らか近いように思う。

    2017-11-27 追記
    どうやら () の中の単語ではチルダ展開も有効のようだ。以下で hello が出力される。
    case a=~ in (a=/home/murase) echo hello; esac # これは対応済み
    case a=/home/murase in (a=~) echo hello; esac

  * syntax: case x) とした時の ")" の着色が括弧でちゃんと囲んだ時と異なる [#D1475]
    これは #D1474 における再実装で一緒に修正した。

  * syntax: case a in @) で @() と入力すると fatal error [#D1474]

    case a in ) の状態でパターンに @() を入力しようとするとシフトエラーになる

    | もっと具体的に調べてみると case a in @) の状態で @ の直後に ( を挿入する
    | となる。シフトエラーになるという事は case a in @) と入力した時点で壊れて
    | いると考えられる。
    |
    | | 先に ) を入力した時
    | | $ case a in @)
    | | _ble_syntax_attr/tree/nest/stat?
    | | 18 a    000 'c' | stat=(CMDX w=- n=- t=-:-)
    | |  | a    001 'a' |
    | |  | a    002 's' |
    | |  | a    003 'e' + word=CMDI:0-4/(wattr=d)
    | | 39 a    004 ' '   stat=(CARGX1 w=- n=- t=$4:-)
    | | 40 a    005 'a' + word=ARGI:@3>5-6/(wattr=d) stat=(CARGX1 w=- n=- t=$4:-)
    | | 41 a    006 ' '   stat=(CARGX2 w=- n=- t=$6:-)
    | | 42 a    007 'i' | stat=(CARGX2 w=- n=- t=$6:-)
    | |  | a    008 'n' + word=CARGI2:@5>7-9/(wattr=d)
    | | 34*a    009 ' '   stat=(CASE w=- n=- t=$9:-)
    | | 30*a    010 '@' | nest=(CMDX w=- n=- t=$9:-) stat=(CASE w=- n=- t=$9:-)
    | | 30*a  s 011 ')' + word="none":@8>10-12 stat=(PATN w=- n=@10 t=-:$9)
    | |  |    s 012 ^@   stat=(CMDX w=- n=- t=$12:-)
    | |
    | | 先に @ を入力した時
    | | $ case a in @)
    | | _ble_syntax_attr/tree/nest/stat?
    | | 18 a    000 'c' | stat=(CMDX w=- n=- t=-:-)
    | |  | a    001 'a' |
    | |  | a    002 's' |
    | |  | a    003 'e' + word=CMDI:0-4/(wattr=d)
    | | 39 a    004 ' '   stat=(CARGX1 w=- n=- t=$4:-)
    | | 40 a    005 'a' + word=ARGI:@3>5-6/(wattr=d) stat=(CARGX1 w=- n=- t=$4:-)
    | | 41 a    006 ' '   stat=(CARGX2 w=- n=- t=$6:-)
    | | 42 a    007 'i' | stat=(CARGX2 w=- n=- t=$6:-)
    | |  | a    008 'n' + word=CARGI2:@5>7-9/(wattr=d)
    | | 34 a    009 ' '   stat=(CASE w=- n=- t=$9:-)
    | | 30*a    010 '@' | nest=(CMDX w=- n=- t=$9:-) stat=(CASE w=- n=- t=$9:-)
    | | 30*a    011 ')' + word="none":@8>10-12 stat=(PATN w=- n=@10 t=-:$9)
    | |  |    s 012 ^@   stat=(CMDX w=- n=- t=$12:-)
    |
    | これら二つを比較しても違いは 011 の位置の s という記号のみである。この s
    | というのが何であるかは覚えていないが、実のところこの二つの両方で問題が再
    | 現するので @ を先に入力するか ) を先に入力するかは問題には関係ない。
    |
    | @の代わりに X を挿入した場合にどうなるか調べる。X に引き続いて (
    | を挿入しても問題は発生しない。
    |
    | | $ case a in X)
    | | _ble_syntax_attr/tree/nest/stat?
    | | 18 a    000 'c' | stat=(CMDX w=- n=- t=-:-)
    | |  | a    001 'a' |
    | |  | a    002 's' |
    | |  | a    003 'e' + word=CMDI:0-4/(wattr=d)
    | | 39 a    004 ' '   stat=(CARGX1 w=- n=- t=$4:-)
    | | 40 a    005 'a' + word=ARGI:@3>5-6/(wattr=d) stat=(CARGX1 w=- n=- t=$4:-)
    | | 41 a    006 ' '   stat=(CARGX2 w=- n=- t=$6:-)
    | | 42 a    007 'i' | stat=(CARGX2 w=- n=- t=$6:-)
    | |  | a    008 'n' + word=CARGI2:@5>7-9/(wattr=d)
    | | 34 a    009 ' '   stat=(CASE w=- n=- t=$9:-)
    | | 30 a    010 'X' | nest=(CMDX w=- n=- t=$9:-) stat=(CASE w=- n=- t=$9:-)
    | | 30 a    011 ')' + word="none":@8>10-12 stat=(PATN w=- n=@10 t=-:$9)
    | |  |    s 012 ^@   stat=(CMDX w=- n=- t=$12:-)
    |
    | 然し木構造を調べても X の時と @ の時で全く同じ状態になっている。な
    | のにシフトでエラーが発生するというのは不思議である。
    | →改めて確認した所、一番最初に発生するエラーはシフトエラーではなかった。
    |
    | | ble/syntax/tree-enumerate/.initialize/FATAL2
    | |   @ /home/murase/.mwg/src/ble.sh/out/lib/core-syntax.sh:4 (ble/syntax/tree-enumerate)
    | |   @ /home/murase/.mwg/src/ble.sh/out/lib/core-syntax.sh:6 (ble/syntax/print-status/.dump-tree)
    | |   @ /home/murase/.mwg/src/ble.sh/out/lib/core-syntax.sh:8 (ble/syntax/print-status)
    | |   @ /home/murase/.mwg/src/ble.sh/out/lib/core-syntax.sh:74 (ble/highlight/layer:syntax/update)
    | |   @ /home/murase/.mwg/src/ble.sh/out/ble.sh:13 (ble/highlight/layer/update)
    | |   @ /home/murase/.mwg/src/ble.sh/out/ble.sh:10 (ble/textarea#update-text-buffer)
    | |   @ /home/murase/.mwg/src/ble.sh/out/ble.sh:76 (ble/textarea#render)
    | |   @ /home/murase/.mwg/src/ble.sh/out/ble.sh:3 (ble-edit/bind/.tail)
    | |   @ /home/murase/.mwg/src/ble.sh/out/ble.sh:18 (ble-decode/EPILOGUE)
    | |   @ /home/murase/.mwg/src/ble.sh/out/ble.sh:79 (ble-decode/.hook)
    |
    | print-status の段階でエラーが発生している。つまり、直前の状態が問
    | 題なのではなくて ( を入力した直後の状態が壊れているのである。
    |
    | | _ble_syntax_attr/tree/nest/stat?
    | | 18 a e  000 'c' | stat=(CMDX w=- n=- t=-:-)
    | |  | a e  001 'a' |
    | |  | a e  002 's' |
    | |  | a e  003 'e' + word=CMDI:0-4/(wattr=d)
    | | 39 a e  004 ' '   stat=(CARGX1 w=- n=- t=$4:-)
    | | 40 a e  005 'a' + word=ARGI:@3>5-6/(wattr=d) stat=(CARGX1 w=- n=- t=$4:-)
    | | 41 a e  006 ' '   stat=(CARGX2 w=- n=- t=$6:-)
    | | 42 a e  007 'i' | stat=(CARGX2 w=- n=- t=$6:-)
    | |  | a e  008 'n' + word=CARGI2:@5>7-9/(wattr=d)
    | | 34 a e  009 ' '   stat=(CASE w=- n=- t=$9:-)
    | | 31*a e  010 '@' | nest=(PATN w=- n='none':10- t=-:$9) stat=(CASE w=- n=- t=$9:-)
    | |  |*a e  011 '(' |
    | |  6*a es 012 ')' + word="none":10-13 stat=(PATN w=- n=@10 t=-:-)
    | |  |    s 013 ^@   stat=(PATN w=- n=@10 t=$13:$9)
    |
    | というか、")" が存在しなくても普通に @( と入力しただけでエラーになってい
    | る。a@( としている時には大丈夫である。これはつまり単語と nest が同じ場所
    | で始まる事によってエラーになっているという事だろうか。うーん。確かに a@(
    | とすると a の位置と @ の位置の両方に nest が設定されている。という事は、
    | @( を入力した時に同時に二箇所に nest を設定しようとして状態が破壊されてい
    | るのである。だとすると $( でも問題が発生する筈→発生した。" でも問題が発
    | 生した。うーん。根本的に nest を再考する必要があるのかもしれない。

    [状況]

    以下の何れでも問題が発生する。原因は同じ位置に2つの nest を設置しようとして
    いる事にある。

    - case a in @(
    - case a in $(
    - case a in "
    - case a in (x);;"

    nest の位置をずらそうとしても " の場合には一文字しか無いのでずらす事ができ
    ない。逆にパターンの側の nest の位置を一文字前にずらすという事も考えたが、
    必ずしもパターンの前が空白とは限らない。例えば ;; など。この場合には結局同
    じ位置に nest を設置するしかない。或いは ;; の位置に nest を設置してしまう
    という手もあるのかもしれないが、それは不自然だし色々とまた変な問題が発生し
    そうである。

    [修正]

    やはり解決策としては同じ位置に nest を設置できる様にするという事。然し、現
    状のコードで nest が同じ位置に設置されないという前提は何処で使っていただろ
    うか。場合によって単に対応するだけでは済まないかもしれない。

    或いはもう一つの方法として、そもそも case パターンを nest にする必要があっ
    たのかという事。この方法の方が確実に簡単に修正できる気がする。然し、nest に
    した理由は何だろうか。単に既存の CTX_PATN を使いたかったからというのであれ
    ば簡単である。

    コードを確認してみたがやはり nest を使わないとすると新しい文脈値が必要にな
    りそうである。更に、元から case pattern の中は単語が一個だけになる様に制限
    を加える予定だった。これに対応する為には結局新しい文脈値が必要だったのだ。
    case pattern の単語数も一緒に対応してしまうのが良いだろう。

    うーん。実はコマンド文脈で読み取った方が良い? とも思ったがそうでも
    ない気もする。例えば | の取り扱いが異なる。& や ; 等他の delim の
    場合にはエラーにする必要がある。|| は一まとまりではなく一文字ずつ取る。
    | の直後は再び単語を受け付けて OK。など。

    - done: ble/syntax:bash/ctx-command-case-pattern

    実装したが無限ループになってしまう。調べると parse の中で同じ位置に対してずっ
    と計算している。

    parse (i=19): ctx=78 ble/syntax:bash/ctx-command-case-pattern-expect

    $ case x in @() echo ;; esac

    問題は ;; の直前で起きている様だ。これは BASH_REMATCH が途中で書き換わって
    いたのが見落としだった。修正した。OK 動いている。

    ----------------------------------------------------------------------

    2021-02-19 assertion failure が出た。

    assertion failure: ((_ble_syntax_bash_command_isARGI[ctx]))
    invalid ctx=79 in words
      @ /home/murase/.mwg/src/ble.sh/out/lib/core-syntax.sh:15 (ble/syntax:bash/ctx-command)
      @ /home/murase/.mwg/src/ble.sh/out/lib/core-syntax.sh:86 (ble/syntax/parse)
      @ /home/murase/.mwg/src/ble.sh/out/ble.sh:7 (ble-edit/content/update-syntax)
      @ /home/murase/.mwg/src/ble.sh/out/ble.sh:75 (ble/textarea#render)
      @ /home/murase/.mwg/src/ble.sh/out/ble.sh:3 (ble/textarea#panel::render)
      @ /home/murase/.mwg/src/ble.sh/out/ble.sh:5 (ble/function#try)
      @ /home/murase/.mwg/src/ble.sh/out/ble.sh:8 (ble/canvas/panel/render)
      @ /home/murase/.mwg/src/ble.sh/out/ble.sh:3 (ble-edit/bind/.tail)
      @ /home/murase/.mwg/src/ble.sh/out/ble.sh:18 (ble-decode/EPILOGUE)

    [再現]

    | 以下のコマンドラインに於いて "'; の ; の前にカーソルを置いて、其処から BS
    | の autorepeat で削除を行うと確率的に上記のエラーが発生する。不思議なのは
    | ctx=79 は最近追加した CTX_CPATQ であり、これは case の時にしか発生しない筈
    | の物であるという事。現状では何処にも case はないので ctx が 79 になる事はな
    | い様に思われる。core-syntax.sh の中を再度確認してみたが混入する事はない気が
    | する。
    |
    | $ debug/builtin() { unset -f builtin; IFS=" " eval 'echo "[$*]"'; builtin "$@"; local _ext=$?; echo "[$* ($_ext)]";
    |   builtin() { debug/builtin "$@"; }; return "$_ext"; }
    |
    | $ d() { unset -f builtin; A=" " : ': "[$*]"'; : "$@"; : a=$?; : "[$* ($a)]"; }
    |
    | $ : helloworldhelloworld; A=" " :; : a=$?; : "[$* ($a)]"
    |
    | あー。成程。79 が現れたのは BS で消す途中に ;; が現れる為である。確率的に発
    | 生していたのは、丁度 ";;" の時に文法の再解析が起こるか起こらないかである。
    | 一つずつ BS を押していれば必ず発生する。
    |
    | $ :; :;: a=$?;:
    |
    | OK. 以下が最小再現コードである。以下の状態から間の空白を削除するとエラーになる。
    |
    | $ ; ;a=1
    |
    | というより変な事をしなくても普通に以下で問題が発生する。
    |
    | $ case x in a=1

    取り敢えず 79 が出るのは別にバグではないという事は確認できた。
    そして修正は簡単だった。これは fixup にする。

2021-02-10

  * ble/builtin/read: 空文字列の時 C-d でキャンセルしない [#D1473]

    使い心地が変だと思って plain Bash で試してみたら C-d でちゃんとキャンセルに
    なる。ble/builtin/read もこれと同様に振る舞うべきである。

    →これも実装した。これは簡単な修正。

  * ble/builtin/read: 全く描画されなくなっている [#D1472]

    これは ble/canvas/panel/render において描画するかどうかを各パネルの高さで決
    定しているが、textarea は textarea#render の中で高さを決定する事にしている。
    なので高さがいつまでも 0 の儘になってしまって結局全く描画されないという事態
    になっている。

    | 本来は描画を実行する前に高さを決定するべきなのである。然し、現在の実装では
    | 中身の計算が重いために必要になるまで計算しない事にしている。うーん。
    | getHeight を受け取った時点で中身の計算を終わらせるべきだろうか。然し、希望
    | の高さを伝えたからと言って必ずしもその高さが通るとも限らないし、結局結果に
    | よっては再計算する必要が出てくる可能性は変わらない。
    |
    | その様に考えると結局現在の様な実装でも変わらないのではないかという気はする。
    | 或いは 0 という高さは特別な高さという事にして中身がある場合には必ず有限の高
    | さを指定する事にする?
    |
    | 然し、0を特別扱いする事にすると一時的に高さを 0 にして再び後で高さが有限に
    | なる可能性がある時、そしてその高さが有限になる機会が render の中で得られる
    | 場合に困る。なので、0 であってもやはり render は呼び出すべきなのではないだ
    | ろうか。
    |
    | うーん。然しそうすると… textarea を隠したい時にも必ず textarea が表示され
    | てしまうという事になってしまう。或いは、textarea を隠したい時には
    | _ble_textarea_panel には -1 などの値を代入しておくというルールにする? とい
    | うよりそもそも表示・非表示という状態は height とは別に持っておくべきなので
    | ある。

    * 表示・非表示の状態は height とは別に持っておくべき。現在の実装では取り敢
      えず各実装に任せる事にする。

    * render では取り敢えず高さ 0 であっても全ての panel について
      $class#panel::render を呼び出す事にする。これは render の中でレイアウトを
      計算する時に高さを変更したくなるかもしれないからである。

    * reject: 将来的には textarea#render を textarea#layout と textarea#render
      に分ける事も考えるべきかもしれない。

    | 少し textarea#layout と textarea#render に分ける事も考えたが、これをして
    | も結局何も変わらない。というのも、textarea#layout で高さを計算する時に自
    | 身の高さを変更すると結局、他のパネルの高さも全て再計算になる。なので、再
    | 帰的な高さ変更の可能性は、高さ計算を textarea#layout に分離したとしても本
    | 質的には解決していない。何か利があるとすれば最後の描画処理が省略できるだ
    | けである。そして最後の描画処理は ble.sh ではそんなに重い処理ではないので
    | 意味がない。
    |
    | また、今まで問題が起こらなかった理由でもあるが textarea は高さを要求する
    | が、info は高さが足りなければ他から奪おうという事はしないので、高さの更新
    | が再帰的になる事はない。特に textarea よりも info の方が後に render を行
    | うという事もあるので特に問題になっていない。(実は今までは info が描画した
    | 内容を textarea が truncate するという事になっていたのではないかという気
    | がするので、現在の実装のほうがよりまともなのであろう)

    * 結局 height 更新の無限ループは可能性として排除できない。それは render の
      中で height 設定をしても、layout の中で height 設定をしても同じことである。
      最終的には誰かが皺寄せを食うという事にしておけば何れにしても問題にならな
      いし、そうでなければそもそも解が存在しない。現在の実装では info が皺寄せ
      を食う事になっている。

  * global: 今度はまた別の連想配列のエラーが出ている (reported by 0xC0ncord) [#D1471]
    https://github.com/akinomyoga/ble.sh/issues/86#issuecomment-776165286

    新しいシェルを開いてもエラーが出ていると書いているが本当だろうか?
    もしこれが同じシェルだとしたら ble-update で駄目な事になるというのは理解できる。
    取り敢えずその為の修正だけは入れる事にした。

  * global: 連想配列の中身が bash-4.2 関数内ble.shソースで消滅する (reported by 0xC0ncord) [#D1470]
    https://github.com/akinomyoga/ble.sh/issues/86

    4.2 で動かないという話。調べると問題の _ble_builtin_trap_n2i は連想配列であ
    る。という事は -g の指定が怪しい。実際に ble.sh を関数内で source したら再
    現できた。

    然し、手元で reduced case を作ってみると動いている様な気がする。WINCH に対
    するシグナル番号を取得する時に結果が空になってしまってい
    る。_ble_builtin_trap_n2i から引いている。然し、 _ble_builtin_trap_n2i の値
    を見るとちゃんと SIGWINCH に対して 28 が割り当てられている様に見える。と思っ
    てよく見てみたら、途中で _ble_builtin_trap_n2i の中身が空になっている。もし
    かして、bash-4.2 だと属性は global まで適用されるが、値が local になってし
    まっているという事か。

    実際に試してみると確かに中身が空になる。うーん。今までは -gA を 40200 以上
    という条件で使っていたが、これは 40300 以上という条件に引き上げるべきだろう。

    * 結局最小再現コードは以下の様になった

      $ bash-4.2 -c 'a(){ declare -gA d=([k]=v);};a;declare -p d'
      declare -A d='()'
      $ bash-4.3 -c 'a(){ declare -gA d=([k]=v);};a;declare -p d'
      declare -A d='([k]="v" )'

    * reject: 判定条件を変数に入れて再利用できるようにする? と思ったがどうせそ
      の次の判定で細かく場合分けするので全体の条件だけ変数に入れて再利用しても
      却って分かりにくいだけである。これは棄却。

    * reject: 連想配列の使い方に応じて declare -gA を使う bash version を切り替える?

      使い方によっては引き続き 40200 でも大丈夫かもしれない。つまり、ble.sh を
      source した段階では空の儘で、実際に使っていく中で中に値をキャッシュすると
      いう場合。或いは、単にキャッシュとして使うという場合にも問題は起こらない。
      然し、実際に関数の中で値が初期化されるかどうかは attach の仕方にも依存す
      る。更に、これは関数内で ble.sh を source するという特殊な場合に於いての
      み影響が出るので余り細かい最適化を考えても仕方がない。

    全て 40300 に書き換えた。まあ、これで何も起こらないだろう。

2021-02-09

  * 2021-02-01: spike branch で tab completion で crash する (reported by 3ximus) [#D1469]
    https://github.com/akinomyoga/ble.sh/issues/82#issuecomment-770390986

    Ref: これは #D1452 / #D1468 と同じ問題。詳細は #D1468 で議論。

    eval-pathname-expansion の中で死んでいるのだろうか。failglob などの判定に失
    敗している可能性もある。つまり、shopt -s failglob が設定されている時に、
    globpat が含まれているのに含まれていないと判定された時に、set -f 等の操作を
    行わずにパス名展開を直接実行して、それにより強制的に終了してしまっている可
    能性。

    →でも元々 failglob があっても大丈夫な様に eval を使って評価していた筈→本
      当だろうか。eval だけで failglob を回避する事ができていたのだろうか。
      syntax の方で .set-result という関数を用意したのは何か理由があったのでは
      ないか。と思ったが、.set-result は failglob を避ける為の物ではなくて展開
      結果を格納する為の物だった。

    →更に、現在の判定方法で globpat を見逃すとも考えづらい。

    実際に手元で failglob の設定下で補完を試みたが変な事は起こっていない。bash
    version の違いかもしれないとも思ったが別に 5.1 でも dev でも変な事はない。
    3.2 や 4.0 4.3 4.4 で試しても違いはない。

    →hangは観測できたという話をしたらどうやら正確にはcrash ではなくて hang し
    ていた様だ。そして振る舞いを見る限りに於いては自分の手元で観測した hang と
    全く同じである。

  * 2021-02-03 TAB completion に於いて conditional-sync で hang する [#D1468]
    Ref: #D1452 と #D1469 は実はこの問題と同一であった。

    chatoyancy で再現している。

    3ximus の報告した crash は観測されていないが代わりに linux 上で hang すると
    いう現象は起こっている。親 shell が固まっていて一方で子 shell はいつまで経っ
    ても終了しないという状態になる。これはどういう状態だろうか。子 shell に対し
    て kill を実行するとその時点で終了して親 shell も使える様になる。時々、再び
    子 shell を生成してそれが固まるという現象は発生している。subshell が発生し
    ている状態で固まっているという様子を見る限りは恐らく conditional-sync で変
    な問題が起こっているのだと思われるが分からない。

    * 親shellの CPU が微妙に動いている。
    * ユーザー入力しても何故か親シェルが中断しない

    改めて condtional sync の実装を確認してみると2回 fork している。1つの fork
    はジョブ管理によって変なメッセージが発生するのを避ける為。2つ目の fork が実
    際に & で bg job を起動する為の物。症状として見られていた hanging shell は
    実は worker ではなくて最初の subshell の様だ。更に詳しく調べてみるとどうや
    ら msleep の中で停止してしまっているようだ。つまりこれは Cygwin 上で発生し
    ていた #D1452 のフリーズと全く同じ問題である。

    Cygwin のテストケースと同じ物で再現できるだろうか。

    ( echo {1..1000} & builtin read -t 0.000100 v < /dev/udp/0.0.0.0/80 ) >/dev/null

    Linux では /dev/udp ではなくて fifo を使っている筈。

    OK 再現した。

    $ mkfifo a.pipe
    $ exec 9<>a.pipe
    $ test1() { (eval "echo {0..$count}" & builtin read -u 9 -t 0.001 v) >/dev/null; echo ok $((count++)); }
    $ bind -t '"\C-t":test1'

    これは結局 bash のバグなので別の場所で議論する事にした。

    workaround を考える。

    A 一つの方向は先ず変な事が起こる発生確率を下げるという事。
      然し、それでも read -t がブロックする可能性は 0 ではない。
      これは実の所 /dev/zero を使っていても同様の筈である。
      とにかく変な事が発生する確率は 0 ではないという事。

      変な事が起こる確率を下げる為に。もう一つの可能性は以下の様に、
      $() を使って fork して、その後で read timeout を
    一番外側で実行するという事。

        { pid=$({ echo OK >&3; sleep 10; } &>/dev/null & echo $!); } 3>&1

      疑問としは孫シェルを wait できるのかという事。→うーん。駄目だった。

        bash: wait: pid 9447 はこのシェルの子プロセスではありません

      wait できない。という事は終了ステータスを検知する方法がない。或いは
      ble/util/assign と同様に終了ステータスは自前のファイル経由で読み取るとい
      う手もあるのかもしれないが…。とにかく面倒になってしまうという事は避けら
      れない。

      そもそもこの方向で問題を軽減できるのかどうかも非自明である。

    B read timeout を使わない方法を模索するべきなのかもしれない。
      然し read timeout が使えないとなるとやはり方法は絞られてくる。
      一つの方法は普通にコマンドの sleep を呼び出すという事。

      然し、spawn のコストと、更に sleep の分解能が秒単位しか無いという可能性が
      ある。そう考えると read timeout はどのシステムでも使う事ができるかなり便
      利な機能だったのである。

    c というよりそもそも conditional-sync ではデフォルトでユーザの入力を待って
      いるのだから、read -t を sleep に使うのではなくて、直接ユーザー入力を検出
      するのに使えば良いのではないのか? と思ったが駄目だ。read -t 0 ならばユー
      ザー入力を読み取らずに検査する事ができるが、read -t 0.001 だとユーザー入
      力を消費してしまう。そうなると気軽に実行できない。或いは、ユーザー入力を
      読み取る事ができた暁にはその場で ble-decode-char するという手もある?

      うーん。然し、_ble_bind_hook の中で実行した bind/.tail の中で
      ble-decode-char するとすると、例えば其処でコマンド実行が _ble_bind_hook
      に大して設定された時に、それがその場で実行されない可能性がある。更に、設
      定した物が実行される前に消滅してしまう可能性すらある。ble-decode-char を
      その場で実行する方式にすると色々木にしなければならない事が多い。

    d conditional-sync に限っては ALRM を subshell から投げれば良いのでは。と思っ
      て試してみたが、何も設置していない状態で kill -ALRM $$ すると親シェルが終
      了してしまう。ALRM に何か無視する様に ble.sh でハンドラを設置しても良いが、
      それはそれでまた面倒事が増える。

    うーん。二つの方向性がある。全般に msleep の問題を解決するという事と
    conditional-sync の問題を解決するという事。今までの発生頻度から考えると
    conditional-sync の対策だけをしても当面は大丈夫な気もするが、何れは msleep
    の問題を完全解決したい。そうなった暁には conditional-sync の対策は不要にな
    るし、また conditional-sync の問題だけ解決するのは臭いものに蓋をしているだ
    けで本質的問題の解決にはなっていない。それよりは msleep 自体の問題を解決す
    る様に考えたいのである。

    仕方がないので cygwin と同じ手法で回避する事にした。

    2021-02-13 /dev/zero による workaround を追加したがよく考えたら /dev/zero
    が全ての環境にあるとは限らないし、ある環境でも read をブロックしてくれるか
    は微妙である。と思ったが /dev/zero で止まるかどうかは bash の側の実装の問題
    なので、もし /dev/zero が 0 を出力し続けるのであれば、ちゃんとブロックはす
    るだろうと思われる。

    /dev/zero が存在する環境について一度確認はしておきたい。Solaris, Minix に存
    在する。FreeBSD, Haiku にも存在した。当然 Cygwin と Linux にも存在する。
    MSYS2 でも OK だった。何れも read -t 0.2 < /dev/zero がちゃんと期待通りに動
    いた。という事を考えれば基本的に全ての環境で /dev/zero が使えると考えて良い
    のではないだろうか。

2021-02-04

  * global: read timeout は $?==142 とは限らない [#D1467]

    read timeout は本当に常に 142 なのか。と思ったが現在の用例では 142 は
    conditional-sync によって固定で返されているので気にしなくて良い。因みに
    bash のソースコードを確認する限りは 142 は hardcoded ではない。

    * edit (ble/builtin/read/.loop): うーん。予め 142 に対応する終了ステータス
      を調べておくか、或いは 128 以上を一括で timeout と解釈するか。マニュアル
      には "128 より大きな値になる" とだけ書かれている。マニュアルに従った判定
      にするのが良い気がする。

    * util (ble/util/msleep/.use-read-timeout): これは現在は使っていない。何れ
      にしても Cygwin/MSYS の時にだけチェックする様にすれば、これらのシステムで
      は 142 固定と期待されるので大丈夫。

  * util (bleopt): bleopt でパイプに繋いでいても _ble_term_sgr0 が出力されている場合がある [#D1466]
    追加で関連する関数に於いて --color オプションで着色を制御できるようにする。
    * "--color" options for bleopt, blehook, ble-color-setface

  * 2021-02-01 highlight: highlight_timeout_sync=0 にしても遅い (reported by 3ximus) [#D1465]
    https://github.com/akinomyoga/ble.sh/issues/82#issuecomment-770390986

    % OK. Sorry, I actually reproduce this level of delay at my side too, but I
    % haven't regarded it as *terrible*. That's probably because I know what
    % `ble.sh` is doing in the background. I felt that it's actually doing a good
    % job considering how strange things `ble.sh` is doing in the background.
    %
    % →と思ったが、bleopt highlight_timeout_sync=0 を実行していなかった。これを
    % 実行したら自分のところでは特に問題もなく動く様になった。当初は実装のバグか
    % とも思ったが、一部の host の上でだけ動作しないという事があるだろうか。
    %
    % Do you think it is related to `ffmpeg` running in the background? I see in
    % the `top` pane multiple instances of `ffmpeg` are running, but the load
    % average is smaller than 2, which means that those `ffmpeg` instances are
    % waiting for an interrupt in more than half of their running time. If those
    % `ffmpeg` are encoding some video clips, they may be waiting for disk I/O.
    %
    % →と思ったが disk I/O 待ちだと status D になる筈である。画面を見る限りはそ
    % うなっていない。更に -x11grab というオプションについて調べてみるとこれはス
    % クリーンキャプチャである。つまり、これらの ffmpeg は単にこの説明を作るため
    % に起動しているだけで、問題には関係してこない。

    何れにしてもこれは background highlighting におけるユーザー入力による中断速
    度に関係している。でもどの部分が悪さをしているのか分からない。

    1. 入力検出?
    2. 生存検出?
    3. 或いは kill & wait だろうか。

    どうも background highlighting のユーザー入力によるキャンセルの応答が遅い様
    である。自分の手元では残念ながら再現しない。取り敢えず勘で可能性のある時間
    のかかりそうな箇所に関連した時間計測を依頼したがぴんと来ない。多分、別の所
    に原因があるのではないか。

    2021-02-04 追加報告では遅い時もあるしそうでない時もあるそうだ。後、遅いとは
    言っている割にそれ程遅い訳でもない気がする。単に複数のパス名展開が試みられ
    るのでそれぞれについてタイムアウトが試みられて遅くなっているというだけなの
    ではないか。という訳で、取り敢えずの修正として一度 timeout を起こしたら後続
    の eval も即刻で timeout する様に修正した。

    それから conditional-sync をチェックする頻度も変更する事にする。取り敢えず
    これで改善するかどうか判断する事にする。

    | 後、timeout は total でカウントするべきなのかもしれない。或いは一つ
    | timeout したらそれ以降は timeout が必要になる物はもう処理しない様に変更す
    | る。

    2021-02-05 新しい報告で上記の cumulative timeout & shorter polling interval
    で改善するという事が確かめられた。問題は現在の cumulative timeout によって
    本来短時間で着色できる単語が着色されずに残ってしまう可能性について。

    然し、そもそも cumulative timeout で本当に改善しているのかというのは謎であ
    る。今 highlight_timeout_sync=0 にしている。とすると highlight_timeout_sync
    が効いていないか、或いは highlight_timeout_async の側での cumulative
    timeout が効いているか。highlight_timeout_async の側での timeout が効いてい
    るとすると何故なのか。ユーザー入力がある場合には何れにしても has-input の
    チェックによってキャンセルされるのではないか。うーん。手元で試してみたが余
    り違いが分からない。

    * done: syntax_eval_polling_interval について doc を記述する

  * 展開済みであっても展開される単語の数に比例して遅い (reported by 3ximus) [#D1464]
    https://github.com/akinomyoga/ble.sh/issues/82#issuecomment-772529714

    * 以前大量の入力を与えた時に遅いという事を解決した時に似たような事があった
      気がする。パス名展開がなかったとしても大量の単語を含む配列をコピーすると
      遅いという話。

      前に経験した時にはどの様な事が原因でどのように対策したのだったか。記録を
      漁ってみると #D1302 に関連しそうな内容が書かれている。

      > chars=("${...[@]}" "$@") が 13 秒もかかっている。何故?

      うーん。改めて試してみたがそんなに遅くない。関数経由で代入して改善したと
      いう事が書かれているが、実際に試してみても関数経由で代入すると却って遅く
      なる。またパス名展開の影響かとも思ったが set -f しても大して変化しない。
      結局再現はできない。

      再現ができないので現在発生している問題が具体的にどういう物なのか調べる事
      もできない。取り敢えずまた計測をお願いするしかないのだという気がする。予
      想では cache が巨大である為に起こっている事ではないか。

    * reject: そういう意味では既に議論した様に、単語ごとに展開済みの単純な情報
      を記録する事にして必要になった時は eval まで取りに行くのではなくて一部だ
      け記録する事にするという手もある。

      →今は其処までしなくても良いという気がする。

    取り敢えず simple-word/eval のキャッシュとして完全な情報を記録する物と、最
    初の単語だけ記録する物を用意して、highlighting の内部では主に最初の単語だけ
    を参照する様に変更した。

  * syntax: tilde で始まる単語の着色がされない? (reported by 3ximus) [#D1463]
    https://github.com/akinomyoga/ble.sh/issues/82#issuecomment-772529714

    と思ったがそうでもない。条件が不明

    % notilde 関連かと思ったが違った。どうも evaluate-path-spec が after-sep の時
    % に変な振る舞いをしている。spec の抽出に失敗している。
    %
    % $ ble/syntax:bash/simple-word/evaluate-path-spec '~/work/idt/**/*.sh' after-sep
    % $ declare -p spec path
    % declare -a spec=([0]="~/wo" [1]="~/work/id" [2]="~/work/idt/**/*." [3]="~/work/idt/**/*.sh")
    % declare -a path=([0]="/home/murase/wo" [1]="/home/murase/work/id" [2]="" [3]="/home/murase/work/idt/agh/src/addon/make_latex_embedfont_css.sh")
    %
    % と思ったら単に evaluate-path-spec の使い方を間違っていただけだった。
    % 正しく sep を指定したら evaluate-path-spec の結果は期待した物になった。

    改めて evaluate-path-spec の中で何が起こっているのか調べたら確かに失敗している。

    wtxt='~/**/*.sh' path_opts='stopcheck:timeout-highlight:cached:after-sep' ext='1'
    spec=('~/' '~/**/' '~/**/*.sh')
    path=('/home/murase/' '' '')

    どうも stopcheck の有無で結果が変わる様である。
    ble/syntax:bash/simple-word/eval '~/**/*.sh' stopcheck; ext=$?; ble/debug/print-variables ext ret

    問題を狭めて行った所、原因が分かった。これは単純なミスである。
    command="print-result $word" とするべき所を 'print-result $word' にしていた。修正した。

2021-02-03

  * edit: status line に対応しても良いのではないか [#D1462]

    →改めて確認してみた所、prompt_status_line という設定が既に存在していた。

    ? terminfo tsl/fsl に対応している TERMは存在するのか

      これは terminfo の tsl fsl を使って何かを表示する物だが、実のところ
      tsl/fsl に対応している TERM はなかなかない。少なくとも screen, xterm は違
      う。

      * tmux の term entry には tsl/fsl が存在しているが、シーケンスを見るとこ
        れは prompt_xterm_title と同じ OSC であって間違っている。terminfo の説
        明を読む限りに於いては、tsl/fsl は端末の特別な行で内部ではエスケープシー
        ケンスなども普通に使える物と見られる。という事を考えると、tmux の様に振
        る舞うのは間違っている気がする。

      * cygwin も tmux と同様である。但し、OSC 0 ; ではなくて OSC ; になってい
        る。0 は省略可能という事なのだろう。

      * kterm には \e[?E\e[?..T ... \e[?F という物が登録されている。
      * aixterm は \e[?..T ... \e[?F
      * aixterm は \e[?..T ... \e[?F

      うーん。何れにしても最近の端末エミュレータに存在する様な物ではない気がする
      ので、取り敢えず prompt_status_line は ble.sh の新しい機能の為に使う事にし
      てしまって良い。

    既存の tsl/fsl によるタイトルは別名の設定にする事にする。
    prompt_terminfo_status という名前にでもするか。terminfo だけでなく termcap
    にも存在するようだから、prompt_termcap_status の方が良いのかもしれない。或
    いは、prompt_term_status にするか。

    * status line の区別がやはり付きにくい。背景色を設定できる様にしても良いのではないだろうか。
      元々 trace にその様な機能があった様な気がする。改めて確認する。なかったので新しく実装した。

  * syntax: echo ${!_} と入力すると誤った代入ですというエラーメッセージが表示される [#D1461]
    そもそも "${!_}" を実行しようとするとエラーメッセージが出るが、
    これが着色等の際に発生するのは良くない。何処で発生しているのか確認する必要がある。

    これは新しく追加した ble/syntax:bash/simple-word/is-simple-noglob の中で起
    こしている展開に対して2>/dev/null を付加すれば良かった。未だ master に push していない
    修正なので commit を fixup しようかと思ったが、実装ログが面倒な事になるので、
    下手に fixup するのは止める事にする。

  * benchmark: EPOCHREALTIME は LC_NUMERIC 依存 (reported by 3ximus) [#D1460]

    報告の画像で出ているエラーが何だろうと思って ble-measure の実装を
    見たが変な事はない。と思ったが此処で気づいた。EPOCHREALTIME の小数
    点は locale 依存である。という訳で対策する事にした。

  * global: help の類の整理 [#D1459]
    * bleopt: --help に対応していない
    * blehook: --help が単純すぎる

  * canvas: status line を最終行に表示する可能性 (suggested by 0neGuyDev) [#D1458]
    https://github.com/akinomyoga/ble.sh/issues/85

    元々の提案は vim の mode 名という事だったが、vim の mode 名だけを最終行に表
    示するのか、或いは補完候補等の情報も全て最終行付近に表示するのかという可能
    性がある。Emacs 等を考えると補完候補も最終行に表示するのが自然な気がする。
    なので、実装としては info を丸ごと一番最後に表示する可能性について考えて良
    い気がする。

    最終行に表示する為に必要な事。

    a 一つの方法は \e7 \e8 で現在位置を記録するという事。これは visible-bell で
      既にやっている事。問題になるのは info の内容を構築する時に \e7 \e8 を使え
      ないという事。trace に明示的に禁止・代替するオプションを付ける必要がある
      かもしれない。

    b もう一つの方法は DSR(6)/CPR で問い合わせるという方法。実はこの方法は未だ
      ble.sh には積極的に取り入れた事はない。とはいいつつも歴史的な端末でも軒並
      みこれに対応しているので、全ての端末で使えると思って良い。問題になるのは
      応答に時間がかかるので頻繁に問い合わせる訳には行かないという事。どのタイ
      ミングで問い合わせるのが良いのか非自明であるという点。

    取り敢えず実装としては a の方針を試すのが自然な気がする。実は canvas の
    panel を調整するだけで、他の部分は触れずに実装できてしまうのではないだろう
    か。前にも似た様な事を考えた事があるような気がしないでもない。

    自身の高さ変更だけでなく他の panel の高さ変更の時にも注意が必要。
    特に高さを増やす時。

    * ok: bell を表示する為の行が canvas origin の一つ上に確保されている事に注
      意する。と思ったが、\e7\e8 で移動するのであれば実は余り関係ないという気が
      する。

    ? reject: 間に適当な高さの空 panel を設置すれば良いのではないか、と思ったが
      間の高さが不明なので関係ない。

    * vfill 以降の高さが 0 の時に変な事が起こらないか
      →これについてはちゃんと意識して実装する事にした。

    うーん。取り敢えず実装した。canvas.sh に対する修正だけで大体動いているが細
    かい所で変な事が起こっている。

    x fixed: C-l をしても画面の一番上に移動しなくなってしまう。何故だろうか。
      →これは clear-screen する時に下部に excursion している状態で行っていたので、
      その後 textarea を描画する時に _ble_term_rc で位置が復元されるのが原因だった。

    x 空コマンドを実行した時に info が押し出されて消える。実装を見ると
      ble/widget/.insert-newline の *:keep-info:* が該当する部分だがちゃんと動
      きそうな気がする。と思ったら canvas.sh の panel#increase-total-height が
      未実装だったのを思い出した。

      % と思ったがよく見たらちゃんと実装できている気がする。然し整理した。それで
      % も動かない。そもそも普通に C-q C-j で改行を入力した時も info が消えてしまっ
      % ている。うーん。increase-height に失敗している?

      やっぱり実装できていなかった。端末の高さが十分に高い時は、全体の高さは増
      えない。うーん。制御機能を工夫してこれを何とかする方法は実際に存在するの
      だろうか。勿論 CPR や他の機能を使えば可能なのだろうと思うが基本的な移動と
      IND RI の組み合わせでできない物だろうか。

      うーん。無理の気がする。CUU&CUD の累積でできるのではないかと考えたが、累
      積させる方法が存在しない。


      やはり DECSTBM 等に依存するしかないのだろうか。或いは CPR を利用する。も
      しくは、再描画する。再描画が現実的な気がする、と思ったがサイズが変化する
      可能性がある場合全般に問題が発生するので、やはり現実的ではないように思わ
      れる。うーん。CPR を毎回発行して現在位置を記録する様にした方が良いのだろ
      うか。

      a reject: CPR の可能性について→余り現実的でない気がする

        ble/term/enter の辺りで CPR を発行する様にする事を考えたが。或いは
        ble/textarea#invalidate を発行する度に実行した方が良いのではないか。うー
        ん。然し、描画しようとしている時に即座に返答が帰ってくる訳でもない。と
        いって CPR が帰って来るまでブロックするというのも変だし、続きを async
        に処理するとういのも変である。やはり CPR は飽くまで補助的に使うべきなの
        だという気がする。或いは、画面の大きさが変わる時に初めて CPR 要求を出す
        という考え方もある。然し、そうすると async に処理しなければならなくな
        る…或いはその場で入力を待っても良いのかもしれないが…やはり駄目。別の
        入力を先に受信したりすると変な事になる。

      b done: 再描画の可能性について→呼び出し元で再描画が必要化判定するのは困難なの
        で event を発火するなどして対処する。

        実の所、再描画の為の関数を用意する筈だったので丁度良いのではないか。うー
        ん。再描画というよりは invalidate して、後で再描画するという形にするの
        が良い。invalidate については…。全体を invalidate するというのも考えら
        れるが一部を invalidate するというのも考えられる。矩形で invalidate さ
        れた領域を記録できる様にするのが良い気がする。

        →invalidate を呼び出してそれからそれを記録して、更に次の render の時に
        改めて反映させるというコードを ble-edit/info について新しく書いた。
        ble/textarea に関しては既に実装した関数を適当に呼び出すだけで良いという
        事にする。

      c done: DECSTBM を使う可能性について。取り敢えず最近の端末はこれに対応している
        だろうと想像されるのでこれを使うというので良い気がする。ble.sh 起動時に
        DECSTBM に対応しているかどうかを検出する。

    * done: DECSTBM の判定コード
      取り敢えず判定コードを書いた。

      →と思ったら行が消滅してしまう。うーん。→ IND の代わりに CUD を使って
      DECSTBM をテストする事にした。動いている。OK

    x fixed: cursor-position (DECSTBM が使えない場合) が info の中になってしまっている
      _ble_canvas_panel_focus という変数を用意した。
      然し、それでも振る舞いが変である。

    x fixed: (DECSTBM が使えない場合) 一番最後の行での描画が重複している。

      DECSTBM の有無で振る舞いが逆になってしまっている。これは明らかに
      set-height の振る舞いに (少なくとも片方は) 間違いがあるという事。

      →これは単純にバグだった。

    x fixed: DECSTBM を使っている時に一番最後から二行目が使われない。

      DECSTBM を使わない場合にはちゃんと動いているのでここにも何が間違いがある。

    * util (visible-bell) との干渉について

      x fixed: 実は visible-bell の実装にバグがある。

        RI を使って現在編集のコマンドと被らない様にしているが、実は現在行と被らな
        い様にしているだけであって、実際には編集文字列の2行目以降にいる時には
        visible-bell が上書きしてしまう。

      x fixed: 先頭行の visible-bell で info が消滅する。

      * resolved: _ble_term_{sc,rc} ... util.sh で使っている箇所がある

      * ok: visible-bell の中の trace で sc rc を使えない様にするべきでは? と思っ
        たが、visible-bell は純粋な text という事になっているので今は関係ない。
        将来的には esc seq も指定できる様にする可能性もあるが今は考えない。

    * resolved: ble/canvas 内で他にも _ble_term_{sc,rc} を使っている箇所がある。
      これは曖昧文字幅の問い合わせに使っていた。

    * ok: _ble_term{sc,rc} は edit.sh でも使っている箇所がある。
      →adjust-eol で使っている。これは大丈夫の筈。

    * ok: ble/canvas/panel#report-cursor-position 等については影響がないか確認
      が必要。ble/canvas/panel#get-origin についても。

      get-origin に関しては core-complete.sh で menu の構築で使われている様だが、
      絶対位置として他の panel の座標系と混ぜて使っている訳ではないので問題ない。

      report-cursor-position に関してはパネルの局所座標を引数に指定しているので
      呼び出し元は気にしなくて良い。特に問題も無い様に思われる。

    * done: trace で SC/RC を emulate する (with opts=noscrc)

    * done: bleopt で制御できる様にする

    * blerc に bleopt info_display を追記する。

2021-02-01

  * complete: support "bleopt complete_timeout_compvar" (motivated by 3ximus) [#D1457]
    https://github.com/akinomyoga/ble.sh/issues/82#issuecomment-770390986

    これは progcomp の関数を呼び出す時にパス名展開を実行しているからである。
    一応、応答がなくなるという事はないが補完に不自然に時間がかかるのは避けたい。
    progcomp の為に展開する時は noglob で展開する事も考えたが、
    展開した文字列を quote しているので、noglob で呼び出すと例えば *.txt
    が '*.txt' 等になってしまって意図しない結果になってしまう。

    どの様にするのが良いのかは不明である。或いは timeout したら '*.txt' にして
    しまうというのでも良いのかもしれない。

    bleopt complete_timeout_progcomp_glob=200 等の設定にして、timeout したら
    noglob で呼び出すというので良い気がする。

    retry-noglob-on-timeout という opts を追加する事にする。

    新しい bleopt の変数名は何が良いだろうか。

      complete_timeout_progcomp_glob だと長い。
      それに似たような変数が沢山あって気になる。
      そもそも単に timeout としていると何の timeout か分からない。

      ちゃんとした名前にするなら glob_timeout が良いが長い。
      一単語でこれを表現できないか。fsys_timeout, path_timeout, ...
      やはり専用の単語は存在しない以上は一単語にするのは難しい。
      また、似たような設定をまとめるという立場からすると以下の様な
      変数名で良いのではないかという気もしないでもないが、微妙。

        glob_timeout_progcomp
        glob_timeout_sync_highilght
        glob_timeout_async_highilght
        glob_timeout_auto_complete

      やはり highlight_*, complete_* という名前にしたい。

        highlight_timeout_sync
        highlight_timeout_async
        complete_timeout_auto
        complete_timeout_compvar

    →これは実際に試してみたが改善していない。

  * setup を動詞の様に使っている箇所が多くて気になるので修正する [#D1456]

    set up に代わる動詞を探しても余り良いのが見つからない。文脈に応じて全く違う
    表現に改めた関数もある。set up だけの場合には関数名としてはくっつけて setup
    としても良い事にした。setup-xxx というのは気になるのでせめて set-up-xxx の
    様に変更した。

2021-01-30

  * edit: emoji の表を更新する (reported by endorfina) [#D1455]
    https://github.com/akinomyoga/ble.sh/issues/84

    更新しようと思ったが現在のコードを確認すると色々工夫して高速化している。
    少し面倒である。取り敢えずデータのダウンロードだけは行う事にする。

    https://unicode.org/Public/emoji/

    色々考えて現在のコードの構造に近い形で再実装した。実は以前の実装に
    はバグがあった。

    以前のテーブルは https://github.com/vim-jp/issues/issues/1086 から
    拾ってきた物だったが、これは 2017 年の物だったので報告のあった
    flamingo の絵文字 (2018) は含まれていなかったのだ。

  * syntax: 構文解析で無限ループになっている [#D1454]

    特定のコマンドの編集で固まってしまったので gdb でアタッチしてみたらstack が
    300 段ぐらいまで成長している。問題の起こるコマンドを探ってみると、[[ ]] が
    あるかどうかで振る舞いが変わる様だ。

    [再現]

    $ for f in *; do [[ ]]; done

    に於いて、* の直前に "out/" を挿入しようとすると無限ループになる。 [[ ]] で
    はない別のコマンドの時には発生しない。


    [原因]

    | 構文構造を確かめてみると確かに構造が破壊されている。正常な場合にはちゃんと
    | 単語の chain が繋がって木構造を形成している。しかし、問題が起こるコマンドの
    | 場合、[[ ]] の兄要素が記録されていない。唯、これだけで無限ループになるとい
    | うのも変である。無限ループになってしまう原因も探りたい気がする。
    |
    | 正常時
    |
    | | $ for f in *; do :; done
    | | _ble_syntax_attr/tree/nest/stat?
    | | 18*a    000 'f' | stat=(CMDX w=- n=- t=-:-)
    | |  |*a    001 'o' |
    | |  |*a    002 'r' + word=CMDI:0-3/(wattr=d)
    | | 16*a    003 ' '   stat=(FARGX1 w=- n=- t=$3:-)
    | |  7*a    004 'f' + word=ARGI:@2>4-5/(wattr=d) stat=(FARGX1 w=- n=- t=$3:-)
    | | 36*a    005 ' '   stat=(FARGX2 w=- n=- t=$5:-)
    | | 37*a    006 'i' | stat=(FARGX2 w=- n=- t=$5:-)
    | |  |*a    007 'n' + word=FARGI2:@4>6-8/(wattr=d)
    | | 58*a    008 ' '   stat=(FARGX3 w=- n=- t=$8:-)
    | | 31*aw   009 '*' + word=ARGI:@7>9-10/(wattr=m1:72057594037934596) stat=(FARGX3 w=- n=- t=$8:-)
    | | 12*a    010 ';'   stat=(FARGX3 w=- n=- t=$10:-)
    | | 68*a    011 ' '   stat=(CMDXD w=- n=- t=$10:-)
    | | 20*a    012 'd' | stat=(CMDXD w=- n=- t=$10:-)
    | |  |*a    013 'o' + word=CMDI:@9>12-14/(wattr=d)
    | | 17*a    014 ' '   stat=(CMDX1 w=- n=- t=$14:-)
    | |  2*aw   015 ':' + word=CMDI:@13>15-16/(wattr=72057594037930241) stat=(CMDX1 w=- n=- t=$14:-)
    | | 12*a    016 ';'   stat=(ARGX w=- n=- t=$16:-)
    | |  1*a    017 ' '   stat=(CMDX w=- n=- t=$16:-)
    | | 19*a    018 'd' | stat=(CMDX w=- n=- t=$16:-)
    | |  |*a    019 'o' |
    | |  |*a    020 'n' |
    | |  |*a    021 'e' + word=CMDI:@15>18-22/(wattr=d)
    | |  |    s 022 ^@   stat=(CMDXE w=- n=- t=$22:-)
    | | \_ 'for'
    | | \_ 'f'
    | | \_ 'in'
    | | \_ '*'
    | | \_ 'do'
    | | \_ ':'
    | | \_ 'done'
    |
    | 異常時
    |
    | | $ for f in *; do [[ ]]; done
    | | _ble_syntax_attr/tree/nest/stat?
    | | 18 a    000 'f' |  stat=(CMDX w=- n=- t=-:-)
    | |  | a    001 'o' |
    | |  | a    002 'r' +  word=CMDI:0-3/(wattr=d)
    | | 16 a    003 ' '    stat=(FARGX1 w=- n=- t=$3:-)
    | |  7 a    004 'f' +  word=ARGI:@2>4-5/(wattr=d) stat=(FARGX1 w=- n=- t=$3:-)
    | | 36 a    005 ' '    stat=(FARGX2 w=- n=- t=$5:-)
    | | 37 a    006 'i' |  stat=(FARGX2 w=- n=- t=$5:-)
    | |  | a    007 'n' +  word=FARGI2:@4>6-8/(wattr=d)
    | | 58 a    008 ' '    stat=(FARGX3 w=- n=- t=$8:-)
    | | 31 aw   009 '*' +  word=ARGI:@7>9-10/(wattr=m1:72057594037934596) stat=(FARGX3 w=- n=- t=$8:-)
    | | 12 a    010 ';'    stat=(FARGX3 w=- n=- t=$10:-)
    | | 68 a    011 ' '    stat=(CMDXD w=- n=- t=$10:-)
    | | 20 a    012 'd' |  stat=(CMDXD w=- n=- t=$10:-)
    | |  | a    013 'o' +  word=CMDI:@9>12-14/(wattr=d)
    | | 17 a    014 ' '    stat=(CMDX1 w=- n=- t=$14:-)
    | | 12 a    015 '[' || nest=(ARGX0 w=- n=- t=-:-) stat=(CMDX1 w=- n=- t=$14:-)
    | |  | a    016 '[' |+ word=CMDI:15-17/(wattr=d)
    | | 32 a    017 ' ' |  stat=(CONDX w=- n=@15 t=$17:-)
    | | 12 a    018 ']' || stat=(CONDX w=- n=@15 t=$17:-)
    | |  | a    019 ']' ++ word="none":15-20>@19 word=CONDI:@16>18-20/(wattr=d)
    | | 12 a    020 ';'    stat=(ARGX0 w=- n=- t=$20:-)
    | |  1 a    021 ' '    stat=(CMDX w=- n=- t=$20:-)
    | | 19 a    022 'd' |  stat=(CMDX w=- n=- t=$20:-)
    | |  | a    023 'o' |
    | |  | a    024 'n' |
    | |  | a    025 'e' +  word=CMDI:@19>22-26/(wattr=d)
    | |  |    s 026 ^@    stat=(CMDXE w=- n=- t=$26:-)
    | | \_ '[[ ]]'
    | | |   \_ '[['
    | | |   \_ ']]'
    | | \_ 'done'
    |
    | どうも auto-complete が有効になっていると発生する様だ。
    | 入力のタイミングにも依る。一旦構文解析が終了してから無限ループに入る。
    |
    | 無限ループに入る時の構造
    |
    | | $ for f in out/*; do [[ ]]; done
    | | _ble_syntax_attr/tree/nest/stat?
    | | 18 a    000 'f' |  stat=(CMDX w=- n=- t=-:-)
    | |  | a    001 'o' |
    | |  | a    002 'r' +  word=CMDI:0-3/(wattr=d)
    | | 16 a    003 ' '    stat=(FARGX1 w=- n=- t=$3:-)
    | | 26 a    004 'f' +  word=ARGI:@2>4-5/(wattr=d) stat=(FARGX1 w=- n=- t=$3:-)
    | | 36 a    005 ' '    stat=(FARGX2 w=- n=- t=$5:-)
    | | 37 a    006 'i' |  stat=(FARGX2 w=- n=- t=$5:-)
    | |  | a    007 'n' +  word=FARGI2:@4>6-8/(wattr=d)
    | | 58 a    008 ' '    stat=(FARGX3 w=- n=- t=$8:-)
    | | 59*a    009 'o'    stat=(FARGX3 w=- n=- t=$8:-)
    | |  |*a    010 'u'
    | |  |*a    011 't'
    | |  |*a    012 '/' |
    | | 31 a  s 013 '*' +  word=ARGI:@10>12-14 stat=(FARGI3 w=FARGX3:9- n=- t=-:$8)
    | | 12 a  s 014 ';'    stat=(FARGX3 w=- n=- t=$14:-)
    | | 68 a  s 015 ' '    stat=(CMDXD w=- n=- t=$14:-)
    | | 20 a  s 016 'd' |  stat=(CMDXD w=- n=- t=$14:-)
    | |  | a  s 017 'o' +  word=CMDI:@13>16-18/(wattr=d)
    | | 17 a  s 018 ' '    stat=(CMDX1 w=- n=- t=$18:-)
    | | 12 a  s 019 '[' || nest=(ARGX0 w=- n=- t=-:-) stat=(CMDX1 w=- n=- t=$18:-)
    | |  | a  s 020 '[' |+ word=CMDI:19-21/(wattr=d)
    | | 32 a  s 021 ' ' |  stat=(CONDX w=- n=@19 t=$21:-)
    | | 12 a  s 022 ']' || stat=(CONDX w=- n=@19 t=$21:-)
    | |  | a  s 023 ']' ++ word="none":19-24>@23 word=CONDI:@20>22-24/(wattr=d)
    | | 12 a  s 024 ';'    stat=(ARGX0 w=- n=- t=$24:-)
    | |  1 a  s 025 ' '    stat=(CMDX w=- n=- t=$24:-)
    | | 19 a  s 026 'd' |  stat=(CMDX w=- n=- t=$24:-)
    | |  | a  s 027 'o' |
    | |  | a  s 028 'n' |
    | |  | a  s 029 'e' +  word=CMDI:@23>26-30/(wattr=d)
    | |  |    s 030 ^@    stat=(CMDXE w=- n=- t=$30:-)
    | | \_ '[[ ]]'
    | | |   \_ '[['
    | | |   \_ ']]'
    | | \_ 'done'
    |
    | うーん。変だ。やはり構文解析で起こっている無限ループではない様だ。とすると
    | 何が別の箇所で無限ループになっている。特に auto-complete で起こっているとい
    | う事、応答もしなくなる (SIGINT にも反応しない) という事から、
    | eval-pathname-expansion が怪しいのではないか。
    |
    | やはり /dev/zero で問題が発生しているという事なのだろうか…と思ったが、
    | msleep を read -t を使わない手法に置き換えても同様に無限ループになる事から
    | read -t ... /dev/zero の問題ではない。(それに [[ ]] によって構文構造がおか
    | しくなっている時にのみ発生するという事だから、やはり構文構造に関係のある問
    | 題なのだろう)。
    |
    | * 一つ怪しい箇所は extract-command である。core-complete.sh 関連でコマンド
    |   ライン内部の文法構造に関連する所と言えばこれしかない気がする。→実際に確
    |   かめてみたが無限ループは extract-command とは関係ない所で起こっている様だ。
    |
    | * パス名展開の中で起こっているとも考えにくい。何故ならばファイルの少ない場
    |   所でも問題が発生しているから。それに関数呼び出しが何十段にもなる事から、
    |   関数呼び出し自体で問題が発生しているというのは明らかである。
    |
    | 呼び出されている関数名を調べる事ができれば簡単なのだが難しい。
    |
    | * そもそも本当に auto-complete.idle の中で発生しているのだろうか。と思って
    |   確かめたらどうやら違う様だ。だとすると、bgworker による textarea#render
    |   が怪しい?
    |
    |   調べてみたらそうだった。更に textarea#render の中で怪しい所に絞り込みをか
    |   ける。どうやら update-text-buffer の中で問題が発生している。update-syntax
    |   の問題ではないようだ。update-text-buffer の中では layer/update を呼び出し
    |   ているので、恐らく layer:syntax/update が変な事になっているのだろう。
    |
    |   やはり ble/highlight/layer:syntax/update-word-table の中で無限ループになっ
    |   ている様だ。
    |
    |   ble/syntax/tree-enumerate-in-range で無限に要素が列挙されているか、或いは
    |   ble/highlight/layer:syntax/word/.update-attributes/.proc の中で無限ループ
    |   になっているかである。後者だった。
    |
    |   ble/syntax:bash/extract-command-by-noderef が怪しい。実際に中を調べるとど
    |   うやら ble/syntax/tree#previous-sibling が無限に兄要素を生成している様だっ
    |   た。何故その様な事になるのか。
    |
    | OK. 原因が分かった。
    | 1. 木構造が壊れている
    | 2. 単語情報のシフトに失敗する
    | 3. 兄要素の位置がずれて何も単語が登録されていない位置を参照している
    | 4. 空の単語情報なので兄の相対位置が '' = 0 に評価されて自己参照している。
    | という具合にして空単語でループが出来上がっている。実際に問題が起こっている
    | 時の木構造を見るとその様になっている。

    まとめると二つの問題がある。

    * [[ ]] の解析で構文木の兄情報が欠けてしまっている。nest-push する時に何故
      か tprev が記録されていないのが原因であろう。

    * 木構造が壊れている時に ble/syntax:bash/extract-command-by-noderef の中で
      兄ノードを探索する時に、一旦、空の単語情報に行き当たると自己参照して無限
      に兄ノードを取得してしまうという問題がある。

    [修正]

    後者に関しては、単語がちゃんと登録されているかどうか確認する様に実装を変更
    した。構文木の欠陥があった場合にそれを出力する様にした。これで構文木が壊れ
    ていても無限ループにはならない。

    前者に関しては何処で問題が生じているか分かった気がする。word-cancel した時
    に tprev の情報を復元しきれていないという事。然し、不思議なのは word-cancel
    は単語が設置された後に呼び出されるのだから tprev は既にその新しい値になって
    いる筈だという事。なので、改めて tprev を計算する必要はない筈なのである。

    うーん。もしかして二回連続で word-pop が起こった為に情報が消滅しているとい
    う事だろうか…。つまり nest-pop も既に終わっている状態という可能性?

    →恐らく2回連続で word-pop をした時に、外側の word から順に pop しているの
    がいけないのではないか。内側の word から順に pop するべきという事の気がする。
    いや、それも変だ外側の word を pop する時に内側の単語も全部削除するべきなの
    ではないか。うーん…? 或いは単語を設置する直前の状態に復元するというのが正
    しい振る舞いだろうか。

    改めて振る舞いについて何が起こっているのか考える事にする。

    A B [ [ X Y ] ] という状態になっている。但し [...] が単語の範囲である。そも
    そもどう言った情報が記録されているかというと。

    * 外側の単語については、tchild=(Yの位置), tprev=(Bの位置) になっている。
    * 内側の単語については、tchild=- tprev=- になっている。
    * 二つの単語を設置し終わった時の解析状態は、tchild=(Yの位置) tprev=- である。
    * 一つ単語終端を削除した時の解析状態は tchild=(Yの位置) tprev=(Bの位置) であるべき。
    * 更にもう一つ単語終端を削除した時の解析状態は tchild=- tprev=- になる。
      → word-cancel を2回施した時はこの状態を復元しているという事。

    実際の振る舞いを見ると tprev が初めから空になっている。これは nest-push を
    実行した為の気がする。nest-pop もちゃんと実行しておくべきの気がする? うーん。
    確認してみると別に nest-push した事によって tprev になっている訳ではない気
    がする。どういう事だろうか。そもそも inest=-1 になっている。変だ。

    ※現在の解析状態は "もしここで単語を閉じたらその単語にどの様な tchild,
    tprev が割り当てられるか" を表している。つまり、現在の文脈における
    tchild/tprev ではなくて、一つ上に上がった時の tchild/tprev である事に注意す
    る。

    よく分からなくなった。取り敢えず現在の実装を理解することは諦めて、改めてど
    の様に実装するべきかについて考えてみることにする。word-cancel は二種類の考
    え方がある。それぞれについて適切な実装は何だろうか。

    a 閉じてしまった単語を閉じる前の状態にする。

      この場合には実は単純に word に格納されている tclen tplen をそれぞれ
      tchild tprev に変換すれば良い。

    b そもそも単語がそもそも始まるよりも前の状態に戻す。

      この場合には tchild は記録されている単語の tprev で、tprev については変化
      はない。という事を考えると…。実は現在の実装はこちらを狙った物であると考
      える事ができる。

      この場合には word-cancel は実は一回だけしか呼び出さなくて良い。そして、一
      番外側の単語を削除すると同時に中に設置されている単語も全て削除するべきで
      ある。中に設置されている単語を削除するにはどうすれば良いか。tchild を辿っ
      て削除していく必要がある。面倒な事である。というか、tprev に至る迄を全削
      除で良いのではないだろうか。

2021-01-28

  * syntax/simple-word/eval: キャッシュ機能を付ける [#D1453]

    特に一回の着色 (layer:syntax/update) の中では同じ評価は一回しかしない様に工
    夫したい。キャッシュは dict に保存したいが二種類の問題がある。

    1. eval の展開結果は配列なのでそれをどうにか再評価可能な形式に変換する必要
      がある。bash-4.4 以降であれば ${ret[@]@Q} を用いれば良い。古い bash では
      この形式に合わせて記録を行う。

    2. bash3 では dict がないので工夫が必要

    取り敢えずこれは必要である。

    | うーん。それどころか一つのキーストロークの中でずっとキャッシュしても良いの
    | ではないか。tail 辺りで clear すれば良い。と思ったが余り変な事をしても駄目
    | な気もする。これだと bind 以外の枠組みで syntax/simple-word/eval を呼び出し
    | た時にキャッシュが全くクリアされなくて問題に成るのではないか。
    |
    | 例えば ble/builtin/read を使った時にキャッシュクリアが全くされないという事
    | になってしまう。但し、現在は read に対しては構文着色も auto-complete も有効
    | にしていないが。うーん。或いは widget を呼び出すタイミングでキャッシュをク
    | リアするという手もあるかもしれない…が、やはり ble/textarea#render と同じタ
    | イミングでクリアするのが自然な気がする。うーん。
    |
    | ble/textarea#render の中で clear してしまう? と思ったが、それはそれでやはり
    | 問題になる。将来的に textarea ではない物に対するキーボード操作も考えたいと
    | いう事を思うと、textarea#render の中からキャッシュをクリアするというのはや
    | はり変だ。
    |
    | そもそも汎用性を考えるのだとしたら cache は opts に指定した時にだけ使うとい
    | うので良い気がする。キャッシュをクリアする関数も別に公開しておいて、cache
    | を使う場合には自分でキャッシュの管理をせよという事にすれば良いのである。


    * done: dict を整備する。
    * done: キャッシュする様にする
    * done: キャッシュクリア用の関数を公開する

  * 2021-01-26 util: Cygwin 上で ble/util/msleep がフリーズしてしまう [#D1452]

    | 何故だろうか。普通にユーザコマンドとして実行した場合には特に問題は発生して
    | いない。サブシェルで実行しても問題は発生していない。内部 stty でサブシェル
    | で実行すると問題が起こる?
    |
    | →どうも繰り返し実行すると発生する様である。
    |
    | 以下を実行するとかなりの確率で固まる。
    | ( echo {1..1000} & builtin read -t 0.000100 v < /dev/udp/0.0.0.0/80 ) >/dev/null

    以下によって通常の bash でも固まるという事が分かった。Cygwin 特有の振る舞い
    である。Linux 上で試した限りでは問題は起こらない。

    ( echo {0..1000} >/dev/null & builtin read -t 0.001 v < /dev/udp/127.0.0.1/80 )

    他の実装だと exec 9<(sleep) を起動して置くという物や、builtin sleep を使う
    という物がある。

    a builtin sleep

      builtin sleep はコンパイラが利用可能なときにしか使えないのでこれに依存し
      たくない。飽くまで exec 9<(sleep) を使って実装して可能であれば builtin
      sleep を使うという様にする形になる。

    b 現在の /dev/udp/0.0.0.0/80 を弄って解決できないか

      うーん。不思議だ。'echo {1..1000}' を a.sh に書き出して置いて以下の様にす
      ると再現しない。

      ( . a.sh >/dev/null & builtin read -t 0.001 v < /dev/udp/127.0.0.1/80 )

      関数を function a { echo {1..1000}; } として a>/dev/null とした場合は再現する。

      * builtin read は read に置き換えても発生する。
      * 0.0.0.0 を 0.0.0.1 にすると通信エラーになって別の意味で使えない。
      * 127.0.0.1/80 でも再現する。
      * >/dev/null を >a.txt にしても再現する。
      * read を試みる前に様々なリダイレクトをしてみても状況は変わらない。
      * {0..1000} の部分や 0.001 の部分を変えると発生確率が下がる。

      うーん。微妙。というか環境が Cygwin だけというのであれば、最初からバイナ
      リを用意しておくという手もある。

      うーん。やはり Cygwin ではもっと別の実装を考えた方が良いだろうか。

    c exec 9< <(sleep)

      改めて exec 9< <(sleep) を試してみた所、遅延は殆どない様なので、これを採
      用する事にする。

    思えば今までにも時々あった Cygwin で固まってしまう問題はこれが原因だったの
    かもしれない。直前に fork してから is-stdin-ready を確認する機会が余りなかっ
    たり、或いはその他の条件で発生しにくかったりして再現しにくかったという事の
    気がする。という事を考えるとやはり /dev/udp/0.0.0.0/80 は今後は使わない方が
    良い気がする。

    →c の方法を使う事にした。古いコミットを参考にしてコードを復元する。
    8bb54be acb7163 d14557c f53c26d

    また udp によるコードを使いたくなるかもしれないので、取り敢えず今の所は
    bleopt internal_msleep_socket というオプションで udp 方式に切り替えられる様
    にしてコードを残しておく事にする。

    ----------------------------------------

    procsubst による実装に切り替えてもやはり同様の問題が発生する様だ…。
    うーん。どうした物だろうか。というかこれは bug-bash に報告しても良いのではないか。
    然し、normal Bash で再現させようとしても再現しない。然し症状としては同じなので、
    Cygwin における read のタイムアウトに問題があるという事は確かなのだろう。

    うーん。やはり Cygwin 用に特別にコンパイル済み sleep builtin を提供する?

    今試したら fifo が Cygwin 上でも動く様になっている。最近動く様になったのだ
    ろうか。或いは cygwin バージョンの問題だろうか。うーん。取り敢えず試しに動
    かしてみて、それで失敗したら procsubst に切り替えるという作戦にする。

    →駄目。やはり同じ問題が発生する。FIFO でも駄目という事。
    read -t を使うのが本質的に駄目という事なのだろう。
    唯、確率は格段に小さくなっている。

    sleep 10 | { echo {1..1000} >/dev/null & read -t 0.001 v; echo end; }

    この様にしている時には特に問題も発生しない様だ。

    builtin read -t "$v" v < "$$.pipe"

    この実装にしても固まる時には固まる。

    % 何と、builtin sleep を使っても同様に固まるという事が判明した。
    % つまり、read -t の問題ではない。Cygwin 自体に問題があるという事?
    % スレッドが停止するともう二度と動かないという種類の何か…。
    % →と思ったら勘違いだった。builtin sleep を使っているつもりが、
    % 別の方式をつかっていたのだった。

    一応 /dev/zero は期待通りに動く。但し、CPU 100% になるという事には注意する。
    短時間の sleep であれば /dev/zero に頼っても良いかもしれない。と考えたが、
    短時間の sleep を繰り返し使う場合などを考えるとやはり cpu100% になるのは好
    ましくない気もする。

    /dev/ptmx を試してみた。これはちゃんとブロックするし、勝手に停止してしまう
    事もないが代わりの問題として bash が終了しなくなってしまうという物がある。
    然し、通常の bash で同様の事をしても特に問題は発生しない様だ。何故だろうか。
    というか exec 9<&- を実行しようとしただけで固まってしまう。これは問題である。

    ble/util/msleep/.use-read-timeout socket check
    ble/util/msleep/.use-read-timeout fifo.exec2 check ||
      ble/util/msleep/.use-read-timeout procsub
    ble/util/msleep/.use-read-timeout fifo.open1
    ble/util/msleep/.use-read-timeout zero.open1
    ble/util/msleep/.use-read-timeout zero.exec1

    --------------------------------------------------------------------------

    結局 loadable builtin を使う事にしようと思って実装したが…。loadable
    builtin のライセンスはどうなっているのだったか。普通に考えるとこれは GPLv2
    に感染する気がする。という事は loadable builtin のソースコードをつけて配布
    するのは難しいという事になる。うーん。loadable builtin ならば OK という訳
    は…ないだろう。GPLv2 的に。調べたら正にそういう項目について記述されていた。

    https://www.gnu.org/licenses/gpl-faq.ja.html#GPLAndPlugins

    従って loadable builtins を使う方針は採用できない。結局、他の手法について考
    える必要があるのである。或いは確率が小さければ cygwin でも read -t を使って
    大丈夫だろうか、と思ったが conditional-sync を使っている限り、従来よりも格
    段に問題が起こる確率が高い。やはり read -t は諦めるべきだろうか。

    或いは conditional-sync の時だけ別の方法を用いるという可能性もある…。が、
    別の方法に心当たりがある訳ではない。どうしようもない。バイナリを添付する訳
    にも行かない。

    --------------------------------------------------------------------------

    取り敢えず /dev/zero では未だ hang が起きた事はないので、これで様子見する事にする。

  * util,syntax,complete: 配列内容の記録時に @Q を使った print に切り替える [#D1451]
    大した高速化ではないと思うがコードの整理も兼ねて。

  * syntax: auto-complete 内部の pathname-expansion についても conditional-sync を使う (motivated by 3ximus) [#D1450]
    https://github.com/akinomyoga/ble.sh/issues/82 (for auto-complete)

    取り敢えず [[ :$comp_type: != *:sync:* ]] の時には stop_check で実行して、
    それ以外の場合には強制的に実行するという方針で行く。

    ble/complete/util/eval-pathname-expansion に関してはそんなに面倒そうではない。
    ble/complete/util/eval-pathname-expansion は常にグロブパターンを伴って呼び出されるので場合分けは必要ない。
    常に conditional-sync を使えば良いのではないかという気がする。
    うーん。 *:sync:* が含まれる時だけはそのまま展開を実行する。
    →eval-pathname-expansion については対応した。恐らくこれで良いだろう。

    次に complete の内部から沢山の simple-word/eval を利用している。
    これらについても一つずつ確認して行く必要がある。

    以下の四つの関数が core-syntax.sh における stop_check を指定して実行するべき関数である。
    実際に使われているのは前者2つだけの様である。

    - ble/syntax:bash/simple-word/eval
    - ble/syntax:bash/simple-word/evaluate-path-spec
    - ble/syntax:bash/simple-word/detect-separated-path
    - ble/syntax:bash/simple-word/locate-filename

    |   $ grc 'simple-word/(eval|locate|detect)' lib/core-complete.sh
    | f lib/core-complete.sh:1970:    ble/syntax:bash/simple-word/eval "$subword" "$eval_opts"
    | f lib/core-complete.sh:1980:      ble/syntax:bash/simple-word/eval "$subword" noglob
    |   lib/core-complete.sh:2006:  ble/syntax:bash/simple-word/eval "$ret"; local value1=$ret
    |   lib/core-complete.sh:2011:      ble/syntax:bash/simple-word/eval "$ret"
    |   lib/core-complete.sh:2072:    ble/syntax:bash/simple-word/eval "$ret"; word=$ret
    |   lib/core-complete.sh:2093:          ble/syntax:bash/simple-word/eval "$ret"; left=$ret
    |   lib/core-complete.sh:2806:      ble/syntax:bash/simple-word/eval "$word" &&
    |   lib/core-complete.sh:2861:    ble/syntax:bash/simple-word/eval "$ret*" && ((${#ret[*]})) &&
    |   lib/core-complete.sh:3048:  local ret; ble/syntax:bash/simple-word/eval "$pattern"
    |   lib/core-complete.sh:3050:    ble/syntax:bash/simple-word/eval "$pattern*"
    |   lib/core-complete.sh:3223:    elif ble/syntax:bash/simple-word/eval "$reconstructed"; then
    |   lib/core-complete.sh:3229:        ble/syntax:bash/simple-word/eval "${reconstructed::${simple_ibrace#*:}}"
    |   lib/core-complete.sh:3234:      # Note: failglob により simple-word/eval が失敗した時にここに来る。
    |   lib/core-complete.sh:3624:  ble/syntax:bash/simple-word/evaluate-path-spec "$word0"; spec0=("${spec[@]}") path0=("${path[@]}")
    |   lib/core-complete.sh:3625:  ble/syntax:bash/simple-word/evaluate-path-spec "$word1"; spec1=("${spec[@]}") path1=("${path[@]}")
    |   lib/core-complete.sh:3705:        if ble/syntax:bash/simple-word/eval "$common_reconstructed" &&
    |   lib/core-complete.sh:3731:             ble/syntax:bash/simple-word/eval "$notilde$ret" noglob &&
    |   lib/core-complete.sh:3733:             ble/syntax:bash/simple-word/eval "$notilde$common_reconstructed" noglob &&
    |   lib/core-complete.sh:3761:                 ble/syntax:bash/simple-word/eval "$ret" &&
    |   lib/core-complete.sh:4206:      ble/syntax:bash/simple-word/eval "$ret"
    |   lib/core-complete.sh:4706:        ble/syntax:bash/simple-word/eval "$ret"
    |   lib/core-complete.sh:4930:  ble/syntax:bash/simple-word/eval "$ret"
    |   lib/core-complete.sh:5573:      if ble/syntax:bash/simple-word/eval "$ret" && local compv_new=$ret; then
    |   lib/core-complete.sh:5968:      ble/syntax:bash/simple-word/eval "$ret" || continue

    - ble/complete/progcomp/.compvar-generate-subwords/impl2
      この関数は eval を呼び出している。複数の単語に展開される時にそれを全て取得している。

    - ble/complete/source:argument/.contains-literal-option
      この関数は noglob を指定して変換を試すべきの気がするのでその様に変更する。

    - ble/complete/progcomp/.compvar-quote-subword

    - ble/complete/source:argument
      failglob で展開に失敗した時に * を付加して再度挑戦するのに使っている。
    - ble/complete/source:glob
    - ble/complete/candidates/.pick-nearest-sources
    - ble/complete/candidates/determine-common-prefix
    - ble/complete/candidates/determine-common-prefix/.apply-partial-comps
      ここでは evaluate-path-spec を使っている。
    - ble/complete/insert-common

    以上は候補生成時に使われる関数群である。
    全てユーザー入力があったらキャンセルという形で良い気がする。
    元々 148 を返す仕様の関数になっているので 148 の伝播についても面倒な対応は不要。

    - ble/complete/menu-filter
      これは .filter-candidates の戻り値を返すのを忘れている気がする。
      →修正した。

    - ble/widget/auto_complete/self-insert
      これは微妙。どの様にすればよいだろうか。
      timeout はまあいらない気がする。
      ユーザー入力によって interrupt されたらそのまま false を返せば、
      auto_complete モードから抜けるという動作になる。これで良い。

    - ble/complete/source:sabbrev
      % 展開した結果が使用されていない。バグが有る気がする。
      % →と思ったが iniitialize の中で参照されていた。

    [修正]

    * done: 毎回 timeout 等を設定するのは大変なので関数を用意する。
    * done: simple-word/{eval,evaluate-path-spec} の呼び出しを置き換える。

    x timeout した時に 142 を返すのを 148 に置き換えているが、
      これだと auto-complete 内部で timeout した時に、
      後続の idle まで中断してしまうのではないだろうか。

      →これは idle.do の側で修正する事にした。そもそも IS_IDLE で条件を差し替
      える事ができるようにしているので、呼び出した task の終了ステータスを信用
      する訳には行かない筈なのだ。

      此処で気になるのは complete における 148 の意味が必ずしもユーザ入力ではな
      くて、auto-complete における timeout の場合もあるという事になってしまった
      事だが、これが重大な結果を生み出す様には思われないので、取り敢えずはこれ
      で良いとする。

  * highlight: グロブパターンが含まれるファイル名の着色が遅い (reported by 3ximus) [#D1449]
    https://github.com/akinomyoga/ble.sh/issues/82 (for highlighting)

    glob expansion を subshell で実行してユーザー入力があったら timeout させる
    方針について考察。timeout は必要だろうか。

    * 或いは、もういきなり中断しても良いかもしれない。着色は次の rendering の時
      に反映させれば良いという発想。然し、その場合には再 rendering を発生させる
      為にどうにかして部分 invalidate しなければならない。或いは再描画の条件に
      着色未完の状態を含めても良いのかもしれない。着色の更新に関しては
      ble/textarea#update-text-buffer を呼び出した時に実行される。実は dirty
      range の有無に関わらず毎回 layer/update は呼び出される様だ。考えてみれば
      region の着色等は dirty range に関係なく変化する可能性があるので、この振
      る舞いも妥当である。

      一般に単語着色に関してはユーザーの入力があったら中断してしまって良いので
      はないだろうか。background worker の方で処理する事にすれば良い (但し、
      bash3 だと判定できないので難しい。bash3 に関しては loadable builtin が使
      えれば自前でそれを使ってしまうという手もある)。

    * キャッシュする可能性。同じ単語が繰り返し使われている場合に処理を短縮する
      為。これは特殊な場合にしか効果が現れない。余り効果はないのではないかとい
      う気がする。

    * globpat が含まれる場合にだけ subshell 実行する?
      globpat があるかどうかに関しては正規表現で判定すれば良い。

      "**" が含まれる場合にだけ subshell 実行するという可能性も考えたが、"*" や
      "?" だけでも大量のファイル名に展開される可能性もあるので、"*" だけ特別扱
      いしても仕方がない。

    * reject: ファイル数が多いディレクトリだけで subshell 実行する?

      ディレクトリ移動はそんなに頻繁に行わない筈なのでファイル数をディレクトリ
      移動をする度に確認すれば良いのではないか。と思ったが引数に
      dir1/dir2/... と指定する事もできるのでファイル数が多いディレクトリに現在
      いるかどうかという情報は余り当てにならない。

      "/" が含まれるかどうかを事前に判定する可能性もあるが、変数展開の中に / が
      含まれる可能性もあるので、完全に判定するのは難しい。

    * そもそも単語が単純な場合には展開の操作すら必要ないのではないか。

      {} も quote も history expan も param も ~ もない場合。

    [実装]

    * done: 取り敢えずユーザーからの入力がある場合には着色を中断する。サブシェ
      ルの中で実行する。後で着色し直す可能性については取り敢えず考えない。

      取り敢えず実装してみたが、微妙。とにかく入力を続ければ応答が全くないとい
      う訳ではないが、常に位置文字分だけ遅延している。何故だろうか。一文字だけ
      次の文字が来ている場合に次の文字が来ているという事を検出できていないとい
      う事だろうか。うーん。ble/decode/has-input の問題であろう。

    * done: simple-word/eval-noglob を eval ... noglob に書き換える

    * done: 以下の関数の呼び出し元で適切に stop_check を設定する様にする?

      ble/syntax:bash/simple-word/detect-separated-path
      ble/syntax:bash/simple-word/evaluate-path-spec
      ble/syntax:bash/simple-word/locate-filename

      特に bash3 で stop_check を行うかどうか。bash3 で stop_check をしたとして
      も常に is-stdin-ready は false になるので、唯単に今まで通りにブロックされ
      るだけである。然し、そうであるならば最初から subshell を生成する必要もな
      い。やはり bash3 では stop_check を省略する様に工夫する必要があるのではな
      いか。と思ったが、それならば simple-word/eval の側で bash3 では
      stop_check しないという様にしても良い気がする。
      →その様にする事にした。

      結局上記の3関数では常に stop_check を指定して、
      bash3 についての特別な取り扱いは simple-word/eval の側で実装した。

    * done: 以下の関数について 148 を返した時の振る舞いを正しく実装する。

      148 を返した時に現在はエラー着色にしているが、
      そうではなくて着色せずに抜ける事にする。

      ble/syntax:bash/simple-word/evaluate-path-spec [done]
        ble/syntax/progcolor/word:default/.highlight-filename [done]
          ble/syntax/progcolor/word:default [ok]
      ble/syntax:bash/simple-word/locate-filename/.exists [done]
        ble/syntax:bash/simple-word/locate-filename [done]
          ble/syntax/progcolor/word:default [ok]
        ble/syntax:bash/simple-word/detect-separated-path [done]
          ble/syntax/progcolor/word:default/.detect-separated-path [done]
            ble/syntax/progcolor/word:default [ok]

      取り敢えず ble/syntax/progcolor/word:default まで行って抜ければ、
      単語情報として何か間違った物が登録される事はない。

    x ok: ble/decode/has-input で次の文字が来ている判定しているが、一文字分だけずれ
      がある様に見える。何が起こっているのか調べる必要がある。

      調べてみると既に次の文字は受信している様である。
      問題は未だ処理しきっていないのに描画が実施されているという事である。
      コールスタックを見るとちゃんと EPILOGUE から呼び出されている。
      つまり、ちゃんと文字を処理してからという事になっている筈である。

      と此処で理由が分かった。入力した文字を表示する為に配色を計算しているのだから、
      配色を計算している間は未だ文字が描画されないというのは道理である。
      やはり timeout を入れないと変である。

      conditional-sync に timeout 機能も付ける事にする。

    * done: 着色せずに抜けた場合にはその事を記録に残す (progcolor_dirty)。
      これは ble/syntax/progcolor/word:default に対して実行すれば良い。
      或いは idle に bgworker を登録するだけでも良い?
      と思ったが、それだと沢山の bgworker が生成されてしまう気がする。
      idle に bgworker を登録するとしても、
      未着色単語がある事の情報は何処かに記録する必要がある。

      実は未着色範囲を管理した方が自然な実装になる気もする。
      例えば _ble_syntax_word_async_u{min,max} 等の変数に記録する。
      bgworker ではこれを _ble_syntax_word_u{min,max} に反映させて
      その上で着色を実行する…と思ったが shift 等の取り扱いがどうなるのか分からない。
      _ble_syntax_word_u{min,max} の場合にはどの様にしていただろうか。
      というより、_ble_syntax_word_u{min,max} が設定されるのはどのタイミングだろうか。

      % うーん。ble/syntax/parse/touch-updated-word で変更している。そしてこれは
      % ble/syntax/parse の中で呼び出される物である。一方で、ble/syntax/parse は
      % ble-edit/content/update-syntax から単体で呼び出される事もある。という事を
      % 考えると、此処で設定された _ble_syntax_word_u{min,max} は処理される事なく
      % 次の ble/syntax/parse に伝播する可能性があるという事。その時に必要になる
      % と考えられる shift が実行されていない。
      %
      % _ble_syntax_attr_u{min,max} についても同様である。これらもちゃんと shift
      % する必要がある。
      %
      % →と思ったら、ble/syntax/parse/shift の中でちゃんと shift されていた。
      % _ble_syntax_word_ 及び _ble_syntax_attr_ が接頭辞になっていたのだった。


    * done: 着色せずに残っている部分を着色する bgworker を実装する。
      最後まで完了した時に progcolor_dirty を clear する。

    * done: highlight_timeout_background: bg で着色している時の timeout は長めに取る。

    x fixed: 実際に試してみると相変わらず止まってしまう。CPUがぶんぶん回っている。

      調べてみると eval が stop_check なしで呼び出されている。
      stackdump してみると以下の様な呼び出しになっている。
      どうやら simple-word/eval の呼び出し元のチェックに漏れがあった様だ。

      stackdump:
        @ /home/murase/.mwg/src/ble.sh/out/lib/core-syntax.sh:27 (ble/syntax:bash/simple-word/eval)
        @ /home/murase/.mwg/src/ble.sh/out/lib/core-syntax.sh:17 (ble/syntax/progcolor/eval-word)
        @ /home/murase/.mwg/src/ble.sh/out/lib/core-syntax.sh:5 (ble/syntax/progcolor/word:default/.is-option-context)
        @ /home/murase/.mwg/src/ble.sh/out/lib/core-syntax.sh:26 (ble/syntax/progcolor/word:default/.impl)
        @ /home/murase/.mwg/src/ble.sh/out/lib/core-syntax.sh:3 (ble/syntax/progcolor/word:default)
        @ /home/murase/.mwg/src/ble.sh/out/lib/core-syntax.sh:7 (ble/syntax/progcolor/default)
        @ /home/murase/.mwg/src/ble.sh/out/lib/core-syntax.sh:31 (ble/syntax/progcolor)
        @ /home/murase/.mwg/src/ble.sh/out/lib/core-syntax.sh:8 (ble/highlight/layer:syntax/word/.update-attributes/.proc)
        @ /home/murase/.mwg/src/ble.sh/out/lib/core-syntax.sh:12 (ble/syntax/tree-enumerate-in-range)
        @ /home/murase/.mwg/src/ble.sh/out/lib/core-syntax.sh:2 (ble/highlight/layer:syntax/word/.update-attributes)
        @ /home/murase/.mwg/src/ble.sh/out/lib/core-syntax.sh:4 (ble/highlight/layer:syntax/update-word-table)
        @ /home/murase/.mwg/src/ble.sh/out/lib/core-syntax.sh:32 (ble/highlight/layer:syntax/update)
        @ /home/murase/.mwg/src/ble.sh/out/ble.sh:12 (ble/highlight/layer/update)
        @ /home/murase/.mwg/src/ble.sh/out/ble.sh:9 (ble/textarea#update-text-buffer)
        @ /home/murase/.mwg/src/ble.sh/out/ble.sh:75 (ble/textarea#render)
        @ /home/murase/.mwg/src/ble.sh/out/ble.sh:2 (ble-edit/bind/.tail)
        @ /home/murase/.mwg/src/ble.sh/out/ble.sh:17 (ble-decode/EPILOGUE)
        @ /home/murase/.mwg/src/ble.sh/out/ble.sh:78 (ble-decode/.hook)

      取り敢えずこれについては修正した。

    x ok: 次におかしいのは、既に着色済みの筈単語も改めて毎回着色されている様な気がするという事。

      と思ったらやはり気の所為だろうか。。。今度はちゃんと新しい単語に対しての
      み処理が行われている様な気がする。と思ったが、どうも word:default 自体は
      新しい単語に対してのみ呼び出されているが、simple-word/eval は何度も呼び
      出されているという事の様である。呼び出し履歴を探ると以下の様になっている。

        ble/syntax:bash/simple-word/eval
        ble/syntax/progcolor/eval-word
        ble/syntax/progcolor/word:default/.is-option-context
        ble/syntax/progcolor/word:default/.impl
        ble/syntax/progcolor/word:default
        ble/syntax/progcolor/default
        ble/syntax/progcolor
        ble/highlight/layer:syntax/word/.update-attributes/.proc
        ble/syntax/tree-enumerate-in-range
        ble/highlight/layer:syntax/word/.update-attributes
        ble/highlight/layer:syntax/update-word-table
        ble/highlight/layer:syntax/update
        ble/highlight/layer/update
        ble/textarea#update-text-buffer
        ble/textarea#render
        ble-edit/bind/.tail
        ble-decode/EPILOGUE
        ble-decode/.hook

      うーん。分かった。ble/syntax/progcolor/word:default/.is-option-context で
      全ての引数に対して評価を行っている。ble/syntax/progcolor/eval-word で一応
      キャッシュはしているが、これは一回の着色の内部でのキャッシュであって、着
      色を跨いだキャッシュは行っていない。これはまた別の箇所で対策するべきの気がする。

    x fixed: 展開が timeout した時にエラー着色になっている。
      timeout の時には d で削除する事にしてみたが、
      d ではなく 0 になってしまって黒で塗潰されている。

      どうやら #setattr は g を設定するのであって、
      wattr の指定を行える物ではない様だ。

    * reject: 実は pathname expansion に限らずユーザー入力がある時には単語着色
      は中断して良いのではないだろうか。

      うーん。これは様子見。早く着色が終わる物から順に着色して行かないと、一番
      遅い着色によって他の着色がブロックされてしまう。なので、軽い物は先に処理
      するべき。何段階にも分けるのは現実的でないので、現状は重い単語だけ処理を
      後回しにする事にする。

    x fixed: ble/util/assign の混線に関連して発生していた様々な問題

      x "bash: 予期しないトークン `(' 周辺に構文エラーがあります" というエラー
        メッセージが出る。何処かにバグが有るという事。background で実行している
        時に発生している気がする。先ずは再現性。

      x うーん。操作していると突然 hang して暫くして emacs が起動した

        何やら操作していたら "# reached line_limit_length=10000" に抵触して、そ
        の後に emacs が起動した。2500項目の要素を含んだ "ret=(......) fdsa1
        aaaa" と言った感じの内容が入力されている。これが意味する所は何
        か。_ble_edit_str に内容が展開されているのが原因と考えられるが何が起こっ
        ているのだろうか。

        a ble-decode-char に紛れ込むとは考えにくい。

        b terminal の echo back に引っかかっているとも考えにくい。そもそもその為
          にはそれ専用の escape sequence で囲まなければならないし、それを出力する
          ような事が起こるとも思えない。

        c _ble_edit_str を直接編集している箇所もないだろうし、

        d 一つの可能性は ble/util/assign の混線である。然し、そうだとしても
          ble/util/assign で挿入内容を決定する様な機会があるだろうか。

        TAB は入力していなかったと思う。従って補完が関係している可能性は取り敢
        えず除外する事にする。

        →あー。分かった。ble/util/assign の混線である。conditional-sync で
        timeout した時に動かしていたプロセスを kill するのを忘れていた為に、遅
        延して ble/util/assign の一時ファイルに様々な情報が書き込まれて変な事が
        起こっていたという事。一つ前の問題もこれに関連して発生していた現象であ
        ろうと推測される。取り敢えず再びいろいろ試して問題が再現しないか確認す
        る必要がある。

      x fixed: failglob が発生する様な状況で failglob にならなくなっている。何
        故だろうか。これは瞬間的に timeout になっている所為で、failglob で失敗
        するよりも先に timeout 142 を返して、その為に着色が無効化されているのが
        原因だった。

    * done: glob が有効な場合でも実は最初に noglob で展開を行って、其処に
      rex='[*?]|\[.*\]|[@+!]\(.*\)' が含まれている時に限り改めて
      subshell で実行するという形式にしても良いのではないだろうか。

      これに関してはわざわざ noglob で展開を行わなくても、
      変数代入を実行すれば良いのではないだろうか。
      builtin eval -- "tmp=$word"

    * done: bash3 では globstar を一時的に off にする事も考える。

      然し、そうするとユーザに対して嘘の情報を提供する事になる。本来は一致する
      筈なのに failglob して赤色に着色される等の可能性。そういう事を考えるとや
      はり時間がかかっても良いから着色するか、或いは着色自体を諦めるか。簡単な
      内容の場合には着色を諦めても良いのではという気がする。

      或いは、** が含まれる場合に限って着色を諦めるという手もある。即座に 142
      を出力する様にすれば良い。これで OK

    * done: 変数展開の中まで参照して noglob かどうかを判定する前に、
      先に extract-parameter-names & 変数内容の復元をするべき。

      再び eval の構造を大きく書き換えたが取り敢えずは動作している模様である。
      取り敢えず conditional-sync を経由した展開も動いている様子だ。OK

    x 別項目: 全く同じ内容で eval を連続して2回試すという事が頻繁に起こっている。
      これは何だろうか。やはり eval-word による呼び出しと、それから本当の着色用
      の呼び出しが混ざっているという事だろうか。これに関しては、eval の呼び出し
      をキャッシュする事で対応できる気がする。

      但し呼び出しをキャッシュすると言っても、bash3 でどの様に対処するべきかは
      微妙である。やはり汎用の hash 辞書のインターフェイスを準備するべきかもし
      れない。

      これは調べてみた所、ble/syntax:bash/simple-word/detect-separated-path と
      ble/syntax:bash/simple-word/evaluate-path-spec の二箇所で発生していれう事
      の様である。これは eval の内容をキャッシュする様にすれば解決する話である。
      独立項目で取り扱う事にする。

2021-01-25

  * edit: change default behavior of "C-w" and "M-w" to operate on backward words (reported by 3ximus) [#D1448]

    ? done: C-w の振る舞いを readline に合わせる?

      後、やはりここまで来ると普通の bash との振る舞いの違いが俄然気になってくる。
      やはり C-w は kill-uword ではなくて kill-backward-uword であるべきなのではないか。
      やはり既定で kill-backward-uword にする様に変更する。
      M-w による copy-backward-word についてはどうするか。
      どうも readline の copy-backward-word は widget copy-uword と同じ振る舞いの様である。
      しかし、M-w は元の readline では使われていないし、
      ble.sh の M-w でどの様に振る舞っても問題はない気がする。

    ? ok: C-w で kill-uword する現在の振る舞いに何か理由があっただろうか。
      何か理由があって敢えて現在の振る舞いにしている可能性もある。

      bbbd155f src/edit.sh (Koichi Murase     2019-03-22 07:28:24 +0900 6763)   ble-decode/keymap:safe/.bind 'C-w'       'kill-region-or kill-uword'
      1fc7cbaf ble-edit.sh (Koichi Murase 2017-12-04 20:48:17 +0900 6185)   ble-decode/keymap:safe/.bind 'C-w'       'kill-region-or uword'
      f18485f0 (Koichi Murase 2017-12-04 14:36:52 +0900 4442)   ble-bind -f 'C-w'       'kill-region-or uword'
      3aa7fa66 (Koichi Murase 2017-12-03 18:31:00 +0900 4461)   ble-bind -f 'C-w'      'kill-region-or uword'
      6ca737d2 (Koichi Murase 2015-02-28 12:48:55 +0900  54)   ble-bind -f 'C-w'      'kill-region-or uword'
      ^c68412b (Koichi Murase 2015-02-09 03:13:19 +0900 3381)   ble-bind -f 'C-w'      'kill-region-or uword'

      どうやら一番最初に commit した時から現在の振る舞いだった様だ。
      ここから分かる事は現在の振る舞いに根拠はないという事。
      実装初期に kill-backward-uword がなかったか不完全だった時からこうである可能性がある。
      なので、振る舞いを現時点で変更しても何の問題もない。

      copy-uword vs copy-backward-uword についても全く同じだった。
      最初から M-w は copy-uword になっていた。

    これは他の ble versions にも適用した方が良いと思われるので独立した commit にする事にした。

  * edit ({kill,copy}-region-or): fix unconditionally combined kills/copies (reported by 3ximus) [#D1447]
    https://github.com/akinomyoga/ble.sh/issues/83#issuecomment-766831785

    C-w で無限に文字列が追加されてしまうという事を指摘された。

    % 何故だろう。手許で確認した時には動いている様に見えたのに。と思ったが手許で
    % 試した時は C-k や C-u を使っていたために気づかなかったという事の気がする。
    % →と思ったら分かった。テストのために自分で ble-bind していたが、
    %   その時に kill-region-or を使っていなかった。

    kill-region-or または copy-region-or の中で
    ble/decode/widget/call を用いて widget を呼び出した時に
    LASTWIDGET が {kill,copy}-region-or に書き換わる為に、
    無条件に前回のコマンドが切り取りコマンドであったと判定されてしまうのが原因。
    取り敢えず修正した。ble/decode/widget/* の関数がまた増えてしまったが仕方がない。

  * mandb: man のオプションの情報が文字化けしている [#D1446]

    % キャッシュが全然使われていない。毎回再生成されている様に見える
    % と思ったが、これは単に core-complete.sh が更新されたから、
    % それに応じて更新されているというだけの事だった。

    データを再生成してもやはり同様に文字化けしてしまう。

    調べると nroff は UTF-8 には対応していない様だ。groff は groff -k にて
    UTF-8 に対応する様だ。更に -k に加えて -Tutf8 も必要だった。

    groff ではなくて nroff の時にはどうするのかという問題は残るが、まあ groff
    のないシステムでは UTF-8 の man は存在しないと思って良い気がする。なので取
    り敢えずは気にしない事にする。

  * 2020-11-02 complete: support complete_limit{,_auto} (contributed by timjrd) [#D1445]
    https://github.com/akinomyoga/ble.sh/issues/64
    https://github.com/akinomyoga/ble.sh/issues/65

    これは時間はかかったが無事に merge まで行った。

    * done: source:file において substr を実装する。
    * done: filter を自前で実行する場合には cand/yield 内部での filter は不要。
      これは flag_source_filter=1 を設定して実行する事にした。
    * done: timjrd を README/acknowledgement に追加する。
    * done: complete_limit_reached にリークが存在している。
      ちゃんと source:* や candidates/generate などのコメントに使う変数を記述して、
      それから auto-complete の中で candidates/generate を呼び出す前に local で宣言する。

  * main: nfs の上に _ble_base_run があると問題になるのでは [#D1444]
    取り敢えずローカルに runtime directory を作る時には $HOSTNAME も含める事にした。
    XDG_RUNTIME_DIR 及び /tmp を使う場合には host specific であると期待してその儘にする。

2021-01-22

  * edit: C-w で kill-ring への追加を実装するという事 (suggested by 3ximus) [#D1443]
    https://github.com/akinomyoga/ble.sh/issues/83#issuecomment-764893198

    これについては先ず初めに仕様を確定しなければならない。

    例えば前方を切り取るコマンドの場合には必ず左に挿入する事にする? と思ったが、
    そうすると C-k を連続で使用した時に、切り取られる行の順序が逆になってしまう。

    ? というよりどの様なコマンドが存在しているだろうか。

      | 調べると C-k, C-u, C-w, M-d, M-h で kill-... を実行している。
      |
      | widget 名で言うと
      | - kill-{forward,backward}-{?word,{graphical-,logical-,}line,text}
      |   これの対応は簡単。backward に削除する場合には prepend し、
      |   forward に削除する場合には append すれば良い。
      | - kill-{?word,{graphical-,logical-,}line}
      |   これは微妙。emacs でどの様に振る舞っているだろうかと考えたが、
      |   よく考えてみたらその様に振る舞う物は存在しない気がする。
      |
      |   emacs.rlfunc.txt で対応表を見てみたが、kill-line に対応する
      |   rlfunc kill-whole-line しか振る舞いを確認できる物が存在しない。そして、
      |   この rlfunc kill-whole-line は kill-line と違って、
      |   コマンドライン全体を切り取ってしまうのでやはり振る舞いとして異なる。
      |
      |   と思ったが、実際に readline で実行してみると kill-whole-line は
      |   前回の内容に append する様である。取り敢えず ble.sh でもその様に振る舞う事にする。
      |
      | - kill-region
      |   これは前回の内容は完全に忘れるという振る舞いで良い。
      |
      | - vi_imap/delete-backward-word
      |   これは実は kill-ring には何も影響を与えない様だ。取り敢えず無視する事にする。
      |   readline の vi mode の時には kill するが combine はしない様だ。

      →結論としては、kill-region,kill-region-or 以外の kill-* は全て対象という事。
      kill-backward-* に関しては prepend で、それ以外については append という事。

    ? ok: append/prepend をした時に元々あった内容を上書きするのか、
      新しく項目が追加されるのか。
      →試して見た所、上書きする様である。

    ? done: /.*-range の allow_empty という引数は必要なのだろうか。
      kill,copy,delete に関しては決して指定される事はない。
      replace に関しては大体指定されている。
      指定されていない物は意図的な物かどうか確認する必要がある。

      - ./keymap/vi.sh:3995:    ble/widget/.replace-range "$eol1" "$eol2" "$text"
      - ./keymap/vi.sh:4016:    ble/widget/.replace-range "$eol1" "$bol2" "$text"
        上記二つに関しては eol1<eol2 が保証されているのでどちらでも良い。
      - ./lib/core-complete.sh:5832:    ble/widget/.replace-range "$pos" "$comp_index" "$value"
      - ./lib/core-complete.sh:5865:      ble/widget/.replace-range "$pos" "$comp_index" "$value"
      - ./lib/core-complete.sh:5871:    ble/widget/.replace-range "$pos" "$comp_index" ''
        上記3つに関しても同様に pos<comp_index が保証されている。
      - ./lib/vim-surround.sh:509:  ble/widget/.replace-range "$beg" "$end" "$content"
        operator なので幅0になる事は余りない気がするが、例えば編集文字列が空の時?
        →うーん。その様な場合であっても cs 経由でしかこの operator は呼び出されないので、
        結局、delimiter を使って範囲を切り出そうとする段階で失敗してしまう。
        結局、この operator が空文字列に対して呼び出される事はない気がする。

        もし仮に呼び出される事があったとしても、allow_empty を指定する方が自然。

      replace-range については常に allow_empty という事にする。
      kill,copy,delete については常に not allow_empty という事にする。
      →書き換えた。

    ? done: copy でも同様に振る舞う必要があるだろうか。
      →実際に試してみた所、同様に振る舞う様である。。。

    動かしていて気づいたが、C-k で行末の改行を削除できていない…。
    これは別 commit での bugfix にする事にする。

  * edit: support "bleopt edit_line_type" (motivated by 3ximus) [#D1442]
    https://github.com/akinomyoga/ble.sh/issues/83

    手で一つ一つ logical-line を明示的に指定するよりは、
    一つのオプションで一括で切り替えられる様にした方が良い。
    更に、今まで既定で graphical line を使っていたのを、
    logical line を使う様に変更する事にする。

  * edit (sword): fix definition of sword (motivated by 3ximus) [#D1441]
    https://github.com/akinomyoga/ble.sh/issues/83#issuecomment-764893198

    この質問で具体的に各単語がどのような定義になっているのか説明しようとして
    コードを参照した時に気づいた。sed によって & が置換前の文字列に展開されて、
    変な事になっていたのが原因。

2021-01-17

  * LC_CTYPE の切り替えエラーが出る (reported by 3ximus) [#D1440]
    https://github.com/akinomyoga/ble.sh/issues/81

    実際に確かめてみたら確かにエラーメッセージが出る。
    過去に対策したつもりだったが対策の仕方が間違っていた。
    色々実験した所、結局余計に一つ関数呼び出しをしなければ駄目な様だ。
    自動で stderr を抑制するように書き換える汎関数を作って対応する事にした。

2021-01-01

  * decode (ble-decode-kbd): support various keyseq specifications [#D1439]
    https://github.com/urbainvaes/fzf-marks/pull/41
    https://github.com/urbainvaes/fzf-marks/pull/43

    上記で ble.sh 特有の binding を追加してもらったが、ble-bind がユーザーが自
    由に対応キーを指定できる様に公開されている変数 FZF_MARKS_JUMP の形式に合わ
    ない為に C-g 決め打ちになってしまっている。ble-bind でも bind と同様の形式
    で keyseq を指定できる様にしたい。

2020-12-25

  * edit: f1 で関数定義を表示する時に LESS=-r が効いていない [#D1438]
    これは bash のバグの様である。バグ報告は bug-report でする事にして、
    ここでは簡単に修正してしまう。

  * edit: 2020-12-09 READLINE_MARK, etc. の値が残ってしまっている [#D1437]

    これは ble/textarea#adjust-for-bash-bind によって設定されている値である。
    コマンドを実行する時に復元・保存する様にするのが良いのではないだろうか。

    * 何故か READLINE_LINE, READLINE_POINT が export されている。
      と思ったが、これは ble.sh を bind -x の内部で動かしているからであった。
      READLINE_LINE 及び READLINE_POINT が

    * 普通の bash で実行するとどうなるのかと思ったが、どうやら自分で設定した
      READLINE_LINE 及び READILNE_POINT があっても bind -x の実行と共に削除され
      てしまう様である。

    取り敢えず adjust/restore する様にした。コマンドの実行の間で値が保存される
    様にした。bind -x が実行されても値がクリアされる事はない。

2020-12-20

  * [解消] 2020-09-27 SIGWINCH で job メッセージが出る [#D1436]
    2020-12-20 これは #D1435 と同一の問題であろう。直ったと見て良い。

    SIGWINCH に対して次の様な job メッセージが表示される様になっている。
    [1] 終了 [[ -n $_dotfiles_blesh_manual_attach ]] | [[ -n $_dotfiles_blesh_manual_attach ]]
    これは .bashrc で設定されている関数の一部である。何故?

    調べてみるとそもそも関数ですらなくて、
    これは ble-attach を呼び出す条件の中に含まれているコマンドだと分かった。
    つまり SIGWINCH に際して ble-attach 関連の何かが呼び出されて、
    そして最後に呼び出された ble-attach の呼び出し時のコマンド文字列が何処かに保持されている?
    もしくは再び .bashrc が source されている可能性もあるがやはりそれは変だ。

    2020-10-10 今試してみると再現しない。


  * edit: WINCH 後に偽のジョブ情報が表示される (reported by 3ximus) [#D1435]
    https://github.com/akinomyoga/ble.sh/issues/78

    前回報告を受けていた謎のジョブ終了メッセージについて。
    これは端末のサイズを変えた直後に起こるという新情報を得た。
    3ximus/dotfiles の .bashrc を確認して再現を試みた所、
    git-prompt.sh, prompt_7.sh, ble.sh の組み合わせで再現できた。

    更に設定を最小化していく。どうやら fork があると
    jobs にメッセージが乗る様になってしまうらしい。

    これの回避方法としてどの様な方法があるか。

    a jobs で得た新しいイベントを除去する?
      然し、これの問題点は唯の fork と、
      本当にジョブとして起動したコマンドの区別が付かないという事。

      振る舞いの違いとしては trap handler の中で発生したfork に対応するジョブの
      情報は trap handler を抜けた時に消滅しているという事である。

      但し、バックグラウンドとして起動したコマンドのジョブ情報もtrap handler を
      抜けると消えてしまうのかもしれない。試せば分かるが面倒なので必要になった
      ら確認する事にする。

    b もう一つの方法はシグナルを処理している時は
      jobs の更新は行わないという物。これが妥当な気がする。

      ? この現象が起こるのは WINCH だけなのか、或いは別のシグナルでも発生するのか。
        →確認した所、INT でも同様にジョブ情報に fork が乗る様である。

        trap '(true); jobs' INT

      ? 現在シグナルの中にいるかどうかを判定する方法は存在するだろうか。
        或いは ble.sh の枠組みの中で trap-handler 経由で呼び出されたか
        どうかの情報を用いて判定する?

        trap-handler の中にいるかどうかの判定方法。一つは return を
        使って関数を抜けた時に、直前の exit status を返すか、
        或いは固定の exit status を返すかを見るという方法。
        よく考えたらこれは bash-4.4 以降でしか使えない。
        Bash はこの部分について振る舞いを変更したのだった。

    % 取り敢えず b の方向で実装する事にする。
    % ble.sh の中での jobs の仕様実態について確認する。
    %
    % どうやら指定した名称に対応する jobs が存在するかどうかの確認にも
    % jobs -- "$value" を使用している様である。これについては、偶々
    % value に一致する終了したジョブ名が存在すると jobs -- "$value" を実行する事によって
    % その情報がジョブ情報のリストから削除されてしまう。この問題を回避する為に
    % jobs -- "$value" を実行する為に ble/util/joblist.check を実行しているが、
    % trap handler の中で joblist.check をスキップしてしまうと、
    % そのジョブ情報が正しく拾われずに消滅してしまう可能性が残る。
    % trap handler の内部では jobs はサブシェルで実行するのが良い気がする。
    %
    % 1 done: 何れにしても最初に trap handler の中で実行しているかどうかを確認す
    %   る必要がある。特に ble.sh の実装が原因で発生する変なメッセージを防げれば
    %   良いので、trap/.handler の中でローカル変数を定義する事にする。
    %
    % 2 done: jobs を使っている箇所を確認する。
    %
    %   * util.sh は ble/util/joblist だけでしか jobs を呼び出していない。修正した。
    %   * core-syntax.sh も ble/syntax/highlight/cmdtype/.is-job-name だけで使っ
    %     ている。対策した。
    %   * edit.sh では ble/builtin/exit で終了する時にユーザに確認を求める所で実
    %     行しているが、exit する時には何れにしてもジョブ一覧を出力するので敢えて
    %     直接実行する。変なジョブ情報が出力される事になってしまうがこれは仕方が
    %     ない。
    %   * 他に ble/widget/command-help/.type で jobs -- "" を実行している。これに
    %     ついても修正を行った。
    %
    % 3 動作確認: さて、実際に修正して見た所直っていない。どうも trap を抜けた後
    %   も変なジョブ情報は残っている様である。ユーザのコマンドとして jobs を実行
    %   すれば変なジョブは消えてなくなっているが、bind -x の中から jobs を呼び出
    %   すと全て出力されてしまうという事だろうか。
    %
    %   サブシェルの中で jobs を実行する様にした結果か、余計に大量の偽ジョブが登
    %   録されてしまっている。
    %
    % 改めて bind -x を組み合わせた時の動作についても確認する→うーん。再現した…。
    % WINCH の直後の bind -x の中で jobs を実行すると偽情報が出る。
    % 別の bind -x を一回実行してから次の bind -x で jobs を実行しても再現する。
    % bind -x 以外の入力を行った後でも、bind -x の中で jobs を実行すると再現する。
    % 一回でもユーザコマンドを (空でも良いので) 実行すると、偽情報は出なくなる。
    %
    % こうなって来ると変なジョブ情報が消えるのを待つ作戦に頼るのは困難である。
    % 今までの変更は取り敢えずなかった事にする。

    うーん。trap/.handler の中で jobs を敢えて実行して結果が描画に回る前に
    偽情報をクリアしてしまう事にする。blehook WINCH を実行する前に joblist 更新をして、
    更に実行した直後にも joblist の更新を行う。二回目の joblist の更新では、
    一時的に現れてそれで直ぐに消滅したイベントはイベントとして登録しない事にした。

    これだと blehook WINCH を実行している最中に終了した本当のジョブ終了の情報が
    消滅すrことになるが、実際に blehook を実行している途中に jobs の状態変化を
    Bash が受信するのか不明だし、もしそうだとしても blehook WINCH の処理のよう
    なごく短時間でその様な事が起こる確率は低いと考えられる。なので、気にしない
    事にする。

    取り敢えず動いてはいる様子である。

2020-12-14

  * progcomp: : や = の quote の取り扱い (reported by 3ximus) [#D1434]
    https://github.com/akinomyoga/ble.sh/issues/77

    ? そもそも \=, \: の様にエスケープしていたのは何故だったか。

    ? bash-completion の提供した補完に対して \= や \: の様にエスケープを実施す
      る必要はあっただろうか。その辺りの実装はどの様になっていたのだったか。

    関連しそうな物を探す。ble-0.3 では = のエスケープはしていない。

    #D1133 でコマンド名に関しては =, : の quote はしない様にしている。
    #D1098 6c6bae56 で = や : のエスケープが導入されている。
    #D1094 では = や : による候補の分割を議論している。

    うーん。元々エスケープは #D1098 で導入された物の様だが深くは考察していない。
    改めてどの様に振る舞うのが自然か考察する必要がある。

    * そもそも ble.sh の補完は展開後の結果を生成して貰う前提になっている。
      一方で bash の補完は展開前の結果を生成する事を許容している。
      例えば abc$(echo hello) の様な文字列を補完で生成する事すら可能なのである。
      それどころか複数単語からなる展開結果にする事も可能の筈である。

    * それでは progcomp の結果はそのまま挿入する事にすれば良いのではないか
      とも思われるが此処で問題になるのは、ble.sh の側で適当に展開を実行してから
      COMP_LINE を構築して progcomp に渡しているという事である。

      これは途中に $var 等の単純な展開等が含まれている場合でも
      progcomp で補完を実行できる様にする為に必要。

      この時、progcomp が展開前の補完結果を生成した時に、
      それを如何に元のコマンドライン文字列に反映させるのかが問題になる。

    x [OK] 手許では再現していないが scp chat\:down[TAB] で chat\: が消滅してしまう?

      notepc の方は bash_completion が入っていないので今試せない。
      * chat は port を変えているので localhost: から試そうとしてもできない。
        localhost や chat を .ssh/config に登録してパスワード無しで補完できる様にしたが、
        補完候補は出してくれない様である。
      * hp2019 -> chat を試してみたが再現しない。local にも mkdir downloads したが再現しない。

      うーん。取り敢えずそもそも何故失敗するのか考える?
      plain bash で実行したところ failglob で失敗している。
      shopt -u failglob にしたら ble.sh の中でも補完が動く様になった。

      そして chat\: が消滅してしまう問題に関しては、
      plain bash でも再現する事ができた。
      これは bash-completion の問題である。

      特にローカルのカレントディレクトリに "host:..." というファイルが存在する時に、
      host\:... と入力している可能性があって、この時に host: の部分が消滅してしまう
      という問題が発生する。

      https://github.com/scop/bash-completion/issues で報告をしようかと考えたが、
      もしかすると最新版で直っている可能性もあるので、
      最新版の bash-completion を試してみても良い。

    うーん。progcomp による展開結果が空白などを含んでいる時にどのように振る舞うのか。
    plain bash はそのまま何も加工を行わずに展開してしまう。うーん。
    blesh ではどの様に取り扱うべきか。

    * できるだけ progcomp が提供した quote を保持する様にしたい。
      然し、これは現実的には難しいのではないか。

      a = 及び : についてだけ quote しているかそうでないか保持する? それ以外の
        文字については自分で quote し直す。

        その為には progcomp が生成した単語について = や : で分割を試して、その
        上でそれぞれ quote してから再結合する? これだといかにも処理量が大きい。
        非効率的である。

        これは処理方法として複雑でありユーザから見たら不自然で予測不能に見える
        かもしれない。処理の重さとしては次に述べる方法よりは現実的である。

      b 入力済みの部分に一致する部分を除去してそのまま挿入。

        ここで問題になっているのは既に入力済みの部分に対応する文字列を
        どの様に取り除くのかという事であった。二分法を用いる等して
        これについて既に入力済みの部分を除去する方法はないだろうか。

        どの様にしたら良いのかを調べる必要がある。二分探索で調べるという方法と、
        1 unit ずつ読み取って行くという方法の二種類を考える事ができる。

        * 二分探索で調べるというのは複雑な気がする。元の文字列について途中で切
          断して二分探索していくという手も考えられるが、変数名の途中など変な所
          で切断すると内容が空になるなどして意図しない結果になってしまう。

        * 取り敢えず 1 unit (simple word element) ずつ読み取って行って、切断す
          るという方法? 然し、'...' 等の様に一気に読み取る事ができるliteral 等
          になっているとすると、実装が複雑になる。面倒である。そもそも処理が複
          雑になる。面倒である。

      c 今まで通り基本的に progcomp が生成した物は展開毎と見做して quote を行う。
        = 及び : は基本的には quote を加えない。compopt -o filename で quote が
        明示的に指定された時にのみ =, : の quote を行う。

        これは progcomp が quote を自前で行って候補を生成した時に問題になる。つ
        まり quote が二重に為される事になり、意図しない結果になってしまう。然し、
        この問題は今までにも存在していた問題の筈である。取り敢えずの修正として
        は妥当である。

    取り敢えず今までも quote を勝手にする事による問題はあった。
    全てを一度に解決するのは難しいししなくても良い。
    此処は c の方針で修正する事にする。

2020-12-13

  * README: ((_ble_bash)) && ble-attach だと set -u の時駄目 [#D1433]
    ble.sh ロードに失敗した時や ble.sh を意図的に読み込まなかった時に
    _ble_bash が存在しないので内容をチェックする前にエラーになってしまう。

    [[ ${BLE_VERSION-} ]] && ble-attach にするべき。

2020-12-10

  * complete/mandb: FreeBSD 上で man 情報の抽出に失敗している [#D1432]

    | freebsd には roff, nroff, troff 等が存在していない。
    | それでも man が動作している事を考えると、
    | 何らかの方法で man pages を変換しているという事の筈。
    | それについて調べて対応する。

    対応した。FreeBSD では mandoc というコマンドを使って変換を行っている。
    nroff と同様に -man 等を指定する事ができる様だが、
    どうやら FreeBSD は -man ではなくて -mdoc を想定して man pages を書いている様だ。
    という訳なので -mdoc を前提として抽出をする様に書き換えた。

    ちゃんと nroff を使う版も動いている。OK

  * highlight: command \^J-a とした時に -a がオプションとして着色されない (reported by cmplstofB) [#D1431]
    https://github.com/akinomyoga/ble.sh/issues/76

    現在の着色では \-a や ''-a 等の様に quote がある場合には、
    意図的にオプションとしての着色を避けている。
    そういう意味に於いて \^J-a もやはりオプションの前に quote が
    ある物として取り扱ってオプションとしての着色が無効になっている。

    a 然し意味的に考えるとやはり \^J は単語の一部に含まれない様にするのが自然に
      も思われる。

      ? その様に構文解析を変更する事は恐らく簡単だろうが、単語の一部として解析
        しない部分文字列がコマンドラインに含まれる事による副作用などはあるだろ
        うか。思うにリダイレクションなども単語の一部として登録していないので、
        特にこの事で問題が発生する事はない気がする。

      また sabbrev の単語判定でもやはり語頭の \^J は含まれない様にしたい。

    語頭の \^J は skip する事にする。これはどの様に実装すれば良いか?
    ^J や空白を処理している箇所で一緒に処理すれば良いだろうか。

    取り敢えず構文解析は修正した。多分大丈夫。副作用が起こるかもしれないが、
    それは実際に何かが起こってから見るという事で良いだろう。
    うーん。問題が起こるとすれば二次的に起こる問題ではなくて、
    構文解析自体が変になる可能性が高い気がするが多分大丈夫。

  * color: italic が描画できていないという (by rlanore) [#D1430]
    https://github.com/akinomyoga/ble.sh/issues/73

    試してみると手許では動いている。対応していない端末で使おうとしているのではないか。
    この Issue には返信がないがもう一つの新しい Issue に対して Terminal 情報を載せている。
    Terminator 1.92 を使っている様である。

    Cygwin 付属の Terminator 0.98 は italic に対応していない。
    Cygwin 附属の GNOME terminal は対応している。
    vte のソースコードを見ると 2012 には italic 関連のコードが存在している様だ。
    2014 にまた別のフォント初期化コードが追加されている。然し一方で pango も呼び出している。
    これが実際に X11 環境で使われるのかどうかはよく分からない。

    →これは結局向こうの tmux の設定が問題であった。手許で試して見たところに依
    るとどうも tmux は default-terminal の値に応じて自身の振る舞いも変更する様
    である。これについて wiki の manual にも書いておく必要があるのではないか。
    →wiki に説明を追加した。

  * complete/mandb: ^H が大量に挿入される (reported by rlanore) [#D1429]
    https://github.com/akinomyoga/ble.sh/issues/75

    これは nroff で太字を表現するのに <CHAR>^H<CHAR> を出力する物がある為。
    なので、単に .\b を削除すれば良い。

    取り敢えず修正してみたが本当に動くか微妙。複数の OS で試す必要があるのではないか。
    freebsd で試して見たところ、troff がないので動いていない。
    これについては後で対応する事にする。

2020-12-09

  * complete: 補完候補が更新されない問題 (reported by 3ximus) [#D1428]
    https://github.com/akinomyoga/ble.sh/issues/74

    これは明らかに menu-filter で候補がなくなった時に、
    元の候補を全て表示する様に変更したのが原因である。
    やはり一致しなくなった時点で候補は表示しない様に変更する事にした。

    b 或いは別の変更方法として、候補再生成のフラグを設定して、
      この時にはメニューから候補を拾う事はしない様にする?

      x と思ったが、そうすると結局候補を全て表示する意味がない? 候補を表示する
        のはメニューから選択させる為であるが、メニューから候補を拾わない様にし
        た時点でそれが使えない?

        % x と思ったが連続 TAB や、明示的な menu-complete の bind の時には、候
        % 補の再生成をせずに menu に入る事が可能になる。

        でも連続 TAB の場合は最初の TAB の時点で候補再生成が起こるので、表示し
        ている候補が使われる事はない。明示的な menu-complete の bind についても
        既定では C-TAB 等余り使われなさそうな物になっているので設計に考慮に入れ
        なくて良い気がする。

      此処まで処理を複雑にしても余り有用ではなさそう。次の TAB で候補一覧はすぐ
      に消えてしまうので、絞り込み前の候補一覧を表示しても却って混乱を生むだけ
      である。この選択肢は却下である。

2020-12-08

  * util/term: lxterminal, gnome-terminal で vte の検出に失敗している [#D1427]
    これはソースコードを確認してみた所、xterm の version 抽出コードを追加した時
    に動かなくなった物の様に見える。修正した。
