Exemplo n.º 1
0
        /// <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());
                }
            }
        }