Bash完成:在别名完成中荣获特定于存储库的Git别名

use*_*087 29 git bash bash-completion

假设bash配置了以下别名:

alias up="git --git-dir /path/to/backup/.git"

而那个特定的存储库 - 只有该存储库 - 具有以下git别名:

[alias]
backup = commit --allow-empty-message
Run Code Online (Sandbox Code Playgroud)

怎么能up自动完成backup


这自动完成backup但不是up:

cd /a/different/dir
git --git-dir=/path/to/backup/.git ba
Run Code Online (Sandbox Code Playgroud)

这是up使用标准git命令自动完成但不是backup:

complete -o bashdefault -o default -o nospace -F __git_wrap__git_main up


编辑:Etan是对的,完成功能需要查看扩展的别名,所以我创建了以下内容:

CompletableAlias() {
    if (($#<2)); then
        return 1
    fi
    source_c="$1"
    target_c="$2"
    target_a=( "${@:2}" )
    target_s="${target_a[*]}"
    alias "${source_c}=${target_s}"
    completion_modifier="__${source_c}_completion"
    completion_original="$( complete -p "$target_c" 2>/dev/null |
                            sed 's/.*-F\W\+\(\w\+\).*/\1/'
                          )"
    if [[ -n "$completion_original" ]]; then
        read -r -d '' completion_function <<-EOF
        function $completion_modifier() {
            COMP_LINE="\${COMP_LINE/#${source_c}/${target_s}}"
            ((COMP_POINT+=${#target_s}-${#source_c}))
            ((COMP_CWORD+=${#target_a[@]}-1))
            COMP_WORDS=( ${target_a[@]} \${COMP_WORDS[@]:1} )
            $completion_original
        }
EOF
        eval "$completion_function"
        completion_command="$( complete -p "$target_c" |
                               sed "s/${completion_original}/${completion_modifier}/;
                                    s/\w\+\$/${source_c}/"
                             )"
        $completion_command
    fi
}


source "/usr/share/bash-completion/completions/git"

CompletableAlias "up" "git" "--git-dir" "/path/to/backup/.git"
Run Code Online (Sandbox Code Playgroud)

但是有一些莫名其妙的问题:

  • up bac<Tab> 不起作用
  • up <Tab> 使用默认完成并且不列出git子命令
  • 还有很多 ...

编辑2:使用Re:Bash完成别名命令的建议更新了脚本以修复上述问题.显然这是一项非常常见的任务.但是现在我遇到了这个错误消息:

$ cd /a/different/dir
$ up backup<Tab> fatal: Not a git repository (or any of the parent directories): .git
Run Code Online (Sandbox Code Playgroud)

Kir*_*voy 1

在如此复杂的情况下,您不应该真正使用别名,而应使用bash 函数。别名更像是 C 中的预处理器(从使用的意义上来说),而函数更像是……代码函数。而且我发现它们也更“可自动完成”。

您还可以查看其他 shell(例如Fish)如何解决此问题。