///////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC PROCEDURES ///////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Returns the tag ranges that intersect with the specified normalized snapshot ranges. /// </summary> /// <param name="snapshotRanges">The collection of normalized snapshot ranges.</param> /// <param name="parameter">An optional parameter that provides contextual information about the tag request.</param> /// <returns>The tag ranges that intersect with the specified normalized snapshot ranges.</returns> public override IEnumerable <TagSnapshotRange <IClassificationTag> > GetTags(NormalizedTextSnapshotRangeCollection snapshotRanges, object parameter) { // Loop through the requested snapshot ranges... foreach (TextSnapshotRange snapshotRange in snapshotRanges) { // If the snapshot range is not zero-length... if (!snapshotRange.IsZeroLength) { // Get a snapshot reader ITextSnapshotReader reader = snapshotRange.Snapshot.GetReader(snapshotRange.StartOffset); // If not already at the start of a line, back up to the start if (!reader.IsAtSnapshotLineStart) { reader.GoToCurrentSnapshotLineStart(); } // Read through the snapshot until the end of the target range is reached while ((!reader.IsAtSnapshotEnd) && (reader.Offset < snapshotRange.EndOffset)) { // Save the start of the line offset int lineStartOffset = reader.Offset; // Get the line start text (we need at most 6 chars for this sample) string lineStartText = reader.PeekText(6); // Go to the end of the line reader.GoToCurrentSnapshotLineEnd(); // Add a range for the line if it starts with one of the defined strings... // The StyleRegistryClassificationTag is a special ClassificationTag that allows you to indicate // an alternate IHighlightingStyleRegistry to use for syntax highlighting... if using the // normal AmbientHighlightingStyleRegistry, you'd just use a regular ClassificationTag instead if (lineStartText.StartsWith("---")) { // Apply green to lines that start with "---" yield return(new TagSnapshotRange <IClassificationTag>( new TextSnapshotRange(snapshotRange.Snapshot, new TextRange(lineStartOffset, reader.Offset)), new StyleRegistryClassificationTag(commentCT, styleRegistry) )); } else if (lineStartText.StartsWith("Error:")) { // Apply maroon to lines that start with "Error:" yield return(new TagSnapshotRange <IClassificationTag>( new TextSnapshotRange(snapshotRange.Snapshot, new TextRange(lineStartOffset, reader.Offset)), new StyleRegistryClassificationTag(errorCT, styleRegistry) )); } // Consume the newline reader.GoToNextSnapshotLineStart(); } } } }
private string ReadArrayIndexExpression(ITextSnapshotReader reader) { // we're looking for an expression of the form [123] or [myVariable] // if we don't find one, return false. string indexValue = null; var token = reader.ReadTokenReverse(); while (token != null) { var text = reader.PeekText(token.Length); if (token.Key == "Identifier" && indexValue == null) { // substitute 0 for the name of the variable to give us // the best chance of matching something when we look up the path in a document indexValue = "0"; } else if ((token.Key == "IntegerNumber") && indexValue == null) { indexValue = text; } else if (token.Key == "Whitespace") { // skip it } else if (token.Key == "OpenSquareBrace") { if (indexValue == null) { // we didn't find a properly formed (and simple) index expression // before hitting the square brace return(null); } else { break; } } token = reader.ReadTokenReverse(); } if (indexValue == null) { return(null); } return("[" + indexValue + "]"); }
private static string FindPrecedingField(ITextSnapshotReader reader) { while (true) { var token = reader.ReadTokenReverse(); if (token == null) { return(null); } if (token.Key == "Field") { return(GetFieldName(reader.PeekText(token.Length))); } } }
private string DetermineFullMemberExpression(string tokenText, ITextSnapshotReader reader) { var sb = new StringBuilder(tokenText); var token = reader.ReadTokenReverse(); while (token != null) { var text = reader.PeekText(token.Length); if (token.Key == "Identifier" || (token.Key == "Punctuation" && text == ".") || (token.Key == "Keyword" && text == "this")) { sb.Insert(0, text); } else if (token.Key == "CloseSquareBrace") { var indexExpression = ReadArrayIndexExpression(reader); if (indexExpression == null) { // we're not going to be able to make sense // of the rest of the expression, so bail out. break; } sb.Insert(0, indexExpression); } else if (token.Key == "Whitespace") { // skip it } else { break; } token = reader.ReadTokenReverse(); } return(sb.ToString()); }
private string ReadArrayIndexExpression(ITextSnapshotReader reader) { // we're looking for an expression of the form [123] or [myVariable] // if we don't find one, return false. string indexValue = null; var token = reader.ReadTokenReverse(); while (token != null) { var text = reader.PeekText(token.Length); if (token.Key == "Identifier" && indexValue == null) { // substitute 0 for the name of the variable to give us // the best chance of matching something when we look up the path in a document indexValue = "0"; } else if ((token.Key == "IntegerNumber") && indexValue == null) { indexValue = text; } else if (token.Key == "Whitespace") { // skip it } else if (token.Key == "OpenSquareBrace") { if (indexValue == null) { // we didn't find a properly formed (and simple) index expression // before hitting the square brace return null; } break; } token = reader.ReadTokenReverse(); } if (indexValue == null) { return null; } return "[" + indexValue + "]"; }
private string DetermineFullMemberExpression(string tokenText, ITextSnapshotReader reader) { var sb = new StringBuilder(tokenText); var token = reader.ReadTokenReverse(); while (token != null) { var text = reader.PeekText(token.Length); if (token.Key == "Identifier" || (token.Key == "Punctuation" && text == ".") || (token.Key == "Keyword" && text == "this")) { sb.Insert(0, text); } else if (token.Key == "CloseSquareBrace") { var indexExpression = ReadArrayIndexExpression(reader); if (indexExpression == null) { // we're not going to be able to make sense // of the rest of the expression, so bail out. break; } sb.Insert(0, indexExpression); } else if (token.Key == "Whitespace") { // skip it } else { break; } token = reader.ReadTokenReverse(); } return sb.ToString(); }
private static string FindPrecedingField(ITextSnapshotReader reader) { while (true) { var token = reader.ReadTokenReverse(); if (token == null) return null; if (token.Key == "Field") return GetFieldName(reader.PeekText(token.Length)); } }