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); } } }
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(); }
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); } }
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))); } } } }
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); }
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))); } } }
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(); } }
protected abstract void OnTextBufferChanged(object sender, TextContentChangedEventArgs e);
void TextBuffer_ChangedLowPriority(object sender, TextContentChangedEventArgs e) => UpdateCachedState();
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();
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(); }
private void OnTextBufferChanged(object sender, TextContentChangedEventArgs e) => _semanticModel = null;
/// <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)); } } }
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); }
internal void OnSubjectBufferChanged(object sender, TextContentChangedEventArgs e) { this.ComputeCurrentParameter(); }
private void Buffer_Changed(object sender, TextContentChangedEventArgs e) { timer.Stop(); AsyncParse(e.After); }
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))); } } } }
public bool MyOwnChanges(TextContentChangedEventArgs args) { return(args.EditTag == s_propagateSpansEditTag); }
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--; }
/// <summary> /// Re-parses the document whenever it changes. /// </summary> private void OnBufferChanged(object sender, TextContentChangedEventArgs e) { ParseDocument(); }
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(); }
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); }
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); }
private void TextBufferChanged(object sender, TextContentChangedEventArgs e) { // Clear all error tags from all files _currentSnapshot = _buffer.CurrentSnapshot; _errorBuilder.ClearErrors(); }
void OnTextBufferChanged(object sender, TextContentChangedEventArgs e) { // keep the list of errors updated every time the buffer changes CreateErrors(); }
void buffer_Changed(object sender, TextContentChangedEventArgs e) { IsUpdated = true; }