営業の枠から飛び出せ!
営業の枠から飛び出せ!
2019.05.16

僕がVimで愛用しているプラグイン30連発

まさくに

こんにちは。バックエンドエンジニアのまさくにです。

最近、「もう少しだけ生きたい」ということを思い(単に健康診断で怒られました)、「完全食」なるものを購入し、流動食のような粉っぽい何かを飲みながらジムに行く日々を送っています。栄養は理論上全部足りているという完全食で、致命的にたりていないものがありました。

満足感だ。

ずばり、完全食という名前ながら、皮肉にも「食べるってなんだっけかな?」と行為の意味を考えさせられます。でもひとまず、続けられそうだし、何となく体調もいい気がします。

さて、VimVim。Vimの話をしましょうか。プラグインです。プラグイン、皆さんはどのようなものを使っていますか。Vim Awesome、楽しいですね。

今回は僕が愛用しているプラグインを30個無造作に並べてみました。有名なものばかりなので今さらではありますけれど、どのプラグインもおすすめです。

なお、この一覧の中には、特定の言語の補完やLinterは省き、テーマも除いています。また下の各種プラグインの実行に僕はNeovim v0.3.3を使っていますが、本家Vimでもバージョンが合えば動くはずです。Neovimを使っている経緯なんかは下記をどうぞ。今回の話と重複している部分もあります。

目次

  1. プラグイン管理
  2. ファイル周辺情報表示、操作
  3. エディタ強化
  4. ツール
  5. もう自然に帰れない

プラグイン管理

dein.vim/プラグインマネージャー

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

もうこれは使っているというか何というか、アレですね。プラグインを管理するためのプラグイン。Vim 8.0以降かNeovimで動き、NeoBundleの後継にあたります。これ以降のプラグインはすべてこのdeinを介してインストールしているので、これがなければ始まりません。特殊な使い方は何もしておらず、下記のような設定で他のプラグインのインストール、ロードに使っています。

set runtimepath+=~/.cache/dein/repos/github.com/Shougo/dein.vim

if dein#load_state('~/.cache/dein')
  call dein#begin('~/.cache/dein')

  call dein#add('some/plugin')

  call dein#end()
  call dein#save_state()
endif

ファイル周辺情報表示、操作

nerdtree/ツリー状ファイルビューワ


https://github.com/scrooloose/nerdtree

たぶん一番有名なツリー状のファイルビューワ。使いやすい。ツリービュー内ではC-nとC-pが5行ずつ上下に動くように設定しておき、ジャンプしながらファイルを辿れるようにしてあります。下記のような設定にしてあります。

nnoremap <silent> <Leader>e :<C-u>NERDTreeToggle<CR>

" 表示幅
let g:NERDTreeWinSize=50

" ブックマークを表示
let g:NERDTreeShowBookmarks=1

" 親ディレクトリへ移動
let g:NERDTreeMapUpdir='<C-u>'

" ファイルの開き方
let g:NERDTreeMapOpenSplit='<C-j>'
let g:NERDTreeMapOpenVSplit='<C-l>'

" ファイルを開いたらNERDTreeを閉じる
let g:NERDTreeQuitOnOpen=1

" 隠しファイルを表示
let g:NERDTreeShowHidden=1

" 非表示ファイル
let g:NERDTreeIgnore=['\.git$', '\.clean$', '\.swp$', '\.bak$', '\~$']

augroup vimrc_nerdtree
  autocmd!
  " 他のバッファをすべて閉じた時にNERDTreeが開いていたらNERDTreeも一緒に閉じる。
  autocmd bufenter * if (winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree()) | q | endif

  " Tree内では5ずつ移動する
  autocmd FileType nerdtree nnoremap 5j
  autocmd FileType nerdtree nnoremap 5k
augroup END

lightline.vim/ステータスラインをリッチにする

https://github.com/itchyny/lightline.vim

ステータスラインを変更するために、いくつか類似のプラグインはあると思うのですが、僕はこれ。あまり華美ではなく、必要な情報が必要なだけ表示できてると思います。テーマとしてhybridも見つけたので、特に過不足を感じていません。

