Vimの生産性を高める12の方法

1. LeaderをSpaceキーにする

Leaderは素晴らしい概念です。キーの組み合わせではなく並びによって、操作を行えるようにするものです。私はこれを使っているので、操作のために”Ctrl-何らかのキー”の組み合わせを押す必要はめったにありません。

私は長い間、,Leaderキーとして使っていました。ですがある時、キーボードの中で一番目立つキーにマップすることを思い付いたのです。Space(スペース)キーです。

let mapleader = "\<Space>"

これで私のVim生活は激変しました。今や、私はLeaderをどちらの親指でも押すことができ、他の指は常にホームポジションにあります。Leaderがとても使いやすくなったので、私が様々なキーバインドで用いるようになったことは周知の話です。

2. 自分が特によく行う操作をLeaderにマップする

私は、自分がVimで作業を行っている中で、その時間の大半を費やしている操作を特定して、それらをLeaderキーでマップすることにしました。例えば以下のような操作です。

<Space>oを押して新しいファイルを開く

nnoremap <Leader>o :CtrlP<CR>

<Space>wを押してファイルを保存する(:w<Enter>よりずっと速い)

nnoremap <Leader>w :w<CR>

<Space>p<Space>yでシステムのクリップボードにコピー&ペーストする

vmap <Leader>y "+y
vmap <Leader>d "+d
nmap <Leader>p "+p
nmap <Leader>P "+P
vmap <Leader>p "+p
vmap <Leader>P "+P

<Space><Space>でビジュアルラインモードに切り替える

nmap <Leader><Leader> V

自分が特によく行う操作を特定して、それをマップすると良いでしょう。

3. 範囲拡大を使う

私は、以下のマッピングにterryma/vim-expand-regionを使っています。

vmap v <Plug>(expand_region_expand)
vmap <C-v> <Plug>(expand_region_shrink)

これで以下の操作ができるようになります。

  • vを押して、1文字を選択する
  • もう1回vを押して、選択範囲を単語に拡大する
  • さらに1回vを押して、選択範囲を段落に拡大する
  • (以下省略)
  • 範囲を拡大しすぎた場合は、<C-v>を押して前回の選択範囲に戻す

vvvvpより時間が掛かるように思えますが、実際には、選択すべき範囲や使うべきキーの組み合わせを事前に考えずに済んでいます。

この方法でvが、viwvawvi"va"vi(va(vi[va[vi{va{vipvapvitvatなどの代わりとなっていることにはお気づきですね。

4. テキスト検索オブジェクトを見つける

私はVimの検索と置換を決して十分に活用してはいなかったのですが、そんな時にVim wikiで以下のスニペットを見つけました。

vnoremap <silent> s //e<C-r>=&selection=='exclusive'?'+1':''<CR><CR>
    \:<C-u>call histdel('search',-1)<Bar>let @/=histget('search',-1)<CR>gv
omap s :normal vs<CR>

これで、検索と置換を以下の流れで実行できるようになりました。

  • 検索を実行するには通常と同様に/somethingを使う
  • csを押し、最初の一致項目を置換して、<Esc>を押す
  • n.n.n.n.n.と押して、全ての一致項目を確認しながら置換する

補足:代わりに、Vim 7.4から導入されたcgnを使う方法もあります。

5. もっと便利なキーマッピングを考案する

私は、以下のショートカットを毎日のように使っています。これで何カ月分もの時間を節約できているはずです。

貼り付けたテキストの末尾へ自動的に移動する

pppppと押すだけで、複数行の貼り付けを繰り返し実行できます。

vnoremap <silent> y y`]
vnoremap <silent> p p`]
nnoremap <silent> p p`]

貼り付け時にペーストバッファが上書きされないようにする

テキストを選択してその上に貼り付ける時に、削除しようとしているテキストでペーストバッファが上書きされてしまう心配がありません(以下のコードを~/vimrcの末尾付近に置きます)。

" vp doesn't replace paste buffer
function! RestoreRegister()
  let @" = s:restore_reg
  return ''
endfunction
function! s:Repl()
  let s:restore_reg = @"
  return "p@=RestoreRegister()\<cr>"
endfunction
vmap <silent> <expr> p <sid>Repl()
  • 12<Enter>を押して、12行目に移動する(12Gだと手首が曲がってしまう)
  • Enterを押して、ファイルの末尾に移動する
  • Backspaceを押して、ファイルの先頭に移動する
nnoremap <CR> G
nnoremap <BS> gg

貼り付けたテキストを素早く選択する

noremap gV `[v`]

不要なウィンドウのポップアップを抑制する

map q: :q

6. 単体テストをシームレス化する

vim-roomを使い、テストに合うようにtmuxを設定しました。

vim-roomでは、<Leader>rを押すとテストスイートが実行されるようになっています。私は<Space>をLeaderに使っているので、<Space>rを押すとテストが実行されます。

tmuxで画面を分割してテストを行うため、次の項目の開発に移りつつ、常にコードを確認しながらテストを実行することができます。

7. Ctrl-Zを使ってVimにスイッチバックする

私は度々、シェルでランダムなコマンドを実行する必要があります。そういった場合、Ctrl-zを押してVimを一時停止しておきます。そしてコマンドを打ち込んだら、fg<Enter>を押してVimにスイッチバックします。

しかし、個人的には、fgを使うのは嫌でした。もう一度、Ctrl-zを押してVimにスイッチバックしたかったのです。ソリューションが見つからなかったので自分で開発したところ、ZSH上でうまく動作しています。

fancy-ctrl-z () {
  if [[ $#BUFFER -eq 0 ]]; then
    BUFFER="fg"
    zle accept-line
  else
    zle push-input
    zle clear-screen
  fi
}
zle -N fancy-ctrl-z
bindkey '^Z' fancy-ctrl-z

これを自分の~/.zshrcに貼り付けると、シェルとVimを非常に素早く切り替えることができるようになります。ぜひ試してみてください。

8. tmuxを正しくセットアップする

tmuxとOS XとVimは、かなり難しい組み合わせです。理由は以下の通りです。

  • システムのクリップボード処理に弱い
  • Vimとtmuxのウィンドウ間のナビゲーションが難しい
  • tmuxコマンド(C-b)が実行しづらい
  • tmuxのコピーモードを使うのが大変

かなりの時間を費やして調整したところ、以下のような結果に至りました。

tmuxの新しいプレフィックスキーとして<C-Space>をバインドする

マッピングに<C-a>を使う人がいますが、私は行の先頭に移動するショートカットキーとして使っていますので対象外です。その上、<C-Space>の方がはるかに便利です。その理由は、後で説明します。

unbind C-b
set -g prefix C-Space
bind Space send-prefix

<Space>をバインドしてコピーモードに切り替わるようにする

考えてみてください。<C-Space><Space>を押すだけで、tmuxのコピーモードに切り替えられるようになるのです。

bind Space copy-mode
bind C-Space copy-mode

OSX上でyreattach-to-user-namespaceを使う

システムのクリップボードにコピーするには、brew install reattach-to-user-namespaceを事前に実行します。

bind-key -t vi-copy y \
  copy-pipe "reattach-to-user-namespace pbcopy"

vim-tmux-navigatorを使う

<C-j><C-k><C-l>を使って、Vimとtmuxウィンドウのいずれの組み合わせでも、シームレスに切り替えることができます。

また、tmuxのウィンドウを分割するには、以下のキーバインドを使うことをお勧めします。<C-Space>l<C-Space>j<C-Space>%<C-Space>|に比べると、明らかに速く押すことができます。

bind j split-window -v
bind C-j split-window -v

bind l split-window -h
bind C-l split-window -h

詳しい情報についてはtmux.confをご覧ください。

9. GitプロジェクトのCtrl-Pプラグインを高速化する

以下のコードを.vimrcに挿入します(そうすることで、CtrIPがオートコンプリートにgitまたはThe Silver Searcherを使うように設定されます)。

let g:ctrlp_use_caching = 0
if executable('ag')
    set grepprg=ag\ --nogroup\ --nocolor

    let g:ctrlp_user_command = 'ag %s -l --nocolor -g ""'
else
  let g:ctrlp_user_command = ['.git', 'cd %s && git ls-files . -co --exclude-standard', 'find %s -type f']
  let g:ctrlp_prompt_mappings = {
    \ 'AcceptSelection("e")': ['<space>', '<cr>', '<2-LeftMouse>'],
    \ }
endif

vim-scripts/gitignoreを使うことをお勧めします。

10. パッケージマネージャを使う

neobundle.vimは、以下の点でVimプラグインの管理に非常に役立ちます。

  • gitサブモジュール(pathogen)を手動で管理しなくても済むようになる
  • 複数のプラグインが並行してインストールおよび更新される
  • 以下のYouCompleteMeのようなプラグインをビルドできる
NeoBundle 'Valloric/YouCompleteMe', {
      \ 'build' : {
      \     'mac' : './install.sh',
      \    },
      \ }
  • あるいは、以下のpryプラグインのようにカスタムパスからフェッチできる
NeoBundle 'rking/pry-de', {'rtp': 'vim/'}

11. Vimプラグインを活用する

私は、生産性を高めるために以下の一般的なプラグインを利用しています。

NeoBundle 'bling/vim-airline'
let g:airline_theme='powerlineish'
let g:airline_left_sep=''
let g:airline_right_sep=''
let g:airline_section_z=''

私はRuby開発者なので、以下のRubyプラグインも使っています。

12. Vimをサーバで素早くセットアップできるようにする

私は、サーバを構成するために頻繁にVimを使う必要があります。残念がなら、Vimには私にとって都合の良いデフォルト設定がないのでそのまま使うことはできません。

vim-sensibleが役に立つこともあるかもしれませんが、私の場合、それでは不十分でした。そこで、(特にRuby開発者にとって)非常に便利なデフォルト設定をもつvimrcプラグインを開発し、~/.vimrcがVim構成のシングルソースになるようにしました。このプラグインには、デフォルトスキーマ、パッケージマネージャ、多言語構文サポートも含まれています。

つまり、サーバサイドでVimを構成するために~/.vimディレクトリを台無しにしなくても済むということです。以下のようにして簡単にVim環境をサーバにインストールすることができます。

git clone --recursive https://github.com/sheerun/vimrc.git ~/.vim

また、独自のdotfilesも開発したので、開発環境をあっという間にセットアップできるようになりました。

自分で考えることが重要

Vimのセットアップを有効なものにするための秘訣は、開発時に遭遇する問題を常に認識し、それらに対処することです。

対処の手段は、.vimrcによるクイックマッピング、Google検索、IRCでのチャットなど、どのようなものでも構いません。

どのようにしてVimの生産性を高めることができるか考えてみてください。

さらに詳しい情報が必要な場合

Vimコンサルタントとしてご相談に乗ります。ご連絡はEメールでお願いします。