ライブテンプレートの作り方

By: Yusuke Konno

Abstract: ガリレオIDEの機能のひとつであるライブテンプレートの作り方を紹介します。

    ライブテンプレートの概要

    そもそもライブテンプレートとは?

IDEがガリレオIDEになってから、コードテンプレートがライブテンプレートに進化しました。ライブテンプレートは従来のコードテンプレートとは違い、変数の自動宣言やスクリプトの実行などが可能です。また、ライブテンプレートの実態(テンプレートファイル)はXMLファイルですので、カスタムテンプレートを他のユーザーとの共有することも容易です。

    ライブテンプレート実演

例えば、try~finallyをライブテンプレートで入力しようとしてみます。まず、Ctrl+Jでテンプレート一覧を呼び出し、"try"を選択します。すると以下のような画面になります。

Hide image
ide_lt01

青い四角形で囲われた語句がありますが、これらはtabないしshift+tabで単語間を移動できます。また、同じ語句(画像ではMyClass)であれば同期編集が働くため、瞬時に全てが同じ入力内容に置き換わります。

ここで、MyClassをTFileStream変数のFSに書き換えて、tabキーを1回押します。すると、ふたつのMyClassと言う文字がFSに置き換わり、Componentが選択されます。

Hide image
ide_lt02

Componentが選択された瞬間、自動的にコード補完が立ち上がりました。そして補完内容はFSに適した型であるTFileStreamが選ばれています。Enterキーを押すとComponentがFileStreamに置き換わります。次はtabキーを押してSelfを選択して、fmOpenReadと入力してからtabキーを押します。

最終的に以下のようになります。

Hide image
ide_lt03

従来のコードテンプレートではtry~finally~endが挿入されるだけで、他の箇所を自力で書かなければなりませんでしたが、ライブテンプレートを使えばこの様にあっという間に終わります。

    ライブテンプレートを作成する

    with文のテンプレートを作る

今回はwith文のテンプレートを作ってみようと思います。さほど難しくもないので簡単に読めると思います。

まず、テンプレートファイルの作成方法ですが、通常であればちょっとしたテンプレートを作る時には既存のテンプレートを流用した方が比較的楽に作れます。が、それではあまり意味がないので、今回は新規作成からやってみようと思います。ファイル|新規作成|その他|その他のファイル|コードテンプレートを選んで下さい。

選択するとxmlがエディタに表示されます。ちょうどこんな感じです。

Hide image
ide_lt04

なにやらよく分からないタグがいっぱい出てきました。

    ファイルエンコーディングを適合させる(Delphi 2007以前)

Delphi 2007以前であれば、編集の前にひとつだけやらなければならないことがあります。

ライブテンプレートのファイルはXMLです。そして新規作成でエディタに表示されたコードにもちゃんとXML宣言とタグがならんでいます。ここで、気をつけなければならないのがファイルのエンコーディングです。何気なくXML宣言にはencoding="utf-8"と書かれていますが、エディタのデフォルトのエンコーディングはANSIです。つまりそのまま保存してしまと問題が起こることがあります。具体的に言うと、ASCII以外の文字列を書いて保存した瞬間にエラーが発生することになります。(テンプレートリストの項目が非表示になったり、エラーメッセージが出たり、コードテンプレートが使えなくなります)

この問題を回避するには、

  • XML宣言を修正する
  • エディタのエンコーディングをUTF-8にする

の2通りの方法があります。
UTF-8で保存するのが最も楽です。エディタを右クリックして、ファイルフォーマット|UTF-8を選択してください。

    最初に書かなければならないこと

まず、忘れないうちに以下の項目を真っ先に埋めます。これらを埋める前に保存すると、先述のエラーを発生させる原因となります。

  • template要素のname属性(<template name=””>の部分)
  • code要素のlanguage属性(<code language=””>の部分)
  • description要素(<description>~</description>の部分)
  • author要素(<author>~</author>の部分)

要するに、CDATA以外を全て埋めればよいのです。以下、項目毎に解説します。

    template要素のname属性

テンプレートリストに表示されるテンプレート名です。入力が必須の項目です。Delphi 2009ではUnicode化がされたことを考えると日本語でも良さそうな気がしますが、コード入力中のことを考えれば半角英数以外の文字を混入させること自体あまりよい選択とは言えません。基本的に半角英数のみで名前を付けましょう。

今回の例では"withb"としました。

    code要素のlanguage属性

テンプレートが利用される言語を選択します。ここで言う言語とはDelphi、C++、HTMLといった意味です。これも入力が必須の項目です。

今回の例では"Delphi"としました。

    description要素

テンプレートリストに表示される説明です。分かりやすい説明を付けましょう。ただし、長すぎるとかえって読みづらくなりますので注意してください。

今回は"with文(begin/end付き)"としました。

    author要素

テンプレートの作者の情報を入力します。ご自分の名前を入力しておいて下さい。