let g:lightline = {
  \ 'colorscheme': 'hybrid',
  \ 'active': {
  \ 'left': [ [ 'mode', 'paste' ],
  \ [ 'fugitive', 'readonly', 'filename', 'modified' ],
  \ [ 'ale' ] ]
  \ },
  \ 'component': {
  \ 'readonly': '%{&filetype=="help"?"":&readonly?"ro":""}',
  \ 'modified': '%{&filetype=="help"?"":&modified?"+":&modifiable?"":"-"}',
  \ 'fugitive': '%{exists("*fugitive#head")?fugitive#head():""}'
  \ },
  \ 'component_visible_condition': {
  \ 'readonly': '(&filetype!="help"&& &readonly)',
  \ 'modified': '(&filetype!="help"&&(&modified||!&modifiable))',
  \ 'fugitive': '(exists("*fugitive#head") && ""!=fugitive#head())'
  \ },
  \ 'component_function': {
  \ 'ale': 'LinterStatus'
  \ }
  \ }

function! LinterStatus() abort
  let l:counts = ale#statusline#Count(bufnr(''))

  let l:all_errors = l:counts.error + l:counts.style_error
  let l:all_non_errors = l:counts.total - l:all_errors

  return l:counts.total == 0 ? 'OK' : printf(
  \ '%dW %dE',
  \ all_non_errors,
  \ all_errors
  \)
endfunction

vim-gitgutter/変更箇所を左端に表示する

https://github.com/airblade/vim-gitgutter

Gitでの変更行などの差分を左側に表示することができます。地味だけど変更箇所に飛べるのはかなり便利。ただ、したいことに対してプラグインがオーバーキル気味な気がしています。

nmap <silent> <C-g><C-n> <Plug>GitGutterNextHunk
nmap <silent> <C-g><C-p> <Plug>GitGutterPrevHunk

vim-fugitive/Git操作をする

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

Vim上でGitの操作ができるようになるVim Awesomeでもトップを走るプラグインですね。うーん。愛用と言っていますが、僕、そんな……使わない……かもしれませんね? lightlineで結果を表示しているので、常に使っていると言えば使っているのですが、明示的にGblameとかを叩くことはめったにありません。Gstatusとか参照系ならまだいいんですけど、GremoveやGcommitは少し、コマンドでやらないと打つのをためらってしまう方です。

vim-tags/ctagsを実行する

https://github.com/szw/vim-tags
(universal-ctagsでは動きません)

自動でctagsを走らせたりしてくれるやつ、のはずなんですが、たぶんuniversal-ctagsに対応してないんです。更新が2015年から止まり、プルリクもマージされていません。なので、僕はこれをFolkして微修正を行って使っています。後述のfzf.vimと組み合わせるとタグをインクリメンタルサーチすることができてとても便利。

" コアファイルも含めるため.gitignoreを無視
let g:vim_tags_ignore_files = []

tagbar/スクリプトの構造を右端に表示する

https://github.com/majutsushi/tagbar

タグが作られたソースコードのclassやmethodを非常に見やすく右側に表示してくれるプラグインです。逆に言うと、タグが作られていなければ無用の長物なので、定期的にctagsを動かす必要があります。

nnoremap <silent> <Leader>t :<C-u>TagbarToggle<CR>

vim-showmarks/マークを左端に表示する

https://github.com/jacquesbh/vim-showmarks

Vimのマーク機能って、それはもうビジュアルにまったく訴えかけてこないので、記憶だけが頼りの、それってもうマークした意味あんのかなって感じだったんですけれど、このプラグインを使うとマークした場所を左側に表示してくれます。これも後述のfzfを使うことによって、インクリメンタルサーチでタグをした場所を絞って移動することができます。

augroup show_marks_sync
  autocmd!
  autocmd BufReadPost * silent! DoShowMarks
augroup END

fzf.vim/何でもインクリメンタルサーチ


https://github.com/junegunn/fzf.vim

これもうすっごいからパートワン。

インクリメンタルサーチができるfzfコマンドを介して、ファイルビューワやらgrepやら、ctagsの検索やらが高速にできるようになります。そのため、このプラグインを使うにはfzfをインストールしておいてくださいね。このfzf.vimでfzf自体をインストールはできるのですが、fzfはとても強力なコマンドであるため、Vim以外でも使うと嬉しいことが次々と起きると思います。brewなんかでインストールできます。その場合はfzfへのパスを通すため、下記のようにrtpでパスを設定してあげてください。

