/// <summary>
        /// This function formats a specific line after <code>ch</code> is pressed.
        /// </summary>
        /// <returns>
        /// the caret delta position the caret will be moved this number
        /// of bytes (e.g. the number of bytes inserted before the caret, or
        /// removed, if this number is negative)
        /// </returns>
        public virtual int FormatLine(IFormattableDocument d, int line, int cursorOffset, char ch)
        {
            if (ch == '\n')
                return IndentLine (d, line);

            return 0;
        }
        /// <summary>
        /// This function sets the indentlevel in a range of lines.
        /// </summary>
        public void IndentLines(IFormattableDocument d, int begin, int end)
        {
            d.BeginAtomicUndo ();

            for (int i = begin; i <= end; ++i)
                IndentLine (d, i);

            d.EndAtomicUndo ();
        }
 /// <summary>
 /// This function sets the indentation level in a specific line
 /// </summary>
 /// <returns>
 /// the number of inserted characters.
 /// </returns>
 public int IndentLine(IFormattableDocument d, int line)
 {
     switch (d.IndentStyle) {
         case IndentStyle.Auto  : return AutoIndentLine (d, line);
         case IndentStyle.Smart : return SmartIndentLine (d, line);
         case IndentStyle.None  :
         default                : return 0;
     }
 }
        /// <summary>
        /// Could be overwritten to define more complex indenting.
        /// </summary>
        protected virtual int AutoIndentLine(IFormattableDocument d, int lineNumber)
        {
            string indentation = lineNumber != 0 ? GetIndentation (d, lineNumber - 1) : "";

            if (indentation.Length > 0) {
                string newLineText = indentation + d.GetLineAsString (lineNumber).Trim ();
                d.ReplaceLine (lineNumber, newLineText);
            }

            return indentation.Length;
        }
        // used for comment tag formater/inserter
        public override int FormatLine(IFormattableDocument d, int lineNr, int cursorOffset, char ch)
        {
            switch (ch) {
                //case '}':
                //case '{':
                //	return d.FormattingStrategy.IndentLine (d, lineNr);
                case '\n':
                    if (lineNr <= 0) {
                        return IndentLine(d, lineNr);
                    }

                    if (d.AutoInsertCurlyBracket) {
                        string oldLineText = d.GetLineAsString (lineNr - 1);
                        if (oldLineText.EndsWith ("{") && NeedCurlyBracket (d.TextContent)) {
                                d.Insert (cursorOffset, "\n}");
                                IndentLine(d, lineNr + 1);
                        }
                    }

                    string  lineAboveText = d.GetLineAsString (lineNr - 1);

            #if NON_PORTABLE_CODE
                    if (lineAbove.HighlightSpanStack != null && lineAbove.HighlightSpanStack.Count > 0) {
                        if (!((Span)lineAbove.HighlightSpanStack.Peek()).StopEOL) {	// case for /* style comments
                            int index = lineAboveText.IndexOf("/*");

                            if (index > 0) {
                                string indentation = GetIndentation(d, lineNr - 1);
                                for (int i = indentation.Length; i < index; ++ i) {
                                    indentation += ' ';
                                }
                                d.Document.Replace(curLine.Offset, cursorOffset - curLine.Offset, indentation + " * ");
                                return indentation.Length + 3;
                            }

                            index = lineAboveText.IndexOf("*");
                            if (index > 0) {
                                string indentation = GetIndentation(d, lineNr - 1);
                                for (int i = indentation.Length; i < index; ++ i) {
                                    indentation += ' ';
                                }
                                d.Document.Replace(curLine.Offset, cursorOffset - curLine.Offset, indentation + "* ");
                                return indentation.Length + 2;
                            }
                        }
                    }
            #endif
                    return IndentLine(d, lineNr);
            }
            return 0;
        }
 // used for comment tag formater/inserter
 public override int FormatLine(IFormattableDocument d, int lineNr, int caretOffset, char charTyped)
 {
     try {
         if (charTyped == '>') {
             StringBuilder stringBuilder = new StringBuilder();
             int offset = Math.Min(caretOffset - 2, d.TextLength - 1);
             while (true) {
                 if (offset < 0) {
                     break;
                 }
                 char ch = d.GetCharAt(offset);
                 if (ch == '<') {
                     string reversedTag = stringBuilder.ToString().Trim();
                     if (!reversedTag.StartsWith("/") && !reversedTag.EndsWith("/")) {
                         bool validXml = true;
                         try {
                             XmlDocument doc = new XmlDocument();
                             doc.LoadXml(d.TextContent);
                         } catch (Exception) {
                             validXml = false;
                         }
                         // only insert the tag, if something is missing
                         if (!validXml) {
                             StringBuilder tag = new StringBuilder();
                             for (int i = reversedTag.Length - 1; i >= 0 && !Char.IsWhiteSpace(reversedTag[i]); --i) {
                                 tag.Append(reversedTag[i]);
                             }
                             string tagString = tag.ToString();
                             if (tagString.Length > 0) {
                                 d.Insert(caretOffset, "</" + tagString + ">");
                             }
                         }
                     }
                     break;
                 }
                 stringBuilder.Append(ch);
                 --offset;
             }
         }
     } catch (Exception e) { // Insanity check
         Debug.Assert(false, e.ToString());
     }
     return charTyped == '\n' ? IndentLine(d, lineNr) : 0;
 }
        public override int FormatLine(IFormattableDocument textArea, int lineNr, int cursorOffset, char ch)
        {
            PropertyService propertyService = (PropertyService)ServiceManager.GetService(typeof(PropertyService));
            doCasing = propertyService.GetProperty("VBBinding.TextEditor.EnableCasing", true);
            doInsertion = propertyService.GetProperty("VBBinding.TextEditor.EnableEndConstructs", true);

            if (lineNr > 0) {
                //LineSegment curLine = textArea.Document.GetLineSegment(lineNr);
                //LineSegment lineAbove = lineNr > 0 ? textArea.Document.GetLineSegment(lineNr - 1) : null;

                //string curLineText = textArea.Document.GetText(curLine.Offset, curLine.Length);
                //string lineAboveText = textArea.Document.GetText(lineAbove.Offset, lineAbove.Length);
                string curLineText=textArea.GetLineAsString(lineNr).Trim();
                string lineAboveText=textArea.GetLineAsString(lineNr-1).Trim();

                if (ch == '\n' && lineAboveText != null) {
                    int undoCount = 1;

                    // remove comments
                    string texttoreplace = Regex.Replace(lineAboveText, "'.*$", "", RegexOptions.Singleline);
                    // remove string content
                    MatchCollection strmatches = Regex.Matches(texttoreplace, "\"[^\"]*?\"", RegexOptions.Singleline);
                    foreach (Match match in strmatches) {
                        texttoreplace = texttoreplace.Remove(match.Index, match.Length).Insert(match.Index, new String('-', match.Length));
                    }

                    if (doCasing) {
                        foreach (string keyword in keywords) {
                            string regex = "(?:\\W|^)(" + keyword + ")(?:\\W|$)";
                            MatchCollection matches = Regex.Matches(texttoreplace, regex, RegexOptions.IgnoreCase | RegexOptions.Singleline);
                            foreach (Match match in matches) {
                                textArea.ReplaceLine(lineNr-1 + match.Groups[1].Index, keyword);
                                ++undoCount;
                            }
                        }
                    }

                    if (doInsertion) {
                        foreach (VBStatement statement in statements) {
                            if (Regex.IsMatch(texttoreplace.Trim(), statement.StartRegex, RegexOptions.IgnoreCase)) {
                                string indentation = GetIndentation(textArea, lineNr - 1);
                                if (isEndStatementNeeded(textArea, statement, lineNr)) {
                                    //textArea.Insert(textArea.Caret.Offset, "\n" + indentation + statement.EndStatement);
                                    //++undoCount;
                                }
                                for (int i = 0; i < statement.IndentPlus; i++) {
                                    indentation += "\t";	//Tab.GetIndentationString(textArea.Document);
                                }

                                textArea.ReplaceLine(lineNr, indentation + curLineText.Trim());
                                //Is this automagic now?
                                //textArea.Document.UndoStack.UndoLast(undoCount + 1);
                                return indentation.Length;
                            }
                        }
                    }

                    if (IsInString(lineAboveText)) {
                        if (IsFinishedString(curLineText)) {
                            textArea.Insert(lineNr-1 + lineAboveText.Length,
                                                     "\" & _");
                            curLineText = textArea.GetLineAsString(lineNr);
                            textArea.Insert(lineNr, "\"");

                            if (IsElseConstruct(lineAboveText))
                                SmartIndentLine(textArea, lineNr - 1);
                            int result = SmartIndentLine(textArea, lineNr) + 1;
                            //textArea.UndoStack.UndoLast(undoCount + 3);
                            return result;
                        } else {
                            textArea.Insert(lineNr-1 + lineAboveText.Length,
                                                     "\"");
                            if (IsElseConstruct(lineAboveText))
                                SmartIndentLine(textArea, lineNr - 1);
                            int result = SmartIndentLine(textArea, lineNr);
                            //textArea.Document.UndoStack.UndoLast(undoCount + 2);
                            return result;
                        }
                    } else {
                        string indent = GetIndentation(textArea, lineNr - 1);
                        if (indent.Length > 0) {
                            //string newLineText = indent + TextUtilities.GetLineAsString(textArea.Document, lineNr).Trim();
                            string newLineText=indent + textArea.GetLineAsString(lineNr).Trim();
                            //curLine = textArea.GetLineAsString(lineNr);
                            textArea.ReplaceLine(lineNr, newLineText);
                            //++undoCount;
                        }
                        if (IsElseConstruct(lineAboveText))
                            SmartIndentLine(textArea, lineNr - 1);
                        //textArea.Document.UndoStack.UndoLast(undoCount);
                        return indent.Length;
                    }
                }
            }
            return 0;
        }
        bool isEndStatementNeeded(IFormattableDocument textArea, VBStatement statement, int lineNr)
        {
            int count = 0;
            int i=0;

            //for (int i = 0; i < textArea.TotalNumberOfLines; i++) {
            try{
                while(true){
                    //LineSegment line = textArea.Document.GetLineSegment(i);
                    //string lineText = textArea.Document.GetText(line.Offset, line.Length).Trim();
                    string lineText=textArea.GetLineAsString(i++).Trim();

                    if (lineText.StartsWith("'")) {
                        continue;
                    }

                    if (Regex.IsMatch(lineText, statement.StartRegex, RegexOptions.IgnoreCase)) {
                        count++;
                    } else if (Regex.IsMatch(lineText, statement.EndRegex, RegexOptions.IgnoreCase)) {
                        count--;
                    }
                }
            } catch(Exception ex){
                //exit while
            }//try
            return count > 0;
        }
 static int ScanLineStart(IFormattableDocument document, int offset)
 {
     bool hasComment = false;
     for (int i = offset - 1; i > 0; --i) {
         char ch = document.GetCharAt(i);
         if (ch == '\n') {
             if (!hasComment) return -1;
             return i + 1;
         } else if (ch == '\'') {
             hasComment = true;
         }
     }
     return 0;
 }
        /// <summary>
        /// Define VB.net specific smart indenting for a line :)
        /// </summary>
        protected override int SmartIndentLine(IFormattableDocument textArea, int lineNr)
        {
            PropertyService propertyService = (PropertyService)ServiceManager.GetService(typeof(PropertyService));
            doCasing = propertyService.GetProperty("VBBinding.TextEditor.EnableCasing", true);
            IFormattableDocument document = textArea;
            if (lineNr <= 0)
                return AutoIndentLine(textArea, lineNr);
            //LineSegment lineAbove = document.GetLineSegment(lineNr - 1);
            //string lineAboveText = document.GetText(lineAbove.Offset, lineAbove.Length).Trim();
            string lineAboveText=document.GetLineAsString(lineNr-1).Trim();

            //LineSegment curLine = document.GetLineSegment(lineNr);
            //string oldLineText = document.GetText(curLine.Offset, curLine.Length);
            string oldLineText=document.GetLineAsString(lineNr);
            string curLineText = oldLineText.Trim();

            // remove comments
            string texttoreplace = Regex.Replace(lineAboveText, "'.*$", "", RegexOptions.Singleline).Trim();
            // remove string content
            foreach (Match match in Regex.Matches(texttoreplace, "\"[^\"]*?\"")) {
                texttoreplace = texttoreplace.Remove(match.Index, match.Length).Insert(match.Index, new String('-', match.Length));
            }

            string curLineReplace = Regex.Replace(curLineText, "'.*$", "", RegexOptions.Singleline).Trim();
            // remove string content
            foreach (Match match in Regex.Matches(curLineReplace, "\"[^\"]*?\"")) {
                curLineReplace = curLineReplace.Remove(match.Index, match.Length).Insert(match.Index, new String('-', match.Length));
            }

            StringBuilder b = new StringBuilder(GetIndentation(textArea, lineNr - 1));

            //string indentString = Tab.GetIndentationString(document);
            string indentString="\t";

            if (texttoreplace.IndexOf(':') > 0)
                texttoreplace = texttoreplace.Substring(0, texttoreplace.IndexOf(':')).TrimEnd();

            bool matched = false;
            foreach (VBStatement statement in statements) {
                if (statement.IndentPlus == 0) continue;
                if (Regex.IsMatch(curLineReplace, statement.EndRegex, RegexOptions.IgnoreCase)) {
                    for (int i = 0; i < statement.IndentPlus; ++i) {
                        RemoveIndent(b);
                    }
                    if (doCasing && !statement.EndStatement.EndsWith(" "))
                        curLineText = statement.EndStatement;
                    matched = true;
                }
                if (Regex.IsMatch(texttoreplace, statement.StartRegex, RegexOptions.IgnoreCase)) {
                    for (int i = 0; i < statement.IndentPlus; ++i) {
                        b.Append(indentString);
                    }
                    matched = true;
                }
                if (matched)
                    break;
            }

            if (lineNr >= 2) {
                if (texttoreplace.EndsWith("_")) {
                    // Line continuation
                    char secondLastChar = ' ';
                    for (int i = texttoreplace.Length - 2; i >= 0; --i) {
                        secondLastChar = texttoreplace[i];
                        if (!Char.IsWhiteSpace(secondLastChar))
                            break;
                    }
                    if (secondLastChar != '>') {
                        // is not end of attribute
                        //LineSegment line2Above = document.GetLineSegment(lineNr - 2);
                        //string lineAboveText2 = document.GetText(line2Above.Offset, line2Above.Length).Trim();
                        string lineAboveText2=document.GetLineAsString(lineNr-2).Trim();
                        lineAboveText2 = Regex.Replace(lineAboveText2, "'.*$", "", RegexOptions.Singleline).Trim();
                        if (!lineAboveText2.EndsWith("_")) {
                            b.Append(indentString);
                        }
                    }
                } else {
                    //LineSegment line2Above = document.GetLineSegment(lineNr - 2);
                    //string lineAboveText2 = document.GetText(line2Above.Offset, line2Above.Length).Trim();
                    string lineAboveText2=document.GetLineAsString(lineNr-2).Trim();
                    lineAboveText2 = StripComment(lineAboveText2);
                    if (lineAboveText2.EndsWith("_")) {
                        char secondLastChar = ' ';
                        for (int i = texttoreplace.Length - 2; i >= 0; --i) {
                            secondLastChar = texttoreplace[i];
                            if (!Char.IsWhiteSpace(secondLastChar))
                                break;
                        }
                        if (secondLastChar != '>')
                            RemoveIndent(b);
                    }
                }
            }

            if (IsElseConstruct(curLineText))
                RemoveIndent(b);

            if (IsElseConstruct(lineAboveText))
                b.Append(indentString);

            int indentLength = b.Length;
            b.Append(curLineText);
            if (b.ToString() != oldLineText)
                textArea.ReplaceLine(lineNr, b.ToString());
            return indentLength;
        }
 public int SearchBracketForward(IFormattableDocument document, int offset, char openBracket, char closingBracket)
 {
     bool inString  = false;
     bool inComment = false;
     int  brackets  = 1;
     for (int i = offset; i < document.TextLength; ++i) {
         char ch = document.GetCharAt(i);
         if (ch == '\n') {
             inString  = false;
             inComment = false;
         }
         if (inComment) continue;
         if (ch == '"') inString = !inString;
         if (inString)  continue;
         if (ch == '\'') {
             inComment = true;
         } else if (ch == openBracket) {
             ++brackets;
         } else if (ch == closingBracket) {
             --brackets;
             if (brackets == 0) return i;
         }
     }
     return -1;
 }
 /// <summary>
 /// Could be overwritten to define more complex indenting.
 /// </summary>
 protected virtual int SmartIndentLine(IFormattableDocument d, int line)
 {
     return AutoIndentLine (d, line); // smart = autoindent in normal texts
 }
