Beispiel #1
0
        /// <summary>
        /// Idle time event handler. Retrieves results from the validation task queue,
        /// creates new error tags (squiggles) and fires an event telling editor that
        /// tags changed. The code must operate on UI thread and hence it is called on idle.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="eventArgs"></param>
        private void OnIdle(object sender, EventArgs eventArgs)
        {
            if (_settings.SyntaxCheckEnabled && _textBuffer != null)
            {
                if (_resultsQueue.Count > 0)
                {
                    var addedTags    = new List <IEditorTaskListItem>();
                    var changedRange = _errorTags.BeginUpdate();
                    changedRange = TextRange.Intersection(changedRange, 0, _textBuffer.CurrentSnapshot.Length);

                    var timer = Stopwatch.StartNew();
                    timer.Reset();

                    while (timer.ElapsedMilliseconds < 100)
                    {
                        if (!_resultsQueue.TryDequeue(out var error))
                        {
                            break;
                        }

                        if (string.IsNullOrEmpty(error.Message))
                        {
                            // Empty message means remove all errors.
                            changedRange = new TextRange(0, _textBuffer.CurrentSnapshot.Length);
                        }
                        else
                        {
                            var tag = new EditorErrorTag(_document.EditorTree, error);
                            if (tag.Length > 0)
                            {
                                if (changedRange.End == 0)
                                {
                                    changedRange = tag;
                                }
                                else
                                {
                                    changedRange = changedRange.Union(tag);
                                }

                                _errorTags.Add(tag);
                                addedTags.Add(tag);
                            }
                        }
                    }

                    _errorTags.EndUpdate(changedRange.Length > 0);

                    // Clip range to the current snapshot
                    var start = Math.Max(changedRange.Start, 0);
                    start = Math.Min(start, _textBuffer.CurrentSnapshot.Length);
                    var end = Math.Min(changedRange.End, _textBuffer.CurrentSnapshot.Length);

                    if (changedRange.Length > 0)
                    {
                        TagsChanged?.Invoke(this, new SnapshotSpanEventArgs(new SnapshotSpan(_textBuffer.CurrentSnapshot, start, end - start)));
                    }

                    BeginUpdatingTasks?.Invoke(this, EventArgs.Empty);

                    try {
                        if (addedTags.Count > 0)
                        {
                            TasksAdded?.Invoke(this, new TasksListItemsChangedEventArgs(addedTags));
                        }
                        if (_errorTags.RemovedTags.Count > 0)
                        {
                            var removedTags = new List <IEditorTaskListItem>();
                            while (_errorTags.RemovedTags.Count > 0)
                            {
                                if (_errorTags.RemovedTags.TryDequeue(out var tag))
                                {
                                    removedTags.Add(tag);
                                }
                            }
                            if (removedTags.Count > 0)
                            {
                                TasksRemoved?.Invoke(this, new TasksListItemsChangedEventArgs(removedTags));
                            }
                        }
                    } finally {
                        EndUpdatingTasks?.Invoke(this, EventArgs.Empty);
                    }

                    timer.Stop();
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Idle time event handler. Retrieves results from the validation task queue,
        /// creates new error tags (squiggles) and fires an event telling editor that
        /// tags changed. The code must operate on UI thread and hence it is called on idle.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="eventArgs"></param>
        private void OnIdle(object sender, EventArgs eventArgs)
        {
            if (_settings.SyntaxCheckEnabled && _textBuffer != null)
            {
                if (ResultsQueue.Count > 0)
                {
                    _fireCodeMarkerUponCompletion = true;

                    var addedTags    = new List <IEditorTaskListItem>();
                    var changedRange = _errorTags.BeginUpdate();
                    changedRange = TextRange.Intersection(changedRange, 0, _textBuffer.CurrentSnapshot.Length);

                    var timer = Stopwatch.StartNew();
                    timer.Reset();

                    while (timer.ElapsedMilliseconds < 100)
                    {
                        if (!ResultsQueue.TryDequeue(out var error))
                        {
                            break;
                        }

                        if (string.IsNullOrEmpty(error.Message))
                        {
                            // Empty message means remove all error for the element.
                            var removedRange = TextRange.EmptyRange; // _errorTags.RemoveTagsForNode(error.NodeKey);

                            // Only update changedRange if there were errors removed
                            if (removedRange.End > 0)
                            {
                                if (changedRange.End == 0)
                                {
                                    changedRange = removedRange;
                                }
                                else
                                {
                                    changedRange = changedRange.Union(removedRange);
                                }
                            }
                        }
                        else
                        {
                            var tag = new EditorErrorTag(_document.EditorTree, error);
                            if (tag.Length > 0)
                            {
                                if (changedRange.End == 0)
                                {
                                    changedRange = tag;
                                }
                                else
                                {
                                    changedRange = changedRange.Union(tag);
                                }

                                _errorTags.Add(tag);
                                addedTags.Add(tag);
                            }
                        }
                    }

                    _errorTags.EndUpdate(changedRange.Length > 0);

                    // Clip range to the current snapshot
                    var start = Math.Max(changedRange.Start, 0);
                    start = Math.Min(start, _textBuffer.CurrentSnapshot.Length);
                    var end = Math.Min(changedRange.End, _textBuffer.CurrentSnapshot.Length);

                    if (changedRange.Length > 0)
                    {
                        TagsChanged?.Invoke(this, new SnapshotSpanEventArgs(new SnapshotSpan(_textBuffer.CurrentSnapshot, start, end - start)));
                    }

                    BeginUpdatingTasks?.Invoke(this, EventArgs.Empty);

                    try {
                        if (addedTags.Count > 0)
                        {
                            TasksAdded?.Invoke(this, new TasksListItemsChangedEventArgs(addedTags));
                        }
                        if (_errorTags.RemovedTags.Count > 0)
                        {
                            var removedTags = new List <IEditorTaskListItem>();
                            while (_errorTags.RemovedTags.Count > 0)
                            {
                                if (_errorTags.RemovedTags.TryDequeue(out var tag))
                                {
                                    removedTags.Add(tag);
                                }
                            }
                            if (removedTags.Count > 0)
                            {
                                TasksRemoved?.Invoke(this, new TasksListItemsChangedEventArgs(removedTags));
                            }
                        }
                    } finally {
                        EndUpdatingTasks?.Invoke(this, EventArgs.Empty);
                    }

                    timer.Stop();
                }

                if (_fireCodeMarkerUponCompletion && (ResultsQueue.Count == 0))
                {
                    // Use this flag so we don't incessantly fire this code marker on every idle.
                    // TODO: Even this isn't quite correct, as it's possible that a validator
                    //  yet pushed all it's entries into the results queue. There should really
                    //  be a notification from the validators to indicate their completeness. If there
                    //  were such a notification, then we could actually even unhook ourselves from idle.
                    _fireCodeMarkerUponCompletion = false;
                }
            }
        }