private async void OnBreakpointsChanged(object sender, EventArgs eventArgs) { var newBreakpoints = new Dictionary <Breakpoint, ManagerBreakpoint> (); var snapshot = textBuffer.CurrentSnapshot; var needsUpdate = false; foreach (var breakpoint in DebuggingService.Breakpoints.GetBreakpointsAtFile(textDocument.FilePath)) { if (breakpoint.Line > snapshot.LineCount) { continue; } if (eventArgs is BreakpointEventArgs breakpointEventArgs && breakpointEventArgs.Breakpoint == breakpoint) { needsUpdate = true; } var line = snapshot.GetLineFromLineNumber(breakpoint.Line - 1); var position = line.Start.Position + breakpoint.Column; var span = await DebuggingService.GetBreakpointSpanAsync(textDocument, position); if (breakpoints.TryGetValue(breakpoint, out var existingBreakpoint)) { newBreakpoints.Add(breakpoint, existingBreakpoint); if (existingBreakpoint.Span != span) { // Update if anything was modified existingBreakpoint.Span = span; needsUpdate = true; } } else { // Update if anything was added newBreakpoints.Add(breakpoint, new ManagerBreakpoint { Breakpoint = breakpoint, TrackingSpan = snapshot.CreateTrackingSpan(span, SpanTrackingMode.EdgeExclusive), Span = span }); needsUpdate = true; } } // Update if anything was removed if (needsUpdate || breakpoints.Keys.Except(newBreakpoints.Keys).Any()) { needsUpdate = true; } breakpoints = newBreakpoints; if (needsUpdate) { BreakpointsChanged?.Invoke(this, new SnapshotSpanEventArgs(new SnapshotSpan(snapshot, 0, snapshot.Length))); } }