如何让两个程序在bash中只使用一个自动完成功能?

时间:2012-05-07 04:50:23

标签: bash autocomplete refactoring

我按照此tutorialfiglet / toilet设置了自动完成功能。

# bash completion for figlet/toilet

have figlet &&
_figlet()
{
    local prev cur opts
    _get_comp_words_by_ref cur prev
    opts="-f"

    COMPREPLY=()

    case $prev in
        -f)
            local running=$(find /usr/share/figlet -name '*.flf' -printf '%P\n' | sed 's/\.flf$//')
            COMPREPLY=( $(compgen -W "${running}" -- ${cur}) )
            return 0
            ;;
        *)
            ;;
    esac

    COMPREPLY=( $( compgen -W "$opts" -- "$cur" ) )

    return 0
} &&
complete -F _figlet figlet

###################################################################################################

have toilet &&
_toilet()
{
    local prev cur opts
    _get_comp_words_by_ref cur prev
    opts="-f"

    COMPREPLY=()

    case $prev in
        -f)
            local running=$(find /usr/share/figlet -name '*.[tf]lf' -printf '%P\n' | sed 's/\.[tf]lf$//')
            COMPREPLY=( $(compgen -W "${running}" -- ${cur}) )
            return 0
            ;;
        *)
            ;;
    esac

    COMPREPLY=( $( compgen -W "$opts" -- "$cur" ) )

    return 0
} &&
complete -F _toilet toilet
_figlet / _toilet命令中的模式外,

findsed几乎完全相同。
如何提取一个名为_figlet_toilet的函数,该函数将模式作为参数?

1 个答案:

答案 0 :(得分:0)

来自:http://www.gnu.org/software/bash/manual/html_node/Programmable-Completion.html

  

生成这些匹配后,将调用使用-F和-C选项指定的任何shell函数或命令。调用命令或函数时,COMP_LINE,COMP_POINT,COMP_KEY和COMP_TYPE变量将按上述方式分配值(请参阅Bash变量)。如果正在调用shell函数,则还会设置COMP_WORDS和COMP_CWORD变量。当调用函数或命令时,第一个参数是参数完成的命令的名称,第二个参数是正在完成的单词,第三个参数是单词之前的单词在当前命令行上完成。不执行针对正在完成的单词的生成的完成的过滤;函数或命令可以完全自由地生成匹配项。


# bash completion for figlet/toilet

{
    have figlet || have toilet
} &&
_figlet_toilet()
{
    local prev cur opts pat
    _get_comp_words_by_ref cur prev
    opts="-f"

    COMPREPLY=()

    case $prev in
        -f)
            case "${1}" in
                figlet)
                    pat='flf'
                ;;
                toilet)
                    pat='[tf]lf'
                ;;
            esac
            local running=$(find /usr/share/figlet -name "*.${pat}" -printf '%P\n' | sed "s/\.${pat}\$//")
            COMPREPLY=( $(compgen -W "${running}" -- ${cur}) )
            return 0
            ;;
        *)
            ;;
    esac

    # if '-f' is already given, then generate random string
    for (( i=0; i < ${#COMP_WORDS[@]}-1; i++ )); do
        if [[ ${COMP_WORDS[i]} == -f ]]; then
            # COMPREPLY=("'$(fortune -sn42)'")
            return 0
        fi
    done

    COMPREPLY=( $( compgen -W "$opts" -- "$cur" ) )

    return 0
} &&
complete -F _figlet_toilet figlet toilet