private void UpdateDirtySpans(TextContentChangedEventArgs e) { _currentSnapshot = e.After; var newDirtySpans = _dirtySpans.CloneAndTrackTo(e.After, SpanTrackingMode.EdgeInclusive); newDirtySpans = e.Changes .Aggregate(newDirtySpans, (current, change) => NormalizedSnapshotSpanCollection.Union( current, new NormalizedSnapshotSpanCollection(e.After, change.NewSpan))); _dirtySpans = newDirtySpans; }
private void UpdateDirtySpans(TextContentChangedEventArgs e) { currentSnapshot = e.After; var newDirtySpans = dirtySpans.CloneAndTrackTo(e.After, SpanTrackingMode.EdgeInclusive); foreach (var change in e.Changes) { newDirtySpans = NormalizedSnapshotSpanCollection.Union(newDirtySpans, new NormalizedSnapshotSpanCollection(e.After, change.NewSpan)); } dirtySpans = newDirtySpans; }
internal void EnqueueChanges( ITextSnapshot snapshot, NormalizedSnapshotSpanCollection changedSpans) { AssertIsForeground(); var version = snapshot.Version.VersionNumber; var currentSpans = _snapshotVersionToSpansMap.GetOrAdd(version, s_addFunction); var allSpans = NormalizedSnapshotSpanCollection.Union(currentSpans, changedSpans); _snapshotVersionToSpansMap[version] = allSpans; EnqueueNotificationRequest(_throttleDelay); }
internal void EnqueueChanges(NormalizedSnapshotSpanCollection changedSpans) { AssertIsForeground(); if (changedSpans.Count == 0) { return; } var snapshot = changedSpans.First().Snapshot; var version = snapshot.Version.VersionNumber; var currentSpans = _snapshotVersionToSpansMap.GetOrAdd(version, s_addFunction); var allSpans = NormalizedSnapshotSpanCollection.Union(currentSpans, changedSpans); _snapshotVersionToSpansMap[version] = allSpans; EnqueueNotificationRequest(TaggerDelay.NearImmediate); }
private void OnBufferChange(object sender, TextContentChangedEventArgs e) { _currentSnapshot = e.After; // Translate all of the old dirty spans to the new snapshot. NormalizedSnapshotSpanCollection newDirtySpans = _dirtySpans.CloneAndTrackTo(e.After, SpanTrackingMode.EdgeInclusive); // Dirty all the spans that changed. foreach (var change in e.Changes) { newDirtySpans = NormalizedSnapshotSpanCollection.Union(newDirtySpans, new NormalizedSnapshotSpanCollection(e.After, change.NewSpan)); } // Translate all the security errors to the new snapshot (and remove anything that is a dirty // region since we will need to check that again). var oldSecurityErrors = this.Factory.CurrentSnapshot; var newSecurityErrors = new DevSkimErrorsSnapshot(this.FilePath, oldSecurityErrors.VersionNumber + 1); // Copy all of the old errors to the new errors unless the error was affected by the text change foreach (var error in oldSecurityErrors.Errors) { Debug.Assert(error.NextIndex == -1); var newError = DevSkimError.CloneAndTranslateTo(error, e.After); if (newError != null) { Debug.Assert(newError.Span.Length == error.Span.Length); error.NextIndex = newSecurityErrors.Errors.Count; newSecurityErrors.Errors.Add(newError); } } this.UpdateSecurityErrors(newSecurityErrors); _dirtySpans = newDirtySpans; // Start processing the dirty spans (which no-ops if we're already doing it). if (_dirtySpans.Count != 0) { this.KickUpdate(); } }
static NormalizedSnapshotSpanCollection SymmetricDifference(NormalizedSnapshotSpanCollection first, NormalizedSnapshotSpanCollection second) { return(NormalizedSnapshotSpanCollection.Union( NormalizedSnapshotSpanCollection.Difference(first, second), NormalizedSnapshotSpanCollection.Difference(second, first))); }
internal IEnumerable <ICollapsible> InternalGetAllRegions(NormalizedSnapshotSpanCollection spans, bool exposedRegionsOnly, CancellationToken?cancel = null) { EnsureValid(spans); // No collapsibles if disabled if (!isEnabled || spans.Count == 0) { return(new List <Collapsible>()); } ITextSnapshot snapshot = spans[0].Snapshot; IList <Collapsed> currentCollapsed = GetCollapsedRegionsInternal(spans, exposedRegionsOnly); IEnumerable <ICollapsible> newCollapsibles; if (!exposedRegionsOnly || currentCollapsed.Count == 0) { newCollapsibles = CollapsiblesFromTags(this.InternalGetTags(spans, cancel)).Keys; } else { NormalizedSnapshotSpanCollection collapsedRegions = new NormalizedSnapshotSpanCollection(currentCollapsed.Select(c => c.Extent.GetSpan(snapshot))); NormalizedSnapshotSpanCollection exposed = NormalizedSnapshotSpanCollection.Difference(spans, collapsedRegions); // Ensure there is an empty region on each end SnapshotSpan first = spans[0]; SnapshotSpan last = spans[spans.Count - 1]; NormalizedSnapshotSpanCollection ends = new NormalizedSnapshotSpanCollection(new SnapshotSpan[] { new SnapshotSpan(first.Start, 0), new SnapshotSpan(last.End, 0) }); exposed = NormalizedSnapshotSpanCollection.Union(exposed, ends); newCollapsibles = CollapsiblesFromTags(this.InternalGetTags(exposed, cancel)).Keys.Where(c => IsRegionExposed(c, snapshot)); } IEnumerable <ICollapsed> removed; var merged = MergeRegions(currentCollapsed, newCollapsibles, out removed); // NOTE: IF we have misbehaved taggers, it is possible that we'll see invalid // changes here in removed regions that are currently collapsed. We can deal // with this by expanding as needed, but it will cause an event to be sent out, which will // likely be unexpected and cause bugs in our clients. // There are a few ways we can deal with this: // #1: Expand/collapse regions and event foreach (var removedRegion in removed) { Debug.Fail("Removing a region here means a tagger has misbehaved."); if (removedRegion.IsCollapsed) { Expand(removedRegion); } } // Other options: // #2: Return the new regions without doing anything special // #3: Return the current collapsed + uncollapsed added regions return(merged); }