autocomplpop.vimでclass属性値入力時に出るエラーを回避する

KaoriYaのWindows版Vimにautocomplpop.vimを入れると以下のスクリーンショットのようなエラーが出るようになります。

スクリーンショット:class属性値を入力するとエラーが出て鬱陶しい

コレ、HTMLのclass属性値を入力しようとすると出るエラーなのですが、どうやら編集中のHTMLファイルに関連付けられているCSSを見に行って、そこに定義されていないクラスを入力しようとすると出るようです。便利なようですが、スクリプトのために書くclass属性値もなんかもあるわけで、そういうのでいちいちエラー窓が開いていては入力しにくくて仕方ありません。
そこで、このエラーが出ないようにする、というか、class属性値をいちいちチェックしないようにする方法を。

まずVimのホームディレクトリから runtime/autoload/ とたどっていくと htmlcomplete.vim というファイルがあります。つまり、コレですね $VIMRUNTIME/autoload/htmlcomplete.vim
コレの中身を以下のように編集します。

245〜256行目

        "let headclasslines = filter(copy(styleheadlines), "v:val =~ '\\([a-zA-Z0-9:]\\+\\)\\?\\.[a-zA-Z0-9_-]\\+'")
else
let stylesheet = split(headjoined, '[{}]')
" Get all lines which fit id syntax
"let classlines = filter(copy(stylesheet), "v:val =~ '#[a-zA-Z0-9_-]\\+'")
" Filter out possible color definitions
"call filter(classlines, "v:val !~ ':\\s*#[a-zA-Z0-9_-]\\+'")
" Filter out complex border definitions
"call filter(classlines, "v:val !~ '\\(none\\|hidden\\|dotted\\|dashed\\|solid\\|double\\|groove\\|ridge\\|inset\\|outset\\)\\s*#[a-zA-Z0-9_-]\\+'")
"let templines = join(classlines, ' ')
"let headclasslines = split(templines)
"call filter(headclasslines, "v:val =~ '#[a-zA-Z0-9_-]\\+'")

294〜313行目

            "let classlines = filter(copy(stylesheet), "v:val =~ '\\([a-zA-Z0-9:]\\+\\)\\?\\.[a-zA-Z0-9_-]\\+'")
else
let stylesheet = split(stylefile, '[{}]')
" Get all lines which fit id syntax
"let classlines = filter(copy(stylesheet), "v:val =~ '#[a-zA-Z0-9_-]\\+'")
" Filter out possible color definitions
"call filter(classlines, "v:val !~ ':\\s*#[a-zA-Z0-9_-]\\+'")
" Filter out complex border definitions
"call filter(classlines, "v:val !~ '\\(none\\|hidden\\|dotted\\|dashed\\|solid\\|double\\|groove\\|ridge\\|inset\\|outset\\)\\s*#[a-zA-Z0-9_-]\\+'")
"let templines = join(classlines, ' ')
"let stylelines = split(templines)
"let classlines = filter(stylelines, "v:val =~ '#[a-zA-Z0-9_-]\\+'")
endif
endif
" We gathered classes definitions from all external files
"let classes += classlines
endfor
if internal == 1
"let classes += headclasslines

つまり、classlinesというコードが登場する行を全てコメントアウトします。こうしたら、エラーが出なくなりました。

スマートな方法ではありませんが、とりあえず普通に動くのでOKってことで。

MTのコンテキストについての考察と解説

MovableTypeのテンプレートを書くにあたってまず理解すべきなのは、MTタグやテンプレートの種類よりも、まずコンテキストなのではないかと思います。CSSによるレイアウトを学ぶにあたって、ブロックモデルを理解すべきであるのと一緒です。というわけで、このコンテキストについて解説しようと試みます。

コンテキストとは

直訳すれば「文脈」です。ここではテンプレートにおける前後の文脈のことをそう呼びます。自然言語における人間の会話や文章にも前後の文脈というものが存在しますから、会話を例に挙げます。

Aさん:今日は天気がいいですね。
→「今日の天気」のコンテキスト

MTのテンプレートでは現在のコンテキストに適合しないMTタグを使おうとすると、エラーが出るようになっています。

コンテキストに適合しないタグを使おうとするとエラーが出る

人間の会話において、文脈に沿っていない話題や発言をすると会話が成立しなくなるのと同じです。

Aさん:今日は天気がいいですね。
→「今日の天気」のコンテキスト
Bさん:はい、僕はハンバーグが好きです。
→コンテキストに沿っていないのでエラー

コンテキストの種類と、テンプレートとの関係

MTのコンテキストは大別すると「ブログ記事」・「ブログ記事リスト(アーカイブ)」・「ウェブページ」の3つです。そしてこれはテンプレート一覧の「アーカイブテンプレート」の種類でもあります。これらのテンプレートは、最初から該当のコンテキストを持っており、「ブログ記事」アーカイブは最初から「ブログ記事」コンテキストを持っています。

「アーカイブテンプレート」の一覧の例

「ブログ記事リスト」では「日付別」・「ユーザー別」・「カテゴリ別」という、大別して3つの分類を「アーカイブマッピング」で与えることができます。このテンプレートに該当するコンテキストが与えられるだけでなく、この指定を元にページファイルが生成されます。

例えば「カテゴリ」アーカイブマッピングを選択したテンプレートでは、最初から「ブログ記事リスト」コンテキストと、「カテゴリ」コンテキストを持ちます。

コンテキストの指定方法

任意のコンテキストを作り出すために使用するのがMTEntriesや、MTArchivesMTPagesなどのブロックタグです。これらのタグで囲んだ部分はそのタグが表すコンテキストが設定され、指定の回数分繰り返されます。例えば以下の例は、「最新5件の記事のタイトル」を出力します。

<mt:Entries lastn="5">
<p><$mt:EntryTitle$></p>
</mt:Entries>

<mt:Entries>に囲まれた部分が5回繰り返されますが、その内容は「ブログ記事」コンテキストの最新5件であることを<mt:Entries lastn="5">が表しています。

このように、任意のコンテキストを作り出すMTタグは数多く存在しており、その全てはブロックタグです。ブロックタグで囲んだ内容はそのタグの属するコンテキストになる、と覚えておけばよいでしょう。

コンテキストは入れ子にできる

ブロックタグを入れ子にしたり、特定のアーカイブテンプレート内にブロックタグを記述することによって、コンテキストを入れ子にすることができます。入れ子にしたコンテキストでは、特に指定をしない限り、親のコンテキスト内で対象を絞り込んだものとなります。

例えば以下は記事ごとに、記事本文に続いてコメント一覧を表示するための記述です。

<mt:Entries lastn="5">
<div class="entry">
<h3><$mt:EntryTitle$></h3>
<div class="entry-body">
<$mt:EntryBody$>
</div>
<div class="comments">
<h4>記事へのコメント</h4>
<ul>
<mt:Comments>
<li>
<$mt:CommentAuthor$>さんのコメント:<br />
<$mt:CommentBody$>
</li>
</mt:Comments>
</ul>
</div>
</div>
</mt:Entries>

<mt:Entries><mt:Comments>を入れ子にすることによって、「特定のエントリーへのコメント」に絞り込んで出力させています。なお、特にコンテキストの指定がない状態で<mt:Comments>タグを使用すると、そのブログに対して投稿されたコメント全てが対象となります。

このエントリーの内容はMovableType4(現時点での最新製品版:Version 4.261)におけるものです。まもなく出荷となるMovableType5では「ウェブサイト」という概念が追加されるそうですし、コンテキストの種類には追加や修正があるかもしれません。