/// <summary> /// Gets a classifier for the given text buffer. /// </summary> /// <param name="buffer">The <see cref="ITextBuffer"/> to classify.</param> /// <returns>A classifier for the text buffer, or null if the provider cannot do so in its current state.</returns> public IClassifier GetClassifier(ITextBuffer buffer) { // only return a classifier when this is really our document if (!factory.IsXSharpDocument(buffer)) { return(null); } return(buffer.Properties.GetOrCreateSingletonProperty(creator: () => XSharpClassifier.GetColorizer(buffer, this.classificationRegistry, this.factory))); }
private void registerClassifier() { if (_classifier == null) { _classifier = _buffer.GetClassifier(); if (_classifier != null) { _classifier.ClassificationChanged += Classifier_ClassificationChanged; } } }
public IEnumerable <ITagSpan <IOutliningRegionTag> > GetTags(NormalizedSnapshotSpanCollection spans) { //yield break; if (spans.Count == 0) { yield break; } // Try to retrieve an already parsed list of Tags XSharpClassifier xsClassifier = buffer.GetClassifier(); if (xsClassifier != null) { // ITextSnapshot snapshot = xsClassifier.Snapshot; SnapshotSpan Span = new SnapshotSpan(snapshot, 0, snapshot.Length); var classifications = xsClassifier.GetRegionTags(); SnapshotSpan fullSpan = new SnapshotSpan(spans[0].Start, spans[spans.Count - 1].End).TranslateTo(snapshot, SpanTrackingMode.EdgeExclusive); int startLineNumber = fullSpan.Start.GetContainingLine().LineNumber; int endLineNumber = fullSpan.End.GetContainingLine().LineNumber; // Stack <ClassificationSpan> startStack = new Stack <ClassificationSpan>(); // convert classifications to an array so there will be no crash when the classifications are changed // in another thread. // Now, let's have a look at all the Classifications we have in the document foreach (var tag in classifications) { // Is it a Region ? if (tag.ClassificationType.IsOfType(this.xsharpRegionStartType.Classification)) { startStack.Push(tag); } else if (tag.ClassificationType.IsOfType(this.xsharpRegionStopType.Classification) && (startStack.Count > 0)) { // var startTag = startStack.Pop(); var startLine = startTag.Span.Start.GetContainingLine(); var endLine = tag.Span.End.GetContainingLine(); // if (startTag.Span.Start < tag.Span.End && startLine.LineNumber <= endLineNumber && endLine.LineNumber >= startLineNumber) { SnapshotSpan sSpan; try { sSpan = new SnapshotSpan(startLine.Start, endLine.End); } catch (Exception e) { System.Diagnostics.Debug.WriteLine("Incorrect span " + e.Message); sSpan = new SnapshotSpan(startLine.Start, startLine.Start); } hoverText = sSpan.GetText(); if (hoverText.Length > 1024) { hoverText = hoverText.Substring(0, 1024) + "\r\n......"; } // sSpan = new SnapshotSpan(startLine.Start, startLine.End); ////the region starts at the beginning of the entity, and goes until the *end* of the line that ends. yield return(new TagSpan <IOutliningRegionTag>( new SnapshotSpan(startLine.End, endLine.End), new OutliningRegionTag(false, true, ellipsis, hoverText))); } } } } else { yield break; } }
public IEnumerable <ITagSpan <TextMarkerTag> > GetTags(NormalizedSnapshotSpanCollection spans) { // Todo: the classifier is now marking open and close keywords with (invisible) classification // on another location the classifier is building regions based on Open/Close keywords. // During this process of building regions we can also 'remember' the open/close pairs // so we do not have to look for these in this code. DateTime oStart, oEnd; TimeSpan timeSpan; oStart = DateTime.Now; if (spans.Count == 0 || _currentChar == null) //there is no content in the buffer { yield break; } WriteOutputMessage($"GetTags() Spans: {spans.Count}"); //don't do anything if the current SnapshotPoint is not initialized or at the end of the buffer if (!_currentChar.HasValue || _currentChar.Value.Position >= _currentChar.Value.Snapshot.Length) { yield break; } //hold on to a snapshot of the current character SnapshotPoint currentChar = _currentChar.Value; //if the requested snapshot isn't the same as the one the brace is on, translate our spans to the expected snapshot if (spans[0].Snapshot != currentChar.Snapshot) { currentChar = currentChar.TranslateTo(spans[0].Snapshot, PointTrackingMode.Positive); } //get the current char and the previous char SnapshotSpan pairSpan = new SnapshotSpan(); // check to see if we are on a closing or opening keyword if (!cursorOnKwOpenClose(currentChar)) { yield break; } // Try to Match Keywords // Try to retrieve an already parsed list of Tags XSharpClassifier xsClassifier = _buffer.GetClassifier(); if (xsClassifier == null) { yield break; } else { ITagSpan <TextMarkerTag> result1 = null; ITagSpan <TextMarkerTag> result2 = null; ITagSpan <TextMarkerTag> result3 = null; ITagSpan <TextMarkerTag> result4 = null; try { WriteOutputMessage("Match Open/Close keywords : " + oStart.ToString("hh:mm:ss.fff")); ITextSnapshot snapshot = xsClassifier.Snapshot; if (snapshot.Version != currentChar.Snapshot.Version) { yield break; } SnapshotSpan Span = new SnapshotSpan(snapshot, 0, snapshot.Length); var classifications = xsClassifier.GetTags(); // We cannot use SortedList, because we may have several Classification that start at the same position List <ClassificationSpan> sortedTags = new List <ClassificationSpan>(); foreach (var tag in classifications) { // Only keep the Brace matching Tags if ((tag.ClassificationType.IsOfType(ColorizerConstants.XSharpKwOpenFormat)) || (tag.ClassificationType.IsOfType(ColorizerConstants.XSharpKwCloseFormat))) { sortedTags.Add(tag); } } sortedTags.Sort((a, b) => a.Span.Start.Position.CompareTo(b.Span.Start.Position) * 1000 + string.Compare(a.ClassificationType.Classification, b.ClassificationType.Classification)); // var tags = sortedTags.Where(x => currentChar.Position >= x.Span.Start.Position && currentChar.Position <= x.Span.End.Position); foreach (var currentTag in tags) { var index = sortedTags.IndexOf(currentTag); if (currentTag.ClassificationType.IsOfType(ColorizerConstants.XSharpKwOpenFormat) && result1 == null) { if (FindMatchingCloseTag(sortedTags, index, snapshot, out pairSpan)) { var span = currentTag.Span; result1 = new TagSpan <TextMarkerTag>(span, _tag); result2 = new TagSpan <TextMarkerTag>(pairSpan, _tag); } } else if (result3 == null) { if (FindMatchingOpenTag(sortedTags, index, snapshot, out pairSpan)) { var span = currentTag.Span; result3 = new TagSpan <TextMarkerTag>(pairSpan, _tag); result4 = new TagSpan <TextMarkerTag>(span, _tag); } } } } catch (Exception e) { XSettings.LogException(e, "KeywordMatchingTagger.GetTags failed"); } finally { oEnd = DateTime.Now; timeSpan = oEnd - oStart; WriteOutputMessage("Finished Match Open/Close keywords: " + oEnd.ToString("hh:mm:ss.fff")); WriteOutputMessage("Finished Match Open/Close keywords - total ms: " + timeSpan.TotalMilliseconds.ToString()); } if (result1 != null) { yield return(result1); } if (result2 != null) { yield return(result2); } if (result3 != null) { yield return(result3); } if (result4 != null) { yield return(result4); } } }