Railsをvimで書いてみよう!

GASHOO Inc. Advent Calendar 2017土曜日担当、19日目を飾ります、t-kusakabeです。 先週の土曜日は多忙のため記事をあげることが出来ずリスケして今です、頑張ります。

Railsvim

皆さん大好き宗教戦争です。 普段はエディタは何をお使いでしょうか? 弊社ではatomsublime textを使っている人がいる中僕だけvimでコードを書いています。(VSCodeがいないのは珍しいのかな?)(IDE臨機応変に使ってるよ!) よく「vimは勉強コストが高い」や「vimrc書くのが面倒」という理由からvimを避けている人を見かけます。 ただ僕はvimmer同士が集まったときに必ず繰り広げられる「自分が使っているvimの便利なプラグイン自慢」みたいなものに全く参加できません。 というくらい僕が使っているものはしれています。 ただコードを書くのには十分過ぎるので以外とvimの導入コストって高くないと感じいます。 今回はgashooのコードをvimで書けるようにしてみようと思います。 (gashooのコードを公開するわけじゃないよ)

構成

通常一つの.vimrcにいろいろ書いていくと思いますが僕は以下の様にディレクトリを分けています。

├── .vimrc
└── .vim
  ├── bundle
  ├── colors
  └── userautoload

なにはともあれ.vimrc

.vimrcには各種設定ファイルを読み紅葉にします。 (カラースキームだけ面倒くかったのでそのままです...mm)

