クォーテーションや括弧の中を削除するスキル

Vimはちょっとしたテクニックの積み重ねで使い勝手が大きく向上するエディタだ。したがって、時々スキルを見直し、より効率の良い操作方法を覚えていくリファイン作業はとても大切である。ここのところ、プラグインを使ってVimの機能を拡張する方法を紹介してきたが、この辺りでいったん基本に戻り、Vimのデフォルトの機能で使い勝手の良いものを紹介していこう。

今回はテキストの削除に関するスキルを取り上げる。具体的には、次のようなXML形式のテキストファイルを編集することを考えてみよう。

編集対象のファイル

上記スクリーンショットでは、カーソルが「”(ダブルクォーテーション)」に囲まれている。XML形式のファイルでは、このように属性値がダブルクォーテーションで囲まれているのだが、このダブルクォーテーションの中のテキストを削除したいときがある。まず思いつくのは、「x」を連打したり、「数字x」みたいな指定で削除したり、ビジュアル選択してから「x」や「d」で削除したりといった方法だろう。先頭の「”」に移動してから「lv/”↩️d」といった操作でもよい。だが、Vimにはもっと簡単な操作方法がある。

次のように「”“」の内側にカーソルがある状態で「di”」と入力してみよう。

ダブルクォーテーションの中のテキストを削除

実行すると次のようになる。ダブルクォーテーションの中のテキストが削除されたことがわかる。

ダブルクォーテーションの中のテキストが削除されている

「di”」というのは「d=削除 i=内側を “=ダブルクォーテーションの」という意味になる。鋭い方なら、これだけわかればかなりの応用ができるようになるはずだ。「di’」とすれば「シングルクォーテーションの内側のテキストを削除」という意味になる。

この削除方法は括弧に対しても適用できる点が強力だ。括弧を指定する場合、指定する括弧は始まりの括弧でも終わりの括弧でもよい。例えば、次のスクリーンショットではカーソルが「[]」の内側にあるわけだが、この場合には「di[」または「di]」で括弧の中を削除という意味になる。

「di[」または「di]」で括弧の中を削除

実行すると次のようになる。

「di[」または「di]」で括弧の中を削除した後

例えば、このファイルはXML形式なので、タグがそもそも「<」と「>」に囲まれているわけで、これも同じ要領で削除できる。次のような感じだ。

タグ名も括弧で囲まれているので同じ要領で削除可能

実行すると次のようになる。

タグ名を削除

「di」の「i」は「内側」という指定だったわけだが、この部分を「a」に変えると括弧やクォーテーションも含めて削除が行われる。次の「da[」または「da]」を実行する例をご覧いただきたい。

「da[」または「da]」で括弧も含めて削除

実行すると次のようになる。括弧も含めて削除されていることがわかる。

「da[」または「da]」で括弧も含めて削除した後

簡単な操作だが、このやり方は便利だ。特に、XMLやHTMLのようにダブルクォーテーションが多用されるテキストでは、この削除方法が威力を発揮する。

「di」による削除には、もう少し抽象的な指定も用意されており、「dit」」で「タグの中身を削除」という操作を行うことができる。次の例を見てみよう。

「dit」でタグの中身を削除

実行すると次のようになる。

「dit」でタグの中身を削除した後

タグの中身だけが削除されたことがわかる。

「di」や「da」のような指定による操作はVimにはたくさんある。最初は飲み込みづらい操作方法かもしれないが、この手の操作方法をたくさん知っているとそれだけで作業効率が大きく違ってくる。思考と操作が直結するというか、「ここを削除したい」みたいな思考をそのまま3回のストロークで実現できる。慣れてくるとこれは病みつきになる操作感覚だ。

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

プラグインを使うために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