gitのZSH完成は自動的に絶対パスを完成しませんか?

gitのZSH完成は自動的に絶対パスを完成しませんか?

/.git私のファイルシステムのルートであるgitリポジトリがあります。

私が入って/etc/foo/実行すると、git statusgitはファイルが../fstab変更されたことを知らせます。

zshコマンド補完(まだ/etc/foo/にあります)を使用したい場合は、次のgitようになります。

git diff ../fs<TAB>

これはうまくいきます。しかし、絶対パスを使用すると、次のようになります。

git diff /etc/fs<TAB>

これによりzsh絶対パスが不完全になります。

zsh完全な絶対パスと相対パスをどのように知ることができますか?

私はDebian Busterのバージョンを使用していますzsh5.7.1-1

答え1

ZSH完了:

Zshコンプリートは/usr/share/zsh/5.5/functions/Completion/Unix通常(デプロイメントによって異なる場合があります)にあるスクリプトを使用して実行されます。各コマンド補完のスクリプトには名前が付けられ、ZshにはVariablesに似た_commandName環境変数が含まれています。この場合、スクリプトはYes、Zshのため、場所の順序が重要です。見つかった最初のスクリプトを使用し、他のスクリプトがある場合は無視します(同様)。$fpath$PATH_git$fpath_git$PATH

スクリプト:

これで説明されているように品質保証そして例えば次の関数は、ファイルの一般的な完成関数$PWD/に渡す前に相対パスに追加します。_files

_absolute_files () {
  local expansion=$PREFIX$SUFFIX; expansion=${(e)expansion}
  if [[ "${expansion%%/#}" != "${expansion:a}" ]]; then
    PREFIX="\$PWD/$PREFIX"
  fi
  _files "$@";
}

~/これは、絶対などで始まるパス識別を含む多くの一般的なケースで機能します。

解決策:

デフォルトgitの完了アクションには相対パスは含まれません。スクリプトを編集し、上記と同様の機能を追加することで、相対パスのサポートを追加できます。またはgit基本的な完成を次の完成プラグインに簡単に変更できます。gitfastオメジッシュ次の手順を実行します。

クローンオメジッシュ特定の場所(例/location:)で:

git clone https://github.com/ohmyzsh/ohmyzsh.git

~/.zshrc設定ファイルの一番下に次を編集して追加しますgitfast

fpath=( /location/ohmyzsh/plugins/gitfast $fpath ) 

前に説明したように、順序が重要ですここ

~/.zcompdump*実行中のエントリを削除して完了キャッシュを更新しますcompinit

代替ソリューション:

関数に次のパッチを適用して/usr/share/zsh/5.5/functions/Completion/Unix/_git編集します。_git-diff

--- _git
+++ _git
@@ -766,6 +766,12 @@

   case $state in
     (from-to-file)
+  
+      if [[ $line[1] == *\/* ]]; then
+        _alternative 'files::_files' && ret=0
+        return ret
+      fi
+      
       # If "--" is part of $opt_args, this means it was specified before any
       # $words arguments. This means that no heads are specified in front, so
       # we need to complete *changed* files only.

答え2

Zshは絶対パスを非常にうまく実行します。一度試してみてくださいls /etc/fsTab

問題は_git使用している完成機です。 (以下の脚注を参照してください。)

次のようにテストできます。

  1. 初期化したことを確認してくださいcompinit
autoload -Uz compinit && compinit
  1. git diff(最後にスペースがあります)を入力しCtrlXて文字を押しますH

次の結果が表示されます。

tags in context :completion::complete:git-diff::
    argument-rest options  (_arguments _git-diff _git)
tags in context :completion::complete:git-diff:argument-rest:
    commit-ranges blobs-and-trees-in-treeish files blobs  (_git-diff _git) 
    heads commit-tags commit-objects                      (__git_commits __git_commit_ranges _git-diff _git) 
    heads-local heads-remote                              (__git_heads __git_commits __git_commit_ranges _git-diff _git) 
    messages                                              (_message __git_command_successful __git_heads_local __git_heads __git_commits __git_commit_ranges _git-diff _git) 
    heads-local                                           (__git_describe_branch __git_describe_commit __git_heads_local __git_heads __git_commits __git_commit_ranges _git-diff _git) 
    heads-remote                                          (__git_describe_branch __git_describe_commit __git_heads_remote __git_heads __git_commits __git_commit_ranges _git-diff _git) 
    messages                                              (_message __git_command_successful __git_tags_of_type __git_commit_tags __git_commits __git_commit_ranges _git-diff _git) 
    messages                                              (_message __git_command_successful __git_recent_commits __git_commit_objects_prefer_recent __git_commits __git_commit_ranges _git-diff _git) 
    changed-in-working-tree-files                         (__git_changed-in-working-tree_files _git-diff _git) 
    blob-tags blob-objects                                (__git_blobs _git-diff _git) 
    messages                                              (_message __git_command_successful __git_tags_of_type __git_blob_tags __git_blobs _git-diff _git)
tags in context :completion::complete:git::
    argument-rest  (_arguments _git)

これが起こるので注意してくださいいいえfiles、または(directories入力時に表示され、その後に+がglobbed-files表示されます)が含まれます。それが含むのは、彼らが作られたということです(ご覧のようにlsCtrlXHchanged-in-working-tree-filesgit diff -z --name-only --no-colorここ) - 絶対パスではなく、ストレージルートへの相対パスを生成します。

gitしたがって、絶対パスには実行する情報がないため、コンテキストでは完了しません。


脚注:Zsh独自の_git完成プログラムを使用していますか、それともGitがインストールした可能性がある完成プログラムを使用していますか?私は強くお勧めしますいいえGitがインストールされているバージョンを使用していますが、Zsh標準に従って正しく実装されていないため、いくつかの部分にバグがたくさんあります。 (GitのBash Completeプログラムは自動的に移植されたようですが、バグがあります。)fpathZshインストールの一部ではない名前の完成ファイルがあることを確認して削除します。_git

関連情報