FLINTERS Engineer's Blog

FLINTERSのエンジニアによる技術ブログ

vim入門 + operator・motion・text-object を活用しよう

こんにちは。 FLINTERS GANMA課でエンジニアをやっている生田です。
本記事は FLINTESR 10周年記念ブログリレーの80日目の記事となります。

今回は、

  • vim を使っていない方
  • vim を使ってはいるが、そんなに便利とは感じていない方

を対象に、vim の機能紹介をしていきたいと思います。
vim パワーを感じて頂けると嬉しいです。

vim 入門

vim はテキストエディタです。
シンプルで、それでいて機能的で、超高速なテキスト編集がウリです。
しかし、

  • 開いた直後に文字が打てないのでやめた
  • 自分で何をしているのかわからない
  • ssh したときに vi がデフォで入ってるから nginx.conf 編集できる程度には…

といった方も多いのではないでしょうか。

ということでまずは vim を最低限操作できるようになるための入門レベルの内容から紹介していきます。

vim の用意

mac 等であればデフォルトで入っているので、ターミナル経由ですぐ起動できるはずです。

> vim

しかし、私としては

好きなIDEやエディタ + vimエミュレータ

のスタイルを推します。
(vim 至上主義のみなさん、許してください)
ある程度知名度のあるIDE・エディタであれば、大体 vim エミュレータがプラグインにあることでしょう。

なぜこのスタイルを推すのかというと

多機能+GUI+vim キーバインドによる高速編集

が実現できると思っているからです。

vim も多機能ではありますが、素の状態では現代のテキストエディタ・IDE などには勝らないと思います。
そうなると vim にプラグインを導入し、『俺の考えた最強の vimrc』が爆誕するのが自然な流れです。
しかし、vim をカスタマイズして他のテキストエディタ・IDEレベルに近づけるのにはそこそこ時間が掛かります(その時間が楽しいというのもありはしますがね)。

まずは 「好きなIDEやエディタ + vimエミュレータ」 で慣れ、気が向いたら vim を使ってみたり、カスタマイズしたりする方向に行くと良いと思います。

最低限できるようになりたいこと

まずは『モード』と『h, j, k, l』『削除』『ヤンク』『保存』『閉じる』あたりだけでも覚えればそこそこのテキスト編集ができるはずです。 慣れてきたら「そういえばもっとできそうな事があったな…」と少しずつできることを増やしていくのがおすすめです。

以下のモードの紹介の中では、今挙げたものや、早い段階で覚えておくと嬉しいものを挙げてみているので参考にして頂ければと思います。

モード

Wikipedia によると vim には「6つの基本モードと5つの派生モード」があるらしいです。 しかし、ほとんど以下の4つのモードしか使いません

vimのモードと切り替え方法

この4つのモードは必ず把握しておきましょう。 vim を扱う上で基礎になります。

モード 概要
NORMAL 基礎となるモード。カーソル移動やテキストの削除、コピー、ペーストなどの簡単な指示を行う。
VISUAL テキストを選択するだけのモード。
INSERT 実際にテキストを入力するモード。
COMMAND ファイルを開いたり、検索・置換などの様々な指示を行う。

