前回の準備編の続きです。
今回は、言語サービスの拡張を作るための、ベース部分を作成していきます。
ということで、早速ベース部分を作成していきます。
前回作成した VSPackage を変更します。
言語サービスの提供には、 ProvideServiceAttribute
, ProvideLanguageServiceAttribute
を、
拡張子の登録として、 ProvideLanguageExtensionAttribute
を付けます。
つけた例が下の感じ。
using System; using System.ComponentModel.Design; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using HSPToolsVS.Language; using Microsoft.VisualStudio.OLE.Interop; using Microsoft.VisualStudio.Package; using Microsoft.VisualStudio.Shell; namespace HSPToolsVS { /// <summary> /// This is the class that implements the package exposed by this assembly. /// </summary> /// <remarks> /// <para> /// The minimum requirement for a class to be considered a valid package for Visual Studio /// is to implement the IVsPackage interface and register itself with the shell. /// This package uses the helper classes defined inside the Managed Package Framework (MPF) /// to do it: it derives from the Package class that provides the implementation of the /// IVsPackage interface and uses the registration attributes defined in the framework to /// register itself and its components with the shell. These attributes tell the pkgdef creation /// utility what data to put into .pkgdef file. /// </para> /// <para> /// To get loaded into VS, the package must be referred by <Asset Type="Microsoft.VisualStudio.VsPackage" ... /// > in .vsixmanifest file. /// </para> /// </remarks> [PackageRegistration(UseManagedResourcesOnly = true)] [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] // Info on this package for Help/About [Guid(PackageGuidString)] [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "pkgdef, VS and vsixmanifest are valid VS terms")] // Register a Language Service [ProvideService(typeof(HSPLanguageService), ServiceName = "HSP Language Service")] [ProvideLanguageService(typeof(HSPLanguageService), "HSP", 0)] [ProvideLanguageExtension(typeof(HSPLanguageService), ".hsp")] [ProvideLanguageExtension(typeof(HSPLanguageService), ".as")] public sealed class HSPVSPackage : Package { /// <summary> /// HSPVSPackage GUID string. /// </summary> public const string PackageGuidString = "d831da21-d940-4ad0-aa2a-4a7a04e3d6c4"; #region Package Members /// <summary> /// Initialization of the package; this method is called right after the package is sited, so this is the place /// where you can put all the initialization code that rely on services provided by VisualStudio. /// </summary> protected override void Initialize() { base.Initialize(); } protected override void Dispose(bool disposing) { var serviceContainer = this as IServiceContainer; serviceContainer.RemoveService(typeof(HSPLanguageService)); base.Dispose(disposing); } #endregion } }
ProvideLanguageExtension
にて、 *.hsp
, .as
を対象の拡張子として登録しています。
また、言語サービスのクラスとして、 HSPLanguageService
を指定しています。
次に、サービスコンテナに HSPLanguageService
を登録します。
Initialize
メソッドの中に、以下の処理を追加します。
base.Initialize(); var serviceContainer = this as IServiceContainer; var hspLangService = new HSPLanguageService(); hspLangService.SetSite(this); serviceContainer.AddService(typeof(HSPLanguageService), hspLangService, true);
次は、 HSPLanguageServie
の実装です。
このクラスは、 LanguageService
を継承しておく必要があります。
using Microsoft.VisualStudio.Package; using Microsoft.VisualStudio.TextManager.Interop; namespace HSPToolsVS.Language { internal class HSPLanguageService : LanguageService { private LanguagePreferences _languagePreferences; private IScanner _scanner; public override string Name => "HSP"; public override LanguagePreferences GetLanguagePreferences() { if (_languagePreferences != null) return _languagePreferences; _languagePreferences = new LanguagePreferences(Site, typeof(HSPLanguageService).GUID, Name); _languagePreferences.Init(); return _languagePreferences; } public override IScanner GetScanner(IVsTextLines buffer) { return _scanner ?? (_scanner = new HSPScanner(buffer)); } public override AuthoringScope ParseSource(ParseRequest req) { return new HSPAuthoringScope(); } public override string GetFormatFilterList() => "HSP Script Files(*.hsp,*.as)|*.hsp;*.as"; } }
Name
プロパティには言語名を、 GetFormatFilterList
メソッドには、 ファイルダイアログで用いるフィルター文字列を設定しておきます。
フィルター文字列については、こちらを参照してください。
LanguagePreferences
には、提供する機能や、言語のデフォルト設定(タブのスペース数など)を
設定したものを返します。
特に設定する必要が無い場合は、デフォルトの物を使えば問題ありません。
GetScanner
及び ParseSource
は、それぞれ IScanner
, AuthoringScope
を実装/継承した
クラスを作成し、それを返せば OK です。
これで、言語サービスを提供するための、必要最低限の実装が完了しました。
次回は、必要不可欠な要素の一つである、シンタックスハイライトの実装をしていきます。
参考: