Morning Girl

Web API, Windows, C#, .NET, Dynamics 365/CRM etc..

独自スクリプト言語の VS Code Snippet を作ってみた:CData API Script

普段メインのエディタとして、VS Codeを使っています。

簡単なプログラミングから、ログ漁り、PowerShellなどの実行まで、これで一通りやっているんですが、その中の一つに私の会社で出している製品の独自スクリプト言語を書くという仕事(半分趣味)がありました。

こんな感じでXMLを拡張して、製品に独自の拡張機能をもたらす感じのもので、CData API Script と言います。

f:id:sugimomoto:20191029224204p:plain

結構いい感じに狂っていて(褒め言葉)、変数定義から連想配列、IF文、ループ処理、バリデーション、Try Catch機構から、文字列・日付・算術操作用の関数まであって、なかなか面白いんですが、いかんせんインテリセンスも効かないので、毎度リファレンスを漁りながら書き書きしているわけです。XML的文法チェックは効くんですけどね。

f:id:sugimomoto:20191029224211p:plain

そんな折、最近「徹底解説Visual Studio Code」で独自のSnippetを追加できるという記事を読みまして、これはやってみるかしか無い! と思い作ってみた記録がこの記事です。

ちなみに、CData API Script で何ができるの? と言いますと、いろんなクラウドサービスのWeb APIREST APIをコールして、コネクター・ドライバー製品からデータの操作ができるようにしています。以下一例

kageura.hatenadiary.jp

なんだかんだで既に数十サービスのScriptを書いているんですが、結構コピペが重なるパターンも多いので、これはいいのではと思ったり。

ちなみに今回作ったものは以下で公開しています。

github.com

Snippet って何?

繰り返し使う条件ステートメントやループ、何度も使うコード・一連の処理などを登録しておいて、入力を安易にするためのテンプレートセットのことを指します。

以下のURLの解説とGIF画像がわかりやすいですね。

code.visualstudio.com

https://code.visualstudio.com/assets/docs/editor/userdefinedsnippets/ajax-snippet.gif

有名なプログラミング言語は、VS Code Marketplaceから入手したりできますが、今回のように独自の言語や、自分や組織だけが使うコードの場合は、ユーザー独自のSnippet が作れるようにVS Code拡張機能を用意しています。

VS Code の Snippet の作り方(ユーザースニペット

作り方は簡単です。VS Codeを立ち上げて、コマンドパレットからユーザースニペットの構成(もしくはファイル > 基本設定 > ユーザースニペット)を選択します。

f:id:sugimomoto:20191029224315p:plain

ここで各言語を選択すれば、その言語用のSnippetを追加できますし、新しいグローバルスニペットファイルを選択すれば、どの範囲まで作成したsnippetを利用できるようにするか、スコープを決めたsnippetも作れます。

f:id:sugimomoto:20191029224321p:plain

とりあえずわかりやすく新しいグローバルスニペットを選択しました。

ファイルを保存すると以下のようにスニペットを書くためのJSONファイルが生成されます。

f:id:sugimomoto:20191029224328p:plain

サンプルにもありますが、私が実際に作っているものベースで以下のような感じで書きます。

{
  "api:if": { // Snippet の名前。ファイル内で重複できません。
    "scope": "xml", // Scope。使う言語を指定できます。
    "prefix": "if", // Snippetを使う時の文字列。これをプレフィックスを打ちはじめることで候補として表示されます。
    "body": [ // Snippetで実際に生成される文字列です。配列で1行ごとに指定します。
      "<api:if attr=\"${1:attr1}\" value=\"[${2:attr2}]\" operator=\"${3:equals}\">",
      "<api:else>",
      "False",
      "</api:else>",
      "True",
      "</api:if>"
    ],
    "description": "You can use the api:if keyword to evaluate expressions that can contain items, attributes, and values. The scope of the keyword is executed if the specified expression evaluates to true." 
  },// Snippetを選択する時に表示される説明文です。
  "api:include": { // Snippet 2つ目
    "scope": "xml",
    "prefix": "include",
    "body": [
      "<api:include file=\"${1:globals.rsb}\"/>"
    ],
    "description": "The api:include keyword is used to include API Script from other files. Like traditional includes in other programming languages, api:include is replaced by the contents of the file specified in the file parameter."
  }
}

ちなみにBodyに書いてある「${1:attr1}」はタブストップです。数字の番号順にタブが止まります。

「$1」「$2」と書いてもいいですし、デフォルトの値を表示したい場合は「${1:Hogehoge}」と書きます。

このあたりは以下のリンクにも詳しく書いてあります。

Snippets in Visual Studio Code

で実際に使ってみた感じが以下の通りです。

https://cdatajbuilds.s3-ap-northeast-1.amazonaws.com/sugimototest/snippet.gif

インデント入れ忘れたな、と作ったあとに気づきました。

まったく需要が無いと思われる CData API Scriptの作り方

最終的にできあがった Snippet ファイルはこんな感じです。1200行あってエグいですね。200個近く Snippet がある感じです。

https://cdatajbuilds.s3-ap-northeast-1.amazonaws.com/sugimototest/snippetlist.gif

ちなみにどうやったかと言えば、C#スクレイピングAngleSharp)するプログラムを書いて、以下のHTMLベースリファレンスから全部漁りました。

http://cdn.cdata.com/help/DWE/jp/ado/pg_stringvalueformatters.htm

f:id:sugimomoto:20191029224421p:plain

それを最終的にJSON用のオブジェクトに格納して、シリアライズJson.NET

あまりに汎用性が無いので、非公開。

中の人なのになんで!? って思われれるかもしれないですが、言語定義とヘルプ用説明HTMLがわかれていて、どうしようもなかった・・・。

ただ、リファレンスだけが公開されている独自言語ってそれなりにあると思うので、こういったスクレイピングアプローチは他にも結構ありえるかなと思ったりです。

使い方

もし使って、CData API Scriptを使って、書いてみたい! という方は、以下からCData REST Driverのトライアル版と

www.cdata.com

以下から Snippet を取得してやってみましょう!(布教

github.com

CallConnect REST API をベースに作ったサンプルが以下にあります。

github.com