Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash completion: Honor repository-specific Git alias in alias completion

Say bash is configured with the following alias:

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

And that particular repository - and only that repository - has the following git alias:

[alias]
backup = commit --allow-empty-message

How can up auto-complete backup?


This auto-completes backup but not up:

cd /a/different/dir
git --git-dir=/path/to/backup/.git ba

This auto-completes up with standard git commands but not backup:

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


Edit: Etan is right, the completion function needs to see the expanded alias, so I've created the following:

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"

But there inexplicable problems:

  • up bac<Tab> doesn't work
  • up <Tab> uses default completion and doesn't list git subcommands
  • and many more ...

Edit 2: Updated the script to fix the aforementioned problems using the suggestions at Re: Bash completion of aliased commands. Apparently this is a pretty common task. However now I'm running into this error message:

$ cd /a/different/dir
$ up backup<Tab> fatal: Not a git repository (or any of the parent directories): .git
like image 850
user19087 Avatar asked Apr 29 '15 21:04

user19087


1 Answers

You shouldn't really use aliases at such complicated cases, use bash functions. Aliases are more like pre-processor in C (in sense of using), when functions are more like... code functions. And I've found that they are also more "auto-completable".

You can also take a look at how this problem is being solved at other shells, like fish.

like image 147
Kirill Rogovoy Avatar answered Nov 03 '22 18:11

Kirill Rogovoy