Beispiel #13
0
        // used for comment tag formater/inserter
        public override int FormatLine(IFormattableDocument d, int lineNr, int cursorOffset, char ch)
        {
            switch (ch)
            {
            //case '}':
            //case '{':
            //	return d.FormattingStrategy.IndentLine (d, lineNr);
            case '\n':
                if (lineNr <= 0)
                {
                    return(IndentLine(d, lineNr));
                }

                if (d.AutoInsertCurlyBracket)
                {
                    string oldLineText = d.GetLineAsString(lineNr - 1);
                    if (oldLineText.EndsWith("{") && NeedCurlyBracket(d.TextContent))
                    {
                        d.Insert(cursorOffset, "\n}");
                        IndentLine(d, lineNr + 1);
                    }
                }

                string lineAboveText = d.GetLineAsString(lineNr - 1);


#if NON_PORTABLE_CODE
                if (lineAbove.HighlightSpanStack != null && lineAbove.HighlightSpanStack.Count > 0)
                {
                    if (!((Span)lineAbove.HighlightSpanStack.Peek()).StopEOL)                                   // case for /* style comments
                    {
                        int index = lineAboveText.IndexOf("/*");

                        if (index > 0)
                        {
                            string indentation = GetIndentation(d, lineNr - 1);
                            for (int i = indentation.Length; i < index; ++i)
                            {
                                indentation += ' ';
                            }
                            d.Document.Replace(curLine.Offset, cursorOffset - curLine.Offset, indentation + " * ");
                            return(indentation.Length + 3);
                        }

                        index = lineAboveText.IndexOf("*");
                        if (index > 0)
                        {
                            string indentation = GetIndentation(d, lineNr - 1);
                            for (int i = indentation.Length; i < index; ++i)
                            {
                                indentation += ' ';
                            }
                            d.Document.Replace(curLine.Offset, cursorOffset - curLine.Offset, indentation + "* ");
                            return(indentation.Length + 2);
                        }
                    }
                }
#endif
                return(IndentLine(d, lineNr));
            }
            return(0);
        }
        /// <summary>
        /// returns the whitespaces which are before a non white space character in the line line
        /// as a string.
        /// </summary>
        protected string GetIndentation(IFormattableDocument d, int lineNumber)
        {
            string lineText = d.GetLineAsString (lineNumber);
            StringBuilder whitespaces = new StringBuilder ();

            foreach (char ch in lineText) {
                if (! Char.IsWhiteSpace (ch))
                    break;
                whitespaces.Append (ch);
            }

            return whitespaces.ToString ();
        }
        bool IsInsideStringOrComment(IFormattableDocument d, int curLineOffset, int cursorOffset)
        {
            // scan cur line if it is inside a string or single line comment (//)
            bool isInsideString  = false;

            for (int i = curLineOffset; i < cursorOffset; ++i) {
                char ch = d.GetCharAt (i);
                if (ch == '"')
                    isInsideString = !isInsideString;

                if (ch == '/' && i + 1 < cursorOffset && d.GetCharAt (i + 1) == '/')
                    return true;
            }

            return isInsideString;
        }
        // used for comment tag formater/inserter
        public override int FormatLine(IFormattableDocument d, int lineNr, int cursorOffset, char ch)
        {
            int curLineOffset, curLineLength;
            d.GetLineLengthInfo (lineNr, out curLineOffset, out curLineLength);

            if (ch != '\n' && ch != '>' && IsInsideStringOrComment (d, curLineOffset, cursorOffset))
                return 0;

            switch (ch) {
                case '>':
                    if (IsInsideDocumentationComment (d, curLineOffset, cursorOffset)) {
                        string curLineText  = d.GetLineAsString (lineNr);
                        int column = cursorOffset - curLineOffset;
                        int index = Math.Min (column - 1, curLineText.Length - 1);
                        if (curLineText [index] == '/')
                            break;

                        while (index >= 0 && curLineText [index] != '<')
                            --index;

                        if (index > 0) {
                            bool skipInsert = false;
                            for (int i = index; i < curLineText.Length && i < column; ++i) {
                                if (i < curLineText.Length && curLineText [i] == '/' && curLineText [i + 1] == '>')
                                    skipInsert = true;

                                if (curLineText [i] == '>')
                                    break;
                            }

                            if (skipInsert)
                                break;

                            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 (">"))
                                tag += ">";

                            if (!tag.StartsWith ("/"))
                                d.Insert (cursorOffset, "</" + tag.Substring (1));
                        }
                    }
                    break;
                case '}':
                case '{':
                    return IndentLine (d, lineNr);
                case '\n':
                    if (lineNr <= 0)
                        return IndentLine (d, lineNr);

                    if (d.AutoInsertCurlyBracket) {
                        string oldLineText = d.GetLineAsString (lineNr - 1);
                        if (oldLineText.EndsWith ("{") && NeedCurlyBracket (d.TextContent)) {
                            d.Insert (cursorOffset, "\n}");
                            IndentLine (d, lineNr + 1);
                        }
                    }

                    //string  lineAboveText = d.GetLineAsString (lineNr - 1);

            #if NON_PORTABLE_CODE
                    if (lineAbove.HighlightSpanStack != null && lineAbove.HighlightSpanStack.Count > 0) {
                        if (!((Span)lineAbove.HighlightSpanStack.Peek ()).StopEOL) {	// case for /* style comments
                            int index = lineAboveText.IndexOf ("/*");

                            if (index > 0) {
                                string indentation = GetIndentation (d, lineNr - 1);
                                for (int i = indentation.Length; i < index; ++ i)
                                    indentation += ' ';

                                d.Replace (curLine.Offset, cursorOffset - curLine.Offset, indentation + " * ");
                                return indentation.Length + 3;
                            }

                            index = lineAboveText.IndexOf ("*");
                            if (index > 0) {
                                string indentation = GetIndentation (d, lineNr - 1);
                                for (int i = indentation.Length; i < index; ++ i)
                                    indentation += ' ';

                                d.Replace (curLine.Offset, cursorOffset - curLine.Offset, indentation + "* ");
                                return indentation.Length + 2;
                            }
                        } else {
                            LineSegment nextLine = lineNr + 1 < d.TotalNumberOfLines ? d.GetLineSegment (lineNr + 1) : null;
                            string  nextLineText  = lineNr + 1 < d.TotalNumberOfLines ? d.GetText (nextLine.Offset, nextLine.Length) : "";

                            // don't handle // lines, because they're only one lined comments
                            int indexAbove = lineAboveText.IndexOf ("///");
                            int indexNext  = nextLineText.IndexOf ("///");

                            if (indexAbove > 0 && (indexNext != -1 || indexAbove + 4 < lineAbove.Length)) {
                                string indentation = GetIndentation (d, lineNr - 1);
                                for (int i = indentation.Length; i < indexAbove; ++ i)
                                    indentation += ' ';

                                d.Replace (curLine.Offset, cursorOffset - curLine.Offset, indentation + "/// ");
                                return indentation.Length + 4;
                            }
                        }
                    }
            #endif
                    return IndentLine (d, lineNr);
            }
            return 0;
        }
