🎼

よく使うディレクトリやGitHubのリポジトリに素早く移動する

に公開

Zshで、私が日頃から便利に使っている設定があるので紹介させてもらいます。

ターミナル上でディレクトリを移動する場合の基本はcdコマンドかと思いますが、よく使うディレクトリやソースコードが置いてあるディレクトリには素早く移動したいですよね。私はできるだけ簡単に移動できるように、特定のキーバインドを押すと「よく使うディレクトリの一覧」が出てきて、絞り込み検索して移動ができるようにしています。

大前提:fzfで絞り込みできるようにする

以下の設定を進めるにあたって、大前提として何らかのFuzzy Finder系のコマンドが必要です。Fuzzy Finderは、曖昧検索をするためのツールで、たくさんある候補の中から文字列の一部を入力するだけで簡単高速に絞り込みをしてくれます。macOSにあるSpotlightでファイル検索するときと同じイメージでしょうか。今回のように移動先の候補を絞り込む用途には相当便利です。

Fuzzy Finderは種類が色々あるのでお好みのもので良いと思います。私は長いことfzfというのを使っています。Homebrewならbrew install fzfでインストールできます。

https://github.com/junegunn/fzf/

今回の記事ではcdコマンドを便利にする設定について書いてますけど、fzfを活用するとコマンドの入力履歴の検索や、gitのブランチ切り替えなんかにも使えてすこぶる便利です。

よく使うディレクトリに移動する

私はターミナル上で、Ctrl-g + Ctrl-fを押すと、最近移動したディレクトリの一覧が表示され、絞り込みをして移動できるようにしています。大変便利でめちゃくちゃ多用しています。


候補の一覧が表示されている様子

zでよく使うディレクトリを記録する

よく使うディレクトリの一覧を表示するためには、よく使うディレクトリを保存しておく必要があります。私はzを使ってます。

https://github.com/rupa/z

zを使うとディレクトリの移動履歴が管理できるようになります。インストールはHomebrewならbrew install z。そして.zshrcに以下の設定を追加したら準備完了です。

.zshrc
. `brew --prefix`/etc/profile.d/z.sh

.zshrcに設定をする

zが使えるようになったら、以下の設定を.zshrcに追加します。

.zshrc
function fzf-cdr() {
    local selected_dir=$(z -tl | cut -c 12- | fzf --prompt="Dir> " --tac)
    if [ -n "$selected_dir" ]; then
        BUFFER="cd ${selected_dir}"
        zle accept-line
        zle clear-screen
     else
        zle redisplay
    fi
}

zle -N fzf-cdr

bindkey '^g^f' fzf-cdr

これで、Ctrl-g + Ctrl-fを押すと、最近移動したディレクトリの一覧が表示され、適当に文字列を入力すると絞り込みが行われ、Enterで確定して移動します。

GitHubのリポジトリに移動する

zを使えば十分なんですけど、GitHubのリポジトリに絞って移動したい場合もあると思います。特に会社の環境だとリポジトリがすごい多いので、できるだけ簡単に移動したいです。

ghqでリポジトリを管理する

リポジトリのチェックアウトにはghqを使います。ghqはソースコードリポジトリを管理するためのツールで、ディレクトリ構成が強制されるため、ファイルがあちこちに散らばらなくなるのでおすすめです。

https://github.com/x-motemen/ghq

例えばghq get -p x-motemen/ghqというようにghqのリポジトリをチェックアウトすると、~/ghq/github.com/x-motemen/ghqにリポジトリがチェックアウトされます。

.zshrcに設定をする

以下のように.zshrcに設定を追加すると、cdghqというコマンドで、ローカルにチェックアウトしているリポジトリから絞り込み検索して移動できます。

.zshrc
function cdghq() {
    moveto=$(ghq root)/$(ghq list | fzf)

    if [[ "${moveto}" != "$(ghq root)/" ]]
    then
       cd $moveto
    fi
}

こんな感じで一覧が出てくるので、適当に目的のリポジトリ名を入力して絞り込み、Enterで確定するとそのリポジトリのルートに移動します。

gitのWorktreeを選択して移動する

最近gwqというツールを使い始めました。これは、gitのWorktreeを管理できるツールで、Worktreeを作ったり消したりが簡単にできます。ghqと似た名前なのはコンセプトを踏襲しているかららしいです。

https://github.com/d-kuro/gwq

gwqはFuzzy Finderとも統合しているので、特別な設定をしないでも曖昧検索で移動できます。

cd $(gwq get)

ただ、残念ながら私が用意してる他のコマンドとプレビュー表示の統一感が出せなかったので、工夫してカスタムしています。

.zshrcに設定をする

というわけで、gitにあるWorktreeの一覧から選択してディレクトリを移動できるようにするための独自設定を.zshrcに追加します。cdgwqというコマンドです!(全部左手での打鍵だ)なお、JSONをパースするために、jqコマンドを併用しています。

.zshrc
function cdgwq() {
   # git 内かどうかをチェック
   if ! git rev-parse --is-inside-work-tree &>/dev/null; then
      echo "Not inside a git repository."
      return 1
   fi
   moveto=$(gwq list --json | jq -r '.[].path' | fzf)
   cd $moveto
}

もう一つ、最も新しいWorktreeに移動するためのcdwというコマンドも用意しています。gwqの場合、Worktreeの追加とディレクトリの移動を一緒に実行するコマンドがないので、gwq add -b issues/4-api && cdwのようにしてWorktreeを追加してからすぐにWorktreeの中に移動できるようにしています。

.zshrc
function cdw() {
   # git 内かどうかをチェック
   if ! git rev-parse --is-inside-work-tree &>/dev/null; then
      echo "Not inside a git repository."
      return 1
   fi

   moveto=$(gwq list --json | jq -r 'max_by(.created_at) | .path')
   if [ -z "$moveto" ]; then
      echo "No recent gwq found."
      return 1
   fi
   cd $moveto
}

最後に:bindkeyかコマンドか

私はこんな風に設定して使ってますという紹介でした。愚直にcdコマンドを使うと、プロジェクト間のディレクトリ移動は結構面倒だと思うので、何らか手に馴染む方法を見つけたいですね!

ところで、私はzコマンドを使ったディレクトリの移動は、bindkeyを使ってCtrl-g + Ctrl-fで呼び出すようにしています。ghq, gwqの方は、前者と比べて利用頻度は低くなるのでコマンドで呼び出すようにしています。これは単に好みでしかないので、fzf-cdrcdghqの中身を見ながら適当にカスタマイズしてもらえればと思います。良い設定ができたらぜひ教えてください!

ARMテックブログ

Discussion