問題

問題

問題

私は次のものを持っています

git reset HEAD^ half_entered_file_n<Tab>

この時点で、half_entered_file_name.txt を 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

なぜ思い込みをしてはいけないのか

長い間、私は自分の zsh 設定の git 補完が/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 楽器.appファイルシステム上でどのスクリプトがアクセスされているかを監視しようとしましたが、その時はわかりませんでした (出力は非常に冗長で、他のアプリからのアクセスも表示されます)。

どうしたの?

痕跡はこれを示していました(部分的な痕跡は後ほど!)

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 から補完スクリプトを実行することもできます。この回答に従うことでそれができます

関連情報