当选项卡绑定到bash中的menu-complete时,按Tab键两次执行第二次完成

时间:2014-05-15 16:40:26

标签: bash tab-completion

设置

标题可能有点迟钝,但我想不出更好的描述方式。 我有一个bash函数,可以向上导航任意数量的目录,所以:up 2将在目录结构2级中导航cd。

如果您执行up 2<TAB>,则会自动完成并打印完整路径。

想象一下这个文件结构:

└── demos/
    ├── audio/
    │   ├── assets/
    │   └── index.html
    └── video/
        ├── assets/
        └── index.html

我当前的目录是/demos/video/assets。 如果我按up 2,则会将我转到/demos,如果我按up 2<TAB>,则会自动完成up /demos

完成还有另外一个方面,如果我输入up 2/au<TAB>,它会自动完成up /demos/au<CURSOR>

问题

但是,因为我在我的bash_profile:bind 'TAB:menu-complete'中,然后在自动填充到up /demos/au<CURSOR>之后,就好像tab键被捕获了,并且没有进一步完成。 我可以进一步完成的唯一方法是按下另一个键(按下目录名的另一个字母,或按一次箭头键,然后按Tab键等)。

有什么方法可以告诉bash完成响应第二个标签按下或者在完成功能返回后以某种方式没有捕获标签键?

如果我没有选项卡绑定菜单完成,那么第二个选项卡不会被吞下,但是,我不想禁用菜单完成,因为它在所有其他完成中都很有用。

代码

这样你就可以看到我在做什么,这是我的完成代码(我只粘贴了有趣的部分,但你可以在这里看到整个函数:https://gist.github.com/natecavanaugh/10104c3408bc2bc8d733):

function _complete_up {
    COMPREPLY=()

    local curToken=${COMP_WORDS[COMP_CWORD]}

    curToken=${curToken//'\'}

    if [[ $curToken =~ ^[0-9]+/? ]]; then

        local strpath=$( printf "%${curToken%%/*}s" )
        local upDirSpec=${strpath// /../}

        local trailingpath="${curToken#*/}"

        if [[ $trailingpath =~ ^[0-9]+$ ]]; then
            trailingpath=""
        fi

        local dir=$(cd "$upDirSpec"; echo -n "$PWD/")

        if [[ "$dir" == '//' ]]; then dir='/'; fi

        if [[ -n $trailingpath ]]; then
            if [[ "${trailingpath:0:1}" != "/" && "${dir: -1}" != "/" ]]; then
                trailingpath="/$trailingpath"
            fi

            dir="${dir}${trailingpath}"
        fi

        COMPREPLY=("$dir")
    fi

    return 0
}

complete -o plusdirs -o nospace -o filenames -F _complete_up up

感谢您提供的任何帮助:)

1 个答案:

答案 0 :(得分:1)

menu-complete会导致Tab键循环显示替代选项,但您的完整功能仅提供一种替代方法。所以没有什么可以循环的。

据我所知,没有办法根据类型化的上下文有条件地重新绑定密钥; readline作为一个库会允许这样的回调,但bash没有利用这个功能,我想我并不是唯一一个认为bash / readline界面已经过于复杂的人(“BUGS” :它太大而且太慢了“,正如man bash多年来所说的那样,并非专门针对readline)。

您是否尝试通过将完成函数中外部if的最后一行更改为以下内容来显式添加默认完成:

COMPREPLY=("$dir" ${dir}*)

(显然,有很多极端情况使得上述情况不够稳健,从${dir}*扩展为$dir后跟*的情况开始,因为它不匹配任何文件名。)