private GherkinTextBufferChange GetTextBufferChange(TextContentChangedEventArgs textContentChangedEventArgs)
        {
            Tracing.VisualStudioTracer.Assert(textContentChangedEventArgs.Changes.Count > 0, "There are no text changes");

            var startLine = int.MaxValue;
            var endLine = 0;
            var startPosition = int.MaxValue;
            var endPosition = 0;
            var lineCountDelta = 0;
            var positionDelta = 0;

            var beforeTextSnapshot = textContentChangedEventArgs.Before;
            var afterTextSnapshot = textContentChangedEventArgs.After;
            foreach (var change in textContentChangedEventArgs.Changes)
            {
                startLine = Math.Min(startLine, beforeTextSnapshot.GetLineNumberFromPosition(change.OldPosition));
                endLine = Math.Max(endLine, afterTextSnapshot.GetLineNumberFromPosition(change.NewEnd));

                startPosition = Math.Min(startPosition, change.OldPosition);
                endPosition = Math.Max(endPosition, change.NewEnd);
                lineCountDelta += change.LineCountDelta;
                positionDelta += change.Delta;
            }

            return new GherkinTextBufferChange(
                startLine == endLine ? GherkinTextBufferChangeType.SingleLine : GherkinTextBufferChangeType.MultiLine,
                startLine, endLine,
                startPosition, endPosition,
                lineCountDelta, positionDelta,
                afterTextSnapshot);
        }
        /// <summary>
        /// Combines multiple changes into one larger change.
        /// </summary>
        /// <param name="e">Text buffer change event argument</param>
        /// <param name="start">Combined span start</param>
        /// <param name="oldLength">Length of the change in the original buffer state</param>
        /// <param name="newLength">Length of the change in the new buffer state</param>
        internal static void CombineChanges(TextContentChangedEventArgs e, out int start, out int oldLength, out int newLength) {
            start = 0;
            oldLength = 0;
            newLength = 0;

            if (e.Changes.Count > 0) {
                // Combine multiple changes into one larger change. The problem is that
                // multiple changes map to one current snapshot and there are no
                // separate snapshots for each change which causes problems
                // in incremental parse analysis code.

                Debug.Assert(e.Changes[0].OldPosition == e.Changes[0].NewPosition);

                start = e.Changes[0].OldPosition;
                int oldEnd = e.Changes[0].OldEnd;
                int newEnd = e.Changes[0].NewEnd;

                for (int i = 1; i < e.Changes.Count; i++) {
                    start = Math.Min(start, e.Changes[i].OldPosition);
                    oldEnd = Math.Max(oldEnd, e.Changes[i].OldEnd);
                    newEnd = Math.Max(newEnd, e.Changes[i].NewEnd);
                }

                oldLength = oldEnd - start;
                newLength = newEnd - start;
            }
        }
 private void OnBufferChanged(object sender, TextContentChangedEventArgs e)
 {
     foreach(ITextChange change in e.Changes)
     {
         _bufferChanges.Append(change.OldText);
     }
 }
        private void TextBufferOnChanged(object sender, TextContentChangedEventArgs ea)
        {
            Func<int, DateTime, IEnumerable<DateTime>> fill = (count, time) => Enumerable.Range(0, count).Select(t => time);

            foreach (var textChange in ea.Changes)
            {
                var lineNumber = ea.Before.GetLineFromPosition(textChange.OldPosition).LineNumber;

                if (textChange.LineCountDelta > 0)
                {
                    var count =_lineTimeStamps.Count;
                    _lineTimeStamps.InsertRange(
                        Math.Min(lineNumber, count), 
                        fill(textChange.LineCountDelta + lineNumber - count, DateTime.Now));
                }
                else if (textChange.LineCountDelta < 0)
                {
                    try
                    {
                        _lineTimeStamps.RemoveRange(lineNumber, -textChange.LineCountDelta);
                    }
                    catch (ArgumentException)
                    {
                        _lineTimeStamps.Clear();
                    }
                }
            }
        }
 static void BufferChanged(object sender, TextContentChangedEventArgs e)
 {
     if (!Settings.Default.DisableAllParsing)
     {
         BufferChanged(sender);
     }
 }
        void OnBeforeTextBufferChanged(object sender, TextContentChangedEventArgs e)
        {
            foreach (var change in e.Changes)
            {
                var offset = change.NewLength - change.OldLength;

                if (change.OldEnd < _span.Start)
                {
                    _span = new Span(_span.Start + offset, _span.Length);
                }
                else if (change.OldPosition > _span.End)
                {
                }
                else if (change.OldPosition == _span.End && _span.Length == 0)
                {
                    _span = new Span(_span.Start, _span.Length + offset);
                }
                else if (_span.Contains(change.OldPosition) &&
                        (_span.Contains(change.OldEnd) || _span.End == change.OldEnd) &&
                        (_span.Contains(change.NewEnd) || _span.End == change.NewEnd))
                {
                    _span = new Span(_span.Start, _span.Length + offset);
                }
            }
        }
        private void NewBufferChanged(object sender, TextContentChangedEventArgs e)
        {
            bool isCommand = IsCommand(e.After.GetExtent());

            ITextBuffer buffer = e.After.TextBuffer;
            IContentType contentType = buffer.ContentType;
            IContentType newContentType = null;

            if (contentType == languageContentType)
            {
                if (isCommand)
                {
                    newContentType = commandContentType;
                }
            }
            else
            {
                if (!isCommand)
                {
                    newContentType = languageContentType;
                }
            }

            if (newContentType != null)
            {
                buffer.ChangeContentType(newContentType, editTag: null);
            }
        }
 private void OnTextBufferChanged(object sender, TextContentChangedEventArgs e)
 {
     lock (_lockObject)
     {
         _currentParseCancellationTokenSource?.Cancel();
         _hasWork.Set();
     }
 }
        static void BufferChanged(object sender, TextContentChangedEventArgs e)
        {
            ITextBuffer buffer = sender as ITextBuffer;
            if (buffer == null)
                return;

            RestartTimerForBuffer(buffer);
        }
 protected virtual void RaiseChanged(TextContentChangedEventArgs textChangedEventArgs = null)
 {
     var changed = this.Changed;
     if (changed != null)
     {
         changed(this, new TaggerEventArgs(EventKind, _delay, textChangedEventArgs));
     }
 }
 void TextBuffer_Changed(object sender, TextContentChangedEventArgs e)
 {
     if (e.After.LineCount != _ovlc.Count)
     {
         IsRedraw = true;
         this.ReGenOv(e.After);
     }
 }
        void TextBuffer_Changed(object sender, TextContentChangedEventArgs e)
        {
            if (_processing)
                return;

            _typedChar = '\0';

            if (e.Changes.Count != 1 || e.AfterVersion.ReiteratedVersionNumber <= _bufferVersionWaterline)
                return;

            var change = e.Changes[0];

            _bufferVersionWaterline = e.AfterVersion.ReiteratedVersionNumber;

            // Change length may be > 1 in autoformatting languages.
            // However, there will be only one non-ws character in the change.
            // Be careful when </script> is inserted: the change won't
            // actually be in this buffer.

            var snapshot = _textBuffer.CurrentSnapshot;

            if (change.NewSpan.End > snapshot.Length)
                return;

            var text = _textBuffer.CurrentSnapshot.GetText(change.NewSpan);

            text = text.Trim();

            if (text.Length != 1)
                return;

            // Allow completion of different characters inside spans, but not when
            // character and its completion pair is the same. For example, we do
            // want to complete () in foo(bar|) when user types ( after bar. However,
            // we do not want to complete " when user is typing in a string which
            // was already completed and instead " should be a terminating type-through.

            var typedChar = text[0];
            var completionChar = GetCompletionCharacter(typedChar);

            var caretPosition = GetCaretPositionInBuffer();

            if (!caretPosition.HasValue)
                return;

            bool compatible = true;

            var innerText = GetInnerProvisionalText();

            if (innerText != null)
                compatible = IsCompatibleCharacter(innerText.ProvisionalChar, typedChar);

            if (IsPositionInProvisionalText(caretPosition.Value) && typedChar == completionChar && !compatible)
                return;

            _typedChar = typedChar;
            _caretPosition = caretPosition.Value;
        }
            private void Buffer_Changed(object sender, TextContentChangedEventArgs e)
            {
                AssertIsForeground();

                if (!_buffer.GetOption(InternalFeatureOnOffOptions.RenameTracking))
                {
                    // When disabled, ignore all text buffer changes and do not trigger retagging
                    return;
                }

                using (Logger.LogBlock(FunctionId.Rename_Tracking_BufferChanged, CancellationToken.None))
                {
                    // When the buffer changes, several things might be happening:
                    // 1. If a non-identifer character has been added or deleted, we stop tracking
                    //    completely.
                    // 2. Otherwise, if the changes are completely contained an existing session, then
                    //    continue that session.
                    // 3. Otherwise, we're starting a new tracking session. Find and track the span of
                    //    the relevant word in the foreground, and use a task to figure out whether the
                    //    original word was a renamable identifier or not.

                    if (e.Changes.Count != 1 || ShouldClearTrackingSession(e.Changes.Single()))
                    {
                        ClearTrackingSession();
                        return;
                    }

                    // The change is trackable. Figure out whether we should continue an existing
                    // session

                    var change = e.Changes.Single();

                    if (this.TrackingSession == null)
                    {
                        StartTrackingSession(e);
                        return;
                    }

                    // There's an existing session. Continue that session if the current change is
                    // contained inside the tracking span.

                    SnapshotSpan trackingSpanInNewSnapshot = this.TrackingSession.TrackingSpan.GetSpan(e.After);
                    if (trackingSpanInNewSnapshot.Contains(change.NewSpan))
                    {
                        // Continuing an existing tracking session. If there may have been a tag
                        // showing, then update the tags.
                        if (this.TrackingSession.IsDefinitelyRenamableIdentifier())
                        {
                            this.TrackingSession.CheckNewIdentifier(this, _buffer.CurrentSnapshot);
                            TrackingSessionUpdated();
                        }
                    }
                    else
                    {
                        StartTrackingSession(e);
                    }
                }
            }
