Ejemplo n.º 1
0
        /// <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));
 }
Ejemplo n.º 4
0
 public static bool IsLineStartInsideString(this IHighlighter highligher, int lineNumber)
 {
     return(highligher.GetColorStack(lineNumber).Any(c => c.Name == String));
 }