/// <summary> /// Retrieves the names of the spans that are active at the start of the specified line. /// </summary> /// <param name="highlighter">The syntax highlighter.</param> /// <param name="lineNumber">The line number.</param> /// <returns> /// The spans that are active at the start of the specified line. Nested spans are returned in /// inside-out order (first element of result enumerable is the innermost span). /// </returns> public static IEnumerable <string> GetSpanColorNamesFromLineStart(this IHighlighter highlighter, int lineNumber) { if (highlighter != null) { return(highlighter.GetColorStack(lineNumber - 1) .Select(highlightingColor => highlightingColor.Name) .Where(name => !string.IsNullOrWhiteSpace(name))); } return(Enumerable.Empty <string>()); }
void FormatLineInternal(ITextEditor textArea, int lineNr, int cursorOffset, char ch) { IDocumentLine curLine = textArea.Document.GetLineByNumber(lineNr); IDocumentLine lineAbove = lineNr > 1 ? textArea.Document.GetLineByNumber(lineNr - 1) : null; string terminator = DocumentUtilities.GetLineTerminator(textArea.Document, lineNr); string curLineText; // local string for curLine segment if (ch == '/') { curLineText = textArea.Document.GetText(curLine); string lineAboveText = lineAbove == null ? "" : textArea.Document.GetText(lineAbove); if (curLineText != null && curLineText.EndsWith("///", StringComparison.Ordinal) && (lineAboveText == null || !lineAboveText.Trim().StartsWith("///", StringComparison.Ordinal))) { string indentation = DocumentUtilities.GetWhitespaceAfter(textArea.Document, curLine.Offset); IUnresolvedEntity member = GetMemberAfter(textArea, lineNr); if (member != null) { StringBuilder sb = new StringBuilder(); sb.Append(" <summary>"); sb.Append(terminator); sb.Append(indentation); sb.Append("/// "); sb.Append(terminator); sb.Append(indentation); sb.Append("/// </summary>"); IUnresolvedMethod method = null; if (member is IUnresolvedMethod) { method = (IUnresolvedMethod)member; } else if (member is IUnresolvedTypeDefinition) { IUnresolvedTypeDefinition type = (IUnresolvedTypeDefinition)member; if (type.Kind == TypeKind.Delegate) { method = type.Methods.FirstOrDefault(m => m.Name == "Invoke"); } } if (method != null) { for (int i = 0; i < method.Parameters.Count; ++i) { sb.Append(terminator); sb.Append(indentation); sb.Append("/// <param name=\""); sb.Append(method.Parameters[i].Name); sb.Append("\"></param>"); } if (!method.IsConstructor) { KnownTypeReference returnType = method.ReturnType as KnownTypeReference; if (returnType == null || returnType.KnownTypeCode != KnownTypeCode.Void) { sb.Append(terminator); sb.Append(indentation); sb.Append("/// <returns></returns>"); } } } textArea.Document.Insert(cursorOffset, sb.ToString()); textArea.Caret.Offset = cursorOffset + indentation.Length + "/// ".Length + " <summary>".Length + terminator.Length; } } return; } if (ch != '\n' && ch != '>') { if (IsInsideStringOrComment(textArea, curLine, cursorOffset)) { return; } } switch (ch) { case '>': if (IsInsideDocumentationComment(textArea, curLine, cursorOffset)) { curLineText = textArea.Document.GetText(curLine); int column = cursorOffset - curLine.Offset; int index = Math.Min(column - 1, curLineText.Length - 1); while (index >= 0 && curLineText[index] != '<') { --index; if (curLineText[index] == '/') { return; // the tag was an end tag or already } } if (index > 0) { StringBuilder commentBuilder = new StringBuilder(""); for (int i = index; i < curLineText.Length && i < column && !Char.IsWhiteSpace(curLineText[i]); ++i) { commentBuilder.Append(curLineText[i]); } string tag = commentBuilder.ToString().Trim(); if (!tag.EndsWith(">", StringComparison.Ordinal)) { tag += ">"; } if (!tag.StartsWith("/", StringComparison.Ordinal)) { textArea.Document.Insert(cursorOffset, "</" + tag.Substring(1), AnchorMovementType.BeforeInsertion); } } } break; case ':': case ')': case ']': case '{': //if (textArea.Document.TextEditorProperties.IndentStyle == IndentStyle.Smart) { IndentLine(textArea, curLine); //} break; case '}': // Try to get corresponding block beginning brace var bracketSearchResult = textArea.Language.BracketSearcher.SearchBracket(textArea.Document, cursorOffset); if (bracketSearchResult != null) { // Format the block if (!FormatStatement(textArea, cursorOffset, bracketSearchResult.OpeningBracketOffset)) { // No auto-formatting seems to be active, at least indent the line IndentLine(textArea, curLine); } } break; case ';': // Format this line if (!FormatStatement(textArea, cursorOffset, cursorOffset)) { // No auto-formatting seems to be active, at least indent the line IndentLine(textArea, curLine); } break; case '\n': string lineAboveText = lineAbove == null ? "" : textArea.Document.GetText(lineAbove); // curLine might have some text which should be added to indentation curLineText = textArea.Document.GetText(curLine); if (lineAboveText != null && lineAboveText.Trim().StartsWith("#region", StringComparison.Ordinal) && NeedEndregion(textArea.Document)) { textArea.Document.Insert(cursorOffset, "#endregion"); return; } IHighlighter highlighter = textArea.GetService(typeof(IHighlighter)) as IHighlighter; bool isInMultilineComment = false; bool isInMultilineString = false; if (highlighter != null && lineAbove != null) { var spanStack = highlighter.GetColorStack(lineNr).Select(c => c.Name).ToArray(); isInMultilineComment = spanStack.Contains(HighlighterKnownSpanNames.Comment); isInMultilineString = spanStack.Contains(HighlighterKnownSpanNames.String); } bool isInNormalCode = !(isInMultilineComment || isInMultilineString); if (lineAbove != null && isInMultilineComment) { string lineAboveTextTrimmed = lineAboveText.TrimStart(); if (lineAboveTextTrimmed.StartsWith("/*", StringComparison.Ordinal)) { textArea.Document.Insert(cursorOffset, " * "); return; } if (lineAboveTextTrimmed.StartsWith("*", StringComparison.Ordinal)) { textArea.Document.Insert(cursorOffset, "* "); return; } } if (lineAbove != null && isInNormalCode) { IDocumentLine nextLine = lineNr + 1 <= textArea.Document.LineCount ? textArea.Document.GetLineByNumber(lineNr + 1) : null; string nextLineText = (nextLine != null) ? textArea.Document.GetText(nextLine) : ""; int indexAbove = lineAboveText.IndexOf("///", StringComparison.Ordinal); int indexNext = nextLineText.IndexOf("///", StringComparison.Ordinal); if (indexAbove > 0 && (indexNext != -1 || indexAbove + 4 < lineAbove.Length)) { textArea.Document.Insert(cursorOffset, "/// "); return; } if (IsInNonVerbatimString(lineAboveText, curLineText)) { textArea.Document.Insert(cursorOffset, "\""); textArea.Document.Insert(lineAbove.Offset + lineAbove.Length, "\" +"); } } if (textArea.Options.AutoInsertBlockEnd && lineAbove != null && isInNormalCode) { string oldLineText = textArea.Document.GetText(lineAbove); if (oldLineText.EndsWith("{", StringComparison.Ordinal)) { if (NeedCurlyBracket(textArea.Document.Text)) { int insertionPoint = curLine.Offset + curLine.Length; textArea.Document.Insert(insertionPoint, terminator + "}"); IndentLine(textArea, textArea.Document.GetLineByNumber(lineNr + 1)); textArea.Caret.Offset = insertionPoint; } } } return; } }
public IEnumerable <HighlightingColor> GetColorStack(int lineNumber) { return(baseHighlighter.GetColorStack(lineNumber)); }
public static bool IsLineStartInsideString(this IHighlighter highligher, int lineNumber) { return(highligher.GetColorStack(lineNumber).Any(c => c.Name == String)); }