Exemple #14
0
        void SubjectBufferChangedLowPriority(object sender, TextContentChangedEventArgs e) {
            var session = _curSession;
            if (session == null || session.IsDismissed) {
                return;
            }

            session.Dismiss();
            Interlocked.CompareExchange(ref _curSession, null, session);
        }
            private void OnTextBufferChanged(object sender, TextContentChangedEventArgs e)
            {
                if (e.Changes.Count == 0)
                {
                    return;
                }

                this.RaiseChanged();
            }
Exemple #16
0
 internal TaggerEventArgs(
     string kind,
     TaggerDelay delay,
     TextContentChangedEventArgs textChangeEventArgs = null)
 {
     this.Kind = kind;
     this.Delay = delay;
     this.TextChangeEventArgs = textChangeEventArgs;
 }
 private void SourceTextChanged(object sender, TextContentChangedEventArgs e)
 {
     if (this.enabled && e.Changes.Count > 0)
     {
         ITextChange firstChange = e.Changes[0];
         ITextChange lastChange = e.Changes[e.Changes.Count - 1];
         SnapshotSpan changedSpan = new SnapshotSpan(e.After, Span.FromBounds(firstChange.NewSpan.Start, lastChange.NewSpan.End));
         UpdateAfterChange(changedSpan);
     }
 }
