Emacs からVim へ移行しました

今までCarbon Emacs を使っていたのですが、カスタマイズによって動作が重くなったり少し不満に思っていました。そうした中、Emacs23 がリリースされたり、Carbon EmacsからCocoa Emacsへの流れも来ていました。
僕もCocoa Emacs に移行しようと思ったのですが、Web+DB の記事やRails ユーザにVim を使う人が多いことを知り、ふと食わず嫌いだったVim を試してみようと思いました。
少しカスタマイズしてある程度使えるレベルになったので、まとめておきたいと思います。

環境

Vim のバージョン

Mac OS X 用 Vimのいろいろを見ると分かる通り、Macvim を使うにも色々種類があります。
僕の場合は、ターミナルと別に使いたかったのでGUI 版。そして、開発が盛んで、日本語環境で使う上で便利な設定が追加されているmacvim-kaoriya を選択しました。
以前はinsert mode に入る際に自動的にIM がON になったり(iminsert=0 が効かない)したらしいのですがこのリリースで改善されていました。

デフォルトのVim で困ったこと

最初からシンタックスハイライトとか効いているし(そうコンパイルされているからですが)、入力時にインデントを考えてカーソル位置を調整してくれたりと、なかなか使いやすいと思ったのですが、少し使っている内に何点か使いにくいと思う部分がありました。
以下詳細です。

1. バッファ切り替えが面倒

    • ls でバッファ一覧を確認して、b # で切り替え
    • Emacs のC-xC-b みたいにコマンドラインバッファに現在のバッファ一覧がでてきて、その中から選択したい

bufexplorer.vim で解決。C-l でバッファ一覧がでるようにしている。


2. session.el のように最近開いたファイルや実行したコマンドの履歴を保存しておく仕組みが欲しい

fuzzyfinder.vim(の紹介記事)YankRing.vimで解決。fuzzyfinder はEmacsanything.el ライクなインクリメンタル検索ができて凄く便利。anything.el をファイル探索やコマンド探索くらいしか使っていなかった自分にとっては代替として十分な機能。


3. insert mode まわり

    • カーソルキーで移動するのが嫌
      • vim に慣れた人は移動時にはnormal mode に戻してから移動するのか分からないのですが、insert mode のままでもカーソルキーなしで移動したい
    • C-d でDelete にならない
    • C-a(Home), C-e(End) も欲しい

この辺りはキーマッピングを変更して対応。insert mode 中の移動については、上下左右を「C-k」「C-j」「C-b」「C-f」にあてました。vimの「hjkl」に対応させようと思ったのですが、「C-h」のBackSpace と被るので左右はEmacs のバインドを採用…。


4. OS Xクリップボードと連携したい

    • デフォルトだとyank したものをブラウザのフォームにコピーとかできない

ぼちぼち散歩 MacのVimでシステムのクリップボードとやりとりするでできた。MacVim だと簡単だった。


設定ファイル

具体的な設定ファイルは以下になります。主に春なのでemacsからvimに乗り換えてみました « ふぃふmemoとWeb+DB vol.52 の記事を参考にして、なるべくカスタマイズしないようにしています。

  • .vimrc
" for macvim-kaoriya http://code.google.com/p/macvim-kaoriya/

" set nocompatible " vim の機能を使う

