/// <summary> /// Add a classification span to <paramref name="results"/> that corresponds to the open classification spans in <paramref name="openSpans"/> /// between <paramref name="start"/> and <paramref name="end"/>. /// </summary> private void AddClassificationSpan(List <OpenSpanData> openSpans, ITextSnapshot snapshot, int start, int end, IList <ClassificationSpan> results) { IClassificationType classificationType; if (openSpans.Count == 1) { // If there is only one classification type, then don't create a transient type. classificationType = openSpans[0].ClassificationType; } else { // There is more than one classification type, create a transient type that corresponds // to all the open classificaiton types. List <IClassificationType> classifications = new List <IClassificationType>(openSpans.Count); foreach (OpenSpanData osd in openSpans) { classifications.Add(osd.ClassificationType); } classificationType = _classificationTypeRegistry.CreateTransientClassificationType(classifications); } results.Add(new ClassificationSpan(new SnapshotSpan(snapshot, start, end - start), classificationType)); }
private static void IncreaseServiceFormatPriority(IClassificationFormatMap formatMap, IClassificationTypeRegistryService registry, string formatName, IClassificationType highestPriorityType) { IClassificationType predefinedClassificationType = registry.GetClassificationType(formatName); IClassificationType artificialClassType = registry.CreateTransientClassificationType(predefinedClassificationType); TextFormattingRunProperties properties = formatMap.GetExplicitTextProperties(predefinedClassificationType); formatMap.AddExplicitTextProperties(artificialClassType, properties, highestPriorityType); formatMap.SwapPriorities(artificialClassType, predefinedClassificationType); formatMap.SwapPriorities(highestPriorityType, predefinedClassificationType); }
public IEnumerable <TextClassificationTag> GetTags(TextClassifierContext context) { var list = new List <TextClassificationTag>(); int textLength = context.Text.Length; foreach (var classifier in textClassifiers) { foreach (var tagTmp in classifier.GetTags(context)) { var tag = tagTmp; if (tag.Span.End > textLength) { tag = new TextClassificationTag(Span.FromBounds(Math.Min(textLength, tag.Span.Start), Math.Min(textLength, tag.Span.End)), tag.ClassificationType); } if (tag.Span.Length == 0) { continue; } list.Add(tag); } } if (list.Count <= 1) { return(list); } list.Sort(TextClassificationTagComparer.Instance); // Common case if (!HasOverlaps(list)) { return(Merge(list)); } int min = 0; int minOffset = 0; var newList = new List <TextClassificationTag>(); var ctList = new List <IClassificationType>(); while (min < list.Count) { while (min < list.Count && minOffset >= list[min].Span.End) { min++; } if (min >= list.Count) { break; } var cspan = list[min]; minOffset = Math.Max(minOffset, cspan.Span.Start); int end = cspan.Span.End; ctList.Clear(); ctList.Add(cspan.ClassificationType); for (int i = min + 1; i < list.Count; i++) { cspan = list[i]; int cspanStart = cspan.Span.Start; if (cspanStart > minOffset) { if (cspanStart < end) { end = cspanStart; } break; } int cspanEnd = cspan.Span.End; if (minOffset >= cspanEnd) { continue; } if (cspanEnd < end) { end = cspanEnd; } if (!ctList.Contains(cspan.ClassificationType)) { ctList.Add(cspan.ClassificationType); } } Debug.Assert(minOffset < end); var newSpan = new Span(minOffset, end - minOffset); var ct = ctList.Count == 1 ? ctList[0] : classificationTypeRegistryService.CreateTransientClassificationType(ctList); newList.Add(new TextClassificationTag(newSpan, ct)); minOffset = end; } Debug.Assert(!HasOverlaps(newList)); return(Merge(newList)); }
IList <ClassificationSpan> GetClassificationSpansCore(SnapshotSpan span, CancellationToken?cancellationToken) { if (span.Snapshot is null) { throw new ArgumentException(); } if (span.Length == 0) { return(Array.Empty <ClassificationSpan>()); } var list = new List <ClassificationSpan>(); var targetSnapshot = span.Snapshot; var tags = !(cancellationToken is null) ? tagAggregator.GetTags(span, cancellationToken.Value) : tagAggregator.GetTags(span); foreach (var mspan in tags) { foreach (var s in mspan.Span.GetSpans(textBuffer)) { var overlap = span.Overlap(s.TranslateTo(targetSnapshot, SpanTrackingMode.EdgeExclusive)); if (!(overlap is null)) { list.Add(new ClassificationSpan(overlap.Value, mspan.Tag.ClassificationType)); } } } if (list.Count <= 1) { return(list); } list.Sort(ClassificationSpanComparer.Instance); // Common case if (!HasOverlaps(list)) { return(Merge(list)); } int min = 0; int minOffset = span.Start.Position; var newList = new List <ClassificationSpan>(); var ctList = new List <IClassificationType>(); while (min < list.Count) { while (min < list.Count && minOffset >= list[min].Span.End) { min++; } if (min >= list.Count) { break; } var cspan = list[min]; minOffset = Math.Max(minOffset, cspan.Span.Start.Position); int end = cspan.Span.End.Position; ctList.Clear(); ctList.Add(cspan.ClassificationType); for (int i = min + 1; i < list.Count; i++) { cspan = list[i]; int cspanStart = cspan.Span.Start.Position; if (cspanStart > minOffset) { if (cspanStart < end) { end = cspanStart; } break; } int cspanEnd = cspan.Span.End.Position; if (minOffset >= cspanEnd) { continue; } if (cspanEnd < end) { end = cspanEnd; } if (!ctList.Contains(cspan.ClassificationType)) { ctList.Add(cspan.ClassificationType); } } Debug.Assert(minOffset < end); var newSnapshotSpan = new SnapshotSpan(targetSnapshot, minOffset, end - minOffset); var ct = ctList.Count == 1 ? ctList[0] : classificationTypeRegistryService.CreateTransientClassificationType(ctList); newList.Add(new ClassificationSpan(newSnapshotSpan, ct)); minOffset = end; } Debug.Assert(!HasOverlaps(newList)); return(Merge(newList)); }