Завершение Bash: учитывайте псевдоним Git для конкретного репозитория в завершении псевдонима

Скажем, bash настроен со следующим псевдонимом:

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

И этот конкретный репозиторий — и только этот репозиторий — имеет следующий псевдоним git:

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

Как up может автоматически заполнять backup?


Это автоматически дополняет backup, но не up:

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

Это автоматически дополняет up стандартными командами git, но не backup:

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


Изменить: Итан прав, функция завершения должна видеть расширенный псевдоним, поэтому я создал следующее:

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"

Но есть необъяснимые проблемы:

  • 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

person user19087    schedule 29.04.2015    source источник
comment
Видит ли функция завершения up или расширенный псевдоним?   -  person Etan Reisner    schedule 30.04.2015
comment
если функция завершения читается в команде как «вверх», она не будет вести себя так, как ожидалось, используйте дополнительную функцию для расширения до «резервного копирования», чтобы вы могли быть уверены, что точная команда отправляется в функцию завершения. Так обстоит дело со многими более полными функциями: они ожидают (или предполагают), что команда — это то, для чего они ее запрограммировали. Поэтому, если вы пойдете и прикрепите комплемент к какой-то другой команде, он не будет работать (отсюда и функция посредника). Для начала вы можете показать некоторый результат -xv от вызова двух, чтобы убедиться, что ваша функция делает то, что вы ожидаете (или ее отличие)   -  person osirisgothra    schedule 21.05.2015


Ответы (1)


В таких сложных случаях не стоит использовать псевдонимы, используйте функции bash. Псевдонимы больше похожи на препроцессор в C (в смысле использования), тогда как функции больше похожи на... функции кода. И я обнаружил, что они также более «автозаполняемые».

Вы также можете посмотреть, как эта проблема решается в других оболочках, таких как fish.

person Kirill Rogovoy    schedule 07.12.2015