任意深度嵌套的自动完成
Arbitrarily deep nested autocomplete
我已经尝试(并且悲惨地失败了)编写一个 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
。
逻辑有问题。我建议您使用 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 in
seuss) COMPREPLY=($(compgen -W "fox tweedle" -- "")) ;;
fox) COMPREPLY=($(compgen -W "socks" -- "")) ;;
socks) COMPREPLY=($(compgen -W "box clocks" -- "")) ;;
box) COMPREPLY=($(compgen -W "knox" -- "")) ;;
tweedle) COMPREPLY=($(compgen -W "beetle poodle" -- "")) ;;
beetle) COMPREPLY=($(compgen -W "puddle battle" -- "")) ;;
poddle) COMPREPLY=($(compgen -W "noodle" -- "")) ;;
*) COMPREPLY=() ;;
esac
}
complete -F _seuss seuss
这里</code>表示当前单词正在完成,<code>
是前一个单词。
我已经尝试(并且悲惨地失败了)编写一个 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
。
逻辑有问题。我建议您使用 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 in
seuss) COMPREPLY=($(compgen -W "fox tweedle" -- "")) ;;
fox) COMPREPLY=($(compgen -W "socks" -- "")) ;;
socks) COMPREPLY=($(compgen -W "box clocks" -- "")) ;;
box) COMPREPLY=($(compgen -W "knox" -- "")) ;;
tweedle) COMPREPLY=($(compgen -W "beetle poodle" -- "")) ;;
beetle) COMPREPLY=($(compgen -W "puddle battle" -- "")) ;;
poddle) COMPREPLY=($(compgen -W "noodle" -- "")) ;;
*) COMPREPLY=() ;;
esac
}
complete -F _seuss seuss
这里</code>表示当前单词正在完成,<code>
是前一个单词。