private void BuildLanguageBlockCollection() { var tokenizer = new MdTokenizer(); var tokens = tokenizer.Tokenize(TextBuffer.CurrentSnapshot.GetText()); var rCodeTokens = tokens.OfType <MarkdownCodeToken>().Where(t => t.LeadingSeparatorLength > 1); // TODO: incremental updates Blocks.Clear(); _separators.Clear(); foreach (var t in rCodeTokens) { // Verify that code block is properly terminated. // If not, it ends at the end of the buffer. _separators.Add(new TextRange(t.Start, t.LeadingSeparatorLength)); // ```{r or `r if (t.IsWellFormed) { // Count backticks Blocks.Add(new RLanguageBlock(TextRange.FromBounds(t.Start + t.LeadingSeparatorLength, t.End - t.TrailingSeparatorLength), t.LeadingSeparatorLength == 2)); _separators.Add(new TextRange(t.End - t.TrailingSeparatorLength, t.TrailingSeparatorLength)); } else { Blocks.Add(new RLanguageBlock(TextRange.FromBounds(t.Start + t.LeadingSeparatorLength, t.End), t.LeadingSeparatorLength == 2)); } } }
private static ITextRange GetCodeBlockRange(ITextSnapshot snapshot, ITextRange block, ITextRange parametersRange) { // In // {r echo=FALSE} // code // // we want to format just *code* section and not spill range into the line // with {r echo=FALSE} or the next (empty) line. I.e. // // {r echo=FALSE} //| code| // // and not // {r echo=FALSE}| // code| //| // var startLine = snapshot.GetLineFromPosition(parametersRange.End); var endline = snapshot.GetLineFromPosition(block.End); if (endline.LineNumber > startLine.LineNumber) { endline = snapshot.GetLineFromLineNumber(endline.LineNumber - 1); } return(TextRange.FromBounds(startLine.EndIncludingLineBreak, endline.End)); }
public void TextRangeCollection_AddTest() { TextRange[] ranges = new TextRange[3]; ranges[0] = TextRange.FromBounds(1, 2); ranges[1] = TextRange.FromBounds(3, 5); ranges[2] = TextRange.FromBounds(5, 7); TextRangeCollection<TextRange> target = new TextRangeCollection<TextRange>(); target.Count.Should().Be(0); target.Add(ranges[0]); target.Count.Should().Be(1); target.Start.Should().Be(1); target.End.Should().Be(2); target.Length.Should().Be(1); target[0].Start.Should().Be(1); target.Add(ranges[1]); target.Count.Should().Be(2); target.Start.Should().Be(1); target.End.Should().Be(5); target.Length.Should().Be(4); target[0].Start.Should().Be(1); target[1].Start.Should().Be(3); target.Add(ranges[2]); target.Count.Should().Be(3); target.Start.Should().Be(1); target.End.Should().Be(7); target.Length.Should().Be(6); target[0].Start.Should().Be(1); target[1].Start.Should().Be(3); target[2].Start.Should().Be(5); }
private static TextRangeCollection<TextRange> MakeCollection() { var ranges = new TextRange[3]; ranges[0] = TextRange.FromBounds(1, 2); ranges[1] = TextRange.FromBounds(3, 5); ranges[2] = TextRange.FromBounds(5, 7); return new TextRangeCollection<TextRange>(ranges); }
public static NextTokenType PeekNextToken(HtmlCharStream cs, int tagEnd, out ITextRange range) { NextTokenType tokenType = NextTokenType.Unknown; int current = cs.Position; if (cs.IsEndOfStream() || cs.Position == tagEnd) { range = new TextRange(); return NextTokenType.None; } int start = cs.Position; while (cs.IsWhiteSpace()) cs.MoveToNextChar(); if (cs.IsEndOfStream() || cs.Position == tagEnd) { range = TextRange.FromBounds(start, cs.Position); return NextTokenType.Unknown; } if (cs.IsAtTagDelimiter()) { tokenType = NextTokenType.Tag; } else if (cs.CurrentChar == '=') { tokenType = NextTokenType.Equals; } else { int digits = 0; bool firstLetter = false; int length = 0; int chars = 0; if (cs.IsAnsiLetter()) firstLetter = true; while (!cs.IsEndOfStream() && !cs.IsWhiteSpace() && !cs.IsAtTagDelimiter() && cs.CurrentChar != '=' && cs.Position < tagEnd) { if (cs.IsAnsiLetter() || cs.CurrentChar == '_' || cs.CurrentChar == '-') chars++; else if (cs.IsDecimal() || cs.CurrentChar == '.') digits++; cs.MoveToNextChar(); length++; } if (length > 0) { if (length == digits) tokenType = NextTokenType.Number; else if (length == chars) tokenType = NextTokenType.Letters; else if (firstLetter) tokenType = NextTokenType.Identifier; } } range = TextRange.FromBounds(start, cs.Position); cs.Position = current; return tokenType; }
public CharacterStream(ITextProvider textProvider, ITextRange range) { _text = textProvider; int end = Math.Min(_text.Length, range.End); _range = TextRange.FromBounds(range.Start, end); Position = _range.Start; _currentChar = _text[_range.Start]; }
private static TextRangeCollection<TextRange> MakeCollection(params int[] positions) { var ranges = new TextRange[positions.Length / 2]; for (int i = 0; i < ranges.Length; i++) { int start = positions[2 * i]; int end = positions[2 * i + 1]; ranges[i] = TextRange.FromBounds(start, end); } return new TextRangeCollection<TextRange>(ranges); }
internal void OnEndTagState() { Debug.Assert(_cs.CurrentChar == '<' && _cs.NextChar == '/'); int start = _cs.Position; _cs.Advance(2); // element name may be missing if (_cs.CurrentChar == '<') return; NameToken nameToken = _tokenizer.GetNameToken(); if (nameToken == null || nameToken.Length == 0) return; if (EndTagOpen != null) EndTagOpen(this, new HtmlParserOpenTagEventArgs(start, nameToken)); while (!_cs.IsEndOfStream()) { _tokenizer.SkipWhitespace(); if (_cs.CurrentChar == '>') { var range = new TextRange(_cs.Position); if (EndTagClose != null) EndTagClose(this, new HtmlParserCloseTagEventArgs(range, true, false)); _cs.MoveToNextChar(); return; } if (_cs.CurrentChar == '<') { // Untermimated end tag (sequence may be '</<', '</{ws}>', '</>', '</name <' // '</name attrib="value" <' and so on. Close tag at the previous position. if (EndTagClose != null) EndTagClose(this, new HtmlParserCloseTagEventArgs(new TextRange(_cs.Position - 1), false, false)); return; } // attributes are not allowed in end tags so skip over any extra characters until > or < _cs.MoveToNextChar(); } }
public TextChange(TextChange change, ITextProvider newTextProvider) : this() { this.Combine(change); ITextSnapshotProvider newSnapshotProvider = newTextProvider as ITextSnapshotProvider; ITextSnapshotProvider changeNewSnapshotProvider = change.NewTextProvider as ITextSnapshotProvider; if ((newSnapshotProvider != null) && (changeNewSnapshotProvider != null)) { ITextSnapshot changeNewSnapshot = changeNewSnapshotProvider.Snapshot; ITextSnapshot newSnapshot = newSnapshotProvider.Snapshot; if (changeNewSnapshot.Version.ReiteratedVersionNumber != newSnapshot.Version.ReiteratedVersionNumber) { SnapshotSpan changeNewSpan = change.NewRange.ToSnapshotSpan(changeNewSnapshot); Span? oldChangedSpan; Span? newChangedSpan; if (changeNewSnapshot.Version.GetChangedExtent(newSnapshot.Version, out oldChangedSpan, out newChangedSpan)) { int start = Math.Min(oldChangedSpan.Value.Start, change.NewRange.Start); int end = Math.Max(oldChangedSpan.Value.End, change.NewRange.End); changeNewSpan = new SnapshotSpan(changeNewSnapshot, Span.FromBounds(start, end)); } SnapshotSpan newSpan = changeNewSpan.TranslateTo(newSnapshot, SpanTrackingMode.EdgeInclusive); NewRange = new TextRange(newSpan.Start.Position, newSpan.Length); } } NewTextProvider = newTextProvider; Version = NewTextProvider.Version; }
/// <summary> /// Creates projection mapping /// </summary> /// <param name="sourceStart">Mapping start in the primary (view) buffer</param> /// <param name="projectionStart">Mapping start in contained language buffer</param> /// <param name="length">Mapping length</param> /// <param name="trailingInclusion">Trailing content inclusion rule</param> public ProjectionMapping(int sourceStart, int projectionStart, int length) : base(sourceStart, length) { SourceRange = new TextRange(sourceStart, length); ProjectionRange = new TextRange(projectionStart, length); }
public CharacterStream(ITextProvider textProvider) : this(textProvider, TextRange.FromBounds(0, textProvider.Length)) { }
public void Clear() { TextChangeType = TextChangeType.Trivial; OldRange = TextRange.EmptyRange; NewRange = TextRange.EmptyRange; FullParseRequired = false; OldTextProvider = null; NewTextProvider = null; }
/// <summary> /// Combines one text change with another /// </summary> public void Combine(TextChange other) { if (other.IsEmpty) return; FullParseRequired |= other.FullParseRequired; TextChangeType |= other.TextChangeType; if (OldRange == TextRange.EmptyRange || NewRange == TextRange.EmptyRange) { OldRange = other.OldRange; NewRange = other.NewRange; OldTextProvider = other.OldTextProvider; NewTextProvider = other.NewTextProvider; } else { ITextSnapshotProvider oldSnapshotProvider = OldTextProvider as ITextSnapshotProvider; ITextSnapshotProvider newSnapshotProvider = NewTextProvider as ITextSnapshotProvider; ITextSnapshotProvider otherOldSnapshotProvider = other.OldTextProvider as ITextSnapshotProvider; ITextSnapshotProvider otherNewSnapshotProvider = other.NewTextProvider as ITextSnapshotProvider; bool changesAreFromNextSnapshot = false; if ((oldSnapshotProvider != null) && (newSnapshotProvider != null) && (otherOldSnapshotProvider != null) && (otherNewSnapshotProvider != null)) { ITextSnapshot newSnapshot = newSnapshotProvider.Snapshot; ITextSnapshot otherOldSnapshot = otherOldSnapshotProvider.Snapshot; if (newSnapshot.Version.ReiteratedVersionNumber == otherOldSnapshot.Version.ReiteratedVersionNumber) { changesAreFromNextSnapshot = true; } } if (!changesAreFromNextSnapshot) { // Assume these changes are from the same snapshot int oldStart = Math.Min(other.OldRange.Start, this.OldRange.Start); int oldEnd = Math.Max(other.OldRange.End, this.OldRange.End); int newStart = Math.Min(other.NewRange.Start, this.NewRange.Start); int newEnd = Math.Max(other.NewRange.End, this.NewRange.End); OldRange = TextRange.FromBounds(oldStart, oldEnd); NewRange = TextRange.FromBounds(newStart, newEnd); } else { // the "other" change is from the subsequent snapshot. Merge the changes. ITextSnapshot oldSnapshot = oldSnapshotProvider.Snapshot; ITextSnapshot newSnapshot = newSnapshotProvider.Snapshot; ITextSnapshot otherOldSnapshot = otherOldSnapshotProvider.Snapshot; ITextSnapshot otherNewSnapshot = otherNewSnapshotProvider.Snapshot; SnapshotSpan otherOldSpan = other.OldRange.ToSnapshotSpan(otherOldSnapshot); SnapshotSpan oldSpan = otherOldSpan.TranslateTo(oldSnapshot, SpanTrackingMode.EdgeInclusive); SnapshotSpan newSpan = NewRange.ToSnapshotSpan(newSnapshot); SnapshotSpan otherNewSpan = newSpan.TranslateTo(otherNewSnapshot, SpanTrackingMode.EdgeInclusive); OldRange = new TextRange(TextRange.Union(OldRange, oldSpan.ToTextRange())); NewRange = new TextRange(TextRange.Union(other.NewRange, otherNewSpan.ToTextRange())); NewTextProvider = other.NewTextProvider; } } Version = Math.Max(this.Version, other.Version); }
/// <summary> /// Formats line the caret is currently at /// </summary> public static void FormatViewLine(ITextView textView, ITextBuffer textBuffer, int offset, IEditorShell editorShell) { SnapshotPoint? caretPoint = REditorDocument.MapCaretPositionFromView(textView); if (!caretPoint.HasValue) { return; } ITextSnapshot snapshot = textBuffer.CurrentSnapshot; int lineNumber = snapshot.GetLineNumberFromPosition(caretPoint.Value.Position); ITextSnapshotLine line = snapshot.GetLineFromLineNumber(lineNumber + offset); ITextRange formatRange = new TextRange(line.Start, line.Length); UndoableFormatRange(textView, textBuffer, formatRange, editorShell, exactRange: true); }
private void CloseStartTag(int position, int length, bool selfClose, bool wellFormed) { var range = new TextRange(position, length); StartTagClose?.Invoke(this, new HtmlParserCloseTagEventArgs(range, wellFormed, selfClose)); _cs.Advance(length); }
public NameToken(TextRange nameRange) : this(nameRange.Start, nameRange.Length) { }
protected NameToken(int nameStart, int nameLength) { NameRange = new TextRange(nameStart, nameLength); }
public NameTokenWithPrefix(TextRange prefixRange, int colonPos, TextRange nameRange) : this(prefixRange.Start, prefixRange.Length, colonPos, nameRange.Start, nameRange.Length) { }