開発者を中心に幾多のユーザーに愛されてきたテキストエディタのVimが30周年を迎え話題になっています。Vimは1991年にリリースされたテキストエディタですが、今なお現役で多くのユーザーに使われています。そして、その陰にはVimScriptと呼ばれるVimを拡張するスクリプト言語の存在があります。今回はVimを支えるVimScriptにフォーカスしてみます。

Vimエディタが人気の理由は?

Vimエディタは多くの開発者に愛されています。好きなエディタランキングを行えば、必ず上位に入っています。とは言え、身の回りに開発者がいなければ、それほど目にすることはないかもしれません。そのため、時々見かけるので気になっているけれども使ったことないという方も多いことでしょう。

そもそも、Vimの操作感はWindowsやmacOSのエディタと大きく異なっています。例えば、ただVimを起動し文字を入力するだけでもVimの流儀を覚える必要があるからです。Vimを起動して文字を入力するには「i」をタイプする必要があります。文字の入力が終わったら[esc]キーを押します。Vimを終了するには「:q!」とタイプする必要があります。このように、Vimは独特のキーバインドを持っています。

それでも長年に渡りVimが圧倒的な人気を誇るのには多くの理由があります。まず、コマンドライン上で動作するため、幅広い環境で動かすことができます。Win/Mac/Linuxと主流OSは当然のこと、デスクトップを持たないサーバーマシンやリソースの限られた環境でもVimなら動かすことができるという安心感があり、動作速度が速いのも魅力の一つです。

そして、Vim独自のキーバインドがそのまま魅力なのです。一度操作方法を覚えると、非常に効率的にテキストの編集が可能です。さらに、拡張性の高さ・カスタマイズ性の高さも人気の理由です。

  • Vimを起動してヘルプ画面を表示したところ

    Vimを起動してヘルプ画面を表示したところ

VimScriptとVimのインストール

そんな人気のVimを陰から強力に支えてきたのがVimScriptです。VimさえインストールされていればVimScriptを使うのに特別な設定は要りません。VimScriptはVimに組み込まれておりVimを拡張する目的で利用します。

それでは、最初にVimをインストールしましょう。WindowsでVim利用するには、VimのWebサイト からダウンロードできます。画面上部にある「MS-Windows:」から「gvim_(バージョン).exe」をダウンロードしてインストールすると良いでしょう。

  • WindowsではVimのインストーラーが用意されている

    WindowsではVimのインストーラーが用意されている

macOSであれば、パッケージ管理システムのHomebrewを使うと良いでしょう。Homebrewをインストールした後、ターミナル.appを開き、以下のコマンドを入力します。

brew install vim

LinuxのUbuntuやDebianであれば、OS標準のパッケージ管理システムであるAPTを利用してインストールできます。

sudo apt update
sudo apt install vim

VimScriptでHello, World!を書いてみよう

VimScriptはVimのコマンドモードでインタラクティブに実行できます。そもそも、Vimにはモードがあります。Vimを起動すると「ノーマルモード」となります。ノーマルモードではカーソルの移動が可能ですが、この状態では文字が入力できません。「i」や「a」を押すと文字入力が可能な「挿入モード」となります。そして、[esc]キーを押すとノーマルモードに戻ります。簡単な表にすると次のようになります。

操作 モード できること
vimを起動 ノーマルモード カーソルの移動
「i」キーを押す 挿入モード 文字の入力
「:」キーを押す コマンドモード 各種コマンドが実行できる
[esc]キーを押す ノーマモードル ノーマルモードに戻る

そして、コマンドモードとは、ノーマルモードで「:」キーを押した状態です。コマンドモードでは、さまざまなコマンドを実行できます。ファイルの保存「w」やエディタの終了も「q」を行うにもコマンドモードで行います。なお、コマンドモードでは、VimScriptを実行できます。例えば、Vimを起動した状態(ノーマルモード)で、「:」を押してコマンドモードにしたら、以下のコマンドを実行してみましょう。

echo "Hello, World!"

するとVimの最下行に「Hello, World!」と表示されます。

  • VimのコマンドモードでHello, World!を実行したところ

    VimのコマンドモードでHello, World!を実行したところ

なお、簡単な計算をしたい場合も、同じようにコマンドモードで以下のように記述できます。以下のコマンドを実行すると、610が表示されます。

echo 10 + 20 * 30
  • VimScriptで計算してみたところ

    VimScriptで計算してみたところ

そして、Vimで編集しているテキストに計算結果を埋め込みたい時は、「call append(行指定, 計算式)」のように記述します。例えば、カーソル行のすぐ下に、10+20*30の計算結果を埋め込みたい場合、以下のように記述します。

call append(".", 10 + 20 * 30)
  • Vimで計算結果をカーソル行の下に挿入した

    Vimで計算結果をカーソル行の下に挿入した

設定ファイルにVimScriptを記述しよう

VimScriptはインタラクティブに実行するだけでなく、任意のファイルに記述することも可能です。変数や制御構文・関数など、プログラミング言語で必要な機能は一通り備わっています。

