在 bash 中使用 compgen 获得不区分大小写的补全

在 bash 中使用 compgen 获得不区分大小写的补全

我正在尝试使用 bash 自动完成我的命令(devmode2)复合基因-W,我的 bashrc 有:

_devmode2() {
    COMPREPLY=()
    local sonames=$(devmode2 --auto --current "${COMP_CWORD}" -- ${COMP_WORDS[@]})
    COMPREPLY=($(compgen -W "${sonames}" -- ${COMP_WORDS[COMP_CWORD]}))
}
complete -F _devmode2 devmode2

自动完成示例

$ devmode2 g<tab>

结果是索纳梅斯具有以下值:

game-life-adv
game-life-sparse
getopt-alt
git-workflow
git-workflow-extra
github-testers
group-git
group-git-ivan
Group-Git-Taggers-Maven
Group-Git-Taggers-Node
Group-Git-Taggers-Perl
Group-Git-Taggers-Ruby

但我的自动完成会产生以下建议:

game-life-adv       game-life-sparse    getopt-alt          github-testers      git-workflow        git-workflow-extra  group-git           group-git-ivan

我怎样才能获得我传递给的所有值康普根后退?

答案1

据我所知,compgen没有选项可以对您提供的选项列表进行不区分大小写的过滤。

您可以设置一个readline变量以使文件名完成不区分大小写:

bind "set completion-ignore-case on"

但这不会影响 的行为compgen,因此它可能不适用于可编程完成。 (它的行为对于文件名也有点奇怪。)

这使您可以进行自己的过滤,而不是使用compgen(或者如果您需要过滤以外的功能,则与 结合使用compgen,这在您的示例中不是这种情况)。

您可以通过对替代列表进行简单迭代,进行不区分大小写的前缀比较来做到这一点,但以下小函数应该可以工作:

_devmode2() {
  local sonames=($(devmode2 --auto --current "${COMP_CWORD}" -- ${COMP_WORDS[@]}))
  local prefix="${COMP_WORDS[COMP_CWORD]}"
  COMPREPLY=($(printf %s\\n "${sonames[@]}" |
               awk -v IGNORECASE=1 -v p="$prefix" \
                   'p==substr($0,0,length(p))'))
}

如果devmode2每行输出一个替代方案,则将其用作 的输入会更容易awk。另外,据我所知,完成函数的第二个参数始终与 相同${COMP_WORDS[COMP_CWORD]}。所以这可能更简单:

_devmode2() {
  COMPREPLY=($(devmode2 -auto --current "${COMP_CWORD}" -- "${COMP_WORDS[@]}" \
               awk -v IGNORECASE=1 -v p="$2" \
                   'p==substr($0,0,length(p))'))
}

相关内容