Exemple #18
0
        private void TextBufferChanged(object sender, TextContentChangedEventArgs changed) {
            RemoveExistingHighlights();

            if (changed.Changes.Count == 1) {
                var newText = changed.Changes[0].NewText;
                if (newText == ")" || newText == "}" || newText == "]") {
                    UpdateBraceMatching(changed.Changes[0].NewPosition + 1);
                }
            }
        }
        void OnTextBufferChanged(object sender, TextContentChangedEventArgs e)
        {
            var handler = this.ClassificationChanged;
            if (handler != null)
            {
                // For now raise the event for the entire changed buffer.
                var span = new SnapshotSpan(_buffer.CurrentSnapshot, 0, _buffer.CurrentSnapshot.Length);

                handler(this, new ClassificationChangedEventArgs(span));
            }
        }
        public void OnTextChange(object sender, TextContentChangedEventArgs args)
        {
            List<TextChangeData> changeData = new List<TextChangeData>();

            foreach (var change in args.Changes)
            {
                changeData.Add(new TextChangeData(change.OldPosition, change.Delta, Math.Max(change.NewSpan.Length, change.OldSpan.Length)));
            }

            _bufferTextChangeHandler.OnTextChanged(changeData);
        }
        protected virtual void OnTextBufferChanged(object sender, TextContentChangedEventArgs e) {
            // In order to provide nicer experience when user presser and holds
            // ENTER or DELETE or just types really fast, we are going to track
            // regions optimistically and report changes without going through
            // async or idle processing. Idle/async is still going to hit later.

            if (e.Changes.Count > 0) {
                int start, oldLength, newLength;
                TextUtility.CombineChanges(e, out start, out oldLength, out newLength);

                int changeStart = Int32.MaxValue;
                int changeEnd = 0;

                lock (_regionsLock) {
                    // Remove affected regions and shift the remaining ones. Outlining 
                    // regions are not sorted and can overlap. Hence linear search.

                    for (int i = 0; i < CurrentRegions.Count; i++) {
                        var region = CurrentRegions[i];

                        if (region.End <= start) {
                            continue;
                        }

                        if (region.Contains(start) && region.Contains(start + oldLength)) {
                            region.Expand(0, newLength - oldLength);
                        } else if (region.Start >= start + oldLength) {
                            region.Shift(newLength - oldLength);
                        } else {
                            changeStart = Math.Min(changeStart, region.Start);
                            changeEnd = Math.Max(changeEnd, region.End);

                            CurrentRegions.RemoveAt(i);
                            i--;

                            if (e.Changes.Count > 0) {
                                // If we merged changes, this might be an overaggressive delete. Ensure
                                //   that we'll do a full recalculation later.
                                BackgroundTask.DoTaskOnIdle();
                            }
                        }
                    }
                }

                // If there were previously any regions, make sure we notify our listeners of the changes
                if ((CurrentRegions.Count > 0) || (changeStart < Int32.MaxValue)) {
                    CurrentRegions.TextBufferVersion = TextBuffer.CurrentSnapshot.Version.VersionNumber;
                    if (RegionsChanged != null) {
                        changeEnd = (changeStart == Int32.MaxValue ? changeStart : changeEnd);
                        RegionsChanged(this, new OutlineRegionsChangedEventArgs(CurrentRegions, TextRange.FromBounds(changeStart, changeEnd)));
                    }
                }
            }
        }
Exemple #22
0
 private void OnTextBufferChanged(object sender, TextContentChangedEventArgs e) {
     if(!_changed && _tree.AstRoot != null) {
         foreach(var c in e.Changes) {
             if(c.OldText.IndexOf('-') >= 0 || c.NewText.IndexOf('-') >= 0) {
                 if (_tree.AstRoot.Comments.GetItemContaining(c.OldPosition) >= 0) {
                     _changed = true;
                     break;
                 }
             }
         }
     }
 }
 private void OnTextBufferChanged(object sender, TextContentChangedEventArgs e)
 {
     var buffer = sender as ITextBuffer;
     if (buffer != null)
     {
         var snapshot = _latestReiteratedVersionSnapshot;
         if (snapshot != null && snapshot.Version != null && e.AfterVersion != null &&
             snapshot.Version.ReiteratedVersionNumber < e.AfterVersion.ReiteratedVersionNumber)
         {
             _latestReiteratedVersionSnapshot = e.After;
         }
     }
 }
        void TextBuffer_Changed(object sender, TextContentChangedEventArgs args)
        {
            var textBuffer = (ITextBuffer)sender;
            string filePath = textBuffer.GetFilePath();// textBuffer.ToIVsTextBuffer().GetFilePath();

            var project = GetProjectInfo(filePath);
            if (project == null)
                return;

            project.Engine.RequestOnBuildTypesTree();

            //System.Diagnostics.Trace.WriteLine("Changed: (" + args.AfterVersion + ") " + filePath);
        }