そして、Vimの設定ファイルである「~/.vimrc」に関数をよく使う処理を記述しておけば、コマンドモードで手軽にVimScriptを実行できます。Vimを起動したら設定ファイル「~/.vimrc」を読み込んでみましょう。

Vimでファイルを開くにはコマンドモードで「e ファイル名」のように記述します。ノーマルモードで「:e ~/.vimrc」を実行すれば、Vimの設定ファイルを開けます。設定ファイルを読み込んだら、以下のような関数を記述しましょう。(もちろん、Vimで文字を入力するには、挿入モードにする必要があるため「i」キーを押してから以下の関数を入力しましょう。)

function! InsHello()
  let msg = "Hello, World!"
  call append(".", msg)
endfunction

関数を記述したらファイルを保存します。[esc]を押してノーマルモードに戻してから「:wq」でファイルを保存してVimを一度閉じます。そして、もう一度Vimを起動しましょう。(あるいは、「:source ~/.vimrc」で設定を再読込します。)

そして、コマンドモードにして以下のコマンドを実行します。

call InsHello()

すると、次の図のようにカーソル行の下の行に「Hello, World!」と挿入します。

  • InsHello関数を記述して実行したところ

コンソール版のvimも、GUI版のgvimも全く同じように実行できます。設定ファイルを読み込む手順もコンソール版と同じでノーマルモードで「:e ~/.vimrc」とタイプすることで読み込めます。

  • InsHello関数を記述して実行したところ

    InsHello関数を記述して実行したところ(gvim)

FizzBuzz問題をVimScriptで解いてみよう

このように、append関数など、いくつかエディタに関連するコマンドさえ覚えれば、VimScriptを利用して、簡単な拡張機能を書くことができるでしょう。それでは、本連載でいつも作っているFizzBuzzのプログラムをVimScriptでも解いてみましょう。

なお、FizzBuzz問題とは次のようなプログラムです。

> 1から100までの数を出力するプログラムを書いてください。ただし、3の倍数のときは数の代わりに「Fizz」と、5の倍数のときは「Buzz」と表示してください。3と5の倍数の時は「FizzBuzz」と表示してください。

それでは、プログラムを作ってみましょう。なお、これまで本連載で作ってきたFizzBuzz問題は一行に一つずつ値を出力していましたが、今後は結果が分かりやすいように、値一つ図つをカンマで区切って出力するようにしてみます。

function! InsFizzBuzz()
  let result = []
  for i in range(1,100)
    let result = add(result, FizzBuzz(i))
  endfor
  call append(".", join(result, ","))
endfunction

function! FizzBuzz(n)
  if a:n % 3 == 0 && a:n % 5 == 0
    return "FizzBuzz"
  elseif a:n % 3 == 0
    return "Fizz"
  elseif a:n % 5 == 0
    return "Buzz"
  else
    return a:n
  endif
endfunction

そして、コマンドモードで以下のコマンドを実行すると、FizzBuzzの結果がカーソル行のすぐ下に挿入されます。

call InsFizzBuzz()

macOSのVimで実行すると以下のように表示されます。

  • macOSでVimScriptを実行しFizzBuzzの結果をエディタに挿入したところ

    macOSでVimScriptを実行しFizzBuzzの結果をエディタに挿入したところ

GUI版のgvimでも同じように実行できます。

  • WinでVimScriptを実行しFizzBuzzの結果をエディタに挿入したところ

    WinでVimScriptを実行しFizzBuzzの結果をエディタに挿入したところ

プログラムを簡単に確認しましょう。変数への代入が「let」であり、任意の範囲を繰り返すには、for 変数 in range(開始, 終了) ... endforが使えます。ちょっと癖があるのが引数を参照する方法で、関数FizzBuzzの引数nを参照するには、a:nのように記述します。また、関数InsFizzBuzzを見ると分かりますが、「let result = []」のように記述してリスト(配列)を作成し、add関数でリストに値を追加できます。さらに、join(リスト, "区切り文字")のように記述すれば、リストを区切り文字で連結して文字列を得られます。

まとめ

以上、今回は公開から30年を経ても人気のVimエディタのためのスクリプト言語であるVimScriptについて取り上げました。もちろん、はじめてVimを使う方であれば、Vimのモードの切り替えに慣れるのが大変だったかもしれません。しかし、VimScriptのプログラム自体は、少し癖があるものの、それほど難しい言語という印象はありません。本連載で紹介している他の言語と比べても大きく異なることはありません。既にVimを使っている方であれば、これをきっかけに自分で拡張機能を作ってみると面白いと思います。

自由型プログラマー。くじらはんどにて、プログラミングの楽しさを伝える活動をしている。代表作に、日本語プログラミング言語「なでしこ」 、テキスト音楽「サクラ」など。2001年オンラインソフト大賞入賞、2004年度未踏ユース スーパークリエータ認定、2010年 OSS貢献者章受賞。技術書も多く執筆している。直近では、「シゴトがはかどる Python自動処理の教科書(マイナビ出版)」「すぐに使える!業務で実践できる! PythonによるAI・機械学習・深層学習アプリのつくり方 TensorFlow2対応(ソシム)」「マンガでざっくり学ぶPython(マイナビ出版)」など。