bash - 在逐个命令的基础上为 bash 完成设置不区分大小写

标签 bash case-insensitive tab-completion

有没有一种方法可以指定特定命令不区分大小写,而不需要全局打开不区分大小写(至少对于那个 shell)?

在我的特殊情况下,我有一个小应用程序,可以让我通过命令行访问电子邮件地址数据库,所以我输入:

db get email john smith

它返回 John Smith 的电子邮件地址。所以我设法在应用程序内部实现了主要的完成:设置

COMPREPLY=($(compgen -W "$(db --complete $COMP_CWORD "$COMP_WORDS[@]"}")" -- ${COMP_WORDS[COMP_CWORD]}))

允许我使用制表符完成 getemail .但是,如果我然后键入 j<tab> , 它拒绝了,因为在电子邮件数据库中,它被正确地大写了。无论如何,我想让 bash 完成它。 (如果我使用大写字母 J,它会起作用。)

否则,我可以得到我的 --complete选项通过匹配输入来更改其回复的大小写,我想,但理想情况下命令行会尽可能匹配数据库。

请注意,我在使用 readline 时在应用程序内部进行了此操作,它仅与 bash 交互,这似乎是一个问题。

最佳答案

确实,似乎没有办法让 compgen 对单词列表 (-W) 进行不区分大小写的匹配。 我看到以下解决方法:

简单的解决方案:首先将单词列表和输入标记都翻译成全小写。 注意:这是一个可以接受将所有补全变成全小写的选项。

complete_lower() {

    local token=${COMP_WORDS[$COMP_CWORD]}
    local words=$( db --complete $COMP_CWORD "${COMP_WORDS[@]}" )

    # Translate both the word list and the token to all-lowercase.
    local wordsLower=$( printf %s "$words" | tr [:upper:] [:lower:] )
    local tokenLower=$( printf %s "$token" | tr [:upper:] [:lower:] )

    COMPREPLY=($(compgen -W "$wordsLower" -- "$tokenLower"))   
}

更好但更精细的解决方案:推出您自己的不区分大小写的匹配逻辑:

complete_custommatch() {

    local token=${COMP_WORDS[$COMP_CWORD]}
    local words=$( db --complete $COMP_CWORD "${COMP_WORDS[@]}" )

    # Turn case-insensitive matching temporarily on, if necessary.
    local nocasematchWasOff=0
    shopt nocasematch >/dev/null || nocasematchWasOff=1
    (( nocasematchWasOff )) && shopt -s nocasematch

    # Loop over words in list and search for case-insensitive prefix match.
    local w matches=()
    for w in $words; do
        if [[ "$w" == "$token"* ]]; then matches+=("$w"); fi
    done

    # Restore state of 'nocasematch' option, if necessary.
    (( nocasematchWasOff )) && shopt -u nocasematch

    COMPREPLY=("${matches[@]}")
}

关于bash - 在逐个命令的基础上为 bash 完成设置不区分大小写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10525659/

相关文章:

python - 如何让我的程序利用制表符补全?

python - manage.py runserver 不终止

python - 在 Python 中将项目插入不区分大小写的排序列表

Bash 整数比较

entity-framework - 我可以使Entity Framework使用sqlite的LIKE代替instr()吗?

python - 不区分大小写 'in'

scala - ILoop 选项卡完成

shell - Zsh 颜色部分选项卡完成

linux - 遍历 CSV 文件中的每一列并将不同的值导出到文件

c - 使用环境变量执行不同的文件