本連載では、ここしばらくCSVデータを扱うプラグインである「chrisbra/csv.vim」について取り上げてきた。このプラグインはCSVデータをスプレッドシートアプリケーションのように整えて表示する機能があることはすでに説明済みだ。この「そろえる」機能だけに特化したプラグインも複数存在している。今回からは、そうしたプラグインの一つである「vim-easy-align」を取り上げていく。このプラグインも、chrisbra/csv.vimと同様に利便性が高い。適用できるシーンで考えると、むしろvim-easy-alignのほうが便利かもしれない。

メールやWebページに、テキストベースのテーブルデータが掲載されているのを見たことはないだろうか。フォントがモノスペース系であることが前提となるわけだが、よくもまあテキストデータだけでここまで綺麗に表として整えたものだと関心してしまう。手動で編集しているとすれば、それはとても面倒なことだ。しかし、Vimとvim-easy-alignを使うと整える作業が一発で完了する。手動で編集している方も多いと思うが、このようにプラグインを使って自動で整えている方も多いのだ。

こうした「整える」作業は表データに限ったものではない。最もよくあるのは次のようなデータを揃えたいといったものではないだろうか。

「:」でデータをそろえたい

このように「項目」「値」という2つのデータで構成されたデータを表のようにそろえたいというのはよくあることだ。手動でそろえることはできるのだが、データ量が増えると、その方法はあまり現実的ではなくなってくる。Vimの機能を使ってコマンドである程度自動化することもできるが、できれば一発でそろえてほしい。

vim-easy-alignはそういう場合に使えるプラグインだ。例えば、次のように「vipga」とコマンドを入力すると(もちろんこれを機能させるには設定が必要だ)データが選択され、そろえる対象として認識される。「vip」はVimのデフォルト機能でデータをビジュアルに選択するというもので、「ga」が設定したコマンドでvim-easy-alignの機能を呼び出している部分だ。

vim-easy-alignでデータをそろえる前段階

ここで「:」を入力すると、次のようにデータが「:」でそろうようになる。

「:」でそろえて表示

試しに、そろえる操作を「:」から「←:」にすると次のようなそろえ方になる。

「←:」でそろえて表示

この辺りは自分で設定できるので、求める挙動を設定すればよい(上記もある程度カスタム設定を行った状態での動作なので、実はデフォルトの挙動とは少し異なる)。vim-easy-alignがある程度デフォルトで設定を施しており、多くのシーンで問題なく適用できるような状態になっている。自分の求める動作がそれと異なっている場合には、自分で設定を行ってカスタマイズすればよい。これまで手動、またはVimコマンドを駆使して行っていた「そろえる」作業が一発で終わるのは、作業効率の向上に大きくつながるはずだ。じっくり使い方を習得しておきたいプラグインだと言える。

インタラクティブモード

今後、何回かはvim-easy-alignプラグインについて取り上げていく予定だが、最初に、このプラグインには主に以下の3つの使い方があることを説明しておく必要があるだろう。

  • インタラクティブモード
  • ライブインタラクティブモード
  • 非インタラクティブモード


それぞれに特徴があり、最終的にはユーザーが好みで使えばよいのだが、ここでは「インタラクティブモード」での操作を取り上げることにする。それは、このモードが最も扱いやすく覚えることが少なくて済むからだ。カスタマイズ性ではライブインタラクティブモードや非インタラクティブモードのほうが融通が効くのだが、その方法を覚えておくのは至難の業というか、面倒すぎる。

カスタマイズはライブインタラクティブモードや非インタラクティブモードではなく、調べて設定ファイルに記述することにして、基本的にインタラクティブモードで楽をする。多くのユーザーには、これがよいのではないかと思う。

vim-easy-alignの設定

それではvim-easy-alignを利用できるようにしよう。連載でこれまでに作った設定ファイルは、稿末に掲載しておくので、それを使っていただきたい。設定ファイルから、以下の行を探してほしい。

  call dein#add('sheerun/vim-polyglot')

