protected IndentationResult GetIndentationOfLine(ITextSnapshotLine lineToMatch, int addedSpaces) { var firstNonWhitespace = lineToMatch.GetFirstNonWhitespacePosition(); firstNonWhitespace = firstNonWhitespace ?? lineToMatch.End.Position; return GetIndentationOfPosition(new SnapshotPoint(lineToMatch.Snapshot, firstNonWhitespace.Value), addedSpaces); }
protected IndentationResult GetIndentationOfLine(ITextSnapshotLine lineToMatch, int addedSpaces) { var firstNonWhitespace = lineToMatch.GetFirstNonWhitespacePosition(); firstNonWhitespace = firstNonWhitespace ?? lineToMatch.End.Position; return(GetIndentationOfPosition(new SnapshotPoint(lineToMatch.Snapshot, firstNonWhitespace.Value), addedSpaces)); }
private bool StartsWithRegionTag(ITextSnapshotLine line) { var start = line.GetFirstNonWhitespacePosition(); if (start != null) { var index = start.Value; return(line.StartsWith(index, "#region", ignoreCase: true)); } return(false); }
/// <summary> /// Returns true if the span includes all of the non-whitespace text on the first and last line. /// </summary> private static bool SpanIncludesAllTextOnIncludedLines(SnapshotSpan span) { var(firstLine, lastLine) = DetermineFirstAndLastLine(span); var firstNonWhitespacePosition = firstLine.GetFirstNonWhitespacePosition(); var lastNonWhitespacePosition = lastLine.GetLastNonWhitespacePosition(); var allOnFirst = !firstNonWhitespacePosition.HasValue || span.Start.Position <= firstNonWhitespacePosition.Value; var allOnLast = !lastNonWhitespacePosition.HasValue || span.End.Position > lastNonWhitespacePosition.Value; return(allOnFirst && allOnLast); }
public static bool ShouldUseSmartTokenFormatterInsteadOfIndenter( IEnumerable <IFormattingRule> formattingRules, CompilationUnitSyntax root, ITextSnapshotLine line, OptionSet optionSet, CancellationToken cancellationToken) { Contract.ThrowIfNull(formattingRules); Contract.ThrowIfNull(root); Contract.ThrowIfNull(line); if (optionSet.GetOption(FormattingOptions.SmartIndent, LanguageNames.CSharp) != FormattingOptions.IndentStyle.Smart) { return(false); } var firstNonWhitespacePosition = line.GetFirstNonWhitespacePosition(); if (!firstNonWhitespacePosition.HasValue) { return(false); } var token = root.FindToken(firstNonWhitespacePosition.Value); if (token.IsKind(SyntaxKind.None) || token.SpanStart != firstNonWhitespacePosition) { return(false); } // first see whether there is a line operation for current token var previousToken = token.GetPreviousToken(includeZeroWidth: true); // only use smart token formatter when we have two visible tokens. if (previousToken.Kind() == SyntaxKind.None || previousToken.IsMissing) { return(false); } var lineOperation = FormattingOperations.GetAdjustNewLinesOperation(formattingRules, previousToken, token, optionSet); if (lineOperation != null && lineOperation.Option != AdjustNewLinesOption.ForceLinesIfOnSingleLine) { return(true); } // no indentation operation, nothing to do for smart token formatter return(false); }
public static bool ShouldUseSmartTokenFormatterInsteadOfIndenter( IEnumerable<IFormattingRule> formattingRules, CompilationUnitSyntax root, ITextSnapshotLine line, OptionSet optionSet, CancellationToken cancellationToken) { Contract.ThrowIfNull(formattingRules); Contract.ThrowIfNull(root); Contract.ThrowIfNull(line); if (optionSet.GetOption(FormattingOptions.SmartIndent, LanguageNames.CSharp) != FormattingOptions.IndentStyle.Smart) { return false; } var firstNonWhitespacePosition = line.GetFirstNonWhitespacePosition(); if (!firstNonWhitespacePosition.HasValue) { return false; } var token = root.FindToken(firstNonWhitespacePosition.Value); if (token.IsKind(SyntaxKind.None) || token.SpanStart != firstNonWhitespacePosition) { return false; } // first see whether there is a line operation for current token var previousToken = token.GetPreviousToken(includeZeroWidth: true); // only use smart token formatter when we have two visible tokens. if (previousToken.Kind() == SyntaxKind.None || previousToken.IsMissing) { return false; } var lineOperation = FormattingOperations.GetAdjustNewLinesOperation(formattingRules, previousToken, token, optionSet); if (lineOperation != null && lineOperation.Option != AdjustNewLinesOption.ForceLinesIfOnSingleLine) { return true; } // no indentation operation, nothing to do for smart token formatter return false; }
static bool IsImport(ITextSnapshotLine line, string language) { var start = line.GetFirstNonWhitespacePosition(); if (start is null) { return(false); } // For VB we only need to find "Imports" at the start of a line if (language == LanguageNames.VisualBasic) { return(line.StartsWith(start.Value, ImportsStatement, ignoreCase: true)); } // For the purposes of collapsing, extern aliases are grouped with usings if (line.StartsWith(start.Value, ExternDeclaration, ignoreCase: false)) { return(true); } return(line.StartsWith(start.Value, UsingDirective, ignoreCase: false)); }
static bool StartsWithRegionTag(ITextSnapshotLine line) { var start = line.GetFirstNonWhitespacePosition(); return(start != null && line.StartsWith(start.Value, "#region", ignoreCase: true)); }
protected virtual int GetLineExpectedIndent(ITextSnapshotLine line, XmlBackgroundParser parser, int indentSize) { var snapshot = line.Snapshot; //create a lightweight tree parser, which will actually close nodes var spineParser = parser.GetSpineParser(line.Start); var startNodes = spineParser.Spine.ToList(); var startState = spineParser.CurrentState; startNodes.Reverse(); //advance the parser to the end of the line for (int i = line.Start.Position; i < line.End.Position; i++) { spineParser.Push(snapshot[i]); } var endNodes = spineParser.Spine.ToList(); endNodes.Reverse(); //count the number of elements in the stack at the start of the line //which were not closed by the end of the line int depth = 0; //special case if the line starts with something else than a closing tag, //treat it as content and don't take the remaining closing tags on the //current line into account bool startsWithClosingTag = false; var firstNonWhitespacePosition = line.GetFirstNonWhitespacePosition(); if (firstNonWhitespacePosition is int first && line.End > first + 1 && snapshot[first] == '<' && snapshot[first + 1] == '/') { startsWithClosingTag = true; } //first node is the xdocument, skip it for (int i = 1; i < startNodes.Count; i++) { if (!(startNodes[i] is XElement)) { continue; } if (startsWithClosingTag) { if (i == endNodes.Count || startNodes[i] != endNodes[i]) { break; } } depth++; } //if inside a tag state, indent a level further while (startState != null) { if (startState is XmlTagState) { depth++; } startState = startState.Parent; } int indent = indentSize * depth; return(indent); }