Я запускаю zsh 5.0.4 на OS X 10.8 с oh-my-zsh a38af27
с плагином git
. Когда я набираю gco <TAB>
, я получаю следующий результат:
% gco zsh:12: command not found: __git-checkout_main
extegco
file
MIT-LICENSE.txt custom/ log/ plugins/ themes/
README.textile lib/ oh-my-zsh.sh templates/ tools/
Я обнаружил, что виноват вариант complete_aliases
. Как только я его выключаю, все работает как положено.
Что дает? Есть ли вариант коллизии? Я давно не менял свои .zshrc
, и у меня всегда были complete_aliases
.
Мне эта опция особо не нужна, но, думаю, здесь есть какая-то ошибка.
: +1: Точно такая же проблема ... очень озадачивающая.
Интересно.
Для ленивых вот что говорится в руководстве Zsh о complete_aliases
:
Предотвращает внутреннюю замену псевдонимов в командной строке до попытки завершения. Эффект состоит в том, чтобы сделать псевдоним отдельной командой для целей завершения.
Однако, поскольку 57f55e69ed967e93c0fd44a6a7e470781eb38029 и 2e9492969b0ea90932ad3f4298330b75ef8cf2ce, псевдонимы из подключаемого модуля git имеют собственный набор завершения и gco
перенаправляются на соответствующую подкоманду git 1, включая gco
. Так что эта проблема _не должна_ возникать. Кто-нибудь знает, почему до сих пор?
Наконец, я не могу воспроизвести проблему с Zsh 5.0.2 на Mac 10.9.2: complete_aliases
вообще не изменяет поведение завершения на gco
, даже если я очищаю завершение кеш.
@slhck @mecampbellsoup Можете ли вы попробовать с шаблоном .zshrc
и посмотреть, происходит ли это по-прежнему?
Также @mecampbellsoup, можете ли вы опубликовать конфигурацию вашей системы и версию Zsh?
@mcornella @simonweil (мои счастливые помощники = D) вы можете попытаться воспроизвести проблему?
Сейчас я использую Zsh 5.0.5 с oh-my-zsh eafd5f3
. Если я использую шаблон .zshrc
проблем нет. Конечно, потому что там нет опции complete_aliases
.
Как только я включаю setopt complete_aliases
, нажатие Tab
после gco
вызывает ту же старую ошибку.
@ncanceill Конечно, вот и все:
⇒ zsh --version
zsh 5.0.5 (x86_64-apple-darwin13.0.0)⇒ zsh --version
zsh 5.0.5 (x86_64-apple-darwin13.0.0)
Мои полные конфигурации .zshrc
и zsh
можно найти здесь: https://github.com/mecampbellsoup/dotfiles/tree/master/zsh
Версия oh-my-zsh тоже eafd5f3
.
Понятия не имею .. может быть ошибка compinit cache? Если да, попробуйте удалить файлы .zcompdump*
в каталоге $ HOME.
@mcornella К сожалению, это не помогло.
@slhck Думаю, нам стоит начать проверять предыдущие zsh
коммиты, чтобы увидеть, сможем ли мы найти ошибку ...?
@mecampbellsoup да, это может быть полезно! Я рекомендую использовать git-bisect
.
Невоспроизводимость проблемы предполагает, что она имеет какое-то отношение к вашей конфигурации, а тот факт, что она все еще происходит с шаблоном .zshrc
указывает на то, что она не связана с вашей конфигурацией OMZ.
Давайте начнем с определения того, что должен делать оператор compdef
. Прочитав руководство по
#compdef names... [ -[pP] patterns... [ -N names... ] ]
Каждое имя также может иметь форму «_cmd = service_». При завершении команды _cmd_ функция обычно ведет себя так, как если бы вместо этого выполнялась команда (или специальный контекст) _service_. Это дает возможность изменить поведение функций, которые могут выполнять множество различных операций. Это реализуется установкой параметра$service
при вызове функции; функция может интерпретировать это так, как она хочет, а более простые функции, вероятно, проигнорируют это.
compdef [ -ane ] function names... [ -[pP] patterns... [ -N names... ] ]
Первая форма определяет _function_ для вызова завершения в заданных контекстах, как описано для тега#compdef
выше.
В качестве альтернативы все аргументы могут иметь форму «_cmd = service_». Здесь _service_ уже должен был быть определен строками '_cmd1 = service_' в файлах#compdef
, как описано выше. Аргумент для _cmd_ будет заполнен так же, как _service_.
Но затем я взглянул на завершение Zsh git (с количеством строк 6661), и git-checkout
не указано в операторе #compdef
, а $service
тоже не проверяется. Так что я понятия не имею, почему работает compdef _git gco=git-checkout
но это действительно работает!
@pielgrzym не могли бы вы рассказать нам о 2e9492969b0ea90932ad3f4298330b75ef8cf2ce?
Приятно копать @ncanceill!
$service
тоже не проверяется. Так что я понятия не имею, почемуcompdef _git gco=git-checkout
работает - но это действительно работает!
Это действительно проверено внутри функции _git()
, CTRL + F показывает, что это простой if-else:
if [[ $service == git ]]; then
[...]
else
_call_function ret _$service
fi
поэтому он затем вызывает _git-checkout
, который также определен, но только если он не был ранее определен :
(( $+functions[_git-checkout] )) ||
_git-checkout () { [...] }
Может быть, у них обоих есть специальная функция _git-checkout
определенная где-то еще, которая запускает это поведение?
Кроме того, в сообщении об ошибке отображается __git-checkout_main
(_с двумя знаками подчеркивания_), а затем extegco\n
file
. Мне кажется, что сообщение перезаписано, как будто zle
как-то связано с этим ..
Кстати, источник, который вы связали, был из основной ветки, вот как 5.0.4, так и 5.0.5
Спасибо @mcornella , я нашел чек на $service == git
но тупо проигнорировал условие else
! И я не нашел в себе смелости поиграть с программой просмотра SF git (у которой, кстати, нет номеров строк!), Чтобы найти конкретный момент в истории, ленив меня!
Мне нравится ваш намек о том, что _git-checkout
не определен, потому что он находится в другом месте. @slhck @mecampbellsoup можно запустить which _git-checkout
чтобы проверить правильность работы?
Что касается странного вывода, я видел, как zle
делал много странных вещей, поэтому я не слишком удивлен. Но меня сбивает с толку __git-checkout_main
как и вам.
И последнее: использование git checkout
вместо gco
должно показывать такое же поведение.
@ncanceill @mcornella Итак, вот некоторые результаты для вас, оба берутся после попытки завершения табуляции:
matthewcampbell@Matthews-MacBook-Air:~/Sites/code/stack-builders/seo_platform|69220108_adjust_keyword_editing_on_dealer⚡
⇒ gco ......zsh:12: command not found: __git-checkout_main
⇒ git checkout
67061970_notify_sidekiq_hangs origin/67061970_notify_sidekiq_hangs production
67394702_track_keywords_change origin/67394702_track_keywords_change production_2014-04-21
(PS Это то же самое, что и результат, когда у меня просто alias gco=git checkout
active и я использую gco
, т.е. после того, как я закомментировал setopt complete_aliases
в моем .zshrc
файле )
И когда я спрашиваю о which _git-checkout
(а также о which __git-checkout
):
⇒ which _git-checkout
_git-checkout not found
⇒ which __git-checkout
__git-checkout not found
Попробуй это:
autoload -Uz _git-checkout && _git-checkout
which _git-checkout
Извините, но не выяснилось, возникла ли проблема с использованием всего git checkout <TAB>
вместо gco <TAB>
..
Также попробуйте полностью отключить OMZ: то есть использовать пустой файл .zshrc
. Завершение Git должно сохраниться, и проблема тоже
И последнее: происходит ли то же самое в другом репозитории git?
@mcornella Больше результатов для тебя ':
⇒ autoload -Uz _git-checkout && _git-checkout
zsh: _git-checkout: function definition file not found
⇒ which _git-checkout
_git-checkout () {
# undefined
builtin autoload -XUz
}
Похоже, что в основном все мои функции завершения Git, кстати, не работают (мне нужно дважды <TAB>
чтобы появились ошибки):
⇒ ga ......zsh:12: command not found: __git-add_main
⇒ gco ......zsh:12: command not found: __git-checkout_main
⇒ gd ......zsh:12: command not found: __git-diff_main
⇒ gst ......zsh:12: command not found: __git-status_main
Я в полном недоумении. Сообщите мне, чем еще я могу помочь.
@mcornella Еще одна очень странная вещь, происходящая в моей настройке, - это результаты моей функции where
:
⇒ where ruby
ruby: aliased to bundled_ruby
/Users/matthewcampbell/.rbenv/shims/ruby
/Users/matthewcampbell/.rbenv/shims/ruby
/usr/bin/ruby
⇒ where coqc
/usr/local/bin/coqc
/usr/local/bin/coqc
/usr/local/bin/coqc
/usr/local/bin/coqc
Почему ZSH возвращал мне один и тот же результат 4 раза ?!
Хорошо, потерпите меня, в последний раз:
autoload -Uz _git && _git
which _git-checkout
а также
echo '$fpath = ('$fpath')'
echo '$path = ('$path')'
Также попробуйте то, что я упоминал об использовании пустого файла .zshrc
⇒ autoload -Uz _git && _git
zsh:12: command not found: ___main
_default:compcall:12: can only be called from completion function
⇒ which _git-checkout
_git-checkout not found
⇒ echo '$fpath = ('$fpath')'
$fpath = (/Users/matthewcampbell/.oh-my-zsh/plugins/gem /Users/matthewcampbell/.oh-my-zsh/plugins/brew /Users/matthewcampbell/.oh-my-zsh/plugins/bundler /Users/matthewcampbell/.oh-my-zsh/plugins/git /Users/matthewcampbell/.oh-my-zsh/functions /Users/matthewcampbell/.oh-my-zsh/completions /Users/matthewcampbell/.dotfiles/zsh /Users/matthewcampbell/.dotfiles/xcode /Users/matthewcampbell/.dotfiles/vim /Users/matthewcampbell/.dotfiles/tmux /Users/matthewcampbell/.dotfiles/system /Users/matthewcampbell/.dotfiles/sublime2 /Users/matthewcampbell/.dotfiles/script /Users/matthewcampbell/.dotfiles/ruby /Users/matthewcampbell/.dotfiles/python /Users/matthewcampbell/.dotfiles/osx /Users/matthewcampbell/.dotfiles/macvim /Users/matthewcampbell/.dotfiles/homebrew /Users/matthewcampbell/.dotfiles/git /Users/matthewcampbell/.dotfiles/functions /Users/matthewcampbell/.dotfiles/ctags /Users/matthewcampbell/.dotfiles/cloudapp /Users/matthewcampbell/.dotfiles/bin /Users/matthewcampbell/.dotfiles/functions /usr/local/share/zsh/site-functions /usr/local/Cellar/zsh/5.0.5/share/zsh/functions)
⇒ echo '$path = ('$path')'
$path = (/Users/matthewcampbell/.rbenv/shims /usr/local/opt/coreutils/libexec/gnubin /usr/local/bin /Users/matthewcampbell/.cabal/bin /Applications/Postgres93.app/Contents/MacOS/bin /usr/local/bin /usr/local/heroku/bin ./bin /Users/matthewcampbell/.rbenv/shims /usr/local/bin /usr/local/sbin /Users/matthewcampbell/.sfs /Users/matthewcampbell/.dotfiles/bin /usr/bin /bin /usr/sbin /sbin /usr/local/bin /opt/X11/bin /usr/local/go/bin /usr/local/MacGPG2/bin /Users/matthewcampbell/.rbenv/shims /usr/local/opt/coreutils/libexec/gnubin /Users/matthewcampbell/.cabal/bin /Applications/Postgres93.app/Contents/MacOS/bin /usr/local/heroku/bin ./bin /usr/local/sbin /Users/matthewcampbell/.sfs /Users/matthewcampbell/.dotfiles/bin /usr/local/Cellar/go/1.2.1/bin /usr/local/Cellar/go/1.2.1/bin)
Также попробуйте полностью отключить OMZ: то есть использовать пустой файл
.zshrc
. Завершение Git должно сохраниться, и проблема тоже
Matthews-MacBook-Air% autoload -Uz _git-checkout && _git-checkout
zsh: _git-checkout: function definition file not found
Matthews-MacBook-Air% gd
zsh: command not found: gd
Matthews-MacBook-Air% gst
zsh: command not found: gst
Matthews-MacBook-Air% gco
zsh: command not found: gco
Похоже, завершение не сохраняется ...
⇒ автозагрузка -Uz _git && _git
zsh: 12 : команда не найдена: ___main
Это подтверждает, что проблема возникает при каждом завершении git, я думаю, что-то не так с _git()
. Пожалуйста, опубликуйте результат which _git
Похоже, завершение не сохраняется ...
Когда вы используете zsh без oh-my-zsh, используйте не псевдонимы, а полную команду git, поскольку псевдонимы не определяются без oh-my-zsh. Вы можете перейти в репозиторий git и ввести любую команду git (например, git checkout <TAB>
) с setopt completealiases
и без него; Завершение git включено по умолчанию.
Кроме того, похоже, что в вашем пути $ есть повторяющиеся записи; для обеспечения уникальных значений добавьте команду typeset -U path
в конец вашего .zshrc
(после добавления всех записей пути)
Спасибо @mcornella , мне очень помогло.
⇒ which _git
_git () {
local _ret=1
local cur cword prev
cur=${words[CURRENT]}
prev=${words[CURRENT-1]}
let cword=CURRENT-1
if (( $+functions[__${service}_zsh_main] ))
then
__${service}_zsh_main
else
emulate ksh -c __${service}_main
fi
let _ret && _default && _ret=0
return _ret
}
Когда вы используете zsh без oh-my-zsh, используйте не псевдонимы, а полную команду git, поскольку псевдонимы не определяются без oh-my-zsh.
Когда я использую полные команды git
С АКТИВНЫМ OMZ, поведение немного отличается от того, что я имел раньше с псевдонимами ... взгляните:
⇒ git checkout <TAB>
64879538_fix_li_elements master origin/master
64908958_center_products_text_in_div next_ror_post origin/next_ror_post
64916916_fix_contact_emails origin/64879538_fix_li_elements origin/oss_contrib_blog_post
64919128_override_fonts origin/64908958_center_products_text_in_div origin/production
65271680_fix_map_resizing origin/64916916_fix_contact_emails origin/sprites
65753620_translate_navigation_bar origin/64919128_override_fonts origin/title-update-final
Раньше при использовании gco <TAB>
в качестве параметров отображались только локальные ветки. В приведенном выше выводе отображаются все ветки на удаленном origin
.
Вот результат, когда я отключил OMZ и запустил те же команды git
:
Matthews-MacBook-Air% git checkout README.md
Procfile Setup.hs circle.yml dist/ node_modules/ stackbuilders.com.cabal
README.md assets/ client_session_key.aes news/ src/ tests/
Кажется, что он сломан, что имеет смысл, поскольку я отключил плагин git
поскольку он включен в моем .zshrc
.
Хорошо, теперь мы знаем, откуда берутся эти _git-checkout_main
. Ваша функция _git()
испорчена, но я не знаю почему. Я предполагаю, что у вас есть setopt completealiases
в вашем .zshrc
. Идите дальше и отключите это, а затем снова запустите which _git
.
Также опубликуйте файл /usr/local/Cellar/zsh/5.0.5/share/zsh/functions/Completion/Unix/_git
по сути
Это с отключенным setopt complete_aliases
:
⇒ which _git
_git () {
# undefined
builtin autoload -XUz
}
Похоже, у меня нет этого пути к файлу - у меня есть до /functions
но не /Completion
и более ... (далее партии опущены):
matthewcampbell@Matthews-MacBook-Air:~|
⇒ vim /usr/local/Cellar/zsh/5.0.5/share/zsh/functions/
VCS_INFO_adjust _dmidecode _matlab _snoop _zpty
VCS_INFO_bydir_detect _domains _md5sum _socket _zsh-mime-handler
VCS_INFO_check_com _dpatch-edit-patch _mdadm _sockstat _zstyle
VCS_INFO_detect_bzr _dpkg _members _softwareupdate _ztodo
VCS_INFO_detect_cdv _dpkg-buildpackage _mencal _sort _zypper
Хорошо, путь к файлу должен быть /usr/local/Cellar/zsh/5.0.5/functions/Completion/Unix/_git
Что касается _git()
, вам нужно попробовать выполнить автозаполнение некоторой команды git перед запуском which _git
Все еще не могу найти этот путь к файлу, брат ... вот Gist с выводом tree
из моего каталога ZSH
: https://gist.github.com/mecampbellsoup/1065d4228b143140ac69
Вот which _git
после запуска функции автозаполнения (в частности, я пробовал ga
, gd
и gc
):
⇒ which _git
_git () {
local _ret=1
local cur cword prev
cur=${words[CURRENT]}
prev=${words[CURRENT-1]}
let cword=CURRENT-1
if (( $+functions[__${service}_zsh_main] ))
then
__${service}_zsh_main
else
emulate ksh -c __${service}_main
fi
let _ret && _default && _ret=0
return _ret
}
Хорошо, теперь я понимаю, как Homebrew устанавливает zsh
, спасибо за tree
gist! Таким образом, ваш файл завершения _git
находится в /usr/local/Cellar/zsh/5.0.5/functions/_git
. Пожалуйста, опубликуйте это.
Я начинаю думать, что это проблема с вашей домашней установкой zsh. Может, стоит удалить его и снова установить заново .. Или спросите ребят из @Homebrew ?
https://gist.github.com/80a00d7af3766c1ad6dc
@mcornella Как вы думаете, это может иметь какое-то отношение к точечным файлам, которые я установил не так давно? Это @holman ... https://github.com/mecampbellsoup/dotfiles/blob/master/zsh/config.zsh
Что ж, вы правильно установили zsh. Кажется, что у вас есть другое место, которое переопределяет ваше завершение git, потому что ваш which _git
и функция _git()
определенная в файле _git
указанном в сути, очень разные.
Как вы думаете, это может иметь какое-то отношение к точечным файлам, которые я установил не так давно?
Может быть, да. В этом файле находится файл завершения, проверьте его для меня, пожалуйста, и спасибо : cat $(brew --prefix)/share/zsh/site-functions/_git
@slhck , это может быть та же проблема, у вас тоже есть точечные файлы @holman?
@mcornella Еще раз https://gist.github.com/mecampbellsoup/fb74f902ccfe9cc5b6c5
Да, виноват этот файл. Определение функции _git ()
находится внизу файла, вы увидите, что оно совпадает с выводом which _git
который вы получаете.
Я не знаю, как тебе теперь действовать. Вы можете переименовать файл, который вы только что указали, чтобы ваш dotfiles
не нашел его, или полностью удалите dotfiles
, или просто удалите dotfiles/git/completion.zsh
из вилки (но тогда у вас будут конфликты слияния при обновлении точечных файлов).
@mcornella Извините, а как вы конкретно объясните такое поведение? Я немного запутался: /
⇒ which _git
_git () {
# undefined
builtin autoload -XUz
}
matthewcampbell@Matthews-MacBook-Air:~/.dotfiles|master⚡
⇒ ga
Nothing specified, nothing added.
Maybe you wanted to say 'git add .'?
matthewcampbell@Matthews-MacBook-Air:~/.dotfiles|master⚡
⇒ which _git
_git () {
local _ret=1
local cur cword prev
cur=${words[CURRENT]}
prev=${words[CURRENT-1]}
let cword=CURRENT-1
if (( $+functions[__${service}_zsh_main] ))
then
__${service}_zsh_main
else
emulate ksh -c __${service}_main
fi
let _ret && _default && _ret=0
return _ret
}
Под _это поведение_ вы имеете в виду разный вывод обоих which _git
? Если да, то это потому, что завершение _autoloaded_, как вы видите в первом which _git
. Это означает, что определение загружается только при первой необходимости, поэтому в первый раз, когда вы запрашиваете завершение команды git, это когда функция _git
загружает определение.
И правильное поведение, вероятно, в какой-то момент будет перезаписано, вероятно, чем-то в моем config.zsh
?
Да, файл, который загружает старое завершение, и есть этот файл в ваших точечных файлах . Если вы удалите его, вы получите правильное завершение.
Это очень похоже на brew install hub
. Взгляните на этот комментарий и на этот выпуск: # 1727.
Следуя совету по последнему, это исправит.
@slhck, вы найдете свое исправление в этом комментарии: https://github.com/robbyrussell/oh-my-zsh/issues/2800#issuecomment -43694975
@mcornella Извините за поздний ответ. У меня не было доступа к машине, обнаружившей проблему.
Бег
brew uninstall --force git && brew install git --without-completions
действительно решил проблему.
Большое спасибо за ваше расследование.
Проблема здесь в том, что официальное завершение Git не было подготовлено для 'complete_aliases', я внес исправление:
https://github.com/felipec/git/commit/aaafa76
Таким образом, вы можете вручную определить завершение с помощью:
compdef _git gco=git_checkout
Однако, если вы хотите использовать формат zsh: gco=git-checkout
и чтобы он работал в распространяемой в настоящее время версии Git, вы можете сделать это:
alias __git-checkout_main=_git_checkout
найдите .zshrc и удалите комментарий
псевдоним zshconfig = "st ~ / .zshrc"
псевдоним gco = "git checkout"
Может ли кто-нибудь помочь мне отладить, почему у меня возникает эта проблема? Это происходит с установленным complete_aliases
и без него. Кроме того, удаление файлов .zcompdump*
не исправляет. Мои плагины просто установлены на plugins=(git gitfast)
, однако я получаю эти проблемы с завершением функций (что расстраивает, потому что в идеале я бы использовал свою собственную настроенную функцию gco
вместо gco
плагина git.
ggl _git:12: command not found: __git-checkout_main
gdv _git:12: command not found: __git-diff_main
Я использую Powerlevel10k на oh-my-zsh 173d4ca68f1ff4b04e9f3fd783244c309d848092, с zsh 5.8 (x86_64-apple-darwin19.3.0) и git версии 2.26.1. К сожалению, brew uninstall --force git && brew install git --without-completions
больше не подходит для git.
Вот мое определение _git
.
❯ which _git
_git () {
local _ret=1
local cur cword prev
cur=${words[CURRENT]}
prev=${words[CURRENT-1]}
let cword=CURRENT-1
if (( $+functions[__${service}_zsh_main] ))
then
__${service}_zsh_main
else
emulate ksh -c __${service}_main
fi
let _ret && _default && _ret=0
return _ret
}
@jessrosenfield Это потому, что вам не хватает патча. Я не уверен, что вы используете последнюю версию ohmyzsh, но было некоторое несоответствие, и мой патч был отменен:
@felipec Я обновился, но все еще не работает (моя текущая проблема № 9018 немного отличается)
Самый полезный комментарий
Проблема здесь в том, что официальное завершение Git не было подготовлено для 'complete_aliases', я внес исправление:
https://github.com/felipec/git/commit/aaafa76
Таким образом, вы можете вручную определить завершение с помощью:
Однако, если вы хотите использовать формат zsh:
gco=git-checkout
и чтобы он работал в распространяемой в настоящее время версии Git, вы можете сделать это: