Skip to content

Commit

Permalink
complete: evaluate words for "noquote"
Browse files Browse the repository at this point in the history
  • Loading branch information
akinomyoga committed Feb 13, 2022
1 parent ceb2e7c commit 0a42299
Show file tree
Hide file tree
Showing 6 changed files with 326 additions and 6 deletions.
2 changes: 1 addition & 1 deletion contrib
Submodule contrib updated 1 files
+1 −1 fzf-completion.bash
1 change: 1 addition & 0 deletions docs/ChangeLog.md
Expand Up @@ -315,6 +315,7 @@
- canvas: test the terminal for the sequence of clearing `DECSTBM` `#D1748` 4b1601d
- main: check `/dev/tty` on startup (reported by andychu) `#D1749` 711c69f
- util: add identification of Windows Terminal `wt` `#D1758` e332dc5
- complete: evaluate words for `noquote` (motivated by SuperSandro2000) `#D1767` 0000000

## Internal changes and fixes

Expand Down
60 changes: 55 additions & 5 deletions lib/core-complete.sh
Expand Up @@ -1681,11 +1681,61 @@ function ble/complete/action:file/get-desc {
#
# DATA ... compopt 互換のオプションをコロン区切りで指定します
#
## @fn ble/complete/action:progcomp/initialize/.reconstruct-from-noquote
## @var[in,out] INSERT CAND
## @var[in] progcomp_resolve_brace
function ble/complete/action:progcomp/initialize/.reconstruct-from-noquote {
local simple_flags simple_ibrace ret count
ble/syntax:bash/simple-word/is-simple-or-open-simple "$INSERT" &&
ble/syntax:bash/simple-word/reconstruct-incomplete-word "$INSERT" &&
ble/complete/source/eval-simple-word "$ret" single:count &&
((count==1)) || return 0

CAND=$ret

# ブレース展開がある時は逆に INSERT を補正し返す。
if [[ $quote_fixed_comps && $CAND == "$quote_fixed_compv"* ]]; then
local ret; ble/complete/string#escape-for-completion-context "${CAND:quote_fixed_compv_len}" "$escape_flags"
INSERT=$quote_fixed_comps$quote_trav_prefix$ret
return 3
fi
return 0
}

function ble/complete/action:progcomp/initialize {
ble/complete/action/quote-insert progcomp
if [[ :$DATA: == *:noquote:* ]]; then
local progcomp_resolve_brace=$quote_fixed_comps
[[ :$DATA: == *:syntax-raw:* ]] && progcomp_resolve_brace=
ble/complete/action:progcomp/initialize/.reconstruct-from-noquote
return 0
else
ble/complete/action/quote-insert progcomp
fi
}
## @fn ble/complete/action:progcomp/initialize.batch
## @arr[in] cands
## @arr[out] inserts
function ble/complete/action:progcomp/initialize.batch {
ble/complete/action/quote-insert.batch newline
if [[ :$DATA: == *:noquote:* ]]; then
inserts=("${cands[@]}")

# Note: 直接 comp_words に対して補完した時は意図的にブレース展開を潰してい
# ると解釈できるので、ブレース展開を復元する事はしない。
local progcomp_resolve_brace=$quote_fixed_comps
[[ :$DATA: == *:syntax-raw:* ]] && progcomp_resolve_brace=

cands=()
local INSERT simple_flags simple_ibrace ret count icand=0
for INSERT in "${inserts[@]}"; do
((cand_iloop++%bleopt_complete_polling_cycle==0)) && ble/complete/check-cancel && return 148
local CAND=$INSERT
ble/complete/action:progcomp/initialize/.reconstruct-from-noquote ||
inserts[icand]=$INSERT # INSERT を上書きした時 ($?==3)
cands[icand++]=$CAND
done
else
ble/complete/action/quote-insert.batch newline
fi
}

function ble/complete/action:progcomp/complete {
Expand Down Expand Up @@ -1972,12 +2022,12 @@ function ble/complete/cand/yield {
[[ $flag_force_fignore ]] && ! ble/complete/.fignore/filter "$CAND" && return 0
[[ $flag_source_filter ]] || ble/complete/candidates/filter#test "$CAND" || return 0

local PREFIX_LEN=0
[[ $CAND == "$COMP_PREFIX"* ]] && PREFIX_LEN=${#COMP_PREFIX}

local INSERT=$CAND
ble/complete/action:"$ACTION"/initialize || return "$?"

local PREFIX_LEN=0
[[ $CAND == "$COMP_PREFIX"* ]] && PREFIX_LEN=${#COMP_PREFIX}

local icand
((icand=cand_count++))
cand_cand[icand]=$CAND
Expand Down
65 changes: 65 additions & 0 deletions memo/D1760.fzf-completion-reduced.sh
@@ -0,0 +1,65 @@

_fzf_host_completion () {
_fzf_complete +m -- "$@" < <(
command cat <(
command tail -n +1 ~/.ssh/config ~/.ssh/config.d/* /etc/ssh/ssh_config 2> /dev/null |
command grep -i '^\s*host\(name\)\? ' |
awk '{for (i = 2; i <= NF; i++) print $1 " " $i}' |
command grep -v '[*?]'
) <(
command grep -oE '^[[a-z0-9.,:-]+' ~/.ssh/known_hosts |
tr ',' '\n' |
tr -d '[' |
awk '{ print $1 " " $1 }'
) <(
command grep -v '^\s*\(#\|$\)' /etc/hosts | command grep -Fv '0.0.0.0'
) | awk '{if (length($2) > 0) {print $2}}' | sort -u
)
}


function generate1 {
{
command tail -n +1 ~/.ssh/config ~/.ssh/config.d/* /etc/ssh/ssh_config 2> /dev/null |
command grep -i '^\s*host\(name\)\? ' |
awk '{for (i = 2; i <= NF; i++) print $1 " " $i}' |
command grep -v '[*?]'
command grep -oE '^[[a-z0-9.,:-]+' ~/.ssh/known_hosts |
tr ',' '\n' |
tr -d '[' |
awk '{ print $1 " " $1 }'
command grep -v '^\s*\(#\|$\)' /etc/hosts |
command grep -Fv '0.0.0.0'
} | awk '{if (length($2) > 0) {print $2}}' | sort -u
}

function generate2 {
cat <<EOF
aur.archlinux.org
bitbucket.org
chat
chatoyancy.home
front1
gell-mann
github.com
gitlab.com
hankel
hp2019
laguerre
ln25
localhost
mag
magnate
magnate2016
magnate2016.home
magnate2018.home
mercury
neumann
pad
padparadscha
padparadscha.home
song123
tkynt2
tkyntn
EOF
}
17 changes: 17 additions & 0 deletions memo/D1760.fzf-completion.bashrc
@@ -0,0 +1,17 @@
#!/bin/bash

source out/ble.sh --norc

source ~/.mwg/git/scop/bash-completion/bash_completion

_ble_contrib_fzf_base=~/.mwg/git/junegunn/fzf
if [[ ${BLE_VERSION-} ]]; then
ble-import -d contrib/fzf-completion
else
PATH=$PATH:$_ble_contrib_fzf_base/bin
source $_ble_contrib_fzf_base/shell/completion.bash
fi

if [[ ${BLE_VERSION-} ]]; then
ble-attach
fi
187 changes: 187 additions & 0 deletions note.txt
Expand Up @@ -1752,6 +1752,43 @@ bash_tips
ToDo
-------------------------------------------------------------------------------

2022-02-12

* git submodule update は even の時にはしなくても良いのでは
https://github.com/raccoonasdf/raccoonpkgs/commit/d7ec0af3db2cd473adcb12a0132e53d3c216dddf

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

* complete: ls ~/.c{onfig,1}/[TAB] としても候補が生成されない。

* いつの間にかに rps1 に接した時の計算が壊れてしまっている。改行位置が正しく
計算できていない? と思ったが、うーん。これは改行が継続する様にして欲しいと
いう要望に応えた時に導入したバグの気がする。

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' に書き換える時文法構造が破壊 (?)
Expand Down Expand Up @@ -6049,6 +6086,156 @@ bash_tips

2022-02-12

* complete: _fzf_path_completion 経由だと ~ で始まるパスのディレクトリの後に / が挿入されない [#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

Expand Down

0 comments on commit 0a42299

Please sign in to comment.