はじめに: Vimならではの便利機能をマスターしよう!
かれこれ数年前、僕がVim(というか、たぶんVi)と初対面したときは、「なんて使いにくいエディタなんだ!!」と最悪の印象でした。
しかし、周りのプログラマやネット上のエンジニアたちはみんな「Vim便利!」「Vim最高!」と言います。
なのでその言葉を信じ、僕も最悪の印象だったVimともう一度正面から向き合うことにしました。
そして、月日が過ぎ・・・僕もいつしか「Vim便利!」「Vim最高!」と叫ぶようになってしまいました!!
これって洗脳?
いやいや、洗脳じゃありませんw
Vimにはメモ帳の延長線上にあるエディタでは実現できないような数々の便利な機能があります。
覚えるまでにはちょっと苦労しますが、覚えてしまえばメモ帳系のエディタでは追いつけないようなスピードでテキストを編集することができます。
とはいえ、そもそも覚える以前に「そんなコマンドがあるとは知らなかった」というのであれば、いつまで経っても作業効率は上がりません。
そこでこの記事では「これはVimならではだね!」と僕が個人的に感じている 便利機能ベスト25 をまとめました。(注: もともとベスト20だったのですが、さらに5個追加しました。)
さらに、言葉だけではその便利さが伝わりにくいので、すべてアニメーションGIF付きで説明しています。
Vimは使い始めたけど、まだイマイチ便利さがわからない、もっと便利な機能があるかもしれないけど、面倒くさくて調べてない、というVim初心者の方はぜひ参考にしてみてください!
また、本文の最後であなたの「Vimmerレベル」を診断するおまけコーナーも載せていますw
この記事ではMacVimを使っています
僕が普段使っているのはMacVimです。
動作確認もMacVimで行っています。
ただし、この記事で紹介している機能はMacVim以外のVimでも同じように動作するはずです。
さらに便利コマンドを追記するかも?
ネット上の反応を参考にしながら後日「みんなが知らなさそうな便利コマンド」をさらに追記するかもしれません。
この記事を「ストック」してもらうと、便利コマンドを追記した際に変更通知を受け取ることができます。
追記されるコマンドが気になる方は ストック をどうぞ!
カーソル移動・画面スクロール系
w/e/b/W/E/Bを使い分けて単語単位に移動する
ノーマルモードでw
とタイプすると、次の単語に移動します。
e
は単語の最後の文字に移動します。
b
は手前にある単語の先頭に移動します。
また、W
/E
/B
とタイプすると、ドット(.)やコロン(:)のような記号もひと続きの単語とみなして移動します。
3w
のように数字を付けてタイプすると「3つ先にある単語へ移動」という意味になります。
状況に応じて適切な移動用コマンドを使い分けると効率的です。
(2014.06.14追記) ge/gEで手前にある単語の末尾に移動する
ge
は手前にある単語の末尾に移動します。
gE
はW
/E
/B
と同じく、記号もひと続きの単語と見なして移動します。
H/M/Lでカーソルをウインドウ内の上/中/下に移動させる
ノーマルモードでH
とタイプすると、カーソルが現在表示されているウインドウ内の一番の上の行に移動します。
同様にM
で中央、L
で最下行に移動します。
z<enter>/z./z-で現在のカーソル位置を基準に画面をスクロールさせる
ノーマルモードでz<enter>
(またはzt
)とタイプすると、現在カーソルのある行が画面の一番上になるように画面がスクロールします。
同様に、z.
で中央、z-
で一番下にスクロールします。
Ctrl-f/Ctrl-b/Ctrl-e/Ctrl-yで画面を上下にスクロールさせる
ノーマルモードでCtrl-f
とタイプすると1画面分下へスクロールします。
Ctrl-b
は1画面分上へスクロールします。
Ctrl-e
は画面を1行分下へスクロールさせます。
Ctrl-y
は1行分上へスクロールさせます。
(2014.06.14追記) %で対応する括弧に移動する
()、{}、[]など、括弧を表す記号の上で%
をタイプすると、括弧の開始位置と終了位置にカーソルを移動させることができます。
括弧がたくさんあったり複雑にネストしているときは対応関係をすぐに把握できるので便利です。
(2014.06.14追記) gg/G/<数字>G(または:<数字>)で好きな行にカーソルを移動する
ノーマルモードでgg
をタイプすると、ファイルの先頭行にカーソルが移動します。
G
をタイプすると、ファイルの最終行に移動します。
14G
のように、<数字>G
とタイプすると指定した行番号へカーソルが移動します。(:14<enter>
のようにタイプしても同じ)
このコマンドを応用すると、ggVG
でファイル全体をビジュアル選択することができます。
編集系
i/a/s/cw/I/A/S/Cを使い分けて挿入モードに入る
ノーマルモードでi
とタイプすると、カーソルの左側に文字が挿入できるようになります。
a
とタイプするとカーソルの右側に文字が挿入できます。
s
はカーソル上の1文字を削除してから挿入モードに入ります。
cw
はカーソル上の単語を削除してから挿入モードに入ります。(単語の途中にカーソルがある場合は、そこから単語の末尾までを削除します)
また、I
は行の先頭から、A
は行の末尾から文字を挿入できます。
S
は行全体を削除してから挿入モードに入ります。
C
は現在のカーソルから行末までを削除してから挿入モードに入ります。
どれも基本のVimコマンドですが、状況に応じて一番タイプ量が少なく済むコマンドを選べるようになりましょう。
(2014.06.14追記) o/Oで新しい行を追加してから挿入モードに入る
o
とタイプすると、現在行の下に新たな行を追加して挿入モードに入ります。
O
とタイプすると、現在行の上に新たな行を追加して挿入モードに入ります。
v/c/d/y + f/t/F/T/w/Wの組み合わせを駆使してテキストを編集する
ノーマルモードでf+(任意の文字)
とタイプすると、fの次にタイプした文字にカーソルが移動します。
たとえば、fa
とタイプしたときは次に出現するaにカーソルが移動します。
数字と組み合わせることもできます。
たとえば、2fa
はふたつ先のaに移動します。
t+(任意の文字)
もf
によく似ていますが、指定した文字の 一つ手前 にカーソルが移動するのがf
と異なる点です。
F
/T
はf
/t
の逆で、カーソルの手前にある文字を探してそこへ移動します。
さて、以上の内容を踏まえた上で、ここからがこのセクションの本題です。
f
/t
/F
/T
はカーソルを移動させるだけでなく、v
/c
/d
/y
と組み合わせて使うこともできます。
たとえば、vfa
は「次に出現するaまでビジュアル選択する」という意味になります。
c2t(
であれば、「二つ先に出現する"("の手前まで削除して挿入モードに入る」という意味になります。
また、v
/c
/d
/y
はf
/t
/F
/T
だけでなく、w
/W
(単語選択)と組み合わせるのも効果的です。
たとえば、yw
とタイプすると単語全体をヤンク(コピー)します。(カーソルが単語の先頭にある場合)
このようにコマンドの組み合わせを駆使して、狙った範囲を素早く選択したり削除したりすると非常に効率よくテキストを編集できます。
ci'/dat/vi{/ya"のようなコンビネーションを使い分けてテキストを編集する
ノーマルモードでci'
とタイプすると、シングルクオートの内部にある文字列を削除して挿入モードに入ります。
ca'
とタイプすると、シングルクオートで囲まれた文字列をシングルクオートごと削除して挿入モードに入ります。
ci"
であればダブルクオートで囲まれた文字列を、ci{
であれば中括弧({})で囲まれた文字列を、cit
であればHTMLタグで囲まれた文字列をそれぞれ編集できます。
c
の変わりにd
を使ってdi'
とタイプするとシングルクオートの内部にある文字列を削除します。(挿入モードには入らない)
va'
であれば、シングルクオートで囲まれた文字列をシングルクオートごとビジュアル選択します。
このように、
c/d/v/y + a/i + (文字列を囲む記号)
というコンビネーションで、何かに囲まれた文字列を編集したり削除したりすることができます。
HTMLタグで囲まれた文字列を編集するときは記号ではなく、t
で指定する点にだけちょっと注意してください。
応用テクニックとして、d2i{
のようにタイプすると、2つ外側にある{}の内部文字列を削除したりできます。({}がネストしている場合)
(2014.06.14追記) c/d/v/y + a/i + w/Wでカーソルが単語の途中にあっても単語全体を編集する
単語の途中にカーソルがある場合、cw
をタイプするとカーソルから後ろだけが削除されてしまい、カーソルより前の部分は残ってしまいます。
そんなときはciw
とタイプすると、カーソルがどこにあってもその単語全体を削除してから挿入モードに入ります。
caw
とした場合は単語の前後にあるスペース等も一緒に削除されます。
もちろん、diw
やdaw
とした場合は単語の削除だけが行われ、挿入モードには入りません。
同様の考え方でviw
/vaw
で単語全体をビジュアル選択したり、yiw
/yaw
でヤンクしたりすることもできます。
w
の代わりにW
にすると、記号もひとかたまりの単語として扱われるのもその他のコマンドと同様です。
J/gJで行を連結する
ノーマルモードで複数行をビジュアル選択してJ
とタイプすると、選択された行を連結することができます。
行を連結したときは半角スペースが境目に入ります。
この半角スペースが不要な場合はgJ
とタイプします。
3J
のようにタイプすればビジュアル選択せずに3行分を連結する、ということも可能です。
Ctrl-vで矩形選択する
ノーマルモードでCtrl-v
とタイプすると、矩形選択がスタートします。
矩形選択した状態でd
とタイプすれば、その範囲を削除できます。
s
またはc
とタイプすれば、その範囲を削除した後に挿入モードに入ります。
I
またはA
とタイプすれば、選択範囲の先頭または末尾にカーソルが移動して挿入モードに入ります。
矩形選択+$+Aで、長さの異なる複数行の行末に同じ文字列を追加する
複数の行に渡って同じ文字列を行末に追加したいと思った場合、各行の長さが揃っている場合は矩形選択+A
で編集できますが、長さが揃っていない場合はちょっとひと工夫必要です。
この場合は、まず行方向に矩形選択(Ctrl-v
+j
)し、次に$
をタイプします。(全行を行末までビジュアル選択)
そのあとにA
をタイプすると、長さが異なる行であっても同じ文字列を行末に追加できます。
>>や複数行選択&>でインデントを変える
ノーマルモードで>>
とタイプすると、その行のインデントを1つ増やせます。
反対に<<
とタイプすると1つ減らせます。
複数行をビジュアル選択した状態で>
とタイプすると、選択した行をまとめてインデントできます。
また、数字と組み合わせてインデントを実行することもできます。
たとえば、2>>
とタイプすると、2行に渡ってインデントを1つ増やします。
一方、複数行を選択した状態で2>
とタイプすると、その範囲でインデントを2つ増やせます。
複数行選択するときとしないときとで、数字の意味が異なる点に注意してください。
Ctrl-a/Ctrl-xでカーソルの下にある数字を増減させる
ノーマルモードでCtrl-a
とタイプすると、カーソルの下にある数字を1つ増やせます。
Ctrl-x
は反対に数字を1つ減らします。
挿入モードに入らなくて済むのでちょっと便利です。
r/Rを使って1文字/複数の文字を上書きする
ノーマルモードでr+(任意の文字)
とタイプすると、カーソルの上にある1文字を上書きします。
また、R+(任意の文字列)+(ESC)
とタイプすると、ESCを押すまで上書きを続けます。
~/u/Uで大文字/小文字を切り替える
ノーマルモードで~
とタイプすると、カーソルの上にある文字の大文字/小文字を切り替えることができます。
ビジュアル選択している場合に~
をタイプすると、選択範囲内にある文字の大文字/小文字を反転させます。
また、ビジュアル選択中にu
とタイプすると、選択範囲内にある文字をすべて小文字にします。
U
は反対にすべて大文字にします。
Ctrl-p/Ctrl-nで単語補完する
挿入モードで初めの数文字をタイプし、Ctrl-p
またはCtrl-n
とタイプすると、現在開いているバッファの中からその文字列で始まる単語を補完の候補として選択することができます。
Ctrl-p
は「カーソルの前にあるキーワードと合致する単語を逆方向に検索して挿入」、Ctrl-n
は「カーソルの前にあるキーワードと合致する単語を順方向に検索して挿入」という違いはありますが、僕はあまり気にせずにいつもCtrl-p
を使っています。
(2014.06.14追記) ドット(.)で直前のテキスト編集を繰り返す
テキストの挿入や削除を実行したあとに、.
をタイプするとそのテキスト編集を再度繰り返すことができます。
たとえば、Vimではdd
で1行を丸ごと削除できますが、一度dd
したあとに.
すると1行削除を1回のタイプで繰り返すことができます。
他にも「ciw
してから hoge を入力」みたいなちょっとややこしい操作も.
で繰り返したりできます。
「同じコマンドを何度もタイプしてるなー」と思ったときは.
が役に立つかもしれません。
検索・置換系
正規表現検索を使いこなす (Perl系と記述が異なるメタ文字を理解する)
ノーマルモードで/hoge
のようにタイプすると、テキスト中に現れる文字列"hoge"を検索できます。
/
で検索するときは正規表現が使えます。
たとえば、/^\d
のようにタイプすると、「行頭に現れる任意の数字を検索」という意味になります。
ただし、Vimの正規表現で使うメタ文字はPerl系の正規表現で使うメタ文字と少し異なります。
いくつかのメタ文字はバックスラッシュと組み合わせて使う必要があるので、Perl系の正規表現に慣れている人でも注意が必要です。
メタ文字 | 意味 |
---|---|
\(hoge\) | 文字列"hoge"をキャプチャする |
hoge\|piyo | "hoge"または"piyo"を検索 |
Regexp\? | "Regex"または"Regexp"を検索(pが0または1個) |
go\+gle | "gooooogle"のような"o"が1個以上連続する"go..gle"を検索 |
go\{2,4}gle | "google"や"goooogle"のように"o"が2個以上4個以下で連続する"go..gle"を検索 |
上記のメタ文字はバックスラッシュを付けないと普通の文字として検索されます。
たとえば、/go+gle
は純粋に"go+gle"という文字列を検索します。
2016.06.30追記 \v (very magic)オプションでPerl系のメタ文字をそのまま使えるようにする
/
の後ろに\v
を付けるとPerl系の正規表現と同じように、( )
や{ }
、|
、?
、+
がバックスラッシュなしでメタ文字として扱われます。(very magicオプション)
たとえば\v
なしだと、/go\+gle
のように+
にバックスラッシュを付ける必要がありました。
しかし、\v
付きだと、/\vgo+gle
のようにバックスラッシュなしで+
がメタ文字扱いされます。
Perl系の正規表現に慣れている方は、\v
を付けた方が直感的に正規表現を書けると思います。
なお、「正規表現自体が苦手だ、よくわからない」という方はこちらの記事を読んでみてください。
初心者歓迎!手と目で覚える正規表現入門・その1「さまざまな形式の電話番号を検索しよう」 - Qiita
2015.01.30追記 文字クラスを使う場合の注意点
Perl系の正規表現では /[\d,]/
のように書くと「数字またはカンマのどれか1文字」という意味になりますが、Vimではこの形式が使えません。
Vimで同じことをする場合は、/[[:digit:],]
と書きます。
これはPOSIX文字クラスと呼ばれる形式です。
他にはこのような文字クラス表現があります。
表現 | 意味 |
---|---|
[:alpha:] | アルファベット |
[:alnum:] | アルファベットとアラビア数字 |
[:blank:] | スペースとタブ文字 |
[:space:] | ホワイトスペース文字 |
[:digit:] | 10進数 |
[:xdigit:] | 16進数 |
[:graph:] | スペースを除いた印字可能な文字 |
[:print:] | スペースを含めた印字可能な文字 |
[:upper:] | アルファベットの大文字 |
[:lower:] | アルファベットの小文字 |
[:punct:] | 句読点文字 |
[:cntrl:] | 制御文字 |
[:return:] | <CR> 文字 |
[:tab:] | <Tab> 文字 |
[:escape:] | <Esc> 文字 |
[:backspace:] | <BS> 文字 |
参考文献
grep検索を活用する
Vimのgrep検索はバリエーションが豊富なので、詳細に説明するとそれだけで一つの記事になってしまいます。
ここでは一つだけ使用例を示します。
ノーマルモードで:vimgrep 'class [A-Z]' **/*.rb | cw
のようにタイプすると、拡張子が.rbになっているファイルを対象にして、「class (任意の大文字)」を含む行を検索します。
最後の| cw
は検索実行後にQuickfix Listを表示するための命令です。
:cn
または:cp
で次または一つ前の検索結果へ移動することができます。
Quickfix Listから検索結果を選択してジャンプすることもできます。
ただし、僕はfugutive.vimプラグインを使って:Ggrep
コマンドで検索することが多いです。
:Ggrep
を使うとgitで管理されているファイルだけを対象にして検索することができます。
fugutive.vimについてはこちらのweb記事を参考にしてください。
その他、grep検索に関する詳しい情報は以下のweb記事を参考にしてください。
grep置換を活用する
Vimではgrep検索だけでなく、grep置換をすることもできます。
grep置換をする場合は以下のように2つのコマンドを発行する必要があります。
:args **/*.rb
:argdo %s/tel/phone/gc | update
上の例では次のようなgrep置換を実施します。
- 拡張子が.rbになっているファイルを対象にする(
:args **/*.rb
) - "tel"を"phone"に置換する(
/tel/phone/g
) - 置換する際に一つずつ確認を入れる(
/gc
のc
) - 置換が終わったらファイルを保存する(
| update
)
(2014.06.14追記) *でカーソルの下にある単語を検索する
ノーマルモードで*
をタイプすると、カーソルの下にある単語を検索できます。
そのあとn
をタイプすると、次に合致する場所へカーソルが移動します。
N
は一つ手前の合致する場所へカーソルが移動します。
ちなみに*
のかわりに#
をタイプすると、下方向ではなく上方向に検索を開始します。
g*
/g#
は部分一致検索を実行します。
たとえば、"user"の上でg*
すると、"user"だけでなく"user_name"も合致するようになります。
(*
だと"user_name"は合致しません)
バッファ・ウインドウ操作系
:lsで現在開いているバッファを確認する
ノーマルモードで:ls
とタイプすると現在開いているバッファの一覧が表示されます。
"+"マークの付いているファイルはまだ保存していないファイルです。
先頭に表示されている番号はバッファ番号です。
:b3
のようにタイプするとその番号のバッファを表示できます。
ただし、僕はUnite.vimプラグインのバッファ一覧もよく活用します。
Unite.vimを使うと現在開いているバッファの一覧を表示してくれるだけでなく、ファイル名で絞り込んだりカーソルを上下に移動させて目的のファイルを開いたりすることができます。
Unite.vimについてはこちらのweb記事を参考にしてください。
Ctrl-w v/Ctrl-w sでウインドウを分割する
ノーマルモードでCtrl-w v
とタイプするとウインドウを縦方向に分割できます。
Ctrl-w s
とタイプすると横方向に分割できます。
ウインドウを移動する場合は以下のようなコマンドが使えます。
-
Ctrl-w w
: 次のウインドウへ -
Ctrl-w W
: 前のウインドウへ -
Ctrl-w h
: 左へのウインドウへ(j
/k
/l
なら下/上/右へ)
ウインドウを閉じるときは:q
とタイプします。
(2014.06.14追記) zf/<space>で指定した範囲を折りたたむ/開く
ビジュアル選択で複数行を選択したあとに、zf
をタイプするとその範囲を折りたたむことができます。
折りたたんだ範囲を元に戻す場合は<space>
キーをタイプします。(zO
でも同じ)
Vimmerレベル診断
さて、上で紹介したVimコマンドは全部で25種類ありました。
このうち、あなたが普段使いこなしているコマンドはいくつありましたか?
1項目1ポイントとして、自分のVimmerレベルを採点してみましょう!
- w/e/b/W/E/Bを使い分けて単語単位に移動する
- H/M/Lでカーソルをウインドウ内の上/中/下に移動させる
- z<enter>/z./z-で現在のカーソル位置を基準に画面をスクロールさせる
- Ctrl-f/Ctrl-b/Ctrl-e/Ctrl-yで画面を上下にスクロールさせる
- %で対応する括弧に移動する
- gg/G/<数字>G(または:<数字>)で好きな行にカーソルを移動する
- i/a/s/cw/I/A/S/Cを使い分けて挿入モードに入る
- v/c/d/y + f/t/F/T/w/Wの組み合わせを駆使してテキストを編集する
- ci'/dat/vi{/ya"のようなコンビネーションを使い分けてテキストを編集する
- J/gJで行を連結する
- Ctrl-vで矩形選択する
- 矩形選択+$+Aで、長さの異なる複数行の行末に同じ文字列を追加する
-
や複数行選択+>でインデントを変える
- Ctrl-x/Ctrl-aでカーソルの下にある数字を増減させる
- r/Rを使って1文字/複数の文字を上書きする
- ~/u/Uで大文字/小文字を切り替える
- Ctrl-p/Ctrl-nで単語補完する
- ドット(.)で直前のテキスト編集を繰り返す
- 正規表現検索を使いこなす (Perl系と記述が異なるメタ文字を理解する)
- grep検索を活用する
- grep置換を活用する
- *でカーソルの下にある単語を検索する
- :lsで現在開いているバッファを確認する
- Ctrl-w v/Ctrl-w sでウインドウを分割する
- zf/<space>で指定した範囲を折りたたむ/開く
0ポイント: これからVimmer
Vimを普段使っている人ならさすがに0ポイントということはないはずです。
あなたはきっと、これからVimを使おうと考えている人ですね?
いらっしゃいませ、ようこそVimの世界へ!
1~5ポイント: ひよっこVimmer
Vimでコーディングはしていても、まだまだVimのイロハぐらいの機能しか使いこなしていませんね?
まずはもっと基礎を固めてから、それから応用力を付けていきましょう!
6ポイント~10ポイント: 初級Vimmer
そろそろVimの若葉マークは外れたころですね。
でもまだまだ伸びる余地はあるので、ここで怠けずにもっとコマンドを覚えていきましょう!
11ポイント~19ポイント: 中級Vimmer
このあたりのポイントになるとそれなりにVimの経験がある人だと思います。
とはいえ、Vimにはあなたの作業効率を向上させる機能がまだ隠されているようです。
ネットや書籍で上級者向けのコマンドや機能を学習すればより完璧ですね!
20ポイント以上: ひょっとして、達人Vimmer!?
すごい!!あなたはたぶん普段からバリバリとVimを使いこなしている 達人Vimmer さんですね?
たぶんVimのスキルは僕なんかよりもずっと上なんだと思います。
「このコマンドもすごく便利なんだけど、ちゃんと使えてる?」という情報があったらコメント等で教えてください!
まとめ
というわけで今回は、個人的に「これはVimならでは」と感じている便利機能を25個集めてみました。
もちろん、Vimの便利機能はこれだけに限りません。
ここで取り上げなかったものもいくつかありますし、僕自身が勉強不足で使いこなせていない便利機能もたくさんあると思います。
誰でもエディタを使いこなせば使いこなすほど、開発の効率はどんどん上がっていきます。
「なんとなく使えてるからまあいいや」ではなく、「もっと効率よく開発できないか?」と自分に問いかけながら、エディタの操作に習熟していきましょう!
あわせて読みたい
脱初心者を目指すVimmerにオススメしたいVimプラグインや.vimrcの設定 - Qiita
こちらは便利なプラグインや.vimrcの設定について紹介したQiita記事です。
僕がサクラエディタからVimに乗り換えるまで - give IT a try
数年前は僕も全くVimが使えず、サクラエディタのような「メモ帳の延長線上にあるテキストエディタ」を使っていました。
そんな僕がVimに乗り換えようと思った動機と、乗り換えるまでにやったトレーニング(?)の数々を公開しています。
Vimコマンドを定期的にツイートするbotも作っています
Vimコマンドの勉強用に作った @be_vimmer_jp というbotがあります。
このbotをフォローすると定期的にVimコマンドの内容をランダムにツイートしてくれます。
よかったらフォローしてみてください。
開発の経緯はこちらのブログエントリにまとめてあります。
Vimコマンドを定期的に解説してくれるTwitterボットを作りました - give IT a try
余談:アニメーションgifはこちらのツールで作成しました
アニメーションgifの作成はLICEcapというフリーソフトを使っています。
シンプルで便利です。