- 2009-05-30 (土) 17:59
- CSharp | FlashDevelop

FlashDevelop 3.0.0 RC3 から Macro が追加された。
今回はそれについて勉強してみようと思う。
さて、Macro ではどんなことができるのか。
http://www.flashdevelop.org/wikidocs/index.php?title=Macros
を読んでみる。
まぁ簡単に説明すると、
「マクロを使うことで FlashDevelop で行う処理をショートカットに割り当てたりできますよ。」
的な感じだと思う。
どんな感じで書くかというと
<Command>|<Parameters>
と書く、最初にコマンドを入れて、次にパラメータを入力する。
コマンドはどんなのがあるのかというと以下のコマンドが実行できる。
- ExtractZip|<File>
ZipFile を解凍して、 FlashDevelopHome の Templates の中に入れる。 - ExecuteScript|[<Mode>;]<File>
C# で書かれたスクリプトを実行する。 - RunProcess|<File>[;<Args>[...;<Args>]]
プロセスを実行する。引数をつけることもできる。 - RunProcessCaptured|<File>[;<Args>[...;<Args>]]
RunProcess と同じだがキャプチャしながら実行できる。 - PluginCommand|<Command>[;<Args>]
プラグイン全部にコマンドを送ることができる。 - ScintillaCommand|<Command>
Scintilla エディターコンポーネントのメソッドを呼ぶことができる。 - SaveAllModified[|<Extension>]
現在開いているすべての変更があったファイルをセーブすることができる。Extension に指定した拡張子のファイル、またはすべて。 - NewFromTemplate[|<Extention>[;<TemplateFile>]]
新しいファイルを作る。テンプレートを指定することもできる。
[] で囲まれている部分は省略可。
他にもあるらしいよ。
なんといっても ExecuteScript が一番便利!っていうかやれる幅がほかのとは違う。
ほとんど何でもできるといっていいのでは?と思うくらい。
今回はこの ExecuteScript コマンドを説明しようと思う。
さて、ExecuteScript はパラメータを “;” でつないで実行モード(Internal, External, Development) を選択できる。
またはモードは省略することができる。
モードを省略した場合は External モードと同じ。
つまり
ExecuteScript|[<Mode>;]<File>
となる。それぞれのモードは以下のようになっている。
Internal モードは
FlashDevelop のプラグインとしてスクリプトを実行して、FlashDevelop の ランタイムインスタンスにアクセスできる。同じアプリケーションドメインにロードされるときテンプファイルはロックされる。
External モードは
FlashDevelop のランタイムインスタンスへのアクセスなしで終了するとスクリプトは実行して解放される。テンプファイルは実行された後で解放され、ファイルロックは起こらない。
Development モードは
Internal モードと似ているが、いつでも新しい一時ファイルを作りなおす。新しい内部スクリプトを開発するときだけ使用すべき。
んー、いまいち External の使い道がわからない。とりあえず、External だと FlashDevelop のランタイムインスタンスにアクセスができない?っぽいので Development で作って、Internal で設定しておくとよさげ。
と思ったのだが、一時ファイルがロックされるため、Internal にしておくと2回目以降一時ファイルにアクセスできませんと表示され実行できない。俺の環境だけなのかな?・・・。
一時ファイルって何だ?って思って調べてみたら、一回目に実行した際に
C:\Documents and Settings\[ユーザー名]\Local Settings\Temp\CSSCRIPT\Cache
にコンパイルしたファイルが作られる。次回からはコンパイルされないので早くマクロが動くとかそういうことだと思う。
Development モードにしておけば毎回一時ファイルを破棄して新しく作り直すのでちょっと遅い。
でも Internal にしておくと一回しか動かないし・・・。
とりあえず、詳しくわかるまでは Development モードで進めます。
Script の Syntax はシンプル。public なクラスを作って、 public static void Execute っていうメソッドを書いておけばそこからスタートする。
さて、実際に書いてみよう。
ちなみに C# は一度も書いたことがない。なので自分と同じように C# を書いたことがない人でもわかるレベルのことしか書けないと思います。
まずはベースを作ります。このクラスを拡張して作っていきましょう。
ベースはこれにします。
// FDScript.cs
using FlashDevelop;
public class FDScript
{
public static void Execute()
{
Globals.MainForm.About(null, null);
}
}
これをどこか適当に置いておく。
自分は E:\FDP\csmacro のようなディレクトリを掘って置いておいた。
まずは実行してみよう。
Macros に Execute Script のサンプルがあるのでそれで実行してみる。
Execute Script を選択すると、ファイルを選ぶ画面になるので先ほど作った FDScript.cs を選択してみます。
すると Help の About FlashDevelop が表示された。
いちいち選択するのが面倒な人は Macros の Edit で以下のように設定しておこう。
Add ボタンで新しいマクロを作り、 Entries に以下を書いておく
ExecuteScript|Development;<FilePath>
ファイルパスは、$(BaseDir) などを使うことができるので長くなるのが嫌な人は使って短くしよう。
Shortcut を設定すれば使いやすさは向上するよ!
さて、マクロを動かすことはできたので目標を立てよう。
Twitter で何かできたらいいなを聞いてみたところ、dkgkAs さん(http://d.hatena.ne.jp/ActionScript/)が こんなことを呟いていたのでそれを目標にすることにした。
http://twitter.com/dkgkAs/status/1969021868
・今開いてるasをショートカットキー1つでAlways Compileに設定する
これならいけそうな気がするーーー!!!
というかこれ確かにほしい!って思ったのでww
まず C# がどんな感じで書くのか AS3 と比較してみようと思う。
AS3 ではこんな感じかな?
package
{
import FlashDevelop.*;
public class FDScript
{
public static function Execute(): void
{
Globals.MainForm.About(null, null);
}
}
}
C# で書くとこんな感じ?
using FlashDevelop;
// おそらくFlashDevelop っていうネームスペース以下を使いますよ宣言
// AS3 でいうパッケージ以下 import って感じだと思う。
// namespace を使うときは namespace Hoge {} で括る
public class FDScript
{
public static void Execute() // 戻り値は後じゃなくてメソッド名の前につける。
{
Globals.MainForm.About(null, null);
}
}
FlashDevelop っていうネームスペース以下にはおそらく Globals ってのがあるんだろう。
どこに何があるのかわからないとどうしようもない。って思ってさまよっていると
googlecode にたどり着いた。
ここ見ればわかる!
http://code.google.com/p/flashdevelop/source/browse/
ここに FlashDevelop のソースが公開されているので
それを参考に進めようと思う。
まず、目標を達成するためにどんな行程が必要そうかを予想する。
- 現在開いているファイルのパスを取得する。
- 現在のプロジェクト以下にあるかどうかを比較する。
- 現在のプロジェクト以下じゃなければエラー
- 現在のプロジェクト以下なら次へ進む
- 現在開いているファイルが AS, MXML ファイルかどうかを調べる。
- AS, MXML じゃなかったらエラー
- AS, MXML だったら次へ
- 現在開いているファイルを AlwaysCompile に指定する。
こんな感じの大雑把な流れを作ってみた。
これでいけるのかはわからない。
とりあえず現在開いているファイルのパスをとってみる。
Globals を見ていたら CurrentDocument というプロパティがあったのでそれを使うことにした。
とはいえ、これをどうやったら、開いているファイルだといえるのか・・・。
そうだ!トレースしよう!
開発の基本は trace にあり!
trace を笑うものは trace に泣く!
おそらく、FlashDevelop の Output パネルに表示させるためのクラスがあるはず。で見つけた。
PluginCore.Managers に TraceManager があったのでこれを使うことにした。
// FDScript.cs
using FlashDevelop;
using PluginCore.Managers;
public class FDScript
{
public static void Execute()
{
TraceManager.Add("現在のドキュメント : " + Globals.CurrentDocument);
}
}
これを実行してみる。
現在のドキュメント : FlashDevelop.Docking.TabbedDocument, Text: FDScript.cs
と表示された。
さて、次は現在のプロジェクトを見ることにしよう。
ざっと FlashDevelop のソースを見たところ PluginBase に CurrentProject ってのがあった。
おそらくこれ。
// FDScript.cs
using FlashDevelop;
using FlashDevelop.Docking;
using PluginCore;
using PluginCore.Managers;
using ProjectManager.Projects;
public class FDScript
{
public static void Execute()
{
TabbedDocument nowDoc = (TabbedDocument)Globals.CurrentDocument;
// 後でいろいろ使うから変数に持っておく。
// (TabbedDocument) ってのは後ろに続く変数をカッコ内の型にキャストする。ってこと。
// 変数の書き方は
// 型 変数名 = new 型();
// な感じ。
TraceManager.Add("現在のドキュメント : " + nowDoc);
Project project = (Project)PluginBase.CurrentProject;
TraceManager.Add("現在のプロジェクト : " + PluginBase.CurrentProject);
}
}
現在のドキュメント : FlashDevelop.Docking.TabbedDocument, Text: FDScript.cs
現在のプロジェクト : ProjectManager.Projects.AS3.AS3Project
うん。どうやらうまく前に進んでる気がする。
さて、次はそれぞれのパスを見てみる。
using FlashDevelop;
using FlashDevelop.Docking;
using PluginCore;
using PluginCore.Managers;
using ProjectManager.Projects;
public class FDScript
{
public static void Execute()
{
TabbedDocument nowDoc = (TabbedDocument)Globals.CurrentDocument; // 後でいろいろ使うから変数に持っておく。
TraceManager.Add("現在のドキュメント : " + nowDoc);
Project project = (Project)PluginBase.CurrentProject;
TraceManager.Add("現在のプロジェクト : " + PluginBase.CurrentProject);
TraceManager.Add("nowDoc Path : " + nowDoc.FileName);
TraceManager.Add("project Dir : " + project.Directory);
}
}
現在のドキュメント : FlashDevelop.Docking.TabbedDocument, Text: FDScript.cs
現在のプロジェクト : ProjectManager.Projects.AS3.AS3Project
nowDoc Path : E:\FDP\csmacro\DScript.cs
project Dir : E:\FDP\test\alltest\test
あとはこれを現在のプロジェクトのファイルかどうかを判断して AS, MXML ファイルかどうかで分岐させる。
ついでにエラーだったら警告アラートみたいなのを出すようにしておこう。
警告アラートは TraceManager と同じディレクトリに ErrorManager ってのがあったからそれを利用することにする。
using FlashDevelop;
using FlashDevelop.Docking;
using PluginCore;
using PluginCore.Managers;
using ProjectManager.Projects;
public class FDScript
{
public static void Execute()
{
Project project = (Project)PluginBase.CurrentProject;
TabbedDocument nowDoc = (TabbedDocument)Globals.CurrentDocument;
// StartsWith で始まりに指定した文字列があるかを比較できる。
if (nowDoc.FileName.StartsWith(project.Directory))
{
if (nowDoc.FileName.EndsWith(".as"))
{
// AS
TraceManager.Add("ASファイルですよ!");
}
else
{
if (nowDoc.FileName.EndsWith(".mxml"))
{
// MXML
TraceManager.Add("MXMLファイルですよ!");
}
else
{
ErrorManager.ShowWarning(nowDoc.FileName + " は、AS, MXMLファイルではありません。", null);
}
}
}
else
{
ErrorManager.ShowWarning(nowDoc.FileName + " は、現在の Project のファイルではありません。", null);
}
}
}
これで判断できるようになった。
さてあとは AlwaysCompile を変える。
一応 FD の仕様通りトグル状にしておこう。(AlwaysCompile に指定されてた場合は AlwaysCompile からはずす)
これで完成!!!!
完成したからとりあえず 名前を AlwaysCompileShortcut.cs に変えてみた。
using FlashDevelop;
using FlashDevelop.Docking;
using PluginCore;
using PluginCore.Managers;
using ProjectManager.Controls.TreeView;
using ProjectManager.Projects;
public class AlwaysCompileShortcut
{
public static void Execute()
{
Project project = (Project)PluginBase.CurrentProject;
TabbedDocument nowDoc = (TabbedDocument)Globals.CurrentDocument;
// StartsWith で始まりに指定した文字列があるかを比較できる。
if (nowDoc.FileName.StartsWith(project.Directory))
{
// 現在のプロジェクト内のファイル。
if (nowDoc.FileName.EndsWith(".as"))
{
// AS
ToggleAlwaysCompile(project, nowDoc.FileName);
}
else
{
if (nowDoc.FileName.EndsWith(".mxml"))
{
// MXML
ToggleAlwaysCompile(project, nowDoc.FileName);
}
else
{
ErrorManager.ShowWarning(nowDoc.FileName + " は、AS, MXMLファイルではありません。", null);
}
}
}
else
{
// 現在のプロジェクト外のファイル。
ErrorManager.ShowWarning(nowDoc.FileName + " は、現在の Project のファイルではありません。", null);
}
}
public static void ToggleAlwaysCompile(Project project, string path)
{
bool isTarget = project.IsCompileTarget(project.GetAbsolutePath(path));
// 指定しようとしているファイルがコンパイルターゲットかどうかを判断する。
project.SetCompileTarget(path, !isTarget);
// コンパイルターゲットに指定する。
if (project.MaxTargetsCount > 0)
{
while (project.CompileTargets.Count > project.MaxTargetsCount)
{
// 以前までのコンパイルターゲットをターゲットからはずす。
string relPath = project.CompileTargets[0];
string path2 = project.GetAbsolutePath(relPath);
project.SetCompileTarget(path2, false);
}
}
project.Save();
// project をセーブする。
ProjectTreeView.Instance.RefreshTree();
// ツリーを再描画させる。
TraceManager.Add("AlwaysCompile のターゲットを" + path + " に変更しました。");
}
}
C# を微塵もかじったことのない ASer が、2時間ぐらいで作った割には意外とよく出来てる方だと思うw
自分で自分をほめてあげようと思いますw
ダウンロードはここからどうぞ(http://www.bk-zen.com/lab/csmacro/AlwaysCompileShortcut.cs)
これを以下のように設定して、ショートカットを指定すれば、現在のファイルが AlwaysCompile に設定される。
ExecuteScript|Development;E:\FDP\csmacro\AlwaysCompileShortcut.cs
まとめ
ざーっと調べてわかったこととしては、
マクロで ExecuteScript 以外はほとんど使わなくていいかもしれない。
ExecuteScript があれば、ほかのことが全て可能。
内部的に CallCommand を呼んでるっぽい。
ExecuteScript をコマンドとしてファイルをコンパイルしたら、それは一時的にプラグインとして使用される。
つまり、ExecuteScript でその他のコマンドはすべて実行できる!
さぁ、これで誰でも楽ちんな FlashDevelop マクロが作れる!
おまけ
ScintillaCommand を使うと Cut とか Paste とか を実行できるよ。
おまけ2
Edit で AutoRun を true にすると 起動時に実行されるよ。
- Newer: FlashDevelop 3.0.0 RC5 リリースされたよ。
- Older: FlashDevelop 3.0.0 RC4 でたよ
Comments:0
Trackbacks:4
- Trackback URL for this entry
- http://blog.bk-zen.com/2009/05/30/164/trackback/
- Listed below are links to weblogs that reference
- FlashDevelop Macro ExecuteScript で無限の可能性 from 馬鹿全
- trackback from 独学ActionScript 09-05-31 (日) 10:14
-
[FlashDevelop]FlashDevelopの使い方 (11)マクロ機能(コンパイル指定してムービープレビューまでを自動化)…
RC3から搭載されたマクロ機能ですが、ほとんど日本語の情報が無かったので全く使えていませんでした。ところが昨日、FlashDevelopエバンジェリストと一部で呼ばれている馬鹿全さんが、…
- trackback from papi-blo 09-06-26 (金) 3:46
-
FlashDevelop Macro で連番のダミー画像生成…
馬鹿全 - FlashDevelop Macro ExecuteScript ……
- pingback from flabaka - FlashDevelopのマクロ機能を使ってみる(1) 09-08-30 (日) 21:52
-
[...] FlashDevelop Macro ExecuteScript で無限の可能性(馬鹿全さん) [...]
- pingback from flabaka - マクロの実行方法 10-01-06 (水) 13:14
-
[...] 以前にbkzenさんが、『FlashDevelop Macro ExecuteScript で無限の可能性』という記事をエントリされているので、ご存じの方もいらっしゃるかも知れませんが… [...]