set rtp+=/usr/local/opt/fzf
  let g:fzf_buffers_jump = 1
  nnoremap <silent> <Leader>ff :<C-u>Ag<CR>
  nnoremap <silent> <Leader>fh :<C-u>History<CR>
  nnoremap <silent> <Leader>ft :<C-u>call fzf#vim#tags(expand('<cword>'))<CR>
  nnoremap <silent> <Leader>fb :<C-u>Buffers<CR>
  nnoremap <silent> <Leader>fgs :<C-u>GFiles?<CR>
  nnoremap <silent> <Leader>fgf :<C-u>GFiles<CR>
  nnoremap <silent> <Leader>fm :<C-u>Marks<CR>
  let g:fzf_layout = { 'down': '30%' }
  let g:fzf_action = {
    \ 'ctrl-t': 'tab split',
    \ 'ctrl-j': 'split',
    \ 'ctrl-l': 'vsplit' }

  augroup vimrc_fzf
      autocmd!
      autocmd FileType fzf tnoremap <buffer> <leader>z <Esc>
  augroup END

エディタ強化

supertab/タブ補完

https://github.com/ervandew/supertab

タブで補完をしてくれるようになる憎いやつ。導入するだけで、他のIDEでは常識だと思うんですけれど、タブ補完をVimでもできるようになります。なんか自分でもいろいろ設定してダメだったことがあるのですが、これで一発でした。シンプルながら力強いプラグイン。

vim-polyglot/一括で多種言語パックを扱う

https://github.com/sheerun/vim-polyglot

130以上の言語パック。とりあえず入れているだけですが、サポートをしてくれているようです。ただ、Markdownのコード部分のところだけ、テーマとの相性が悪かったのか見えなくなってしまったのでMarkdownを無効にしてあります。

let g:polyglot_disabled = ['markdown']

NERD Commenter/コメントアウトする

https://github.com/scrooloose/nerdcommenter

言語に合わせてコメント化を簡単にしてくれるプラグイン。これ系のやつは有名なところでcommentaryや、tCommentなど、あると思うんですけど、NERDTreeと合わせるのも一興と思って、こちらを愛用しています。<Leader>ccで対象行をコメントアウトしてくれます。<Leader>c<Space>でトグルなので、基本的に僕はこっちを使います。

auto-pairs/カッコ閉じる

https://github.com/jiangmiao/auto-pairs

