ぼくのかんがえたさいきょうのVim

Vimmerはモテるから、みんなVimmerになろう！
ソースは俺！！（白目

[DIVE INTO CODE Advent Calendar 12日目](http://qiita.com/advent-calendar/2016/diveintocode) の記事です。

## 前提

* For Rubyiest
* 俺の方がつよいって方は挑戦受け付けます（訳：アドバイスください。お願いします（切実））
* MacVim 使ってるので、GUIありきの機能が結構あります
* 力尽きて導入方法とか端折ってるんで、リンク先を参照ください。。。
    * （コメントいただければ、お答えします）

## ソース

https://github.com/mktktmr/vim_config

## ディレクトリ構成

```zsh
$HOME
├ .vimrc  # vimのメイン設定ファイル
├ .gvimrc # gvimの設定ファイル
└ .vim/
     ├ filetype.vim    # 拡張子とファイルタイプを紐付ける設定ファイル
     ├ .backup/        # バックアップファイルの出力先
     ├ .swap/          # スワップファイルの出力先
     ├ .undo/          # UNDO履歴ファイルの出力先
     ├ bundle/         # プラグインの置き場所
     └ ftplugin/       # ファイルタイプ毎の設定ファイルの置き場所
```

## .vimrc

こんな感じです。

詳細は後述

```vim:.vimrc
"-------------------------------------------------------------------------------
" NeoBundle:

" Note: Skip initialization for vim-tiny or vim-small.
if 0 | endif

if has('vim_starting')
  if &compatible
    set nocompatible               " Be iMproved
  endif

  " Required:
  set runtimepath+=~/.vim/bundle/neobundle.vim/
endif

" Required:
call neobundle#begin(expand('~/.vim/bundle/'))

  " Let NeoBundle manage NeoBundle
  " Required:
  NeoBundleFetch 'Shougo/neobundle.vim'

  " My Bundles here:
  " Refer to |:NeoBundle-examples|.
  " Note: You don't set neobundle setting in .gvimrc !

  " vimgrepの結果から置換
  NeoBundle 'thinca/vim-qfreplace'

  " previm
  NeoBundle 'kannokanno/previm'
  NeoBundle 'tyru/open-browser.vim'

  " 静的解析
  NeoBundle 'scrooloose/syntastic'

  " ドキュメント参照
  NeoBundle 'thinca/vim-ref'
  NeoBundle 'yuku-t/vim-ref-ri'

  " メソッド定義元へのジャンプ
  NeoBundle 'szw/vim-tags'

  " ブロックのendを自動で挿入
  NeoBundle 'tpope/vim-endwise'

  " ファイルをtree表示
  NeoBundle 'scrooloose/nerdtree'

  " indent for yaml
  NeoBundle 'chase/vim-ansible-yaml'

  " Railsプロジェクトのナビゲーション
  NeoBundle 'tpope/vim-rails'

  " コメントアウト
  NeoBundle 'tpope/vim-commentary'

  " カラースキーム
  NeoBundle 'cocopon/iceberg.vim'

call neobundle#end()

" Required:
filetype plugin indent on

" If there are uninstalled bundles found on startup,
" this will conveniently prompt you to install them.
NeoBundleCheck

"-------------------------------------------------------------------------------
" 編集に関する設定:

" タブの画面上での幅
set tabstop=4
" 自動インデントでずれる幅
set shiftwidth=4
" タブの代わりに空白文字を指定する
set expandtab
" 新しい行のインデントを現在行と同じにする
set autoindent

"-------------------------------------------------------------------------------
" ファイル操作に関する設定:

" バックアップファイル
"" 有効化
set backup
"" 出力先
set backupdir=~/.vim/.backup
" スワップファイル
"" 有効化
set swapfile
"" 出力先
set directory=~/.vim/.swap
" UNDOファイル
"" 有効化
set undofile
"" 出力先
set undodir=~/.vim/.undo

"-------------------------------------------------------------------------------
" 表示に関する設定:

" 行番号の表示
se nu

" 全角スペースの表示:
function! ZenkakuSpace()
    highlight ZenkakuSpace cterm=underline ctermfg=lightblue guibg=darkgray
endfunction

if has('syntax')
    augroup ZenkakuSpace
        autocmd!
        autocmd ColorScheme * call ZenkakuSpace()
        autocmd VimEnter,WinEnter,BufRead * let w:m1=matchadd('ZenkakuSpace', '　')
    augroup END
    call ZenkakuSpace()
endif

"-------------------------------------------------------------------------------
" NERDTree:

" .ファイルの表示（1: 表示）
let NERDTreeShowHidden=1
" ブックマークを表示 (1:表示)
let g:NERDTreeShowBookmarks=1
" 引数なしで起動した場合、NERDTreeを開く
" autocmd vimenter * if !argc() | NERDTree | endif
" 表示・非表示切り替え
nmap <silent> <C-n><C-t>      :NERDTreeToggle<CR>

"-------------------------------------------------------------------------------
" Previm:

let g:previm_open_cmd = 'open -a FirefoxDeveloperEdition'

augroup PrevimSettings
    autocmd!
    autocmd BufNewFile,BufRead *.{md,mdwn,mkd,mkdn,mark*} set filetype=markdown
augroup END

"-------------------------------------------------------------------------------
" rubocop:
" syntastic_mode_mapをactiveにするとバッファ保存時にsyntasticが走る
" active_filetypesに、保存時に syntastic を走らせるファイルタイプを指定する

let g:syntastic_mode_map = { 'mode': 'passive', 'active_filetypes': ['ruby'] }
let g:syntastic_ruby_checkers = ['rubocop']

"-------------------------------------------------------------------------------
" refe:
let g:ref_refe_cmd = $HOME.'/.rbenv/shims/refe' "refeコマンドのパス

"-------------------------------------------------------------------------------
" map:

" 検索結果のハイライトをEsc連打でクリアする
nnoremap <ESC><ESC> :nohlsearch<CR>
" 常にvery magicを利用
nnoremap / /\v
" タブ移動
nnoremap [t :tabprevious<CR>
nnoremap ]t :tabnext<CR>

" :ls + :buffer
cnoremap bb ls<CR>:buf
" 開いてるファイルのパスを表示 (Show Path)
cnoremap sp echo expand("%:p")<CR>
" 現在日時を入力 (yyyy/MM/dd)
cnoremap date <ESC>a<C-r>=strftime("%Y/%m/%d")<CR><ESC>
" 現在日時を入力 (yyyy/MM/dd hh:mm:ss)
cnoremap datetime <ESC>a<C-r>=strftime("%Y/%m/%d %H:%M:%S")<CR><ESC>

"-------------------------------------------------------------------------------
" その他設定:

" not ignore case.
se noic
" スペルチェック
set spell
set spelllang=en,cjk
" matchit.vim
runtime macros/matchit.vim
" color
colorscheme iceberg
```

### NeoBundle について

https://github.com/Shougo/neobundle.vim

NeoBundleは Vim のプラグインを管理するためのツールです。

`.vimrc` の、１行目から `NeoBundleCheck` までは この NeoBundle の設定とインストールするプラグインを定義しています。

[Dein.vim](https://github.com/Shougo/dein.vim) に移行しないとな。。。（遠い目

### プラグインについて

#### thinca/vim-qfreplace

`vimgrep` の検索結果に対して一括して置き換えを行うことができるプラグイン。

#### kannokanno/previm

http://kannokanno.hatenablog.com/entry/2013/06/11/225806

マークダウンのプレビュー表示を行うプラグイン。

![PrevimOpen.gif](https://qiita-image-store.s3.amazonaws.com/0/137110/4031d106-f9cc-c840-c360-85981fc067c6.gif)

#### tyru/open-browser.vim

上記のPrevimが依存しているプラグイン。

#### scrooloose/syntastic

ソースの静的解析を行ってくれるプラグイン。

`rubocop` などと組み合わせて利用する。

今回の設定だと、バッファの保存時に静的解析が走るようになっている。

![synta.gif](https://qiita-image-store.s3.amazonaws.com/0/137110/92ff012f-420e-5f21-9786-4617ae8e4551.gif)

#### thinca/vim-ref

http://qiita.com/c8112002/items/85a2c2cc3721c79a5322

~~rubyの~~[^1] リファレンスをvimから開くことができるようにしてくれるプラグイン。

[^1]: 特定の言語に依存はしてないです。。。

調べたいメソッドやクラス名などにカーソルが当たっている状態で `Shift + k` で、そのリファレンスが開けます。

また、 `Ref refe {調べたいメソッド名やクラス名}` でも、検索できます。

![explain.gif](https://qiita-image-store.s3.amazonaws.com/0/137110/3b88e59b-a2ff-6b13-fde0-84975d7ed432.gif)

#### szw/vim-tags

http://to-developer.com/blog/?p=1425

タグの生成やキーバインドの設定など、タグジャンプ機能の補助してくれる。

#### tpope/vim-endwise

`class` とか `def` とかの `end` を自動挿入してくれるプラグイン。

地味だけど超便利。

![end.gif](https://qiita-image-store.s3.amazonaws.com/0/137110/d88573f9-9ce2-0f80-b0c5-94687ed89a72.gif)

#### scrooloose/nerdtree

https://kamiya555.github.io/2015/10/14/nerdtree-command/

IDE とか でお馴染みのサイドメニュー的なファイルエクスプローラ。

ブックマーク機能が便利。

![NREDTree.gif](https://qiita-image-store.s3.amazonaws.com/0/137110/71fc8610-be48-22ab-8d9a-28e061ddc450.gif)

#### chase/vim-ansible-yaml

vim 標準の yaml のシンタックスハイライトやインデント制御が残念なので、このプラグインでいい感じにする。

#### tpope/vim-commentary

https://github.com/tpope/vim-commentary

コメントアウト・非コメントアウトが簡単に行えるようになる。

![gc.gif](https://qiita-image-store.s3.amazonaws.com/0/137110/81399ae3-8242-1d7b-d949-1c9901fd7e2e.gif)

#### cocopon/iceberg.vim

vimのシンタックスハイライトなどの色の設定です。

私のお気に入りは [iceberg](http://cocopon.me/app/vim-iceberg/) です。

モテるVimmerはカラースキームにこだわるんだぜ！

### 編集に関する設定

タブキーで半角スペースを入れるようにしたり、その際、スペースがいくつ入るのかなどの設定。

```vim
"-------------------------------------------------------------------------------
" 編集に関する設定:

" タブの画面上での幅
set tabstop=4
" 自動インデントでずれる幅
set shiftwidth=4
" タブの代わりに空白文字を指定する
set expandtab
" 新しい行のインデントを現在行と同じにする
set autoindent
```

### ファイル操作に関する設定

http://nanasi.jp/articles/howto/file/seemingly-unneeded-file.html

ファイルのバックアップなどの設定

```vim
"-------------------------------------------------------------------------------
" ファイル操作に関する設定:

" バックアップファイル
"" 有効化
set backup
"" 出力先
set backupdir=~/.vim/.backup
" スワップファイル
"" 有効化
set swapfile
"" 出力先
set directory=~/.vim/.swap
" UNDOファイル
"" 有効化
set undofile
"" 出力先
set undodir=~/.vim/.undo
```

* バックアップファイル
    * => 編集前のファイルを自動的にバックアップする。ファイルを誤って削除したり、誤った編集をしてしまっても、１つ前のバージョンであれば救出が可能になる
* スワップファイル
    * => Vimが異常終了などして保存ができなかった際、データを復元するためのファイル
* UNDOファイル
    * => Undo履歴が保存されている。このファイルがあると、ファイルを閉じた後でも、閉じる前のUndoを再現できる。

### 表示に関する設定

```vim
"-------------------------------------------------------------------------------
" 表示に関する設定:

" 行番号の表示
se nu

" 全角スペースの表示:
function! ZenkakuSpace()
    highlight ZenkakuSpace cterm=underline ctermfg=lightblue guibg=darkgray
endfunction

if has('syntax')
    augroup ZenkakuSpace
        autocmd!
        autocmd ColorScheme * call ZenkakuSpace()
        autocmd VimEnter,WinEnter,BufRead * let w:m1=matchadd('ZenkakuSpace', '　')
    augroup END
    call ZenkakuSpace()
endif
```

#### 全角スペースの表示

全角スペースの強調表示するための関数の定義と呼び出し

![スクリーンショット 2016-12-12 11.41.10.png](https://qiita-image-store.s3.amazonaws.com/0/137110/6ad96bd1-f6ed-fb20-dea1-7d8cb274ca28.png)

### NERDTree

```vim
"-------------------------------------------------------------------------------
" NERDTree:

" .ファイルの表示（1: 表示）
let NERDTreeShowHidden=1
" ブックマークを表示 (1:表示)
let g:NERDTreeShowBookmarks=1
" 引数なしで起動した場合、NERDTreeを開く
" autocmd vimenter * if !argc() | NERDTree | endif
" 表示・非表示切り替え
nmap <silent> <C-n><C-t>      :NERDTreeToggle<CR>
```

### Previm

以下の設定では、Firefox のディベロッパー版で開くようになってます。

```vim
"-------------------------------------------------------------------------------
" Previm:

let g:previm_open_cmd = 'open -a FirefoxDeveloperEdition'

augroup PrevimSettings
    autocmd!
    autocmd BufNewFile,BufRead *.{md,mdwn,mkd,mkdn,mark*} set filetype=markdown
augroup END
```

### rubocop

Rubyの静的解析ツール `rubocop` 巡査の設定。

```vim
"-------------------------------------------------------------------------------
" rubocop:
" syntastic_mode_mapをactiveにするとバッファ保存時にsyntasticが走る
" active_filetypesに、保存時に syntastic を走らせるファイルタイプを指定する

let g:syntastic_mode_map = { 'mode': 'passive', 'active_filetypes': ['ruby'] }
let g:syntastic_ruby_checkers = ['rubocop']
```

### refe

Rubyのリファレンスツール `refe` の設定。

```vim
"-------------------------------------------------------------------------------
" refe:
let g:ref_refe_cmd = $HOME.'/.rbenv/shims/refe' "refeコマンドのパス
```

### キーバインドの設定

ショートカットやちょっとしたスクリプトのキーバインドを設定。

```vim
"-------------------------------------------------------------------------------
" map:

" 検索結果のハイライトをEsc連打でクリアする
nnoremap <ESC><ESC> :nohlsearch<CR>
" 常にvery magicを利用
nnoremap / /\v
" タブ移動
nnoremap [t :tabprevious<CR>
nnoremap ]t :tabnext<CR>

" :ls + :buffer
cnoremap bb ls<CR>:buf
" 開いてるファイルのパスを表示 (Show Path)
cnoremap sp echo expand("%:p")<CR>
" 現在日時を入力 (yyyy/MM/dd)
cnoremap date <ESC>a<C-r>=strftime("%Y/%m/%d")<CR><ESC>
" 現在日時を入力 (yyyy/MM/dd hh:mm:ss)
cnoremap datetime <ESC>a<C-r>=strftime("%Y/%m/%d %H:%M:%S")<CR><ESC>
```

### その他

```vim
"-------------------------------------------------------------------------------
" その他設定:

" not ignore case.
se noic
" スペルチェック
set spell
set spelllang=en,cjk
" matchit.vim
runtime macros/matchit.vim
" color
colorscheme iceberg
```

以下の設定をしています。

* 大文字/小文字の区別
* スペルチェック機能の有効化
* matchit[^2]の有効化
* 前述のカラースキームの有効化

[^2]: `class` と `end`、 `if` と `end` など対応するブロックの先頭、終端にジャンプできる機能

**スペルチェックの様子**

![typo.gif](https://qiita-image-store.s3.amazonaws.com/0/137110/4a70e5e7-076a-7373-e9b9-5d05f31ca3a3.gif)

スペルミスの警告の他にも修正案の提示や、適用、例外単語の追加などもできます！

http://d.hatena.ne.jp/h1mesuke/20100803/p1

## .gvimrc

MacVim 用の設定ファイル。

主に見た目に関わること。

透過設定とかしてあげると最高にクールになるぜ！

![スクリーンショット 2016-12-12 5.18.34.png](https://qiita-image-store.s3.amazonaws.com/0/137110/bed11e17-e379-1d90-11a5-0857bc9a6134.png)

$$\style{color:red;}{\text{※ デスクトップが汚いことがバレます！}}$$

## filetype.vim

ファイル名とファイルタイプの紐付けを行う。

vimのデフォルトでは定義されていない拡張子のファイルとかをここで定義してあげる。

下記の例では、yamlファイルに対して、プラグインで定義された `ansible` というファイルタイプを割り当てている。

```vim
augroup filetypedetect
  au BufRead,BufNewFile *.yaml setfiletype ansible
  au BufRead,BufNewFile *.yml  setfiletype ansible
augroup END
```

## モテるVimmerになるにはまだまだ先は長い。。。

私は Vim を使い始めてから１年も経ってないビギナーなので、ぜひ本物のVimmerの方から「こんな便利なプラグインあるよ」とか、「そのキーバインドダメじゃね？」とかご意見いただけると嬉しいです。

また、この記事をきっかけに「Vim使ってみようかな」とかいう方が増えればいいなと思います。

最後に、本気でVimmer目指される方は、入門書として『[実践Vim　思考のスピードで編集しよう！](https://www.amazon.co.jp/dp/B00HWLJI3U)』をお勧めします！

Vim でいかに効率よくコーディングできるかや、Vimの苦手なこと（日本語入力とか）がよく分かります。