Exemple #25
0
 public void ApplyTextChanges(TextContentChangedEventArgs args)
 {
     try
     {
         ApplyTextChange(args.Before, args.After, new JoinedTextChange(args.Changes));
     }
     catch(Exception ex)
     {
         Utils.PrintToOutput("Exception during parsing:\n{0}", ex.Message);
         Initialize();
         RaiseTokensChanged(tree.ToList());
     }
 }
		private bool IsMultiLineChange(TextContentChangedEventArgs e) {
			return e.Changes.Any(change => {
				return multiLinesSigTexts.Any(sigText => {
					var len1 = sigText.Length - 1;
					var beforeStart = Math.Max(0, change.OldPosition - len1);
					var beforeEnd = Math.Min(e.Before.Length, change.OldPosition + change.OldLength + len1);
					var textOld = beforeEnd > beforeStart ? e.Before.GetText(beforeStart, beforeEnd - beforeStart) : "";
					var afterStart = Math.Max(0, change.NewPosition - len1);
					var afterEnd = Math.Min(e.After.Length, change.NewPosition + change.NewLength + len1);
					var textNew = afterEnd > afterStart ? e.After.GetText(afterStart, afterEnd - afterStart) : "";
					return textOld.Contains(sigText) || textNew.Contains(sigText);
				});
			});
		}
        void TextBuffer_Changed(object sender, TextContentChangedEventArgs args)
        {
            var textBuffer = (ITextBuffer)sender;
            string filePath = textBuffer.GetFilePath();// textBuffer.ToIVsTextBuffer().GetFilePath();

            var project = ProjectInfo.FindProject(filePath);
            if (project == null)
                return;

            var fileIndex = Location.GetFileIndex(filePath);
            var text = args.After.GetText();
            project.Engine.NotifySourceChanged(new StringSource(fileIndex, text));

            //System.Diagnostics.Trace.WriteLine("Changed: (" + args.AfterVersion + ") " + filePath);
        }
        protected virtual void OnTextBufferChanged(object sender, TextContentChangedEventArgs e) {
            // In order to provide nicer experience when user presser and holds
            // ENTER or DELETE or just types really fast, we are going to track
            // regions optimistically and report changes without going through
            // async or idle processing. Idle/async is still going to hit later.

            if (e.Changes.Count > 0) {
                int start, oldLength, newLength;
                TextUtility.CombineChanges(e, out start, out oldLength, out newLength);

                int changeStart = Int32.MaxValue;
                int changeEnd = 0;

                lock (_regionsLock) {
                    // Remove affected regions and shift the remaining ones. Outlining 
                    // regions are not sorted and can overlap. Hence linear search.

                    for (int i = 0; i < CurrentRegions.Count; i++) {
                        var region = CurrentRegions[i];

                        if (region.End <= start) {
                            continue;
                        }

                        if (region.Contains(start) && region.Contains(start + oldLength)) {
                            region.Expand(0, newLength - oldLength);
                        } else if (region.Start >= start + oldLength) {
                            region.Shift(newLength - oldLength);
                        } else {
                            CurrentRegions.RemoveAt(i);
                            i--;
                        }

                        changeStart = Math.Min(changeStart, region.Start);
                        changeEnd = Math.Max(changeEnd, region.End);
                    }

                    if (changeStart < Int32.MaxValue)
                        CurrentRegions.TextBufferVersion = TextBuffer.CurrentSnapshot.Version.VersionNumber;
                }

                if (changeStart < Int32.MaxValue) {
                    if (RegionsChanged != null)
                        RegionsChanged(this, new OutlineRegionsChangedEventArgs(CurrentRegions, TextRange.FromBounds(changeStart, changeEnd)));

                }
            }
        }
Exemple #29
0
 protected override void OnTextBufferChanged(object sender, TextContentChangedEventArgs e) {
     var changes = e.ConvertToRelative();
     foreach (var c in changes) {
         var destructive = _separators.IsDestructiveChange(c.OldStart, c.OldLength, c.NewLength, c.OldText, c.NewText);
         if (destructive) {
             // Allow existing command call to complete so we don't yank projections
             // from underneath code that expects text buffer to exist, such as formatter.
             IdleTimeAction.Cancel(GetType());
             IdleTimeAction.Create(UpdateProjections, 0, GetType(), _coreShell);
             break;
         } else {
             Blocks.ReflectTextChange(c.OldStart, c.OldLength, c.NewLength);
             _separators.ReflectTextChange(c.OldStart, c.OldLength, c.NewLength);
         }
     }
 }
            private void OnTextBufferChanged(object sender, TextContentChangedEventArgs e)
            {
                if (e.Changes.Count == 0)
                {
                    return;
                }

                if (_reportChangedSpans)
                {
                    this.RaiseChanged(e);
                }
                else
                {
                    this.RaiseChanged();
                }
            }
Exemple #31
0
 protected abstract void OnTextBufferChanged(object sender, TextContentChangedEventArgs e);
Exemple #32
0
 void TextBuffer_ChangedLowPriority(object sender, TextContentChangedEventArgs e) => UpdateCachedState();