これらを埋めた段階で、ソースは以下のようになっています。

<?xml version="1.0" encoding="utf-8" ?>
<codetemplate xmlns="https://schemas.borland.com/Delphi/2005/codetemplates" version="1.0.0">
  <template name="withb" invoke="manual">
    <description>
      with文(begin/end付き)
    </description>
    <author>
      totonica
    </author>
    <code language="Delphi"><![CDATA[]]>
    </code>
  </template>
</codetemplate>

入力が完了したら、保存をしましょう。保存するパスは%BDSUSERDIR%\code_template\にしておきましょう。

    テンプレートの実体は<![CDATA[]]>に記述する

さて、肝心のテンプレートの実体ですが、それはcode要素の<![CDATA[]]>に記述します。早速with文を記述してみましょう。

<?xml version="1.0" encoding="" ?>
<codetemplate xmlns="https://schemas.borland.com/Delphi/2005/codetemplates" version="1.0.0">
  <template name="withb" invoke="manual">
    <description>
      with文(begin/end付き)
    </description>
    <author>
      totonica
    </author>
    <code language="Delphi"><![CDATA[with do
begin

end;]]>
    </code>
  </template>
</codetemplate>

<![CDATA[]]>内部に単純なwith文のスケルトンだけを記述しました。一応これでも問題なく動作しますが、もっと便利にするために通常はもう少し作業をします。

    ジャンプポイントの作成

ライブテンプレート実演のところで書きましたが、tabまたはShift+Tabで移動できるポイントをジャンプポイントと言います。これが設定されているとコーディングが非常に楽になるので、大抵のテンプレートでは設定されています。

ジャンプポイントを作成するには、point要素に必要事項を記入していきます。具体的なコードを見てみましょう

<?xml version="1.0" encoding="" ?>
<codetemplate xmlns="http://schemas.borland.com/Delphi/2005/codetemplates" version="1.0.0">
  <template name="withb" invoke="manual">
    <description>
      with文(begin/end付き)
    </description>
    <author>
      totonica
    </author>
    <point name="expr">
      <text>
        variable
      </text>
      <hint>
        変数
      </hint>
    </point>
    <code language="Delphi" context="methodbody" delimiter="|"><![CDATA[with |expr| do
begin
|selected||*||end|
end;]]>
    </code>
  </template>
</codetemplate>

point要素内にtext要素とhint要素を記述し、code要素と<![CDATA[]]>を編集しました。順を追って説明します。

    point要素のname属性

<![CDATA[]]>内でのジャンプポイントの識別子になります。言うまでもないことですがユニークである必要性があります。

text要素

ジャンプポイントに記述されるデフォルトの値です。

    hint要素

文字通りですが、チップヘルプとして表示される文字列です。

    code要素のcontext属性

テンプレートのコンテキストを設定します。今回の例だと、methodbodyが適切です。

    code要素のdelimiter属性

<![CDATA[]]>内で区切り文字となる文字を指定します。ジャンプポイントはpoint要素のname属性に指定した値をこの区切り文字で囲むことで有効に成立します。ジャンプポイントを使用する際には必ず指定しなければなりません。通常は |(縦線)が用いられます。

    予約済みジャンプポイント(selected、end、*)

  • selected:コードエディタで選択されたテキストです。ちなみに編集不能です。
  • end:テンプレート実行後のカーソル位置です。
  • *:インデントです。インデント幅はエディタの設定に準じます。

ジャンプポイントを複数にする場合は、point要素を追加し、<![CDATA[]]>内に反映していけばOKです。

とりあえずこれでwith文の作成は完了です。お疲れ様でした。

    スクリプト(参考)

ジャンプポイントでは特定のスクリプトを実行することが出来ます。point要素内にscript要素を記述し、その内部に実行するスクリプトを指定します。

    script要素の属性

  • language:言語(Delphi、Cなど)を指定します。これにより実行できるスクリプトが変わります。必須属性です。
  • onvalidate:trueにすると、テンプレート実行前にスクリプトを実行します。デフォルトはfalseです。
  • onenter:trueにすると、そのジャンプポイントに移った時にスクリプトを実行します。デフォルトはtrueです。
  • onleave:trueにすると、そのジャンプポイントから正しく離れた際にスクリプトを実行します。デフォルトはfalseです。

    languageにDelphiを指定した際に実行できるスクリプト

  • InvokeClassCompletion:クラス補完を起動します。
  • InvokeCodeCompletion;コード補完を起動します。
  • PopulateCase(|expression|):expressionに指定された値のcase文のラベルを列挙します。
  • DeclareVariable(|variable|):変数を宣言します。
  • RemoveTemplate:テンプレートを除去します。
  • ValidateForTemplate:For文を検証します。

    参考サイト

英語ではありますが、Delphi Wikiにライブテンプレートに関する資料がたくさんあります。

Live Templates Technical Info - DelphiWiki(英語)

Server Response from: ETNASC04