挿入、ビジュアルモードについて学ぼう 〜 Vimはいいぞ!ゴリラと学ぶVim講座(3)

こんにちは。
ゴリラ.vimを運営しているゴリラです。
8月に入り、各地が猛暑に見舞われていますね。みなさんも水分を多めにとって、体調には気をつけていきましょう。

お知らせ

はじめの前に少しみなさんにお知らせがあります。
2019/11/3(日)にVimConf 2019が開催されます。こちらはVimの国際カンファレンスで、年に一度国内外の著名なVimmerの方々が集まります。筆者も僭越ながら「My Vim life」というタイトルで発表させて頂く予定です。年に一度Vimやそれに纏わる深い知見を得られたり、著名なVimmerの方とお話しできる貴重な機会でもあります。興味ある方はぜひ参加を検討してみてください。

また、9/22(日)に技術書典7というイベントが開催されますが、筆者は「Vimが好きになる本」という本を配布予定です。オンラインでも配布予定なので、興味ある方はぜひ筆者のTwitterの方をチェックして頂ければと思います。

はじめに

前回の記事ではVimノーマルモードについて解説しました。本記事ではノーマル以外の次のモードを解説していきます。それぞれのモードではどんなことができるのか、また便利な使い方を紹介します。ぜひ最後まで読んでみてください。

  • 挿入モード
  • ビジュアルモード

挿入モード

ノーマルモードはテキストの"編集"に特化したモードですが、挿入モードはテキストの"入力"に特化したモードと筆者は考えています。具体的には入力補完やレジスタによるテキストのプットなどがあります。

テキストの再挿入

挿入モードでは、CTRL-aで直前に入力したテキストを再度挿入することができます。直前に挿入したテキストというのは"挿入モードに切替えてから抜けるまでに挿入したテキスト"という単位になります。次の操作例動画は再挿入の一例になります。


上記の動画では、"s:hello()" という関数に "your_name" という引数を定義し、その関数を関数内で利用するため、"echo a:" を打ったところでCTRL-aで再度挿入しています。

また、CTRL-@というのもあります。こちらは基本同じ動きですが、挿入後に挿入モードを抜けます。CTRL-aのあとにEscを打つのと同じになります。こういったキーは、挿入モードで直前に入力した値を再利用する時に便利です。

ちなみに、動画のサンプルコードはVim scriptというVimの設定やプラグイン開発時に使用する言語になります。連載の後半にVim scriptや設定、プラグイン開発について解説する予定なので、楽しみにして頂ければと思います。

テキストの削除

挿入モードではノーマルモードほど豊富ではないのですが、テキストを削除する方法がいくつかあります。筆者がよく使うのはCTRL-wです。下の動画の様に、"gorilla" を入力した後、やっぱり "banana" にしようと思い "gorilla" を削除したいときは、CTRL-wでカーソル前にある単語を削除できます。これはノーマルモードでいうとdwcwと同じ動きになります。

他にも、CTRL-uでカーソルより前のテキストをすべて削除できます。これはノーマルモードいうとd0c0と同じ動きになります。

インデント

コーディングしていると、挿入モードでインデントを調整したいときがあります。ノーマルモードでは<>オペレーターを使用することでインデントの調整を行うことができますが、モードを切り替えるのは少しばかり手間がかかります。そこで、CTRL-tCTRL-dを使用することでインデントの調整を行うことができます。CTRL-tはインデントを1つ右に、CTRL-dは1つ左にずらします。

<>オペレーターと違う点としては、現在行のみインデントを調整できるところです。オペレーターは範囲を指定することができるため、より柔軟にインデントの調整が可能です。複数行のインデントを調整するときはノーマルモードでオペレーターを使用したほうが良いでしょう。

レジスタ

Vimではレジスタというデータを保存する領域があります。このレジスタはdyxコマンドを使用して削除、ヤンクしたテキストを保存したり、レジスタにあるテキストをプットしたりすることができます。一部ではありますが、主なレジスタは次になります。

名称 レジスタ 説明
無名レジスタ " dyxなどの削除、ヤンクしたテキストが保存される
削除用レジスタ _ dなどで削除したレジスタを"に保存せず破棄する
名前付きレジスタ a ~ z ユーザが自由に指定してヤンク、プットできる
expression用レジスタ = 式の評価結果を挿入する

無名レジスタはレジスタを指定していてもいなくてもテキストは保存されます。dwyiwpなどのコマンドで削除、ヤンク、プットしたテキストはこちらのレジスタを使用しています。他のレジスタを使用したい場合、ノーマルモードではオペレーターコマンドの前に"{register} というふうにレジスタを指定できます。次の動画ではレジスタを指定してヤンク、プットする一例になります。

上の動画では "call" を yiw でヤンクして、 "s:hello("gorilla")" を "ry$でレジスタry$でヤンクしたテキストを保存しています。そのためpはレジスタを指定していない yiw の結果、"rpはレジスタrの結果をプットしています。

小削除レジスタでは削除するテキストを破棄する時に使用します。先程解説した通りdxなどの削除コマンドでは自動的に無名レジスタにテキストが保存されてしまいます。レジスタに保存させたくないときは"_d{motion}"_xというふうに指定することで、無名レジスタに保存されることなく削除できます。