Exemple #33
0
 void TextBuffer_ChangedLowPriority(object sender, TextContentChangedEventArgs e) => Refilter();
 private void OnTextBufferChanged(object sender, TextContentChangedEventArgs e)
 {
     e.Changes.ToList().ForEach(change => changes.Append(change.OldText));
 }
 void TextBuffer_ChangedLowPriority(object?sender, TextContentChangedEventArgs e) => UpdateMaxLineDigits();
Exemple #36
0
 internal static TextChangeEventArgs ToTextChangeEventArgs(this TextContentChangedEventArgs e) =>
 new TextChangeEventArgs(e.Before.AsText(), e.After.AsText(), e.Changes.ToTextChangeRange());
 private void OnDocumentChanged(object sender, TextContentChangedEventArgs e)
 {
     updaterDocument.Stop();
     updaterDocument.Start();
 }
 /// <summary>
 /// Called when the contents of the text buffer change.
 /// </summary>
 /// <param name="sender">The object that raised the event.</param>
 /// <param name="e">A <see cref="TextContentChangedEventArgs"/> that contains the event data.</param>
 public abstract void OnBufferChanged(Object sender, TextContentChangedEventArgs e);
            private void OnTextBufferChanged(object sender, TextContentChangedEventArgs args)
            {
                AssertIsForeground();

                // This might be an event fired due to our own edit
                if (args.EditTag == s_propagateSpansEditTag || _session._isApplyingEdit)
                {
                    return;
                }

                using (
                    Logger.LogBlock(FunctionId.Rename_OnTextBufferChanged, CancellationToken.None)
                    )
                {
                    var trackingSpansAfterEdit = new NormalizedSpanCollection(
                        GetEditableSpansForSnapshot(args.After).Select(ss => (Span)ss)
                        );
                    var spansTouchedInEdit = new NormalizedSpanCollection(
                        args.Changes.Select(c => c.NewSpan)
                        );

                    var intersectionSpans = NormalizedSpanCollection.Intersection(
                        trackingSpansAfterEdit,
                        spansTouchedInEdit
                        );
                    if (intersectionSpans.Count == 0)
                    {
                        // In Razor we sometimes get formatting changes during inline rename that
                        // do not intersect with any of our spans. Ideally this shouldn't happen at
                        // all, but if it does happen we can just ignore it.
                        return;
                    }

                    // Cases with invalid identifiers may cause there to be multiple intersection
                    // spans, but they should still all map to a single tracked rename span (e.g.
                    // renaming "two" to "one two three" may be interpreted as two distinct
                    // additions of "one" and "three").
                    var boundingIntersectionSpan = Span.FromBounds(
                        intersectionSpans.First().Start,
                        intersectionSpans.Last().End
                        );
                    var trackingSpansTouched = GetEditableSpansForSnapshot(args.After)
                                               .Where(ss => ss.IntersectsWith(boundingIntersectionSpan));
                    Debug.Assert(trackingSpansTouched.Count() == 1);

                    var singleTrackingSpanTouched = trackingSpansTouched.Single();
                    _activeSpan =
                        _referenceSpanToLinkedRenameSpanMap
                        .Where(
                            kvp =>
                            kvp.Value.TrackingSpan
                            .GetSpan(args.After)
                            .Contains(boundingIntersectionSpan)
                            )
                        .Single().Key;
                    _session.UndoManager.OnTextChanged(
                        this.ActiveTextView.Selection,
                        singleTrackingSpanTouched
                        );
                }
            }
 private void OnSubjectBufferChanged(object sender, TextContentChangedEventArgs e)
 {
     // Whenever this subject buffer has changed, we always consider that to be a
     // semantic change.
     this.RaiseChanged();
 }
Exemple #41
0
 private void OnTextBufferChanged(object sender, TextContentChangedEventArgs e) => _semanticModel = null;
