public static bool FormatRange(ITextView textView, ITextBuffer textBuffer, ITextRange formatRange, AstRoot ast, RFormatOptions options, bool respectUserIndent = true) { ITextSnapshot snapshot = textBuffer.CurrentSnapshot; int start = formatRange.Start; int end = formatRange.End; // When user clicks editor margin to select a line, selection actually // ends in the beginning of the next line. In order to prevent formatting // of the next line that user did not select, we need to shrink span to // format and exclude the trailing line break. ITextSnapshotLine line = snapshot.GetLineFromPosition(formatRange.End); if (line.Start.Position == formatRange.End && formatRange.Length > 0) { if (line.LineNumber > 0) { line = snapshot.GetLineFromLineNumber(line.LineNumber - 1); end = line.End.Position; start = Math.Min(start, end); } } // Expand span to include the entire line ITextSnapshotLine startLine = snapshot.GetLineFromPosition(start); ITextSnapshotLine endLine = snapshot.GetLineFromPosition(end); formatRange = TextRange.FromBounds(startLine.Start, endLine.End); return FormatRangeExact(textView, textBuffer, formatRange, ast, options, -1, respectUserIndent); }
public int IndexOf(string text, ITextRange range, bool ignoreCase) { for (int i = range.Start; i < range.End; i++) { bool found = true; int k = i; int j; for (j = 0; j < text.Length && k < range.End; j++, k++) { char ch1 = text[j]; char ch2 = this[k]; if (ignoreCase) { ch1 = Char.ToLowerInvariant(ch1); ch2 = Char.ToLowerInvariant(ch2); } if (ch1 != ch2) { found = false; break; } } if (found && j == text.Length) { return i; } } return -1; }
public static void DoActionOnLines(ITextView textView, ITextBuffer textBuffer, ITextRange range, IEditorShell editorShell, Func<ITextSnapshotLine, bool> action, string actionName) { // When user clicks editor margin to select a line, selection actually // ends in the beginning of the next line. In order to prevent commenting // of the next line that user did not select, we need to shrink span to // format and exclude the trailing line break. ITextSnapshot snapshot = textBuffer.CurrentSnapshot; ITextSnapshotLine line = snapshot.GetLineFromPosition(range.End); int start = range.Start; int end = range.End; if (line.Start.Position == range.End && range.Length > 0) { if (line.LineNumber > 0) { line = snapshot.GetLineFromLineNumber(line.LineNumber - 1); end = line.End.Position; start = Math.Min(start, end); } } int startLineNumber = textBuffer.CurrentSnapshot.GetLineNumberFromPosition(start); int endLineNumber = textBuffer.CurrentSnapshot.GetLineNumberFromPosition(end); using (var undoAction = editorShell.CreateCompoundAction(textView, textBuffer)) { undoAction.Open(actionName); bool changed = false; for (int i = startLineNumber; i <= endLineNumber; i++) { line = textBuffer.CurrentSnapshot.GetLineFromLineNumber(i); changed |= action(line); } if (changed) { undoAction.Commit(); } } }
/// <summary> /// Determines if element is a self-closing element (i.e. like <br /> /// </summary> /// <param name="textProvider">Text provider</param> /// <param name="prefixRange">Text range of the element prefix</param> /// <param name="nameRange">Text range of the element name</param> /// <returns>True if element is a self-closing element.</returns> public bool IsSelfClosing(ITextProvider textProvider, ITextRange prefixRange, ITextRange nameRange) { if (nameRange.Length == 0) return false; string name = textProvider.GetText(nameRange); if (name[0] == '!') return true; // bang tags are always self-closing if (prefixRange.Length == 0) return _defaultProvider.IsSelfClosing(textProvider, nameRange); string prefix = textProvider.GetText(prefixRange); IHtmlClosureProvider provider; ; _providers.TryGetValue(prefix, out provider); var textRangeProvider = provider as IHtmlClosureProviderTextRange; if (textRangeProvider != null) return textRangeProvider.IsSelfClosing(textProvider, nameRange); if (provider != null) return provider.IsSelfClosing(name); return false; }
public ValidationErrorBase(ITextRange range, string message, ErrorLocation location, ErrorSeverity severity) : base(range) { Message = message; Severity = severity; Location = location; }
public static AstRoot Parse(ITextProvider textProvider, ITextRange range, IExpressionTermFilter filter) { var tokenizer = new RTokenizer(separateComments: true); IReadOnlyTextRangeCollection<RToken> tokens = tokenizer.Tokenize(textProvider, range.Start, range.Length); TokenStream<RToken> tokenStream = new TokenStream<RToken>(tokens, new RToken(RTokenType.EndOfStream, TextRange.EmptyRange)); return Parse(textProvider, range, tokenStream, tokenizer.CommentTokens, filter); }
internal WindowsRichEditRange(ITextRange range, WindowsRichEdit pattern) { Debug.Assert(range != null); Debug.Assert(pattern != null); _range = range; _pattern = pattern; }
public static ITextView MakeTextView(string content, ITextRange selectionRange) { TextBufferMock textBuffer = new TextBufferMock(content, RContentTypeDefinition.ContentType); TextViewMock textView = new TextViewMock(textBuffer); textView.Selection.Select(new SnapshotSpan(textBuffer.CurrentSnapshot, new Span(selectionRange.Start, selectionRange.Length)), false); return textView; }
public ParseContext(ITextProvider textProvider, ITextRange range, TokenStream<RToken> tokens, IReadOnlyList<RToken> comments) { this.AstRoot = new AstRoot(textProvider); this.TextProvider = textProvider; this.Tokens = tokens; this.TextRange = range; this.Scopes = new Stack<IScope>(); this.Expressions = new Stack<Expression>(); this.Comments = comments; }
public IReadOnlyList<EditorErrorTag> ItemsInRange(ITextRange range) { IReadOnlyList<EditorErrorTag> list; lock (_lockObj) { list = _tags.ItemsInRange(range); } return list; }
/// <summary> /// Writes a content of current range in form of valid xml. /// Places an artificial element xaml:FlowDocument as a root of output xml. /// </summary> /// <param name="xmlWriter"> /// XmlWriter to which the range will be serialized /// </param> /// <param name="range"> /// TextRange whose content is copied into XmlWriter xmlWriter. /// </param> /// <param name="useFlowDocumentAsRoot"> /// true means that we need to serialize the whole FlowDocument - used in FileSave scenario; /// false means that we are in copy-paste scenario and will use Section or Span as a root - depending on context. /// </param> /// <param name="wpfPayload"> /// When this parameter is not null, images are serialized. When null, images are stripped out. /// </param> /// <param name="preserveTextElements"> /// When TRUE, TextElements are serialized as-is. When FALSE, they're upcast to their base type. /// </param> internal static void WriteXaml(XmlWriter xmlWriter, ITextRange range, bool useFlowDocumentAsRoot, WpfPayload wpfPayload, bool preserveTextElements) { // Set unindented formatting to avoid inserting insignificant whitespaces as significant ones Formatting saveWriterFormatting = Formatting.None; if (xmlWriter is XmlTextWriter) { saveWriterFormatting = ((XmlTextWriter)xmlWriter).Formatting; ((XmlTextWriter)xmlWriter).Formatting = Formatting.None; } // Get the default xamlTypeMapper. XamlTypeMapper xamlTypeMapper = XmlParserDefaults.DefaultMapper; // Identify structural scope of selection - nearest common ancestor ITextPointer commonAncestor = FindSerializationCommonAncestor(range); // Decide whether we need last paragraph merging or not bool lastParagraphMustBeMerged = !TextPointerBase.IsAfterLastParagraph(range.End) && range.End.GetPointerContext(LogicalDirection.Backward) != TextPointerContext.ElementStart; // Write wrapping element with contextual properties WriteRootFlowDocument(range, commonAncestor, xmlWriter, xamlTypeMapper, lastParagraphMustBeMerged, useFlowDocumentAsRoot); // The ignoreWriteHyperlinkEnd flag will be set after call WriteOpeningTags. // If ignoreWriteHyperlinkEnd is true, WriteXamlTextSegment won't write Hyperlink end element // since Hyperlink writing opening tag is ignored by selecting the partial of Hyperlink. bool ignoreWriteHyperlinkEnd; List<int> ignoreList = new List<int>(); // Start counting tags needed to be closed. // EmptyDocumentDepth==1 - counts FlowDocument opened in WriteRootFlowDocument above. int elementLevel = EmptyDocumentDepth + WriteOpeningTags(range, range.Start, commonAncestor, xmlWriter, xamlTypeMapper, /*reduceElement:*/wpfPayload == null, out ignoreWriteHyperlinkEnd, ref ignoreList, preserveTextElements); if (range.IsTableCellRange) { WriteXamlTableCellRange(xmlWriter, range, xamlTypeMapper, ref elementLevel, wpfPayload, preserveTextElements); } else { WriteXamlTextSegment(xmlWriter, range.Start, range.End, xamlTypeMapper, ref elementLevel, wpfPayload, ignoreWriteHyperlinkEnd, ignoreList, preserveTextElements); } // Close all remaining tags - scoping its End position Invariant.Assert(elementLevel >= 0, "elementLevel cannot be negative"); while (elementLevel-- > 0) { xmlWriter.WriteFullEndElement(); } // Restore xmlWriter's Formatting property if (xmlWriter is XmlTextWriter) { ((XmlTextWriter)xmlWriter).Formatting = saveWriterFormatting; } }
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]; }
public ParseContext(ITextProvider textProvider, ITextRange range, TokenStream<RToken> tokens, IReadOnlyList<RToken> comments, IExpressionTermFilter filter = null) { AstRoot = new AstRoot(textProvider); TextProvider = textProvider; Tokens = tokens; TextRange = range; Scopes = new Stack<IScope>(); Expressions = new Stack<Expression>(); Comments = comments; ExpressionTermFilter = filter ?? new DefaultExpressionTermFilter(); }
/// <summary> /// Creates a new instance of BaseHighlighter /// </summary> /// <param name="document">Document to highlight</param> public BaseHighlighter(ITextDocument document) { this.document = document; // Much faster to keep a worker range rather than to keep requesting one from // the document this.workerRange = document.GetRange(0, 0); this._highlights = new List<Tuple<Regex, Action<ITextCharacterFormat>>>(); // Add highlighting rules AddHighlightRules(); }
/// <summary> /// Parse text from a text provider within a given range /// </summary> /// <param name="textProvider">Text provider</param> /// <param name="range">Range to parse</param> public static AstRoot Parse(ITextProvider textProvider, ITextRange range) { var tokenizer = new RTokenizer(separateComments: true); IReadOnlyTextRangeCollection<RToken> tokens = tokenizer.Tokenize(textProvider, range.Start, range.Length); TokenStream<RToken> tokenStream = new TokenStream<RToken>(tokens, new RToken(RTokenType.EndOfStream, TextRange.EmptyRange)); ParseContext context = new ParseContext(textProvider, range, tokenStream, tokenizer.CommentTokens); context.AstRoot.Parse(context, context.AstRoot); context.AstRoot.Errors = new TextRangeCollection<IParseError>(context.Errors); return context.AstRoot; }
/// <summary> /// Determines if given element can be implicitly closed like <li> or <td> in HTML" /// </summary> /// <param name="text">Text provider</param> /// <param name="name">Element name</param> /// <returns>True if element can be implictly closed</returns> public bool IsImplicitlyClosed(ITextProvider text, ITextRange name, out string[] containerElementNames) { containerElementNames = null; if (name.Length < _minCharCountImplicitClosing || name.Length > _maxCharCountImplicitClosing) return false; bool found = FindElementName(text, name, _implicitlyClosingElementNameIndex, ignoreCase: true); if (found) { string elementName = text.GetText(name); containerElementNames = GetContainerElements(elementName); } return found; }
protected ITextRange GetLanguageBlockOfLocation(int bufferPosition) { if (_cachedPosition != bufferPosition) { var items = Blocks.GetItemsContainingInclusiveEnd(bufferPosition); int index; if (items.Count > 0) { index = items[0]; } else { index = Blocks.GetItemAtPosition(bufferPosition); } _cachedLanguageBlock = index >= 0 ? Blocks[index] : null; _cachedPosition = bufferPosition; } return _cachedLanguageBlock; }
public static bool FormatRange(ITextView textView, ITextBuffer textBuffer, ITextRange formatRange, RFormatOptions options, IEditorShell editorShell) { ITextSnapshot snapshot = textBuffer.CurrentSnapshot; int start = formatRange.Start; int end = formatRange.End; if(!CanFormatRange(textView, textBuffer, formatRange, editorShell)) { return false; } // When user clicks editor margin to select a line, selection actually // ends in the beginning of the next line. In order to prevent formatting // of the next line that user did not select, we need to shrink span to // format and exclude the trailing line break. ITextSnapshotLine line = snapshot.GetLineFromPosition(formatRange.End); if (line.Start.Position == formatRange.End && formatRange.Length > 0) { if (line.LineNumber > 0) { line = snapshot.GetLineFromLineNumber(line.LineNumber - 1); end = line.End.Position; start = Math.Min(start, end); } } // Expand span to include the entire line ITextSnapshotLine startLine = snapshot.GetLineFromPosition(start); ITextSnapshotLine endLine = snapshot.GetLineFromPosition(end); // In case of formatting of multiline expressions formatter needs // to know the entire expression since otherwise it may not correctly // preserve user indentation. Consider 'x >% y' which is a plain statement // and needs to be indented at regular scope level vs // // a %>% b %>% // x %>% y // // where user indentation of 'x %>% y' must be preserved. We don't have // complete information here since expression may not be syntactically // correct and hence AST may not have correct information and besides, // the AST is damaged at this point. As a workaround, we will check // if the previous line ends with an operator current line starts with // an operator. int startPosition = FindStartOfExpression(textBuffer, startLine.Start); formatRange = TextRange.FromBounds(startPosition, endLine.End); return FormatRangeExact(textView, textBuffer, formatRange, options, editorShell); }
private static bool IsChangeDestructiveForChildNodes(IAstNode node, ITextRange changedRange) { if(changedRange.End <= node.Start || changedRange.Start >= node.End) { return false; } else if(node.Children.Count == 0) { return true; } bool result = false; foreach (var child in node.Children) { result |= IsChangeDestructiveForChildNodes(child, changedRange); if(result) { break; } } return result; }
/// <summary> /// Incrementally applies whitespace change to the buffer /// having old and new tokens produced from the 'before formatting' /// and 'after formatting' versions of the same text. /// </summary> /// <param name="textBuffer">Text buffer to apply changes to</param> /// <param name="newTextProvider">Text provider of the text fragment before formatting</param> /// <param name="newTextProvider">Text provider of the formatted text</param> /// <param name="oldTokens">Tokens from the 'before' text fragment</param> /// <param name="newTokens">Tokens from the 'after' text fragment</param> /// <param name="formatRange">Range that is being formatted in the text buffer</param> /// <param name="transactionName">Name of the undo transaction to open</param> /// <param name="selectionTracker">Selection tracker object that will save, track /// <param name="additionalAction">Action to perform after changes are applies by undo unit is not yet closed.</param> /// and restore selection after changes have been applied.</param> public static void ApplyChangeByTokens( ITextBuffer textBuffer, ITextProvider oldTextProvider, ITextProvider newTextProvider, IReadOnlyList<ITextRange> oldTokens, IReadOnlyList<ITextRange> newTokens, ITextRange formatRange, string transactionName, ISelectionTracker selectionTracker, IEditorShell editorShell, Action additionalAction = null) { Debug.Assert(oldTokens.Count == newTokens.Count); if (oldTokens.Count == newTokens.Count) { ITextSnapshot snapshot = textBuffer.CurrentSnapshot; using (CreateSelectionUndo(selectionTracker, editorShell, transactionName)) { using (ITextEdit edit = textBuffer.CreateEdit()) { if (oldTokens.Count > 0) { // Replace whitespace between tokens in reverse so relative positions match int oldEnd = oldTextProvider.Length; int newEnd = newTextProvider.Length; string oldText, newText; for (int i = newTokens.Count - 1; i >= 0; i--) { oldText = oldTextProvider.GetText(TextRange.FromBounds(oldTokens[i].End, oldEnd)); newText = newTextProvider.GetText(TextRange.FromBounds(newTokens[i].End, newEnd)); if (oldText != newText) { edit.Replace(formatRange.Start + oldTokens[i].End, oldEnd - oldTokens[i].End, newText); } oldEnd = oldTokens[i].Start; newEnd = newTokens[i].Start; } newText = newTextProvider.GetText(TextRange.FromBounds(0, newEnd)); edit.Replace(formatRange.Start, oldEnd, newText); } else { string newText = newTextProvider.GetText(TextRange.FromBounds(0, newTextProvider.Length)); edit.Replace(formatRange.Start, formatRange.Length, newText); } edit.Apply(); additionalAction?.Invoke(); } } } }
/// <summary> /// Given an R AST, and a range in that AST, determines the DataTip expression for that range. /// </summary> /// <returns> /// AST node corresponding to the DataTip expression, or <c>null</c> if there is no valid DataTip for the given range. /// </returns> /// <remarks> /// DataTip expression is defined as the outermost expression enclosing the range, such that the sequence /// of operators from that outermost expression to the innermost node still enclosing the range only consists /// of operators: <c>$ @ :: ::: [ [[</c>. Furthermore, in case of <c>[ [[</c>, only their left operands /// are considered. /// </remarks> public static IAstNode GetDataTipExpression(IAstNode ast, ITextRange range) { var node = ast.NodeFromRange(range, inclusiveEnd: true); if (node == null || !IsValidInitialNode(node)) { return null; } // When the lookup starts at [ or [[, the immediate node is the token, but its parent is an Indexer node, // and the parent of the indexer is the Operator. The loop below assumes that Operator is the immediate // parent, so walk one level up before entering it in this case. var indexer = node.Parent as Indexer; if (indexer != null) { node = indexer; } // Walk the AST tree up to determine the expression that should be evaluated, according to the following rules: // - if current node is a child of $, @, :: or ::: (on either side of the operator), keep walking; // - if current node is a left child of [ or [[, keep walking; // - otherwise, stop. // Thus, for an expression like a::b$c@d, the entire expression will be considered when hovering over a, b, c or d. // But for a[b$c][[d]], hovering over a will consider a[b$c][d], but hovering over b or c will only consider b$c. while (true) { var parent = node.Parent as Operator; if (parent == null) { break; } var op = parent.OperatorType; if (op == OperatorType.Index) { // This is a[b] or a[[b]], and the current node is either a or b. If it is a, then we want to continue // walking up; but if it is b, we want to stop here, so that only b is shown. if (parent.Children.FirstOrDefault() != node) { break; } } else if (op != OperatorType.ListIndex && op != OperatorType.Namespace) { break; } node = parent; } return node; }
public static bool FormatRangeExact(ITextView textView, ITextBuffer textBuffer, ITextRange formatRange, RFormatOptions options, IEditorShell editorShell) { ITextSnapshot snapshot = textBuffer.CurrentSnapshot; Span spanToFormat = new Span(formatRange.Start, formatRange.Length); string spanText = snapshot.GetText(spanToFormat.Start, spanToFormat.Length); string trimmedSpanText = spanText.Trim(); RFormatter formatter = new RFormatter(options); string formattedText = formatter.Format(trimmedSpanText); formattedText = formattedText.Trim(); // There may be inserted line breaks after { // Apply formatted text without indentation. We then will update the parse tree // so we can calculate proper line indents from the AST via the smart indenter. if (!spanText.Equals(formattedText, StringComparison.Ordinal)) { // Extract existing indent before applying changes. Existing indent // may be used by the smart indenter for function argument lists. var startLine = snapshot.GetLineFromPosition(spanToFormat.Start); var originalIndentSizeInSpaces = IndentBuilder.TextIndentInSpaces(startLine.GetText(), options.IndentSize); var selectionTracker = new RSelectionTracker(textView, textBuffer, formatRange); RTokenizer tokenizer = new RTokenizer(); IReadOnlyTextRangeCollection<RToken> oldTokens = tokenizer.Tokenize(spanText); IReadOnlyTextRangeCollection<RToken> newTokens = tokenizer.Tokenize(formattedText); IncrementalTextChangeApplication.ApplyChangeByTokens( textBuffer, new TextStream(spanText), new TextStream(formattedText), oldTokens, newTokens, formatRange, Resources.AutoFormat, selectionTracker, editorShell, () => { var ast = UpdateAst(textBuffer); // Apply indentation IndentLines(textView, textBuffer, new TextRange(formatRange.Start, formattedText.Length), ast, options, originalIndentSizeInSpaces); }); return true; } return false; }
public static bool FormatRangeExact(ITextView textView, ITextBuffer textBuffer, ITextRange formatRange, AstRoot ast, RFormatOptions options, int scopeStatementPosition, bool respectUserIndent = true) { ITextSnapshot snapshot = textBuffer.CurrentSnapshot; Span spanToFormat = new Span(formatRange.Start, formatRange.Length); string spanText = snapshot.GetText(spanToFormat.Start, spanToFormat.Length); string trimmedSpanText = spanText.Trim(); if (trimmedSpanText == "}") { // Locate opening { and its statement var scopeNode = ast.GetNodeOfTypeFromPosition<IAstNodeWithScope>(spanToFormat.Start); if (scopeNode != null) { scopeStatementPosition = scopeNode.Start; } } RFormatter formatter = new RFormatter(options); string formattedText = formatter.Format(trimmedSpanText); formattedText = formattedText.Trim(); // there may be inserted line breaks after { formattedText = IndentLines(textBuffer, spanToFormat.Start, ast, formattedText, options, scopeStatementPosition, respectUserIndent); if (!spanText.Equals(formattedText, StringComparison.Ordinal)) { var selectionTracker = new RSelectionTracker(textView, textBuffer); RTokenizer tokenizer = new RTokenizer(); IReadOnlyTextRangeCollection<RToken> oldTokens = tokenizer.Tokenize(spanText); IReadOnlyTextRangeCollection<RToken> newTokens = tokenizer.Tokenize(formattedText); IncrementalTextChangeApplication.ApplyChangeByTokens( textBuffer, new TextStream(spanText), new TextStream(formattedText), oldTokens, newTokens, formatRange, Resources.AutoFormat, selectionTracker); return true; } return false; }
//----------------------------------------------------- // // ITextRange Methods // //----------------------------------------------------- #region ITextRange Methods //...................................................... // // Selection Building // //...................................................... /// <summary> /// </summary> // internal static bool Contains(ITextRange thisRange, ITextPointer textPointer) { NormalizeRange(thisRange); if (textPointer == null) { throw new ArgumentNullException("textPointer"); } if (textPointer.TextContainer != thisRange.Start.TextContainer) { throw new ArgumentException(SR.Get(SRID.NotInAssociatedTree), "textPointer"); } // Correct position normalization on range boundary so that // our test would not depend on what side of formatting tags // pointer is located. if (textPointer.CompareTo(thisRange.Start) < 0) { textPointer = textPointer.GetFormatNormalizedPosition(LogicalDirection.Forward); } else if (textPointer.CompareTo(thisRange.End) > 0) { textPointer = textPointer.GetFormatNormalizedPosition(LogicalDirection.Backward); } // Check if at least one segment contains this position. for (int i = 0; i < thisRange._TextSegments.Count; i++) { if (thisRange._TextSegments[i].Contains(textPointer)) { return true; } } return false; }
/// <summary> /// Finds out if range represents valid text range (when range is not null and it's length is greater than zero) /// </summary> /// <returns>True if range is valid</returns> public static bool IsValid(ITextRange range) { return(range != null && range.Length > 0); }
/// <summary> /// Finds out if range intersects another range /// </summary> /// <param name="range">First text range</param> /// <param name="rangeStart2">Start of the second range</param> /// <param name="rangeLength2">Length of the second range</param> /// <returns>True if ranges intersect</returns> public static bool Intersect(ITextRange range1, int rangeStart2, int rangeLength2) => Intersect(range1.Start, range1.Length, rangeStart2, rangeLength2);
/// <summary> /// Finds out of range intersects another range /// </summary> /// <param name="range">Text range</param> /// <returns>True if ranges intersect</returns> public virtual bool Intersect(ITextRange range) => TextRange.Intersect(this, range.Start, range.Length);
/// <summary> /// Determines if range contains given position /// </summary> /// <param name="range">Text range</param> /// <param name="position">Position</param> /// <returns>True if position is inside the range</returns> public static bool Contains(ITextRange range, int position) => Contains(range.Start, range.Length, position);
public int CompareEndpoints(TextPatternRangeEndpoint srcEndPoint, ITextRange targetRange, TextPatternRangeEndpoint targetEndPoint) { var nativeRange = ToNativeRange(targetRange); return(NativeRange.CompareEndpoints((UIA.Text.TextPatternRangeEndpoint)srcEndPoint, nativeRange, (UIA.Text.TextPatternRangeEndpoint)targetEndPoint)); }
/// <summary> /// Determines if range contains another range /// </summary> public static bool Contains(ITextRange range, ITextRange other) { var textRange = new TextRange(range); return(textRange.Contains(other)); }
/// <summary> /// Finds out if range intersects another range /// </summary> /// <param name="range1">First text range</param> /// <param name="range2">Second text range</param> /// <returns>True if ranges intersect</returns> public static bool Intersect(ITextRange range1, ITextRange range2) => Intersect(range1, range2.Start, range2.Length);
/// <summary> /// Finds out of range intersects another range /// </summary> /// <param name="start">Text range</param> /// <returns>True if ranges intersect</returns> public virtual bool Intersect(ITextRange range) { return(TextRange.Intersect(this, range.Start, range.Length)); }
public TemplateCommentArtifact(ITextRange range, bool isClosed) : base(ArtifactTreatAs.Comment, range, isClosed) { }
public static TemplateArtifact Create(TemplateTokenKind kind, ITextRange range, bool isClosed) { switch (kind) { case TemplateTokenKind.Block: return new TemplateBlockArtifact(range, isClosed); case TemplateTokenKind.Variable: return new TemplateVariableArtifact(range, isClosed); case TemplateTokenKind.Comment: return new TemplateCommentArtifact(range, isClosed); default: throw new ArgumentException("Unsupported TemplateTokenKind", "kind"); } }
// Check the text range whether it is empty or not without normalization. private bool IsTextRangeEmpty(ITextRange textRange) { // We assume that TextRange.TextSegments property getter does not normalize a range, // thus we can avoid re-entrancy. Invariant.Assert(textRange._TextSegments.Count > 0); return textRange._TextSegments[0].Start.CompareTo(textRange._TextSegments[textRange._TextSegments.Count - 1].End) == 0; }
public ROutlineRegion(ITextBuffer textBuffer, ITextRange range) : base(textBuffer, range) { }
public ISelectionTracker CreateSelectionTracker(IEditorView editorView, IEditorBuffer editorBuffer, ITextRange selectedRange) => new RSelectionTracker(editorView.As <ITextView>(), editorBuffer.As <ITextBuffer>(), selectedRange);
/// <summary> /// Finds out if range intersects another range /// </summary> /// <param name="range1">First text range</param> /// <param name="range2">Second text range</param> /// <returns>True if ranges intersect</returns> public static bool Intersect(ITextRange range1, ITextRange range2) { return(Intersect(range1, range2.Start, range2.Length)); }
public void MoveEndpointByRange(TextPatternRangeEndpoint srcEndPoint, ITextRange targetRange, TextPatternRangeEndpoint targetEndPoint) { var nativeRange = ToNativeRange(targetRange); NativeRange.MoveEndpointByRange((UIA.Text.TextPatternRangeEndpoint)srcEndPoint, nativeRange, (UIA.Text.TextPatternRangeEndpoint)targetEndPoint); }
/// <summary> /// Determines if range contains all ranges in a collection /// </summary> public static bool Contains(ITextRange range, IEnumerable <ITextRange> ranges) { var textRange = new TextRange(range); return(textRange.Contains(ranges)); }
public ROutlineRegion(ITextBuffer textBuffer, ITextRange range, string displayText) : base(textBuffer, range) { _displayText = displayText; }
/// <summary> /// Determines if range contains given position /// </summary> /// <param name="range">Text range</param> /// <param name="position">Position</param> /// <returns>True if position is inside the range</returns> public static bool Contains(ITextRange range, int position) { return(Contains(range.Start, range.Length, position)); }
public bool Compare(ITextRange range) { var nativeRange = ToNativeRange(range); return(NativeRange.Compare(nativeRange)); }
/// <summary> /// Determines if range contains another range or it contains start point /// of the other range and their end points are the same. /// </summary> public static bool ContainsInclusiveEnd(ITextRange range, ITextRange other) => range.Contains(other.Start) && (range.Contains(other.End) || range.End == other.End);
/// <summary> /// Determines if text range fully contains another range /// </summary> /// <param name="range"></param> public virtual bool Contains(ITextRange range) => Contains(range.Start) && Contains(range.End);
/// <summary> /// Determines if text range fully contains another range /// </summary> /// <param name="range"></param> public virtual bool Contains(ITextRange range) { return(Contains(range.Start) && Contains(range.End)); }
/// <summary> /// Finds out if range represents valid text range (when range is not null and it's length is greater than zero) /// </summary> /// <returns>True if range is valid</returns> public static bool IsValid(ITextRange range) => range != null && range.Length > 0;
/// <summary> /// Determines if range contains another range /// </summary> public static bool Contains(ITextRange range, ITextRange other) => range.Contains(other.Start) && range.Contains(other.End);
public IList <T> ItemsInRange(ITextRange range) { return(_collection.ItemsInRange(range)); }
/// <summary> /// Comments selected lines or current line if range has zero length. /// Continues adding commentcharacter even if line is already commented. /// # -> ## -> ### and so on. Matches C# behavior. /// </summary> public static void CommentBlock(ITextView textView, ITextBuffer textBuffer, ITextRange range) { DoActionOnLines(textView, textBuffer, range, CommentLine, Resources.CommentSelection); }
/// <summary> /// Creates text range based on another text range /// </summary> /// <param name="range">Text range to use as position source</param> public TextRange(ITextRange range) : this(range.Start, range.Length) { }
private static bool CanFormatRange(ITextView textView, ITextBuffer textBuffer, ITextRange formatRange, IEditorShell editorShell) { // Make sure we are not formatting damaging the projected range in R Markdown // which looks like ```{r. 'r' should not separate from {. var host = ContainedLanguageHost.GetHost(textView, textBuffer, editorShell); if (host != null) { ITextSnapshot snapshot = textBuffer.CurrentSnapshot; int startLine = snapshot.GetLineNumberFromPosition(formatRange.Start); int endLine = snapshot.GetLineNumberFromPosition(formatRange.End); for (int i = startLine; i <= endLine; i++) { if (!host.CanFormatLine(textView, textBuffer, i)) { return(false); } } } return(true); }
private bool CanFormatRange(ITextRange formatRange) { // Make sure we are not formatting damaging the projected range in R Markdown // which looks like ```{r. 'r' should not separate from {. return(true); }
public static bool FormatRangeExact(ITextView textView, ITextBuffer textBuffer, ITextRange formatRange, RFormatOptions options, IEditorShell editorShell) { ITextSnapshot snapshot = textBuffer.CurrentSnapshot; Span spanToFormat = new Span(formatRange.Start, formatRange.Length); string spanText = snapshot.GetText(spanToFormat.Start, spanToFormat.Length); string trimmedSpanText = spanText.Trim(); RFormatter formatter = new RFormatter(options); string formattedText = formatter.Format(trimmedSpanText); formattedText = formattedText.Trim(); // There may be inserted line breaks after { // Apply formatted text without indentation. We then will update the parse tree // so we can calculate proper line indents from the AST via the smart indenter. if (!spanText.Equals(formattedText, StringComparison.Ordinal)) { // Extract existing indent before applying changes. Existing indent // may be used by the smart indenter for function argument lists. var startLine = snapshot.GetLineFromPosition(spanToFormat.Start); var originalIndentSizeInSpaces = IndentBuilder.TextIndentInSpaces(startLine.GetText(), options.IndentSize); var selectionTracker = new RSelectionTracker(textView, textBuffer, formatRange); RTokenizer tokenizer = new RTokenizer(); IReadOnlyTextRangeCollection <RToken> oldTokens = tokenizer.Tokenize(spanText); IReadOnlyTextRangeCollection <RToken> newTokens = tokenizer.Tokenize(formattedText); IncrementalTextChangeApplication.ApplyChangeByTokens( textBuffer, new TextStream(spanText), new TextStream(formattedText), oldTokens, newTokens, formatRange, Resources.AutoFormat, selectionTracker, editorShell, () => { var ast = UpdateAst(textBuffer); // Apply indentation IndentLines(textView, textBuffer, new TextRange(formatRange.Start, formattedText.Length), ast, options, originalIndentSizeInSpaces); }); return(true); } return(false); }
/// <summary> /// Constructs validation error for an element at a specified location. /// </summary> public ValidationError(ITextRange range, string message, ErrorLocation location) : base(range, message, location, ErrorSeverity.Error) { }
public TemplateVariableArtifact(ITextRange range, bool isClosed) : base(ArtifactTreatAs.Code, range, isClosed) { }
/// <summary> /// Creates a new parse error object with these properties. /// </summary> /// <param name="code">The code of the error.</param> /// <param name="range">The text range of the error.</param> public ParseError(ErrorCode code, ITextRange range) { _code = code; _range = range; }
/// <param name="isClosed">Whether the artifact has a closing separator, or is terminated by EOF.</param> public TemplateArtifact(ArtifactTreatAs t, ITextRange range, bool isClosed) : base(t, range, 2, (isClosed ? 2 : 0), DjangoPredefinedClassificationTypeNames.TemplateTag, wellFormed: isClosed) { }
public string GetText(ITextRange range) { return(GetText(range.Start, range.Length)); }