SDD(Sleep-Driven Development)

睡眠の重要性!!睡眠の重要性!!

Visual Studio for Mac Extensionの作り方

Visual Studio for Macが正式リリースされたっぽい?のでVisual Studio for Macの拡張の作り方を調べてみました。(Xamarin Studio Addinと変わってなかったけど)

Addin Makerインストー

最初にVS for Mac ExtensionのテンプレートやデバッグサポートをしてくれるAddin Makerを入れます。

VS for Macを開き、Main MenuのVisual Studio→Extensions…を選択します。

f:id:crocus7724:20170513161535p:plain

そして開いたウィンドウのGallery→Addin Development→Addin Makerを選択しインストールします。

f:id:crocus7724:20170513161923p:plain

いつものようにFile→New Solution…を開き、Other→Miscellaneous→Generalに以下のようなものが追加されていたらインストール成功です。

f:id:crocus7724:20170513162226p:plain

_人人人人人人人人人人人人人人_
> Xamarin Studio Addin <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄

Extension作成

ここではサンプルとしてメニューから選択するとConsole.WriteLine("Hello World");を挿入するExtensionを作りたいと思います。(誰得だけど)

まずNew SolutionでXamarin Studio Addinを選択し、プロジェクトを作成します。
なおAddin Makerをインストールして最初の数回はよくアセンブリが見つからなかったりするエラーが発生しますが、VS for Macを再起動したりビルドしたりするとそのうちなおります。

次にメニュー等から選択されたときに実行されるCommandHandlerを作成し以下のように記述します。

using MonoDevelop.Components.Commands;
using MonoDevelop.Ide;

namespace SampleVSExtension
{
    /// <summary>
    /// コマンドが選択されると現在のキャレット位置に
    /// <code>Console.WriteLine("Hello World");</code>が挿入される
    /// コマンドハンドラー
    /// </summary>
    public class HelloWorldCommandHandler : CommandHandler
    {
        /// <summary>
        /// メインメニューなどが開かれるときなどに実行される
        /// ここで可視性や非活性、動的な文字の変更などができる
        /// </summary>
        /// <param name="info">コマンドのステータス</param>
        protected override void Update(CommandInfo info)
        {
            // ActiveDocument(現在開いているファイル)がnullではない(なにかしらのファイルを開いている)
            // ときにコマンドを表示
            info.Visible = IdeApp.Workbench.ActiveDocument != null;
        }

        /// <summary>
        /// コマンドが実際に選択されたときに実行される
        /// </summary>
        protected override void Run()
        {
            // 現在開いているエディタの情報を取得
            var editor = IdeApp.Workbench.ActiveDocument.Editor;
            // 現在のキャレット位置にConsole.WriteLine("Hello World");
            // を表示
            editor.InsertAtCaret("Console.WriteLine(\"Hello World\");");
        }
    }
}

もしusing MonoDevelopとかでエラーが表示されたらVS for Macを一回閉じてもう一度起動してみてください。

細かい説明などはソースコードに書いたので省略して次にCommandの種別を決めるSampleVSExtensionCommandsを作成します。

namespace SampleVSExtension
{
    public enum SampleVSExtensionCommands
    {
        InsertHelloWorld,
    }
}

これはただ単に種別を表すだけなのでとくに説明はありません。

最後に実際にどのような拡張をするかをVS for Macに知らせるManifest.addin.xmlを編集しましょう。
Manifest.addin.xmlAssemblyInfo.csなどがあるPropertiesフォルダの中にあります。

以下のように定義してみましょう。

<?xml version="1.0" encoding="UTF-8"?>
<ExtensionModel>
    <!-- Editという種類のコマンドを定義する -->
    <Extension path="/MonoDevelop/Ide/Commands/Edit">
        <!-- idは用意した種別を表すenumを完全修飾名({namespace}.{enum}.{value})で指定 -->
        <!--_labelはコマンドが表示される文字 -->
        <!-- defaultHandlerはCommandHandlerを拡張したクラスを完全修飾名で指定 -->
        <Command id="SampleVSExtension.SampleVSExtensionCommands.InsertHelloWorld"
                 _label="Insert Hello World"
                 defaultHandler="SampleVSExtension.HelloWorldCommandHandler"/>
    </Extension>
    <!-- MainMenuのEditに表示するコマンドを定義する -->
    <Extension path="/MonoDevelop/Ide/MainMenu/Edit">
        <!-- 上で定義したコマンドのidを指定 -->
        <CommandItem id="SampleVSExtension.SampleVSExtensionCommands.InsertHelloWorld"/>
    </Extension>
</ExtensionModel>

これで準備は完了です。実際に実行してみましょう!

MainMenuのEditにInsert Hello Worldが追加されていて

f:id:crocus7724:20170513171210p:plain

選択したら現在の行に挿入されたら成功です!

f:id:crocus7724:20170513171321p:plain

何故かキャレット位置ではなく行の頭に挿入されているのが謎というかバグですが気にしたら負けです。これで無事やりたいことはできました!!

他の機能の作り方

Visual Studio for Mac Extensionは参考になるものがたくさん公開されています。

私の場合はEditなどのソースコードを編集する機能などは以下を参考にしましたし、

monodevelop/main/src/addins/CSharpBinding at master · mono/monodevelop · GitHub

プロジェクトテンプレートなどの作り方は以下が参考になりました。

monodevelop/main/src/addins/AspNet at master · mono/monodevelop · GitHub

そしてこれらは以下にまとまっています。

monodevelop/main/src/addins at master · mono/monodevelop · GitHub

素晴らしいですね(((

まとめ

VS for MacのPreviewが外れ、.NET CoreやC#7対応を含めてXamarin Studioから徐々に移行してくると思います。
VS for MacのExtensionもXamarin Studio addinとあまり変わってない(たぶん)と思うのでぜひ作ってみてください!!