このように、レジスタを使い分けることで、複数のテキストを自由にヤンク、プットすることができます。ちなみに:regコマンドでレジスタの中身を確認できます。

ノーマルモードに限らず、挿入モードや他のいくつかのモードでもレジスタを使用することができます。挿入モードではCTRL-rの後にレジスタ番号"a~zなどを入力することでその中身をプットできます。

上の動画では先程のヤンクした中身をそれぞれプットしています。挿入モードではテキストのヤンクを行うことができないのでプットのみになりますが、モードを切り替えることなくレジスタを使用することは大きなメリットと筆者は考えています。

基本的なレジスタについて解説したところで、expressionという特別なレジスタについて解説していきます。こちらのレジスタは説明にある通りですが、式の結果をプットすることができます。例えば、現在のディレクトリパスを取得するVimの組み込み関数getcwd()を評価して、その結果を挿入したりできます。挿入モードならCTRL-R=でコマンドラインモードのところに=が出ますので、続けて式を入力してEnterを押下すると評価結果を挿入できます。

挿入ノーマルモード

「挿入ノーマルモード」と聞いて、どういうこと?と思う方もいるかと思います。挿入モードではCTRL-oで一度だけノーマルモードのコマンドを実行してまた挿入モードに戻るという特殊なモードがあります。例えば単語の削除はCTRL-wでもできますが、こちらはdwと同様"go|rilla"のようにカーソルが"go"の後ろにある場合、CTRL-wではカーソルよりも前の部分のみの削除になります。カーソルが単語のどの部分にあっても単語を削除するにはdiwもしくはdawを使用する必要があります。その様な一度だけノーマルモードのコマンドを使用したい場合に、このモードは便利です。

上の動画ではCTRL-oで挿入ノーマルモードに切替えて、diwで"gorilla"を削除しています。削除後挿入モードに自動で戻るのがわかります。ノーマルモードの間は通常のノーマルモードと同じことができるので、"rpというようにプットすることもできます。

入力補完

Vimは標準で補完機能を持っています。補完を使用することで誤字脱字をなくすことができ、かつ入力スピードが向上しますので、常用することをお勧めします。いくつかの補完方法があるので、それについて紹介していきます。

CTRL-x + CTRL-f でファイル・ディレクトリ名を補完できます。カーソルより前にパスがある場合はそのパスから補完しますが、特になければカレントディレクトリから補完します。また、パスが環境変数の場合は展開されます。

補完ウィンドウでの操作ですが、CTRL-nで次の候補、CTRL-pで前の方法、CTRL-eで候補を選択せず終了になります。ファイル、パス名の補完の他に、ファイル内の単語補完もあります。

上の動画ではCTRL-x + CTRL-nで現在開いているファイル内の単語を補完しています。場面によっては他のファイル内の単語を補完したいことがあります。その場合はCTRL-nで他のファイル内の単語を補完できます。

上の動画ではCTRL-x + CTRL-nによる補完をしようとしていますが、画面下部にPattern not found と出ています。その後CTRL-nで補完して他ファイルの単語が候補に出てきます。CTRL-nはすべてのファイルから単語を取得するため、場合によっては表示するまで時間がかかります。必要な範囲内で補完するようにするのが良いでしょう。

ビジュアルモード

ビジュアルモードは範囲を選択して、その範囲に対してなにか操作を行うことができます。基本的な操作は初回の記事で解説したので、今回はいくつか便利な使い方について紹介していきます。

複数行頭にテキストを挿入

コーディング時に、複数行をまとめてコメントアウトしたいことが良くあります。その場合は矩形選択を使用します。次の動画はVim scriptで関数をコメントアウトする例になります。

まずはCTRL-vで選択開始して、コメントアウトしたい行を選択します。次に0で行頭にカーソルを移動してIで挿入モードに入り"を入力してCTRL-[もしくはEscで挿入モードを抜けます。

複数行末にテキストを追記

行頭以外にも、行末になにかを追記したい場合があります。その場合は先頭に追記する時とほぼ同じです。CTRL-vで選択開始して、追記したい行を選択します。次に$で行末にカーソルを移動してAで挿入モード入り"を入力してCTRL-[もしくはEscで挿入モードを抜けます。

外部コマンドの実行

ビジュアルモードでは選択した範囲のテキストを外部コマンドの標準入力に渡すことができます。外部コマンドの実行はコマンドラインモードで行います。例えば、ソースコードの一部だけ整形したいときに便利です。次のgitではjqコマンドを使用したJSONの整形を行う例になっています。

上の動画では範囲を選択した後に:を打つと:'<,'>が挿入されます。これは選択した範囲を指しています。!のあとに外部コマンドjqを入力してEnterを押下するとコマンドの実行結果が反映されます。このように、一部のテキストを外部コマンド利用して整形するのに便利です。外部コマンド実行に関しては次回の記事にて詳しく解説します。

最後に

今回は挿入モードとビジュアルモードについて実例を交えながら詳しく解説しました。それぞれの例は筆者が日頃よく行っていることの一例です。他にももっと便利な使い方があるかも知れません。ぜひご自身で触って探してみて下さい。

次回は外部コマンドとの連携が得意なコマンドラインモードとTerminal-Jobモード/Terminal-Normalモードについて解説していきます。楽しみにして頂ければと思います。