using System; using System.Collections.Generic; using System.ComponentModel.Composition; using System.Linq; using System.Windows.Media; using Microsoft.VisualStudio.ApplicationModel.Environments; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Classification; using Microsoft.VisualStudio.Utilities; namespace ClassifyAllBut { public static class TypeAndFormatExports { [Export(typeof(ClassificationTypeDefinition))] [Name("strike-out")] internal static ClassificationTypeDefinition StrikeOutType; [Export(typeof(EditorFormatDefinition))] [ClassificationType(ClassificationTypeNames = "strike-out")] [Name("Strike-out")] [DisplayName("Strike-out Text")] [UserVisible(true)] [Order(Before = Priority.High)] internal sealed class StrikeOutFormat : ClassificationFormatDefinition { public StrikeOutFormat() { this.TextDecorations = System.Windows.TextDecorations.Strikethrough; } } } [Export(typeof(IClassifierProvider))] [ContentType("CSharp")] internal sealed class GrayedOutClassifierProvider : IClassifierProvider { [Import] internal IClassificationTypeRegistryService TypeRegistry; [Import] internal IClassifierAggregatorService AggregatorService; internal static bool ignoreRequest = false; public IClassifier GetClassifier(ITextBuffer textBuffer, IEnvironment context) { if (ignoreRequest) return null; try { ignoreRequest = true; return textBuffer.Properties.GetOrCreateSingletonProperty( () => new GrayedOutClassifier(AggregatorService.GetClassifier(textBuffer, context), TypeRegistry)); } finally { ignoreRequest = false; } } } internal sealed class GrayedOutClassifier : IClassifier { private IClassifier aggregator; private IClassificationTypeRegistryService typeRegistry; public GrayedOutClassifier(IClassifier aggregator, IClassificationTypeRegistryService typeRegistry) { this.aggregator = aggregator; this.typeRegistry = typeRegistry; } public event EventHandler ClassificationChanged; public IList GetClassificationSpans(SnapshotSpan span) { var classifiedSpans = from cspan in aggregator.GetClassificationSpans(span) let name = cspan.ClassificationType.Classification.ToLower() where name.Contains("string") || name.Contains("comment") || name.Contains("xml doc") select cspan.Span; NormalizedSnapshotSpanCollection ignored = new NormalizedSnapshotSpanCollection(classifiedSpans); NormalizedSnapshotSpanCollection request = new NormalizedSnapshotSpanCollection(span); var spansToStrikeOut = NormalizedSnapshotSpanCollection.Difference(request, ignored); IClassificationType type = typeRegistry.GetClassificationType("strike-out"); return spansToStrikeOut.Select(s => new ClassificationSpan(s, type)) .ToList(); } } }