(Git)Bash 带有短“-...”和长“--...”选项的可编程补全
(Git)Bash programmable completion with short '-...' and long '--...' options
我受 How to Create a Custom Bash Completion Script (which has some obvious errors but I corrected these) and in a newer version on GitHub 启发创建了一个完成函数。
bash_completion_test
#!/bin/bash
#
# bash_completion_test
#
# from https://maskedbyte.com/how-to-create-a-custom-bash-completion-script/
# and https://github.com/SumuduLansakara/custom-bash-completion-script/blob/master/completer.sh
#
echo 'Begin bash_completion_test...'
# test definitions
_args=(add list remove)
list_args=(student teacher)
list_student_args=(age grade name)
list_student_grade_args=(-a -o --another --option)
list_teacher_args=(name)
#
# Generic hierarchical completion
#
function generic_hierarchical_completion_test() {
local arguments word_list_ptr word DEBUG
log='bash_completion_test.log'
echo -n '␃' > $log # clear log file
DEBUG= #true # set variable for debugging info in log file
[[ $DEBUG ]] && echo -n > $log
# Array of individual words in the current command line
# see https://www.gnu.org/software/bash/manual/bash.html#index-COMP_005fWORDS
[[ $DEBUG ]] && echo "COMP_WORDS=${COMP_WORDS[@]}" >> $log
# Second word to last word in the current command line
arguments=("${COMP_WORDS[@]:1}")
[[ $DEBUG ]] && echo "arguments=${#arguments[@]}:${arguments[@]}" >> $log
# Remove last empty word from arguments
[[ "${#COMP_WORDS[@]}" -gt 1 ]] && unset 'arguments[${#arguments[@]}-1]'
[[ $DEBUG ]] && echo "arguments=${#arguments[@]}:${arguments[@]}" >> $log
# Create word list pointer variable from arguments while replacing spaces with '_'
IFS=_
word_list_ptr="${arguments[*]}_args[*]"
unset IFS
[[ $DEBUG ]] && echo "word_list_ptr=$word_list_ptr" >> $log
[[ $DEBUG ]] && echo "word_list=${!word_list_ptr}" >> $log
# -W <word list from variable indirected by word_list_ptr>
# COMP_CWORD: An index into ${COMP_WORDS} of the word containing the current cursor position.
# see https://www.gnu.org/software/bash/manual/bash.html#index-COMP_005fCWORD
word=${COMP_WORDS[${COMP_CWORD}]}
[[ $DEBUG ]] && echo "word=$word" >> $log
COMPREPLY=( $( compgen -W "${!word_list_ptr}" "$word" ) )
}
complete -F generic_hierarchical_completion_test ct
echo 'End bash_completion_test.'
ct
#!/bin/bash
echo ">> $# arguments: $*"
在 $ ct list student grade
之前效果很好。
如果我$ ct list student grade
TAB,结果是$ ct list student grade -
。到目前为止一切顺利。
如果我 $ ct list student grade -
TABTAB 预期结果是:
$ ct list student grade -
--another --option -a -o
但现在变成了@§$%&!
如果我 $ ct list student grade --
TAB 结果是 $ ct list student grade -
,即删除尾随连字符。
如果我 $ ct list student grade -a
TABTAB 它会正确显示所有选项,但 我所有的别名在添加(其中一个是alias a=alias
):
$ ct list student grade -a
--another --option -a -o .. a b bp c df kc ll ls x
如果我$ ct list student grade --a
TAB我得到一个错误:
$ ct list student grade --abash: compgen: --: invalid option
compgen: usage: compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]
如何正确处理短“-...
”和长“--...
”选项?
How can I handle short '-...' and long '--...' options correctly?
您必须将 compgen 选项和单词分开。
compgen -W "<words>" -- "$word"
参考
Guideline 10:
The first -- argument that is not an option-argument should be accepted as a delimiter indicating the end of options. Any following arguments should be treated as operands, even if they begin with the '-'
character.
--
A --
signals the end of options and disables further option processing. Any arguments after the --
are treated as filenames and arguments.
我受 How to Create a Custom Bash Completion Script (which has some obvious errors but I corrected these) and in a newer version on GitHub 启发创建了一个完成函数。
bash_completion_test
#!/bin/bash
#
# bash_completion_test
#
# from https://maskedbyte.com/how-to-create-a-custom-bash-completion-script/
# and https://github.com/SumuduLansakara/custom-bash-completion-script/blob/master/completer.sh
#
echo 'Begin bash_completion_test...'
# test definitions
_args=(add list remove)
list_args=(student teacher)
list_student_args=(age grade name)
list_student_grade_args=(-a -o --another --option)
list_teacher_args=(name)
#
# Generic hierarchical completion
#
function generic_hierarchical_completion_test() {
local arguments word_list_ptr word DEBUG
log='bash_completion_test.log'
echo -n '␃' > $log # clear log file
DEBUG= #true # set variable for debugging info in log file
[[ $DEBUG ]] && echo -n > $log
# Array of individual words in the current command line
# see https://www.gnu.org/software/bash/manual/bash.html#index-COMP_005fWORDS
[[ $DEBUG ]] && echo "COMP_WORDS=${COMP_WORDS[@]}" >> $log
# Second word to last word in the current command line
arguments=("${COMP_WORDS[@]:1}")
[[ $DEBUG ]] && echo "arguments=${#arguments[@]}:${arguments[@]}" >> $log
# Remove last empty word from arguments
[[ "${#COMP_WORDS[@]}" -gt 1 ]] && unset 'arguments[${#arguments[@]}-1]'
[[ $DEBUG ]] && echo "arguments=${#arguments[@]}:${arguments[@]}" >> $log
# Create word list pointer variable from arguments while replacing spaces with '_'
IFS=_
word_list_ptr="${arguments[*]}_args[*]"
unset IFS
[[ $DEBUG ]] && echo "word_list_ptr=$word_list_ptr" >> $log
[[ $DEBUG ]] && echo "word_list=${!word_list_ptr}" >> $log
# -W <word list from variable indirected by word_list_ptr>
# COMP_CWORD: An index into ${COMP_WORDS} of the word containing the current cursor position.
# see https://www.gnu.org/software/bash/manual/bash.html#index-COMP_005fCWORD
word=${COMP_WORDS[${COMP_CWORD}]}
[[ $DEBUG ]] && echo "word=$word" >> $log
COMPREPLY=( $( compgen -W "${!word_list_ptr}" "$word" ) )
}
complete -F generic_hierarchical_completion_test ct
echo 'End bash_completion_test.'
ct
#!/bin/bash
echo ">> $# arguments: $*"
在 $ ct list student grade
之前效果很好。
如果我$ ct list student grade
TAB,结果是$ ct list student grade -
。到目前为止一切顺利。
如果我 $ ct list student grade -
TABTAB 预期结果是:
$ ct list student grade -
--another --option -a -o
但现在变成了@§$%&!
如果我 $ ct list student grade --
TAB 结果是 $ ct list student grade -
,即删除尾随连字符。
如果我 $ ct list student grade -a
TABTAB 它会正确显示所有选项,但 我所有的别名在添加(其中一个是alias a=alias
):
$ ct list student grade -a
--another --option -a -o .. a b bp c df kc ll ls x
如果我$ ct list student grade --a
TAB我得到一个错误:
$ ct list student grade --abash: compgen: --: invalid option
compgen: usage: compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]
如何正确处理短“-...
”和长“--...
”选项?
How can I handle short '-...' and long '--...' options correctly?
您必须将 compgen 选项和单词分开。
compgen -W "<words>" -- "$word"
参考
Guideline 10:
The first -- argument that is not an option-argument should be accepted as a delimiter indicating the end of options. Any following arguments should be treated as operands, even if they begin with the
'-'
character.
--
A
--
signals the end of options and disables further option processing. Any arguments after the--
are treated as filenames and arguments.