ghq fzf ezaでローカルリポジトリを楽しく管理する方法

スマートコンテンツ事業部で開発を担当している兒玉です。
アドベントカレンダー9日目ということで「ghq fzf ezaでローカルリポジトリを楽しく管理する方法」を紹介します。

この記事の対象者

  • ローカルでのリポジトリ管理に悩んでいる人
  • 作業のたびにローカルリポジトリを探している人
  • ターミナルをもっと使えるようになりたい人
  • zshを使用している人 (他でも可能ですが、今回はzshのみの紹介になります)

コピペで設定できるようにしてあるので、取り掛かりやすいかと思います。
ぜひ挑戦してみてください。 完成系はこんな感じです。
ローカルリポジトリを一箇所で管理し、ターミナル上でcontrol(^) + fを使って検索移動できます。

それでは早速始めていきましょう!

Git管理とディレクトリ移動

実施リスト

  • ghq fzf ezaのインストール
  • フォントとアイコン設定
  • zshの設定
    • ①ezaの設定
    • ②ghq fzf eza 組み合わせ
    • ③cd + ls の設定 (cdの後にlsしたい)
    • ④ターミナル起動時にディレクトリ移動をしたい

ghq fzf ezaのインストール

■参考リンク
https://github.com/x-motemen/ghq
https://github.com/junegunn/fzf
https://github.com/eza-community/eza

  1. 各toolのインストール
  2. ghqで管理するrootディレクトリを設定(この記事では~/srcとする)
  3. ezaコマンドの確認
brew install ghq fzf eza
mkdir -p ~/src
git config --global ghq.root '~/src'
eza -l -g --icons

ezaコマンド確認をするとアイコンが?になっているのが確認できると思います。 このアイコンを表示するには「アイコンを含んだフォント」のインストールが必要になります。

フォントとアイコン設定

https://github.com/ryanoasis/nerd-fonts

アイコン表示とフォントにも拘りたいので、みんな大好きNerdFontをインストールしたいと思います! この辺りは各自好きなものをご使用ください。

brew install --cask font-jetbrains-mono-nerd-font

ターミナル上でのフォント設定 [ターミナル]→[設定]→[フォント]からJetBrainsMono Nerd Font Monoへ変更

フォント設定完了後、ターミナルを開き直すとアイコンが表示されます。
*ターミナル(vscodeやiTerm2)ごとに表示用のフォント設定が必要なので注意してください。

ここからは、zshの設定

①ezaの設定

■前提条件

  • デフォルトシェルでzshを使用している
  • ezaがインストールされている

ezaをlsの代用として使用する設定

ここからの設定は~/.zshrcに追記していきます。 vscodeがインストール済みならcode ~/.zshrcのコマンドでvscodeが立ち上がり編集できます。

# エイリアス設定
# ezaがインストールされている場合のみ有効化
if [[ $(command -v eza) ]]; then
  alias e='eza --icons --git'
  alias l=e
  alias ls=e
  alias ea='eza -a --icons --git'
  alias la=ea
  alias ee='eza -aahl --icons --git'
  alias ll=ee
  alias et='eza -T -L 3 -a -I "node_modules|.git|.cache" --icons'
  alias lt=et
  alias eta='eza -T -a -I "node_modules|.git|.cache" --color=always --icons | less -r'
  alias lta=eta
  alias l='clear && ls'
fi

■以下解説 (簡易解説になります)

alias et='eza -T -L 3 -a -I "node_modules|.git|.cache" --icons'
alias lt=et
alias eta='eza -T -a -I "node_modules|.git|.cache" --color=always --icons | less -r'
alias lta=eta

上記2つは、node_modules.git.cacheのフォルダーを除いた結果を表示してくれます。

②ghq fzf eza 組み合わせ

■前提条件

  • デフォルトシェルでzshを使用している
  • ghq fzf ezaがインストールされている

control(^) + fでローカルリポジトリを選択し移動できるように、関数とそれをキーバインドさせる設定を~/.zshrcに追記

function ghq-fzf_change_directory() {
    # 選択したリポジトリへ移動 かつ
    # 右にリポジトリのディレクトリ詳細を表示
  local src=$(ghq list | fzf --preview "eza -l -g -a --icons $(ghq root)/{} | tail -n+4 | awk '{print \$6\"/\"\$8\" \"\$9 \" \" \$10}'")
  if [ -n "$src" ]; then
    BUFFER="cd $(ghq root)/$src"
    zle accept-line
  fi
  zle -R -c
}

zle -N ghq-fzf_change_directory
bindkey '^f' ghq-fzf_change_directory

■以下解説

local src=$(
  ghq list | 
  fzf --preview "
    eza -l -g -a --icons $(ghq root)/{} | 
    tail -n+4 | 
    awk '{print \$6\"/\"\$8\" \"\$9 \" \" \$10}'"
)
  • ghqコマンドを使って、管理しているリポジトリのリストを取得
  • fzfの--previewオプションを使って、選択したリポジトリの詳細を右側に表示
    • ezaコマンドを使って、選択したリポジトリの詳細を表示
    • tail -n+4は、出力の最初の3行をスキップする
    • awkでリポジトリのパスや情報を整形

