using System; using System.Collections.Generic; using System.ComponentModel.Composition; using System.Windows.Media; using System.Text.RegularExpressions; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Classification; using Microsoft.VisualStudio.Language.StandardClassification; using Microsoft.VisualStudio.Utilities; namespace Lol.VisualStudio.Plugin { [Export(typeof(IClassifierProvider))] [ContentType("c/c++")] [ContentType("csharp")] [ContentType("lolfx")] internal class LolClassifierProvider : IClassifierProvider { [Import] internal IClassificationTypeRegistryService m_class_registry = null; /* Set via MEF */ //[Import] //internal IClassificationFormatMapService m_lol = null; public IClassifier GetClassifier(ITextBuffer buffer) { //var test = m_lol.GetClassificationFormatMap("Text Editor"); //string[] foo = { "Comment", "Keyword", "C/C++ User Keywords", "Call Return", "HTML Comment" }; //foreach (var s in foo) //{ // var type = m_class_registry.GetClassificationType(s); // if (type == null) // continue; // var prop = test.GetExplicitTextProperties(type); // if (prop == null) // continue; // var c1 = prop.ForegroundBrush as SolidColorBrush; // var c2 = prop.BackgroundBrush as SolidColorBrush; // Logger.Info("[" + s + "]: " + c1.ToString() + " " + c2.ToString() + "\n"); //} return buffer.Properties.GetOrCreateSingletonProperty<CppKeywordClassifier>(delegate { return new CppKeywordClassifier(m_class_registry, buffer.ContentType); }); } } class CppKeywordClassifier : IClassifier { private IClassificationType m_customclass_type; private Regex m_regex; internal CppKeywordClassifier(IClassificationTypeRegistryService registry, IContentType type) { m_customclass_type = registry.GetClassificationType("LolCustomClass"); string tmp = @"\b("; tmp += "void|bool|int|unsigned|char|short|long|float|double|ldouble|"; tmp += "class|struct|union|template|const|static|extern|volatile|inline|namespace|"; if (type.IsOfType("lolfx")) tmp += "attribute|varying|uniform|in|out|"; if (type.IsOfType("csharp")) tmp += "var|string|internal|sealed|public|private|"; if (!type.IsOfType("csharp")) tmp += "(f(16|128)||d|[ui](8|16||64)|r)(vec[234]|mat[234]|quat|cmplx)|"; if (type.IsOfType("c/c++")) { tmp += "u?int(8|16|32|64|ptr)_t|"; tmp += "real|half|explicit|typename|typedef|"; } tmp += @")\b"; m_regex = new Regex(tmp); } public IList<ClassificationSpan> GetClassificationSpans(SnapshotSpan span) { List<ClassificationSpan> ret = new List<ClassificationSpan>(); string tmp = span.GetText(); var matches = m_regex.Matches(tmp); foreach (Match m in matches) { Span newspan = new Span(span.Start.Position + m.Index, m.Length); SnapshotSpan newsnapshot = new SnapshotSpan(span.Snapshot, newspan); ret.Add(new ClassificationSpan(newsnapshot, m_customclass_type)); } return ret; } public event EventHandler<ClassificationChangedEventArgs> ClassificationChanged; } internal static class LolClassifierClassificationDefinition { [Export(typeof(ClassificationTypeDefinition))] [Name(LolCppTypeFormat.m_name)] internal static ClassificationTypeDefinition LolCustomClassType = null; } [Export(typeof(EditorFormatDefinition))] [ClassificationType(ClassificationTypeNames = LolCppTypeFormat.m_name)] [Name(LolCppTypeFormat.m_name)] [UserVisible(true)] [Order(After = Priority.Default)] /* Override the Visual Studio classifiers */ internal sealed class LolCppTypeFormat : ClassificationFormatDefinition { public const string m_name = "LolCustomClass"; public LolCppTypeFormat() { this.DisplayName = "C/C++ Types and Qualifiers"; //this.BackgroundColor = Colors.BlueViolet; this.ForegroundColor = Colors.Lime; this.IsBold = true; //this.TextDecorations = System.Windows.TextDecorations.Underline; } } }