【问题标题】:Arbitrarily deep nested autocomplete任意深度的嵌套自动完成
【发布时间】:2021-01-07 23:28:02
【问题描述】:

我已经尝试(但惨遭失败)编写一个可以任意深度自动完成的 bash 完成脚本。尽管阅读了多个 SO 帖子和一些博客和文档,但我没有超过两个 :-\。例如,我可以到达:

$ seuss tweedle beetle

但无法访问seuss tweedle beetle puddle

我什至不需要每个完成后的函数,只需要选项本身。我尝试从以下帖子中修改脚本,但我所做的一切都会中断。

Nested bash autocompletion script

How do I autocomplete nested, multi-level subcommands?

这是我尝试过的:

_seuss()
{
    local one two three four

    one=${COMP_WORDS[COMP_CWORD]}
    two=${COMP_WORDS[COMP_CWORD-1]}
    three=${COMP_WORDS[COMP_CWORD-2]}
    four=${COMP_WORDS[COMP_CWORD-3]}

    case ${COMP_CWORD} in
        1)
            COMPREPLY=($(compgen -W "fox tweedle" -- ${one}))
            ;;
        2)
            case ${two} in
                fox)
                    COMPREPLY=($(compgen -W "socks" -- ${one}))
                    case ${three} in
                        socks)
                            COMPREPLY=($(compgen -W "box clocks" -- ${one}))
                            ;;
                        box)
                            COMPREPLY=($(compgen -W "knox" -- ${one}))
                            ;;
                    esac
                    ;;
                tweedle)
                    COMPREPLY=($(compgen -W "beetle poodle" -- ${one}))
                    case ${three} in
                        beetle)
                            COMPREPLY=($(compgen -W "puddle battle" -- ${one}))
                            ;;
                        poddle)
                            COMPREPLY=($(compgen -W "noodle" -- ${one}))
                            ;;
                    esac
                    ;;
            esac
            ;;
        *)
            COMPREPLY=()
            ;;
    esac
}

complete -F _seuss seuss

但这只会导致:

$ seuss fox sox

我似乎无法获得box clocks

【问题讨论】:

  • 我对@9​​87654328@ 一无所知,所以您能否详细说明一下预期的行为是什么?
  • 苏斯只是一个不存在的任意例子。预期的行为是:seuss <tab> fox <tab> sox <tab> box|clocks
  • 自动填充候选人是由职位决定的吗?还是通过前面的论点?还是通过之前的所有论点?

标签: bash autocomplete


【解决方案1】:

逻辑有问题。我建议您使用printf 函数进行调试,并了解实际发生的情况。我刚刚添加了以下代码作为 _seuss 函数的最后一行:

printf "\n*** DEBUG ***\nCOMP_CWORD: $COMP_CWORD\nOne: $one\nTwo: $two\nThree: $three\nFour: $four\nCOMP_LINE: $COMP_LINE"

现在,当您调用 $ seuss fox socks <TAB> 时,您可以看到所有变量的填充情况:

*** DEBUG ***
COMP_CWORD: 3
One: 
Two: socks
Three: fox
Four: seuss
COMP_LINE: seuss fox socks

因此,如您所见,没有为COMP_CWORD 何时为3 设置规则。只是一个普通的旧COMPREPLY=(),这意味着不会打印任何建议。使用此printf 作为助手再次检查逻辑。编码愉快!

编辑:由于您询问的 case 树中没有特殊的复杂性,我想这个应该可以完成工作:

_seuss()
{
    case $3 in
        seuss)      COMPREPLY=($(compgen -W "fox tweedle" -- "$2"))     ;;
        fox)        COMPREPLY=($(compgen -W "socks" -- "$2"))           ;;
        socks)      COMPREPLY=($(compgen -W "box clocks" -- "$2"))      ;;
        box)        COMPREPLY=($(compgen -W "knox" -- "$2"))            ;;
        tweedle)    COMPREPLY=($(compgen -W "beetle poodle" -- "$2"))   ;;
        beetle)     COMPREPLY=($(compgen -W "puddle battle" -- "$2"))   ;;
        poddle)     COMPREPLY=($(compgen -W "noodle" -- "$2"))          ;;
        *)          COMPREPLY=()                                        ;;
    esac
}

complete -F _seuss seuss

这里$2 表示正在完成的当前单词,$3 是前一个单词。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-30
    • 1970-01-01
    • 2019-08-31
    • 2014-10-05
    • 2016-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多