Проблема

Проблема

Проблема

У меня есть следующее

git reset HEAD^ half_entered_file_n<Tab>

На этом этапе я бы хотел, чтобы half_entered_file_name.txt был дополнен клавишей Tab.

Мое собственное расследование

Я могу заставить работать автодополнение Tab, если я напишу

git reset HEAD\^ ...

вместо этого экранируем «^».

Написание «^» в качестве последнего символа, похоже, не влияет на автозаполнение, если только не присутствует HEAD:

#autocomplete works
git reset RANDOM^ half_entered_file_n<Tab> #works

Конфигурация Zsh

Я использую Oh-my-zsh. Поверх oh-my-zsh я настроил следующее, что может быть важно:

# Let <TAB> auto completion add a slash at the end instead of space (like BASH)
zstyle ':completion:*' special-dirs true 

# Unless this option is set, you can't write git checkout HEAD^^ without escaping ^ as \^ in zsh
setopt NO_NOMATCH 

# Standard git plugins
plugins=(git git-extras)

Для полноты картины,вот моя конфигурация

Я запускаю это на OSX в iTerm2.

Спасибо!

Обновлять

Я нашел несколько полурешений, но ни одно из них пока не приводит к статусу «решено», что по сути делает их нерешенными.

  1. установить compdef -d gitв .zshrcкак предложил "пещерный человек"
    • Решено: Теперь HEAD^ больше не нарушает автодополнение файлов.
    • Недостаток: автодополнение команд git больше не работает.
  2. Использоватьпринятый ответ от "ralphtheninja" на этот вопрос
    • Решает: Следует заменить способ формирования списка завершения файлов, что решит проблему.
    • Недостаток: Не работает. Похоже, git-completion.zsh/.bash изменил синтаксис.

Я недостаточно хорошо знаю скриптинг оболочки, чтобы точно понять, что происходит в git-completion.zsh/.bash, и является ли это причиной сбоев.

решение1

Почему не стоит предполагать,

Долгое время я предполагал, что автодополнение git в моей конфигурации zsh исходит из /usr/local/share/git-core/contrib/completion/, а именно из git-completion.zshили даже git-completion.bash. Думаю, я предполагал это, потому что большинство поисков дадут результаты, говорящие об этих файлах. Однако я явно не включал ни один из этих файлов и долгое время я просто предполагал, что oh-my-zsh их включает.

Но...

Мы больше не в Канзасе.

Только когда я использовал трассировку методов zsh, включенную через setopt xtrace, я понял (погуглив некоторые названия методов), что используемый скрипт на самом деле был /usr/local/share/zsh/functions/_git. Ранее я использовалXCode Instruments.приложениедля отслеживания того, к каким скриптам осуществляется доступ в файловой системе, но тогда я в этом не разобрался (вывод довольно болтливый и показывает также доступы из других приложений).

Что происходит?

Следы показали это (частичные следы впереди!)

git reset HEAD <TAB>
...
+__git_tree_files:17> tree=HEAD
+__git_tree_files:18> tree_files+=+__git_tree_files:18> _call_program tree-files git ls-tree --name-only -z HEAD ./
+__git_tree_files:18> tree_files+=( first second third )

И

git reset HEAD^ <TAB>
...
+__git_tree_files:17> tree=HEAD^
+__git_tree_files:18> tree_files+=+__git_tree_files:18> _call_program tree-files git ls-tree --name-only -z 'HEAD^' ./
+__git_tree_files:18> tree_files+=( )

Эта пустота tree_filesвыглядит подозрительно.

В строке 6058 /usr/local/share/zsh/functions/_gitмы находим

tree_files+=(${(ps:\0:)"$(_call_program tree-files git ls-tree $extra_args --name-only -z $tree $Path 2>/dev/null)"})

Нам определенно нужно экранировать эту $treeпеременную. Сказано и сделано:

tree_files+=(${(ps:\0:)"$(_call_program tree-files git ls-tree $extra_args --name-only -z ${(q)tree} $Path 2>/dev/null)"}) 

Эпилог

В этом скрипте есть еще несколько ошибок (например, список файлов для git reset <tree-ish>основан на <tree-ish>, хотя он должен быть основан на HEAD). Теперь я знаю, где их исправить!

Обновлять

Также существует возможность запуска скриптов завершения из git.Вы можете сделать это, следуя этому ответу.

Связанный контент