У меня в файле есть следующие строки ~/.aliases
:
function __function_exists() {
declare -f -F $1 > /dev/null
return $?
}
# git aliases (need to have git bash completion installed)
for al in `__git_aliases`; do
alias g$al="git $al"
complete_func=_git_$(__git_aliased_command $al)
__function_exists $complete_fnc && __git_complete g$al $complete_func
done
А у меня ~/.gitconfig
в наличии:
[alias]
# one-line log
l = log --pretty=format:"%C(yellow)%h\\ %ad%Cred%d\\ %Creset%s%Cblue\\ [%cn]" --decorate --date=short
a = add
ap = add -p
c = commit --verbose
ca = commit -a --verbose
cm = commit -m
cam = commit -a -m
m = commit --amend --verbose
d = diff
ds = diff --stat
dc = diff --cached
s = status -s
co = checkout
cob = checkout -b
# list branches sorted by last modified
b = "!git for-each-ref --sort='-authordate' --format='%(authordate)%09%(objectname:short)%09%(refname)' refs/heads | sed -e 's-refs/heads/--'"
# list aliases
la = "!git config -l | grep alias | cut -c 7-"
И в моем ~/.zshrc
:
zstyle :compinstall filename '/home/giuliani/.zshrc'
autoload -Uz compinit
compinit
[[ -f $HOME/.aliases ]] && source "$HOME/.aliases"
Итак, для каждого псевдонима в моем gitconfig я определю псевдоним оболочки, например gl
for git log
и так далее.
Пытаюсь перенести это на zsh, но у меня возникла проблема: autoload
встроенная функция zsh загружает файл только /usr/share/zsh/functions/Completion/Unix/_git
в первый раз, когда я пытаюсь выполнить какую-то команду git.
Я попытался вызвать/загрузить _git
файл напрямую из , .zshrc
но после нескольких предупреждений это не сработало.
Как правильно получить ту же функциональность, что и в bash, используя zsh?
решение1
На самом деле, вызов _git
из вашего .zshrc
действительно работает, поскольку он определяет _git
и сопутствующие ему функции, включая __git_aliases
, и пытается выполнить какое-то завершение, но терпит неудачу (даже без сообщения об ошибке в данном конкретном случае).Это работает с большинством функций завершения.. Это нужно сделать после compinit
того, как _git
и его вспомогательные функции будут отмечены для автозагрузки.
% zsh -f
darkstar% autoload compinit
darkstar% compinit
darkstar% _git
darkstar% __git_aliases
_tags:comptags:36: can only be called from completion function
_tags:comptry:55: can only be called from completion function
_tags:comptags:60: can only be called from completion function
_tags:comptags:67: can only be called from completion function
Проблема в том, что когда вы запускаете __git_aliases
, он вызывает встроенные функции, которые можно использовать только при выполнении завершения. Вы можете обойти это, временно определив функции с тем же именем, что и эти встроенные функции, которые делают только ту часть, которую вы хотите сделать, что часто не является чем-то, но это очень неуклюже. Я не собираюсь показывать, как, потому что в этом конкретном случае есть гораздо более простой способ.
Поскольку вы в любом случае погружаетесь глубоко в _git
файл завершения, вызовите __git_extract_aliases
вместо __git_aliases
. __git_extract_aliases
запихивает информацию в переменную aliases
таким образом, чтобы ее было легко извлечь. (Примечание: я написал этот ответ для zsh 5.4.2, которая является версией в Ubuntu 18.04. Другие версии zsh могут иметь другую структуру в _git
.)
_git 2>/dev/null
define_git_aliases () {
local -a aliases; local al
__git_extract_aliases
for al in ${aliases%%:*}; do
alias g$al="git $al"
done
}
define_git_aliases
Это все еще требует гораздо больше усилий, чем необходимо, и потенциально дополнительных усилий по портированию для работы с различными версиями zsh. __git_extract_aliases
По сути, это одна строка кода.
for al in ${${${(0)"$(git config -z --get-regexp '^alias.')"}%%$'\n'*}#alias.}; do
alias g$al="git $al"
done