Beispiel #17
0
        /// <summary>
        /// Define Java specific smart indenting for a line :)
        /// </summary>
        protected override int SmartIndentLine(IFormattableDocument d, int lineNr)
        {
            if (lineNr > 0)
            {
                string lineAboveText     = d.GetLineAsString(lineNr - 1);
                string trimlineAboveText = lineAboveText.Trim();
                string curLineText       = d.GetLineAsString(lineNr);
                string trimcurLineText   = curLineText.Trim();

                if (lineAboveText.EndsWith(")") && curLineText.StartsWith("{"))
                {
                    string indentation = GetIndentation(d, lineNr - 1);
                    d.ReplaceLine(lineNr, indentation + curLineText);
                    return(indentation.Length);
                }

                if (curLineText.StartsWith("}"))                   // indent closing bracket.
                {
                    int openLine;
                    int closingBracketOffset = d.GetClosingBraceForLine(lineNr, out openLine);
                    if (closingBracketOffset == -1)                        // no closing bracket found -> autoindent
                    {
                        return(AutoIndentLine(d, lineNr));
                    }

                    string indentation = GetIndentation(d, lineNr - 1);

                    d.ReplaceLine(lineNr, indentation + curLineText);
                    return(indentation.Length);
                }

                if (lineAboveText.EndsWith(";"))                   // expression ended, reset to valid indent.
                {
                    int openLine;
                    int closingBracketOffset = d.GetClosingBraceForLine(lineNr, out openLine);
                    if (closingBracketOffset == -1)                        // no closing bracket found -> autoindent
                    {
                        return(AutoIndentLine(d, lineNr));
                    }

                    string closingBracketLineText = d.GetLineAsString(openLine).Trim();

                    string indentation = GetIndentation(d, openLine);

                    // special handling for switch statement formatting.
                    if (closingBracketLineText.StartsWith("switch"))
                    {
                        if (lineAboveText.StartsWith("break;") ||
                            lineAboveText.StartsWith("goto") ||
                            lineAboveText.StartsWith("return"))
                        {
                        }
                        else
                        {
                            indentation += d.IndentString;
                        }
                    }
                    indentation += d.IndentString;

                    d.ReplaceLine(lineNr, indentation + curLineText);
                    return(indentation.Length);
                }

                if (lineAboveText.EndsWith("{") ||                 // indent opening bracket.
                    lineAboveText.EndsWith(":") ||                 // indent case xyz:
                    (lineAboveText.EndsWith(")") &&                // indent single line if, for ... etc
                     (lineAboveText.StartsWith("if") ||
                      lineAboveText.StartsWith("while") ||
                      lineAboveText.StartsWith("for"))) ||
                    lineAboveText.EndsWith("else"))
                {
                    string indentation = GetIndentation(d, lineNr - 1) + d.IndentString;
                    d.ReplaceLine(lineNr, indentation + curLineText);
                    return(indentation.Length);
                }
                else
                {
                    // try to indent linewrap
                    ArrayList bracketPos = new ArrayList();
                    for (int i = 0; i < lineAboveText.Length; ++i)               // search for a ( bracket that isn't closed
                    {
                        switch (lineAboveText[i])
                        {
                        case '(':
                            bracketPos.Add(i);
                            break;

                        case ')':
                            if (bracketPos.Count > 0)
                            {
                                bracketPos.RemoveAt(bracketPos.Count - 1);
                            }
                            break;
                        }
                    }
                    if (bracketPos.Count > 0)
                    {
                        int    bracketIndex = (int)bracketPos[bracketPos.Count - 1];
                        string indentation  = GetIndentation(d, lineNr - 1);

                        for (int i = 0; i <= bracketIndex; ++i)                   // insert enough spaces to match
                        {
                            indentation += " ";                                   // brace start in the next line
                        }

                        d.ReplaceLine(lineNr, indentation + curLineText);
                        return(indentation.Length);
                    }
                }
            }
            return(AutoIndentLine(d, lineNr));
        }
        /// <summary>
        /// Define Java specific smart indenting for a line :)
        /// </summary>
        protected override int SmartIndentLine(IFormattableDocument d, int lineNr)
        {
            if (lineNr > 0) {
                string  lineAboveText = d.GetLineAsString (lineNr - 1);
                string  trimlineAboveText = lineAboveText.Trim ();
                string  curLineText = d.GetLineAsString (lineNr);
                string  trimcurLineText = curLineText.Trim ();

                if (lineAboveText.EndsWith(")") && curLineText.StartsWith("{")) {
                    string indentation = GetIndentation(d, lineNr - 1);
                    d.ReplaceLine (lineNr, indentation + curLineText);
                    return indentation.Length;
                }

                if (curLineText.StartsWith("}")) { // indent closing bracket.
                    int openLine;
                    int closingBracketOffset = d.GetClosingBraceForLine (lineNr, out openLine);
                    if (closingBracketOffset == -1) {  // no closing bracket found -> autoindent
                        return AutoIndentLine(d, lineNr);
                    }

                    string indentation = GetIndentation (d, lineNr - 1);

                    d.ReplaceLine (lineNr, indentation + curLineText);
                    return indentation.Length;
                }

                if (lineAboveText.EndsWith(";")) { // expression ended, reset to valid indent.
                    int openLine;
                    int closingBracketOffset = d.GetClosingBraceForLine (lineNr, out openLine);
                    if (closingBracketOffset == -1) {  // no closing bracket found -> autoindent
                        return AutoIndentLine(d, lineNr);
                    }

                    string closingBracketLineText = d.GetLineAsString (openLine).Trim ();

                    string indentation = GetIndentation (d, openLine);

                    // special handling for switch statement formatting.
                    if (closingBracketLineText.StartsWith("switch")) {
                        if (lineAboveText.StartsWith("break;") ||
                            lineAboveText.StartsWith("goto")   ||
                            lineAboveText.StartsWith("return")) {
                        } else {
                            indentation += d.IndentString;
                        }
                    }
                    indentation += d.IndentString;

                    d.ReplaceLine (lineNr, indentation + curLineText);
                    return indentation.Length;
                }

                if (lineAboveText.EndsWith("{") || // indent opening bracket.
                    lineAboveText.EndsWith(":") || // indent case xyz:
                    (lineAboveText.EndsWith(")") &&  // indent single line if, for ... etc
                    (lineAboveText.StartsWith("if") ||
                     lineAboveText.StartsWith("while") ||
                     lineAboveText.StartsWith("for"))) ||
                     lineAboveText.EndsWith("else")) {
                        string indentation = GetIndentation (d, lineNr - 1) + d.IndentString;
                        d.ReplaceLine (lineNr, indentation + curLineText);
                        return indentation.Length;
                } else {
                    // try to indent linewrap
                    ArrayList bracketPos = new ArrayList();
                    for (int i = 0; i < lineAboveText.Length; ++i) { // search for a ( bracket that isn't closed
                        switch (lineAboveText[i]) {
                            case '(':
                                bracketPos.Add(i);
                                break;
                            case ')':
                                if (bracketPos.Count > 0) {
                                    bracketPos.RemoveAt(bracketPos.Count - 1);
                                }
                                break;
                        }
                    }
                    if (bracketPos.Count > 0) {
                        int bracketIndex = (int)bracketPos[bracketPos.Count - 1];
                        string indentation = GetIndentation (d, lineNr - 1);

                        for (int i = 0; i <= bracketIndex; ++i) { // insert enough spaces to match
                            indentation += " ";                   // brace start in the next line
                        }

                        d.ReplaceLine (lineNr, indentation + curLineText);
                        return indentation.Length;
                    }
                }
            }
            return AutoIndentLine (d, lineNr);
        }
 public int SearchBracketBackward(IFormattableDocument document, int offset, char openBracket, char closingBracket)
 {
     bool inString  = false;
     char ch;
     int brackets = -1;
     for (int i = offset; i > 0; --i) {
         ch = document.GetCharAt(i);
         if (ch == openBracket && !inString) {
             ++brackets;
             if (brackets == 0) return i;
         } else if (ch == closingBracket && !inString) {
             --brackets;
         } else if (ch == '"') {
             inString = !inString;
         } else if (ch == '\n') {
             int lineStart = ScanLineStart(document, i);
             if (lineStart >= 0) { // line could have a comment
                 inString = false;
                 for (int j = lineStart; j < i; ++j) {
                     ch = document.GetCharAt(j);
                     if (ch == '"') inString = !inString;
                     if (ch == '\'' && !inString) {
                         // comment found!
                         // Skip searching in the comment:
                         i = j;
                         break;
                     }
                 }
             }
             inString = false;
         }
     }
     return -1;
 }