Bash 补全 - 如何获取子选项的文件名补全

Bash 补全 - 如何获取子选项的文件名补全

我有一个函数可以接受主参数,然后接受子参数。其中一些子参数是文件名。我目前的完成代码如下。

_scm() {
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts=$(mpv -input cmdlist | awk '{print $1}')

    case "${prev}" in
        sub_add)
            COMPREPLY=( $(compgen -f ${cur}) )
            return 0
            ;;
        *)
            ;;
    esac

    COMPREPLY=( $(compgen -W "${opts}" -- ${cur} ) )
}
complete -o plusdirs -F _scm scm

我希望sub_addarg 将文件名作为 subarg 并且当前代码能够做到这一点。但是,我也想再次获得 args 的自动完成功能,一旦sub_add它的 aubargs 完成。但文件完成却不断地发生。

例如,现在,按

scm sub_add <TAB>

让我完成文件名。我还想要的是,完成文件名后,原始的 arg 补全应该开始

scm sub_add ~/filename.txt <TAB>

应该给sub_add sub_load seek....

文件名完成一次又一次发生的原因是因为complete -o plusdirs.但是,如果没有它,bash 就会完成目录和文件,而我只想要文件名。我怎样才能修改我的代码来实现我想要的?

答案1

我认为没有任何内置或 bash 完成标准函数可以仅完成裸文件名。目录可以包含文件,因此完成文件名的标准行为是完成文件和目录(就像 bash-completion 所做的那样_filedir。它有一个仅适用于目录的选项,但不能仅适用于文件。)。

您可以编写一个自定义函数来仅返回裸文件名匹配,例如迭代completions=( "$word"* )并检查[[ -f "$i" ]]build COMPREPLY

我更仔细地阅读了你的代码。如果您正在生成补全多用途车,您不应将其限制为仅适用于当前目录中的裸文件名。这不是我所知道的任何其他自定义完成函数的行为方式。

相关内容