我正在使用PHP工具http://robo.li和n98-magerun.phar - 两者都基于Sympfony的CLI组件。
当我使用这样的自动完成脚本时:
https://gist.github.com/caseyfw/51bdbcb37e5dfb91b74e
#!/bin/sh
function __robo_list_cmds ()
{
robo list --raw | awk '{print $1}' | sort
}
function __robo_list_opts ()
{
robo list --no-ansi | sed -e '1,/Options:/d' -e '/^$/,$d' -e 's/^ *//' -e 's/ .*//' | sort
}
_robo()
{
local cur="${COMP_WORDS[COMP_CWORD]}"
COMPREPLY=($(compgen -W "$(__robo_list_opts) $(__robo_list_cmds)" -- ${cur}))
return 0;
}
complete -o default -F _robo robo
COMP_WORDBREAKS=${COMP_WORDBREAKS//:}
它打破了scp
命令的自动完成(通常在远程服务器上完成文件 - 但是这与 - 无关 - robo完成到位,scp从命令中删除主机名)
为什么?怎么解决?
修改
根据答案,固定版本在这里:
https://gist.github.com/amenk/d68f1fe54b156952ced621f771ff48ba
答案 0 :(得分:5)
这可能与您的robo
compspec无关。也不是与_scp
相关联的scp
完成功能。
可能是由于您COMP_WORDBREAKS=${COMP_WORDBREAKS//:}
。
您从分隔符列表中删除了:
。显然,_scp
非常强大,可以使用:
作为单词分隔符,但行为相同。它返回相同的候选完成列表。但是当_scp
仅返回一个完成的候选者时,替换的令牌,例如scp host:public_ht
,host:public_ht
,而非public_ht
。证明:
$ _foobar () { COMPREPLY=bazcux; return 0; }
$ complete -o default -F _foobar foobar
$ echo $COMP_WORDBREAKS
"'><=;|&(:
如果您尝试完成foobar host:public_ht
,则会获得foobar host:bazcux
,因为替换的令牌只是public_ht
。同时:
$ COMP_WORDBREAKS=${COMP_WORDBREAKS//:}
$ echo $COMP_WORDBREAKS
"'><=;|&(
如果您尝试完成foobar host:public_ht
,则会获得foobar bazcux
,因为完整的host:public_ht
会被bazcux
取代。
您的问题的解决方案可能是调整您的_robo
完成功能,这样就不需要:
不是单词分隔符。类似的东西:
_stem () {
local lcur lprev
lcur="$cur"
stem="$lcur"
for (( i = cword - 1; i >= 0; i -= 1 )); do
lprev="${words[i]}"
[[ $lcur == ":" ]] && [[ $lprev == ":" ]] && break
[[ $lcur != ":" ]] && [[ $lprev != ":" ]] && break
stem="$lprev$stem"
lcur="$lprev"
done
}
_robo () {
local cur prev words cword
_init_completion || return
local stem options
options=($(__robo_list_opts) $(__robo_list_cmds))
COMPREPLY=()
_stem
COMPREPLY=($(compgen -W '${options[@]}' -- "$stem"))
[[ $stem =~ : ]] && stem=${stem%:*}: && COMPREPLY=(${COMPREPLY[@]#"$stem"})
return 0
}
complete -o default -F _robo robo
一个(显然)更简单的解决方案包括用_stem
库的现有__reassemble_comp_words_by_ref
函数替换上面的bash_completion
函数:
_robo () {
local cur prev words cword
_init_completion || return
__reassemble_comp_words_by_ref ":" words cword
options=($(__robo_list_opts) $(__robo_list_cmds))
COMPREPLY=($(compgen -W '${options[@]}' -- "$cur"))
return 0
}
complete -o default -F _robo robo
所有这些可能都不是你想要的。我不知道robo.il
并且可能有许多改进需要考虑更多背景来提出具体的完成情况。但这可能是一个起点。