上記を、次のようにプラグインとして「junegunn/vim-easy-align」を使う設定に書き換える。これで、次にVimを起動したときにvim-easy-alignプラグインが自動的にインストールされるようになる。

  call dein#add('sheerun/vim-polyglot')
  call dein#add('junegunn/vim-easy-align')

次にvim-easy-align自体の設定を追加する。次の部分を探してほしい。

" fzf
nnoremap <silent> fzf :Files<CR>
nnoremap <silent> ls :Buffers<CR>

上記を、以下のように変更する。

" fzf
nnoremap <silent> fzf :Files<CR>
nnoremap <silent> ls :Buffers<CR>

" vim-easy-align
xmap ga <Plug>(EasyAlign)
nmap ga <Plug>(EasyAlign)

vim-easy-alignは「:EasyAlign」で機能を呼び出すことができる。上記の設定を追加しておけば、ノーマルモードやビジュアルモードで「ga」と入力すると「EasyAlign」が呼び出されるようになる。「ga」に結び付けているのは、vim-easy-alignの説明文章がこの文字列に結び付けているためだ。「ga」が選ばれている理由は書いてないのでわからない。何か支障があれば、別の文字列に結び付けてもらえればと思う。

基本的にはそろえたい範囲をビジュアル選択で選んでから「ga」と入力するという流れになる。ビジュアル選択では「vip」で段落全体を選択することができるので、続けて入力すると「vipga」となる。日本語で「VIPが」となるので、フレーズとして覚えやすい気はする。

vim-easy-alignを使ってみよう

今回はvim-easy-alignの基本的な動作だけを取り上げる。より詳しい使い方は次回以降に取り上げるが、インタラクティブモードでvim-easy-alignを使うための基本的な方法は付録として以下に用意したので、試してみる場合には参考にしていただきたい。

例えば次のようなデータがあったとする。このデータを「:」の部分でそろえるとしよう。

そろえるデータサンプル

まず、対象データをビジュアル選択する。選択方法は何でもよいが、パラグラフとしてまとまったデータであれば「vip」という操作で簡単に選択できる。

「vip」でパラグラフごとビジュアル選択

ビジュアル選択した状態で「ga」と入力する。この状態で「ga」と入力した場合には「:EasyAlign」が実行されるように設定してあるので、次のように「:EasyAlign」が実行された状態になる。

「ga」で「:EasyAlign」が実行された状態になる

ここでデリミタとして「:」を入力すれば処理は完了だ。次のように「:」をベースにデータがそろう。

「:」をデリミタとしてデータが揃えられた後

vim-easy-alignは最初からある程度の設定が行われており、同じデリミタを入力した場合でも、データ形式によってデリミタそのものが揃ったり、デリミタそのものは前のデータの尻についた状態で揃ったりと、挙動が違っている。こうした挙動は細かく設定できるようになっているので、必要に応じてカスタマイズするというのが、このプラグインの最終目標ということになる。

データやコメント、またはプログラムを読みやすい状態に揃えておきたいというのはよくある要望だ。vim-easy-alignを使うとこの操作を効率的に行うことができる。見た目を整えるために手動で編集を行うというのはコンピュータの使い方としては本末転倒というか、そもそもそうした処理が得意なのがコンピュータなので、こうした処理は自動的に処理できるようにしていこう。見た目を整える処理は瞬時に終わるようにし、次の作業へ進む。そのために利用できるプラグインがvim-easy-alignだ。

付録: vim-easy-alignの主な設定と操作方法