Exemple #42
0
        /// <summary>
        /// Find all of the tag regions in the document (snapshot) and notify
        /// listeners of any that changed
        /// </summary>
        void ReparseFile(object sender, TextContentChangedEventArgs args)
        {
            ITextSnapshot snapshot = _buffer.CurrentSnapshot;

            if (snapshot == _snapshot)
            {
                return; // we've already computed the regions for this snapshot
            }
            NormalizedSnapshotSpanCollection difference = new NormalizedSnapshotSpanCollection();
            ScanResult result;

            if (_buffer.Properties.TryGetProperty(bufferTokenTaggerKey, out result) &&
                (result._oldSnapshot == _snapshot) &&
                (result._newSnapshot == snapshot))
            {
                difference = result._difference;
                // save the new baseline
                _regions  = result._regions;
                _snapshot = snapshot;
            }
            else
            {
                List <TokenRegion>  regions          = new List <TokenRegion>();
                List <SnapshotSpan> rescannedRegions = new List <SnapshotSpan>();

                // loop through the changes and check for changes in comments first. If
                // the change is in a comments, we need to rescan starting from the
                // beginning of the comments (which in multi-lined comments, it can
                // be a line that the changes are not on), otherwise, we can just rescan the lines
                // that the changes are on.
                bool          done;
                SnapshotPoint start, end;
                for (int i = 0; i < args.Changes.Count; i++)
                {
                    done = false;
                    // get the span of the lines that the change is on.
                    int cStart = args.Changes[i].NewSpan.Start;
                    int cEnd   = args.Changes[i].NewSpan.End;
                    start = snapshot.GetLineFromPosition(cStart).Start;
                    end   = snapshot.GetLineFromPosition(cEnd).End;
                    SnapshotSpan newSpan = new SnapshotSpan(start, end);
                    foreach (TokenRegion r in _regions)
                    {
                        if (r.Kind == DafnyTokenKind.Comment)
                        {
                            // if the change is in the comments, we want to start scanning from the
                            // the beginning of the comments instead.
                            SnapshotSpan span = r.Span.TranslateTo(snapshot, SpanTrackingMode.EdgeExclusive);
                            if (span.IntersectsWith(newSpan))
                            {
                                start = span.Start.Position < newSpan.Start.Position ? span.Start : newSpan.Start;
                                end   = span.End.Position > newSpan.End.Position ? span.End : newSpan.End;
                                end   = Scan(snapshot.GetText(new SnapshotSpan(start, end)), start, regions, snapshot);
                                // record the regions that we rescanned.
                                rescannedRegions.Add(new SnapshotSpan(start, end));
                                done = true;
                                break;
                            }
                        }
                    }
                    if (!done)
                    {
                        // scan the lines that the change is on to generate the new regions.
                        end = Scan(snapshot.GetText(new SnapshotSpan(start, end)), start, regions, snapshot);
                        // record the span that we rescanned.
                        rescannedRegions.Add(new SnapshotSpan(start, end));
                    }
                }

                List <SnapshotSpan> oldSpans = new List <SnapshotSpan>();
                List <SnapshotSpan> newSpans = new List <SnapshotSpan>();
                // record the newly created spans.
                foreach (TokenRegion r in regions)
                {
                    newSpans.Add(r.Span);
                }
                // loop through the old scan results and remove the ones that
                // are in the regions that are rescanned.
                foreach (TokenRegion r in _regions)
                {
                    SnapshotSpan origSpan = r.Span.TranslateTo(snapshot, SpanTrackingMode.EdgeExclusive);
                    bool         obsolete = false;
                    foreach (SnapshotSpan span in rescannedRegions)
                    {
                        if (origSpan.IntersectsWith(span))
                        {
                            oldSpans.Add(span);
                            obsolete = true;
                            break;
                        }
                    }
                    if (!obsolete)
                    {
                        TokenRegion region = new TokenRegion(origSpan.Start, origSpan.End, r.Kind);
                        regions.Add(region);
                    }
                }

                NormalizedSnapshotSpanCollection oldSpanCollection = new NormalizedSnapshotSpanCollection(oldSpans);
                NormalizedSnapshotSpanCollection newSpanCollection = new NormalizedSnapshotSpanCollection(newSpans);
                difference = SymmetricDifference(oldSpanCollection, newSpanCollection);

                // save the scan result
                _buffer.Properties[bufferTokenTaggerKey] = new ScanResult(_snapshot, snapshot, regions, difference);
                // save the new baseline
                _snapshot = snapshot;
                _regions  = regions;
            }

            var chng = TagsChanged;

            if (chng != null)
            {
                foreach (var span in difference)
                {
                    chng(this, new SnapshotSpanEventArgs(span));
                }
            }
        }
Exemple #43
0
 void TextBuffer_Changed(object?sender, TextContentChangedEventArgs e) =>
 realTextChangedEvent?.Invoke(this, e.ToTextChangeEventArgs());
 private void OnSubjectBufferChanged(object sender, TextContentChangedEventArgs e)
 {
     _workQueue.AssertIsForeground();
     UpdateTagsForTextChange(e);
     AccumulateTextChanges(e);
 }
Exemple #45
0
 internal void OnSubjectBufferChanged(object sender, TextContentChangedEventArgs e)
 {
     this.ComputeCurrentParameter();
 }
Exemple #46
0
 private void Buffer_Changed(object sender, TextContentChangedEventArgs e)
 {
     timer.Stop();
     AsyncParse(e.After);
 }
Exemple #47
0
        protected virtual void OnTextBufferChanged(object sender, TextContentChangedEventArgs e)
        {
            // In order to provide nicer experience when user presser and holds
            // ENTER or DELETE or just types really fast, we are going to track
            // regions optimistically and report changes without going through
            // async or idle processing. Idle/async is still going to hit later.

            if (e.Changes.Count > 0)
            {
                int start, oldLength, newLength;
                TextUtility.CombineChanges(e, out start, out oldLength, out newLength);

                var changeStart = Int32.MaxValue;
                var changeEnd   = 0;

                lock (this._regionsLock)
                {
                    // Remove affected regions and shift the remaining ones. Outlining
                    // regions are not sorted and can overlap. Hence linear search.

                    for (var i = 0; i < this.CurrentRegions.Count; i++)
                    {
                        var region = this.CurrentRegions[i];

                        if (region.End <= start)
                        {
                            continue;
                        }

                        if (region.Contains(start) && region.Contains(start + oldLength))
                        {
                            region.Expand(0, newLength - oldLength);
                        }
                        else if (region.Start >= start + oldLength)
                        {
                            region.Shift(newLength - oldLength);
                        }
                        else
                        {
                            this.CurrentRegions.RemoveAt(i);
                            i--;
                        }

                        changeStart = Math.Min(changeStart, region.Start);
                        changeEnd   = Math.Max(changeEnd, region.End);
                    }

                    if (changeStart < Int32.MaxValue)
                    {
                        this.CurrentRegions.TextBufferVersion = this.TextBuffer.CurrentSnapshot.Version.VersionNumber;
                    }
                }

                if (changeStart < Int32.MaxValue)
                {
                    if (this.RegionsChanged != null)
                    {
                        this.RegionsChanged(this, new OutlineRegionsChangedEventArgs(this.CurrentRegions, TextRange.FromBounds(changeStart, changeEnd)));
                    }
                }
            }
        }