" <status line>
set laststatus=2 " 常にステータスラインを表示
set statusline=%<%F\ %r%h%w%y%{'['.(&fenc!=''?&fenc:&enc).'\|'.&ff.']'}\ \ %l/%L\ (%P)%m%=%{strftime(\"%Y/%m/%d\ %H:%M\")} 

" <encoding>
set encoding=utf-8
set fileencodings=euc-jp,cp932,iso-2022-jp

" <basic>
let mapleader = ","            " キーマップリーダー 
set nobackup                   " バックアップ取らない
set hidden                     " 編集中でも他のファイルを開けるようにする
set formatoptions=lmoq         " テキスト整形オプション,マルチバイト系を追加
set vb t_vb=                   " ビープをならさない
set backspace=indent,eol,start " バックスペースでなんでも消せるように
set autoread                   " 他で書き換えられたら自動で読み直す
set whichwrap=b,s,h,l,<,>,[,]  " カーソルを行頭、行末で止まらないようにする
set scrolloff=5                " スクロール時の余白確保

" <display>
set showmatch         " 括弧の対応をハイライト
set number            " 行番号表示

" <indent>
set expandtab     " tab をスペースに展開
set shiftwidth=2  " 自動インデントの幅


" <search>
set wrapscan     " 最後まで検索したら先頭へ戻る
set ignorecase   " 大文字小文字無視
set smartcase    " 大文字ではじめたら大文字小文字無視しない
set noincsearch  " インクリメンタルサーチOFF
set hlsearch     " 検索文字をハイライト


" <keymapping>
" 行単位で移動(1行が長い場合に便利)
nnoremap j gj
nnoremap k gk

map! <C-a> <Home>
map! <C-e> <End>

nnoremap <Space>. :<C-u>edit $MYVIMRC<CR>
nnoremap <Space>s. :<C-u>source $MYVIMRC<CR> :<C-u>source $MYGVIMRC<CR>
nnoremap <Space>w :write<CR>
nnoremap <Space>d :bd<CR>
nnoremap <Space>q :q<CR>
nnoremap <C-h> :<C-u>help<Space>
nnoremap <C-h><C-h> :<C-u>help<Space><C-r><C-w><CR>
nnoremap ; :
nnoremap : ;

" yank, paste with os clipboard http://relaxedcolumn.blog8.fc2.com/blog-entry-125.html
noremap <Space>y "+y
noremap <Space>p "+p

inoremap <C-d> <Delete>
inoremap <C-f> <Right>
inoremap <C-b> <Left>
inoremap <C-j> <Down>
inoremap <C-k> <Up>

" <command>
" insert mode
" \date で日付
inoremap <Leader>date <C-R>=strftime('%Y/%m/%d (%a)')<CR>


" <completion>
set wildmenu           " コマンド補完を強化
set wildmode=list:full " リスト表示,最長マッチ
set history=1000       " コマンド・検索パターンの履歴数

" <autocommand>
augroup BufferAu
    autocmd!
    " カレントディレクトリを自動的に移動
    autocmd BufNewFile,BufRead,BufEnter * if isdirectory(expand("%:p:h")) && bufname("%") !~ "NERD_tree" | cd %:p:h | endif
augroup END

augroup Chalow
  autocmd!
  autocmd BufWritePost $HOME/var/log/changelog/Changelog silent :!$HOME/bin/chalow
augroup END

" <plugins>
" BufExplorer
nnoremap <C-l> :BufExplorer<CR>

" FuzzyFinder
nnoremap <silent> fb :<C-u>FuzzyFinderBuffer!<CR>
nnoremap <silent> ff :<C-u>FuzzyFinderFile! <C-r>=expand('%:~:.')[:-1-len(expand('%:~:.:t'))]<CR><CR>
nnoremap <silent> fm :<C-u>FuzzyFinderMruFile!<CR>
nnoremap <silent> fc :<C-u>FuzzyFinderMruCmd<CR>

" Vim/Ruby
" http://blog.blueblack.net/item_133
" Rubyのオムニ補完を設定(ft-ruby-omni)
let g:rubycomplete_buffer_loading = 1
let g:rubycomplete_classes_in_global = 1
let g:rubycomplete_rails = 1

" rails.vim
let g:rails_level = 4
let g:rails_devalut_database = 'mysql'

" vimwiki
let g:vimwiki_list = [{'path': '~/var/vimwiki/', 'path_html': '~/Sites/vimwiki/'}]


vim 系の記事を見てこれは便利というのを少しずつ集めました。Space をprefix にした「w」「q」「bd」は便利。insert mode 中のCtrl を使った移動もなんだかんだ便利です。
nocompatible をコメントアウトしているのは、Vim-users.jp - Hack #1: Vimを使うために必要な最小限の設定にある通り、「~/.vimrc」が存在するればvim の機能が有効化されるためです。nocompatible はvim の機能を有効化する以外にも副作用が大きいとのこと。
あとは、rubyrails を主に使うのでその設定。

  • .gvimrc
colorscheme molokai          " http://winterdom.com/2008/08/molokaiforvim 
set guifont=Osaka-Mono:h14   " フォント
set antialias                " アンチエイリアシング
set transparency=15          " 半透明
set guioptions-=T            " ツールバー削除

" カーソル点滅無効化
set guicursor=a:blinkon0

" 自動的にIM をオンにする機能の禁止
set imdisableactivate

" ウィンドウ
set sessionoptions+=resize " 行・列を設定する

if hostname() == 'macbook'
  set lines=48             " 行数
  set columns=160          " 横幅
else
 " setting for iMac
endif

set cmdheight=1            " コマンドラインの高さ
set previewheight=5        " プレビューウィンドウの高さ

set splitbelow             " 横分割したら新しいウィンドウは下に
set splitright             " 縦分割したら新しいウィンドウは右に
set showtabline=2          " タブを常に表示


カラースキームはTextMate のmonokai 調のやつを使っています。ただ、文字が切れてしまい「a」と「d」の区別がつきにくかったりするので、italic の設定は全て削除しました。

plugin

今入れているプラグインは以下の通りです。vim でのオススメ plugin - 川o・-・)<2nd life を主に参考にしました。

  • Align
    • Emacs のM-x align みたいにテキスト整形してくれます。あると地味に便利ですよね
  • bufexplorer
    • バッファのエクスプローラEmacs のC-x C-b に近い感じでバッファ切り替えができる。その場でバッファを消したりもできる。
  • yankring.vim
    • ヤンクの履歴管理。vim を終了した後もきちんと保存してくれる。
  • taglist.vim
    • ctags との連携。タグジャンプや開いているファイルのメソッド一覧を別バッファに表示してそこからジャンプとかできる。メソッド一覧を表示する際にウィンドウが狭くなってしまうのが若干困る。C-], C-t で移動できたりするのは便利。
    • OS X のデフォルトのctags だと「-R」オプションが効かないので、macports 等からctags を入れる必要がある

