PageRenderTime 58ms CodeModel.GetById 32ms RepoModel.GetById 1ms app.codeStats 0ms

/EditorExtensions/Markdown/Classify/CodeLanguageEmbedders.cs

https://github.com/systembugtj/WebEssentials2013
C# | 200 lines | 155 code | 13 blank | 32 comment | 8 complexity | 84221d52cd07eeed84b4dd1a2e8193b6 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel.Composition;
  4. using System.Diagnostics.CodeAnalysis;
  5. using System.Linq;
  6. using Microsoft.Html.Editor;
  7. using Microsoft.Html.Editor.Projection;
  8. using Microsoft.VisualStudio.Shell;
  9. using Microsoft.VisualStudio.Shell.Interop;
  10. using Microsoft.VisualStudio.Text;
  11. using Microsoft.VisualStudio.Utilities;
  12. using Microsoft.Web.Editor;
  13. namespace MadsKristensen.EditorExtensions.Markdown
  14. {
  15. ///<summary>Preprocesses embedded code Markdown blocks before creating projection buffers.</summary>
  16. ///<remarks>
  17. /// Implement this interface to initialize language services for
  18. /// your language, or to add custom wrapping text around blocks.
  19. /// Implementations should be state-less; only one instance will
  20. /// be created.
  21. ///</remarks>
  22. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Embedder")]
  23. public interface ICodeLanguageEmbedder
  24. {
  25. ///<summary>Gets a string to insert at the top of the generated ProjectionBuffr for this language.</summary>
  26. ///<remarks>Each Markdown file will have exactly one copy of this string in its code buffer.</remarks>
  27. string GlobalPrefix { get; }
  28. ///<summary>Gets a string to insert at the bottom of the generated ProjectionBuffr for this language.</summary>
  29. ///<remarks>Each Markdown file will have exactly one copy of this string in its code buffer.</remarks>
  30. string GlobalSuffix { get; }
  31. ///<summary>Gets text to insert around each embedded code block for this language.</summary>
  32. ///<param name="code">The lines of code in the block. Enumerating this may be expensive.</param>
  33. ///<returns>
  34. /// One of the following:
  35. /// - Null or an empty sequence to surround with \r\n.
  36. /// - A single string to put on both ends of the code.
  37. /// - Two strings; one for each end of the code block.
  38. /// The buffer generator will always add newlines.
  39. ///</returns>
  40. ///<remarks>
  41. /// These strings will be wrapped around every embedded
  42. /// code block separately.
  43. ///</remarks>
  44. IReadOnlyCollection<string> GetBlockWrapper(IEnumerable<string> code);
  45. ///<summary>Called when a block of this type is first created within a document.</summary>
  46. void OnBlockCreated(ITextBuffer editorBuffer, LanguageProjectionBuffer projectionBuffer);
  47. }
  48. [Export(typeof(ICodeLanguageEmbedder))]
  49. [ContentType("CSS")]
  50. public class CssEmbedder : ICodeLanguageEmbedder
  51. {
  52. public IReadOnlyCollection<string> GetBlockWrapper(IEnumerable<string> code)
  53. {
  54. // If the code doesn't have any braces, surround it in a ruleset so that properties are valid.
  55. if (code.All(t => t.IndexOfAny(new[] { '{', '}' }) == -1))
  56. return new[] { ".GeneratedClass-" + Guid.NewGuid() + " {", "}" };
  57. return null;
  58. }
  59. public void OnBlockCreated(ITextBuffer editorBuffer, LanguageProjectionBuffer projectionBuffer) { }
  60. public string GlobalPrefix { get { return ""; } }
  61. public string GlobalSuffix { get { return ""; } }
  62. }
  63. [Export(typeof(ICodeLanguageEmbedder))]
  64. [ContentType("Javascript")]
  65. [ContentType("node.js")]
  66. public class JavaScriptEmbedder : ICodeLanguageEmbedder
  67. {
  68. // Statements like return or arguments can only appear inside a function.
  69. // There are no statements that cannot appear in a function.
  70. // TODO: IntelliSense for Node.js vs. HTML.
  71. static readonly IReadOnlyCollection<string> wrapper = new[] { "function() {", "}" };
  72. public IReadOnlyCollection<string> GetBlockWrapper(IEnumerable<string> code) { return wrapper; }
  73. public void OnBlockCreated(ITextBuffer editorBuffer, LanguageProjectionBuffer projectionBuffer) { }
  74. public string GlobalPrefix { get { return ""; } }
  75. public string GlobalSuffix { get { return ""; } }
  76. }
  77. public abstract class IntellisenseProjectEmbedder : ICodeLanguageEmbedder
  78. {
  79. public abstract IReadOnlyCollection<string> GetBlockWrapper(IEnumerable<string> code);
  80. public abstract string ProviderName { get; }
  81. Guid FindGuid()
  82. {
  83. try
  84. {
  85. using (var settings = VSRegistry.RegistryRoot(__VsLocalRegistryType.RegType_Configuration))
  86. using (var languages = settings.OpenSubKey("Languages"))
  87. using (var intellisenseProviders = languages.OpenSubKey("IntellisenseProviders"))
  88. using (var provider = intellisenseProviders.OpenSubKey(ProviderName))
  89. return new Guid(provider.GetValue("GUID").ToString());
  90. }
  91. catch
  92. {
  93. return Guid.Empty;
  94. }
  95. }
  96. public void OnBlockCreated(ITextBuffer editorBuffer, LanguageProjectionBuffer projectionBuffer)
  97. {
  98. EventHandler<EventArgs> h = null;
  99. h = delegate
  100. {
  101. // Make sure we don't set up ContainedLanguages until the buffer is ready
  102. // When loading lots of Markdown files on solution load, we might need to
  103. // wait for multiple idle cycles.
  104. var doc = ServiceManager.GetService<HtmlEditorDocument>(editorBuffer);
  105. if (doc == null) return;
  106. if (doc.PrimaryView == null) return;
  107. WebEditor.OnIdle -= h;
  108. Guid guid = FindGuid();
  109. if (guid != Guid.Empty)
  110. ContainedLanguageAdapter.ForBuffer(editorBuffer).AddIntellisenseProjectLanguage(projectionBuffer, guid);
  111. };
  112. WebEditor.OnIdle += h;
  113. }
  114. public virtual string GlobalPrefix { get { return ""; } }
  115. public virtual string GlobalSuffix { get { return ""; } }
  116. }
  117. [Export(typeof(ICodeLanguageEmbedder))]
  118. [ContentType("CSharp")]
  119. public class CSharpEmbedder : IntellisenseProjectEmbedder
  120. {
  121. public override string ProviderName { get { return "CSharpCodeProvider"; } }
  122. public override string GlobalPrefix
  123. {
  124. get
  125. {
  126. return @"using System;
  127. using System.Collections.Generic;
  128. using System.Data;
  129. using System.IO;
  130. using System.Linq;
  131. using System.Net;
  132. using System.Net.Http;
  133. using System.Net.Http.Formatting;
  134. using System.Reflection;
  135. using System.Text;
  136. using System.Threading;
  137. using System.Threading.Tasks;
  138. using System.Xml;
  139. using System.Xml.Linq;";
  140. }
  141. }
  142. public override IReadOnlyCollection<string> GetBlockWrapper(IEnumerable<string> code)
  143. {
  144. return new[] { @"partial class Entry
  145. {
  146. async Task<object> SampleMethod" + Guid.NewGuid().ToString("n") + @"() {", @"
  147. return await Task.FromResult(new object());
  148. }
  149. }" };
  150. }
  151. }
  152. [Export(typeof(ICodeLanguageEmbedder))]
  153. [ContentType("Basic")]
  154. public class VBEmbedder : IntellisenseProjectEmbedder
  155. {
  156. public override string ProviderName { get { return "VBCodeProvider"; } }
  157. public override string GlobalPrefix
  158. {
  159. get
  160. {
  161. return @"Imports System
  162. Imports System.Collections.Generic
  163. Imports System.Data
  164. Imports System.IO
  165. Imports System.Linq
  166. Imports System.Net
  167. Imports System.Net.Http
  168. Imports System.Net.Http.Formatting
  169. Imports System.Reflection
  170. Imports System.Text
  171. Imports System.Threading
  172. Imports System.Threading.Tasks
  173. Imports System.Xml
  174. Imports System.Xml.Linq";
  175. }
  176. }
  177. public override IReadOnlyCollection<string> GetBlockWrapper(IEnumerable<string> code)
  178. {
  179. return new[] { @"
  180. Partial Class Entry
  181. Async Function SampleMethod" + Guid.NewGuid().ToString("n") + @"() As Task(Of Object)", @"
  182. Return Await Task.FromResult(New Object())
  183. End Function
  184. End Class" };
  185. }
  186. }
  187. }