原型: eza -l -g -a --icons | tail -n+4 | awk '{print $6 "/" $8, $9, $10}' シェルに埋め込む場合はエスケープを実施

■どういうふうに情報が整形されているか確認してみましょう。
例: ghq fzf ezaのリポジトリで確認します。

ghq get https://github.com/x-motemen/ghq https://github.com/junegunn/fzf https://github.com/eza-community/eza
cd ~/src/github.com/eza-community/eza
eza -l -g -a --icons
eza -l -g -a --icons | tail -n+4 | awk '{print $6 "/" $8, $9, $10}'

設定が全て完了するとcontrol(^)+fで検索画面↓が開きます。

if [ -n "$src" ]; then
  BUFFER="cd $(ghq root)/$src"
  zle accept-line
fi

こちらは、リポジトリが選択された場合に実行される条件文で、

  • BUFFER変数へ選択したリポジトリのディレクトリに移動するコマンドを設定
  • zshのラインエディタ(ZLE)に対して、現在のコマンドを実行するように指示

これにより、cdコマンドが実行され、選択したリポジトリのディレクトリに移動できます。

zle -R -c

最後に、zshのラインエディタをリフレッシュ

■参考 ZLEについてはクラスメソッドさんの記事が大変参考になります。

dev.classmethod.jp

③cd + ls の設定 (cdの後にlsしたい)

参考:cdした後にlsするのはzshにやらせよう
カレントディレクトリが変更されたときに発火するchpwdを使用

# hook  cd+ls
chpwd() {
    if [[ $(pwd) != $HOME ]]; then;
        ls
    fi
}

④ターミナル起動時にディレクトリ移動をしたい

ターミナル起動時にディレクトリ移動コマンドを実行させる

# zsh起動時の処理
## VSCodeのターミナルを使っていない、かつ、
## ターミナルでHomeディレクトリ展開時はcdコマンドを実行
if [ "$TERM_PROGRAM" != "vscode" ] && [ "$PWD" = "$HOME" ] ; then
  cd ~/src
fi
## eza(lsの代わり)コマンドの実行
if [[ $(command -v eza) ]]; then;
 eza --icons --git
fi

ターミナル情報は、echo $TERM_PROGRAMで取得できます。
ターミナルによってはディレクトリ移動を有効化したくない場合もあるので、ここで条件を追加してみてください。

最後に設定を反映させましょう。 ターミナルの開き直しか、以下のコマンドで反映ができます。

# 読み込み(設定反映)
source ~/.zshrc

最後に

これだけでもかなり便利ですが、さらにプロンプトをカスタマイズするStarShipというtoolがあります。

https://starship.rs/ja-JP/

電池残量やメモリー使用量などパッと把握したいものをプロンプトに表示できるようになります。今回詳細は含めませんが是非触ってみてください。

brew install starship

# 有効にするため.zshrcへ追記
echo 'eval "$(starship init zsh)"' >> ~/.zshrc

ここまでのドットファイルを置いておくので自分好みに設定してみてください!
また別日にお会いしましょう!

# '~/.zshrc'に記載
# starship起動に必要
eval "$(starship init zsh)"

# zsh起動時の処理
## VSCodeのターミナルを使っていない、かつ、
## ターミナル起動時にHomeディレクトリの場合はcdコマンドを実行
if [ "$TERM_PROGRAM" != "vscode" ] && [ "$PWD" = "$HOME" ] ; then
  cd ~/src
fi
## eza(lsの代わり)コマンドの実行
if [[ $(command -v eza) ]]; then;
 eza --icons --git
fi

# hook # cd+ls
chpwd() {
    if [[ $(pwd) != $HOME ]]; then;
        ls
    fi
}

# エイリアス設定
# ezaがインストールされている場合のみ有効化
if [[ $(command -v eza) ]]; then
  alias e='eza --icons --git'
  alias l=e
  alias ls=e
  alias ea='eza -a --icons --git'
  alias la=ea
  alias ee='eza -aahl --icons --git'
  alias ll=ee
  alias et='eza -T -L 3 -a -I "node_modules|.git|.cache" --icons'
  alias lt=et
  alias eta='eza -T -a -I "node_modules|.git|.cache" --color=always --icons | less -r'
  alias lta=eta
  alias l='clear && ls'
fi

# func
## ghq fzf eza 組み合わせ
function ghq-fzf_change_directory() {
    # 選択したリポジトリへ移動 かつ
    # 右にリポジトリのディレクトリ詳細を表示
  local src=$(ghq list | fzf --preview "eza -l -g -a --icons $(ghq root)/{} | tail -n+4 | awk '{print \$6\"/\"\$8\" \"\$9 \" \" \$10}'")
  if [ -n "$src" ]; then
    BUFFER="cd $(ghq root)/$src"
    zle accept-line
  fi
  zle -R -c
}

zle -N ghq-fzf_change_directory
bindkey '^f' ghq-fzf_change_directory