LoginSignup
50
28

More than 5 years have passed since last update.

作って覚える Vim script

Last updated at Posted at 2017-12-04

はじめに

Vimmerの皆さんこんにちは。
Vimに慣れてくると、色々カスタマイズしたくなりますよね。
でも、プラグインを作るのは大げさだし…と思っている人には
.vimrcでVim Scriptを書いてみるのがおすすめです。

Vim Scriptとは

Vim script は Vim に組み込まれたスクリプト言語です。
vimを開き、 :help vim-script と打ってみましょう。

はじめに

誰もが最初に触れる Vim script は vimrc ファイルです。Vim が起動するときに読
み込まれ、書かれているコマンドが実行されます。それにより好きなように設定を変更
できます。vimrc の中ではすべてのコロンコマンドが使えます (":" で始まるコマンド
のこと。Ex コマンドやコマンドラインコマンドと呼ばれることもある)。

(自分のVimはヘルプが日本語じゃないからやだ!という人はこちらをどうぞ→ Vimヘルプを日本語化!)

「誰もが最初に触れる Vim script は vimrc ファイルです。」ということで
実はVimを触っていれば自然とVim scriptにお世話になっているのです。
シンタックスハイライトに使うカラースキームも、もとを正せばVim script。
Vimが有りさえすれば、そこが実行環境。というわけで気軽に始めてみましょう。

こんな人向け

  • Vimを触っていて、プラグインも使っているけど、もっと痒いところに手が届く自動化をしてみたい人
  • もともと別のプログラム言語を触っているが、Vim scriptは触ったことがない人

今回やってみること

  1. Vim上でPHP lintを実行する
  2. lintでエラーが出た行数をハイライトしてみる
  3. 上記を保存時に実行できるようにする

環境

OS: Mac OS Sierra(10.12.6)
Vim: 8.0

1. Vim上でPHP lintを実行する

これはぶっちゃけいろんな人がやっていますので、
本能の赴くまま、無邪気に作って保存してみましょう。

~/.vimrc
function! PHPLint()
    let result = system('php -l ' . bufname(""))
    echo result
endfunction

→保存・コマンドモードで以下を実行
:source ~/.vimrc

test.php
<?php

$hoge = 1;
aaa // 明らかなシンタックスエラー

echo $hoge;

→保存

コマンドモードで
:call PHPLint() を実行

すると、こんな表示が出ます

スクリーンショット 2017-12-03 16.55.55.png

楽しい\(^o^)/

簡単な解説

関数はfunction ~ endfunctionで定義します。

コマンド・関数名 動き
letコマンド let (変数名) = (値)で変数定義できます。
system()関数 (組み込み)シェルコマンドを実行し、実行結果の文字列を返します。
echoコマンド 引数の値を表示

これらのコマンドや関数については、:help let など、コマンド・関数名などの前に :help をつけて実行すると詳細なマニュアルが見られます:yum:

スクリーンショット 2017-12-03 17.17.09.png

2. lintでエラーが出た行数をハイライトしてみる

では、今度はエラーが出た行数をハイライトしてみましょう。
(Syntaxチェックは必ずしも正しい行数を出してくれるわけではないが、今回はlineを信じて表示する)

~/.vimrc
function! PHPLint()
    let result = system('php -l ' . bufname(""))
    let error_list = matchlist(result, '\(line \)\(\d\+\)', 1)
    if empty(error_list)
        echo "エラーはありませんでした"
        return
    endif
    call matchaddpos("Error",[str2nr(error_list[2])])
    echo result
endfunction

→保存・コマンドモードで以下を実行
:source ~/.vimrc

コマンド・関数名 動き
matchlist()関数 (組み込み)正規表現でマッチした文字列のリストを返します。
str2nr()関数 (組み込み)文字列を数値に変換した結果を返します。
matchaddpos()関数 (組み込み)第二引数に指定された行数を強調表示する

同じく、詳細は:help (関数名)で確認!

