よく使うディレクトリ+αへの移動を便利にするzoxide拡張術

by
カテゴリ:
タグ:

zoxideはシェルでのディレクトリ移動の傾向を学習して、よく使うディレクトリへの移動を楽にするツールです。

https://github.com/ajeetdsouza/zoxide

しかし、行ったことのないディレクトリは候補に出ない。

そこで、使ったことないGitリポジトリへを移動先候補に加える方法として、よく使うディレクトリ+αへの移動を便利にするzoxideとghqの組み合わせという記事を書きました。

今回、もっと筋の良さそうな方法を思いついたので共有します。

Fishを例にしますが、AIを使えばBash版なりZsh版なりも簡単に作れるはず。

zoxide init --no-cmd fish | source # __zoxide_cd を定義させる

function zi
  begin
    # 利用頻度の高い移動先一覧
    zoxide query --list

    # 使いたくなるかもしれない移動先一覧
    ghq list -p
  end \
      | perl -ne 'print unless $seen{$_}++' \
      | fzf --layout=reverse --no-sort --height=~15 --query="$argv" \
      | read -l result
  and __zoxide_cd $result
end

使いたくなるかもしれない移動先一覧として、ghqコマンドで管理しているGitリポジトリ一覧を追加していますが、他にも色んな候補が考えられるかと思います!

これらもそのまま行を足せばいいだけなので非常に拡張しやすいですね。

   begin
     # 利用頻度の高い移動先一覧
     zoxide query --list
 
     # 使いたくなるかもしれない移動先一覧
     ghq list -p
+    find "$HOME" -maxdepth 2 -type d
+    find "$HOME/.local/share/nvim/lazy" -maxdepth 1 -type d
   end \

実装の解説

やっていることは、わりかし単純です。

  1. 移動先候補を用意する
    • beginendの部分
    • zoxide query --listすると、移動したことある場所がよく使う順に一覧される
    • これとghq list -pで出したリポジトリ一覧や、お好みでfindなどで出した移動先候補を合体させる
    • ポイントとしてbeginendを使って標準出力を合成すると、各コマンドの終了を待たずに後続のperlなどのコマンドが動き出すので、一覧完成を待たずに選択を開始できる
  2. 移動先候補の重複を除く
    • perl -ne 'print unless $seen{$_}++'の部分
    • awkでもいいですが、GNU版かどうか気にせず済むperlが好みです
  3. fzfを使ってユーザー入力による移動先絞り込みを行う
    • ここはzoxideの挙動に倣って--no-sortしておくと、よく使うものが上の方に来て便利です
    • その他のオプションは自由に弄ってください
  4. 結果をresult変数に入れる
  5. resultに移動し、次回以降の推薦スコアを更新する
    • zoxideが提供する__zoxide_cd関数を使うと一発です
    • __zoxide_cdzoxide init fish | source などで発生します

過去の記事でやっていた方法もそこまで複雑ではないです。しかし、移動候補の作成までに差分計算などが発生してパフォーマンスの課題がありました。

  1. zoxide未管理な移動先候補を用意する
  2. 1とzoxide管理済みの候補の差分を取得する
  3. 差分をzoxide addで管理済み候補にする
  4. __zoxide_ziを利用する

ENJOY

dotfilesのリファクタ気持ちいいぞー!