快適なターミナル環境を整備する

shell

shell は Mac で現在ではデフォルトの zsh を使っています。

以前 fish を使っていたこともあるのですが、Web 上で公開されているスクリプトや設定がそのままでは動かないことが多く、メリットを上回るデメリットに感じたため今は使っていません。

ターミナルエミュレータ

Hyper を使っています。

iTerm2 はクロスプラットフォームではないこと、alacritty は日本語入力の対応がなさそうなので採用を見送っています。

anyenv

nodenv-package-json-engine を入れておくと、プロジェクトによって使用する Node.js のバージョンを変更してくれます。

language-json
"engines": {
  "node": "^8.0.0"
}

package.json に上記のようにバージョンが記述するか、あるいは .node-version を置いてくことが条件になります。

Prezto

インストール方法についてはリンク先を参照してください。

頑張れるのであれば zplug を使うことになるのですが、設定に強いこだわりがなく面倒なので Prezto を使っています。

Prezto の設定は ~/.zpreztorc にあり、デフォルトだと syntax-highlighting が有効化されていないので、有効にしておくと便利です。

私は上記のモジュールも有効にしていて、最終的には以下のモジュールを読み込ませています。

language-.zpreztorc
zstyle ':prezto:load' pmodule \
  'environment' \
  'terminal' \
  'editor' \
  'history' \
  'directory' \
  'spectrum' \
  'utility' \
  'completion' \
  'prompt' \
  'autosuggestions' \
  'history-substring-search' \
  'syntax-highlighting'

prompt

以前は powerline を使っていたのですが、別途フォントのインストールが必要になります。環境によってはそれが許されないこともあるので、pure に乗り換えました。

こちらの設定も ~/.zpreztorc を編集することで反映されます。

language-diff
-zstyle ':prezto:module:prompt' theme 'sorin'
+zstyle ':prezto:module:prompt' theme 'pure'

ghq

コードを統一的に管理するツール。ghq get でリポジトリを取得して、fzf を使って検索ができるようになるととりあえず手元にもってくることが苦痛でなくなるので本当に便利。

ssh で clone するとき ghq get -p とすればいいんだけど、毎回オプションを忘れてます。

fzf

以前は peco を使っていたのですが、左右に表示されるのがいいなと思って fzf を使い始めました。いまのところ ghq や cdr と組み合わせて使うくらいしかしていません。

Icdiff

VS Code が優秀なのであまりターミナル上で差分の確認をすることはありませんが、するときにあると便利なので入れています。

AWS-CLI

もともとインストールはせず aws にエイリアスを指定していたのですが、インストールをしないと補完がきかなかったため、結局インストールして以下を追加しました。

language-zsh
autoload bashcompinit && bashcompinit
complete -C '/usr/local/bin/aws_completer' aws

最終的な .zshrc

language-zsh
export LANG=ja_JP.UTF-8

export VISUAL='code -w'
export EDITOR=$VISUAL

autoload -Uz is-at-least
autoload bashcompinit && bashcompinit

# prezto
if [ -s "${ZDOTDIR:-$HOME}/.zprezto/init.zsh" ]; then
  source "${ZDOTDIR:-$HOME}/.zprezto/init.zsh"
fi

# aws
complete -C '/usr/local/bin/aws_completer' aws

# anyenv
if [ -d $HOME/.anyenv ]; then
  export PATH="$HOME/.anyenv/bin:$PATH"
  eval "$(anyenv init -)"
fi

# goenv
export GO111MODULE=on
export GOPATH=$HOME/go
export PATH=$GOPATH/bin:$PATH

# fzf
export FZF_DEFAULT_OPTS="--layout=reverse"

# ghq
function _ghq-fzf() {
  local src=$(ghq list | fzf --preview "ls -laTp $(ghq root)/{} | tail -n+4 | awk '{print \$9\"/\"\$6\"/\"\$7 \" \" \$10}'")
  if [ -n "$src" ]; then
    BUFFER="cd $(ghq root)/$src"
    zle accept-line
  fi
  zle -R -c
}
zle -N ghq-fzf _ghq-fzf
bindkey '^]' ghq-fzf

# cdr
if is-at-least 4.3.11; then
  autoload -Uz chpwd_recent_dirs cdr add-zsh-hook
  add-zsh-hook chpwd chpwd_recent_dirs
  chpwd_functions+=chpwd_recent_dirs
  zstyle ':chpwd:*' recent-dirs-max 1000
  zstyle ':chpwd:*' recent-dirs-default true
  zstyle ':completion:*' recent-dirs-insert always

  # 既に存在しないディレクトリをcdrのリストから削除する
  # https://blog.n-z.jp/blog/2014-07-25-compact-chpwd-recent-dirs.html
  function _my-compact-chpwd-recent-dirs() {
    emulate -L zsh
    setopt extendedglob
    local -aU reply
    integer history_size
    autoload -Uz chpwd_recent_filehandler
    chpwd_recent_filehandler
    history_size=$#reply
    reply=(${^reply}(N))
    (( $history_size == $#reply )) || chpwd_recent_filehandler $reply
  }
  _my-compact-chpwd-recent-dirs

  alias cdd='_fzf-cdr'
  function _fzf-cdr() {
    target_dir=`cdr -l | sed 's/^[^ ][^ ]*  *//' | fzf`
    target_dir=`echo ${target_dir/\~/$HOME}`
    if [ -n "$target_dir" ]; then
      cd $target_dir
    fi
  }
fi