【问题标题】:(Git)Bash programmable completion with short '-...' and long '--...' options(Git)Bash 可编程完成,带有短“-...”和长“--...”选项
【发布时间】:2021-12-27 21:14:53
【问题描述】:

我创建了一个受How to Create a Custom Bash Completion Script 启发的完成函数(它有一些明显的错误,但我更正了这些)和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 -aTABTAB 它会正确显示所有选项,但 除了我的所有别名(其中一个是 @987654335 @):

$ ct list student grade -a
--another  --option   -a         -o         ..         a          b          bp         c          df         kc         ll         ls         x

如果我$ ct list student grade --aTAB 我得到一个错误:

$ 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]

如何正确处理短“-...”和长“--...”选项?

【问题讨论】:

  • word_list_ptr="${arguments[*]}_args[*]" "${!word_list_ptr} 呃,这将变得越来越复杂,并且很难真正快速地调试。虽然做“抽象引用”很棒,但编写干净、易于推理、易于编写和调试的代码确实更好。考虑将其重构为case "${arguments[*]}" in "list student grade") complist="complete this"; ;; "list something else") complist="complete that list"; ;;the trailing hyphen is removed. 这很可能是原因 - 参数有来自 "${COMP_WORDS[@]:1}"-,所以 ${!word_list_ptr} 只是失败了。

标签: bash git-bash tab-completion bash-completion


【解决方案1】:

如何正确处理短“-...”和长“--...”选项?

您必须将 compgen 选项和 word 分开。

compgen -W "<words>" -- "$word"

参考

准则 10:

第一个非选项参数的 -- 参数应被接受为指示选项结束的分隔符。任何以下参数都应被视为操作数,即使它们以 '-' 字符开头。

--

-- 表示选项结束并禁用进一步的选项处理。 -- 之后的任何参数都被视为文件名和参数。

【讨论】:

  • 这是什么? gnu.org/software/bash/manual/… 的示例也使用了这个,但是这个和上一章gnu.org/software/bash/manual/… 中的文本没有提到它。
  • 随着完成工作,但我必须过滤掉选项,否则在进一步 TABing 时会出错:$ ct list student grade -a bash: list_student_grade_-a_args[*]: bad substitution$ ct list student grade --another --abash: list_student_grade_--another_args[*]: bad substitution
  • compgen -this-is-an-option --this-is-also-an-option -- --this-is-not -also-not-an-option not-an-option-- 将选项与非选项参数分开。例如,您有一个名为 --file 的文件。您可以cat -- --filetouch -- --file
猜你喜欢
  • 1970-01-01
  • 2011-11-08
  • 1970-01-01
  • 1970-01-01
  • 2012-04-25
  • 2015-06-25
  • 2013-07-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多