vimmerへ憧れる人に贈る、最強お手軽オシャレな開発環境 - vim + tmux + zsh + prezto

vimmer。

エンジニアを志す者なら一度は憧れるはず。

何度か練習したり本を読んでチャレンジしましたが、結局定着せずにVSCodeに出戻り・・・。

試しにvimで開発してみたいけど、始める前からvimrcとか面倒くさい設定は勘弁してほしい・・・。

これからvimで開発してみたい、やってみたけど挫折した・・というエンジニアに向けてカスタマイズ内容を紹介します。

## カスタマイズ内容

カスタマイズ後は👇の様になります。

<img width="1920" alt="vim-tmux-prezto.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116168/f93c5c1a-65b5-4ed8-2d52-d1d698318fb4.png">

画面分割をして下記のように使い分けています。

* 上部 : vim
* 下左部 : git関連
* 下右部 : コンソール操作（ログを流したり）

<span style="color: red;">※今回の一番のこだわりは画面最下部のtmuxステータスバーの設定(^^)</span>

# 対象者

* これからvimで開発したい
* 自分でカスタマイズ方法調べるのは面倒くさい
* とにかくカッコよくてオシャレな開発環境がいい

# 経緯

* 何度かvimチャレンジしたけど、結局VSCodeに戻る
* VSCode使ってたけど、職場が変わったら周りがvimmerばかり
* 素のvimは心許ない、なんとなくやる気が出ない
* 1から設定ファイル(.vimrcとか)書くのは面倒くさい

# 開発環境の構成

基本的な方針は有志のカスタマイズを利用（参考に）し、必要最低限のカスタマイズのみ加えます。

Qiitaやブログにたくさんのカスタマイズが紹介されていますが、多くの人に支持されているものを選定しています。※Githubのstarが多い等

