/// <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));
        }
示例#2
0
        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));
        }
示例#4
0
        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));
        }