diff --git a/docs/ChangeLog.md b/docs/ChangeLog.md index acee0d55..f2822d31 100644 --- a/docs/ChangeLog.md +++ b/docs/ChangeLog.md @@ -81,6 +81,7 @@ - menu (menu-style:desc): improve descriptions (motivated by Shahabaz-Bagwan) `#D1685` 4de1b45 - menu (menu-style:desc): support multicolumns (motivated by Shahabaz-Bagwan) `#D1686` 231dc39 - term: let DECSCUSR pass through terminal multiplexers (motivated by cmplstofB) `#D1697` 0000000 +- complete: requote for more compact representations on full completions `#D1700` 0000000 ## Changes diff --git a/lib/core-complete.sh b/lib/core-complete.sh index 5e040ef8..45d34058 100644 --- a/lib/core-complete.sh +++ b/lib/core-complete.sh @@ -1232,6 +1232,30 @@ function ble/complete/action/util/quote-insert { INSERT=$comps_fixed_part$ins fi } +function ble/complete/action/util/requote-final-insert { + if [[ $insert == "$COMPS"* ]]; then + [[ $comps_flags == *[SEDI]* ]] && return 0 + local comps_prefix=$COMPS + else + # 遡って書き換える場合 (中途半端な quote 状態ではないと仮定) + local comps_prefix= + [[ $comps_fixed ]] && + comps_prefix=${COMPS::${comps_fixed%%:*}} + fi + + if [[ $insert == "$comps_prefix"* && $comps_prefix != *[!':/={,'] ]]; then + local ret ins=${insert:${#comps_prefix}} + if ! ble/syntax:bash/simple-word/is-literal "$ins" && + ble/syntax:bash/simple-word/is-simple "$ins" && + ble/syntax:bash/simple-word/eval "$ins" && + ((${#ret[@]}==1)) + then + ble/string#quote-word "$ret" quote-empty + ((${#ret}<=${#ins})) && insert=$comps_prefix$ret + fi + fi + return 0 +} function ble/complete/action/inherit-from { local dst=$1 src=$2 @@ -1247,7 +1271,9 @@ function ble/complete/action/inherit-from { function ble/complete/action:plain/initialize { ble/complete/action/util/quote-insert } -function ble/complete/action:plain/complete { :; } +function ble/complete/action:plain/complete { + ble/complete/action/util/requote-final-insert +} # action:literal-substr function ble/complete/action:literal-substr/initialize { :; } @@ -1257,7 +1283,9 @@ function ble/complete/action:literal-substr/complete { :; } function ble/complete/action:substr/initialize { ble/complete/action/util/quote-insert } -function ble/complete/action:substr/complete { :; } +function ble/complete/action:substr/complete { + ble/complete/action/util/requote-final-insert +} # action:literal-word function ble/complete/action:literal-word/initialize { :; } @@ -1277,6 +1305,7 @@ function ble/complete/action:word/initialize { ble/complete/action/util/quote-insert } function ble/complete/action:word/complete { + ble/complete/action/util/requote-final-insert ble/complete/action/util/complete.close-quotation ble/complete/action:literal-word/complete } @@ -1290,6 +1319,7 @@ function ble/complete/action:file/initialize { ble/complete/action/util/quote-insert } function ble/complete/action:file/complete { + ble/complete/action/util/requote-final-insert if [[ -e $CAND || -h $CAND ]]; then if [[ -d $CAND ]]; then ble/complete/action/util/complete.mark-directory @@ -1313,7 +1343,7 @@ function ble/complete/action:file/init-menu-item { fi } function ble/complete/action:file_rhs/initialize { - ble/complete/action/util/quote-insert + ble/complete/action:file/initialize } function ble/complete/action:file_rhs/complete { CAND=${CAND:${#DATA}} ble/complete/action:file/complete @@ -1358,6 +1388,7 @@ function ble/complete/action:progcomp/complete { ble/complete/action:file/complete else if [[ $DATA != *:no-mark-directories:* && -d $CAND ]]; then + ble/complete/action/util/requote-final-insert ble/complete/action/util/complete.mark-directory else ble/complete/action:word/complete @@ -2070,7 +2101,7 @@ function ble/complete/source:file/.construct-ambiguous-pathname-pattern { done fi done - [[ $pattern ]] || pattern="*" + [[ $pattern == *'*' ]] || pattern=$pattern* ret=$pattern } ## @fn ble/complete/source:file/.construct-pathname-pattern path @@ -2106,7 +2137,7 @@ function ble/complete/source:file/.impl { local -a candidates=() local ret ble/complete/source:file/.construct-pathname-pattern "$COMPV" - [[ :$opts: == *:directory:* ]] && ret=${ret%/}/ + [[ :$opts: == *:directory:* ]] && ret=$ret/ ble/complete/util/eval-pathname-expansion "$ret"; (($?==148)) && return 148 ble/complete/source/test-limit ${#ret[@]} || return 1 @@ -7633,7 +7664,7 @@ function ble-decode/keymap:dabbrev/define { function ble/complete/action:cdpath/initialize { DATA=$cdpath_basedir - ble/complete/action/util/quote-insert + ble/complete/action:file/initialize } function ble/complete/action:cdpath/complete { CAND=$DATA$CAND ble/complete/action:file/complete diff --git a/lib/core-syntax.sh b/lib/core-syntax.sh index 96b8f7ed..c2a957d6 100644 --- a/lib/core-syntax.sh +++ b/lib/core-syntax.sh @@ -1064,8 +1064,9 @@ _ble_syntax_bash_simple_rex_param= _ble_syntax_bash_simple_rex_bquot= _ble_syntax_bash_simple_rex_squot= _ble_syntax_bash_simple_rex_dquot= -_ble_syntax_bash_simple_rex_word= +_ble_syntax_bash_simple_rex_literal= _ble_syntax_bash_simple_rex_element= +_ble_syntax_bash_simple_rex_word= _ble_syntax_bash_simple_rex_open_word= _ble_syntax_bash_simple_rex_open_dquot= _ble_syntax_bash_simple_rex_open_squot= @@ -1093,6 +1094,7 @@ function ble/syntax:bash/simple-word/update { # @var _ble_syntax_bash_simple_rex_element # @var _ble_syntax_bash_simple_rex_word + _ble_syntax_bash_simple_rex_literal='^('$letter')+$' _ble_syntax_bash_simple_rex_element='('$bquot'|'$squot'|'$dquot'|'$param'|'$letter')' _ble_syntax_bash_simple_rex_word='^'$_ble_syntax_bash_simple_rex_element'+$' @@ -1117,6 +1119,9 @@ function ble/syntax:bash/simple-word/update { } ble/syntax:bash/simple-word/update +function ble/syntax:bash/simple-word/is-literal { + [[ $1 =~ $_ble_syntax_bash_simple_rex_literal ]] +} function ble/syntax:bash/simple-word/is-simple { [[ $1 =~ $_ble_syntax_bash_simple_rex_word ]] } diff --git a/note.txt b/note.txt index a9d556ec..8303b640 100644 --- a/note.txt +++ b/note.txt @@ -1623,8 +1623,6 @@ bash_tips 2021-12-06 - * complete: 沢山 quote が発生する場合には '' で囲むべきなのではないか。 - * mandb: コマンドの名称を抽出して保持して置けば binary の呼び出し時に使える。 dnf や apt 等に問い合わせても良いのかもしれない。或いは、含まれているパッケー ジを見るという手もある。 @@ -5630,6 +5628,61 @@ bash_tips 2021-12-11 + * 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