diff --git a/tools/vslol/LolFxLanguageService.cs b/tools/vslol/LolFxLanguageService.cs new file mode 100644 index 00000000..36ccda31 --- /dev/null +++ b/tools/vslol/LolFxLanguageService.cs @@ -0,0 +1,137 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Microsoft.VisualStudio; +using Microsoft.VisualStudio.Package; +using Microsoft.VisualStudio.TextManager.Interop; +using Microsoft.VisualStudio.OLE.Interop; + +namespace Lol.VisualStudio.Plugin +{ + class LolFxLanguageService : LanguageService + { + public override string GetFormatFilterList() + { + throw new NotImplementedException(); + } + + public override LanguagePreferences GetLanguagePreferences() + { + if (m_preferences == null) + { + m_preferences = new LanguagePreferences(this.Site, + typeof(LolFxLanguageService).GUID, this.Name); + m_preferences.Init(); + } + return m_preferences; + } + + public override IScanner GetScanner(IVsTextLines buffer) + { + if (m_scanner == null) + { + m_scanner = new LolFxScanner(buffer); + } + return m_scanner; + } + + public override string Name + { + get { return "LolFx"; } + } + + public override AuthoringScope ParseSource(ParseRequest req) + { + return new LolFxAuthoringScope(); + } + + private LanguagePreferences m_preferences; + private LolFxScanner m_scanner; + + internal class LolFxScanner : IScanner + { + public LolFxScanner(IVsTextBuffer buffer) + { + m_buffer = buffer; + } + + bool IScanner.ScanTokenAndProvideInfoAboutIt(TokenInfo tokeninfo, ref int state) + { + while (m_offset < m_source.Length) + { + if (m_source[m_offset] == ' ' || m_source[m_offset] == '\t') + { + ++m_offset; + continue; + } + + tokeninfo.StartIndex = m_offset; + tokeninfo.EndIndex = m_offset; + tokeninfo.Type = TokenType.Unknown; + switch (state % 4) + { + case 0: tokeninfo.Color = TokenColor.Number; break; + case 1: tokeninfo.Color = TokenColor.Text; break; + case 2: tokeninfo.Color = TokenColor.Keyword; break; + case 3: tokeninfo.Color = TokenColor.Comment; break; + } + ++m_offset; + ++state; + return true; + } + + return false; + } + + enum State + { + Default, + CComment, + CppComment, + String, + } + + void IScanner.SetSource(string source, int offset) + { + m_source = source; + m_offset = offset; + } + + private IVsTextBuffer m_buffer; + string m_source; + int m_offset; + } + + internal class LolFxAuthoringScope : AuthoringScope + { + public override string GetDataTipText(int line, int col, out TextSpan span) + { + span = new TextSpan(); + return null; + } + + public override Declarations GetDeclarations(IVsTextView view, + int line, + int col, + TokenInfo info, + ParseReason reason) + { + return null; + } + + public override string Goto(VSConstants.VSStd97CmdID cmd, IVsTextView textView, int line, int col, out TextSpan span) + { + span = new TextSpan(); + return null; + } + + public override Methods GetMethods(int line, int col, string name) + { + return null; + } + } + } +} + diff --git a/tools/vslol/MenuGenerateCompilers.cs b/tools/vslol/MenuGenerateCompilers.cs index dd0b05fc..4e08d067 100644 --- a/tools/vslol/MenuGenerateCompilers.cs +++ b/tools/vslol/MenuGenerateCompilers.cs @@ -91,14 +91,14 @@ namespace Lol.VisualStudio.Plugin if (cmd == null) return; - cmd.ClearOutputPane(); - cmd.WriteToOutputPane("------ Build started: Generating Compilers ------\n"); + Logger.Clear(); + Logger.Info("------ Build started: Generating Compilers ------\n"); int scanner_count = 0, parser_count = 0, error_count = 0; foreach (Project project in cmd.projects) { - cmd.WriteToOutputPane("Project " + project.Name + "\n"); + Logger.Info("Project " + project.Name + "\n"); string project_path = Path.GetDirectoryName(project.FullName); @@ -137,7 +137,7 @@ namespace Lol.VisualStudio.Plugin if (item.Name.EndsWith("-scanner.l")) { - cmd.WriteToOutputPane("flex.exe " + filename + "\n"); + Logger.Info("flex.exe " + filename + "\n"); string basename = Path.GetFileName(filename.Substring(0, filename.LastIndexOf("-scanner.l"))); if (!cmd.Run(project_path, @@ -153,7 +153,7 @@ namespace Lol.VisualStudio.Plugin if (item.Name.EndsWith("-parser.y")) { - cmd.WriteToOutputPane("bison.exe " + filename + "\n"); + Logger.Info("bison.exe " + filename + "\n"); string basename = Path.GetFileName(filename.Substring(0, filename.LastIndexOf("-parser.y"))); if (!cmd.Run(project_path, @@ -173,7 +173,7 @@ namespace Lol.VisualStudio.Plugin } } - cmd.WriteToOutputPane(string.Format("========== Done: {0} scanner(s), {1} parser(s), {2} error(s) ==========\n", + Logger.Info(string.Format("========== Done: {0} scanner(s), {1} parser(s), {2} error(s) ==========\n", scanner_count, parser_count, error_count)); } @@ -202,52 +202,26 @@ namespace Lol.VisualStudio.Plugin string output = p.StandardError.ReadToEnd() + p.StandardOutput.ReadToEnd(); p.WaitForExit(); - WriteToOutputPane(output); + Logger.Info(output); if (p.ExitCode != 0) { - WriteToOutputPane("Error: " + executable + " exited with code " + p.ExitCode + "\n"); + Logger.Info("Error: " + executable + " exited with code " + p.ExitCode + "\n"); if (arguments != "") - WriteToOutputPane("Error: args: " + arguments + "\n"); + Logger.Info("Error: args: " + arguments + "\n"); if (env != "") - WriteToOutputPane("Error: env: " + env + "\n"); + Logger.Info("Error: env: " + env + "\n"); return false; } } catch (Exception e) { - WriteToOutputPane("Error: failed to launch " + executable + "\n"); + Logger.Info("Error: failed to launch " + executable + "\n"); return false; } return true; } - private void ClearOutputPane() - { - IVsOutputWindow win = sp.GetService(typeof(SVsOutputWindow)) as IVsOutputWindow; - if (null == win) - { - Trace.WriteLine("Failed to get a reference to IVsOutputWindow"); - pane = null; - } - - Guid guid = Microsoft.VisualStudio.VSConstants.OutputWindowPaneGuid.BuildOutputPane_guid; - if (Microsoft.VisualStudio.ErrorHandler.Failed(win.GetPane(ref guid, out pane))) - { - Trace.WriteLine("Failed to get a reference to the Output window Build pane"); - pane = null; - } - - pane.Activate(); - pane.Clear(); - } - - private void WriteToOutputPane(string s) - { - if (pane != null) - pane.OutputString(s); - } - private static IEnumerable ParseProjectItems(object o) { ProjectItems subitems; @@ -267,7 +241,6 @@ namespace Lol.VisualStudio.Plugin } private ServiceProvider sp; - private IVsOutputWindowPane pane; private List projects; } diff --git a/tools/vslol/VsLol.cs b/tools/vslol/VsLol.cs index 2ac907c2..c279323c 100644 --- a/tools/vslol/VsLol.cs +++ b/tools/vslol/VsLol.cs @@ -13,11 +13,26 @@ namespace Lol.VisualStudio.Plugin { [PackageRegistration(UseManagedResourcesOnly = true)] + /* LolFx syntax highlighting */ + [ProvideServiceAttribute(typeof(LolFxLanguageService), + ServiceName = "LolFx Service")] + [ProvideLanguageServiceAttribute(typeof(LolFxLanguageService), + "LolFx", 106 /* resource ID */, + CodeSense = true, + RequestStockColors = true, + EnableCommenting = true, + EnableAsyncCompletion = true)] + [ProvideLanguageExtensionAttribute(typeof(LolFxLanguageService), + ".lolfx")] + [ProvideMenuResource(1000, 1)] [Guid("f96f7ac5-16ac-4061-8b92-0a02bb455ae9")] [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] [ComVisible(true)] - [ProvideAutoLoad("f1536ef8-92ec-443c-9ed7-fdadf150da82")] // This is needed for the package to be autoloaded + + /* Autoload package */ + [ProvideAutoLoad("f1536ef8-92ec-443c-9ed7-fdadf150da82")] + public sealed class PluginPackage : Package { public PluginPackage() @@ -32,23 +47,74 @@ namespace Lol.VisualStudio.Plugin Trace.WriteLine(String.Format(CultureInfo.CurrentUICulture, "Entering Initialize() of: {0}", this.ToString())); base.Initialize(); - // Ensure the "Build" output pane exists - IVsOutputWindow outputWindow = GetService(typeof(SVsOutputWindow)) as IVsOutputWindow; - if (null != outputWindow) - { - Guid guidBuild = Microsoft.VisualStudio.VSConstants.OutputWindowPaneGuid.BuildOutputPane_guid; - outputWindow.CreatePane(guidBuild, "Build", 1, 0); - } + Logger.Initialize(GetService(typeof(SVsOutputWindow)) as IVsOutputWindow); - // Register the "Generate Compilers" context menu + /* Register the "Generate Compilers" context menu */ OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService; if (null != mcs) { - CommandID id = new CommandID(GuidsList.guidVsLolCmdSet, VsLolIDList.cmdidGenerateCompilers); + CommandID id = new CommandID(GuidsList.guidVsLolCmdSet, + VsLolIDList.cmdidGenerateCompilers); OleMenuCommand command = new MenuGenerateCompilers(new ServiceProvider((IOleServiceProvider)this.GetService(typeof(IOleServiceProvider))), id); mcs.AddCommand(command); } + + /* Register the LolFx language service */ + IServiceContainer serviceContainer = this as IServiceContainer; + LolFxLanguageService lolfxserv = new LolFxLanguageService(); + lolfxserv.SetSite(this); + serviceContainer.AddService(typeof(LolFxLanguageService), + lolfxserv, true); + } + + } + + internal static class Logger + { + public static void Initialize(IVsOutputWindow window) + { + m_window = window; + + OpenBuildPane(); + + if (m_pane == null) + Trace.WriteLine("Failed to get a reference to the Output window Build pane"); + } + + private static void OpenBuildPane() + { + /* Ensure the "Build" output pane exists */ + if (m_window != null) + { + Guid guidBuild = Microsoft.VisualStudio.VSConstants.OutputWindowPaneGuid.BuildOutputPane_guid; + m_window.CreatePane(guidBuild, "Build", 1, 0); + + if (Microsoft.VisualStudio.ErrorHandler.Failed(m_window.GetPane(ref guidBuild, out m_pane))) + m_pane = null; + } } + + public static void Clear() + { + OpenBuildPane(); + + if (m_pane != null) + { + m_pane.Activate(); + m_pane.Clear(); + } + } + + public static void Info(string s) + { + OpenBuildPane(); + + if (m_pane != null) + m_pane.OutputString(s); + } + + private static IVsOutputWindow m_window = null; + private static IVsOutputWindowPane m_pane = null; } internal static class GuidsList @@ -70,4 +136,3 @@ namespace Lol.VisualStudio.Plugin public const int cmdidUnused2 = 0x2003; } } - diff --git a/tools/vslol/VsLol.csproj b/tools/vslol/VsLol.csproj index e2fec03e..4bf810f6 100644 --- a/tools/vslol/VsLol.csproj +++ b/tools/vslol/VsLol.csproj @@ -55,6 +55,7 @@ + @@ -64,6 +65,7 @@ false + @@ -73,6 +75,7 @@ + @@ -154,4 +157,4 @@ --> - + \ No newline at end of file