endwize.vimじゃなくて、言語全般対応してくれるのないかなぁと探して見つけたオートクロージングっていうんですかね、カッコを書き始めたら閉じてくれます。{}も[]も''も""もすぐに閉じてくれます。マークダウンの```なんかも閉じてくれます。時々融通が利かないのは、設定で何とかなるのかもしれません。

vim-surround/カッコ囲む

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

超有名、任意の範囲をクォーテーションやカッコで囲ってくれる(置換したりもできる)プラグインです。キー操作で複雑な文字列をカッコやクォーテーションで囲ったり、置換するのはいかにもVimらしいですね。僕はそんな複雑なことはできません。

vim-textobj-user/テキストオブジェクトを定義する

https://github.com/kana/vim-textobj-user

テキストオブジェクトを定義できるとんでもないやつなんですけれど、定義自体はそんな簡単ではなく、発想力が試されます。このプラグインに紐づいてプラグインがいくつか作られているので、主にそちらを使うことになると思います。後続のvim-textobj-blockwiseとvim-textobj-betweenがそれにあたります。

vim-textobj-blockwise/矩形をテキストオブジェクトにする

https://github.com/osyo-manga/vim-textobj-blockwise

矩形をテキストオブジェクトとして扱い、対象範囲とすることができるようになります。矩形を移動することなく選択することができます。前述のvim-textobj-userに依存しています。

vim-textobj-between/挟まれた文字列をテキストオブジェクトにする

https://github.com/thinca/vim-textobj-between

ある単語に挟まれた文字列を選択できるようになります。例えばスペースに挟まれているけど、その中には記号やらマルチバイトやらがあって、普通のテキストオブジェクトとしては選択できないときに使えます。便利です。前述のvim-textobj-userに依存しています。

vim-operator-user/オペレータを定義する

https://github.com/kana/vim-operator-user

textobj-userがテキストオブジェクトを自分で定義するものなら、こちらはオペレータを定義します。テキストオブジェクトに対して何をするか、ですね。これもvim-textobj-userと同じく、このプラグインに依存するプラグインがいくつか出ていて、そちらをインストールして使うと便利です。

vim-operator-replace/置換というオペレータを追加する


https://github.com/kana/vim-operator-replace

これもうすっごいからパートツー。

ヤンクした文字列で、カーソル配下のテキストオブジェクトと置換したいことあると思うんですけれど、そういうとき、「置換する」っていうデフォルトのオペレータがないじゃないですか。なので、一度カーソル下を消してレジスタから貼り付けるとかしなきゃならないと思うんですけれど、このプラグインを使うと、置換ができるようになります。前述のvim-operator-replaceに依存します。下記のような設定で、アンダースコアに充てていますが、あんまり使いやすくない(でもRやrは変えたくない)。

map _ <Plug>(operator-replace)

vim-repeat/繰り返せない操作を繰り返す

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

ドットコマンドってVimのデフォルト機能しか繰り返してくれないから、前述のvim-operator-replaceもそうなんですが、surround.vimとかも繰り返し以降は上手く動いてくれないんですね。それを問題なく動かしてくれるようになる魔性のプラグインです。

vim-expand-region/選択範囲を拡縮する


https://github.com/terryma/vim-expand-region

これもうすっごいからパートスリー。

もともとPOSTDに書かれていて知ることができたプラグインで、設定も同じようにさせてもらっています。vを押すたびに選択範囲が広がっていくのは、快感とさえ言える。Ctrl-vで選択範囲が狭まっていきます。

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

vim-easymotion/縦横無尽にジャンプする


https://github.com/easymotion/vim-easymotion

これもうすっごいからパートフォー。

Vimってジャンプでの移動が真髄じゃないですか。でもさらにそこからVimのジャンプという概念を進化させる凄いやつです。本当、これは感動もののプラグインなんですが、このプラグインを一度入れるとVimの操作が変わってしまうので邪法にさえ近いのではないかと思います。ウィンドウをまたいで移動するのが凄い。

map  <Leader>j <Plug>(easymotion-bd-w)
nmap <Leader>j <Plug>(easymotion-overwin-w)
map <Leader>l <Plug>(easymotion-bd-jk)
nmap <Leader>l <Plug>(easymotion-overwin-line)
map <Leader>k <Plug>(easymotion-bd-f)
nmap <Leader>k <Plug>(easymotion-overwin-f)

winresizer/ウィンドウサイズを変える


https://github.com/simeji/winresizer

これもうすっごいからパートファイブ。

いくつもウィンドウ開いていると、それぞれのサイズが必要としているものより小さかったり大きかったりすることありますよね。コマンドでそのサイズ変更はできるのですが、あまり直感的ではありません。ですがこれはフォーカスしているウィンドウのサイズをhjklで変更することができるようになるのです。感動した逸品。

vim-trailing-whitespace/行末のブランクを削除する

https://github.com/bronson/vim-trailing-whitespace

行末にブランクが入っちゃってることって地味にあると思うんですけれど、これはそのブランクを可視化してFixWhiteSpaceで削除してくれるプラグイン。地味に助かります。

comfortable-motion.vim/スムーズなスクロールをする


https://github.com/yuttie/comfortable-motion.vim

これもうすっごいからパートシックス。

VimのCtrl-fやCtr-bって、デジタルに切り替わってしまうので、ソースコード中の連続性が感じられず、頭に入ってこないことないですか。そのため僕はあえてCtrl-f、Ctrl-bを無効化してたりしていたんですけれど、このプラグインが凄いのは、スクロールしてくれるんです。これはあえてVimっぽくない動きなんですけど、スクロールしてくれるんです。ファイルを。そうすると頭の切り替えも追いついていくことができて、凄い自然に書けるんです。僕は。感動しました。物理演算してるらしいので、スクロールのパラメータを変更することができます。僕はいろいろ試してみて、下記にしています。

let g:comfortable_motion_interval = 2400.0 / 60
let g:comfortable_motion_friction = 100.0
let g:comfortable_motion_air_drag = 3.0

ツール

ale/非同期でLintを実行する

https://github.com/w0rp/ale

非同期でLinterなどを走らせるときに使っています。filetypeによって走らせるLinterを変えられるので、たとえばPHPであればphpcs、Pythonであればflake8などでチェックし、左側のラインにワーニングやエラーを出力するようにできます。あまりにもLintエラーが多いソースコードを開くと、かなり重さを感じるのですが、普通にコーディングする分には特に弊害を感じたことはありません。<C-a><C-n>で次のLintエラーに飛べるのは便利。

let g:ale_sign_column_always = 1
let g:ale_linters = {
      \ 'php': ['phpcs', 'php'],
      \ 'python': ['flake8']
      \}

let g:ale_php_phpcs_standard = 'PSR1,PSR2'
let g:ale_python_flake8_options="--ignore=E501"
let g:ale_statusline_format = ['E%d', 'W%d', '']

nmap <silent> <C-a><C-n> <Plug>(ale_next_wrap)
nmap <silent> <C-a><C-p> <Plug>(ale_previous_wrap)

vim-quickrun/スクリプトを実行する

https://github.com/thinca/vim-quickrun

実はあんまり使わないですよね。QuickRun。Vimから今書いているスクリプトを実行できるようになります。アプリケーションはどんどん高度になるし、スクリプトペライチで作ってVim上で実行ってことはとても少なくなりました。シェルスクリプトを書くときに、少し助かることが多いです。

open-browser.vim/ワードをググる

https://github.com/tyru/open-browser.vim

別に派手さはないんだけど実は超使ってる愛してる。Vimでワード指定するとブラウザが開き、Google検索をしてくれます。この記事を書くのにも非常に助けられました。結構いると思うんですよ。たとえばfunctionの名前はわかったけど、返り値が未知で調べたいとか、正直英単語の意味がわからんとか。ブラウザへのコピペの手間を減らしてくれます。ChromeもエクステンションでVimiumが入ってると、ブラウザにいってもVimライクなので快適。

nmap <Leader>b <Plug>(openbrowser-smart-search)
vmap <Leader>b <Plug>(openbrowser-smart-search)

calendar.vim/カレンダーを表示する

https://github.com/itchyny/calendar.vim

Vim上でカレンダーが確認できます。ここまでするか、って話ですよ。ブラウザ開けばよくない? ええ、ここまでするかって話なんですけど、ここまでだったら結構便利でした。下記の設定をしておくと、初回起動時にGoogle Calendarとの連携のため、トークンがブラウザから取得できます。

let g:calendar_google_calendar = 1

goyo.vim/禅モードで集中する


https://github.com/junegunn/goyo.vim

これもうすっごいからパートセブン。

いわゆる禅モードにVimを変更します。僕は全般文章をVimで書いているのですが、うるさい装飾が取り外され、ブログと同じくらいの横幅に変更されるこのGoyoプラグインは非常に助かっています。そう、この記事もGoyoから生み出されているのですよ。

もう自然に帰れない

「Vimは素の状態で使わなきゃ意味がない」というポリシーを掲げ、vimrcにもほとんど変更を加えないエンジニアが知り合いにいます。彼は性格からしてとてもストイックで自分に厳しいのですが、僕はそうはなれません。正直、プレーン状態のVimでどうやって進めているのか、開発風景が想像もできません。

逆にVimをIDEのように使う、という記事がいくつかありますが、正直IDEは凄すぎて、Vimの機能をそこまで持ち上げていくのは、難しいというか、僕は意味をあまり感じていません。SpaceVimとか、めちゃんこ凄いですね。起動してみたのですが、どうやら僕にはオーバーテクノロジーのようでした……。

Vimをもっと使っていく中で、今回挙げたプラグインから、僕はさらに増やしていくと思います。自分に合った機能を必要なぶんだけ、適材適所、試行錯誤しながら組み合わせていくのもVimの醍醐味ですよね。もう僕は自然には帰れないようです。ごめんな、ネイチャー。頑張るよ、ゴールデンウィークからの社会復帰。

それでは。まさくにでした。