僕はターミナルに引きこもっています。たまに外出しても最寄りのブラウザ程度です。そんな僕は Mac を使っています。綺麗な UNIX だからです。ターミナルアプリとしてターミナル.appを使っています。iTerm2 含めいろいろ試しましたがコレがさいつよでした。そして、僕は 2 年半かけてさいつよ環境を築き上げました。
tl;dr
最強のターミナル開発環境の構築する
最強の開発環境を目指して
タイトルで豪語しすぎた感はありますが、本気で構築中です。僕がターミナル環境の整備に目覚めたのは学生の時でした。特に何かのプロジェクトに携わるといったこともなく、たまに講義の課題を解いたり趣味のアプリを作成したりといった程度での開発だったので、環境構築や整備に割く時間がありました。
まずは現状
普段のターミナル環境は次のとおりです。
- ターミナル.app(全画面)
- tmux 1.9a
- zsh 5.0.5
- vim 7.4
ベースは以上になります。コレらさえあれば、とりあえず何らかのものづくりは可能です。あとは使い勝手の向上をはかっていくのみです。
基本的に 2 ペインで作業しています。左で作業して右で確認やその他雑務といった具合です。ペイン分けしているとメインペインでエディタを立ち上げたとしても、片側でコマンドラインが見えるので安心します。
カスタマイズ
ソフトウェア個々の設定についてみていきます。
立ち回りとしては、ターミナル立ち上げてログインシェルが tmux を自動起動して、その tmux 上で zsh を動かす感じです。つまり tmux 周りを固めることが先決でした。
ターミナル.app
その前に土台となるアプリケーションのカスタマイズです。
まずは、見た目のカスタマイズです。Solarizedという目に優しいカラースキームがあります。記事トップにある画像の色味がそれです。以下からダウンロードできます。
Solarized Dark を読み込みデフォルト設定としました。
tmux
tmux はターミナルマルチプレクサと呼ばれるもので、ターミナル上でウィンドウを分割(ペイン)したり、複数のウィンドウを立ち上げたりすることができます。tmux のほかには GNU screen などが有名です。
ステータスバーのカスタマイズ
まずはこれです。僕はターミナル.app を全画面表示しています。故に、OS X が持つステータスバー(日時・時刻や IME、常駐アプリなどの表示バー)を確認することができなくなります。そこで、tmux でそれをエミュレートしています。
画像にもある通り、これがあれば何ら困ることもありません。OS X らしく tmux のステータスバーも上部に設定しました(ただし tmux 1.8 以上であること)。
バッテリー表示などエミュレーションに使ったスクリプトは以下にあります。
キーバインドのカスタマイズ
ペイン移動やウィンドウ移動、ペインリサイズなどの操作キーバインドはすべて Vim ライクのものにしました。これら後述しますが僕が Vim 派だからです。好みの問題なのでここは各種それぞれで。
ペインの分割に関しては、直感的に割れる Prefix +|
(縦割り)と Prefix +-
(横割り)を採用しました。カラースキームのカスタマイズ
ターミナル.app 同様、Solarizedです。はやり見た目の統一は大事です。
tmux-colors-solarizedからダウンロードして、tmux 内でsource
するだけです。
詳しくは、ターミナルマルチプレクサ tmux をカスタマイズする - Qiitaで言及しているので併せてどうぞ。
zsh
カスタマイズの大本命です。普段過ごすシェルは自分色に染められずにはいませんが、幸いに zsh はその全てに応えてくれるほどに高機能なポテンシャルを秘めています。
僕は zsh の設定ファイルを分割しています(今までは嫌でしたが)。zsh に限っては分割したほうがベストプラクティスに感じ始めたからです。
現在の zsh に関する構造は以下のとおりです。
$ tree -a
...├── .zsh│ ├── 10_utils.zsh│ ├── 20_keybinds.zsh│ ├── 30_aliases.zsh│ ├── 40_prompt.zsh│ ├── 50_setopt.zsh│ ...├── .zshenv├── .zshrc...
dotfiles の構造については後述します。ひとまず .zsh
というディレクトリを用意して、その中に分割用の設定ファイルを配置しています。数字による番号を振っているのはグロッビングによる自動ソートを無効化するためです。.zshrc
内で、
for f in ~/.zsh/[0-9]*.(sh|zsh)dosource"$f"
...
として、呼び出したい番号順にファイルにプレフィックスとして追加することで、source
の順番を操作しています。
現在、.zshrc
でやっていることは以下のとおりです。
- 各種 zsh モジュールを
autoload
- シェルスクリプトの共通ライブラリを
source
する - tmux を立ち上げる(アタッチ or 新規作成)
- antigen プラグインを呼び出し、
.zsh
にある分割ファイルを読み込む
これだけです。こうすることで、.zshrc
内の見通しが良くなり、保守がしやすくなりました。
ちなみに、tmux は zsh 側で自動アタッチ or 新規セッションを選択できるようになっています。zsh が設定ファイル内で以下のスクリプトを呼び出しているためです。
ターミナル.app を立ち上げただけで以下のアスクがあり、セッションへのアタッチも簡単にできます。
vim
メインで使用するエディタです。開発には欠かせない武器です。IDE やその他の統合開発環境は嫌いよりもエディタ派ですね。Vim バインドが身に染みついているというのもあります。
プラグイン
ゴリゴリにカスタマイズ…派が多いようですが、個人的にはそんなに利用していません。試してみてほんとうに気に入ったものだけなどに限っています。プラグイン依存が進むと、インストールできない環境での操作がつらいので(Vim は zsh などに比べて素の環境での操作を強いられる局面が多い気がするためです)。
また、以下に使っているプラグインを何個か列挙、紹介します。
- junegunn/fzf -
fzf
の Vim インターフェイス - b4b4r07/vim-shellutils - Vim コマンドラインで実行できるシェルコマンドのエミュレートプラグイン
- tpope/vim-surround - Vim のテキストオブジェクトに親和した囲う系プラグイン
- justinmk/vim-dirvish - NERDTree のようなファイルマネージャ
- ...
- junegunn/fzf -
カラースキーム
やっぱり Solarizedですね。GitHub は vim-colors-solarizedにありますので、手動クローンでもよし、プラグイン管理マネージャ(neobundle.vim や pathogen)でインストールしてもいいでしょう。
自動インストール
プラグインその他、Vim の初回立ち上げ時に丸っとインストールするようにしています。
dotfiles という文化
dotfiles という設定ファイルを集めたリポジトリで管理するのが今や主流になっています(GitHub に五万とホスティングされています)。自分好みの設定に仕上げたあとは GitHub 上で公開しましょう。アップするまでが dotfiles です(家に帰るまでが遠足、的な)。こうすることでバージョン管理もでき、バックアップも兼ねることができます。今まで築き上げた設定を失うのはとてつもなく悲しいですからね。
以下では、その dotfiles 周りと取り巻く開発スタイルについて紹介します。
ghq/Go スタイル
これらの管理手法について便宜上、ghq/Go スタイルとしておきます。ghq/Go スタイルによる開発を行うことで、作業場所(作業ディレクトリ)に囚われない、かつ同じお作法で管理することができます。
$ tree -L 2 ~/src
/Users/b4b4r07/src├── github.com│ ├── BurntSushi│ ├── b4b4r07│ │ ├── brionac│ │ ├── dotfiles│ │ ├── enhancd│ │ ├── emoji-cli│ │ ├── gomi│ │ ├── gotcha│ │ └── xtime│ ├── cheggaaa│ ├── codegangsta│ ├── daviddengcn│ ├── google│ ├── jessevdk│ ├── junegunn...│ ├── mitchellh│ ├── motemen│ ├── nlopes│ ├── nsf│ ├── peco│ └── x└── golang.org└── x
~/src
以下にすべてのリポジトリを保持し、開発・保守にあたります。こうすることで、「あのプロジェクトどこにおいたっけ?」とかの心配はなくなります。また、よく ghq
は peco
や fzf
といったインタラクティブなフィルタリング機能を持つコマンドと併用されています。これは ghq
に限らずとても便利なので別記事にて紹介したいと思います。
以下は peco
+ ghq
の例です。ghq/Go スタイルで管理するリポジトリに対し、簡単にディレクトリ移動を行うことができます。次が Bash 版で、
# Require Bash 4.0+
peco-src(){local selected
selected="$(ghq list --full-path | peco --query="$READLINE_LINE")"if[ -n "$selected"];thenREADLINE_LINE="builtin cd $selected"READLINE_POINT=${#READLINE_LINE}fi}bind -x '"\C-]": peco-src'
次が Zsh 版です。
peco-src(){local selected
selected="$(ghq list --full-path | peco --query="$LBUFFER")"if[ -n "$selected"];thenBUFFER="builtin cd $selected"# zle accept-linefi
zle reset-prompt
}
zle -N peco-src
bindkey '^]' peco-src
特にこの開発スタイルで重要なのは、単に「ツール "ghq
" を用いること」ではありません。重要なのは Go 言語の開発スタイルをお作法とし、それに倣って他の言語についても同様に管理・開発していくことです。そしてそのフロントエンドのインターフェイスとして、ツール "ghq
" を用いることです。
そのため、ghq
コマンドだけに縛られずに、よりフレックスに自分スタイルを交えてカスタマイズしていくことができます。僕はリモートリポジトリをクローンすること(git clone
および ghq get
相当)だけに特化した git コマンドを作成し、ghq/Go スタイルで利用しています(後述)。
工夫した点
dotfiles の成熟についてです。僕は 2 年半ほど前にこのリポジトリをつくりだしてから初期は、GitHub 上にある dotfiles リポジトリの多く(ページ数 80 以上)を見てきました。そこでパクったり自分流に改変したり、作りなおしたり書き換えたり取りやめたりを繰り返していくなかで研ぎ澄まされた知見について書き連ねます。
マルチプラットフォーム化
特定のプラットフォームに依存しないように心がけています。メインで使っているマシンは OS X ですが、よく簡易 Linux マシンを使ったり、Linux サーバにアクセスして dotfiles を踏まえた開発を行ったりする場面があります。
OS X のみならず、Linux ひいては Cygwin にも対応したスクリプトを書けるならそのほうがベターでしょう。対応できないのなら、エラー処理をするといいでしょう。
# ostype returns the lowercase OS name
ostype(){
uname | tr "[:upper:]""[:lower:]"}# os_detect export the PLATFORM variable as you see fit
os_detect(){case"$(ostype)" in
*'linux'*)PLATFORM='linux';;
*'darwin'*)PLATFORM='osx';;
*'bsd'*)PLATFORM='bsd';;
*)PLATFORM='unknown';;esacexport PLATFORM
}# is_osx returns true if running OS is Macintosh
is_osx(){
os_detect
if["$PLATFORM"="osx"];thenreturn 0
elsereturn 1
fi}
少し回りくどい書き方をしていますが、OS で分岐させる処理はめっちゃ大事です。Linux と OS X が行き来することも多いため、OS X 向けに書いていてそれがどこかで作用してエラーが起きるとかはよくあります。
オートメーション化
今流行の自動化です。dotfiles についても同様です。環境設定が一発すぐに環境すると気持ちいいし楽です。
僕の場合は、bash -c "$(curl -fsSL dot.b4b4r07.com)"
で dotfiles その他環境設定が終わるようになっています。これについて賛否両論ありそうですが、僕はこれでいいのです。
より深い話については省略します。以前、以下の記事で書きましたのでよろしければどうぞ。
さいつよを支えるコマンドたち
何度も出てきましたが、この最強のターミナル開発環境は最高の dotfiles の設定と ghq/Go スタイルからなっています。すべての作業の起点だからです。
そして開発をバックアップしてくれるのが何らかに特化した自作コマンド群です。何個かだけ紹介します。
git-get
これはリモートリポジトリをクローンすること(git clone
および ghq get
相当)だけに特化した git のサブコマンドです。シェルスクリプトで書いています(以下はコードを短くして掲載しました)。
#!/bin/bash# Check argumentsif[[ -z $1]];thenecho"too few argument" 1>&2;exit 1
elif[[ ! $1=~ ^(((https?|git)://)?github\.com/)?([A-Za-z0-9_-]+/)?[A-Za-z0-9_.-]+(\.git)?$ ]];thenecho"$1: invalid github.com URL" 1>&2
exit 1
fi# Format username/reponameuri="$(echo "$1" | perl -pe "s/^(((https?|git):\/\/)?github\.com\/)?//;s/\.git$//")"# if uri consists of "reponame" onlyif[[ ! $uri=~ / ]];thenuser="$(git config --get user.name)"uri="${user:-$USER}/$uri"fiusername="${uri%/*}"reponame="${uri#*/}"# Destinationdest="${2:-$HOME/src/github.com/${username:?not set}}"if[ -d "$dest"];thendest="$dest/$reponame";fiif[ -d "$dest"];thenecho"${dest/$HOME/~}: already exists" 1>&2;exit 1
fi
mkdir -p "$dest" 2>/dev/null
git clone "https://github.com/${uri}.git""$dest"
ghq get
よりもフレキシブルな指定が可能となっています。
git get gomi
としたとき:gomi
をレポジトリ名として認識し、ユーザ名をgit config --get user.name
から補完しますgit get b4b4r07/enhancd
としたとき: https://github.comを補完しますgit get github.com/b4b4r07/emoji-cli
としたとき: https:// を補完します
git clone
で用いるようなフル URL ももちろん受け付けます。そして、ダウンロード先は指定しない限り ~/src
以下のホスティングされたサービスのドメイン名以下のディレクトリになります。これは ghq/Go スタイルを踏襲しての設計です。
dot
dotfiles に関する機能を一手に担っているシェル関数です。ちょっと長くなるので省略しますが、リポジトリルートへの移動やファイル列挙が可能です。
gotcha
最近賑わっている Go 言語のパッケージを取得してくるコマンドです。このコマンド自体も Go 言語で書いたため並列処理で高速にダウンロードすることができます。Go は優秀な CLI ツールも多いため、専用の go get
を作ったという背景です。
さいつよを支えるプラグインたち
主に zsh プラグインについてなので、vim の項と並んで zsh の項に書くべきですが、エディタと違ってシェルなので、さいつよコマンドに並べて紹介します。
外部プラグインについて詳細にまとめられた Qiita 記事もあるので、より詳しくは以下にお任せします。
また、GitHub に awesome もあるのでどうぞ。
zsh-users/antigen
プラグイン管理マネージャ(プラグイン)です。antigen bundle username/reponame
で簡単にインストールできます。zsh プラグインのヘビーユーザはマストアイテムでしょう。
最近は tarjoilija/zgenという antigen の高速化バージョンもアツいようです。
zsh-users/zsh-history-substring-search
これはヒストリ検索をやりやすくしてくれます。いちいち C-rを使うまでもないとき、grep
とだけコマンドラインにタイプし、C-pすると grep
に限り遡ることができます。慣れると病みつきになります。。。
zsh-users/zsh-syntax-highlighting
コマンドラインにもシンタックスハイライトをもたらしてくれるプラグインです。fish のアレのような感じです。$PATH
に確認できるコマンドや、クォーテーションした文字列、ディレクトリ部分などには色や装飾がつきます。
b4b4r07/enhancd
cd
コマンド強化用のプラグインです。今流行の fzf
や peco
などのインタラクティブなフィルタを使って候補の絞込などができます。詳しくはリンクにある gif アニメを見ると分かりやすいと思います。
b4b4r07/emoji-cli
このプラグインはターミナル上で絵文字補完を行います。絵文字といえば、コロンから始まりコロンで終わる文字列ですが、「本」の絵文字が使いたいと思っても、様々な絵文字がある文字の単語部分が思い出せなかったりします。そんなときは、こいつが類推して変換してくれます。最近は、コミットメッセージなんかでも活発に利用されるため便利です。コレについてもリンクに gif アニメがあるのでどうぞ。
まとめ
この記事では、さいつよターミナル環境を作るための設定や工夫について紹介してきました。なんでここまでする必要があるのかと思った人もいるでしょう。ではまずここで Atom さんの話をしておきます。
最近では、エディタであるはずにも関わらず、ターミナルマルチプレクサちっくな側面とグラフィカルなシェルとカスタマイザブルなプラグイン機構(スクリプト含め)を内蔵した Atom とかいう鉄腕アトム的なフルスタックスーパーマンが台頭してきているようです。しかし、私はそれが嫌い好きではありません。
dotfiles はたまごっち
Atom を好きになれないのはたまごっち的な要素がないからでしょう!以下は僕の GitHub の Contributions ですが最近はこれを育てるのが楽しみの一つです。毎日草生やすことで(dotfilesだけに限りませんが)、リポジトリの育成記録として活躍しています。
Atom 含めそれら GUI アプリには設定やカスタマイズに関する機構があっても、それを育てていくという概念がないような気がします。一方で dotfiles は長い年月をかけ自分好みにカスタマイズ、リポジトリを育てていくことができます。そこに愛情を感じるのではないでしょうか。
よって dotfiles 含め環境構築はたまごっちです。