我有一个 bash 自动完成功能,仅当参数是单个单词时才起作用。我可以自动完成引用的语句,然后在 case 语句中使用来标记文件(想想元数据标记,有时需要多个单词。)
有没有办法让自动完成功能在特定选项后显示目录?脚本如下:
_script()
{
local cur prev opts iter
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
opts="-t"
if [[ ${cur} == -* ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
fi
case "$prev" in
-t)
option="single \"double\ word\""
option="${option//\\ /___}"
for iter in $option; do
if [[ $iter =~ ^$cur ]]; then
COMPREPLY+=( "${iter//___/ }" )
fi
done
return 0
;;
"single"|"double word")
compopt -o default
COMPREPLY=()
return 0
;;
esac
}
complete -F _script script
当我这样使用它时:
script -t <tab>
:它向我显示了正确的选项:single "double word"
并且不显示目录(是的!这就是我想要的!)
如果我使用:
script -t single <tab>
:它显示了可用的目录(是的!这就是我想要的!)
如果我使用:
script -t "double word" <tab>
:它在选项卡上不输出任何内容。这就是我想要解决的问题。
答案1
你的处理double word
是错误的(尽管它比shell,至少是bash,更有意义);因此它在 中不被识别case
。
如果将其放在set -x
函数代码的顶部(或您感兴趣的行之前),您可以看到会发生什么。
您返回正确的字符串 ,"double word"
其中"
being 是可编程补全看到的单词的一部分。这有点奇怪,因为引号被识别,所以这"double word"
只是一个单词,但它们没有被删除,以便函数_script
确实看到它们。因此,完成可以使用"double word"
但不能使用,double\ word
尽管它与执行时的 shell 相同。所以这是文字和解析的命令行字符串的反直觉组合。
解决方案
如果你替换你的代码就可以工作
"single"|"double word"
和
"single"|"\"double word\""
甚至更好
"single"|"\"double word\""|"double\ word"|"'double word'"
建议
不过,我想建议一些更多的改变:
_script()
{
local cur prev opts iter
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
opts="-t"
if [[ ${cur} == -* ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
fi
case "$prev" in
-t)
options=(single "double\ word")
for iter in "${options[@]}"; do
if [[ $iter =~ ^$cur ]]; then
COMPREPLY+=( "$iter" )
fi
done
return 0
;;
"single"|"double\ word")
compopt -o default
COMPREPLY=()
return 0
;;
esac
}