/// <summary> /// Reconciles bookmark service bookmarks on hand with bookmark spans. /// </summary> private void DoChanged(int number, BookmarkType type) { if (!InitializeServices(false)) { return; } var fileName = GetFileName(); if (string.IsNullOrEmpty(fileName)) { return; } _log?.LogMessage($"File '{Path.GetFileName(fileName)}' bookmark {number} change ({type})", LOG_CATEGORY); try { var bookmarks = this.BookmarksService?.GetFileBookmarks(fileName); if ((bookmarks.Count() == 0) && (_bookmarkSpans.Count == 0)) { return; } using (Update()) { // Remove changed bookmark so that it gets re-added further down if (number > 0) { var changedBookmark = _bookmarkSpans.Keys.FirstOrDefault(b => (b.Number == number) && type.HasFlag(b.Type)); if (changedBookmark != null) { _log?.LogMessage($"Removed changed {changedBookmark.Type} bookmark {changedBookmark.Number} tag", LOG_CATEGORY); if (!RemoveTagSpan(_bookmarkSpans[changedBookmark])) { _log?.LogMessage($"Failed to remove changed {changedBookmark.Type} bookmark {changedBookmark.Number} tag span", LOG_CATEGORY); } _bookmarkSpans.Remove(changedBookmark); } } var newBookmarks = bookmarks.Where(b => !_bookmarkSpans.ContainsKey(b)).ToList(); newBookmarks.ForEach(b => { if ((b.Line >= 1) && (b.Line <= _buffer.CurrentSnapshot.LineCount)) { var line = _buffer.CurrentSnapshot.GetLineFromLineNumber(b.Line - 1); var span = _buffer.CurrentSnapshot.CreateTrackingSpan(new SnapshotSpan(line.Start, 1), SpanTrackingMode.EdgeExclusive); // can't be span of 0 length var trackingSpan = CreateTagSpan(span, new BookmarkTag(b.Number, b.Type)); _bookmarkSpans.Add(b, trackingSpan); _log?.LogMessage($"Added {b.Type} bookmark {b.Number} tag on line {b.Line}", LOG_CATEGORY); } else { _log?.LogMessage($"{b.Type} bookmark {b.Number} invalid tag line {b.Line}", LOG_CATEGORY); } }); var deleteBookmarks = _bookmarkSpans.Keys.Where(b => !bookmarks.Contains(b)).ToList(); deleteBookmarks.ForEach(b => { _log?.LogMessage($"Removed deleted {b.Type} bookmark {b.Number} tag", LOG_CATEGORY); if (!RemoveTagSpan(_bookmarkSpans[b])) { _log?.LogMessage($"Failed to remove deleted {b.Type} bookmark {b.Number} tag span", LOG_CATEGORY); } _bookmarkSpans.Remove(b); }); } } catch (Exception ex) { if (_log != null) { _log.LogMessage(ex, LOG_CATEGORY); } else { Trace.TraceError(ex.ToString()); } } }