1. vim
    * [amix/vimrc](https://github.com/amix/vimrc) : vimrcの設定ファイル郡
    * [vim-plug](https://github.com/junegunn/vim-plug) : プラグイン管理マネージャー
2. tmux
    * [gpakosz/.tmux](https://github.com/gpakosz/.tmux) : tmuxの設定がまとめっているやつ（ステータスバーが思うようにカスタマイズできないのでそのままは利用しない）
    * [tmp](https://github.com/tmux-plugins/tpm) : プラグイン管理マネージャー
3. zsh
    * [prezto](https://github.com/sorin-ionescu/prezto) : zshの設定ファイル群
    * [powerlevel9k](https://github.com/Powerlevel9k/powerlevel9k) : zshのテーマ（preztoで設定可能）
4. Terminal
    * [iTerm2](https://iterm2.com) : ターミナルアプリ
    * [Ricty](http://www.yusa.lab.uec.ac.jp/~yusa/ricty.html) : プログラミング用言語（らしい）
    * [powerline](https://github.com/powerline/powerline) : アイコン等のフォントを拡張
    * [nerd-fonts](https://www.nerdfonts.com) : 同上

# 作業手順

## Terminal

### iTerm2

利用するターミナルは**`iTerm2`**を前提として説明します。

インストールされていない方は下記からインストールしてください。

https://www.iterm2.com

マルチバイト文字対策のため、`Preferences > Profiles > Text > Font`を開き、`Ambiguous characters are double-width`の**`チェックを外します。`**

### フォント関連をインストール（Ricty + powerline + nerd-fonts）

ターミナル上でアイコンを使用するため、**`powerline`** 、**`nerd-fonts`**を初めに導入します。

プログラミング用フォント**`Ricty`**を同時にインストールします。
※フォントは好みなので何でもおｋ

```shell
# Ricty + powerline
$ brew tap sanemat/font
$ brew install --with-powerline ricty

$ cp -f /usr/local/bin/brew/opt/ricty/share/fonts/Ricty*.ttf ~/Library/Fonts/ # パスを確認
$ fc-cache -vf

# nerdfonts
$ brew install fontforge
$ git clone https://github.com/ryanoasis/nerd-fonts.git .nerd-fonts
$ cd .nerd-fonts/
$ ./install.sh # 全部はいらないかも・・
 
# Rictyにパッチをあてる
$ fontforge -script ./font-patcher ~/Library/Fonts/Ricty\ Bold\ for\ Powerline.ttf --fontawesome --fontlinux --octicons --powersymbols --powerline --powerlineextra --material --weather
$ fontforge -script ./font-patcher ~/Library/Fonts/Ricty\ Discord\ Bold\ for\ Powerline.ttf --fontawesome --fontlinux --octicons --powersymbols --powerline --powerlineextra --material --weather
$ fontforge -script ./font-patcher ~/Library/Fonts/Ricty\ Discord\ Regular\ for\ Powerline.ttf --fontawesome --fontlinux --octicons --powersymbols --powerline --powerlineextra --material --weather
$ fontforge -script ./font-patcher ~/Library/Fonts/Ricty\ Regular\ for\ Powerline.ttf --fontawesome --fontlinux --octicons --powersymbols --powerline --powerlineextra --material --weather
$ fontforge -script ./font-patcher ~/Library/Fonts/Ricty-Bold.ttf --fontawesome --fontlinux --octicons --powersymbols --powerline --powerlineextra --material --weather
$ fontforge -script ./font-patcher ~/Library/Fonts/Ricty-Regular.ttf --fontawesome --fontlinux --octicons --powersymbols --powerline --powerlineextra --material --weather
$ fontforge -script ./font-patcher ~/Library/Fonts/RictyDiscord-Bold.ttf --fontawesome --fontlinux --octicons --powersymbols --powerline --powerlineextra --material --weather
$ fontforge -script ./font-patcher ~/Library/Fonts/RictyDiscord-Regular.ttf --fontawesome --fontlinux --octicons --powersymbols --powerline --powerlineextra --material --weather
 
# 移動
$ mv Ricty* ~/Library/Fonts/
```

#### iterm2のフォントを変更

設定画面を開きフォントを変更します。

`Preferences > Profiles > Text > Font`から**`Ricty Nerd Font`**を選択

## zsh

bashからzshに切り替えます。
※すでにzshを利用している方は飛ばして大丈夫です。

```shell
$ chsh -s /bin/zsh

# bashの設定をzshに引き継ぎ
$ cat .bashrc >> .zshrc
$ cat .bash_profile >> .zprofile
$ sed -i -e "s/.bashrc/.zshrc/g" .zshrc
$ sed -i -e "s/.bashrc/.zshrc/g" .zprofile
```

上記コマンド実行後、ターミナルを再起動します。

### prezto

zshのフレームワーク（設定ファイル）**`prezto`**をインストールします。

```shell
$ git clone --recursive https://github.com/sorin-ionescu/prezto.git "${ZDOTDIR:-$HOME}/.zprezto"

# 必要な設定ファイルのみコピー
$ cp ~/.zprezto/runcoms/zpreztorc ~/.zpreztorc
```

`.zpreztorc`に下記設定を追加します。

```shell
$ vim .zpreztorc

# powerlevel9kをテーマに設定
zstyle ':prezto:module:prompt' theme 'powerlevel9k'

# 下記2行コメントアウトを外す
zstyle ':prezto:module:tmux:auto-start' local 'yes'
zstyle ':prezto:module:tmux:auto-start' remote 'yes'
```

`.zshrc`に設定を追加します。

```shell
$ vim ~/.zshrc
# 下記を追記
# prezto + poworlevel9k
POWERLEVEL9K_MODE=nerdfont-complete
[ -f "${ZDOTDIR:-$HOME}/.zprezto/init.zsh"  ] && source "${ZDOTDIR:-$HOME}/.zprezto/init.zsh"
POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(dir vcs)
POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=()
POWERLEVEL9K_PROMPT_ON_NEWLINE=true
POWERLEVEL9K_MULTILINE_LAST_PROMPT_PREFIX=" \U25B8 "
POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX=""
```

## vim

Macにプリインストールされていますが、**`Mac⇔vim間でclipboardを共有`**できるようbrewでインストールし直します。

```shell
$ brew update
$ brew install vim

$ source .zprofile

$ vim --version | grep clipboard
+clipboard         +keymap            +printer           +vertsplit       # ← +clipboardとなっていることを確認
+emacs_tags        -mouse_gpm         -sun_workshop      -xterm_clipboard
```

### vim-plug

vimのプラグイン管理マネージャー**`vim-plug`**をインストールします。

```shell
$ curl -fLo ~/.vim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
```

### vimの設定 

vimの設定には**`amix/vimrc`**を適応します。


```shell
$ git clone --depth=1 https://github.com/amix/vimrc.git ~/.vim_runtime
$ sh ~/.vim_runtime/install_awesome_vimrc.sh
```

amix/vimrc導入後、独自設定を記載するファイルを作成します。

```shell
$ vim ~/.vim_runtime/my_configs.vim
```

<details><summary>クリックして~/.vim_runtime/my_configs.vimの内容を確認する</summary><div>

```config
call plug#begin()

" tree icon
Plug 'ryanoasis/vim-devicons'
Plug 'tiagofumo/vim-nerdtree-syntax-highlight'

" bracket auto close
Plug 'cohama/lexima.vim'
Plug 'tpope/vim-surround'

" editorconfig
Plug 'editorconfig/editorconfig-vim'

" git
Plug 'tpope/vim-rhubarb'
Plug 'airblade/vim-gitgutter'

" emmet
Plug 'mattn/emmet-vim'

" js
Plug 'pangloss/vim-javascript'

" markdown
Plug 'tpope/vim-markdown'

call plug#end()

"" NERDTree
let g:NERDTreeChDirMode=1
let g:NERDTreeShowBookmarks=1
let g:nerdtree_tabs_focus_on_files=1
let g:NERDTreeMapOpenInTabSilent = '<RightMouse>'
let g:NERDTreeWinSize = 40
let NERDTreeShowHidden=1
let g:NERDTreeDirArrowExpandable = '▸'
let g:NERDTreeDirArrowCollapsible = '▾'

"" GitGutter
let g:gitgutter_enabled = 1
set updatetime=100
let g:gitgutter_override_sign_column_highlight = 0
highlight clear SignColumn
highlight GitGutterAdd ctermfg=2
highlight GitGutterChange ctermfg=3
highlight GitGutterDelete ctermfg=1
highlight GitGutterChangeDelete ctermfg=4

"" vim-markdown
let g:vim_markdown_folding_disabled=1

"" line
set number

"" multibyte
set ambiwidth=double

"" clipboard
set clipboard+=unnamed

"" background
highlight! Normal ctermbg=NONE guibg=NONE
highlight! NonText ctermbg=NONE guibg=NONE
highlight! LineNr ctermbg=NONE guibg=NONE

```
</div></details>

#### プラグインをインストール

プラグインをインストールするため下記コマンドを実行します。

```shell
$ vim +PlugInstall
```

**※Go言語を利用する場合**

**`vim-go`**が`amix/vimrc`に含まれていますので、下記コマンドを実行するだけです。

```shell
$ vim +GoInstallBinaries
```

## tmux

端末多重化ソフトウェア**`tmux`**をインストールします。

```shell
$ brew install tmux
```

### マルチバイト文字対策

マルチバイト文字が含まれていると表示幅の問題で色々と不具合があるのでパッチをあてます。

```shell
$ brew edit tmux
# 60行目から追記 ※末尾のend手前まで
def patches
[
  "https://raw.githubusercontent.com/z80oolong/tmux-eaw-fix/master/tmux-2.9a-fix.diff"
]

# 再インストール
$ brew reinstall --build-from-source tmux
```

### Macのクリップボードを共有できるようにする

*※tmuxのバージョンが新しいといらないかもしれない*

```shell
$ brew install reattach-to-user-namespace
```

### tpm

プラグイン管理マネージャー**`tpm`**をインストールします。

```
$ git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
```

### tmuxの設定

tmuxの設定ファイルを編集します。

```shell
$ vim .tmux.conf
```

<details><summary>クリックして~/.tmux.confの内容を確認する</summary><div>

```config
# -- general -------------------------------------------------------------------

set -g default-terminal "screen-256color" # colors!
setw -g xterm-keys on
set -s escape-time 10                     # faster command sequences
set -sg repeat-time 600                   # increase repeat timeout
set -s focus-events on

set -g prefix C-q                         # GNU-Screen compatible prefix
bind C-q send-prefix

set -q -g status-utf8 on                  # expect UTF-8 (tmux < 2.2)
setw -q -g utf8 on

set -g history-limit 5000                 # boost history

# reload configuration
bind r source-file ~/.tmux.conf \; display '~/.tmux.conf sourced'


# -- display -------------------------------------------------------------------

set -g base-index 1           # start windows numbering at 1
setw -g pane-base-index 1     # make pane numbering consistent with windows

setw -g automatic-rename on   # rename window to reflect current program
set -g renumber-windows on    # renumber windows when a window is closed

set -g set-titles on          # set terminal title

set -g display-panes-time 800 # slightly longer pane indicators display time
set -g display-time 1000      # slightly longer status messages display time

set -g status-interval 10     # redraw status line every 10 seconds

# clear both screen and history
bind -n C-l send-keys C-l \; run 'sleep 0.1' \; clear-history

# activity
set -g monitor-activity on
set -g visual-activity off


# -- navigation ----------------------------------------------------------------

# create session
bind C-c new-session

# find session
bind C-f command-prompt -p find-session 'switch-client -t %%'

# split current window horizontally
bind - split-window -v
# split current window vertically
bind _ split-window -h

# pane navigation
bind -r h select-pane -L  # move left
bind -r j select-pane -D  # move down
bind -r k select-pane -U  # move up
bind -r l select-pane -R  # move right
bind > swap-pane -D       # swap current pane with the next one
bind < swap-pane -U       # swap current pane with the previous one

# maximize current pane
bind + run 'cut -c3- ~/.tmux.conf | sh -s _maximize_pane "#{session_name}" #D'

# pane resizing
bind -r H resize-pane -L 2
bind -r J resize-pane -D 2
bind -r K resize-pane -U 2
bind -r L resize-pane -R 2

# window navigation
unbind n
unbind p
bind -r C-h previous-window # select previous window
bind -r C-l next-window     # select next window
bind Tab last-window        # move to last active window

# toggle mouse
bind m run "cut -c3- ~/.tmux.conf | sh -s _toggle_mouse"


# -- urlview -------------------------------------------------------------------

bind U run "cut -c3- ~/.tmux.conf | sh -s _urlview #{pane_id}"


# -- facebook pathpicker -------------------------------------------------------

bind F run "cut -c3- ~/.tmux.conf | sh -s _fpp #{pane_id}"


# -- list choice (tmux < 2.4) --------------------------------------------------

# vi-choice is gone in tmux >= 2.4
run -b 'tmux bind -t vi-choice h tree-collapse 2> /dev/null || true'
run -b 'tmux bind -t vi-choice l tree-expand 2> /dev/null || true'
run -b 'tmux bind -t vi-choice K start-of-list 2> /dev/null || true'
run -b 'tmux bind -t vi-choice J end-of-list 2> /dev/null || true'
run -b 'tmux bind -t vi-choice H tree-collapse-all 2> /dev/null || true'
run -b 'tmux bind -t vi-choice L tree-expand-all 2> /dev/null || true'
run -b 'tmux bind -t vi-choice Escape cancel 2> /dev/null || true'


# -- edit mode (tmux < 2.4) ----------------------------------------------------

# vi-edit is gone in tmux >= 2.4
run -b 'tmux bind -ct vi-edit H start-of-line 2> /dev/null || true'
run -b 'tmux bind -ct vi-edit L end-of-line 2> /dev/null || true'
run -b 'tmux bind -ct vi-edit q cancel 2> /dev/null || true'
run -b 'tmux bind -ct vi-edit Escape cancel 2> /dev/null || true'


# -- copy mode -----------------------------------------------------------------

bind Enter copy-mode # enter copy mode

run -b 'tmux bind -t vi-copy v begin-selection 2> /dev/null || true'
run -b 'tmux bind -T copy-mode-vi v send -X begin-selection 2> /dev/null || true'
run -b 'tmux bind -t vi-copy C-v rectangle-toggle 2> /dev/null || true'
run -b 'tmux bind -T copy-mode-vi C-v send -X rectangle-toggle 2> /dev/null || true'
run -b 'tmux bind -t vi-copy y copy-selection 2> /dev/null || true'
run -b 'tmux bind -T copy-mode-vi y send -X copy-selection-and-cancel 2> /dev/null || true'
run -b 'tmux bind -t vi-copy Escape cancel 2> /dev/null || true'
run -b 'tmux bind -T copy-mode-vi Escape send -X cancel 2> /dev/null || true'
run -b 'tmux bind -t vi-copy H start-of-line 2> /dev/null || true'
run -b 'tmux bind -T copy-mode-vi H send -X start-of-line 2> /dev/null || true'
run -b 'tmux bind -t vi-copy L end-of-line 2> /dev/null || true'
run -b 'tmux bind -T copy-mode-vi L send -X end-of-line 2> /dev/null || true'

# copy to macOS clipboard
if -b 'command -v pbcopy > /dev/null 2>&1' 'bind y run -b "tmux save-buffer - | pbcopy"'
if -b 'command -v reattach-to-user-namespace > /dev/null 2>&1' 'bind y run -b "tmux save-buffer - | reattach-to-user-namespace pbcopy"'

# -- buffers -------------------------------------------------------------------

bind b list-buffers  # list paste buffers
bind p paste-buffer  # paste from the top paste buffer
bind P choose-buffer # choose which buffer to paste from


# -- user defined overrides ----------------------------------------------------

# increase history size
#set -g history-limit 10000

# start with mouse mode enabled
set -g mouse on

# force Vi mode
#   really you should export VISUAL or EDITOR environment variable, see manual
set -g status-keys vi
set -g mode-keys vi

# move status line to top
#set -g status-position top

set -g @batt_icon_charge_tier8 '🌕'
set -g @batt_icon_charge_tier7 '🌖'
set -g @batt_icon_charge_tier6 '🌖'
set -g @batt_icon_charge_tier5 '🌗'
set -g @batt_icon_charge_tier4 '🌗'
set -g @batt_icon_charge_tier3 '🌘'
set -g @batt_icon_charge_tier2 '🌘'
set -g @batt_icon_charge_tier1 '🌑'
set -g @batt_icon_status_charged '🔋'
set -g @batt_icon_status_charging '⚡'
set -g @batt_icon_status_discharging '👎'

set -g @online_icon "\u2714"
set -g @offline_icon "\u2717"

set -g status-left-length 50
set -g status-left "#[bg=colour69]#[fg=colour235] ❐ #S:#I.#P "

set -g status-right-length 110
set -g status-right '#(curl wttr.in?format=3) | #[bg=default]#[fg=default]#{battery_icon} #{battery_percentage} | CPU: #{cpu_percentage} | Online: #{online_status} #[bg=colour239]#[fg=colour247] %H:%M #[bg=colour244]#[fg=colour238] %m/%d %a '
# default statusbar colors
set-option -g status-bg colour237 #base02
set-option -g status-fg colour136 #yellow

# default window title colors
set-option -g window-status-style fg='colour244' #base0
set-option -g window-status-style bg='default'
#set-window-option -g window-status-attr dim

# active window title colors
set-option -g window-status-current-style fg='colour166' #orange
set-option -g window-status-current-style bg='default'
#set-window-option -g window-status-current-attr bright

set -g window-status-current-format '#[bg=colour239]#[fg=colour119] #I#[fg=colour249]:#[fg=colour255]#W#[fg=colour249] #F#[fg=colour239]#[bg=colour237]'
set -g window-status-format ' #I#[fg=colour237]:#[fg=colour250]#W#[fg=colour244] #F '

# pane border
set-option -g pane-border-style fg='colour235' #base02
set-option -g pane-active-border-style fg='colour240' #base01

# message text
set -g message-style bg='colour235' #base02
set -g message-style fg='colour166' #orange

# pane number display
set-option -g display-panes-active-colour colour33 #blue
set-option -g display-panes-colour colour166 #orange

# clock
set-window-option -g clock-mode-colour colour64 #green

# List of plugins
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-sensible'

set -g @plugin 'tmux-plugins/tmux-cpu'
set -g @plugin 'tmux-plugins/tmux-battery'
set -g @plugin 'tmux-plugins/tmux-online-status'
set -g @plugin 'tmux-plugins/tmux-resurrect'
set -g @plugin 'tmux-plugins/tmux-continuum'

# Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf)
run -b '~/.tmux/plugins/tpm/tpm'
```
</div></details>

#### プラグインをインストール

ターミナル上で`Ctrl + q` → `I`を叩くとインストールが始まります。

# 使い方

ぼくが参考にしている記事を紹介します。

[tmuxチートシート](https://qiita.com/nmrmsys/items/03f97f5eabec18a3a18b)　※カスタマイズ後のプレフィックスは`Ctrl + q`

[vimのキーマッピング](https://github.com/amix/vimrc#key-mappings)

※いずれはまとめたい

# おわりに

始めは**`bash + powerline`**で構築しようし、試行錯誤の上現在の構成にしたので手順に誤りがあるかも知れませんm(_ _)m

見た目的には満足できる出来に仕上がりましたが、まだまだ使いこなせていないのでそこは使い倒すしかないかなと・・・。

コレでも最低限のカスタマイズと思っているので、個々の設定を掘り下げるとまだまだ伸び代はあります。（やるかはわからんが）

タイトルにお手軽とつけたが、まとめてみると全然お手軽な量じゃなかったので、今後は**`dotfiles`**にまとめワンライナーで導入できるようにしようと思います。

# 謝辞

今回の開発環境を構築するにあたり特に影響を受けた記事です。執筆者に感謝。

[tmuxとvimによる開発作業フロー (動画)](https://blog.craftz.dog/my-dev-workflow-using-tmux-vim-48f73cc4f39e)
[vimって極めればvscode並のIDEになるんじゃないの？ - 最強のvimrcを晒す。](https://qiita.com/ryuta69/items/98901f4c4f0683e7aa57)
[tmux のステータスラインの設定を美しくした](https://blog.black-cat.jp/2018/12/tmux-status-line/)