matchstr()で PHPのSyntaxエラー

Parse error: parse error in test.php on line 6
Errors parsing test.php

line XXXXXXを正規表現で取得し、その行をハイライトしています。

おい、:sourceできないぞ

はい。こんな表示が出たかと思います

Error detected while processing /path/to/.vimrc:
line  (行数):
E122: Function PHPLint already exists, add ! to replace it

関数は、function!で宣言しないと
再度:source コマンドを実行する事ができません。
リローダブルなvimrcを書くには、

function! PHPLint()
...
endfunction

とする必要があります(後述のautocmdも同様)。

matchaddpos の第一引数について

:help matchaddposすると、以下のようなシグネチャになっています。

matchaddpos({group}, {pos}[, {priority}[, {id}[, {dict}]]])

matchadd と同じである、ということで、matchadd のマニュアルを読んでみると、

{group} = 構文グループ

だとわかりますが、構文グループとはなんぞや:question:
ということで、さらに :help group と実行してみると、謎が解けます。

構文グループとは、同じ種類の構文アイテムをグループ化したものである。構文グルー
プから強調グループにリンクされ、強調グループに対して色が設定される。構文グルー
プそれ自体は、色や属性を指定するものではない。

なるほど。と、その下を読み進めていると、構文グループが列挙してありました。

スクリーンショット 2017-12-03 17.52.57.png
(つづく)

今回は下の方にあった、構文グループ ERROR を選択し、
指定した行数を ERROR と同じ強調色にしています。

こんな感じで、:help を使いこなすにはちょっとしたコツが必要ですが
慣れてくるとスルメのようにいい味が出てくるマニュアルです。

気を取り直して

コマンドモードで
:call PHPLint() を実行

すると、こうなります。

スクリーンショット 2017-12-03 18.22.52.png

3. 上記を保存時に実行できるようにする

~/.vimrc
autocmd! BufWritePost *.php :call PHPLint()

→保存・コマンドモードで以下を実行
:source ~/.vimrc

例によって :help autocmd してみると

:au[tocmd] [group] {event} {pat} [nested] {cmd}

コマンドの定義方法が出てきます。
(Vim script上でコロン(:)コマンドを書くときは、:は不要です。)
引数として必要なのは、{event}{pat}{cmd}だということがわかります。

autocmd はフックのようなものです。
{event}で指定されたイベントが発生したとき、{pat} で指定したファイルに対し、
{cmd}で指定したコマンド/関数を実行します。

{event} は、あらかじめVimに文字列で指定されています。
というわけで :help event を見てみましょう。

スクリーンショット 2017-12-03 18.11.06.png

いっぱい出てきました。
ここにあるイベント発生時に、任意のコマンドを実行できます。

BufWritePost

はバッファを保存した後のタイミングで実行するコマンドです。
test.php:w で保存してみましょう。PHPLint()が保存時に実行されているのがわかりますね。

おまけ:強調表示を消す方法

コマンド実行すると、強調表示されたままになってしまいます。
clearmatches() を実行すると強調表示がクリアされるので、以下のようにすると
シンタックスエラーがなくなれば表示も消えます。

function! PHPLint()
    let result = system( 'php -l ' . bufname(""))
    let error_list = matchlist(result, '\(line \)\(\d\+\)', 1)
    if empty(error_list)
        call clearmatches() ' ←こいつを追加
        echo "エラーはありませんでした"
        return
    endif
    call matchaddpos("Error",[str2nr(error_list[2])])
    echo result
endfunction

→保存・コマンドモードで以下を実行
:source ~/.vimrc

test.phpを正しく編集し、保存してみましょう。
強調表示が消えるはずです。

最後に

いかがでしたでしょうか?
今回は「作って覚える」ということで、細かい説明を省き
:helpを調べながら進めていきました。

Vim scriptと仲良くなるには、:helpと仲良くなるのが近道です。
楽しいVimライフを! & Merry Christmas!:christmas_tree:

50
28
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
50
28