runtime! userautoload/*.vim

" colorscheme
colorscheme antares

大きく二つに分ける

基本的に触るファイルはuserautoload以下のファイルです。

userautoload
├── basic.vim
├── neobudle.vim
└── statusline.vim

プラグインを使うのならneobundle.vim、使わないのならbasic.vimに書いていきます。

まずはプラグインなしから

" setting
set number
set title
set expandtab
set autoindent
set tabstop=2
set shiftwidth=2
set ignorecase
set smartcase
set wrapscan
set cursorline
set scrolloff=10
set confirm
set hidden
set nobackup
set noswapfile
set hlsearch
set incsearch
set ignorecase
set nowrapscan
set mouse=a
set wildmenu wildmode=list:longest,full
set fenc=utf-8
set laststatus=2
set ruler
set showcmd
set list
set listchars=trail:.
set clipboard+=unnamed
set clipboard=unnamedplus
set clipboard+=autoselect
set wildmenu
set history=1000
set backspace=indent,eol,start
syntax on
set syntax=markdown
set incsearch

autocmd QuickFixCmdPost *grep* cwindow

" escを
C>

" sキー封印
nnoremap s <Nop>

" window移動
nnoremap sj <C-w>j
nnoremap sk <C-w>k
nnoremap sl <C-w>l
nnoremap sh <C-w>h

" 論理移動
nnoremap j gj
nnoremap k gk
nnoremap gj j
nnoremap gk k

" window分割 shortcut key
nnoremap ss :<C-u>sp<CR>
nnoremap sv :<C-u>vs<CR>

" 新規tab shortcut key
nnoremap st :<C-u>tabnew<CR>

" 画面を閉じる
nnoremap sq :<C-u>q<CR>

" 検索結果を画面中央に
nmap n nzz
nmap N Nzz
nmap * *zz
nmap # #zz

" 強制保存
cnoremap w!! w !sudo tee > /dev/null %<CR> :e!<CR>

" htmlの閉じタグ補完
augroup MyXML
autocmd!
autocmd Filetype xml inoremap <buffer> </ </<C-x><C-o>
autocmd Filetype html inoremap <buffer> </ </<C-x><C-o>
autocmd Filetype eruby inoremap <buffer> </ </<C-x><C-o>
augroup END

" clipboardからのペースト時のインデント崩れの防止
if &term =~ "xterm"
let &t_SI .= "\e[?2004h"
let &t_EI .= "\e[?2004l"
let &pastetoggle = "\e[201~"

function XTermPasteBegin(ret)
set paste
return a:ret
endfunction

inoremap <special> <expr> <Esc>[200~ XTermPasteBegin("")
endif

Gashooのインデントはソフトタブ2つなためそれに合わせいます(ほんとは自分が好きなだけで変える必要がある時はちゃんとeditorconfig使ってます) また新型MBPに対応するためESCを押さなくて良い様に 'j' を2回押すとコマンドモードに切り替わるようにしています。 これが以外と便利で普段タイピングをするときに 'j' を2回連続で押すことは全くと言っていいほどないので入力は困らないです。 またESCを押すときにホームポジションが崩れてしまうのも防げるのでわりとお気に入りです。(実際はタッチバーなしを買った)

vimで分割

sをprefixにしています。 - s + s -> 水平分割 - s + v -> 垂直分割

  • s + (j k, h, l) -> ペインの移動

  • s + t -> 新規タブの作成

  • s + q -> 画面を閉じる

これだけでも他のエディタと似た様なことが出来るかと思います。

そしてプラグイン

昔ながらのneoBundleを使っています(モダンにして行きたいけど不便はないので移行する気があまり起きない。。。)

if has('vim_starting')
  set nocompatible

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

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

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

" editorconfig
NeoBundle 'editorconfig/editorconfig-vim'

" vimのwindowサイズ調整
NeoBundle 'simeji/winresizer'
let g:winresizer_start_key = '<C-T>'

" vim上でgitの差分
NeoBundle 'airblade/vim-gitgutter'
" stauts line
NeoBundle 'itchyny/lightline.vim'

" NERDTreeを設定
NeoBundle 'scrooloose/nerdtree'
nnoremap <silent><C-e> :NERDTreeToggle<CR>
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
map <C-l> gt
map <C-h> gT

" Unite.vim導入
NeoBundle 'Shougo/unite.vim'
" Unite.vim setting
" prefix keyの設定
nmap <Space> [unite]
" insertモードで起動
let g:unite_enable_start_insert=1
" 大文字小文字を区別しない
let g:unite_enable_ignore_case=1
let g:unite_enable_smart_case=1
" キーマップ
"スペースキーとaキーでカレントディレクトリを表示
nnoremap <silent> [unite]a :<C-u>UniteWithBufferDir -buffer-name=files file<CR>
"スペースキーとfキーでバッファと最近開いたファイル一覧を表示
nnoremap <silent> [unite]f :<C-u>Unite<Space>buffer file_mru<CR>
"新規ファイル作成
noremap :uff :<C-u>UniteWithBufferDir file file/new -buffer-name=file<CR>
" ESCキーを2回押すと終了する
au FileType unite nnoremap <silent> <buffer> <ESC><ESC> :q<CR>
au FileType unite inoremap <silent> <buffer> <ESC><ESC> <ESC>:q<CR>

" 括弧を自動で入れる
NeoBundle 'Townk/vim-autoclose'

" vim上でファイル名検索
NeoBundle "ctrlpvim/ctrlp.vim"
NeoBundle 'tacahiroy/ctrlp-funky'
let g:ctrlp_show_hidden = 0

" ファイル名検索にagを使う
NeoBundle 'rking/ag.vim'
if executable('ag')
  let g:ctrlp_use_caching=0
  let g:ctrlp_user_command='ag %s -i --hidden -g ""'
endif

" ag.vim
NeoBundle 'rking/ag.vim'

" plantuml
NeoBundle "aklt/plantuml-syntax"
let g:plantuml_executable_script = "~/.dotfile/plantuml"

" Railsのプラグイン
NeoBundle 'tpope/vim-rails'
" slimのsyntax
NeoBundle 'slim-template/vim-slim'

" Ruby向けにendを自動挿入してくれる
NeoBundle 'tpope/vim-endwise'

" カラースキーム
NeoBundle 'vim-scripts/twilight'

" なんかタグ強調してくれるやつ
NeoBundle 'valloric/matchtagalways'

" Reactのsyntax
NeoBundle 'pangloss/vim-javascript'
NeoBundle 'mxw/vim-jsx'

" Vueのsyntax
NeoBundle 'Shougo/context_filetype.vim'
NeoBundle 'osyo-manga/vim-precious'

autocmd BufNewFile,BufRead *.vue set filetype=html

" emmet-vim
NeoBundle 'mattn/emmet-vim'

" coffee-scriptのsyntax
NeoBundle 'kchmck/vim-coffee-script'

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

基本的にはSyntax系が多いです。 一部抜粋して。

  • airblade/vim-gitgutter -> vim上でgitの差分が見れる
  • scrooloose/nerdtree -> ディレクトリ構造を表示(ctrl + e)
  • Shougo/unite.vim -> pathを指定してファイルを開く(space + a)
  • ctrlpvim/ctrlp.vim -> ファイル名を指定して開く(上記はpathを辿らないといけないのに対してこちらは名前で開く(インクリメンタルサーチ)が出来る)

これだけ結構IDE的なことが出来ます。 ただIDEお得意の関数ジャンプがvimでは結構大変です。(ctagsとか使えばできる) これはサーチャー系を使って代替しています。

  • Highwaty
  • Platinum Searcher
  • The Silver Searcher

定義元に飛ぶだけより、どこで使われているのかなども把握出来るのでこちらの方が便利と言い聞かせています。 関数だけでなく単語なども検索出来るので便利ですね(cmd + shift + f相当)

ステータスライン

個人的にvimで大切なのは自分で設定をすることだと思っています。 よくvimrcくれと言われるのですが、自分で設定しないと何ができるのかわからなかったりするので結局vimを使わなくなったりします。 また自分で設定することで愛着も持てる気がします。 ということでステータスラインに関しては是非自分で設定してみてくださいw lightlineが良い感じになる気がします。 僕はステータスラインに未保存かどうか、現状のモード、書式、文字コード、行数、列数などを表示させています。 またrubocopなどのlintツールの結果を表示させたりしています。(これほんと便利)

まとめ

いかがでしたでしょうか。 僕は普段vim + tmux + zshを使って開発をしているのですが、vimだけでも十分便利に使えると思います。 「プログラマが知るべき97のこと」でも取り上げられていますが、IDEしか使ったことのない人は是非これを機にvimに挑戦していただけると幸いです。 エディタもバージョン管理も全て真っ黒な画面で行うのでちょっと知的になった気もしますねw