テキストデータや文章を編集している際、別の行に書いてあるデータやテキストを見ながら編集を行いたいことがある。通常は、必要な行に移動してデータを確認し、編集していた場所に戻って書くか、見たい行をコピー&ペーストで別の場所に一時的にコピーし、それを見ながら作業することになる。

だが、こんなときにはVimの折り畳み機能を使うとよい。折り畳み機能は、文字通り選択した部分の表示を折り畳んで隠す機能だ。邪魔な行を選択して一時的に折り畳めば、1画面の中に必要なデータだけを表示することができ、スクロールしなくても作業できる。特に、データファイルを編集/分析する際や、プログラミングの際には便利だろう。今回は、この機能の使い方を紹介する。

最低限覚えるのは「zf」と「zR」

折り畳みを行う方法はいくつかある。折り畳みはネストすることもできるし、インデントと関係付けることもできる。折り畳みに関係する操作はいくつも用意されている。ここでは、それらの中で「これだけ知っておけば良い」という操作のみをピックアップして紹介しよう。汎用的に使える便利な機能だけを最初に覚えて、その操作では足りないと思ったら調べて細かい操作方法を覚えてもらえればと思う。

折り畳みの操作は次の手順で行う(これ以外の方法もあるが、この手順を覚えておけば大体の操作はできるはずだ)。

  1. 折り畳みたい範囲をビジュアル行選択
  2. 「zf」を実行する


折り畳み系の命令には、「z」から始まるショートカットキーが設定されている。これは「z」という文字が、紙を折り畳んだところを横から見たビジュアルに似ているからだとされている。そして最初に覚えるべきはビジュアル選択してから「zf」だ。これで選択した範囲が折り畳まれる。

次のサンプルを見てみよう。まず、折り畳みたい範囲をビジュアル行選択する。

折り畳みたい範囲をビジュアル行選択する

選択した状態で「zf」と入力する。

「zf」と入力

すると、次のように選択しておいた領域が1行へ折り畳まれる。これは覚えておくと便利なので、何度か操作して覚えてしまうとよい。「折り畳む」は英語で「fold」だ。「z」が折り畳むときのかたちで、「f」が折り畳みを意味する「fold」の頭文字。一度意味がわかれば、覚えやすいだろう。

折り畳み済み

折り畳みは次のようにいくつも作成することができる。

いくつも折り畳んた状態

折り畳みを展開する方法はいくつか用意されているのだが、ここではスペースキーを使う方法を取り上げておく。次のように折り畳んだ行へカーソルを移動させ、スペースキーを押す。

折り畳んだ行へカーソルを移動させてスペースキーを押す

これで折り畳みが展開される。

折り畳み展開済み

折り畳みの展開については、もう1つ、「zR」だけは覚えておきたい。スペースキーで展開することはできるが、このやり方だと折り畳んだ場所全てでスペースキーを押して回ることになる。zRを使うと、折り畳んだものを一気に展開することができるのだ。「展開する」の意味になる「Release」の頭文字だと覚えておくとわかりやすいだろう(ちなみに「zD」でも似たようなことができる)。

次のサンプルを見てみよう。複数箇所が折り畳まれている。この状態で「zR」と入力する。

「zR」と入力

すると次のように折り畳みが全て展開される。

折り畳みが全て展開されている

ビジュアル行選択からの「zf」、折り畳まれた場所でスペースキーを押して展開、「zR」で折りたたみ箇所を全展開、だ。この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
nnoremap k gk
nnoremap gk k
nnoremap j gj
nnoremap gj j
nnoremap q b
vnoremap q b
nnoremap <Tab> 15<Right>
nnoremap <S-Tab> 15<Left>
nnoremap vis ?\(。\\|\.\\|^$\\|[>:]\)<CR>lv/\(。\\|\.\\|^$\\|<\\|:\)<CR>
nnoremap >< /<\([^>/]\+\)><\/\1><CR>/<<CR>
nnoremap <> ?<<CR>h?<\([^>/]\+\)><\/\1><CR>/<<CR>
nnoremap ( ?\(。\\|、\\|[.:][ \t\n]\\|[\[>]\)<CR>h?\(。\\|、\\|[.:][ \t\n]\\|[\[>]\)<CR>l
vnoremap ( hh?\(。\\|、\\|[.:][ \t\n]\\|[\[>]\)<CR>l
nnoremap ) /\(。\\|、\\|[.:][ \t\n]\\|^\n\)<CR>l
vnoremap ) /\(。\\|、\\|[.:][ \t\n]\\|<\/\\|^\n\)<CR>
nnoremap "" /""<CR>l
nnoremap '' /''<CR>l
nnoremap :: hh?""<CR>l
nnoremap ;; hh?''<CR>l
nnoremap <C-a> <Home>
inoremap <C-a> <Home>
cnoremap <C-a> <Home>
vnoremap <C-a> <Home>
nnoremap <C-e> <End>
inoremap <C-e> <End>
cnoremap <C-e> <End>
vnoremap <C-e> <End>