CUI 開発環境 2019 - tmux, fzf, ghq, Starship, aws-vault, etc

パラレルワーカー兼大学生になることになった · the world as code で書いた新しい職場に入って、実はエンジニア人生9年目にして初めて macOS をメインで与えられる職場に入りまして。今まで全部 Windows だったというなかなか自分でも信じがたい事実(まぁ Linux で VM 立ち上げてその中で作業したりコーディングしてたりもしたけど)。それで macOS だと常に zsh 開いておけるし( Windows でもできなくはないが)、シェルで生活する時間が大幅に増えたので、これを期にと CUI の開発環境を整えたので一旦まとめておく。ざっくり以下の技術あたりを使っているので順に書く。

tmux

4年ぐらい前に一度入門したものの、 iTerm2 のタブと画面分割があれば別にいいかなという感じで使わなくなっていたのを改めて使い始めた。きっかけになった理由は実はだいぶ些細で、 macOS の全画面表示ってメニューバーを隠してしまうので時間がわからないのが困って、ステータスバーに時刻を表示したくなったというところ。実際使い始めてみるとセッションを作って長くかかるコマンドを裏で実行させたままデタッチして別のことやる、みたいなのがなかなか便利で手放せなくなりつつはある。

以前使っていた tmux.conf を引っ張り出してはみたが、 powerline 周りの設定は忘れているし、学習コストかけたくもなかったので外部プラグインへの依存はやめた。 tmux デフォルトのステータスバーを使って時刻などは表示している。

Image from Gyazo

fzf + ghq

fzf は以前から興味はあったけど使ってなくて、というか動作原理がよくわかっていなかったのだが、ちゃんと使ってみたらすごく便利だった。

複数行のテキストを標準入力から突っ込むと、曖昧検索ができる TUI が開き、そこで検索をして1つ結果を選択すると、その文字列を吐き出すという、日本語で書くとこういう動作をする。例えば git のブランチ切り替えだとか、複数のファイルから1つ選んで開くとか、そういう「多くの選択肢から絞りたい」操作をするのに役立つ。まぁ見たほうが早いと思う。

Image from Gyazo

こういう感じ。ただ、手でこういう風に fzf コマンドをわざわざ打つのではなくて、基本的な使い方としてはよく使うコマンドを関数として定義して .zshrc などに書いておいて、必要に応じて呼び出すという形を取る。

これと組み合わせて使うとすごく良いのが ghq 。ローカルに置く git レポジトリを管理してくれるツールで、 .gitconfig に以下のように root となる場所を書いた上で ghq get chroju/chroju.github.io と打つと root 配下に git clone してくれる。そして ghq list で、 root 配下に置かれた git レポジトリの一覧をずらっと出力してくれる。つまり fzf と組み合わせるとこういう関数が書けるということ。これがだいぶ快適で1日100回ぐらい打ってる。

1fghq() {
2  local dir
3  # fzf-tmux は tmux で検索用 TUI をペイン分割して表示してくれるコマンド
4  dir=$(ghq list > /dev/null | fzf-tmux --reverse +m) &&
5    cd $(ghq root)/$dir
6}

他にも fzf はアイディア次第でいろんなことができそう。例えば AWS CLI と組み合わせて、 ec2 describe-instances 結果を食わせてインスタンス停止するとか、よくやるオペレーションを関数化しておいても便利かなと。

ghq と GOPATH

余談的な話。自分は Go を書く機会が多い。で、 Go のレポジトリは最近状況が変わってきてはいるけれど、 $GOPATH で指定したディレクトリを root として、 $GOPATH/src/github.com/chroju/... という具合の場所に置かれるというのがスタンダードになっている。

Go とそれ以外のコードでレポジトリの置き場が替わるのも嫌なので、自分は $GOPATH/src にあたるディレクトリを ghq の root として設定している。幸い Go も ghq も github.com/chroju/chroju.github.io という形でディレクトリを掘って clone してくるので、この設定によって Go でも非 Go でも気にせず同様の構成でディレクトリが管理できている。

このあたりは以下のエントリにインスパイアされている。

Starship

プロンプトをいい感じにしてくれる Rust 製のツール。スクショは tmux のときに貼ったものを参照。

以前までは zsh のプロンプト設定を自分で書いていたんだけど、あんまり可読性のいい記法ではないし、しばらく経つと書き方を忘れてしまうので外部ツールに頼って楽をすることにした。 Starship が良いのはシェル依存ではないので、仮に今後 Fish に移りたくなってもそのまま持っていけるということ。 brew install して eval "$(starship init zsh)" したらその瞬間からプロンプトがいい感じになる。

設定も豊富でよい。デフォルトの状態で git 関係の表示、ディレクトリ表示はやってくれるし、カレントディレクトリに go.mod があれば Go のバージョン、 requirements.txt があれば Python のバージョンを表示してくれる。設定の追加もできて、自分の場合は AWS_PROFILE を設定していたらそれを表示するようにしている。基本的には使わない環境変数だけど、たまに動作確認などでセットしたまま忘れてたりするので、事故防止になっていい感じ。

powerline font を求められることだけ面倒なんだけど、たぶん設定変更して絵文字を使わないようにしてやればそれも要らなくなる気がする。

aws-vault

macOS の Keychain と連携して AWS API のアクセスキーを管理してくれるツール。別の AWS アカウントへ switch する assume role 操作がすごく楽になるのでそれで使っている。以下は README からの引用だけど、 ~/.aws/config をこんな風に書いて aws-vault exec prod-readonly -- aws ec2 describe-instances という具合に実行すると、これで switch ができる。

1[profile jonsmith]
2region = us-east-1
3
4[profile prod-readonly]
5region=us-east-1
6role_arn = arn:aws:iam::111111111111:role/ReadOnly
7source_profile = jonsmith

重宝するのは、これで Terraform も assume role での実行ができること。以前 Terraform で AWS assume role が使用できない場合がある · the world as code で書いたとおり、基本的に Terraform は assume role に対応できていないので、この方法を使うのが一番ラクだと思う。

Conclusion

今書いたような設定は全部 dotfiles としてレポジトリにまとめているので、コードで見てもらったほうが早いのかも知れないです。 Ansible 流して会社 macOS の設定が数分で終わったときにはやるやんけ自分ってちょっと思いました。