private void DrawChanges(DrawingContext drawingContext, NormalizedSnapshotSpanCollection changes, Brush brush) { if (changes.Count > 0) { double yTop = Math.Floor(_scrollBar.GetYCoordinateOfBufferPosition(changes[0].Start)) + markerStartOffset; double yBottom = Math.Ceiling(_scrollBar.GetYCoordinateOfBufferPosition(changes[0].End)) + markerEndOffset; for (int i = 1; i < changes.Count; ++i) { double y = _scrollBar.GetYCoordinateOfBufferPosition(changes[i].Start) + markerStartOffset; if (yBottom < y) { drawingContext.DrawRectangle( brush, null, new Rect(0, yTop, markerWidth, yBottom - yTop)); yTop = y; } yBottom = Math.Ceiling(_scrollBar.GetYCoordinateOfBufferPosition(changes[i].End)) + markerEndOffset; } drawingContext.DrawRectangle( brush, null, new Rect(0, yTop, markerWidth, yBottom - yTop)); } }
public void Add(ISynchronousClassifier classifier, NormalizedSnapshotSpanCollection spans, CancellationToken cancellationToken) { if (classifier == null) throw new ArgumentNullException(nameof(classifier)); if (spans == null) throw new ArgumentNullException(nameof(spans)); foreach (var span in spans) { if (spansCount > 0) htmlWriter.WriteRaw(delimiter); spansCount++; var tagSpans = classifier.GetClassificationSpans(span, cancellationToken); var text = span.GetText(); int pos = span.Start.Position; foreach (var tagSpan in tagSpans) { if (pos < tagSpan.Span.Start) { WriteCss(classificationFormatMap.DefaultTextProperties); htmlWriter.WriteSpan(cssWriter.ToString(), text, pos - span.Start.Position, tagSpan.Span.Start.Position - pos); } WriteCss(classificationFormatMap.GetTextProperties(tagSpan.ClassificationType)); htmlWriter.WriteSpan(cssWriter.ToString(), text, tagSpan.Span.Start - span.Start.Position, tagSpan.Span.Length); pos = tagSpan.Span.End; } if (pos < span.End) { WriteCss(classificationFormatMap.DefaultTextProperties); htmlWriter.WriteSpan(cssWriter.ToString(), text, pos - span.Start.Position, span.End.Position - pos); } } }
public void FormattedStringBuilderEndToEnd1() { var classificationFormatMap = new MockClassificationFormatMap(); var htmlMarkupProvider = new HtmlMarkupProvider( classificationFormatMap, MockClassificationType.Default, Brushes.White); var classifier = new MockClassifier(); var formattedStringBuilder = new FormattedStringBuilder( htmlMarkupProvider, classifier, MockClassificationType.Default, waitIndicator: null); var snapshot = new MockTextSnapshot("bla"); var spans = new NormalizedSnapshotSpanCollection(new [] { new SnapshotSpan(snapshot, 0, 3) }); var actualResult = formattedStringBuilder.AppendSnapshotSpans(spans); var expectedResult = "<pre style=\"font-family:Consolas;font-size:12;color:black;background:white;\">b<span style=\"color:blue;\">l</span>a\r\n</pre>"; Assert.AreEqual(expectedResult, actualResult); }
public void GetOverarchingSpan2() { var spans = new NormalizedSnapshotSpanCollection(); _selection.SetupGet(x => x.SelectedSpans).Returns(spans).Verifiable(); Assert.True(TextSelectionUtil.GetOverarchingSelectedSpan(_selection.Object).IsNone()); _selection.Verify(); }
string GenerateHtmlFragmentCore(NormalizedSnapshotSpanCollection spans, ITextView textView, string delimiter, CancellationToken cancellationToken) { ISynchronousClassifier classifier = null; try { int tabSize; IClassificationFormatMap classificationFormatMap; if (textView != null) { classifier = synchronousViewClassifierAggregatorService.GetSynchronousClassifier(textView); classificationFormatMap = classificationFormatMapService.GetClassificationFormatMap(textView); tabSize = textView.Options.GetTabSize(); } else { classifier = spans.Count == 0 ? null : synchronousClassifierAggregatorService.GetSynchronousClassifier(spans[0].Snapshot.TextBuffer); classificationFormatMap = classificationFormatMapService.GetClassificationFormatMap(AppearanceCategoryConstants.TextEditor); tabSize = defaultTabSize; } tabSize = OptionsHelpers.FilterTabSize(tabSize); var builder = new HtmlBuilder(classificationFormatMap, delimiter, tabSize); if (spans.Count != 0) builder.Add(classifier, spans, cancellationToken); return builder.Create(); } finally { (classifier as IDisposable)?.Dispose(); } }
public NormalizedSnapshotSpanCollection UncommentSpans(NormalizedSnapshotSpanCollection spans) { Contract.Requires<ArgumentNullException>(spans != null, "spans"); Contract.Ensures(Contract.Result<NormalizedSnapshotSpanCollection>() != null); throw new NotImplementedException(); }
public void CalculateForBlock3() { var buffer = EditorUtil.CreateBuffer("dog", "cat", "chicken"); var col = new NormalizedSnapshotSpanCollection(buffer.GetSpan(0, 2)); var span = _calcRaw.CalculateForBlock(buffer.GetLine(1).Start.Add(1), col); Assert.IsTrue(span.IsMultiple); Assert.AreEqual(buffer.GetLine(1).Start.Add(1).GetSpan(2), span.AsMultiple().Item2[0]); }
private static IEnumerable<ITagSpan<OutliningRegionTag>> GetTags(string input) { var buffer = new FakeTextBuffer(input); var tagger = new TemplateOutliningTagger(buffer); var snapshotSpans = new NormalizedSnapshotSpanCollection(new SnapshotSpan(buffer.CurrentSnapshot, 0, buffer.CurrentSnapshot.Length)); return tagger.GetTags(snapshotSpans); }
public string GenerateHtmlFragment(NormalizedSnapshotSpanCollection spans, string delimiter, CancellationToken cancellationToken) { if (spans == null) throw new ArgumentNullException(nameof(spans)); if (delimiter == null) throw new ArgumentNullException(nameof(delimiter)); return GenerateHtmlFragmentCore(spans, null, delimiter, cancellationToken); }
public void GetOverarchingSpan3() { var buffer = CreateTextBuffer("foo bar"); var span = buffer.GetLineRange(0).Extent; var col = new NormalizedSnapshotSpanCollection(span); _selection.SetupGet(x => x.SelectedSpans).Returns(col).Verifiable(); Assert.Equal(span, TextSelectionUtil.GetOverarchingSelectedSpan(_selection.Object).Value); _selection.Verify(); }
public void GetOverarchingSpan4() { var buffer = CreateTextBuffer("foo", "baz", "bar"); var span1 = buffer.GetLineRange(0).Extent; var span2 = buffer.GetLineRange(0, 1).Extent; var col = new NormalizedSnapshotSpanCollection(new SnapshotSpan[] { span1, span2 }); _selection.SetupGet(x => x.SelectedSpans).Returns(col).Verifiable(); Assert.AreEqual(buffer.GetLineRange(0, 1).Extent, TextSelectionUtil.GetOverarchingSelectedSpan(_selection.Object).Value); _selection.Verify(); }
public static void GetTagsReturnsErrorSpanForSemanticError() { var buffer = new FakeTextBuffer("<#@ include file=\" \" #>"); var tagger = new TemplateErrorTagger(buffer); var snapshotSpans = new NormalizedSnapshotSpanCollection(new SnapshotSpan(buffer.CurrentSnapshot, 0, buffer.CurrentSnapshot.Length)); ITagSpan<ErrorTag> errorSpan = tagger.GetTags(snapshotSpans).Single(); Assert.Equal(new Span(12, 8), errorSpan.Span); Assert.Contains("File", (string)errorSpan.Tag.ToolTipContent, StringComparison.OrdinalIgnoreCase); }
public void ShouldClassifyScenario() { TestInitialise("Features/gherkin.feature"); var snapShotSpan = new SnapshotSpan(new MockTextSnapshot(featureFileContent), new Span(0, 15)); var spanCollection = new NormalizedSnapshotSpanCollection(new[] { snapShotSpan }); var tags = playTagger.GetTags(spanCollection); var tag = tags.First(_ => _.Span.GetText().StartsWith(" Scenario: SC2")).Tag; Assert.AreEqual("Scenario: SC2" + Environment.NewLine + " Given something" + Environment.NewLine + " When some event occurs" + Environment.NewLine + " Then there is some outcome", tag.GetText()); }
private static bool IsComment(SnapshotPoint position) { if (position.Position < 2) return false; var tagger = position.Snapshot.TextBuffer.Properties.GetProperty<ITagger<ClassificationTag>>(jsTaggerType); Span span = Span.FromBounds(position.Position - 1, position.Position); var spans = new NormalizedSnapshotSpanCollection(new SnapshotSpan(position.Snapshot, span)); var classifications = tagger.GetTags(spans); return classifications.Any(c => c.Tag.ClassificationType.IsOfType("comment")); }
public static IElisionBuffer CreateElisionBufferWithoutIndentation( this IProjectionBufferFactoryService factoryService, IEditorOptions editorOptions, IContentType contentType, IEnumerable<SnapshotSpan> exposedSpans) { var spans = new NormalizedSnapshotSpanCollection(exposedSpans); if (spans.Count > 0) { // BUG(6335): We have to make sure that the spans refer to the current snapshot of // the buffer. var buffer = spans.First().Snapshot.TextBuffer; var currentSnapshot = buffer.CurrentSnapshot; spans = new NormalizedSnapshotSpanCollection( spans.Select(s => s.TranslateTo(currentSnapshot, SpanTrackingMode.EdgeExclusive))); } contentType = contentType ?? factoryService.ProjectionContentType; var elisionBuffer = factoryService.CreateElisionBuffer( null, spans, ElisionBufferOptions.None, contentType); if (spans.Count > 0) { var snapshot = spans.First().Snapshot; var buffer = snapshot.TextBuffer; // We need to figure out the shorted indentation level of the exposed lines. We'll // then remove that indentation from all lines. var indentationColumn = DetermineIndentationColumn(editorOptions, spans); var spansToElide = new List<Span>(); foreach (var span in spans) { var startLineNumber = snapshot.GetLineNumberFromPosition(span.Start); var endLineNumber = snapshot.GetLineNumberFromPosition(span.End); for (var lineNumber = startLineNumber; lineNumber <= endLineNumber; lineNumber++) { var line = snapshot.GetLineFromLineNumber(lineNumber); var lineOffsetOfColumn = line.GetLineOffsetFromColumn(indentationColumn, editorOptions); spansToElide.Add(Span.FromBounds(line.Start, line.Start + lineOffsetOfColumn)); } } elisionBuffer.ElideSpans(new NormalizedSpanCollection(spansToElide)); } return elisionBuffer; }
public void CalculateForBlock4() { var buffer = EditorUtil.CreateBuffer("dog again", "cat again", "chicken"); var col = new NormalizedSnapshotSpanCollection(new SnapshotSpan[] { buffer.GetLine(0).Start.GetSpan(2), buffer.GetLine(1).Start.GetSpan(2) }); var span = _calcRaw.CalculateForBlock(buffer.GetLine(1).Start, col); Assert.IsTrue(span.IsMultiple); col = span.AsMultiple().item2; Assert.AreEqual(buffer.GetLine(1).Start.GetSpan(2), col[0]); Assert.AreEqual(buffer.GetLine(2).Start.GetSpan(2), col[1]); }
private IEnumerable<SnapshotSpan> Split(SnapshotSpan span, IEnumerable<SnapshotSpan> remove) { var removeNorm = new NormalizedSnapshotSpanCollection(remove); foreach (var r in removeNorm.OrderBy(x => x.Start.Position)) { if (r.Start < span.End) { if (r.Start > span.Start) { yield return new SnapshotSpan(span.Start, r.Start); } if (r.End < span.End) { span = new SnapshotSpan(r.End, span.End); } else { yield break; } } } yield return span; }
public void CreateRegionsAround_SelectionAtEndOfDocument() { var textBuffer = GetCSharpTextBuffer("Outlining1.txt"); var snapshot = textBuffer.CurrentSnapshot; var outlining = SelectionOutliningManager.Get(textBuffer); int lineCount = snapshot.LineCount; var selectionSpan = GetSpanFromLines(snapshot, lineCount-10, lineCount-1); outlining.CreateRegionsAround(selectionSpan); // validate GetTags() gives us two spans var allDocument = new NormalizedSnapshotSpanCollection(snapshot.GetSpan()); var tags = outlining.GetTags(allDocument).ToList(); var span1 = GetSpanFromLines(snapshot, 0, (lineCount - 10)-1); Assert.Equal(span1, tags.First()); }
public void ShouldClassifyScenarioWithExamples() { TestInitialise("Features/gherkin.feature"); var snapShotSpan = new SnapshotSpan(new MockTextSnapshot(featureFileContent), new Span(0, 15)); var spanCollection = new NormalizedSnapshotSpanCollection(new[] { snapShotSpan }); var tags = playTagger.GetTags(spanCollection); var tag = tags.First(span => span.Span.GetText().StartsWith(" Scenario: SC1")).Tag; Assert.AreEqual("Scenario: SC1" + Environment.NewLine + " Given numbers [left] and [right]" + Environment.NewLine + " When I add the numbers" + Environment.NewLine + " Then the sum is [sum]" + Environment.NewLine + "Examples:" + Environment.NewLine + " | left | right | sum |" + Environment.NewLine + " | 1 | 2 | 3 |" + Environment.NewLine + " | 3 | 4 | 7 |", tag.GetText()); }
public IEnumerable<BracePos> BracesInSpans(NormalizedSnapshotSpanCollection spans) { if ( ScanIsUnnecessary() ) yield break; for ( int i = 0; i < spans.Count; i++ ) { var wantedSpan = spans[i]; EnsureLinesInPreferredSpan(wantedSpan); int startIndex = FindIndexOfBraceAtOrAfter(wantedSpan.Start); if ( startIndex < 0 ) { continue; } for ( int j = startIndex; j < braces.Count; j++ ) { BracePos bp = braces[j]; if ( bp.Position > wantedSpan.End ) break; yield return bp; } } }
public void Render(DrawingContext drawingContext) { if (!HighlightWordTaggerProvider.Taggers.ContainsKey(_textView)) { return; } NormalizedSnapshotSpanCollection spans = new NormalizedSnapshotSpanCollection(new SnapshotSpan(_textView.TextSnapshot, 0, _textView.TextSnapshot.Length)); IEnumerable<ITagSpan<HighlightWordTag>> tags = HighlightWordTaggerProvider.Taggers[_textView].GetTags(spans); List<SnapshotSpan> highlightList = new List<SnapshotSpan>(); foreach (ITagSpan<HighlightWordTag> highlight in tags) { highlightList.Add(highlight.Span); } NormalizedSnapshotSpanCollection highlights = new NormalizedSnapshotSpanCollection(highlightList); if (highlights.Count > 0) { double yTop = Math.Floor(_scrollBar.GetYCoordinateOfBufferPosition(highlights[0].Start)) + markerStartOffset; double yBottom = Math.Ceiling(_scrollBar.GetYCoordinateOfBufferPosition(highlights[0].End)) + markerEndOffset; for (int i = 1; i < highlights.Count; ++i) { double y = _scrollBar.GetYCoordinateOfBufferPosition(highlights[i].Start) + markerStartOffset; if (yBottom < y) { drawingContext.DrawRectangle( Colors.HighlightsBrush, null, new Rect(_scrollBar.Width - markerWidth, yTop, markerWidth, yBottom - yTop)); yTop = y; } yBottom = Math.Ceiling(_scrollBar.GetYCoordinateOfBufferPosition(highlights[i].End)) + markerEndOffset; } drawingContext.DrawRectangle( Colors.HighlightsBrush, null, new Rect(_scrollBar.Width - markerWidth, yTop, markerWidth, yBottom - yTop)); } }
public Classifier(CoffeeOverview overview, IClassificationTypeRegistryService classificationRegistry) { this.overview = overview; this.clsCoffeeString = classificationRegistry.GetClassificationType(VisualFormatNames.CoffeeString); this.clsCoffeeIdentifier = classificationRegistry.GetClassificationType(VisualFormatNames.CoffeeIdentifier); this.clsCoffeeKeyword = classificationRegistry.GetClassificationType(VisualFormatNames.CoffeeKeyword); this.clsCoffeeNumericLiteral = classificationRegistry.GetClassificationType(VisualFormatNames.CoffeeNumericLiteral); this.clsCoffeeComment = classificationRegistry.GetClassificationType(VisualFormatNames.CoffeeComment); overview.MultiLinesChanged += (o, e) => { if (this.latestSnapshot != null && this.ClassificationChanged != null) { var spans = new NormalizedSnapshotSpanCollection( e.Added.Concat(e.Removed) .Select(x => x.Span.GetSpan(this.latestSnapshot))); foreach (var span in spans) { var args = new ClassificationChangedEventArgs(span); this.ClassificationChanged(this, args); } } }; }
public void CreateRegionsAround_PartialLines() { var textBuffer = GetCSharpTextBuffer("Outlining1.txt"); var snapshot = textBuffer.CurrentSnapshot; var outlining = SelectionOutliningManager.Get(textBuffer); var selectionSpan = GetSpanFromLines(snapshot, 9, 15); selectionSpan = new SnapshotSpan(selectionSpan.Start + 10, selectionSpan.End - 2); outlining.CreateRegionsAround(selectionSpan); // validate GetTags() gives us two spans var allDocument = new NormalizedSnapshotSpanCollection(snapshot.GetSpan()); var tags = outlining.GetTags(allDocument).ToList(); var span1 = GetSpanFromLines(snapshot, 0, 8); Assert.Equal(span1, tags.First()); var span2 = GetSpanFromLines(snapshot, 16, snapshot.LineCount-1); Assert.Equal(span2, tags.Last()); }
public void ShouldClassifyScenarioWithInlineTable() { TestInitialise("Features/gherkin.feature"); var snapShotSpan = new SnapshotSpan(new MockTextSnapshot(featureFileContent), new Span(0, 15)); var spanCollection = new NormalizedSnapshotSpanCollection(new[] { snapShotSpan }); var tags = playTagger.GetTags(spanCollection); var tag = tags.First(span => span.Span.GetText().StartsWith(" Scenario: inline table")).Tag; Assert.AreEqual("Scenario: inline table" + Environment.NewLine + " Given the following people exists:" + Environment.NewLine + " | Name | Country |" + Environment.NewLine + " | Morgan Persson | Sweden |" + Environment.NewLine + " | Jimmy Nilsson | Sweden |" + Environment.NewLine + " | Jimmy bogard | USA |" + Environment.NewLine + " When I search for people in sweden" + Environment.NewLine + " Then I should get:" + Environment.NewLine + " | Name |" + Environment.NewLine + " | Morgan Persson |" + Environment.NewLine + " | Jimmy Nilsson |", tag.GetText()); }
internal static NormalizedSnapshotSpanCollection[] GetUnifiedChanges(ITextSnapshot snapshot, IEnumerable<IMappingTagSpan<ChangeTag>> tags) { List<SnapshotSpan>[] unnormalizedChanges = new List<SnapshotSpan>[4] { null, new List<SnapshotSpan>(), new List<SnapshotSpan>(), new List<SnapshotSpan>() }; foreach (IMappingTagSpan<ChangeTag> change in tags) { unnormalizedChanges[(int)change.Tag.ChangeTypes].AddRange(change.Span.GetSpans(snapshot)); } NormalizedSnapshotSpanCollection[] changes = new NormalizedSnapshotSpanCollection[4]; for (int i = 1; (i <= 3); ++i) { changes[i] = new NormalizedSnapshotSpanCollection(unnormalizedChanges[i]); } return changes; }
public string GenerateHtml(NormalizedSnapshotSpanCollection spans, IWpfTextView textView) { if (spans == null || spans.Count == 0) { return ""; } // this will trigger loading of the package // so we can ensure ToolsOptionsPage gets created and // ToolsOptionsPage.Instance gets set var dte = (_DTE)_serviceProvider.GetService(typeof(_DTE)); var props = dte.Properties[CopyAsHtmlPackage.CategoryName, CopyAsHtmlPackage.PageName]; IClassificationFormatMap formatMap = _classificationFormatMappingService.GetClassificationFormatMap(textView); IClassificationType defaultClassificationType = _classificationTypeRegistry.GetClassificationType("text"); HtmlMarkupProvider htmlMarkupProvider = new HtmlMarkupProvider( formatMap, defaultClassificationType, textView.Background); IClassifier classifier = _classifierAggregatorService.GetClassifier(textView.TextBuffer); var formattedStringBuilder = new FormattedStringBuilder( htmlMarkupProvider, classifier, defaultClassificationType, this.WaitIndicator); string result = formattedStringBuilder.AppendSnapshotSpans(spans); var classifierDispose = classifier as System.IDisposable; if (classifierDispose != null) { classifierDispose.Dispose(); } return result; }
public IEnumerable <ITagSpan <TTagType> > GetTags(NormalizedSnapshotSpanCollection spans) => wrappedTagger.GetTags(spans);
public IEnumerable <ITagSpan <RenameTrackingTag> > GetTags(NormalizedSnapshotSpanCollection spans) { return(GetTags(spans, RenameTrackingTag.Instance)); }
public bool Find() { if (string.IsNullOrEmpty(this.SearchTerm)) { throw new InvalidOperationException("You must set a non-empty search term before searching."); } bool forward = (this.SearchOptions & FindOptions.SearchReverse) != FindOptions.SearchReverse; bool wrap = (this.SearchOptions & FindOptions.Wrap) == FindOptions.Wrap; bool regEx = (this.SearchOptions & FindOptions.UseRegularExpressions) == FindOptions.UseRegularExpressions; ITextSnapshot searchSnapshot = _buffer.CurrentSnapshot; //There could be a version skew here if someone calls find from inside a text changed callback on the buffer. That probably wouldn't be a good //idea but we need to handle it gracefully. this.AdvanceToSnapshot(searchSnapshot); SnapshotPoint?searchStart = this.CalculateStartPoint(searchSnapshot, wrap, forward); if (searchStart.HasValue) { int index = 0; NormalizedSnapshotSpanCollection searchSpans = this.SearchSpans; if (searchSpans != null) { Debug.Assert(searchSpans.Count > 0); //Index is potentially outside the range of [0...searchSpans.Count-1] but we handle that below. if (!(TextSearchNavigator.TryGetIndexOfContainingSpan(searchSpans, searchStart.Value, out index) || forward)) { //For reversed searches, we want the index of the span before the point if we can't get a span that contains the point. --index; } } else { searchSpans = new NormalizedSnapshotSpanCollection(new SnapshotSpan(searchSnapshot, Span.FromBounds(0, searchSnapshot.Length))); } int searchIterations = searchSpans.Count; for (int i = 0; (i < searchIterations); ++i) { //index needs to be normalized to [0 ... searchSpans.Count - 1] but could be negative. index = (index + searchSpans.Count) % searchSpans.Count; SnapshotSpan searchSpan = searchSpans[index]; if ((i != 0) || (searchStart.Value < searchSpan.Start) || (searchStart.Value > searchSpan.End)) { searchStart = forward ? searchSpan.Start : searchSpan.End; } else if (wrap && (i == 0)) { //We will need to repeat the search to account for wrap being on and we are not searching everything in searchSpans[0]. //This is the same as simply doing a search for i == searchSpans.Count we we can make happen by bumping the number of iterations. ++searchIterations; } foreach (var result in _textSearchService.FindAll(searchSpan, searchStart.Value, this.SearchTerm, this.SearchOptions & ~FindOptions.Wrap)) { // As a safety measure, we don't include results of length zero in the navigator unless regular expressions are being used. // Zero width matches could be useful in RegEx when for example somebody is trying to replace the start of the line using the "^" // pattern. if (result.Length == 0 && !regEx) { continue; } else { // We accept the first match this.CurrentResult = result; return(true); } } if (forward) { ++index; } else { --index; } } } // If nothing was found, then clear the current result this.ClearCurrentResult(); return(false); }
IEnumerable <ITagSpan <ClippyTag> > ITagger <ClippyTag> .GetTags(NormalizedSnapshotSpanCollection spans) { try { if (spans == null || spans.FirstOrDefault() == null) { return(null); } if (spans.FirstOrDefault().Snapshot.ContentType.TypeName != "SQL Server Tools") { return(null); } var items = new List <ITagSpan <ClippyTag> >(); if (_lastCallTime.AddMilliseconds(_lastCallDelay) >= DateTime.Now) { return(_lastSpans); } _lastCallTime = DateTime.Now; if (!Monitor.TryEnter(_lock)) { return(_lastSpans); } var dte = VsServiceProvider.Get(typeof(DTE)); if (null == dte || !ClippySettings.Enabled) { Monitor.Exit(_lock); return(_lastSpans); } //if (_store == null) //{ // _store = new TagStore(); // Monitor.Exit(_lock); // return _lastSpans; //} if (_store.Stopped) { _store.Stopped = false; Monitor.Exit(_lock); return(_lastSpans); } var text = spans.FirstOrDefault().Snapshot.GetText(); var glyphs = new OperationsBuilder(spans.FirstOrDefault().Snapshot, _store).GetStatementOptions(text); foreach (var g in glyphs) { if (g.Menu.Count == 0) { continue; } var tag = new ClippyTag(g); var tagSpan = new TagSpan <ClippyTag>(new SnapshotSpan(spans.FirstOrDefault().Snapshot, g.StatementOffset, g.StatementLength), tag); tag.Tagger = this; tagSpan.Tag.ParentTag = tagSpan; g.Tag = tagSpan.Tag; items.Add(tagSpan); } Monitor.Exit(_lock); _lastSpans = items; return(items); } catch (Exception) { Monitor.Exit(_lock); return(null); } }
/// <summary> /// Get misspelled words in the given set of spans /// </summary> /// <param name="spans">The spans to check</param> /// <returns>An enumerable list of misspelling tags</returns> private IEnumerable <MisspellingTag> GetMisspellingsInSpans(NormalizedSnapshotSpanCollection spans) { List <Match> xmlTags = null; SnapshotSpan errorSpan, deleteWordSpan; Microsoft.VisualStudio.Text.Span lastWord; string text, textToParse; var ignoredWords = wordsIgnoredOnce; foreach (var span in spans) { text = span.GetText(); // Note the location of all XML elements if needed if (configuration.IgnoreXmlElementsInText) { xmlTags = reXml.Matches(text).OfType <Match>().ToList(); } lastWord = new Microsoft.VisualStudio.Text.Span(); foreach (var word in GetWordsInText(text)) { textToParse = text.Substring(word.Start, word.Length); // Spell check the word if it looks like one and is not ignored if (IsProbablyARealWord(textToParse) && (xmlTags == null || xmlTags.Count == 0 || !xmlTags.Any(match => word.Start >= match.Index && word.Start <= match.Index + match.Length - 1))) { // Check for a doubled word. This isn't perfect as it won't detected doubled words // across a line break. if (lastWord.Length != 0 && text.Substring(lastWord.Start, lastWord.Length).Equals( textToParse, StringComparison.OrdinalIgnoreCase) && String.IsNullOrWhiteSpace( text.Substring(lastWord.Start + lastWord.Length, word.Start - lastWord.Start - lastWord.Length))) { errorSpan = new SnapshotSpan(span.Start + word.Start, word.Length); // If the doubled word is not being ignored at the current location, return it if (!ignoredWords.Any(w => w.StartPoint == errorSpan.Start && w.Word.Equals(textToParse, StringComparison.OrdinalIgnoreCase))) { // Delete the whitespace ahead of it too deleteWordSpan = new SnapshotSpan(span.Start + lastWord.Start + lastWord.Length, word.Length + word.Start - lastWord.Start - lastWord.Length); yield return(new MisspellingTag(errorSpan, deleteWordSpan)); lastWord = word; continue; } } lastWord = word; if (!_dictionary.ShouldIgnoreWord(textToParse) && !_dictionary.IsSpelledCorrectly(textToParse)) { // Sometimes it flags a word as misspelled if it ends with "'s". Try checking the // word without the "'s". If ignored or correct without it, don't flag it. This // appears to be caused by the definitions in the dictionary rather than Hunspell. if (textToParse.EndsWith("'s", StringComparison.OrdinalIgnoreCase)) { textToParse = textToParse.Substring(0, textToParse.Length - 2); if (_dictionary.ShouldIgnoreWord(textToParse) || _dictionary.IsSpelledCorrectly(textToParse)) { continue; } textToParse += "'s"; } // Some dictionaries include a trailing period on certain words such as "etc." which // we don't include. If the word is followed by a period, try it with the period to // see if we get a match. If so, consider it valid. if (word.Start + word.Length < text.Length && text[word.Start + word.Length] == '.') { if (_dictionary.ShouldIgnoreWord(textToParse + ".") || _dictionary.IsSpelledCorrectly(textToParse + ".")) { continue; } } errorSpan = new SnapshotSpan(span.Start + word.Start, word.Length); // If the word is not being ignored at the current location, return it and its // suggested corrections. if (!ignoredWords.Any(w => w.StartPoint == errorSpan.Start && w.Word.Equals(textToParse, StringComparison.OrdinalIgnoreCase))) { yield return(new MisspellingTag(errorSpan, _dictionary.SuggestCorrections(textToParse))); } } } } } }
public static IEnumerable <ITagSpan <IOutliningRegionTag> > GetTags(this IGherkinFileScope gherkinFileScope, NormalizedSnapshotSpanCollection spans) { if (gherkinFileScope == null) { return(new ITagSpan <IOutliningRegionTag> [0]); } var result = new List <ITagSpan <IOutliningRegionTag> >(); foreach (var gherkinFileBlock in gherkinFileScope.GetAllBlocks()) { result.AddRange(gherkinFileBlock.OutliningRegions); //TODO: optimize } return(result); }
/// <summary> /// Get misspelled words in the given set of spans /// </summary> /// <param name="spans">The spans to check</param> /// <returns>An enumerable list of misspelling tags</returns> private IEnumerable <MisspellingTag> GetMisspellingsInSpans(NormalizedSnapshotSpanCollection spans) { List <Match> rangeExclusions = new List <Match>(); SnapshotSpan errorSpan, deleteWordSpan; Microsoft.VisualStudio.Text.Span lastWord; string textToSplit, actualWord, textToCheck; int mnemonicPos; // ************************************************************************************************** // NOTE: If anything changes here, update the related solution/project spell checking code in // ToolWindows\SolutionProjectSpellCheckControl.xaml.cs\GetMisspellingsInSpans(). // ************************************************************************************************** foreach (var span in spans) { textToSplit = span.GetText(); rangeExclusions.Clear(); // Note the location of all XML elements if needed if (configuration.IgnoreXmlElementsInText) { rangeExclusions.AddRange(WordSplitter.XmlElement.Matches(textToSplit).Cast <Match>()); } // Add exclusions from the configuration if any foreach (var exclude in configuration.ExclusionExpressions) { try { rangeExclusions.AddRange(exclude.Matches(textToSplit).Cast <Match>()); } catch (RegexMatchTimeoutException ex) { // Ignore expression timeouts Debug.WriteLine(ex); } } // Get any ignored words specified inline within the span foreach (Match m in InlineIgnoredWord.reIgnoreSpelling.Matches(textToSplit)) { string ignored = m.Groups["IgnoredWords"].Value; bool caseSensitive = !String.IsNullOrWhiteSpace(m.Groups["CaseSensitive"].Value); int start = m.Groups["IgnoredWords"].Index; foreach (var ignoreSpan in wordSplitter.GetWordsInText(ignored)) { var ss = new SnapshotSpan(span.Snapshot, span.Start + start + ignoreSpan.Start, ignoreSpan.Length); var match = inlineIgnoredWords.FirstOrDefault(i => i.Span.GetSpan(span.Snapshot).OverlapsWith(ss)); if (match != null) { // If the span is already there, ignore it if (match.Word == ss.GetText() && match.CaseSensitive == caseSensitive) { continue; } // If different, replace it inlineIgnoredWords.Remove(match); } var ts = span.Snapshot.CreateTrackingSpan(ss, SpanTrackingMode.EdgeExclusive); inlineIgnoredWords.Add(new InlineIgnoredWord { Word = ignored.Substring(ignoreSpan.Start, ignoreSpan.Length), CaseSensitive = caseSensitive, Span = ts, IsNew = true }); } } lastWord = new Microsoft.VisualStudio.Text.Span(); foreach (var word in wordSplitter.GetWordsInText(textToSplit)) { if (isClosed) { yield break; } actualWord = textToSplit.Substring(word.Start, word.Length); if (inlineIgnoredWords.Any(w => w.IsMatch(actualWord))) { continue; } mnemonicPos = actualWord.IndexOf(wordSplitter.Mnemonic); if (mnemonicPos == -1) { textToCheck = actualWord; } else { textToCheck = actualWord.Substring(0, mnemonicPos) + actualWord.Substring(mnemonicPos + 1); } if (unescapeApostrophes && textToCheck.IndexOf("''", StringComparison.Ordinal) != -1) { textToCheck = textToCheck.Replace("''", "'"); } // Spell check the word if it looks like one and is not ignored if (wordSplitter.IsProbablyARealWord(textToCheck) && (rangeExclusions.Count == 0 || !rangeExclusions.Any(match => word.Start >= match.Index && word.Start <= match.Index + match.Length - 1))) { errorSpan = new SnapshotSpan(span.Start + word.Start, word.Length); // Check for a doubled word. This isn't perfect as it won't detected doubled words // across a line break. if (configuration.DetectDoubledWords && lastWord.Length != 0 && textToSplit.Substring(lastWord.Start, lastWord.Length).Equals(actualWord, StringComparison.OrdinalIgnoreCase) && String.IsNullOrWhiteSpace(textToSplit.Substring( lastWord.Start + lastWord.Length, word.Start - lastWord.Start - lastWord.Length))) { // If the doubled word is not being ignored at the current location, return it if (!wordsIgnoredOnce.Any(w => w.StartPoint == errorSpan.Start && w.Word.Equals(actualWord, StringComparison.OrdinalIgnoreCase))) { // Delete the whitespace ahead of it too deleteWordSpan = new SnapshotSpan(span.Start + lastWord.Start + lastWord.Length, word.Length + word.Start - lastWord.Start - lastWord.Length); yield return(new MisspellingTag(errorSpan, deleteWordSpan)); lastWord = word; continue; } } lastWord = word; // If the word is not being ignored, perform the other checks if (!this.Dictionary.ShouldIgnoreWord(textToCheck) && !wordsIgnoredOnce.Any( w => w.StartPoint == errorSpan.Start && w.Word.Equals(actualWord, StringComparison.OrdinalIgnoreCase))) { // Handle code analysis dictionary checks first as they may be not be recognized as // correctly spelled words but have alternate handling. if (configuration.CadOptions.TreatDeprecatedTermsAsMisspelled && configuration.DeprecatedTerms.TryGetValue(textToCheck, out string preferredTerm)) { yield return(new MisspellingTag(MisspellingType.DeprecatedTerm, errorSpan, new[] { new SpellingSuggestion(null, preferredTerm) })); continue; } if (configuration.CadOptions.TreatCompoundTermsAsMisspelled && configuration.CompoundTerms.TryGetValue(textToCheck, out preferredTerm)) { yield return(new MisspellingTag(MisspellingType.CompoundTerm, errorSpan, new[] { new SpellingSuggestion(null, preferredTerm) })); continue; } if (configuration.CadOptions.TreatUnrecognizedWordsAsMisspelled && configuration.UnrecognizedWords.TryGetValue(textToCheck, out IList <string> spellingAlternates)) { yield return(new MisspellingTag(MisspellingType.UnrecognizedWord, errorSpan, spellingAlternates.Select(a => new SpellingSuggestion(null, a)))); continue; } if (!this.Dictionary.IsSpelledCorrectly(textToCheck)) { // Sometimes it flags a word as misspelled if it ends with "'s". Try checking the // word without the "'s". If ignored or correct without it, don't flag it. This // appears to be caused by the definitions in the dictionary rather than Hunspell. if (textToCheck.EndsWith("'s", StringComparison.OrdinalIgnoreCase) || textToCheck.EndsWith("\u2019s", StringComparison.OrdinalIgnoreCase)) { string aposEss = textToCheck.Substring(textToCheck.Length - 2); textToCheck = textToCheck.Substring(0, textToCheck.Length - 2); if (this.Dictionary.ShouldIgnoreWord(textToCheck) || this.Dictionary.IsSpelledCorrectly(textToCheck)) { continue; } textToCheck += aposEss; } // Some dictionaries include a trailing period on certain words such as "etc." which // we don't include. If the word is followed by a period, try it with the period to // see if we get a match. If so, consider it valid. if (word.Start + word.Length < textToSplit.Length && textToSplit[word.Start + word.Length] == '.') { if (this.Dictionary.ShouldIgnoreWord(textToCheck + ".") || this.Dictionary.IsSpelledCorrectly(textToCheck + ".")) { continue; } } yield return(new MisspellingTag(errorSpan) { EscapeApostrophes = unescapeApostrophes }); } } } } } }
internal IEnumerable <ClassifiedSpan> GetIdentifiersInSpans(Workspace workspace, SemanticModel model, NormalizedSnapshotSpanCollection spans) { var classifiedSpans = spans.SelectMany(span => { var textSpan = TextSpan.FromBounds(span.Start, span.End); return(Classifier.GetClassifiedSpans(model, textSpan, workspace)); }); return(classifiedSpans.Where(span => ColorCoderClassificationTypeNames.SupportedClassificationTypeNames.Contains(span.ClassificationType, StringComparer.InvariantCultureIgnoreCase))); }
/// <summary> /// Check for misspellings in the given set of dirty spans /// </summary> /// <param name="dirtySpans">The enumerable list of dirty spans to check for misspellings</param> private void CheckSpellings(IEnumerable <SnapshotSpan> dirtySpans) { ITextSnapshot snapshot = _buffer.CurrentSnapshot; foreach (var dirtySpan in dirtySpans) { var dirty = dirtySpan.TranslateTo(snapshot, SpanTrackingMode.EdgeInclusive); // We have to go back to the UI thread to get natural text spans List <SnapshotSpan> naturalTextSpans = new List <SnapshotSpan>(); OnForegroundThread(() => naturalTextSpans = GetNaturalLanguageSpansForDirtySpan(dirty).ToList()); var naturalText = new NormalizedSnapshotSpanCollection( naturalTextSpans.Select(span => span.TranslateTo(snapshot, SpanTrackingMode.EdgeInclusive))); List <MisspellingTag> currentMisspellings = new List <MisspellingTag>(_misspellings); List <MisspellingTag> newMisspellings = new List <MisspellingTag>(); int removed = currentMisspellings.RemoveAll(tag => tag.ToTagSpan(snapshot).Span.OverlapsWith(dirty)); newMisspellings.AddRange(GetMisspellingsInSpans(naturalText)); // Also remove empties removed += currentMisspellings.RemoveAll(tag => tag.ToTagSpan(snapshot).Span.IsEmpty); // If anything has been updated, we need to send out a change event if (newMisspellings.Count != 0 || removed != 0) { currentMisspellings.AddRange(newMisspellings); _dispatcher.Invoke(new Action(() => { if (_isClosed) { return; } _misspellings = currentMisspellings; var temp = TagsChanged; if (temp != null) { temp(this, new SnapshotSpanEventArgs(dirty)); } })); } } lock (_dirtySpanLock) { if (_isClosed) { return; } if (_dirtySpans.Count != 0) { _dispatcher.BeginInvoke(new Action(() => ScheduleUpdate())); } } }
static NormalizedSnapshotSpanCollection SymmetricDifference(NormalizedSnapshotSpanCollection first, NormalizedSnapshotSpanCollection second) { return(NormalizedSnapshotSpanCollection.Union( NormalizedSnapshotSpanCollection.Difference(first, second), NormalizedSnapshotSpanCollection.Difference(second, first))); }
internal IEnumerable <ITagSpan <IClassificationTag> > GetClassificationTags(ProviderCache cache, NormalizedSnapshotSpanCollection spans, Dictionary <string, IClassificationType> classificationTypeDictionary) { var snapshot = spans[0].Snapshot; IEnumerable <ClassifiedSpan> classifiedSpans = GetIdentifiersInSpans(cache.Workspace, cache.SemanticModel, spans); foreach (var classifiedSpan in classifiedSpans) { var node = GetExpression(cache.SyntaxRoot.FindNode(classifiedSpan.TextSpan)); var symbol = cache.SemanticModel.GetSymbolInfo(node).Symbol ?? cache.SemanticModel.GetDeclaredSymbol(node); yield return(GetTagSpan(node, classifiedSpan, snapshot, symbol, classificationTypeDictionary)); } }
public IEnumerable <ITagSpan <GlyphTextMarkerGlyphTag> > GetTags(NormalizedSnapshotSpanCollection spans) => service.GetGlyphTextMarkerGlyphTags(spans);
public static IEnumerable<ITagSpan<IOutliningRegionTag>> GetTags(this IGherkinFileScope gherkinFileScope, NormalizedSnapshotSpanCollection spans) { if (gherkinFileScope == null) return new ITagSpan<IOutliningRegionTag>[0]; var result = new List<ITagSpan<IOutliningRegionTag>>(); foreach (var gherkinFileBlock in gherkinFileScope.GetAllBlocks()) { result.AddRange(gherkinFileBlock.OutliningRegions); //TODO: optimize } return result; }
public static Mock<IMappingSpan> CreateMappingSpan(SnapshotSpan[] spans, MockRepository factory = null) { factory = factory ?? new MockRepository(MockBehavior.Strict); var col = new NormalizedSnapshotSpanCollection(spans); var mock = factory.Create<IMappingSpan>(); mock.Setup(x => x.GetSpans(spans[0].Snapshot)).Returns(col); mock.Setup(x => x.GetSpans(spans[0].Snapshot.TextBuffer)).Returns(col); return mock; }
// To produce adornments that don't obscure the text, the adornment tags // should have zero length spans. Overriding this method allows control // over the tag spans. protected override IEnumerable <Tuple <SnapshotSpan, PositionAffinity?, ColorTag> > GetAdornmentData(NormalizedSnapshotSpanCollection spans) { if (spans.Count == 0) { yield break; } ITextSnapshot snapshot = spans[0].Snapshot; var colorTags = this.colorTagger.GetTags(spans); foreach (IMappingTagSpan <ColorTag> dataTagSpan in colorTags) { NormalizedSnapshotSpanCollection colorTagSpans = dataTagSpan.Span.GetSpans(snapshot); // Ignore data tags that are split by projection. // This is theoretically possible but unlikely in current scenarios. if (colorTagSpans.Count != 1) { continue; } SnapshotSpan adornmentSpan = new SnapshotSpan(colorTagSpans[0].Start, 0); yield return(Tuple.Create(adornmentSpan, (PositionAffinity?)PositionAffinity.Successor, dataTagSpan.Tag)); } }
/// <param name="spans">Spans to provide adornment data for. These spans do not necessarily correspond to text lines.</param> /// <remarks> /// If adornments need to be updated, call <see cref="RaiseTagsChanged"/> or <see cref="InavlidateSpans"/>. /// This will, indirectly, cause <see cref="GetAdornmentData"/> to be called. /// </remarks> /// <returns> /// A sequence of: /// * adornment data for each adornment to be displayed /// * the span of text that should be elided for that adornment (zero length spans are acceptable) /// * and affinity of the adornment (this should be null if and only if the elided span has a length greater than zero) /// </returns> protected abstract IEnumerable <Tuple <SnapshotSpan, PositionAffinity?, TData> > GetAdornmentData(NormalizedSnapshotSpanCollection spans);
public IEnumerable <ITagSpan <AsmTokenTag> > GetTags(NormalizedSnapshotSpanCollection spans) { DateTime time1 = DateTime.Now; if (spans.Count == 0) { //there is no content in the buffer yield break; } foreach (SnapshotSpan curSpan in spans) { ITextSnapshotLine containingLine = curSpan.Start.GetContainingLine(); string line = containingLine.GetText().ToUpper(); var pos = new List <(int BeginPos, int Length, bool IsLabel)>(AsmSourceTools.SplitIntoKeywordPos(line)); int offset = containingLine.Start.Position; int nKeywords = pos.Count; for (int k = 0; k < nKeywords; k++) { string asmToken = NasmIntelTokenTagger.Keyword(pos[k], line); // keyword starts with a remark char if (AsmSourceTools.IsRemarkChar(asmToken[0])) { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._remark)); continue; } // keyword k is a label definition if (pos[k].IsLabel) { SnapshotSpan labelDefSpan = NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan); //AsmDudeToolsStatic.Output_INFO("MasmTokenTagger:GetTags: found label " + asmToken +" at line "+containingLine.LineNumber); if (asmToken.Equals("@@")) { // TODO: special MASM label, for the moment, ignore it, later: check whether it is used etc. } else { var v = Make_AsmTokenTag_LabelDef(containingLine.LineNumber); yield return(new TagSpan <AsmTokenTag>(labelDefSpan, v)); } continue; } AsmTokenType keywordType = this._asmDudeTools.Get_Token_Type_Intel(asmToken); switch (keywordType) { case AsmTokenType.Jump: { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._jump)); k++; // goto the next word if (k == nKeywords) { break; } string asmToken2 = NasmIntelTokenTagger.Keyword(pos[k], line); switch (asmToken2) { case "$": case "@B": case "@F": { // TODO: special MASM label, for the moment, ignore it, later: check whether it is used etc. break; } case "WORD": case "DWORD": case "QWORD": case "SHORT": case "NEAR": { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._misc)); k++; if (k == nKeywords) { break; } string asmToken3 = NasmIntelTokenTagger.Keyword(pos[k], line); switch (asmToken3) { case "$": case "@B": case "@F": { // TODO: special MASM label, for the moment, ignore it, later: check whether it is used etc. break; } case "PTR": { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._misc)); break; } default: { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), Make_AsmTokenTag_Label(containingLine.LineNumber))); break; } } break; } default: { if (RegisterTools.IsRegister(asmToken2)) { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._register)); } else { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), Make_AsmTokenTag_Label(containingLine.LineNumber))); } break; } } break; } case AsmTokenType.UNKNOWN: // asmToken is not a known keyword, check if it is numerical { //if (AsmTools.AsmSourceTools.Evaluate_Constant(asmToken, true).Valid) if (AsmTools.AsmSourceTools.Parse_Constant(asmToken, true).Valid) { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._constant)); } else if (asmToken.StartsWith("\"") && asmToken.EndsWith("\"")) { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._constant)); } else { bool isUnknown = true; // do one word lookahead; see whether we can understand the current unknown word if ((k + 1) < nKeywords) { k++; string nextKeyword = NasmIntelTokenTagger.Keyword(pos[k], line); switch (nextKeyword) { case "PROC": case "EQU": case "LABEL": { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k - 1], offset, curSpan), this._labelDef)); yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._directive)); isUnknown = false; break; } case "PROTO": { // a proto is considered a label definition but it should not clash with other label definitions yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k - 1], offset, curSpan), this._labelDef_PROTO)); yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._directive)); isUnknown = false; break; } default: { k--; break; } } } // do one word look back; see whether we can understand the current unknown word if (k > 0) { string previousKeyword = NasmIntelTokenTagger.Keyword(pos[k - 1], line); switch (previousKeyword) { case "ALIAS": { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._labelDef)); isUnknown = false; break; } case "INCLUDE": { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._constant)); isUnknown = false; break; } default: { break; } } } if (isUnknown) { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._UNKNOWN)); } } break; } case AsmTokenType.Directive: { AssemblerEnum assember = this._asmDudeTools.Get_Assembler(asmToken); if (assember.HasFlag(AssemblerEnum.MASM)) // this MASM token-tagger only tags MASM directives { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._directive)); switch (asmToken) { case "INVOKE": { k++; // goto the next word if (k == nKeywords) { break; } string asmToken2 = NasmIntelTokenTagger.Keyword(pos[k], line); yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), Make_AsmTokenTag_Label(containingLine.LineNumber))); break; } case "EXTRN": case "EXTERN": { k++; // goto the next word if (k == nKeywords) { break; } string asmToken2 = NasmIntelTokenTagger.Keyword(pos[k], line); yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._labelDef_PROTO)); break; } } } } break; default: { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), new AsmTokenTag(keywordType))); break; } } } } AsmDudeToolsStatic.Print_Speed_Warning(time1, "MasmTokenTagger"); }
IEnumerable <ITagSpan <TTag> > ITagger <TTag> .GetTags(NormalizedSnapshotSpanCollection col) { return(Tagger.GetTags(col)); }
public IEnumerable <ITagSpan <NM_TokenTag> > GetTags(NormalizedSnapshotSpanCollection spans) { foreach (SnapshotSpan curSpan in spans) { ITextSnapshotLine containingLine = curSpan.Start.GetContainingLine(); int curLoc = containingLine.Start.Position; int start_span; int temp_finish; var containing_edited = Dictionary_asm.RemoveAux(containingLine.GetText(), out start_span, out temp_finish); string[] tokens = containing_edited.Split(' '); Dictionary_asm.AddCustomLine(containingLine.GetText()); foreach (string nm_Token in tokens) { var temp_token = nm_Token; int macro_size; if (_NM_Types.ContainsKey(temp_token)) { var tokenSpan = new SnapshotSpan(curSpan.Snapshot, new Span(curLoc + start_span, nm_Token.Length)); if (tokenSpan.IntersectsWith(curSpan)) { yield return(new TagSpan <NM_TokenTag>(tokenSpan, new NM_TokenTag(_NM_Types[temp_token]))); } } else if (Dictionary_asm.IsQuoted(temp_token)) { var tokenSpan = new SnapshotSpan(curSpan.Snapshot, new Span(curLoc + start_span, nm_Token.Length)); if (tokenSpan.IntersectsWith(curSpan)) { yield return(new TagSpan <NM_TokenTag>(tokenSpan, new NM_TokenTag(_NM_Types["Quote"]))); } } else if (Dictionary_asm.IsNumber(temp_token)) { var tokenSpan = new SnapshotSpan(curSpan.Snapshot, new Span(curLoc + start_span, nm_Token.Length)); if (tokenSpan.IntersectsWith(curSpan)) { yield return(new TagSpan <NM_TokenTag>(tokenSpan, new NM_TokenTag(_NM_Types["Number"]))); } } else if (Dictionary_asm.IsCustomLabel(containingLine.GetText()) || Dictionary_asm.CustomLabel.Contains(nm_Token.ToLower())) { var tokenSpan = new SnapshotSpan(curSpan.Snapshot, new Span(curLoc + start_span, nm_Token.Length)); if (tokenSpan.IntersectsWith(curSpan)) { yield return(new TagSpan <NM_TokenTag>(tokenSpan, new NM_TokenTag(_NM_Types["Custom_label"]))); } } else if (Dictionary_asm.IsMacro(nm_Token, out macro_size)) { var tokenSpan = new SnapshotSpan(curSpan.Snapshot, new Span(curLoc + start_span, macro_size)); if (tokenSpan.IntersectsWith(curSpan)) { yield return(new TagSpan <NM_TokenTag>(tokenSpan, new NM_TokenTag(_NM_Types["Macro"]))); } } else if (Dictionary_asm.IsComment(nm_Token)) { var tokenSpan = new SnapshotSpan(curSpan.Snapshot, new Span(curLoc + start_span, containingLine.Length - containingLine.GetText().IndexOf(nm_Token))); if (tokenSpan.IntersectsWith(curSpan)) { yield return(new TagSpan <NM_TokenTag>(tokenSpan, new NM_TokenTag(_NM_Types["Comment"]))); } break; } //add an extra char location because of the space curLoc += nm_Token.Length + 1; } } }
public async Task LargeNumberOfSpans() { using (var workspace = TestWorkspace.CreateCSharp(@"class Program { void M() { int z = 0; z = z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z; } }")) { List <ITagSpan <TestTag> > tagProducer(SnapshotSpan span, CancellationToken cancellationToken) { return(new List <ITagSpan <TestTag> >() { new TagSpan <TestTag>(span, new TestTag()) }); } var asyncListener = new AsynchronousOperationListener(); WpfTestRunner.RequireWpfFact($"{nameof(AsynchronousTaggerTests)}.{nameof(LargeNumberOfSpans)} creates asynchronous taggers"); var notificationService = workspace.GetService <IForegroundNotificationService>(); var eventSource = CreateEventSource(); var taggerProvider = new TestTaggerProvider( workspace.ExportProvider.GetExportedValue <IThreadingContext>(), tagProducer, eventSource, workspace, asyncListener, notificationService); var document = workspace.Documents.First(); var textBuffer = document.TextBuffer; var snapshot = textBuffer.CurrentSnapshot; var tagger = taggerProvider.CreateTagger <TestTag>(textBuffer); using (IDisposable disposable = (IDisposable)tagger) { var spans = Enumerable.Range(0, 101).Select(i => new Span(i * 4, 1)); var snapshotSpans = new NormalizedSnapshotSpanCollection(snapshot, spans); eventSource.SendUpdateEvent(); await asyncListener.CreateWaitTask(); var tags = tagger.GetTags(snapshotSpans); Assert.Equal(1, tags.Count()); } } }
public IEnumerable <ITagSpan <IErrorTag> > GetTags(NormalizedSnapshotSpanCollection spans) { if (spans.Count == 0) { // there is no content in the buffer yield break; } bool labelGraph_Enabled = this._labelGraph.Enabled; bool asmSimulator_Enabled = this._asmSimulator.Enabled; if (!labelGraph_Enabled && !asmSimulator_Enabled) { // nothing to decorate yield break; } DateTime time1 = DateTime.Now; //TODO move the followign boolean to constructor bool Decorate_Undefined_Labels = labelGraph_Enabled && Settings.Default.IntelliSense_Decorate_Undefined_Labels; bool Decorate_Clashing_Labels = labelGraph_Enabled && Settings.Default.IntelliSense_Decorate_Clashing_Labels; bool Decorate_Undefined_Includes = labelGraph_Enabled && Settings.Default.IntelliSense_Show_Undefined_Includes; bool Decorate_Registers_Known_Register_Values = asmSimulator_Enabled && Settings.Default.AsmSim_Decorate_Registers; bool Decorate_Syntax_Errors = asmSimulator_Enabled && Settings.Default.AsmSim_Decorate_Syntax_Errors; bool Decorate_Unimplemented = asmSimulator_Enabled && Settings.Default.AsmSim_Decorate_Unimplemented; bool Decorate_Usage_Of_Undefined = asmSimulator_Enabled && Settings.Default.AsmSim_Decorate_Usage_Of_Undefined; bool Decorate_Redundant_Instructions = asmSimulator_Enabled && Settings.Default.AsmSim_Decorate_Redundant_Instructions; bool Decorate_Unreachable_Instructions = asmSimulator_Enabled && Settings.Default.AsmSim_Decorate_Unreachable_Instructions; bool Show_Syntax_Error_Error_List = asmSimulator_Enabled && Settings.Default.AsmSim_Show_Syntax_Errors; bool Show_Usage_Of_Undefined = asmSimulator_Enabled && Settings.Default.AsmSim_Show_Usage_Of_Undefined; AssemblerEnum usedAssember = AsmDudeToolsStatic.Used_Assembler; foreach (IMappingTagSpan <AsmTokenTag> asmTokenTag in this._aggregator.GetTags(spans)) { SnapshotSpan tagSpan = asmTokenTag.Span.GetSpans(this._sourceBuffer)[0]; //AsmDudeToolsStatic.Output_INFO(string.Format("SquigglesTagger:GetTags: found keyword \"{0}\"", tagSpan.GetText())); int lineNumber = AsmDudeToolsStatic.Get_LineNumber(tagSpan); switch (asmTokenTag.Tag.Type) { case AsmTokenType.Label: { if (Decorate_Undefined_Labels) { string label = tagSpan.GetText(); string full_Qualified_Label = AsmDudeToolsStatic.Make_Full_Qualified_Label(asmTokenTag.Tag.Misc, label, usedAssember); if (this._labelGraph.Has_Label(full_Qualified_Label)) { // Nothing to report } else { //AsmDudeToolsStatic.Output_INFO(string.Format("SquigglesTagger:GetTags: found label \"{0}\"; full-label \"{1}\"", label, full_Qualified_Label)); if (usedAssember == AssemblerEnum.MASM) { if (this._labelGraph.Has_Label(label)) { // TODO: is this always a valid label? Nothing to report } else { var toolTipContent = this.Undefined_Label_Tool_Tip_Content(); yield return(new TagSpan <IErrorTag>(tagSpan, new ErrorTag(PredefinedErrorTypeNames.SyntaxError, toolTipContent))); } } else { var toolTipContent = this.Undefined_Label_Tool_Tip_Content(); yield return(new TagSpan <IErrorTag>(tagSpan, new ErrorTag(PredefinedErrorTypeNames.SyntaxError, toolTipContent))); } } } break; } case AsmTokenType.LabelDef: { if (Decorate_Clashing_Labels) { string label = tagSpan.GetText(); string full_Qualified_Label = AsmDudeToolsStatic.Make_Full_Qualified_Label(asmTokenTag.Tag.Misc, label, usedAssember); if (this._labelGraph.Has_Label_Clash(full_Qualified_Label)) { var toolTipContent = this.Label_Clash_Tool_Tip_Content(full_Qualified_Label); //PredefinedErrorTypeNames.Warning is green //PredefinedErrorTypeNames.SyntaxError is red //PredefinedErrorTypeNames.CompilerError is blue //PredefinedErrorTypeNames.Suggestion is NOTHING //PredefinedErrorTypeNames.OtherError is purple yield return(new TagSpan <IErrorTag>(tagSpan, new ErrorTag(PredefinedErrorTypeNames.SyntaxError, toolTipContent))); } } break; } case AsmTokenType.Register: { if (Decorate_Registers_Known_Register_Values) { Rn regName = RegisterTools.ParseRn(tagSpan.GetText()); //AsmDudeToolsStatic.Output_INFO("SquigglesTagger:GetTags: found register " + regName + " at line " + lineNumber); bool preCompute = false; var(HasValue1, Bussy1) = this._asmSimulator.Has_Register_Value(regName, lineNumber, true, preCompute); if (!Bussy1) { var(HasValue2, Bussy2) = this._asmSimulator.Has_Register_Value(regName, lineNumber, false, preCompute); if (!Bussy2) { if ((HasValue1 || HasValue2)) { // only show squiggles to indicate that information is available //AsmDudeToolsStatic.Output_INFO("SquigglesTagger:GetTags: adding squiggles for register " + regName + " at line " + lineNumber); yield return(new TagSpan <IErrorTag>(tagSpan, new ErrorTag(PredefinedErrorTypeNames.Warning))); } } } } break; } case AsmTokenType.Mnemonic: { if (Decorate_Syntax_Errors || Decorate_Unimplemented) { if (this._asmSimulator.Is_Implemented(lineNumber)) { if (Decorate_Syntax_Errors && this._asmSimulator.Has_Syntax_Error(lineNumber)) { string message = AsmSourceTools.Linewrap("Syntax Error: " + this._asmSimulator.Get_Syntax_Error(lineNumber).Message, AsmDudePackage.maxNumberOfCharsInToolTips); yield return(new TagSpan <IErrorTag>(tagSpan, new ErrorTag(PredefinedErrorTypeNames.SyntaxError, message))); } } else if (Decorate_Unimplemented) { string message = AsmSourceTools.Linewrap("Info: Instruction " + tagSpan.GetText() + " is not (yet) supported by the simulator.", AsmDudePackage.maxNumberOfCharsInToolTips); yield return(new TagSpan <IErrorTag>(tagSpan, new ErrorTag(PredefinedErrorTypeNames.CompilerError, message))); } } if (Decorate_Usage_Of_Undefined) { if (this._asmSimulator.Has_Usage_Undefined_Warning(lineNumber)) { string message = AsmSourceTools.Linewrap("Semantic Warning: " + this._asmSimulator.Get_Usage_Undefined_Warning(lineNumber).Message, AsmDudePackage.maxNumberOfCharsInToolTips); yield return(new TagSpan <IErrorTag>(tagSpan, new ErrorTag(PredefinedErrorTypeNames.OtherError, message))); } } if (Decorate_Redundant_Instructions) { if (this._asmSimulator.Has_Redundant_Instruction_Warning(lineNumber)) { string message = AsmSourceTools.Linewrap("Semantic Warning: " + this._asmSimulator.Get_Redundant_Instruction_Warning(lineNumber).Message, AsmDudePackage.maxNumberOfCharsInToolTips); yield return(new TagSpan <IErrorTag>(tagSpan, new ErrorTag(PredefinedErrorTypeNames.OtherError, message))); } } if (Decorate_Unreachable_Instructions) { if (this._asmSimulator.Has_Unreachable_Instruction_Warning(lineNumber)) { string message = AsmSourceTools.Linewrap("Semantic Warning: " + this._asmSimulator.Get_Unreachable_Instruction_Warning(lineNumber).Message, AsmDudePackage.maxNumberOfCharsInToolTips); yield return(new TagSpan <IErrorTag>(tagSpan, new ErrorTag(PredefinedErrorTypeNames.OtherError, message))); } } break; } case AsmTokenType.Constant: { if (Decorate_Undefined_Includes) { foreach (var tup in this._labelGraph.Undefined_Includes) { if (tup.LineNumber == lineNumber) //TODO this is inefficient! { var toolTipContent = "Could not resolve include \"" + tagSpan.GetText() + "\""; yield return(new TagSpan <IErrorTag>(tagSpan, new ErrorTag(PredefinedErrorTypeNames.SyntaxError, toolTipContent))); break; // leave the foreach loop } } } break; } default: break; } } AsmDudeToolsStatic.Print_Speed_Warning(time1, "SquiggleTagger"); }
// Produces tags on the snapshot that this tagger is current with. private IEnumerable <TagSpan <IntraTextAdornmentTag> > GetAdornmentTagsOnSnapshot(NormalizedSnapshotSpanCollection spans) { if (spans.Count == 0) { yield break; } ITextSnapshot snapshot = spans[0].Snapshot; // Since WPF UI objects have state (like mouse hover or animation) and are relatively expensive to create and lay out, // this code tries to reuse controls as much as possible. // The controls are stored in this.adornmentCache between the calls. // Mark which adornments fall inside the requested spans with Keep=false // so that they can be removed from the cache if they no longer correspond to data tags. HashSet <SnapshotSpan> toRemove = new HashSet <SnapshotSpan>(); foreach (var ar in this._adornmentCache) { if (spans.IntersectsWith(new NormalizedSnapshotSpanCollection(ar.Key))) { toRemove.Add(ar.Key); } } foreach (var spanDataPair in GetAdornmentData(spans).Distinct(new Comparer())) { // Look up the corresponding adornment or create one if it's new. TAdornment adornment; SnapshotSpan snapshotSpan = spanDataPair.Item1; PositionAffinity?affinity = spanDataPair.Item2; TData adornmentData = spanDataPair.Item3; if (this._adornmentCache.TryGetValue(snapshotSpan, out adornment)) { if (UpdateAdornment(adornment, adornmentData)) { toRemove.Remove(snapshotSpan); } } else { adornment = CreateAdornment(adornmentData, snapshotSpan); if (adornment == null) { continue; } // Get the adornment to measure itself. Its DesiredSize property is used to determine // how much space to leave between text for this adornment. // Note: If the size of the adornment changes, the line will be reformatted to accommodate it. // Note: Some adornments may change size when added to the view's visual tree due to inherited // dependency properties that affect layout. Such options can include SnapsToDevicePixels, // UseLayoutRounding, TextRenderingMode, TextHintingMode, and TextFormattingMode. Making sure // that these properties on the adornment match the view's values before calling Measure here // can help avoid the size change and the resulting unnecessary re-format. adornment.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); this._adornmentCache.Add(snapshotSpan, adornment); } yield return(new TagSpan <IntraTextAdornmentTag>(snapshotSpan, new IntraTextAdornmentTag(adornment, null, affinity))); } foreach (var snapshotSpan in toRemove) { this._adornmentCache.Remove(snapshotSpan); } }
public IEnumerable <ITagSpan <IOutliningRegionTag> > GetTags(NormalizedSnapshotSpanCollection spans) { return(_outliningRegions); }
private IEnumerable <ITagSpan <IClassificationTag> > GetTagsImpl( Cache doc, NormalizedSnapshotSpanCollection spans) { var snapshot = spans[0].Snapshot; IEnumerable <ClassifiedSpan> classifiedSpans = GetClassifiedSpans(doc.Workspace, doc.SemanticModel, spans); foreach (var span in classifiedSpans) { var node = GetExpression(doc.SyntaxRoot.FindNode(span.TextSpan)); var symbol = doc.SemanticModel.GetSymbolInfo(node).Symbol; if (symbol == null) { symbol = doc.SemanticModel.GetDeclaredSymbol(node); } if (symbol == null) { continue; } switch (symbol.Kind) { case SymbolKind.Field: switch (span.ClassificationType) { case NewClassificationTypeNames.ConstantName: case NewClassificationTypeNames.FieldName: yield return(span.TextSpan.ToTagSpan(snapshot, _fieldType)); break; case NewClassificationTypeNames.EnumMemberName: yield return(span.TextSpan.ToTagSpan(snapshot, _enumFieldType)); break; } break; case SymbolKind.Method: var methodSymbol = (IMethodSymbol)symbol; switch (span.ClassificationType) { case ClassificationTypeNames.Identifier: if (IsConstructor(methodSymbol)) { yield return(span.TextSpan.ToTagSpan(snapshot, _constructorType)); } //local function definition else if (methodSymbol.MethodKind == LocalMethodKind) { yield return(span.TextSpan.ToTagSpan(snapshot, _localFunctionType)); } else if (methodSymbol.IsExtensionMethod) { yield return(span.TextSpan.ToTagSpan(snapshot, _extensionMethodType)); } break; case NewClassificationTypeNames.ExtensionMethodName: yield return(span.TextSpan.ToTagSpan(snapshot, _extensionMethodType)); break; case NewClassificationTypeNames.MethodName: //local function call if (methodSymbol.MethodKind == LocalMethodKind) { yield return(span.TextSpan.ToTagSpan(snapshot, _localFunctionType)); } //static method call else if (methodSymbol.MethodKind == MethodKind.Ordinary && methodSymbol.IsStatic) { yield return(span.TextSpan.ToTagSpan(snapshot, _staticMethodType)); } //other method call else { yield return(span.TextSpan.ToTagSpan(snapshot, _normalMethodType)); } break; } break; case SymbolKind.TypeParameter: yield return(span.TextSpan.ToTagSpan(snapshot, _typeParameterType)); break; case SymbolKind.Parameter: yield return(span.TextSpan.ToTagSpan(snapshot, _parameterType)); break; case SymbolKind.Namespace: yield return(span.TextSpan.ToTagSpan(snapshot, _namespaceType)); break; case SymbolKind.Property: yield return(span.TextSpan.ToTagSpan(snapshot, _propertyType)); break; case SymbolKind.Local: yield return(span.TextSpan.ToTagSpan(snapshot, _localType)); break; case SymbolKind.Event: yield return(span.TextSpan.ToTagSpan(snapshot, _eventType)); break; case SymbolKind.NamedType: if (IsSpecialType(symbol)) { yield return(span.TextSpan.ToTagSpan(snapshot, _typeSpecialType)); } else { switch (span.ClassificationType) { case ClassificationTypeNames.StructName: yield return(span.TextSpan.ToTagSpan(snapshot, _structType)); break; case ClassificationTypeNames.ClassName: yield return(span.TextSpan.ToTagSpan(snapshot, _classType)); break; case ClassificationTypeNames.InterfaceName: yield return(span.TextSpan.ToTagSpan(snapshot, _interfaceType)); break; case ClassificationTypeNames.DelegateName: yield return(span.TextSpan.ToTagSpan(snapshot, _delegateType)); break; case ClassificationTypeNames.EnumName: yield return(span.TextSpan.ToTagSpan(snapshot, _enumType)); break; } } break; } } }
IEnumerable <ITagSpan <IErrorTag> > ITagger <IErrorTag> .GetTags(NormalizedSnapshotSpanCollection spans) { return(GetTags(spans, new ErrorTag(PredefinedErrorTypeNames.Suggestion))); }
public IEnumerable <ITagSpan <SpaceNegotiatingAdornmentTag> > GetTags(NormalizedSnapshotSpanCollection spans) => intraTextAdornmentService.GetTags(spans);
public IEnumerable <ITagSpan <GlyphTextMarkerGlyphTag> > GetGlyphTextMarkerGlyphTags(NormalizedSnapshotSpanCollection spans) { foreach (var info in GetMarkers(spans, startOfSpanOnly: true)) { var imgRef = info.Marker.GlyphImageReference; if (imgRef != null) { yield return(new TagSpan <GlyphTextMarkerGlyphTag>(info.Span, new GlyphTextMarkerGlyphTag(imgRef.Value, info.Marker.ZIndex))); } } }
public IEnumerable <ITagSpan <NASMTokenTag> > GetTags(NormalizedSnapshotSpanCollection spans) { foreach (SnapshotSpan curSpan in spans) { ITextSnapshotLine containingLine = curSpan.Start.GetContainingLine(); int curLoc = containingLine.Start.Position; string[] tokens = Split(containingLine.GetText().ToLower(), _delimiters.ToCharArray()); NASMTokenTypes overrideType = NASMTokenTypes.Default; foreach (string token in tokens) { NASMTokenTypes type = GetTokenType(token); SnapshotSpan tokenSpan; if (type == NASMTokenTypes.Comment) { tokenSpan = new SnapshotSpan(curSpan.Snapshot, new Span(curLoc, containingLine.End.Position - curLoc)); if (tokenSpan.IntersectsWith(curSpan)) { yield return(new TagSpan <NASMTokenTag>(tokenSpan, new NASMTokenTag(type))); break; } } if (overrideType == NASMTokenTypes.String) { if (type == NASMTokenTypes.String) { overrideType = NASMTokenTypes.Default; } else { type = overrideType; } } else { if (type == NASMTokenTypes.String) { overrideType = NASMTokenTypes.String; } } if (overrideType == NASMTokenTypes.Character) { if (type == NASMTokenTypes.Character) { overrideType = NASMTokenTypes.Default; } else { type = NASMTokenTypes.Character; } } else { if (type == NASMTokenTypes.Character) { overrideType = NASMTokenTypes.Character; } } tokenSpan = new SnapshotSpan(curSpan.Snapshot, new Span(curLoc, token.Length)); if (tokenSpan.IntersectsWith(curSpan)) { yield return(new TagSpan <NASMTokenTag>(tokenSpan, new NASMTokenTag(type))); } //add an extra char location because of the space curLoc += token.Length; } } }
public bool Replace() { if (this.ReplaceTerm == null) { throw new InvalidOperationException("Can't replace with a null value. Set ReplaceTerm before performing a replace operation."); } if (!this.CurrentResult.HasValue) { throw new InvalidOperationException("Need to have a current result before being able to replace. Perform a FindNext or FindPrevious operation first."); } bool forward = (this.SearchOptions & FindOptions.SearchReverse) != FindOptions.SearchReverse; bool regEx = (this.SearchOptions & FindOptions.UseRegularExpressions) == FindOptions.UseRegularExpressions; //This may not be the text buffer's current snapshot but that is the desired behavior. We're replacing the current result //with the replace tuern. SnapshotSpan result = this.CurrentResult.Value; ITextSnapshot replaceSnapshot = result.Snapshot; SnapshotPoint searchStart = forward ? result.Start : result.End; SnapshotSpan searchSpan; NormalizedSnapshotSpanCollection searchSpans = this.SearchSpans; if ((searchSpans != null) && (searchSpans.Count > 0)) { //There could be a version skew here. if (searchSpans[0].Snapshot != replaceSnapshot) { searchSpans = new NormalizedSnapshotSpanCollection(replaceSnapshot, TextSearchNavigator.TranslateTo(searchSpans[0].Snapshot, searchSpans, replaceSnapshot)); } int index; if (!TextSearchNavigator.TryGetIndexOfContainingSpan(searchSpans, searchStart, out index)) { // If the match is outside of the search range, then we should noop return(false); } searchSpan = searchSpans[index]; } else { searchSpan = new SnapshotSpan(replaceSnapshot, 0, replaceSnapshot.Length); } searchSpan = forward ? new SnapshotSpan(searchStart, searchSpan.End) : new SnapshotSpan(searchSpan.Start, searchStart); //Ask the search engine to find the actual span we need to replace (& the corresponding replacement string). string replacementValue = null; SnapshotSpan?toReplace = _textSearchService.FindForReplace(searchSpan, this.SearchTerm, this.ReplaceTerm, this.SearchOptions, out replacementValue); if (toReplace.HasValue) { using (ITextEdit edit = _buffer.CreateEdit()) { Span replacementSpan = toReplace.Value.TranslateTo(edit.Snapshot, SpanTrackingMode.EdgeInclusive); if (!edit.Replace(replacementSpan, replacementValue)) { // The edit failed for some reason, perhaps read-only regions? return(false); } edit.Apply(); if (edit.Canceled) { // The edit failed, most likely a handler of the changed event forced the edit to be canceled. return(false); } } return(true); } return(false); }
private static IEnumerable <ITagSpan <ISemanticBlockTag> > GetTags(CodeBlock block, NormalizedSnapshotSpanCollection spans) { if (spans.IntersectsWith(new NormalizedSnapshotSpanCollection(block.Span))) { yield return(new TagSpan <ISemanticBlockTag>(block.Span, block)); foreach (var child in block.Children) { foreach (var tag in GetTags(child, spans)) { yield return(tag); } } } }
public override void PostprocessMouseLeftButtonUp(MouseButtonEventArgs e) { Point pos = GetLocation(e); var oLine = GetLineAt(clickPos); var cLine = GetLineAt(pos); if ( oLine != cLine || cLine == null ) return; // find what outlining regions start on the current line // if it's one of ours, remove it. SnapshotSpan span = new SnapshotSpan(cLine.Start, cLine.End); var spans = new NormalizedSnapshotSpanCollection(span); foreach ( var tag in tagAggregator.GetTags(spans) ) { if ( !(tag.Tag is OutliningGlyphTag) ) continue; var tagSpan = tag.GetSpan(cLine.Snapshot); if ( tagSpan.IsEmpty ) continue; // we might see tags that cover this region, but // don't start on the selected line if ( TagStartsOnViewLine(tagSpan, cLine) ) { RemoveOutlineAt(tagSpan.Start); e.Handled = true; } break; } }
public IEnumerable <ITagSpan <TextMarkerTag> > GetTags(NormalizedSnapshotSpanCollection spans) { DateTime oStart, oEnd; TimeSpan timeSpan; oStart = DateTime.Now; WriteOutputMessage("Start get brackets: " + oStart.ToString("hh:mm:ss.fff")); if (spans.Count == 0) //there is no content in the buffer { yield break; } if (CurrentChar == null || SourceBuffer == null) { yield break; } //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 ssp = 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 != ssp.Snapshot) { ssp = ssp.TranslateTo(spans[0].Snapshot, PointTrackingMode.Positive); } //get the current char and the previous char char currentText = '\0'; char lastText = '\0'; SnapshotSpan pairSpan = new SnapshotSpan(); SnapshotPoint lastChar = new SnapshotPoint(); try { if (ssp.Position < ssp.Snapshot.Length) { currentText = ssp.GetChar(); lastChar = ssp == 0 ? ssp : ssp - 1; //if ssp is 0 (beginning of buffer), don't move it back lastText = lastChar.GetChar(); } else { yield break; } } catch (Exception) { yield break; } // use the tokens stored in the buffer properties XSharpTokens xTokens = null; IList <IToken> tokens = null; int offset = 0; if (m_braceList.ContainsKey(currentText) || (m_braceList.ContainsValue(lastText))) //FM#081219 #1 - Only need to get the tokens if either of these conditions is true { if (SourceBuffer.Properties != null && SourceBuffer.Properties.ContainsProperty(typeof(XSharpTokens))) { xTokens = SourceBuffer.Properties.GetProperty <XSharpTokens>(typeof(XSharpTokens)); if (xTokens == null || xTokens.TokenStream == null || xTokens.SnapShot == null) { yield break; } tokens = xTokens.TokenStream.GetTokens(); if (tokens == null) { yield break; } if (xTokens.SnapShot.Version != ssp.Snapshot.Version) { // get source from the start of the file until the current entity var xfile = SourceBuffer.GetFile(); var member = XSharpTokenTools.FindMemberAtPosition(ssp.Position, xfile); if (member != null) { try { var sourceWalker = new SourceWalker(xfile); string text = ssp.Snapshot.GetText(); var length = Math.Min(member.Interval.Width, text.Length - member.Interval.Start); text = text.Substring(member.Interval.Start, length); //FM#081219 #2 - We are in a 'member'. For brace matching we should only ever need to look to the end of this member offset = member.Interval.Start; WriteOutputMessage("Start sourceWalker.Lex: " + DateTime.Now.ToString("hh:mm:ss.fff")); var stream = (BufferedTokenStream)sourceWalker.Lex(text); WriteOutputMessage("End sourceWalker.Lex: " + DateTime.Now.ToString("hh:mm:ss.fff")); tokens = stream.GetTokens(); } catch (Exception e) { // if it crashes, that might be because the snapshot used for the Lex/Parse is no more // so, we may have a too much difference // we do not break but simply use the 'old' tokens System.Diagnostics.Debug.WriteLine(e.Message); } } } } } // First, try to match Simple chars if (m_braceList.ContainsKey(currentText)) //the key is the open brace { char closeChar; m_braceList.TryGetValue(currentText, out closeChar); if (BraceMatchingTagger.FindMatchingCloseChar(ssp, currentText, closeChar, out pairSpan, tokens, offset) == true) { yield return(new TagSpan <TextMarkerTag>(new SnapshotSpan(ssp, 1), new TextMarkerTag("blue"))); yield return(new TagSpan <TextMarkerTag>(pairSpan, new TextMarkerTag("blue"))); } } else if (m_braceList.ContainsValue(lastText)) //the value is the close brace, which is the *previous* character { var open = from n in m_braceList where n.Value.Equals(lastText) select n.Key; if (BraceMatchingTagger.FindMatchingOpenChar(lastChar, (char)open.ElementAt <char>(0), lastText, out pairSpan, tokens, offset) == true) { yield return(new TagSpan <TextMarkerTag>(new SnapshotSpan(lastChar, 1), new TextMarkerTag("blue"))); yield return(new TagSpan <TextMarkerTag>(pairSpan, new TextMarkerTag("blue"))); } } else { // Second, try to Match Keywords // Try to retrieve an already parsed list of Tags XSharpClassifier xsClassifier = null; if (SourceBuffer.Properties.ContainsProperty(typeof(XSharpClassifier))) { xsClassifier = SourceBuffer.Properties[typeof(XSharpClassifier)] as XSharpClassifier; } if (xsClassifier != null) { ITextSnapshot snapshot = xsClassifier.Snapshot; if (snapshot.Version != ssp.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.XSharpBraceOpenFormat)) || (tag.ClassificationType.IsOfType(ColorizerConstants.XSharpBraceCloseFormat))) { 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 => ssp.Position >= x.Span.Start.Position && ssp.Position <= x.Span.End.Position); foreach (var currentTag in tags) { var index = sortedTags.IndexOf(currentTag); if (currentTag.ClassificationType.IsOfType(ColorizerConstants.XSharpBraceOpenFormat)) { if (FindMatchingCloseTag(sortedTags, index, snapshot, out pairSpan)) { var span = currentTag.Span; yield return(new TagSpan <TextMarkerTag>(span, new TextMarkerTag("bracehighlight"))); yield return(new TagSpan <TextMarkerTag>(pairSpan, new TextMarkerTag("bracehighlight"))); } } else { if (FindMatchingOpenTag(sortedTags, index, snapshot, out pairSpan)) { var span = currentTag.Span; yield return(new TagSpan <TextMarkerTag>(pairSpan, new TextMarkerTag("bracehighlight"))); yield return(new TagSpan <TextMarkerTag>(span, new TextMarkerTag("bracehighlight"))); } } } } } oEnd = DateTime.Now; timeSpan = oEnd - oStart; WriteOutputMessage("Finished get brackets: " + oEnd.ToString("hh:mm:ss.fff")); WriteOutputMessage("Finished get brackets - total ms: " + timeSpan.TotalMilliseconds.ToString()); }
public virtual NormalizedSnapshotSpanCollection UncommentSpans(NormalizedSnapshotSpanCollection spans) { List<SnapshotSpan> result = new List<SnapshotSpan>(); if (spans.Count == 0) return new NormalizedSnapshotSpanCollection(); var undoHistory = TextUndoHistoryRegistry.RegisterHistory(TextView); using (var transaction = undoHistory.CreateTransaction("Uncomment Selection")) { ITextSnapshot snapshot = spans[0].Snapshot; using (var edit = snapshot.TextBuffer.CreateEdit()) { foreach (var span in spans) { var selection = UncommentSpan(span, edit); result.Add(selection); } edit.Apply(); } if (snapshot != TextView.TextSnapshot) transaction.Complete(); } if (result.Count > 1) result.RemoveAll(span => span.IsEmpty); var target = TextView.TextBuffer.CurrentSnapshot; for (int i = 0; i < result.Count; i++) { result[i] = result[i].TranslateTo(target, SpanTrackingMode.EdgeInclusive); } return new NormalizedSnapshotSpanCollection(result); }
/// <summary> /// Find all of the tag regions in the document (snapshot) and notify /// listeners of any that changed /// </summary> void ReparseFile(object sender, TextContentChangedEventArgs args) { ITextSnapshot snapshot = _buffer.CurrentSnapshot; if (snapshot == _snapshot) { return; // we've already computed the regions for this snapshot } NormalizedSnapshotSpanCollection difference = new NormalizedSnapshotSpanCollection(); ScanResult result; if (_buffer.Properties.TryGetProperty(bufferTokenTaggerKey, out result) && (result._oldSnapshot == _snapshot) && (result._newSnapshot == snapshot)) { difference = result._difference; // save the new baseline _regions = result._regions; _snapshot = snapshot; } else { List <TokenRegion> regions = new List <TokenRegion>(); List <SnapshotSpan> rescannedRegions = new List <SnapshotSpan>(); // loop through the changes and check for changes in comments first. If // the change is in a comments, we need to rescan starting from the // beginning of the comments (which in multi-lined comments, it can // be a line that the changes are not on), otherwise, we can just rescan the lines // that the changes are on. bool done; SnapshotPoint start, end; for (int i = 0; i < args.Changes.Count; i++) { done = false; // get the span of the lines that the change is on. int cStart = args.Changes[i].NewSpan.Start; int cEnd = args.Changes[i].NewSpan.End; start = snapshot.GetLineFromPosition(cStart).Start; end = snapshot.GetLineFromPosition(cEnd).End; SnapshotSpan newSpan = new SnapshotSpan(start, end); foreach (TokenRegion r in _regions) { if (r.Kind == DafnyTokenKind.Comment) { // if the change is in the comments, we want to start scanning from the // the beginning of the comments instead. SnapshotSpan span = r.Span.TranslateTo(snapshot, SpanTrackingMode.EdgeExclusive); if (span.IntersectsWith(newSpan)) { start = span.Start.Position < newSpan.Start.Position ? span.Start : newSpan.Start; end = span.End.Position > newSpan.End.Position ? span.End : newSpan.End; end = Scan(snapshot.GetText(new SnapshotSpan(start, end)), start, regions, snapshot); // record the regions that we rescanned. rescannedRegions.Add(new SnapshotSpan(start, end)); done = true; break; } } } if (!done) { // scan the lines that the change is on to generate the new regions. end = Scan(snapshot.GetText(new SnapshotSpan(start, end)), start, regions, snapshot); // record the span that we rescanned. rescannedRegions.Add(new SnapshotSpan(start, end)); } } List <SnapshotSpan> oldSpans = new List <SnapshotSpan>(); List <SnapshotSpan> newSpans = new List <SnapshotSpan>(); // record the newly created spans. foreach (TokenRegion r in regions) { newSpans.Add(r.Span); } // loop through the old scan results and remove the ones that // are in the regions that are rescanned. foreach (TokenRegion r in _regions) { SnapshotSpan origSpan = r.Span.TranslateTo(snapshot, SpanTrackingMode.EdgeExclusive); bool obsolete = false; foreach (SnapshotSpan span in rescannedRegions) { if (origSpan.IntersectsWith(span)) { oldSpans.Add(span); obsolete = true; break; } } if (!obsolete) { TokenRegion region = new TokenRegion(origSpan.Start, origSpan.End, r.Kind); regions.Add(region); } } NormalizedSnapshotSpanCollection oldSpanCollection = new NormalizedSnapshotSpanCollection(oldSpans); NormalizedSnapshotSpanCollection newSpanCollection = new NormalizedSnapshotSpanCollection(newSpans); difference = SymmetricDifference(oldSpanCollection, newSpanCollection); // save the scan result _buffer.Properties[bufferTokenTaggerKey] = new ScanResult(_snapshot, snapshot, regions, difference); // save the new baseline _snapshot = snapshot; _regions = regions; } var chng = TagsChanged; if (chng != null) { foreach (var span in difference) { chng(this, new SnapshotSpanEventArgs(span)); } } }