(´ワ`)

主に技術系備忘録、たまに日記。

(この記事は内容がもう古いです) zinitでgit switchのcompletion(補完)を取り入れる + α

追記

この内容はおそらく情報が古いです。最新のZshを利用している場合、標準でgitのcompletionを利用できます。

github.com

zinitがリリースされた頃から、「何やら早いらしい」ということだけでとりあえずexampleを見様見真似でコピペして使っていた。 zplug を使用していた頃に比べればこれだけでも大分早かったので特に何も触らず放置していたが・・・
その後、 git の新バージョンより、 git switch が出始めた。
現在のzshの補完では switch が対応していないことに不便さを感じたのでどうにか出来ないか調べたところ、gitの公式リポジトリからcompletionを取ってくる必要があったらしい。ので、それをzinitで取り込むために改めてドキュメントを見つつ、gitの件以外にも改善してメリットを感じた部分があったのでそのメモ。

gitの公式リポジトリからcompletionだけ取る

gitの公式リポジトリ内のcompletionファイルがある位置はここ

github.com

zinitでは単一ファイルを取り込むことが出来る。

zinit wait lucid as"completion" atload"zicompinit; zicdreplay" "https://github.com/git/git/blob/master/contrib/completion/git-completion.zsh"

一応引数の説明も。

  • wait : sleep時間。秒数を指定できるが指定しないことでターボモード(バックグラウンドロード)にできる。参考: http://zdharma.org/zinit/wiki/INTRODUCTION/#turbo_mode_zsh_53
  • lucid : ロードメッセージを表示しない
  • as : "plugin" は実行用のコマンドとして使用、"completion"は補完用として使用
  • atload : ロード時をイベントハンドラに実行するコマンド。今回の場合、zicompinit; zicdreplay を実行する。
    • zicompinit: autoload compinit; compinit
    • zicdreplay: atinit'zicompinit; zicdreplay'

ただこの場合、 git-completion.zsh で読み込まれるため、 _git に名前を変更する

zinit wait lucid as"completion" atload"zicompinit; zicdreplay" mv"git-completion.zsh -> _git" "https://github.com/git/git/blob/master/contrib/completion/git-completion.zsh"

mv : "<base> -> <renamed>" のように、 -> を挟むようにインストール後の名前を変更できる

git まで打ってtab押してswitchが出ればできてるはず。

追記(2021-02-02)

git-completion.zsh を使用する場合、 git-completion.bash もインストールする必要があった。最終的には以下のようになる。

zinit wait silent lucid atclone"zstyle ':completion:*:*:git:*' script git-completion.bash" atpull"%atclone" for \
  "https://github.com/git/git/blob/master/contrib/completion/git-completion.bash"
zinit wait lucid as"completion" atload"zicompinit; zicdreplay" mv"git-completion.zsh -> _git" for \
  "https://github.com/git/git/blob/master/contrib/completion/git-completion.zsh"

単純に git-completion.bash を取ってきて、ファイルの先頭コメントにある通りにしたがってpull時にコマンド実行させるだけ。 ただこのままだと git-completion.bash は廃止された旨が毎度出力されるため、 silent を使うことで出力を出さないようにすることができる。

【おまけ】github releaseページからバイナリファイルを直接インストールする

表題の通りのことが出来るとは思わなかった。
よく fzfripgrep を使うのでこれらをインストール。まずは fzf

zinit wait lucid from"gh-r" as"program" for \
  "junegunn/fzf"

gitのときと同様にターボモードで入れるまでは同じ。少し違う点は↓

  • from : どこのサイトからクローン(ダウンロード)するか指定できる。今回は gh-r を指定することでGithub Releaseからクローンできる。
  • for : 前述の引数を使いまわしてインストールできる

ripgrep の場合、ダウンロードされたパッケージの階層が少し複雑なので少し手を加える必要がある。

ripgrep のダウンロードされたパッケージは以下のようになっている。(最新の12.1.1の場合)

ripgrep-12.1.1-x86_64-apple-darwin.tar.gz
├── complete
│  ├── _rg
│  ├── _rg.ps1
│  ├── rg.bash
│  └── rg.fish
├── COPYING
├── doc
│  ├── CHANGELOG.md
│  ├── FAQ.md
│  ├── GUIDE.md
│  └── rg.1
├── LICENSE-MIT
├── README.md
├── rg
└── UNLICENSE

これを踏まえて以下のようになる

zinit wait lucid from"gh-r" mv"ripgrep* -> ripgrep" for \
  as"program" pick"ripgrep/rg" "BurntSushi/ripgrep" \
  as"completion" pick"ripgrep/complete/_rg" atload"zicompinit; zicdreplay" "BurntSushi/ripgrep"
  • pick : ディレクトリ内のどのプログラムを使用するか指定する。

ディレクトリ階層の通り、ダウンロードするパッケージ名は常にバージョン名で変わるため

  1. mv で一意のディレクトリ名に変更する
  2. pick で使用するプログラムを指定する

といった流れでインストールできる。

まとめ・感想

zinitはgithub releasesページからバイナリファイルも直接インストールできる。
Ubuntuとかだとlatestバージョンのパッケージを取得したい場合、自分でリポジトリを取得するように設定したりしないといけなかったりして面倒だったのでzsh依存でこれだけのことをセットアップできるのは非常に良い