また、「NORMAL以外」→「NORMAL」への切り替えは頻度が高いのですが、よく「Esc」で切り替えると紹介されている気がします。
しかし、押しやすさの観点から「Ctrl + [」を使うようにしましょう。 (Esc が良いならそれでも良いですが)
他にはjjという連打で切り替えるようにカスタマイズしている人もいたりします。

最序盤は「とりあえずよくわからなくなったら Esc をおして NORMAL にもどす!」で良いのですが、「Esc以外の選択肢もある」ということを覚えておくことが大事です。
「vim はいちいち Esc 押さないといけないんだろ?w小指が飛んでっちゃうよw」といった批判もありますが(これは嘘)、私の観測範囲では vimmer の多くは Esc を使っていないです。

NORMAL

入門時、NORMAL モードでは以下を覚えておくと良いと思います

キー 効果
h, j, k, l ←, ↓, ↑, → にカーソル移動
gg ファイル先頭に移動
G ファイル末尾に移動
dd 行の削除
yy 行のヤンク(行のコピーと思って下さい)
p ヤンクしたもの貼り付け
i INSERT モードへ

慣れてきたらできることを増やしていきましょう。 ここに書いているもの以外もあるので探してみてくださいませ。

キー 効果
{n}G n行目に移動
I 行頭に移動して INSERT モードへ
a カーソルの1文字右に移動して INSERT モードへ
A 行末に移動してINSERT モードへ
o 下に新しい行を追加して INSERT モードへ
O 上に新しい行を追加して INSERT モードへ
s 一文字消して INSERT モードへ
S 行を消して INSERT モードへ
Ctrl-a 数字をインクリメント
Ctrl-x 数字をデクリメント

VISUAL

範囲選択ができます。

キー 効果
v 1文字単位で VISUAL モードへ
V 行単位で VISUAL モードへ
Ctrl-V 矩形選択の開始
Ctrl-V→ I → ノーマルモードへ 矩形の先頭部に任意の文字を入力

VISUAL モードの際にも、NORMAL モード同様の移動・操作が大体できます。

COMMAND

ファイルを開いたり保存したりなどです。

コマンド 効果
:w {filename} 指定したファイル名で保存、ファイルがあれば上書き、なければ新規作成
:w 上書き保存
:q vim をとじる
:q! 未保存を無視してとじる
:wq 保存して閉じる
/{word} word を検索
:%s/{pattern}/{string}/g 文字列の置換。pattern にマッチする箇所を string に置き換える。gはフラグ指定で、「行の先頭だけでなく全体を置き換え」になる。フラグの詳細は:h :s_flagsで見れる

operator / motion / text-objects

これまでに紹介した内容である程度はテキストファイルの編集ができる状態になるかと思います。 ここから先は vim の柔軟性やパワフルさに繋がる概念を紹介します。

オペレータ(operator)・モーション(motion)・テキストオブジェクト(text-objects)は「組み合わせて使う」ことで様々な用途に柔軟に対処が可能となる便利概念です。

たとえば、「d (削除オペレータ)」+「w (単語モーション)」で単語を削除できます。 他にも「c (変更オペレータ)」+「i{ ({}カッコテキストオブジェクト)」でカッコ内を削除して INSERT モードに入れます。
これは、以下のようにソースコードの編集などで便利です。

def execUdonTabe(numOfTama: Int): Either[TabeFailure, TabeSuccess] = {
  // ↓ 黒丸の位置で「c + i + {」をすれば関数内がまるっと消えて更に INSERT モードになる!
  ●hogePiyo(numOfTama) match {
    case OnakaIsDame => Left(TabeFailure("お腹いっぱいです"))
    case OnakaIsOk => Right(TabeSuccess(numOfTama))
  }
}

また、VISUAL モード + (モーション, テキストオブジェクト) + オペレータという組み合わせも可能です。
オペレータ・モーション・テキストオブジェクトを↓にいくつか羅列してみたので、ぜひ自分の「最強テキスト編集ワザ」を編み出してみてください!

オペレータ(operator)

オペレータはテキストに対する操作の基礎となるものです。 (いつも c, d, y, =, >, < あたりしか使ってない…)

キー 効果
c 変更する(change)
d 削除する(delete)
y yankする
g~ 大文字小文字を入れ替える
gu 小文字にする
gU 大文字にする
! 外部プログラムでフィルタする
= インデントを整形する
gq テキストを整形する
g? ROT13で暗号化する
> 右にインデントする
< 左にインデントする
zf foldを定義する
g@ operatorfuncに設定された関数を呼び出す

モーション(motion)

モーションは移動の基礎となるものです。

左右の移動(抜粋)

キー 効果
h 左に移動
l 右に移動
0 行の最初に移動
^ 行の最初の非空白文字に移動
$ 行の最後に移動
f{char} 右に向かって {char} まで移動
F{char} 左に向かって {char} まで移動

上下の移動(抜粋)

キー 効果
k 上に移動
j 下に移動
gk (表示上の)上に移動
gj (表示上の)下に移動
G 最後の行に移動
{count}G count行目に移動
gg 最初の行に移動

単語単位の移動

キー 効果
w 次の単語の頭に移動
W 次の単語の頭に移動(記号で区切られない)
e 次の単語のお尻に移動
E 次の単語のお尻に移動(記号で区切らない)
b 前の単語の頭に移動
B 前の単語の頭に移動(記号で区切らない)
ge 前の単語のお尻に移動
gE 前の単語のお尻に移動(記号で区切らない)

テキストオブジェクト(text-objects)

テキストオブジェクトとは、ビジュアルモードかオペレータコマンドの後で使える一連のコマンドです。

キー 範囲
aw, iw 単語(a word, inner word)。カウントという概念で少し意味が変わるがここで説明は省く
a], a[, i], i[ [] カッコ
a), a(, i), i( () カッコ
a>, a<, i>, i< <> カッコ
at, it html タグ
a", i" ダブルクォート
a', i' シングルクォート
a`, i` バッククォート

おわりに

???「ここにvimパワーが溜まってきただろう!」

vim を触る場合は、最低限の操作だけ覚えてあとは実際に手を動かしながら試行錯誤していくのが良いかと思います。
特に、operator・motion・text-object は説明を見ても「はい???」という気持ちになりがちですが、実際に触ってみるとプログラミングなどで大いに役立つ機能であると理解できるかと思います。
ぜひ使ってみてください。

それではこれにて失礼します。ご覧いただきありがとうございました。

参考文献