/// <summary> /// On text change, check for the /** /// </summary> private void OnTextChanged(object sender, TextContentChangedEventArgs e) { try { if (!StubUtils.Options.TypeScriptCommentExtensionEnabled) { return; } INormalizedTextChangeCollection changes = e.Changes; foreach (ITextChange change in changes) { if (CurrentTypedCharacterIs(change, "*") && PeviewTextTypedIs(change, "/*")) { CreateMethodComment(change); } if (change.OldText.Trim() == "/**") { //Move the caret back at the comment description int lineNumber = this.view.TextSnapshot.GetLineNumberFromPosition(change.NewPosition) + 2; //2 because we want to be inside the comment var lineSnapShotPoint = this.view.TextSnapshot.GetLineFromPosition(change.NewPosition - 1).Start; this.view.Caret.MoveTo(lineSnapShotPoint); } } } catch (Exception ex) { Console.WriteLine(ERROR_MSG_PREFIX + ex.Message); } }
public JoinedTextChange(INormalizedTextChangeCollection changes) { int oldStart = changes[0].OldSpan.Start; int oldEnd = changes[changes.Count - 1].OldEnd; oldS = new Span(oldStart, oldEnd); delta = changes[changes.Count - 1].NewEnd - changes[changes.Count - 1].OldEnd; }
public static INormalizedTextChangeCollection Create(IList <TextChange> changes, StringDifferenceOptions?differenceOptions, ITextDifferencingService textDifferencingService, ITextSnapshot before = null, ITextSnapshot after = null) { INormalizedTextChangeCollection result = GetTrivialCollection(changes); return(result != null ? result : new NormalizedTextChangeCollection(changes, differenceOptions, textDifferencingService, before, after)); }
void VisualBuffer_Changed(object sender, TextContentChangedEventArgs e) { INormalizedTextChangeCollection a = e.Changes; changes.Add(e); // NeedsDisplay = true; }
private void UpdateBraceList(ITextSnapshot snapshot, INormalizedTextChangeCollection changes) { bool notify = true; var startPoint = new SnapshotPoint(snapshot, changes[0].NewSpan.Start); UpdateBraceList(startPoint, notify); }
//Microsoft.VisualStudio.Text.Impl /// <summary> /// On text change, check for the /// comment. /// </summary> private void OnTextChanged(object sender, TextContentChangedEventArgs e) { try { if (!StubUtils.Options.JSDocEnabled) { return; } INormalizedTextChangeCollection changes = e.Changes; foreach (ITextChange change in changes) { if (change.NewText.EndsWith("*") && LineIsJSDocOpening(change.OldEnd)) { CreateStub(change.NewEnd, change); } else if (StubUtils.Options.AutoNewLine && StubUtils.Options.UseAsterisk && change.NewText.EndsWith(Environment.NewLine)) { CreateNewCommentLine(change); } } } catch (Exception ex) { Console.WriteLine(errorMsgPrefix + ex.Message); } }
/// <summary> /// Constructs a TextBufferChangeUndoPrimitive. /// </summary> /// <param name="undoHistory"> /// The ITextUndoHistory this change will be added to. /// </param> /// <param name="textVersion"> /// The <see cref="ITextVersion" /> representing this change. /// This is actually the version associated with the snapshot prior to the change. /// </param> /// <exception cref="ArgumentNullException"><paramref name="undoHistory"/> is null.</exception> /// <exception cref="ArgumentNullException"><paramref name="textVersion"/> is null.</exception> public TextBufferChangeUndoPrimitive(ITextUndoHistory undoHistory, ITextVersion textVersion) { // Verify input parameters if (undoHistory == null) { throw new ArgumentNullException("undoHistory"); } if (textVersion == null) { throw new ArgumentNullException("textVersion"); } _textChanges = textVersion.Changes; _beforeVersion = textVersion.ReiteratedVersionNumber; _afterVersion = textVersion.Next.VersionNumber; Debug.Assert(textVersion.Next.VersionNumber == textVersion.Next.ReiteratedVersionNumber, "Creating a TextBufferChangeUndoPrimitive for a change that has previously been undone? This is probably wrong."); _undoHistory = undoHistory; TextBuffer = textVersion.TextBuffer; AttachedToNewBuffer = false; _canUndo = true; #if DEBUG // for debug sanity checks _bufferLengthAfterChange = textVersion.Next.Length; #endif }
/// <summary> /// Method calculates the span from the start of the editor changes and until the end of TagSpans /// </summary> private SnapshotSpan CalculateSpanOfChanges(INormalizedTextChangeCollection changeCollection, ITextSnapshot newTextSnapshot) { var startSpans = changeCollection.Select(x => x.NewSpan).ToArray(); var endSpans = TagSpans.Select(x => x.Span.Span); return(CalculateAffectedSpan(newTextSnapshot, startSpans, endSpans)); }
/// <summary> /// Purge any TagSpans that intersect in any way with the text changes, then update all spans /// </summary> public void PurgeAndUpdate(INormalizedTextChangeCollection textChanges, ITextSnapshot textSnapshot) { Span = Span.Translated(SpanTrackingMode.EdgeExclusive, textSnapshot); var fullChangeSpan = new Span(textChanges.First().NewSpan.Start, textChanges.Last().NewSpan.End); // Purge ALL TagSpans from any statements that intersect with these text changes if (Span.IntersectsWith(fullChangeSpan)) { // Now check more incrementally if (textChanges.Any(t => Span.IntersectsWith(t.NewSpan))) { TagSpans.Clear(); } } /*for (var i = TagSpans.Count - 1; i >= 0; i--) * { * var tagSpan = TagSpans[i]; * tagSpan.Translate(textSnapshot); * * if (tagSpan.Span.IntersectsWith(fullChangeSpan)) * { * // Now check more incrementally * if (textChanges.Any(t => tagSpan.Span.IntersectsWith(t.NewSpan))) * { * // Remove this tagspan! * TagSpans.RemoveAt(i); * } * } * }*/ }
void CaretPositionChanged(object sender, CaretPositionChangedEventArgs args) { if (!AlwaysAlignedConfigurationService.Instance.Config.Enabled) { return; } if (_lastChange == null) { return; } if (!_textView.Caret.InVirtualSpace) { _lastChange = null; return; } var rtCount = Math.Max(_textView.Caret.Position.VirtualSpaces / _textView.FormattedLineSource.TabSize, 0); var rtEdit = _textView.TextBuffer.CreateEdit(); rtEdit.Insert(_textView.Caret.ContainingTextViewLine.Start.Position, new string('\t', rtCount)); rtEdit.Apply(); var line = _textView.TextBuffer.CurrentSnapshot.GetLineFromPosition(_textView.Caret.Position.BufferPosition); _textView.Caret.MoveTo(line.End); }
public JoinedTextChange(INormalizedTextChangeCollection changes) { int oldStart = changes[0].OldSpan.Start; int oldEnd = changes[changes.Count - 1].OldEnd; oldS = new Span(oldStart, oldEnd); delta = changes[changes.Count - 1].NewEnd - changes[changes.Count - 1].OldEnd; }
public static void LogTextChanges(INormalizedTextChangeCollection textChanges) { foreach (ITextChange textChange in textChanges) { Log("Text change: (" + textChange.OldPosition + "," + textChange.OldEnd + ") \"" + textChange.OldText + "\" =>(" + textChange.NewPosition + "," + textChange.NewEnd + ") \"" + textChange.NewText + "\""); } }
public static void LogTextChanges(INormalizedTextChangeCollection textChanges) { foreach (ITextChange textChange in textChanges) { Log("Text change: (" + textChange.OldPosition + "," + textChange.OldEnd + ") \"" + textChange.OldText + "\" =>(" + textChange.NewPosition + "," + textChange.NewEnd + ") \"" + textChange.NewText + "\""); } }
internal void SetChanges(INormalizedTextChangeCollection changes) { if (this.Changes != null) { throw new InvalidOperationException("Not allowed to SetChanges twice"); } this.Changes = changes; }
internal static TextChangeRange[] ToTextChangeRange(this INormalizedTextChangeCollection changes) { var res = new TextChangeRange[changes.Count]; for (int i = 0; i < res.Length; i++) { res[i] = changes[i].ToTextChangeRange(); } return(res); }
// Returns spans corresponding to the changes that occurred between startVersion and endVersion public static bool GetChangedExtent(this ITextVersion oldVersion, ITextVersion newVersion, out Span?oldSpan, out Span?newSpan) { oldSpan = null; newSpan = null; if (oldVersion.VersionNumber > newVersion.VersionNumber) { // They've asked for information about an earlier snapshot, not supported Debug.Assert(false); return(false); } int newEnd = Int32.MinValue; int position = Int32.MaxValue; int deltaLen = 0; while (oldVersion != newVersion) { INormalizedTextChangeCollection changes = oldVersion.Changes; if (changes.Count > 0) { ITextChange firstChange = changes[0]; ITextChange lastChange = changes[changes.Count - 1]; int changeDeltaLen = lastChange.NewEnd - lastChange.OldEnd; deltaLen += changeDeltaLen; position = Math.Min(position, firstChange.NewPosition); if (newEnd < lastChange.OldEnd) { newEnd = lastChange.NewEnd; } else { newEnd += changeDeltaLen; } } oldVersion = oldVersion.Next; } if (newEnd < position) { // There weren't any changes between the versions, return a null TextChangeExtent return(false); } int oldEnd = newEnd - deltaLen; oldSpan = Span.FromBounds(position, oldEnd); newSpan = Span.FromBounds(position, newEnd); return(true); }
private ITextEventRaiser ApplyChangesAndSetSnapshot(FrugalList <TextChange> changes, EditOptions options, int?reiteratedVersionNumber, object editTag) { INormalizedTextChangeCollection normalizedChanges = NormalizedTextChangeCollection.Create(changes, options.ComputeMinimalChange ? (StringDifferenceOptions?)options.DifferenceOptions : null, this.textDifferencingService); ITextSnapshot originSnapshot = base.CurrentSnapshot; base.SetCurrentVersionAndSnapshot(normalizedChanges, reiteratedVersionNumber ?? -1); return(new TextContentChangedEventRaiser(originSnapshot, this.CurrentSnapshot, options, editTag)); }
public static bool AllWhitespace(INormalizedTextChangeCollection changes) { foreach (var change in changes) { if (!AllWhitespace(change.NewText)) { return(false); } } return(true); }
public ElisionMap IncorporateChanges(INormalizedTextChangeCollection sourceChanges, FrugalList <TextChange> projectedChanges, ITextSnapshot beforeSourceSnapshot, ITextSnapshot sourceSnapshot, ITextSnapshot beforeElisionSnapshot) { ElisionMapNode newRoot = this.root; int accumulatedProjectedDelta = 0; foreach (ITextChange sourceChange in sourceChanges) { int accumulatedDelete = 0; int incrementalAccumulatedProjectedDelta = 0; ChangeString newText; TextChange concreteSourceChange = sourceChange as TextChange; if (concreteSourceChange != null) { newText = concreteSourceChange._newText; } else { // handle mocks in tests newText = new LiteralChangeString(sourceChange.NewText); } newRoot = newRoot.IncorporateChange(beforeSourceSnapshot: beforeSourceSnapshot, afterSourceSnapshot: sourceSnapshot, beforeElisionSnapshot: beforeElisionSnapshot, sourceInsertionPosition: sourceChange.NewLength > 0 ? sourceChange.NewPosition : (int?)null, newText: newText, sourceDeletionSpan: new Span(sourceChange.NewPosition, sourceChange.OldLength), absoluteSourceOldPosition: sourceChange.OldPosition, absoluteSourceNewPosition: sourceChange.NewPosition, projectedPrefixSize: 0, projectedChanges: projectedChanges, incomingAccumulatedDelta: accumulatedProjectedDelta, outgoingAccumulatedDelta: ref incrementalAccumulatedProjectedDelta, accumulatedDelete: ref accumulatedDelete); accumulatedProjectedDelta += incrementalAccumulatedProjectedDelta; } if (newRoot.TotalSourceSize != sourceSnapshot.Length) { Debug.Fail(String.Format(System.Globalization.CultureInfo.InvariantCulture, "Change incorporation length inconsistency. Elision:{0} Source:{1}", newRoot.TotalSourceSize, sourceSnapshot.Length)); throw new InvalidOperationException(Strings.InvalidLengthCalculation); } if (newRoot.TotalSourceLineBreakCount + 1 != sourceSnapshot.LineCount) { Debug.Fail(String.Format(System.Globalization.CultureInfo.InvariantCulture, "Change incorporation line count inconsistency. Elision:{0} Source:{1}", newRoot.TotalSourceLineBreakCount + 1, sourceSnapshot.LineCount)); throw new InvalidOperationException(Strings.InvalidLineCountCalculation); } return(new ElisionMap(newRoot, this.spanCount)); }
public static bool ContainsControlCharacter(INormalizedTextChangeCollection changes) { foreach (var change in changes) { if (ContainsControlCharacter(change.NewText)) { return(true); } } return(false); }
private SingleTextChange CreateSingleChange(ITextSnapshot snapshot, INormalizedTextChangeCollection changes) { if (changes == null || changes.Count == 0) { return(new SingleTextChange(0, 0, snapshot.Length)); } var start = changes[0]; var end = changes[changes.Count - 1]; return(new SingleTextChange(start.OldPosition, end.OldEnd - start.OldPosition, end.NewEnd - start.OldPosition)); }
public static int TrackPositionBackwardInTime(PointTrackingMode trackingMode, int currentPosition, ITextImageVersion currentVersion, ITextImageVersion targetVersion) { if (trackingMode < PointTrackingMode.Positive || trackingMode > PointTrackingMode.Negative) { throw new ArgumentOutOfRangeException("trackingMode"); } if (currentVersion == null) { throw new ArgumentNullException("currentVersion"); } if (targetVersion == null) { throw new ArgumentNullException("targetVersion"); } if (targetVersion.Identifier != currentVersion.Identifier) { throw new ArgumentException("currentVersion and targetVersion must be from the same ITextImage"); } if (targetVersion.VersionNumber > currentVersion.VersionNumber) { throw new ArgumentOutOfRangeException("targetVersion"); } if (currentPosition < 0 || currentPosition > currentVersion.Length) { throw new ArgumentOutOfRangeException("currentPosition"); } // track backwards in time INormalizedTextChangeCollection[] textChangesStack = new INormalizedTextChangeCollection[currentVersion.VersionNumber - targetVersion.VersionNumber]; int top = 0; { ITextImageVersion roverVersion = targetVersion; while (roverVersion != currentVersion) { textChangesStack[top++] = roverVersion.Changes; roverVersion = roverVersion.Next; } } while (top > 0) { currentPosition = TrackPositionBackwardInTime(trackingMode, currentPosition, textChangesStack[--top]); } return(currentPosition); }
public TextVersion SetChanges(IList<ITextChange> changes, int? reiteratedVersionNumber = null) { var normalizedChanges = NormalizedTextChangeCollection.Create(changes); if (reiteratedVersionNumber == null) reiteratedVersionNumber = changes.Count == 0 ? ReiteratedVersionNumber : VersionNumber + 1; int newLength = Length; foreach (var c in normalizedChanges) newLength += c.Delta; Debug.Assert(newLength >= 0); var newVersion = new TextVersion(TextBuffer, newLength, VersionNumber + 1, reiteratedVersionNumber.Value); Changes = normalizedChanges; Next = newVersion; return newVersion; }
protected static ITextSnapshot CreateBeforeSnapshot(INormalizedTextChangeCollection collection) { var version = new Mock <ITextVersion>(MockBehavior.Strict); version.Setup(v => v.Changes) .Returns(collection); var snapshot = new Mock <ITextSnapshot>(MockBehavior.Strict); snapshot.Setup(obj => obj.Version) .Returns(version.Object); return(snapshot.Object); }
public TextVersion CreateNext(INormalizedTextChangeCollection changes) { if (changes.Count == 0) { // If there are no changes (e.g. readonly region edit or content type change), then // we consider this a reiteration of the current version. return(CreateNext(changes, this.ReiteratedVersionNumber)); } else { return(CreateNext(changes, this.VersionNumber + 1)); } }
/// <summary> /// Attaches the change to the current node and creates the next version node /// </summary> public TextVersion CreateNext(INormalizedTextChangeCollection changes, int reiteratedVersionNumber) { this.normalizedChanges = changes; int delta = 0; int changeCount = changes.Count; for (int c = 0; c < changeCount; ++c) { delta += changes[c].Delta; } this.next = new TextVersion(this.TextBuffer, this.VersionNumber + 1, reiteratedVersionNumber, this.versionLength + delta); return(this.next); }
protected virtual void OnTextBufferChanged(object sender, TextContentChangedEventArgs e) { INormalizedTextChangeCollection changes = e.Changes; // ordered by position if (changes.Count == 0) { return; } int start = changes[0].OldPosition; var last = changes[changes.Count - 1]; int newLength = last.NewEnd - start; int delta = last.NewEnd - last.OldEnd; TextBufferChanged(start, newLength, delta); }
/// <summary> /// Create a new version based on applying <paramref name="changes"/> to this. /// </summary> /// <param name="changes">null if set later</param> /// <param name="newLength">use -1 to compute a length</param> /// <param name="reiteratedVersionNumber">use -1 to get the default value</param> /// <remarks> /// <para>If <paramref name="changes"/> can be null, then <paramref name="newLength"/> cannot be -1.</para> /// </remarks> internal TextVersion CreateNext(INormalizedTextChangeCollection changes, int newLength = -1, int reiteratedVersionNumber = -1) { if (this.Next != null) { throw new InvalidOperationException("Not allowed to CreateNext twice"); } var newTextImageVersion = this._textImageVersion.CreateNext(reiteratedVersionNumber: reiteratedVersionNumber, length: newLength, changes: changes); var next = new TextVersion(this.TextBuffer, newTextImageVersion); this.Next = next; return(next); }
internal static SnapshotSpan?GetPasteSpan(ITextSnapshot prePasteSnapshot, ITextSnapshot postPasteSnapshot) { INormalizedTextChangeCollection changes = prePasteSnapshot.Version.Changes; if (changes != null && changes.Count > 0) { ITextChange firstChange = changes[0]; ITextChange lastChange = changes[changes.Count - 1]; SnapshotSpan newSpan = new SnapshotSpan(postPasteSnapshot, Span.FromBounds(firstChange.NewPosition, lastChange.NewEnd)); return(newSpan); } return(null); }
public StringRebuilder ApplyChangesToStringRebuilder(INormalizedTextChangeCollection normalizedChanges, StringRebuilder source) { var doppelganger = this.GetDoppelgangerBuilder(); if (doppelganger != null) { return(doppelganger); } for (int i = normalizedChanges.Count - 1; (i >= 0); --i) { ITextChange change = normalizedChanges[i]; source = source.Replace(change.OldSpan, TextChange.NewStringRebuilder(change)); } return(source); }
private ElisionSourceSpansChangedEventArgs ApplySpanChanges(NormalizedSpanCollection spansToElide, NormalizedSpanCollection spansToExpand) { ElisionSnapshot beforeSnapshot = this.currentElisionSnapshot; FrugalList <TextChange> textChanges; ElisionMap newContent = this.content.EditSpans(this.sourceSnapshot, spansToElide, spansToExpand, out textChanges); if (newContent != this.content) { this.content = newContent; INormalizedTextChangeCollection normalizedChanges = NormalizedTextChangeCollection.Create(textChanges); SetCurrentVersionAndSnapshot(normalizedChanges); return(new ElisionSourceSpansChangedEventArgs(beforeSnapshot, this.currentElisionSnapshot, spansToElide, spansToExpand, null)); } else { return(null); } }
private void ParseBufferChanges(INormalizedTextChangeCollection textChanges, ITextSnapshot textSnapshot) { // We must feed the GLSLTagSpanCollection ALL tagSpans, old and new, and it will determine what the appropriate differences are var tokenBuilder = new TokenBuilder(_buffer); var statementBuilder = new StatementBuilder(textSnapshot); // Returns any tagspans from our original set (before the text changed) that intersects in any way with our text changes _statements.Translate(textSnapshot); _commentTagger.Translate(textSnapshot); //_bracketTagger.Translate(textSnapshot); _variableTagger.Translate(textSnapshot); _functionTagger.Translate(textSnapshot); foreach (var textChange in textChanges) { // "Reprocess" statement here instead, so we can track which statements and spans we are removing var preprocessorSpan = _statements.ReprocessPreprocessors(textChange.NewPosition, textChange.NewEnd); _commentTagger.Remove(preprocessorSpan); // Need to translate and remove redundant spans from VariableTagger, FunctionTagger var statementSpan = _statements.ReprocessStatements(textChange.NewPosition, textChange.NewEnd); _variableTagger.Remove(statementSpan); _functionTagger.Remove(statementSpan); var span = Span.FromBounds(Math.Min(preprocessorSpan.Start, statementSpan.Start), Math.Max(preprocessorSpan.End, statementSpan.End)); // For now, we can just determine to RE-PARSE the entirety of the current statement that we are in // This is easy enough, but we ALSO need to remove any tag spans that relate to this statement, since we don't want to end up re-adding those tag spans if (tokenBuilder.Position <= span.Start) { // Now we generate token spans until // 1) we have parsed at least the full textChange.NewLength amount, and // 2) we finish whatever statement we are currently on foreach (var tokenSpan in tokenBuilder.GetTokenSpans(span.Start, Math.Max(textChange.NewLength + span.Start, span.End))) { ProcessTokenSpan(tokenSpan, tokenBuilder, statementBuilder); } } } _tagSpans.Update(textSnapshot, _statements.TagSpans); }
private void ConstructChanges() { var diffs = differ.GetDifferences(); List <TextChange> changes = new List <TextChange>(); int pos = this.textPosition; // each difference generates a text change foreach (Difference diff in diffs) { pos += GetMatchSize(diffs.LeftSequence, diff.Before); TextChange change = TextChange.Create(pos, BufferFactoryService.StringRebuilderFromSnapshotSpans(diffs.LeftSequence, diff.Left), BufferFactoryService.StringRebuilderFromSnapshotSpans(diffs.RightSequence, diff.Right), this.currentSnapshot); changes.Add(change); pos += change.OldLength; } this.normalizedChanges = NormalizedTextChangeCollection.Create(changes); }
private void UpdateBraceList(ITextSnapshot snapshot, INormalizedTextChangeCollection changes) { bool notify = true; var startPoint = new SnapshotPoint(snapshot, changes[0].NewSpan.Start); UpdateBraceList(startPoint, notify); }
internal void SetNext(MockTextVersion nextVersion, params ITextChange[] changes) { _nextVersion = nextVersion; _changes = new MockNormalizedTextChangeCollection(changes); }
private SingleTextChange CreateSingleChange(ITextSnapshot snapshot, INormalizedTextChangeCollection changes) { if (changes == null || changes.Count == 0) return new SingleTextChange(0, 0, snapshot.Length); var start = changes[0]; var end = changes[changes.Count - 1]; return new SingleTextChange(start.OldPosition, end.OldEnd - start.OldPosition, end.NewEnd - start.OldPosition); }
public ChangeInfo(INormalizedTextChangeCollection collection, int beforeVersionNumber, int afterVersionNumber) { Collection = collection; BeforeVersionNumber = beforeVersionNumber; AfterVersionNumber = afterVersionNumber; }
private static bool ShouldWrapPrelim( bool optionsAutoWrapEnabled, int optionsAvoidWrappingBeforeLine, INormalizedTextChangeCollection changes, ITextSnapshot snapshot, ITextBuffer buffer, CaretPosition caretPosition, out SnapshotPoint caretPoint, out int firstLine) { caretPoint = default(SnapshotPoint); firstLine = -1; if (!optionsAutoWrapEnabled) { return false; } if (!buffer.CheckEditAccess()) { return false; } // The auto-wrap should only apply during simple typing. Region // edits (simultaneous multi-line typing) could lead to truly bizarre // wrapping behavior, so it really doesn't make sense. if (changes.Count > 1) { return false; } // Need a better (more testable!) way to get the editing state // (change, caret, etc.) out. Perhaps we just take the hit and get // all of these up front instead of only calculating them as needed? var change = changes[0]; caretPoint = caretPosition.Point.GetPoint(snapshot, caretPosition.Affinity).GetValueOrDefault(); // If the caret isn't near the change, this was an undo, or other operation // we shouldn't wrap on! if ((caretPoint.Snapshot != snapshot) || (caretPoint < change.NewPosition) || (caretPoint > change.NewEnd)) { return false; } firstLine = snapshot.GetLineNumberFromPosition(change.NewPosition); // If we're in the "don't auto-wrap" leading lines, bail. if (firstLine < optionsAvoidWrappingBeforeLine) { return false; } return true; }