コメントはデフォルトでは対象外

テキストデータをデリミタ区切りで表形式に整えるプラグイン「junegunn/vim-easy-align」では、コメントと一連の文字列は整理の対象として制御が可能になっている。特にデフォルトの設定ではコメントに対する整形処理が無効になっている。これは便利なこともあり、逆に不便なこともある。必要に応じてこの辺りの設定は変更して使う必要がある。

デフォルトの設定は基本的には便利なものだ。コメントは整形の対象とならないので、ブロック全体を選択して整形処理を行っても、コメントの内容は全く編集の対象とならない。コメントはそのままにデータや設定部分だけを整えることができるわけだ。基本的にはこの動作がデフォルトになっているのは理にかなっている。

逆にこの設定で困るのは、むしろコメント部分のテキストを整形したいケースだ。「コメントにデータシート的なものを書いておきたい」というニーズは、実はプログラミングや設定ファイルの編集ではよくあることだったりする。コメントに対してだけ整形処理をしたいことがあるのだ。今回はそうした処理の方法を紹介する。

デフォルトの動作 - コメントは無視

例として、極端なサンプルを用意してみた。次のテキストデータは、前回使った/etc/passwdの中身をシェルスクリプトに書き換えたもので、コメントとヒアドキュメントに同じデータを配置してある。

/etc/passwdのデータをシェルスクリプトに変換したサンプル

このファイルを次のように「vim-easy-align」で処理の対象として補足する。

「vipga」で全体を処理の対象として選択

「vip」でパラグラフごと選択しているので、コメントもスクリプトも両方とも選択されている。この状態で「*:」と入力して「:」をデリミタとして整理を行うと、次のような結果が得られる。

「*:」で「:」をデリミタとして整理

コメントが処理されていないことがわかるだろう。デフォルトの挙動としてはこれが便利なケースが多い。コメントの中身まで整理されると不便なケースは多い。

コメントだけを処理の対象とする

動作を確認するために、最初の状態に戻しておく。

サンプルのスクリプト

vim-easy-alignでは「g:easy_align_ignore_groups」という変数で処理対象を設定することができる。保持するデータはリストで、値としては「String」「Comment」「!String」「!Comment」を取る。これは「どのデータを処理対象として無視するか」を決めるもので、「Comment」が指定されていればコメントは整形対象として処理されない、ということになる。「!String」と「!Comment」は逆の指定で、例えば「!Comment」が指定されていると、コメントだけを処理対象とするようになる。

例えば、次のように設定を行うとしよう。

:let g:easy_align_ignore_groups = ['!Comment']

:let g:easy_align_ignore_groups = [‘!Comment’]でコメントだけを処理対象とする

この状態でvim-easy-alignによる処理に入ってみよう。

「vipga」でvim-easy-alignによる処理に入る

「*:」で整形を実行すると、次のようになる。今度はコメントだけに処理が適用されたことがわかる。

今度はコメントだけが整形されたことを確認

「g:easy_align_ignore_groups」をその都度設定するのは面倒すぎる。デフォルトの設定を変更する必要があるケースはある程度条件が決まっていると思うので、それに合わせて設定ファイルを書いておくのがよい。上記のように直接「g:easy_align_ignore_groups」を変更してしまうと影響が大きすぎるので、条件に応じてさらに絞り込みを行った状態の設定を行うのが良いだろう。詳細な設定方法については、vim-easy-alignを解説する最後の回にまとめとして取り上げる予定だ。

ブロックを意識した整形

揃えたいデータは構造化されていることがある。特定のブロックに入っているとか、すでにインデントされているといった場合だ。例えば、次のようなデータを考えてみよう。設定は上記の続きで、コメントのみが整形の対象になっているとする。

処理対象のスクリプトサンプル

この状態で「vipga→*:」とすれば、次のように整理が行われる。

「vipga」で処理を開始

「→*:」で整形を実施

ここで3行目に注目したい。3行目も同じように整理されているが、整理せずに「Example:」のまま残っておいてほしいとしよう。その場合、処理は簡単で、ビジュアル選択する対象を絞り込むだけでよい。例えば4行目にカーソルがある状態で「V20G」とすれば、次のようにコメントの処理したい対象だけがビジュアル選択の対象となる。

処理したい対象をビジュアル選択

この状態で「→*:」と実行すると、3行目はそのままに、4行目以下のコメントデータを整えられることがわかる。

対象だけが整理される

「整理する対象をビジュアル選択する」というのはvim-easy-alignがドキュメントでも紹介している方法なので、vim-easy-alignが推奨する方法ということになるのではないだろうか。今回はスクリプトをサンプルとして取り上げたが、JSONのような構造化されたデータに対して、この方法はなかなか効果的なようだ。ぜひ試してみていただきたい。

付録: 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