Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

172 lignes
6.2 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel.Composition;
  4. using System.Windows.Media;
  5. using System.Text.RegularExpressions;
  6. using Microsoft.VisualStudio.Text;
  7. using Microsoft.VisualStudio.Text.Classification;
  8. using Microsoft.VisualStudio.Text.Formatting;
  9. using Microsoft.VisualStudio.Language.StandardClassification;
  10. using Microsoft.VisualStudio.Utilities;
  11. namespace Lol.VisualStudio.Plugin
  12. {
  13. [Export(typeof(IClassifierProvider))]
  14. [ContentType("c/c++")]
  15. [ContentType("csharp")]
  16. [ContentType("lolfx")]
  17. internal class LolClassifierProvider : IClassifierProvider
  18. {
  19. [Import]
  20. internal IClassificationTypeRegistryService m_type_registry = null; /* Set via MEF */
  21. [Import]
  22. internal IClassifierAggregatorService m_aggregator = null;
  23. [Import]
  24. internal IClassificationFormatMapService m_format_map = null;
  25. internal static bool m_inprogress = false;
  26. public IClassifier GetClassifier(ITextBuffer buffer)
  27. {
  28. /* Avoid infinite recursion */
  29. if (m_inprogress)
  30. return null;
  31. LolGenericFormat.SetRegistry(m_type_registry, m_format_map);
  32. try
  33. {
  34. m_inprogress = true;
  35. return buffer.Properties.GetOrCreateSingletonProperty<CppKeywordClassifier>(delegate { return new CppKeywordClassifier(m_type_registry, m_aggregator.GetClassifier(buffer), buffer.ContentType); });
  36. }
  37. finally { m_inprogress = false; }
  38. }
  39. }
  40. class CppKeywordClassifier : IClassifier
  41. {
  42. private IClassifier m_classifier;
  43. private IClassificationType m_customclass_type;
  44. private Regex m_customclass_regex;
  45. internal CppKeywordClassifier(IClassificationTypeRegistryService registry,
  46. IClassifier classifier,
  47. IContentType type)
  48. {
  49. m_classifier = classifier;
  50. m_customclass_type = registry.GetClassificationType("LolCustomClass");
  51. string tmp = @"\b(";
  52. tmp += "void|bool|int|unsigned|char|short|long|float|double|ldouble|";
  53. tmp += "class|struct|union|template|const|static|extern|volatile|inline|namespace|";
  54. if (type.IsOfType("lolfx"))
  55. tmp += "attribute|varying|uniform|in|out|";
  56. if (type.IsOfType("csharp"))
  57. tmp += "var|string|internal|sealed|public|private|protected|";
  58. if (!type.IsOfType("csharp"))
  59. tmp += "(f(16|128)||d|[ui](8|16||64)|r)(vec[234]|mat[234]|quat|cmplx)|";
  60. if (type.IsOfType("c/c++"))
  61. {
  62. tmp += "u?int(8|16|32|64|ptr)_t|";
  63. tmp += "real|half|explicit|typename|typedef|";
  64. }
  65. tmp = tmp.Remove(tmp.Length - 1);
  66. tmp += @")\b";
  67. m_customclass_regex = new Regex(tmp);
  68. }
  69. public IList<ClassificationSpan> GetClassificationSpans(SnapshotSpan span)
  70. {
  71. List<ClassificationSpan> ret = new List<ClassificationSpan>();
  72. foreach (ClassificationSpan cs in m_classifier.GetClassificationSpans(span))
  73. {
  74. string cs_class = cs.ClassificationType.Classification.ToLower();
  75. /* Only apply our rules if we found a keyword or an identifier */
  76. if (cs_class == "keyword" || cs_class == "identifier")
  77. {
  78. if (m_customclass_regex.IsMatch(cs.Span.GetText()))
  79. {
  80. ret.Add(new ClassificationSpan(cs.Span, m_customclass_type));
  81. continue;
  82. }
  83. }
  84. ret.Add(cs);
  85. }
  86. return ret;
  87. }
  88. public event EventHandler<ClassificationChangedEventArgs> ClassificationChanged;
  89. }
  90. internal class LolGenericFormat : ClassificationFormatDefinition
  91. {
  92. static IClassificationTypeRegistryService m_type_registry;
  93. static IClassificationFormatMapService m_format_map;
  94. public static void SetRegistry(IClassificationTypeRegistryService type_registry,
  95. IClassificationFormatMapService format_map)
  96. {
  97. m_type_registry = type_registry;
  98. m_format_map = format_map;
  99. }
  100. protected void CopyStyleColor(string category)
  101. {
  102. if (m_type_registry == null || m_format_map == null)
  103. return;
  104. var map = m_format_map.GetClassificationFormatMap("Text Editor");
  105. if (map == null)
  106. return;
  107. //string[] foo = { "Comment", "Keyword", "C/C++ User Keywords", "Call Return", "HTML Comment" , "User Types", "User Types (Type parameters)", "User Types (Value types)"};
  108. var type = m_type_registry.GetClassificationType(category);
  109. if (type == null)
  110. return;
  111. var prop = map.GetExplicitTextProperties(type);
  112. if (prop == null)
  113. return;
  114. var c1 = prop.ForegroundBrush as SolidColorBrush;
  115. if (c1 != null && c1.Color != Colors.Transparent)
  116. this.ForegroundColor = c1.Color;
  117. var c2 = prop.BackgroundBrush as SolidColorBrush;
  118. if (c2 != null && c2.Color != Colors.Transparent)
  119. this.BackgroundColor = c1.Color;
  120. }
  121. }
  122. internal static class LolClassifierClassificationDefinition
  123. {
  124. [Export(typeof(ClassificationTypeDefinition))]
  125. [Name(LolCppTypeFormat.m_name)]
  126. internal static ClassificationTypeDefinition LolCustomClassType = null;
  127. }
  128. [Export(typeof(EditorFormatDefinition))]
  129. [ClassificationType(ClassificationTypeNames = LolCppTypeFormat.m_name)]
  130. [Name(LolCppTypeFormat.m_name)]
  131. [UserVisible(true)]
  132. [Order(After = Priority.Default)] /* Override the Visual Studio classifiers */
  133. internal sealed class LolCppTypeFormat : LolGenericFormat
  134. {
  135. public const string m_name = "LolCustomClass";
  136. public LolCppTypeFormat()
  137. {
  138. this.DisplayName = "C/C++ Types and Qualifiers";
  139. this.ForegroundColor = Colors.Lime;
  140. this.IsBold = true;
  141. //CopyStyleColor("User Types");
  142. }
  143. }
  144. }