Skip to content

Commit

Permalink
complete (source:option): carve out "ble/complete/source:option/gener…
Browse files Browse the repository at this point in the history
…ate-for-command"
  • Loading branch information
akinomyoga committed Mar 9, 2023
1 parent f95eb0c commit 54ace59
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 4 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -27,6 +27,7 @@
/memo/D1881/pr227.*.txt
/memo/D1881/pr227.*.hist
/memo/D1881/pr227-sleep-delay.pdf
/memo/D2014

# make
/make/*.exe
Expand Down
1 change: 1 addition & 0 deletions docs/ChangeLog.md
Expand Up @@ -248,6 +248,7 @@
- complete (`source:argument`): fallback to rhs completion also for `name+=rhs` `#D2006` xxxxxxxx
- auto-complete: limit the line length for auto-complete `#D2009` xxxxxxxx
- complete (`source:argument`): generate sabbrev completions after normal completions (motivated by mozirilla213) `#D2011` xxxxxxxx
- complete (`source:option`): carve out `ble/complete/source:option/generate-for-command` (requested by mozirilla213) `#D2014` xxxxxxxx

## Fixes

Expand Down
31 changes: 27 additions & 4 deletions lib/core-complete.sh
Expand Up @@ -1701,7 +1701,7 @@ function ble/complete/action:word/get-desc {
# action:file_rhs (source:argument 内部使用)

## @fn ble/complete/action:file/.get-filename word
## "comopt -o ble/syntax-raw" の場合も考慮してファイル名を抽出する。
## "compopt -o ble/syntax-raw" の場合も考慮してファイル名を抽出する。
## Bash の振る舞いを見るとチルダ展開だけを実行する様だ。
## @var[in] CAND DATA
function ble/complete/action:file/.get-filename {
Expand Down Expand Up @@ -5116,10 +5116,33 @@ function ble/complete/source:option {
local comp_words comp_line comp_point comp_cword
ble/syntax:bash/extract-command "$COMP2" || return 1

local -a prev_args=()
((comp_cword>=1)) && prev_args=("${comp_words[@]:1:comp_cword-1}")
ble/complete/source:option/generate-for-command "${comp_words[@]::comp_cword}"
}

## @fn ble/complete/source:option/generate-for-command command prev_args...
## This function generates the option names based on man pages.
##
## @param[in] command
## The command name
## @param[in] prev_args
## The previous arguments before the word we currently try to complete.
##
## For example, when one would like to generate the option
## candidates for "cmd abc def ghi -xx[TAB]", command is "cmd", and
## prev_args are "abc" "def" "ghi".
##
## @var[in] COMP1 COMP2 COMPV COMPS comp_type
## These variables carry the information on the completion
## context. [COMP1, COMP2] specifies the range of the complete
## target in the command-line text. COMPS is the word to
## complete. COMPV is, if available, its current value after
## evaluation. The variable "comp_type" contains additional flags
## for the completion context.
##
function ble/complete/source:option/generate-for-command {
local cmd=$1 prev_args
prev_args=("${@:2}")

local cmd=${comp_words[0]}
local alias_checked=' '
while local ret; ! ble/complete/mandb/load-cache "$cmd"; do
alias_checked=$alias_checked$cmd' '
Expand Down
76 changes: 76 additions & 0 deletions memo/D2014-complete-mandb-for-command.bash
@@ -0,0 +1,76 @@
# -*- mode: sh-bash -*-

# This is a test case provided by "mozirilla213" at the following URL:
# https://github.com/akinomyoga/ble.sh/discussions/287
#
# Step to reproduce:
#
# $ myscript.sh -<TAB> # Menu completions from the man page appear
# $ runme -<TAB> # Menu completions don't appear of course
#

function memo/D2014-initialize {
local base=$_ble_base_repository/memo/D2014

export MANPATH=$base/man
PATH+=:$base/bin

if [[ ! -s $base/man/man8/myscript.sh.8 ]]; then
mkdir -p "$base"/man/man8

# The manpage was named "myscript.sh"
cat <<\EOF > "$base"/man/man8/myscript.sh.8
.TH MYSCRIPT.SH 8 "myscript.sh Manual"
.SH SYNOPSIS
.SY runme
.SH DESCRIPTION
.PP
Change directory to /etc
.SH OPTIONS
.TP
.B \-h ", " \-\-help
Option -h
.TP
.B \-a ", " \-\-all
Option -a
EOF
fi

if [[ ! -s $base/bin/myscript.sh ]]; then
mkdir -p "$base"/bin

# The executable script was named "myscript.sh"
cat <<\EOF > "$base"/bin/myscript.sh
#!/usr/bin/env bash
echo "/etc"
EOF
chmod +x "$base"/bin/myscript.sh
fi
}
memo/D2014-initialize

# It connects to a function that runs in current environment because
# it `cd`s, changes env variables, etc.
runme() {
cd "$(myscript.sh "$@")"
export SCRIPT_PATH=$PWD
}

#------------------------------------------------------------------------------
# An example to define a completion function that generates option names based
# on the man page of a different command.

complete -F _comp_runme runme
_comp_runme() {
# If bash-completion is loaded, we handle basic stuff with _init_completion.
if declare -f _init_completion &>/dev/null; then
local cur prev words cword split
_init_completion -s || return 0
"$split" && return 0
fi

# If ble.sh is loaded and active, we call the man-page based completions.
if [[ ${BLE_ATTACHED-} ]]; then
ble/complete/source:option/generate-for-command myscript.sh "${comp_words[@]:1:comp_cword-1}"
fi
}
20 changes: 20 additions & 0 deletions note.txt
Expand Up @@ -6624,6 +6624,26 @@ bash_tips
Done (実装ログ)
-------------------------------------------------------------------------------

2023-03-09

* complete: option:source を他のコマンド名として呼び出せる様にする (requested by mozirilla213) [#D2014]

complete: progcomp_alias と同様の処理をその他の補完生成の時にも行う
https://github.com/akinomyoga/ble.sh/discussions/287

と思って source:options の実装を確認したが既にちゃんと alias を考慮した処理
になっている。

より詳しい設定について尋ねたら返信が戻ってきた。要するに、他のコマンドのオ
プションを別のコマンドの補完に表示したいという事らしい。これに関しては自前
で新しい補完を定義する必要がある。

* done: それと現在の source:option の生成はコマンド名を決め打ちにしているの
で、それを関数に切り出して調整可能にしたい。取り敢えず source:option を真
ん中で分割した。

取り敢えず試しに簡単に実装してみて振る舞いを調べる。動いている気がする。

2023-03-08

* contrib: sabbrev 補完候補を生成しない設定 (motivated by mozirilla213) [#D2013]
Expand Down

0 comments on commit 54ace59

Please sign in to comment.