Skip to content

Commit

Permalink
complete: support ambiguous completion for command paths
Browse files Browse the repository at this point in the history
  • Loading branch information
akinomyoga committed Jan 24, 2023
1 parent 32277da commit 8a716ad
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 29 deletions.
2 changes: 1 addition & 1 deletion contrib
Submodule contrib updated 1 files
+1 −0 README.md
5 changes: 3 additions & 2 deletions docs/ChangeLog.md
Expand Up @@ -115,6 +115,7 @@
- menu-complete: add `bleopt complete_menu_complete_opts` (requested by DUOLabs333) `#D1911` 6a21ebb
- edit (`magic-space`): support `bleopt edit_magic_expand=...:alias` (requested by telometto) `#D1912` 63da2ac
- auto-complete: cancel auto-complete for `magic-space` `#D1913` 01b4f67
- complete: support ambiguous completion for command paths `#D1922` xxxxxxx

## Changes

Expand Down Expand Up @@ -331,8 +332,8 @@
- complete: suppress error messages for non-bash_completion `_parse_help` (reported by nik312123) `#D1900` 267de7f
- prompt: fix the marker position for the readline variable `show-mode-in-prompt` (reported by Strykar) `#D1903` 09bb4d3
- highlight: fix a bug that `bleopt filename_ls_colors` is not working (reported by qoreQyaS) `#D1919` b568ade
- bind: fix <kbd>M-C-@</kbd>, <kbd>C-x C-@</kbd>, and <kbd>M-C-x</kbd> (`bash-4.2 -o emacs`) `#D1920` xxxxxxx
- complete (action:file): support `ble/syntax-raw` in the filename extraction (reported by qoreQyaS) `#D1921` xxxxxxx
- bind: fix <kbd>M-C-@</kbd>, <kbd>C-x C-@</kbd>, and <kbd>M-C-x</kbd> (`bash-4.2 -o emacs`) `#D1920` a410b03
- complete (action:file): support `ble/syntax-raw` in the filename extraction (reported by qoreQyaS) `#D1921` 32277da

## Documentation

Expand Down
63 changes: 40 additions & 23 deletions lib/core-complete.sh
Expand Up @@ -2290,34 +2290,51 @@ function ble/complete/source:command/.contract-by-slashes {
'
}