Exemple #48
0
 public bool MyOwnChanges(TextContentChangedEventArgs args)
 {
     return(args.EditTag == s_propagateSpansEditTag);
 }
Exemple #49
0
        internal void RawRaiseEvent(TextContentChangedEventArgs args, bool immediate)
        {
            if (immediate)
            {
                EventHandler <TextContentChangedEventArgs> immediateHandler = ChangedImmediate;
                if (immediateHandler != null)
                {
                    if (BaseBuffer.eventTracing)
                    {
                        Debug.WriteLine("<<< Imm  events from " + ToString());
                    }
                    immediateHandler(this, args);
                }
                return;
            }

            EventHandler <TextContentChangedEventArgs> highHandler = ChangedHighPriority;
            EventHandler <TextContentChangedEventArgs> medHandler  = Changed;
            EventHandler <TextContentChangedEventArgs> lowHandler  = ChangedLowPriority;
            EventHandler <TextContentChangedEventArgs> changedOnBackgroundHandler = ChangedOnBackground;

            BaseBuffer.eventDepth++;
            string indent = BaseBuffer.eventTracing ? new String(' ', 3 * (BaseBuffer.eventDepth - 1)) : null;

            if (highHandler != null)
            {
                if (BaseBuffer.eventTracing)
                {
                    Debug.WriteLine(">>> " + indent + "High events from " + ToString());
                }
                this.guardedOperations.RaiseEvent(this, highHandler, args);
            }
            if (changedOnBackgroundHandler != null)
            {
                if (BaseBuffer.eventTracing)
                {
                    Debug.WriteLine(">>> " + indent + "background events from " + ToString());
                }

                // As this is a background event, we need to make sure handlers are executed synchronized
                // and in the order the edits were applied.
                // TODO: with this implementation any handler might delay all subsequent handlers.
                // That's true for other Changed* events too, but this event is raised on a background thread
                // so introducing delays in a handler won't be that easily noticable, also being on a
                // background thread might suggest it's actually ok to perform some long running
                // calculation directly in the  handler.
                // For isolation purposes we need a chain of tasks per handler, or some other, more
                // optimized isolation strategy. Tracked by #449694.
                _lastChangeOnBackgroundRaisedEvent = _lastChangeOnBackgroundRaisedEvent
                                                     .ContinueWith(_ =>
                {
                    // changedOnBackgroundHandler might be stale at this point, get the latest list of handlers
                    var currentChangedOnBackgroundHandler = ChangedOnBackground;
                    if (currentChangedOnBackgroundHandler != null)
                    {
                        this.guardedOperations.RaiseEvent(this, currentChangedOnBackgroundHandler, args);
                    }
                },
                                                                   CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Default);
                // Now register pending task with task tracker to ensure it's completed when editor host is shutdown
                this.guardedOperations.NonJoinableTaskTracker?.Register(_lastChangeOnBackgroundRaisedEvent);
            }
            if (medHandler != null)
            {
                if (BaseBuffer.eventTracing)
                {
                    Debug.WriteLine(">>> " + indent + "Med  events from " + ToString());
                }
                this.guardedOperations.RaiseEvent(this, medHandler, args);
            }
            if (lowHandler != null)
            {
                if (BaseBuffer.eventTracing)
                {
                    Debug.WriteLine(">>> " + indent + "Low  events from " + ToString());
                }
                this.guardedOperations.RaiseEvent(this, lowHandler, args);
            }
            BaseBuffer.eventDepth--;
        }
Exemple #50
0
 /// <summary>
 /// Re-parses the document whenever it changes.
 /// </summary>
 private void OnBufferChanged(object sender, TextContentChangedEventArgs e)
 {
     ParseDocument();
 }
Exemple #51
0
 private void Buffer_TextContentChangedLowPriority(object sender, TextContentChangedEventArgs e)
 {
     Trace("TextContentChangedLowPriority");
     InvokeSinks(new PythonTextBufferInfoNestedEventArgs(PythonTextBufferInfoEvents.TextContentChangedLowPriority, e));
 }
 private void OnBufferChanged(object sender, TextContentChangedEventArgs e)
 {
     _actionThrottler.TriggerAction();
 }
Exemple #53
0
 private void Buffer_Changed(object sender, TextContentChangedEventArgs e)
 {
     this._delay.Reset();
 }
        private void HandleBufferChanged(object sender, TextContentChangedEventArgs args)
        {
            var editedSpans = args.Changes.Select(change => new SnapshotSpan(args.After, change.NewSpan)).ToList();

            InvalidateSpans(editedSpans);
        }
 private void NonRoslynTextBuffer_Changed(object sender, TextContentChangedEventArgs e)
 => _documentTracker.NonRoslynBufferTextChanged?.Invoke(_documentTracker, EventArgs.Empty);
 private void OnSubjectBufferChanged(object?_, TextContentChangedEventArgs e)
 {
     this.AssertIsForeground();
     UpdateTagsForTextChange(e);
     AccumulateTextChanges(e);
 }