操作 内容
ノーマルモードで:EasyAlignまたはビジュアルモードでga vim-easy-alignのインタラクティブモードを起動する。
デフォルトのデリミタ文字 備考
空白 = : , | . # & =は==や!=や+=といったように等号を含む演算子がデリミタと認識される。
Ctrl-X 正規表現 Ctrl-Xを入力するとそのあとはデリミタとして正規表現を使用できる。
キー 内容
デリミタ 最初に一致したデリミタで左揃え。
2デリミタ 2番目に一致したデリミタで左揃え。
3デリミタ 3番目に一致したデリミタで左揃え。
-デリミタ 最後に一致したデリミタで左揃え。
-2デリミタ 最後から1つ前に一致したデリミタで左揃え。
-3デリミタ 最後から2つ前に一致したデリミタで左揃え。
*デリミタ 一致したすべてのデリミタで左揃え。
**デリミタ 一致したすべてのデリミタで揃え(左揃えと右揃えを交互に適用)。
キー 位置 内容
↩️ 最初 押すごとに右揃え、中央揃え、左揃え、右揃え、中央揃え、左揃え… と揃えを変更。
ショートカットキー オプション 
Ctrl-F filter 文字列([gv]/.*/?)
Ctrl-I indentation shallow、deep、none、keep
Ctrl-L left_margin 数字または文字列
Ctrl-R right_margin 数字または文字列
Ctrl-D delimiter_align left、center、right
Ctrl-U ignore_unmatched 0、1
Ctrl-G ignore_groups [], [‘String’], [‘Comment’], [‘String’, ‘Comment’]
Ctrl-A align 文字列(/[lrc]+\*{0,2}/)
stick_to_left { ‘stick_to_left’: 1, ‘left_margin’: 0 }
stick_to_left { ‘stick_to_left’: 0, ‘left_margin’: 1 }
*_margin { ‘left_margin’: 0, ‘right_margin’: 0 }

付録: 使っている設定ファイルとセットアップ方法

プラグインを使うためにDeinをセットアップする方法

mkdir -p ~/.cache/dein
cd ~/.cache/dein/
curl https://raw.githubusercontent.com/Shougo/dein.vim/master/bin/installer.sh > installer.sh
sh ./installer.sh .
rm ./installer.sh

本連載で使っている~/.vimrcファイル

"dein Scripts=============================
if &compatible
  set nocompatible               " Be iMproved
endif

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

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

  " Let dein manage dein
  " Required:
  call dein#add('~/.cache/dein/./repos/github.com/Shougo/dein.vim')

  " Add or remove your plugins here
  call dein#add('junegunn/seoul256.vim')
  call dein#add('vim-airline/vim-airline')
  call dein#add('vim-airline/vim-airline-themes')
  call dein#add('preservim/nerdtree')
  call dein#add('tpope/vim-commentary')
  call dein#add('tpope/vim-fugitive')
  call dein#add('fholgado/minibufexpl.vim')
  call dein#add('dense-analysis/ale')
  call dein#add('junegunn/fzf', {'build': './install --all'})
  call dein#add('junegunn/fzf.vim')
  call dein#add('sheerun/vim-polyglot')
  call dein#add('junegunn/vim-easy-align')

  " Required:
  call dein#end()
  call dein#save_state()
endif

" Required:
filetype plugin indent on
syntax enable

" If you want to install not installed plugins on startup.
if dein#check_install()
  call dein#install()
endif

" seoul256
let g:seoul256_background = 233
colo seoul256

" vim-airline
let g:airline_powerline_fonts = 1
let g:airline_theme = 'molokai'

" NERDTree
"  <C-o> open NERDTree
nnoremap <silent> <C-o> :NERDTreeToggle<CR>

" minibufexpl
nnoremap <silent> bn :<C-u>:bnext<CR>
nnoremap <silent> b1 :<C-u>:b1<CR>
nnoremap <silent> b2 :<C-u>:b2<CR>
nnoremap <silent> b3 :<C-u>:b3<CR>
nnoremap <silent> b4 :<C-u>:b4<CR>
nnoremap <silent> b5 :<C-u>:b5<CR>
nnoremap <silent> b6 :<C-u>:b6<CR>
nnoremap <silent> b7 :<C-u>:b7<CR>
nnoremap <silent> b8 :<C-u>:b8<CR>
nnoremap <silent> b9 :<C-u>:b9<CR>

" fzf
nnoremap <silent> fzf :Files<CR>
nnoremap <silent> ls :Buffers<CR>

" vim-easy-align
xmap ga <Plug>(EasyAlign)
nmap ga <Plug>(EasyAlign)

"End dein Scripts=========================

set number
syntax on
set whichwrap=b,s,[,],<,>,~,h,l
set cursorline
set incsearch
set hlsearch
set ignorecase