Bash 完成覆盖当前单词

Joh*_*nes 5 bash autocomplete

我正在尝试为我的命令创建一个 bash 完成脚本。ls有我想要的行为。我需要从我的命令中获得相同的行为。

这就是我得到的 ls

$ ls /home/tux/<Tab><Tab>
Downloads  Documents  Pictures
$ ls /home/tux/Do<Tab><Tab>
Downloads  Documents
Run Code Online (Sandbox Code Playgroud)

即 bash 只相对地显示下一个路径,而不是绝对地(即它确实添加Downloads到完成列表中,但不是/home/tux/Downloads

我想编写一个以相同方式工作的完成脚本。这是我尝试过的。

_testcommand ()
{
    local IFS=$'\n'
    local cur=${COMP_WORDS[COMP_CWORD]}
    COMPREPLY=( $(compgen -o bashdefault -d -- "$cur") )
    if [ "${#COMPREPLY[@]}" -ne 1 ]
    then
        # remove prefix "$cur", so the preview of paths gets shorter
        local cur_len=$(echo $cur | sed 's|/[^/]*$||' | wc -c)
        for i in ${!COMPREPLY[@]}
        do
            COMPREPLY[$i]="${COMPREPLY[i]:$cur_len}"
        done
    fi
    return 0
}

complete -o nospace -F _testcommand testcommand
Run Code Online (Sandbox Code Playgroud)

然而结果是这样的:

$ testcommand /home/tux/<Tab><Tab>
Downloads  Documents  Pictures
$ testcommand /home/tux/Do<Tab>
Downloads  Documents
$ testcommand Do
Run Code Online (Sandbox Code Playgroud)

如何使我的完成/home/tux/从命令行中删除?

注意:我想我不能complete在底部的调用中添加 '-f' 或 '-d' 等。实际上,在某些情况下,完成还必须完成单词而不是路径。

Joh*_*nes 0

bash 完成目录 ( pkg-config --variable=completionsdir bash-completion) 中的大多数程序都使用_filedirbash-completion 本身提供的功能。重用似乎是合法的_filedir- 无需担心您自己的实现!

微量元素:

_testcommand()
{
    # init bash-completion's stuff
    _init_completion || return

    # fill COMPREPLY using bash-completion's routine
    # in this case, accept only MarkDown and C files
    _filedir '@(md|c)'
}
complete -F _testcommand testcommand
Run Code Online (Sandbox Code Playgroud)

当然,您仍然可以在完成非文件时使用它:

if ...
then
    # any custom extensions, e.g. words, numbers etc
    COMPREPLY=( $(compgen ...) )
else
    # fill COMPREPLY using bash-completion's routine
    _filedir '@(md|c)'
fi
Run Code Online (Sandbox Code Playgroud)

我是怎么找到它的?

感谢@csm:使用他们的答案,检查type _longopt,调用_filedir