CUI環境とdotfilesを紹介する

dena新卒アドベントカレンダー11日目です。

# 開発環境
エンジニアが開発を行うにあたってOSやエディタ、IDEなど様々な環境が考えられます。今では多種多様なツールで触らずに済むような場合も多いですが、やはり効率を考えるとある程度弄る必要はあると思います。
#CUI
所謂黒い画面ですね。CLIとも呼ばれてたりしますが、GUIとの対称性から自分はCUIと呼ぶことが多いです。黒い画面に緑色の文字、所謂macのターミナルにあるhomebrewプロファイルでハッカー気分に浸るのも悪くはないですが、見易いカラースキームやフォント、zshの導入などを行うとより洗練されたターミナルにカスタムできます。実際のところ色は重要でDXが上がること間違いなしです。良い開発は良い環境から。

ちなみに自分がCUI環境を整えようとしたきっかけは以下の記事達です。
[お前らのターミナルはダサい](https://qiita.com/kinchiki/items/57e9391128d07819c321)
[さいつよのターミナル環境を構築しよう](https://qiita.com/b4b4r07/items/09815eda8ef72e0b472e)
[優れた dotfiles を設計して、最速で環境構築する話](https://qiita.com/b4b4r07/items/24872cdcbec964ce2178)
そして彼らの記事やいろんな人のdotfilesを参考に色々弄って数年、だいぶ洗練されてきたはず...と言ってもdotfilesのコミット数はほぼvimの調整だったりする。
## mac版
自分は標準でインストールされているターミナルを使用しています。有名なところでiTerm2がありますが、個人的には特に標準のものと比べてiTerm2にする理由はないと感じました。
現在自分のターミナルは↓のようになっています。
<img width="1679" alt="スクリーンショット 2019-12-05 17.44.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53020/088ae85a-213e-f65a-9ab3-58234288fd63.png">
色々と情報が出てますが、上部にtmuxのステータスバーを表示しています。
左側がウィンドウやセッションの番号
中央やや左寄りがセッションの一覧
右側には主にパソコンの状態を表示しています。
詳しくは後述します。

更に、自分は普段のコーディングをneovimで行なっているのですが、neovimを使って実際にコーディングしている画面は↓のような感じです。
ライバルはvs codeです。
<img width="1680" alt="スクリーンショット 2019-12-05 16.19.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53020/bf909df7-9313-b036-ddfc-cf710d6034cb.png">
中央の領域がメインのエディタ部分
左の領域がファイラー(vimプラグインのnerdtree)
右の領域がctagsの一覧(vimプラグインのtagbar)で、ファイル内のクラスや関数、変数などの一覧が表示されています。ctagsにはuniversal-ctagsを使っていて、vimのプラグインで保存時にプロジェクトのルートディレクトリから再帰的に自動生成及び更新されるようにしています。
下の領域がtmuxの機能で開いた別のターミナルです。ここで編集したコードの実行結果を見たりします。
ちなみにvim(neovim)にもターミナルをエミュレートする機能があり、これをvimの分割機能で開くことで似たような構成にすることも可能ですが
結局のところtmuxの方が利便性が高いと感じました。好みにもよると思いますが...
加えて下の領域でコードを実行するのみであれば、quickrunと言うプラグインもあるのですが、これも個人的にはtmuxで良いかなと言う結果でした。
横の領域の移動がctrl-w+h or lで、縦の移動がctrl-q+j or kなのが少し気持ち悪いですが慣れました。
###プロファイル
ターミナルのプロファイル(カラースキームとかの設定をまとめたもの)はcocopon氏の[iceberg](http://cocopon.github.io/iceberg.vim/)を使用しています。
少し前までは[solarized](https://github.com/tomislav/osx-terminal.app-colors-solarized)でしたが、気分転換にicebergにしてみたところ
そのまま気に入って継続利用しています。
寒色系の色が黒めの背景とマッチしていて見易く非常におすすめ。

###フォント
フォントはコーディングの見易さを考慮して[Cica](https://github.com/miiton/Cica)を使用しています。こちらは元々rictyと言うフォントを使っていましたが
vimのファイラーでファイルの先頭にアイコンを表示したいと思い、そのためにアイコンが入った良い感じのフォントを探したところcicaを見つけました。rictyをベース？にしているようで|とlとIや0とOの見分けがつくようになっていたりとプログラマに優しい仕様になっています。
<img width="109" alt="スクリーンショット 2019-12-05 19.29.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53020/8a4bd220-cfac-0f20-bf1c-fa985886fa26.png">
また、各種ファイルのアイコンも入っているため、ファイラーやdeniteでのアイコン表示もバッチリです。
deniteの画面↓
<img width="403" alt="スクリーンショット 2019-12-05 19.31.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53020/e3f75ff1-a60a-d77a-99ce-86c9cb152ff7.png">
ほんの少し前までファイラーにアイコンは必要ないと思っていましたが、ファイルの量が多いとアイコンの方が可読性が高く便利でした。
denitehttps://github.com/Shougo/denite.nvimはvim上で使えるファイラーのようなもの？です。特定のファイル群（vimのバッファに含まれるファイルや最近開いたファイルなど）から曖昧検索してファイルを開くことができます。nerdtreeやvs codeのファイラーのようにファイル一覧が表示されているのも便利ですが、deniteはファイル名を入れれば目的のファイルを検索してすぐに開くことができ素早いです。特にファイルが多くなるようなプロジェクトでは重宝されると思います。

<details><summary>deniteを使っているところ
</summary>
![画面収録 2019-12-06 21.11.14.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53020/d1739250-4edb-c666-133e-53666bf18689.gif)
ちなみにneovimで最近追加された機能であるfloating windowを使用しています。従来のdeniteや類似機能ではインターフェースとしてコマンドラインが使用されていました。コマンドラインモードに移行するとどうしても視線が下になるのですが、floating windowのおかげで視線移動が少なくなりしかもかっこいいインターフェースが実現されました。
</details>

## Linux版
出先や研究室、インターン先ではメインでmacbook proを使用していますが、自宅ではデスクトップでArch Linuxをメインで使用しています。
そのため使用感をあまり変えないように出来る限りmacとLinuxの環境を揃えるようにしています。とは言え大体のものがMac、Linux両方で使えるのでせいぜい設定ファイルを二つ分用意する程度で済みます。ただ、必要なソフトウェアなどを自動でインストールするようにするとmacとLinuxはもちろんのこと、Linuxでもディストリビューションごとに色々書く必要があって面倒です。一時期はhomebrew、linuxbrew(今はlinuxbrewもhomebrewに名前が変わった)で共通化していましたが、linuxbrewの利用を止めてからは手動でインストールしています。自動化したいけどめんどくさい...
Linux版でのターミナルは↓のような感じです。
![Screenshot from 2019-12-05 15-37-27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53020/37567611-d0b4-cf94-0760-a6ba5275cc25.png)
大体Macと同じです。
ターミナルはgnome terminalを使用しています。ただ、Macで使っていたicebergはLinux版が存在しないので、色々試した結果Azuにしています。
ただ、Azuはインストール方法が独特で、Goghhttps://mayccoll.github.io/Gogh/を使う必要があります。これは様々なカラースキームをまとめてインストールできるもので、前述のAzuはこちらに含まれています。
# dotfiles
ホームディレクトリとかの.からはじまるフォルダとかファイル(主に設定用)をgithubで管理していろんな環境で共通化しようという試み

レポジトリは[こちら](https://github.com/coil398/dotfiles)
いかにも自動でセットアップしてくれそうなコマンドがReadmeにあるけどメンテしてません、というかやっぱりめんどくさい

このdotfilesには先人の知恵、いわばパクリがたくさん入っています。
githubには他にもたくさんのdotfilesがあるので、他人のdotfilesを見て良さげな設定などあれば自分の環境に持ってくるのも良いでしょう。
その際、その設定は何のためにあるのか、そのコマンドで何が起こるかなどを調べながらやると理解が深まると思います。
ファイル構成
githubの画面を拝借(ちなみにgithubをダークモード化するchrome拡張機能github darkを入れてます。おすすめ)
![スクリーンショット 2019-12-05 17.08.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53020/91b6a1ec-e742-b91b-07c4-8cd61247f0b4.png)
(ちょっとでも不満があったり、ここをこうしたいなとかがあればすぐに弄ってコミット、それが気に入らなければまた弄ってコミットとしていると無駄にコミット数が膨れ上がります。ある意味達成感はある。とはいえ数あるレポジトリの中でdotfilesのコミット数が浮いている間は否めない🤔)

ファイルの置き方には各々様々なやり方があると思いますが、自分は大体以下のようなルールで運用しています。

名前がドットから始まるファイルとフォルダ→dotfiles直下
ただしtmuxだけはmac用とlinux用でファイル分割していて、プラグイン用のフォルダもあるので一つのフォルダにまとめています。

インストールやセットアップ用のスクリプト→etc
現在ノーメンテでほぼ使ってない。めんどい...

tmuxでの情報表示に使用するスクリプト→bin
コマンドとして使用するために/usr/local/binに手動で設置している。
自動化するかdotfiles/bin以下のスクリプトのパス指定しても良いかもしれない。

設定ファイルのうちmacとlinuxで分ける必要がある、かつ名前がドットで始まらないもの→options
としています。

次に各種ソフトウェア、ツールと設定を紹介します。
## zsh
macOS catalinaで標準になったzshですが、自分は別途homebrewでインストールしています。バージョンアップできなくても気にしないのであればデフォルトのままでも良いかもしれません。
zshの設定ファイルは.zshrcを使用していますが、ファイルの肥大化に伴いalias関連のは別途.zsh_aliasに記述しています。他にも環境変数やmac向けlinux向けの設定ファイルを分割するのもありかも知れませんが、今のところそこまで記述量がないので2ファイルのみです。
.zshrcは長いので抜粋して紹介すると

```zsh
# 色を使用
autoload -Uz colors
colors
zstyle ':completion:*' list-colors "${LS_COLORS}"
```

補完の際、ファイルかフォルダかで色が変わります。

```zsh
# tab補完
autoload -Uz compinit && compinit -i
compinit
タブ補完用の設定です。ファイル名とかフォルダ名を良い感じに補完してくれます。
特にフォルダ構造がよく分からなかったり、深いフォルダの探索の際には重宝します。
```

```zsh
CURRENT_DIR="%{${fg[blue]}%}[%~]%{${reset_color}%}"

autoload -Uz vcs_info
setopt PROMPT_SUBST
zstyle ':vcs_info:git:*' check-for-changes true
zstyle ':vcs_info:git:*' stagedstr "%F{yellow}!"
zstyle ':vcs_info:git:*' unstagedstr "%F{red}+"
zstyle ':vcs_info:*' formats "%F{green}%c%u[%b]%f"
zstyle ':vcs_info:*' actionformats '[%b|%a]'

function _update_vcs_info_msg() {
    LANG=en_US.UTF-8 vcs_info
    VCS_INFO=" ${vcs_info_msg_0_}"
    RPROMPT=$CURRENT_DIR$VCS_INFO
}

add-zsh-hook precmd _update_vcs_info_msg
```

gitのブランチを表示してくれます。作業ブランチを間違うと後々面倒になるため、常に確認できるのが良い点です。

## tmux
ターミナルマルチプレクサと呼ばれるソフトウェアです。こちらを使用すると同じターミナル画面でタブや、画面分割で複数のシェルを立ち上げることができます。プレフィックスと何かしらのキーで、画面の移動や分割した画面の大きさ変更などができます。また、ステータスバーにechoで任意の情報が表示できます。

macのステータスバー↓
<img width="1678" alt="スクリーンショット 2019-12-05 22.13.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53020/250e2b00-6e11-dc8d-65a8-5728f06ce14e.png">
ステータスバー右側には順番にメモリ使用量、CPUの平均使用率、CPU温度、使用しているWi-Fiの接続先と強度、バッテリー残量、音声出力先、ボリューム、現在の時刻を表示しています。

linuxのステータスバー↓
![Screenshot from 2019-12-05 15-37-27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53020/1cbeb941-656b-b52a-de24-62925dbb8138.png)
こちらも基本的には一緒ですが、順番にメモリ使用量、CPUの平均使用率、CPU温度、GPU1の温度、GPU2の温度、現在の時刻になっています。

これらは単にbinに入っているシェルスクリプトで別のプログラムを実行した結果をechoしているだけです。
使用しているプログラムは以下の通りです。

### 共通
`tmux-mem-cpu-load`
メモリとCPUをどれくらい使用しているかを表示してくれます。
自分でビルドしても良いですが、tmux用のプラグインマネージャーであるtpmでインストールするのが楽です。
### mac
`osx-cpu-temp`
macのcpu温度を表示する。
homebrewでインストール

`switchaudio-osx`
サウンドの出力先とボリュームを取得
homebrewでインストール
### linux
`nvidia-settings`
gpu温度を表示するために使用、gpuのドライバを入れれば自動でついてきます。
Wi-Fi状況は変な接続先に接続していないかが分かりますし、サウンドもAirpodsの接続が切れてて本体のスピーカーから音が出ると言う事故が防げる...かも知れません。
いずれにせよターミナル上で様々なパソコンの状態が分かるのは便利です。そして何となくかっこいい。

## zplug
zsh用のプラグインマネージャーです。新しくzpluginと言うのもあり、zplugより起動が早いらしく気にはなっていますがまだ移行できていません。
プラグインのせいか起動に多少もたつきはありますが、まだ許容範囲内です。こちらはまとめて.zplugrcと言うファイルでプラグインを管理し、.zshrcから呼び出しています。

```zsh
zplug 'mollifier/anyframe', lazy:yes
zplug 'mollifier/cd-gitroot', lazy:yes
zplug 'stedolan/jq', from:gh-r, as:command, rename-to:jq, lazy:yes
zplug 'b4b4r07/emoji-cli', on:'stedolan/jq', lazy:yes
zplug 'b4b4r07/enhancd', use:init.sh
zplug 'zsh-users/zsh-completions'
zplug 'mrowa44/emojify', as:command, lazy:yes
zplug 'junegunn/fzf-bin', as:command, from:gh-r, rename-to:fzf
zplug 'junegunn/fzf', as:command, use:bin/fzf-tmux
zplug 'zsh-users/zsh-history-substring-search'
zplug 'zsh-users/zsh-syntax-highlighting', defer:2
zplug 'zsh-users/zsh-autosuggestions'
zplug 'b4b4r07/git-conflict', lazy:yes
zplug 'b4b4r07/zsh-gomi', if:'which fzf'
zplug 'b4b4r07/zplug-doctor', lazy:yes
zplug 'b4b4r07/zplug-cd', lazy:yes
zplug 'b4b4r07/zplug-rm', lazy:yes
zplug 'mafredri/zsh-async'
zplug 'zplug/zplug', hook-build: 'zplug --self-manage'

# Install plugins if there are plugins that have not been installed
if ! zplug check --verbose; then
    printf 'Install? [y/N]: '
    if read -q; then
        echo; zplug install
    fi
fi

# Then, source plugins and add commands to $PATH
# zplug load --verbose
zplug load
```

色々とオプションがサポートされてはいますが、とりあえず他人のを参考に雰囲気で使っています。
曖昧検索を行うfzf、それを元に良い感じにディレクトリ移動をしてくれるenhancd
zshの補完を強化してくれるzsh-completions
コマンドに色をつけてくれるzsh-syntax-highlighting
入力した文字列に一致する過去の入力履歴を表示してくれるzsh-autosuggestionsあたりは特におすすめです。

<details><summary>こんな感じ</summary>
![画面収録 2019-12-06 21.26.10.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53020/e439cb90-70e9-7ca1-0c5b-56919dd38b3b.gif)
早くて見辛いけど、ホームディレクトリから曖昧検索で目的のフォルダに入って(enhancd)、適当にディレクトリ移動後npm run startしてます。
途中実行するコマンドの色が変わっていたり、前に実行したコマンドの履歴が見えます。
</details>

## vim
何年か前のneovimの非同期サポートを境にそちらに完全に移行しました。neovimの設定ファイルは.config/nvim/nvim.initにあり、vimと共通化するため.vimrcではinit.vimを読み込むだけ...にするつもりでしたがneovimの設定をそのまま書いてあるせいでエラーが毎回出るのでそのまま放置しています。
エイリアスでvimと打つとneovimが起動するので最早vimの存在は忘れました。
vimの設定ファイル群はまとめて同じディレクトリに置いています。
ファイル構成は↓のような感じです。
![スクリーンショット 2019-12-05 23.10.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53020/56d11008-c254-7b3d-7d4a-c37435b8e9fd.png)
こちらは設定が膨大なため役割ごとにできるだけファイルを分けています。
init.vimではsetから始まる各種設定と、他のvimファイルの読み込みを行っています。
また、vimのプラグインマネージャーにはdeinを使用しており、各種tomlファイルはプラグイン用のファイル、autoload以下にはそれらプラグインの設定ファイルが入っています。プラグインについては別途vim2アドベントカレンダーで記事にする予定です。

`autocmds.vim`
各種autocmd（特定のファイルを開いた時に実行されるコマンド群）の設定

`color.vim`
ハイライトの設定

`dein.vim`
プラグインの読み込み

`keymappings.vim`
キーマッピングの設定

`linux.vim, mac.vim`
それぞれlinux, mac用の設定

`types.vim`
ファイルタイプごとの設定
前述した通り、vimの設定は多岐に渡ります。ジャンルごとに設定ファイルをまとめておくのをおすすめします。後から切り分けるのは面倒なので...(体験談)

## .config
基本的にconfigファイル直下はgitignoreしていますが、前述のneovim用のフォルダと特定のlanguage serverのための設定ファイルのみはgit管理しています。比較的重いファイル(deinでインストールしたvimプラグインなど)も入る可能性があるので、.configに関してはホワイトリスト形式で管理するのをおすすめします。

## その他
.imwheelrcと.Xmodmapはそれぞれlinuxでimwheel, xmodmapを使うための設定ファイルです。
それぞれマウスのスクロール速度とキーボードのキーマッピングを変更するソフトウェアです。
他にも各環境で共通化したい設定ファイルなどあればdotfilesで管理すると捗ります。

# まとめ
ターミナル環境での作業も設定を色々としておくことで効率が段違いに上がります。と言うか作業が楽しくてあらゆる作業をターミナルで済ませるようになります。皆さんもこれを機にターミナル環境を弄ってみてはいかがでしょうか。沼にハマりましょう。