有没有办法在当前会话中自定义“可编程完成”?

Que*_*ark 9 bash autocomplete

如果我开始输入命令或文件名,我可以使用 Tab 键自动完成我的字符串。有没有办法更改当前 bash 会话的自动完成行为?

例如

在Tab Tab当前会话中按下时,只会*.txt显示包含的文件。

自动完成功能如何工作?是否有一组环境变量或可以调整以更改自动完成行为的东西?

cha*_*aos 10

在该bash_completion机制中_filedir_xspec(),负责文件名和目录名补全的是 bash 函数。这个功能可以在脚本中找到/etc/bash_completion。

您可以编辑该函数并添加一行包含您的正则表达式。例如使用这个函数(它是原始函数的副本):

_filedir_xspec()
{
    local IFS cur xspec

    IFS=$'\n'
    COMPREPLY=()
    _get_comp_words_by_ref cur

    _expand || return 0

    # get first exclusion compspec that matches this command
    xspec=$( awk "/^complete[ \t]+.*[ \t]${1##*/}([ \t]|\$)/ { print \$0; exit }" \
        "$BASH_COMPLETION" )
    # prune to leave nothing but the -X spec
    xspec=${xspec#*-X }
    xspec=${xspec%% *}

    local -a toks
    local tmp

    toks=( ${toks[@]-} $(
        compgen -d -- "$(quote_readline "$cur")" | {
        while read -r tmp; do
            # see long TODO comment in _filedir() --David
            printf '%s\n' $tmp
        done
        }
        ))

    # Munge xspec to contain uppercase version too
    eval xspec="${xspec}"
    eval xspec="!*.txt" #<---- HERE add your regex, that's the only line changed
    local matchop=!
    if [[ $xspec == !* ]]; then
        xspec=${xspec#!}
        matchop=@
    fi
    [[ ${BASH_VERSINFO[0]} -ge 4 ]] && \
        xspec="$matchop($xspec|${xspec^^})" || \
        xspec="$matchop($xspec|$(printf %s $xspec | tr '[:lower:]' '[:upper:]'))"

    toks=( ${toks[@]-} $(
        eval compgen -f -X "!$xspec" -- "\$(quote_readline "\$cur")" | {
        while read -r tmp; do
            [ -n $tmp ] && printf '%s\n' $tmp
        done
        }
        ))
    [ ${#toks[@]} -ne 0 ] && _compopt_o_filenames
    COMPREPLY=( "${toks[@]}" )
}
Run Code Online (Sandbox Code Playgroud)

注意第32 行的新部分:

eval xspec="!*.txt" 
Run Code Online (Sandbox Code Playgroud)

此语句稍后用于compgen删除所有与正则表达式不匹配的条目。我不建议编辑文件/etc/bash_completion。而是使用上面的内容和source文件(如果需要)创建一个新文件:

source /path/to/file
Run Code Online (Sandbox Code Playgroud)

现在,shell 中的所有命令/应用程序,由函数 _filedir_xspec()完成的,现在只用*.txt文件名完成。

  • 它仅适用于当前会话。您可以将该函数复制到您的 shell 中,它将在下一个会话中消失。但我建议在需要时提供一个包含该函数的文件。在下一个会话中它不再可用。为了使其永久化,我会将其编写为 rc 脚本之一:例如`~/.bashrc`。 (2认同)