## @fn ble/complete/source:command/gen.1
function ble/complete/source:command/gen.1 {
local COMPS=$COMPS COMPV=$COMPV
ble/complete/source/reduce-compv-for-ambiguous-match
# Note #D1922: パス名コマンドの曖昧補完は compgen -c ではなく自前で処理する。
# ディレクトリ名に関しては ble/complete/source:command/gen の側で生成されるの
# でここでは生成しない。
if [[ $COMPV == */* && :$comp_type: == *:[maA]:* ]]; then
local ret
ble/complete/source:file/.construct-pathname-pattern "$COMPV"
ble/complete/util/eval-pathname-expansion "$ret"; (($?==148)) && return 148
ble/complete/source/test-limit "${#ret[@]}" || return 1
ble/array#filter ret '[[ ! -d $1 && -x $1 ]]'
((${#ret[@]})) && printf '%s\n' "${ret[@]}"

# Note: cygwin では cyg,x86,i68 等で始まる場合にとても遅い。
# 他の環境でも空の補完を実行すると遅くなる可能性がある。
local slow_compgen=
if [[ ! $COMPV ]]; then
slow_compgen=1
elif [[ $OSTYPE == cygwin* ]]; then
case $COMPV in
(?|cy*|x8*|i6*)
slow_compgen=1 ;;
esac
fi
local COMPS=$COMPS COMPV=$COMPV
ble/complete/source/reduce-compv-for-ambiguous-match

# Note: 何故か compgen -A command はクォート除去が実行されない。
# compgen -A function はクォート除去が実行される。
# 従って、compgen -A command には直接 COMPV を渡し、
# compgen -A function には compv_quoted を渡す。
if [[ $slow_compgen ]]; then
shopt -q no_empty_cmd_completion && return 0
ble/util/conditional-sync \
'builtin compgen -c -- "$COMPV"' \
'! ble/complete/check-cancel' 128 progressive-weight
else
builtin compgen -c -- "$COMPV"
local COMPS=$COMPS COMPV=$COMPV
ble/complete/source/reduce-compv-for-ambiguous-match

# Note: cygwin では cyg,x86,i68 等で始まる場合にとても遅い。他の環境でも空
# の補完を実行すると遅くなる可能性がある。
local slow_compgen=
if [[ ! $COMPV ]]; then
slow_compgen=1
elif [[ $OSTYPE == cygwin* ]]; then
case $COMPV in
(?|cy*|x8*|i6*)
slow_compgen=1 ;;
esac
fi

# Note: 何故か compgen -A command はクォート除去が実行されない。compgen -A
# function はクォート除去が実行される。従って、compgen -A command には直
# 接 COMPV を渡し、compgen -A function には compv_quoted を渡す。
if [[ $slow_compgen ]]; then
shopt -q no_empty_cmd_completion && return 0
ble/util/conditional-sync \
'builtin compgen -c -- "$COMPV"' \
'! ble/complete/check-cancel' 128 progressive-weight
else
builtin compgen -c -- "$COMPV"
fi
fi

if [[ $COMPV == */* ]]; then
local q="'" Q="'\''"
local compv_quoted="'${COMPV//$q/$Q}'"
Expand Down
56 changes: 54 additions & 2 deletions note.txt
Expand Up @@ -2,10 +2,16 @@

拡張

* プログラム補完に於いて、
補完関数内で compopt -o filter_by_prefix を指定した場合
* 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 は動かない。
Expand Down Expand Up @@ -1855,6 +1861,25 @@ bash_tips
- leakvars
- keymap の移動 (これは別 commit にする?)

2023-01-24

* complete: パス名の曖昧補間でできるだけ各種展開を保持したい

現在の実装では quote-insert で生成候補が COMPV に文字列を追加した物の場合に
は COMPV の部分については COMPS で置き換える様になっている。しかし、遡った
置換がある場合には問答無用で全体が展開されてしまうので、曖昧補間が起こった
時には必ず全体が展開されてしまう。

COMPS を unquoted / 毎に切って、eval して対応する部分 compv を生成して、最
長一致するものについて部分 comps で置き換える。unquote / 毎に切るのは個別の
quote-insert でやっていたら大変なので、事前に処理しておく事にする。

quote-insert.batch で awk で処理する場合にどうするのかについては微妙。awk
の内部で unquote / 毎に切るのを実装するか或いは外で切ったものを何とかして
awk に渡すかする。外で定義したものを渡す方が見通しが良いと思われる。

ToDo 2022-02-03 に関連項目がある。

2022-12-09

* edit,complete: alias expansion で alias sudo='sudo ' 等による引数の展開に対応?
Expand Down Expand Up @@ -6664,6 +6689,33 @@ bash_tips
Done (実装ログ)
-------------------------------------------------------------------------------

2023-01-24

* 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]
Expand Down
16 changes: 15 additions & 1 deletion src/util.sh
Expand Up @@ -589,11 +589,25 @@ function ble/array#insert-before {
'; builtin eval -- "${_ble_local_script//ARR/$1}"
}
## @fn ble/array#filter arr predicate
## @param[in] predicate
## When a function name is specified, the target string is passed
## to the function as the first argument. Otherwise, the value of
## PREDICATE is treated as a command string where the argument can
## be referenced as $1.
function ble/array#filter/.eval {
builtin eval -- "$_ble_local_predicate_cmd"
}
function ble/array#filter {
local _ble_local_predicate=$2
if [[ $2 == *'$'* ]] || ! ble/is-function "$2"; then
_ble_local_predicate=ble/array#filter/.eval
_ble_local_predicate_cmd=$2
fi

local _ble_local_script='
local -a aARR=() eARR
for eARR in "${ARR[@]}"; do
"$2" "$eARR" && ble/array#push "aARR" "$eARR"
"$_ble_local_predicate" "$eARR" && ble/array#push "aARR" "$eARR"
done
ARR=("${aARR[@]}")
'; builtin eval -- "${_ble_local_script//ARR/$1}"
Expand Down

0 comments on commit 8a716ad

Please sign in to comment.