/// <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 }
// 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; }
/// <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; }