Exemple #57
0
            private void Buffer_Changed(object sender, TextContentChangedEventArgs e)
            {
                if (e.Changes.Count == 0)
                {
                    return;
                }
                //throw new NotImplementedException();
                Snapshot = e.After;

                // Update the already changed regions
                Span invalidateRange = e.Changes[0].NewSpan; // All fold regions contained here will be deleted and reparsed

                foreach (ITextChange change in e.Changes)
                {
                    // expand invalidateRange to include change.NewSpan
                    invalidateRange = invalidateRange.Union(change.NewSpan);

                    // - Fix up starts and lengths of spans before/after/around
                    // - Invalidate spans intersecting
                    for (int r = Regions.Count - 1; r >= 0; r--)
                    {
                        FoldRegion region = Regions[r];
                        if (region.StartIndex < change.OldPosition)
                        {
                            // Starts before the change - check end position
                            if (region.StartIndex + region.Length < change.OldPosition)
                            {
                                // Ends before the change - do nothing
                            }
                            else if (region.StartIndex + region.Length - region.ClosingTokenLength > change.OldEnd)
                            {
                                // Ends after the change - adjust length
                                region.Length += change.Delta;
                            }
                            else
                            {
                                // Ends during the change - delete and invalidate
                                Regions.RemoveAt(r);
                                invalidateRange = invalidateRange.Union(new Span(region.StartIndex, region.Length));
                            }
                        }
                        else if (region.StartIndex >= change.OldEnd)
                        {
                            // Starts after the change - adjust start
                            region.StartIndex += change.Delta;
                        }
                        else
                        {
                            // Starts in the change - delete and invalidate
                            Regions.RemoveAt(r);
                            invalidateRange = invalidateRange.Union(new Span(region.StartIndex, region.Length));
                        }
                    }

                    // Check to see if we just added a tail part to a now-valid folding region, and if we did, seek upwards until we find the corresponding top.
                    for (int line = Snapshot.GetLineNumberFromPosition(change.NewPosition); line <= Snapshot.GetLineNumberFromPosition(change.NewEnd); line++)
                    {
                        string       lineText   = Snapshot.GetLineFromLineNumber(line).GetText();
                        List <Token> lineTokens = Lexer.Lex(lineText);
                        if (lineTokens.Count > 0 && lineTokens[0].Type == TokenType.Keyword && lineTokens[0].Content == "end")
                        {
                            if (lineTokens[0].Content == "end")
                            {
                                // Scan upwards until we find a matching begin, or the beginning of the file.
                                int startLine = line - 1;
                                int endCount  = 1; // increase by one for every end that we pass, and decrease for every begin.
                                while (startLine >= 0 && endCount > 0)
                                {
                                    string       startLineText   = Snapshot.GetLineFromLineNumber(startLine).GetText();
                                    List <Token> startLineTokens = Lexer.Lex(startLineText);
                                    if (startLineTokens.Count > 0 && startLineTokens[0].Type == TokenType.Keyword)
                                    {
                                        if (startLineTokens[0].Content == "end")
                                        {
                                            endCount++;
                                        }
                                        else if (startLineTokens[0].Content == "begin")
                                        {
                                            endCount--;
                                        }
                                    }
                                    startLine--;
                                }
                                startLine++;
                                int start = Snapshot.GetLineFromLineNumber(startLine).Start.Position;
                                int end   = Snapshot.GetLineFromLineNumber(line).End.Position;

                                invalidateRange = invalidateRange.Union(new Span(start, end - start));
                            }
                            else if (lineTokens[0].Content == "begin")
                            {
                                // Scan downwards until we find a matching end, or the end of the file.
                                int endLine    = line + 1;
                                int beginCount = 1;
                                while (endLine < Snapshot.LineCount && beginCount > 0)
                                {
                                    string       endLineText   = Snapshot.GetLineFromLineNumber(endLine).GetText();
                                    List <Token> endLineTokens = Lexer.Lex(endLineText);
                                    if (endLineTokens.Count > 0 && endLineTokens[0].Type == TokenType.Keyword)
                                    {
                                        if (endLineTokens[0].Content == "begin")
                                        {
                                            beginCount++;
                                        }
                                        else if (endLineTokens[0].Content == "end")
                                        {
                                            beginCount--;
                                        }
                                    }
                                    endLine++;
                                }
                                endLine--;
                                int start = Snapshot.GetLineFromLineNumber(line).Start.Position;
                                int end   = Snapshot.GetLineFromLineNumber(endLine).End.Position;

                                invalidateRange = invalidateRange.Union(new Span(start, end - start));
                            }
                        }
                    }
                }

                // Make sure we don't invalidate past the end of the file (can be caused by killing fold regions that were where we would now consider out of bounds)
                if (invalidateRange.End > Snapshot.Length)
                {
                    invalidateRange = new Span(invalidateRange.Start, Snapshot.Length - invalidateRange.Start);
                }

                Parse(invalidateRange);
            }
Exemple #58
0
 private void TextBufferChanged(object sender, TextContentChangedEventArgs e)
 {
     // Clear all error tags from all files
     _currentSnapshot = _buffer.CurrentSnapshot;
     _errorBuilder.ClearErrors();
 }
Exemple #59
0
 void OnTextBufferChanged(object sender, TextContentChangedEventArgs e)
 {
     // keep the list of errors updated every time the buffer changes
     CreateErrors();
 }
Exemple #60
0
 void buffer_Changed(object sender, TextContentChangedEventArgs e)
 {
     IsUpdated = true;
 }