vim を使ってみて

今は使いながら操作を勉強しているという感じです。Web+DB の記事や、Vim-users.jpのエントリーを最初から読んで、そこからリンクを辿ったりしています。あとはVimの極め方に習いhelp を引くことに慣れるよう意識しています。vim のhelp はめちゃ見やすいし分かりやすくて驚きます。Kaoriya 版は日本語ヘルプですし。plugin にもhelp がついてくるものが多く理解するのに助かります。Emacs の時はヘルプ引くことがほとんどなかったのですが、vim のhelp は感動レベル。
vim の使用感についていいなーと今感じているのは以下の点です。

  • 軽い

gvim でもサクサク動きますね。コンソール版だとそれを上回る速さでビックリしますが、十分な軽さです

  • help がいけてる

ドキュメントが手元にあるのはとてもうれしいです。タグジャンプできるし使いやすい。plugin にhelp を含める文化があるのもいいですね。ググるよりhelp 見た方が速いです

  • オペレータ、モーション、テキストオブクジェクトが賢い

オペレータで動作を指定して、モーションで範囲を指定というのが面白いです。削除は「d」、対象がカレント行ならオペレータと同じキー(ここではd)を、行末までなら「$」を、次の段落までなら「}」をという組み合わせで操作を行えます。HTML を編集している時もタグで囲まれている中身を削除「dit」とか。慣れてくるとビジュアルモードで範囲選択して…とかしなくなりそうです。

  • 設定ファイルが分かりやすい

help があるのもありますが、emacs-lisp と比べるとやっぱり分かりやすいです。「+ruby」でコンパイルすれば設定ファイル内にruby コードを書けたりして便利。MozRepl と連携する時とかに便利。perl でもpython でも同じようなことができます。


まだflymake の代替にあまりいいのがない(errormarker.vim + 書き込み時に評価とかかなぁ)とか、Emacs で使っていた機能を全て網羅できているわけではないのですが、かなり使いやすいです。このままオライリーのvi 本とかも読んで勉強していきたいと思います。