From 8940434055767ff3276f54502fb8540068e413ab Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Thu, 3 Mar 2022 18:55:58 +0900 Subject: [PATCH] prompt: escape control characters in "\w" and "\W" --- docs/ChangeLog.md | 1 + note.txt | 31 ++++++++++++++++++++----------- src/color.sh | 46 ++++++++++++++++++---------------------------- src/edit.sh | 25 ++++++++++++++++++++++--- 4 files changed, 61 insertions(+), 42 deletions(-) diff --git a/docs/ChangeLog.md b/docs/ChangeLog.md index 67185950..f7166638 100644 --- a/docs/ChangeLog.md +++ b/docs/ChangeLog.md @@ -97,6 +97,7 @@ - progcomp: support `compopt -o ble/no-default` to suppress default completions `#D1789` 0000000 - sabbrev: support options `-r` and `--reset` to remove entries `#D1790` 0000000 - util (blehook): support `hook!=handler` and `hook+-=handler` `#D1791` 0000000 +- prompt: escape control characters in `\w` and `\W` `#D1798` 0000000 ## Changes diff --git a/note.txt b/note.txt index 4010196b..b6813ce0 100644 --- a/note.txt +++ b/note.txt @@ -2051,17 +2051,6 @@ bash_tips 更に関数内で実行された場合には ERR でも INT でも捉えられない。RETURN を使っ ても捕まえられない。これを解決する方法はない気がする。 -2022-01-19 - - * PS1 のディレクトリ名に特殊文字が含まれている場合の取り扱い - https://lists.gnu.org/archive/html/bug-bash/2022-01/msg00051.html - - これは不要な互換性の問題を防ぐために Chet がどの様に対処するのかを見てから - それと同じ様に実装するのが良い。 - - またその他の文字列についても同様に注意が必要なのではないかと思われる。 - と思ったが他に任意の文字列を出力する様な状況もない様な気はする。 - 2022-01-08 * mandb: echo のオプションの抽出 (help echo) がおかしい at fc35 vm @@ -6178,6 +6167,26 @@ bash_tips 2022-03-03 + * 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 が実行されている。どうやら前 diff --git a/src/color.sh b/src/color.sh index 0b1c395c..c4ec6e69 100644 --- a/src/color.sh +++ b/src/color.sh @@ -872,34 +872,24 @@ function ble/color/read-sgrspec { elif ((100<=arg&&arg<108)); then local color=$((arg-100+8)) ble/color/g.setbg-index "$color" - elif ((arg==1)); then - ((g|=_ble_color_gflags_Bold)) - elif ((arg==22)); then - ((g&=~_ble_color_gflags_Bold)) - elif ((arg==4)); then - ((g|=_ble_color_gflags_Underline)) - elif ((arg==24)); then - ((g&=~_ble_color_gflags_Underline)) - elif ((arg==7)); then - ((g|=_ble_color_gflags_Revert)) - elif ((arg==27)); then - ((g&=~_ble_color_gflags_Revert)) - elif ((arg==3)); then - ((g|=_ble_color_gflags_Italic)) - elif ((arg==23)); then - ((g&=~_ble_color_gflags_Italic)) - elif ((arg==5)); then - ((g|=_ble_color_gflags_Blink)) - elif ((arg==25)); then - ((g&=~_ble_color_gflags_Blink)) - elif ((arg==8)); then - ((g|=_ble_color_gflags_Invisible)) - elif ((arg==28)); then - ((g&=~_ble_color_gflags_Invisible)) - elif ((arg==9)); then - ((g|=_ble_color_gflags_Strike)) - elif ((arg==29)); then - ((g&=~_ble_color_gflags_Strike)) + else + case $arg in + (1) ((g|=_ble_color_gflags_Bold)) ;; + (22) ((g&=~_ble_color_gflags_Bold)) ;; + (4) ((g|=_ble_color_gflags_Underline)) ;; + (24) ((g&=~_ble_color_gflags_Underline)) ;; + (7) ((g|=_ble_color_gflags_Revert)) ;; + (27) ((g&=~_ble_color_gflags_Revert)) ;; + (9807) ((g^=_ble_color_gflags_Revert)) ;; # toggle (for internal use) + (3) ((g|=_ble_color_gflags_Italic)) ;; + (23) ((g&=~_ble_color_gflags_Italic)) ;; + (5) ((g|=_ble_color_gflags_Blink)) ;; + (25) ((g&=~_ble_color_gflags_Blink)) ;; + (8) ((g|=_ble_color_gflags_Invisible)) ;; + (28) ((g&=~_ble_color_gflags_Invisible)) ;; + (9) ((g|=_ble_color_gflags_Strike)) ;; + (29) ((g&=~_ble_color_gflags_Strike)) ;; + esac fi done } diff --git a/src/edit.sh b/src/edit.sh index 487f1230..1f5b07ba 100644 --- a/src/edit.sh +++ b/src/edit.sh @@ -883,10 +883,27 @@ function ble/prompt/backslash:V { # = bash version %d.%d.%d ble/prompt/print "$_ble_prompt_const_V" return 0 } +function ble/prompt/backslash/.escape-control-characters { + ret=$1 + local glob_ctrl=$'[\001-\037\177]' + [[ $ret == *$glob_ctrl* ]] || return 0 + + local out= head tail=$ret + while head=${tail%%$glob_ctrl*}; [[ $head != "$tail" ]]; do + out=$out$head + ble/util/s2c "${tail:${#head}:1}" + ble/util/c2s $((ret<32?ret+64:63)) + out=$out$'\e[9807m'^$ret$'\e[9807m' + tail=${tail#*$glob_ctrl} + done + ret=$out$tail +} function ble/prompt/backslash:w { # PWD ble/prompt/unit/add-hash '$PWD' ble/prompt/.update-working-directory - ble/prompt/print "$prompt_cache_wd" + local ret + ble/prompt/backslash/.escape-control-characters "$prompt_cache_wd" + ble/prompt/print "$ret" return 0 } function ble/prompt/backslash:W { # PWD短縮 @@ -895,7 +912,9 @@ function ble/prompt/backslash:W { # PWD短縮 ble/prompt/print "$PWD" else ble/prompt/.update-working-directory - ble/prompt/print "${prompt_cache_wd##*/}" + local ret + ble/prompt/backslash/.escape-control-characters "${prompt_cache_wd##*/}" + ble/prompt/print "$ret" fi return 0 } @@ -1172,7 +1191,7 @@ function ble/prompt/.instantiate { local chars_safe_esc='][0-7aenrdtAT@DhHjlsuvV!$\wW' [[ ( $OSTYPE == cygwin || $OSTYPE == msys ) && $_ble_prompt_const_root == '#' ]] && chars_safe_esc=${chars_safe_esc//'$'} # Note: cygwin では ble.sh 独自の方法で \$ を処理する。 - if ((_ble_bash>=40400)) && [[ $ps != *'\'[!"$chars_safe_esc"]* ]]; then + if ((_ble_bash>=40400)) && [[ $ps != *'\'[!"$chars_safe_esc"]* && ! ( $ps == *'\'[wW]* && $PWD == *[$'\001'-$'\037\177']* ) ]]; then [[ $ps == *'\'[wW]* ]] && ble/prompt/unit/add-hash '$PWD' ble-edit/exec/.setexit "$_ble_edit_exec_lastarg" BASH_COMMAND=$_ble_edit_exec_BASH_COMMAND \