Skip to content

Commit

Permalink
syntax: fix a bug that arguments of "eval" are not highlighted
Browse files Browse the repository at this point in the history
  • Loading branch information
akinomyoga committed Feb 1, 2020
1 parent 7ff68d2 commit 5046d14
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 16 deletions.
17 changes: 12 additions & 5 deletions lib/core-complete.sh
Expand Up @@ -1454,15 +1454,22 @@ function ble/complete/source:command/gen {
# [[ :$comp_type: == *:a:* ]] && local COMPS=${COMPS::1} COMPV=${COMPV::1}
# compgen -A directory -S / -- "$compv_quoted"
#
local ret
ble/complete/source:file/.construct-pathname-pattern "$COMPV"
ble/complete/util/eval-pathname-expansion "$ret/"
((${#ret[@]})) && printf '%s\n' "${ret[@]}"
if [[ $arg != *D* ]]; then
local ret
ble/complete/source:file/.construct-pathname-pattern "$COMPV"
ble/complete/util/eval-pathname-expansion "$ret/"
((${#ret[@]})) && printf '%s\n' "${ret[@]}"
fi
}
## ble/complete/source:command arg
## @param[in] arg
## arg に D が含まれている時、
## ディレクトリ名の列挙を抑制する事を表します。
function ble/complete/source:command {
[[ $comps_flags == *v* ]] || return 1
[[ ! $COMPV ]] && shopt -q no_empty_cmd_completion && return 1
[[ $COMPV =~ ^.+/ ]] && COMP_PREFIX=${BASH_REMATCH[0]}
local arg=$1

# Try progcomp by "complete -I"
if ((_ble_bash>=50000)); then
Expand All @@ -1486,7 +1493,7 @@ function ble/complete/source:command {

local cand arr
local compgen
ble/util/assign compgen 'ble/complete/source:command/gen'
ble/util/assign compgen 'ble/complete/source:command/gen "$arg"'
[[ $compgen ]] || return 1
ble/util/assign-array arr 'ble/bin/sort -u <<< "$compgen"' # 1 fork/exec
for cand in "${arr[@]}"; do
Expand Down
10 changes: 5 additions & 5 deletions lib/core-syntax.sh
Expand Up @@ -4765,7 +4765,7 @@ _ble_syntax_bash_complete_check_prefix[CTX_VALQ]='inside-argument file'
_ble_syntax_bash_complete_check_prefix[CTX_CONDI]='inside-argument file'
_ble_syntax_bash_complete_check_prefix[CTX_CONDQ]='inside-argument file'
_ble_syntax_bash_complete_check_prefix[CTX_ARGVI]='inside-argument variable:='
_ble_syntax_bash_complete_check_prefix[CTX_ARGEI]='inside-argument variable:= command file'
_ble_syntax_bash_complete_check_prefix[CTX_ARGEI]='inside-argument variable:= command:D file'
function ble/syntax/completion-context/.check-prefix/ctx:inside-argument {
if ((wlen>=0)); then
local source
Expand Down Expand Up @@ -4843,7 +4843,7 @@ function ble/syntax/completion-context/.check-prefix/ctx:next-argument {
elif ((ctx==CTX_ARGVX)); then
source=(variable:=)
elif ((ctx==CTX_ARGEX)); then
source=(variable:= command file)
source=(variable:= command:D file)
else
source=(file)
fi
Expand Down Expand Up @@ -6150,7 +6150,7 @@ function ble/syntax/progcolor/word:default {

# --prefix=FILENAME 等の形式をしている場合は開始位置をずらす。
# コマンド名やリダイレクト先ファイル名等の場合は途中で区切って解釈する等の事はしない。
if ((wtype==CTX_ARGI||wtype==CTX_VALI||wtype==ATTR_VAR||wtype==CTX_RDRS)); then
if ((wtype==CTX_ARGI||wtype==CTX_ARGEI||wtype==CTX_VALI||wtype==ATTR_VAR||wtype==CTX_RDRS)); then
local ret; ble/syntax:bash/simple-word/locate-filename "$wtxt" '' url
if ((ret)); then
((p0+=ret))
Expand All @@ -6164,7 +6164,7 @@ function ble/syntax/progcolor/word:default {
((wtype==CTX_RDRS||wtype==ATTR_VAR||wtype==CTX_VALI&&wbeg<p0)) && path_opts=$path_opts:noglob
local ret path spec ext value
ble/syntax:bash/simple-word/evaluate-path-spec "$wtxt" / "$path_opts"; ext=$? value=("${ret[@]}")
if ((ext&&(wtype==CTX_CMDI||wtype==CTX_ARGI||wtype==CTX_RDRF||wtype==CTX_RDRS||wtype==CTX_VALI))); then
if ((ext&&(wtype==CTX_CMDI||wtype==CTX_ARGI||wtype==CTX_ARGEI||wtype==CTX_RDRF||wtype==CTX_RDRS||wtype==CTX_VALI))); then
# failglob 等の理由で展開に失敗した場合
ble/syntax/progcolor/word:default/.update-for-pathname "$ATTR_ERR" && return
elif (((wtype==CTX_RDRF||wtype==CTX_RDRD)&&${#value[@]}>=2)); then
Expand All @@ -6177,7 +6177,7 @@ function ble/syntax/progcolor/word:default {
((type==ATTR_CMD_FILE||type==ATTR_CMD_FILE||type==ATTR_ERR)) &&
ble/syntax/progcolor/word:default/.update-for-pathname "$type" && return
fi
elif ((wtype==CTX_ARGI||wtype==CTX_RDRF||wtype==CTX_RDRS||wtype==ATTR_VAR||wtype==CTX_VALI)); then
elif ((wtype==CTX_ARGI||wtype==CTX_ARGEI||wtype==CTX_RDRF||wtype==CTX_RDRS||wtype==ATTR_VAR||wtype==CTX_VALI)); then
ble/syntax/progcolor/word:default/.update-for-filename "$value" && return
fi
fi
Expand Down
2 changes: 1 addition & 1 deletion make_command.sh
Expand Up @@ -126,7 +126,7 @@ function sub:check/builtin {

function sub:check/a.txt {
echo "--- $FUNCNAME ---"
grc --color --exclude=./test --exclude=./make_command.sh 'a\.txt|/dev/(pts/|pty)[0-9]*' |
grc --color --exclude=./test --exclude=./make_command.sh --exclude=\*.md 'a\.txt|/dev/(pts/|pty)[0-9]*' |
grep -Ev "$rex_grep_head#|[[:space:]]#"
}

Expand Down
1 change: 1 addition & 0 deletions memo/ChangeLog.md
Expand Up @@ -25,6 +25,7 @@
- global: workaround Bash 3.2 bug of array initialization with <kbd>SOH</kbd>/<kbd>DEL</kbd> `#D1238` defdbd4 `#D1241` 1720ec0
- syntax: fix a infinite loop for variable assignments and parameter expansions `#D1239` 327661f
- complete: clear menu on history move `#D1248` 0000000
- syntax: fix a bug that arguments of `eval` are not highlighted `#D1254` 0000000

## Changes
- highlight: highlight symlink directories as symlinks `#D1249` 0000000
Expand Down
78 changes: 73 additions & 5 deletions note.txt
Expand Up @@ -920,12 +920,36 @@ bash_tips

2020-01-30

* syntax: eval の引数のファイル名が着色されていない。
というか、eval の引数はコマンドとして解釈しつつ着色したい気がする。
一方で。'...' としてコマンドを記述できる事を考えると、
awk '...' や sh -c '...' で考えているのと同様に着色したい気もする。
* fzf が動かないという問題の報告。
これは fzf が shell-expand-line & history-expand を使っている為に起こった問題である。

? 然し、何故 history-expand を実行する必要があるのだろうか。
最初から展開結果の文字列を出力しては駄目だったのだろうか。
末尾の改行の為? →試してみて分かった。shell-expand-line だと勝手に改行が削除される。

然し、試した結果 "`command`" ならば改行がちゃんと保持される様である。
確かに echo `...` で生成すると単語分割の対象になって、
改行の類は効果としては空白と同じなので自然である。
* 然し、だからと言って fzf に "`__fzf_history__`" を提案したとすると、
今度は ble.sh の側で明示的に quote された状態になってしまって動かない。
従って、fzf に "`...`" の形式を提供しても意味がない。

* ble.sh の振る舞いを Bash の振る舞いに近づけるとしても。
echo "echo hello" が echo echo hello に展開されたり、
或いは "`...`" がコマンドの実行結果その物になったり、
色々と振る舞いが異なるのである。

* syntax: eval a=() echo helo=() の構文エラーを検出できていない。
近づけるというよりは破壊的に変更しなければならない気がする。
然し、元々の機能が echo "echo hello" を echo echo hello
に変換してしまうぐらい潔い物なのだとしたら、
逆にそれに合わせても良いのかもしれない等とも考える。

bash の振る舞いに合わせる事を考える。
更に fzf の他の binding もちゃんと動くか確認する。

* fzf の様な既定の bash の binding を想定する様な枠組みの場合、
ble.sh 側の binding が少しでも違うと動かなくなる。
その意味でちゃんと何れの機能もそれなりに同じ振る舞いをする様になっているか?

2020-01-26

Expand Down Expand Up @@ -2627,6 +2651,50 @@ bash_tips

2020-02-01

* syntax: eval の引数のファイル名が着色されていない [#D1254]
というか、eval の引数はコマンドとして解釈しつつ着色したい気がする。
一方で。'...' としてコマンドを記述できる事を考えると、
awk '...' や sh -c '...' で考えているのと同様に着色したい気もする。

取り敢えずの所は引数として着色するのが妥当なのではないか?
→確認してみると単語の種類は ARGEI になっている。
補完はコマンド名になっている。
着色はされていない。

% 分かった気がする。コマンドとして補完されているのは、
% 恐らくコマンドラインの一番最初の単語になっているから。
% eval a=() echo としていたので a=() の手前でコマンドラインが途切れている。
% →と思って確認してみたが eval echo g++ としても全てコマンドとして補完される。

実装を確認すると CTX_ARGEI に variable:= command file が割り当てられていた。

x fixed: CTX_ARGEI の補完でディレクトリ名が a/ と a になっていて
絞り込みが出来ていない。コマンドの場合にもディレクトリ名には / を入れずに、
suffix に / を指定するべきでは。と思ったが、その場合にはコマンド名と
ディレクトリ名が重複していた場合に問題にならないか。

更に言うと、異なる種類の見た目が同じ候補があった場合に
どちらの action を採用するのかという問題が残る。
結局、補完対象の文字列を合わせたとしても問題は解決しない。

そもそもコマンド名でもファイル名でもどちらでも良い、
という文脈が不自然なのである。どちらか限定できる様にならないか?

→結局この文脈ではコマンド名の生成時にディレクトリを列挙しない様に修正した。
source:command で引数を受け取る様にして、
D が含まれている時にはディレクトリ名列挙を抑制する。

さて、補完はこれで余り気にしなくて良い気がする。
問題の着色が為されていない問題について。何故着色が為されていないのだろうか。
コマンドの抽出はちゃんとできているだろうか?
→分かった。肝心の progcolor/word:default で CTX_ARGEI を見るのを忘れていた。修正した。

* OK: syntax: eval a=() echo helo=() の構文エラーを検出できていない [#D1253]
→と思ったが、これは eval の時点で構文エラーになっているのではなくて、
eval から呼び出されたコマンドの評価の場面で構文エラーになっているのではないか。
実際に以下を試してみたら何もエラーは発生しなかった。
$ bash -n -c 'eval a=() echo c=()'

* syntax: 何と coproc に対応していない [#D1252]

普通のコマンドと同様に処理しておけば取り敢えず問題ないと思っていたが、
Expand Down

0 comments on commit 5046d14

Please sign in to comment.