Skip to content

Commit

Permalink
cmdspec: refactor "{mandb => cmdspec}_opts"
Browse files Browse the repository at this point in the history
  • Loading branch information
akinomyoga committed Dec 16, 2021
1 parent e12bae4 commit 0786e92
Show file tree
Hide file tree
Showing 8 changed files with 294 additions and 124 deletions.
2 changes: 1 addition & 1 deletion ble.pp
Expand Up @@ -1212,9 +1212,9 @@ function ble-update {
#%x inc.r|@|src/canvas|
#%x inc.r|@|src/history|
#%x inc.r|@|src/edit|
#%x inc.r|@|lib/core-cmdspec-def|
#%x inc.r|@|lib/core-syntax-def|
#%x inc.r|@|lib/core-complete-def|
#%x inc.r|@|lib/core-cmdspec-def|

bleopt -I
#------------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions docs/ChangeLog.md
Expand Up @@ -84,6 +84,7 @@
- complete: requote for more compact representations on full completions `#D1700` 0000000
- complete: improve support for `declare` and `[[ ... ]]` `#D1701` 0000000
- syntax: fix completion and highlighting of `declare` with assignment arguments `#D1704` `#D1705` 0000000
- cmdspec: refactor `{mandb => cmdspec}_opts` `#D1706` `#D1707` 0000000

## Changes

Expand Down
64 changes: 64 additions & 0 deletions lib/core-cmdspec-def.sh
Expand Up @@ -2,3 +2,67 @@

function ble/cmdspec/initialize { ble-import "$_ble_base/lib/core-cmdspec.sh"; }
ble/is-function ble/util/idle.push && ble-import -d "$_ble_base/lib/core-cmdspec.sh"


## @type cmdspec_opts
## 各コマンドのコマンドライン引数解釈に関する情報を記述します。
## コロン区切りのオプションの列で記述されます。
## 以下の値の組み合わせで指定します。
##
## mandb-disable-man
## mandb 構築の際に man page を参照しません。
##
## mandb-help
## mandb 構築の際に $CMD --help の結果を解析します。
## mandb-help=%COMMAND
## mandb 構築の際に COMMAND の実行結果を利用します。
## mandb-help=@HELPTEXT
## mandb 構築の際に HELPTEXT を解析します。
## mandb-help-usage
## mandb 構築を mandb-help を通して行う時に [-abc] [-a ARG] の形の使用方法
## からオプションを抽出します。
##
## mandb-usage
## mandb 構築の際に $CMD --usage の結果を解析します。
##
## plus-options
## plus-options=xyzw
## "'+' CHAR" の形式のオプションを受け取る事を示します。
## 引数を指定した場合には更に対応している plus option の集合と解釈します。
## 例えば xyzw を指定した時、+x, +y, +z, +w に対応している事を示します。
##
## no-options
## オプションを解釈しない事を示します。
## stop-options-on=REX_STOP
## 指定したパターンに一致する引数より後はオプションの解釈を行わないません。
## stop-options-unless=REX_CONT
## 指定したパターンに一致しない引数より後はオプションの解釈を行わないません。
## stop-options-at=IWORD
## 指定した位置以降の引数ではオプションの解釈を行わない事を示します。
## stop-options-postarg
## 通常引数の後はオプションの解釈を行わない事を示します。
## この設定は stop-options-unless により上書きされます。
## disable-double-hyphen
## オプション '--' 以降もオプションの解釈を行います。
## この設定は stop-options-on により上書きされます。
##

builtin eval -- "${_ble_util_gdict_declare//NAME/_ble_cmdspec_opts}"

function ble/cmdspec/opts {
local spec=$1 command; shift
for command; do
ble/gdict#set _ble_cmdspec_opts "$command" "$spec"
done
}
## @fn ble/cmdspec/opts#load command [default_value]
## @var[out] cmdspec_opts
function ble/cmdspec/opts#load {
cmdspec_opts=$2
local ret=
if ble/gdict#get _ble_cmdspec_opts "$1" ||
{ [[ $1 == */*[!/] ]] && ble/gdict#get _ble_cmdspec_opts "${1##*/}"; }
then
cmdspec_opts=$ret
fi
}
35 changes: 33 additions & 2 deletions lib/core-cmdspec.sh
@@ -1,7 +1,38 @@
# -*- mode: sh; mode: sh-bash -*-

function ble/cmdspec/initialize { return 0; }
ble-import core-complete

function ble/complete/opts/initialize {
ble/cmdspec/opts mandb-help printf
ble/cmdspec/opts mandb-disable-man:mandb-help bind
ble/cmdspec/opts mandb-disable-man:mandb-help:mandb-help-usage complete
ble/cmdspec/opts mandb-disable-man:no-options : true false

ble/cmdspec/opts mandb-help=%'help echo':stop-options-unless='^-[neE]+$' echo

local conditional_operators='
-eq (NUM1 -eq NUM2) Arithmetic comparison ==.
-ne (NUM1 -ne NUM2) Arithmetic comparison !=.
-lt (NUM1 -lt NUM2) Arithmetic comparison < .
-le (NUM1 -le NUM2) Arithmetic comparison <=.
-gt (NUM1 -gt NUM2) Arithmetic comparison > .
-ge (NUM1 -ge NUM2) Arithmetic comparison >=.
-nt (FILE1 -nt FILE2) True if file1 is newer than file2 (according to modification date).
-ot (FILE1 -ot FILE2) True if file1 is older than file2.
-ef (FILE1 -ef FILE2) True if file1 is a hard link to file2.'
ble/cmdspec/opts disable-double-hyphen:mandb-help=%'help test':mandb-help=@"$conditional_operators" '[['

local test_operators=$conditional_operators'
-a (EXPR1 -a EXPR2) True if both expr1 AND expr2 are true.
-a (EXPR1 -o EXPR2) True if either expr1 OR expr2 is true.'
ble/cmdspec/opts disable-double-hyphen:mandb-help=%'help test':mandb-help=@"$test_operators" 'test' '['

ble/cmdspec/opts mandb-disable-man:mandb-help:stop-options-postarg:plus-options=aAilnrtux declare typeset local
ble/cmdspec/opts mandb-disable-man:mandb-help:stop-options-postarg local export readonly
ble/cmdspec/opts mandb-disable-man:mandb-help:stop-options-postarg alias
}
ble/complete/opts/initialize


function ble/cmdinfo/cmd:declare/chroma.wattr {
local ret
Expand All @@ -10,8 +41,8 @@ function ble/cmdinfo/cmd:declare/chroma.wattr {
ble/progcolor/highlight-filename.wattr "$ret" "$wend"
else
ble/progcolor/eval-word || return "$?"

local wval=$ret

if ble/string#match "$wval" '^([_a-zA-Z][_a-zA-Z0-9]*)(\[.+\])?$'; then
# ToDo: properly support quoted case
local varname=${BASH_REMATCH[1]}
Expand Down
98 changes: 25 additions & 73 deletions lib/core-complete.sh
Expand Up @@ -3802,9 +3802,9 @@ function ble/complete/mandb/.generate-cache-from-man {
function ble/complete/mandb:help/generate-cache {
local opts=$1
local -x cfg_usage= cfg_help=1 cfg_plus= cfg_plus_generate=
[[ :$opts: == *:help-usage:* ]] && cfg_usage=1
[[ :$opts: == *:usage:* ]] && cfg_usage=1 cfg_help=
ble/string#match ":$opts:" ':plus-option(=[^:]+)?:' &&
[[ :$opts: == *:mandb-help-usage:* ]] && cfg_usage=1
[[ :$opts: == *:mandb-usage:* ]] && cfg_usage=1 cfg_help=
ble/string#match ":$opts:" ':plus-options(=[^:]+)?:' &&
cfg_plus=1 cfg_plus_generate=${BASH_REMATCH[1]:1}

local rex_argsep='(\[?[:=]| ?|\[)'
Expand Down Expand Up @@ -4068,53 +4068,6 @@ function ble/complete/mandb:_parse_help/generate-cache {
fi >| "$subcache"
}

builtin eval -- "${_ble_util_gdict_declare//NAME/_ble_complete_mandb_opts}"
function ble/complete/mandb/opt {
local spec=$1 command; shift
for command; do
ble/gdict#set _ble_complete_mandb_opts "$command" "$spec"
done
}
function ble/complete/mandb/initialize-mandb-opts {
ble/complete/mandb/opt help printf
ble/complete/mandb/opt no-man:help bind
ble/complete/mandb/opt no-man:help:help-usage complete

local conditional_operators='
-eq (NUM1 -eq NUM2) Arithmetic comparison ==.
-ne (NUM1 -ne NUM2) Arithmetic comparison !=.
-lt (NUM1 -lt NUM2) Arithmetic comparison < .
-le (NUM1 -le NUM2) Arithmetic comparison <=.
-gt (NUM1 -gt NUM2) Arithmetic comparison > .
-ge (NUM1 -ge NUM2) Arithmetic comparison >=.
-nt (FILE1 -nt FILE2) True if file1 is newer than file2 (according to modification date).
-ot (FILE1 -ot FILE2) True if file1 is older than file2.
-ef (FILE1 -ef FILE2) True if file1 is a hard link to file2.'
ble/complete/mandb/opt ignore-double-hyphen:help=%'help test':help=@"$conditional_operators" '[['

local test_operators=$conditional_operators'
-a (EXPR1 -a EXPR2) True if both expr1 AND expr2 are true.
-a (EXPR1 -o EXPR2) True if either expr1 OR expr2 is true.'
ble/complete/mandb/opt ignore-double-hyphen:help=%'help test':help=@"$test_operators" 'test' '['

ble/complete/mandb/opt no-man:help:stop-after-argument:plus-option=aAilnrtux declare typeset local
ble/complete/mandb/opt no-man:help:stop-after-argument local export readonly
ble/complete/mandb/opt no-man:help:stop-after-argument alias
}
ble/complete/mandb/initialize-mandb-opts

## @fn ble/complete/mandb/get-opts command [default_value]
## @var[out] mandb_opts
function ble/complete/mandb/get-opts {
mandb_opts=$2
local ret=
if ble/gdict#get _ble_complete_mandb_opts "$1" ||
{ [[ $1 == */*[!/] ]] && ble/gdict#get _ble_complete_mandb_opts "${1##*/}"; }
then
mandb_opts=:$ret:
fi
}

## @fn ble/complete/mandb/generate-cache cmdname
## @var[out] ret
## キャッシュファイル名を返します。
Expand All @@ -4124,10 +4077,11 @@ function ble/complete/mandb/generate-cache {
local mandb_cache_dir=$_ble_base_cache/complete.mandb/${lc_messages//'/'/%}
local fcache=$mandb_cache_dir/$command

local mandb_opts; ble/complete/mandb/get-opts "$command"
local cmdspec_opts; ble/cmdspec/opts#load "$command"
[[ :$cmdspec_opts: == *:no-options:* ]] && return 1

# fcache_help
if ble/opts#extract-all-optargs help "$mandb_opts" --help; then
if ble/opts#extract-all-optargs "$cmdspec_opts" mandb-help --help; then
local -a helpspecs; helpspecs=("${ret[@]}")
local subcache=$mandb_cache_dir/help.d/$command
if ! [[ -s $subcache && $subcache -nt $_ble_base/lib/core-complete.sh ]]; then
Expand All @@ -4142,12 +4096,12 @@ function ble/complete/mandb/generate-cache {
ble/string#split-words helpspec "${helpspec#+}"
"$command" "${helpspec[@]}" 2>&1
fi
done | ble/complete/mandb:help/generate-cache "$mandb_opts" >| "$subcache"
done | ble/complete/mandb:help/generate-cache "$cmdspec_opts" >| "$subcache"
fi
fi

# fcache_man
if [[ :$mandb_opts: != *:no-man:* ]] && ble/bin#has "$1"; then
if [[ :$cmdspec_opts: != *:mandb-disable-man:* ]] && ble/bin#has "$1"; then
local subcache=$mandb_cache_dir/man.d/$command
if ! [[ -s $subcache && $subcache -nt $_ble_base/lib/core-complete.sh ]]; then
ble/util/mkd "${subcache%/*}"
Expand Down Expand Up @@ -4233,34 +4187,32 @@ function ble/complete/mandb/load-cache {
ble/util/mapfile ret < "$ret"
}

## @fn ble/complete/source:option/.stops-option args...
## @fn ble/complete/source:option/.is-option-context args...
## args... に "--" などのオプション解釈を停止する様な引数が含まれて
## いないか判定します。
##
## @param[in] args...
## @var[in] mandb_opts
## @var[in] cmdspec_opts
##
function ble/complete/source:option/.stops-option {
(($#)) || return 1

local reject= rexreq=
[[ :$mandb_opts: != *:ignore-double-hyphen:* ]] && reject=--
if [[ :$mandb_opts: == *:stop-after-argument:* ]]; then
rexreq='^-.+'
if ble/string#match ":$mandb_opts:" ':plus-option(=[^:]*)?:'; then
rexreq='^[-+].+'
fi
function ble/complete/source:option/.is-option-context {
#(($#)) || return 0

local rexrej rexreq stopat
ble/progcolor/stop-option#init "$cmdspec_opts"
if [[ $stopat ]] && ((stopat<=$#)); then
return 1
elif [[ ! $rexrej$rexreq ]]; then
return 0
fi
[[ $reject$rexreq ]] || return 1

local word ret
for word; do
ble/syntax:bash/simple-word/is-simple "$word" &&
ble/syntax:bash/simple-word/eval "$word" noglob &&
[[ $reject && $ret == $reject || $rexreq && ! ( $ret =~ $rexreq ) ]] &&
return 0
ble/progcolor/stop-option#test "$ret" &&
return 1
done
return 1
return 0
}

function ble/complete/source:option {
Expand Down Expand Up @@ -4294,12 +4246,12 @@ function ble/complete/source:option {
done
local -a entries; entries=("${ret[@]}")

local ret mandb_opts=
local ret cmdspec_opts=
ble/syntax:bash/simple-word/is-simple "$cmd" &&
ble/syntax:bash/simple-word/eval "$cmd" noglob &&
ble/complete/mandb/get-opts "$ret"
ble/cmdspec/opts#load "$ret"
# "--" や非オプション引数など、オプション無効化条件をチェック
ble/complete/source:option/.stops-option "${prev_args[@]}" && return 1
ble/complete/source:option/.is-option-context "${prev_args[@]}" || return 1

local entry fs=$_ble_term_FS has_desc=
for entry in "${entries[@]}"; do
Expand Down

0 comments on commit 0786e92

Please sign in to comment.