bash - 别名的 Git 完成就像 Git 本身一样

标签 bash git bash-completion git-alias

背景
我已经成功地为各种 Git 别名配置了 Bash 完成。例如:

$ git config alias.subject
!git --no-pager show --quiet --pretty='%s'
$ function _git_subject() { _git_show; }
$ git subject my<TAB>
$ git subject my-branch
挑战
但是,我有一个 Git 别名,我不知道如何为其设置 Bash 完成。问题是我希望别名能够像顶级 Git 命令本身一样完成。别名是这样的:
$ git config alias.alias
alias = !"f() { if [[ \"$#\" != 1 ]]; then >&2 echo \"Usage: git alias COMMAND\"; return 1; fi; git config alias.\"$1\"; }; f"
# Example
$ git alias s
status
我试过使用 _git , __git_main , 和 __git_wrap__git_main ,但它们都不起作用(我认为这会导致无限循环,因为在我按下 Tab 后它永远不会返回)。
有没有办法为 Git 别名添加完成,就像它是顶级 Git 命令一样?或者具体如何完成这个别名?
尝试过但不起作用
function _git_alias() { _git; }
function _git_alias() { __git_main; }
function _git_alias() { __git_wrap__git_main; }
期望的行为
$ git alias su<TAB>
subject     submodule
$ git alias sub
或者,如果有一种简单的方法来完成别名也很酷。不过,我也想知道如何完成就好像顶级 Git 命令一样,只是出于好奇。

最佳答案

我终于能够围绕“神奇”的 Bash 完成变量创建一个带有一些技巧的工作解决方案。我将这些变量更改为“假装”我们正在完成给定给 git 本身的命令。
如果有人有任何建议来简化这一点,我将完全接受建议。

# This is complex because we want to delegate to the completion for Git
# itself without ending up with an infinite loop (which happens if you try
# to just delegate to _git).
_git_alias() {
    if [[ "$COMP_CWORD" -lt 2 ]]; then
        return
    fi
    local old_comp_line_length new_comp_line_length
    COMP_WORDS=(git "${COMP_WORDS[@]:2}")
    ((COMP_CWORD -= 1))
    old_comp_line_length=${#COMP_LINE}
    if [[ "$COMP_LINE" =~ ^[^[:blank:]]+[[:blank:]]+[^[:blank:]]+[[:blank:]]+(.*)$ ]]; then
        COMP_LINE="git ${BASH_REMATCH[1]}"
    fi
    new_comp_line_length=${#COMP_LINE}
    (( COMP_POINT += new_comp_line_length - old_comp_line_length ))

    _git "$@"

    # git alias blah
    #            ^
    # 01234567890123
    # 0         1
    # point:  11
    # length: 13
    #
    # git blah
    #      ^
    # 01234567
    # point:  5
    # length: 7
    #
    # point = point - (old length) + (new length)
    # point = 11 - 13 + 7
    # point = -2 + 7
    # point = 5
}

关于bash - 别名的 Git 完成就像 Git 本身一样,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66890696/

相关文章:

bash - 循环浏览 Bash 中的文件列表

linux - 经常在特定时间做某事

Git for Windows 停止工作 - VS Team Services

linux - 如何启用 bash-completion xrdp lxde

linux - 没有夏令时 (DST) 的给定时区的 GMT/UTC 偏移量(小时/分钟)

狂欢 : space in path access

git将多个提交压缩为多个提交

git - 将 Jenkins 连接到 AWS CodeCommit 存储库

python - 使用 pip install -e 在 setup.py 中安装 data_files

bash - 如何缓存当前 session 的 Bash 完成脚本中使用的变量