/// <summary> /// Gets the type of code at offset.<br/> /// 0 = Code,<br/> /// 1 = Comment,<br/> /// 2 = String<br/> /// Block comments and multiline strings are not supported. /// </summary> private static int GetStartType(ICSharpCode.AvalonEdit.Document.TextDocument document, int linestart, int offset) { bool inString = false; bool inChar = false; bool verbatim = false; int result = 0; for (int i = linestart; i < offset; i++) { switch (document.GetCharAt(i)) { case '/': if (!inString && !inChar && i + 1 < document.TextLength) { if (document.GetCharAt(i + 1) == '/') { result = 1; } } break; case '"': if (!inChar) { if (inString && verbatim) { if (i + 1 < document.TextLength && document.GetCharAt(i + 1) == '"') { ++i; // skip escaped quote inString = false; // let the string go on } else { verbatim = false; } } else if (!inString && i > 0 && document.GetCharAt(i - 1) == '@') { verbatim = true; } inString = !inString; } break; case '\'': if (!inString) inChar = !inChar; break; case '\\': if ((inString && !verbatim) || inChar) ++i; // skip next character break; } } return (inString || inChar) ? 2 : result; }
/// <summary> /// Class constructor /// </summary> /// <param name="document"></param> /// <param name="offset"></param> /// <returns></returns> public BracketSearchResult SearchBracket(ICSharpCode.AvalonEdit.Document.ITextSource document, int offset) { if (offset > 0) { char c = document.GetCharAt(offset - 1); int index = openingBrackets.IndexOf(c); int otherOffset = -1; if (index > -1) otherOffset = SearchBracketForward(document, offset, openingBrackets[index], closingBrackets[index]); index = closingBrackets.IndexOf(c); if (index > -1) otherOffset = SearchBracketBackward(document, offset -1, openingBrackets[index], closingBrackets[index]); // if we found the other bracket if (otherOffset > -1 ) return new BracketSearchResult(Math.Min(offset - 1, otherOffset), 1, Math.Max(offset - 1, otherOffset), 1); if (otherOffset == -2) // in string return null; // if we are on a bracket, but did not find a match if (index >= 0 || openingBrackets.IndexOf(c) >= 0) return new BracketSearchResult(offset - 1, 1, 0, 0); } return null; }
public void RawlyIndentLine(int tabsToInsert, ICSharpCode.AvalonEdit.Document.TextDocument document, DocumentLine line) { if (!_doBeginUpdateManually) document.BeginUpdate(); /* * 1) Remove old indentation * 2) Insert new one */ // 1) int prevInd = 0; int curOff = line.Offset; if (curOff < document.TextLength) { char curChar = '\0'; while (curOff < document.TextLength && ((curChar = document.GetCharAt(curOff)) == ' ' || curChar == '\t')) { prevInd++; curOff++; } document.Remove(line.Offset, prevInd); } // 2) string indentString = ""; for (int i = 0; i < tabsToInsert; i++) indentString += dEditor.Editor.Options.IndentationString; document.Insert(line.Offset, indentString); if (!_doBeginUpdateManually) document.EndUpdate(); }
static TextLocation FindMethodStart(ICSharpCode.TextEditor.Document.IDocument document, DomRegion bodyRegion) { if (bodyRegion.IsEmpty) return TextLocation.Empty; int offset = document.PositionToOffset(new TextLocation(bodyRegion.BeginColumn - 1, bodyRegion.BeginLine - 1)); while (offset < document.TextLength) { if (document.GetCharAt(offset) == '{') { return document.OffsetToPosition(offset + 1); } offset++; } return TextLocation.Empty; }
/// <summary> /// Class constructor /// </summary> /// <param name="document"></param> /// <param name="offset"></param> /// <returns></returns> public BracketSearchResult SearchBracket(ICSharpCode.AvalonEdit.Document.TextDocument document, int offset) { if (offset > 0) { char c = document.GetCharAt(offset - 1); int index = openingBrackets.IndexOf(c); int otherOffset = -1; if (index > -1) otherOffset = SearchBracketForward(document, offset, openingBrackets[index], closingBrackets[index]); index = closingBrackets.IndexOf(c); if (index > -1) otherOffset = SearchBracketBackward(document, offset - 2, openingBrackets[index], closingBrackets[index]); if (otherOffset > -1) return new BracketSearchResult(Math.Min(offset - 1, otherOffset), 1, Math.Max(offset - 1, otherOffset), 1); } return null; }
public void RawlyIndentLine(string indentString, ICSharpCode.AvalonEdit.Document.TextDocument document, DocumentLine line) { if (!_doBeginUpdateManually) document.BeginUpdate(); // 1) int prevInd = 0; int curOff = line.Offset; if (curOff < document.TextLength) { char curChar = '\0'; while (curOff < document.TextLength && ((curChar = document.GetCharAt(curOff)) == ' ' || curChar == '\t')) { prevInd++; curOff++; } document.Remove(line.Offset, prevInd); } document.Insert(line.Offset, indentString); if (!_doBeginUpdateManually) document.EndUpdate(); }
private int SearchBracketForward(ICSharpCode.AvalonEdit.Document.ITextSource document, int offset, char openBracket, char closingBracket) { bool inString = false; bool inChar = false; bool verbatim = false; bool lineComment = false; bool blockComment = false; if (offset < 0) return -1; // first try "quick find" - find the matching bracket if there is no string/comment in the way int quickResult = QuickSearchBracketForward(document, offset, openBracket, closingBracket); if (quickResult >= 0) return quickResult; // we need to parse the line from the beginning, so get the line start position int linestart = ScanLineStart(document, offset); // we need to know where offset is - in a string/comment or in normal code? // ignore cases where offset is in a block comment int starttype = GetStartType(document, linestart, offset); if (starttype != 0) return -1; // start position is in a comment/string int brackets = 1; while (offset < document.TextLength) { char ch = document.GetCharAt(offset); switch (ch) { case '\r': case '\n': lineComment = false; inChar = false; if (!verbatim) inString = false; break; case '-': if (!inString && !blockComment && document.GetCharAt(offset - 1) == '-') { lineComment = true; } break; case '/': if (blockComment) { Debug.Assert(offset > 0); if (document.GetCharAt(offset - 1) == '*') { blockComment = false; } } if (!inString && !inChar && offset + 1 < document.TextLength) { if (!blockComment && document.GetCharAt(offset + 1) == '/') { lineComment = true; } if (!lineComment && document.GetCharAt(offset + 1) == '*') { blockComment = true; } } break; case '"': if (!(inChar || lineComment || blockComment )) { if (inString && verbatim) { if (offset + 1 < document.TextLength && document.GetCharAt(offset + 1) == '"') { ++offset; // skip escaped quote inString = false; // let the string go } else { verbatim = false; } } else if (!inString && offset > 0 && document.GetCharAt(offset - 1) == '@') { verbatim = true; } inString = !inString; } break; case '\'': if (!(inString || lineComment || blockComment)) { inChar = !inChar; } break; case '\\': if ((inString && !verbatim) || inChar) ++offset; // skip next character break; default: if (ch == openBracket) { if (!(inString || inChar || lineComment || blockComment )) { ++brackets; } } else if (ch == closingBracket) { if (!(inString || inChar || lineComment || blockComment)) { --brackets; if (brackets == 0) { return offset; } } } break; } ++offset; } if (inString || inChar || lineComment || blockComment) return -2; return -1; }
private int SearchBracketBackward(ICSharpCode.AvalonEdit.Document.ITextSource document, int offset, char openBracket, char closingBracket) { if (offset >= document.TextLength) return -1; // this method parses a DAX document backwards to find the matching bracket // first try "quick find" - find the matching bracket if there is no string/comment in the way int quickResult = QuickSearchBracketBackward(document, offset, openBracket, closingBracket); if (quickResult >= 0) return quickResult; // we need to parse the line from the beginning, so get the line start position int linestart = ScanLineStart(document, offset + 1); // we need to know where offset is - in a string/comment or in normal code? // ignore cases where offset is in a block comment int starttype = GetStartType(document, linestart, offset + 1); if (starttype == 1) { return -2; // start position is in a comment } // I don't see any possibility to parse a DAX document backwards... // We have to do it forwards and push all bracket positions on a stack. Stack<int> bracketStack = new Stack<int>(); bool blockComment = false; bool lineComment = false; bool inChar = false; bool inString = false; bool verbatim = false; for (int i = 0; i < offset; ++i) { char ch = document.GetCharAt(i); switch (ch) { case '\r': case '\n': lineComment = false; inChar = false; if (!verbatim) inString = false; break; case '-': if (!inString && !inChar && !blockComment && i != document.TextLength ) { if (i > 0) { if (document.GetCharAt(i - 1) == '-') { lineComment = true; } } } break; case '/': if (blockComment) { Debug.Assert(i > 0); if (document.GetCharAt(i - 1) == '*') { blockComment = false; } } if (!inString && !inChar && i + 1 < document.TextLength) { if (!blockComment && document.GetCharAt(i + 1) == '/') { lineComment = true; } if (!lineComment && document.GetCharAt(i + 1) == '*') { blockComment = true; } } break; case '"': if (!(inChar || lineComment || blockComment)) { if (inString && verbatim) { if (i + 1 < document.TextLength && document.GetCharAt(i + 1) == '"') { ++i; // skip escaped quote inString = false; // let the string go } else { verbatim = false; } } else if (!inString && offset > 0 && document.GetCharAt(i - 1) == '@') { verbatim = true; } inString = !inString; } break; case '\'': if (!(inString || lineComment || blockComment)) { inChar = !inChar; } break; case '\\': if ((inString && !verbatim) || inChar) ++i; // skip next character break; default: if (ch == openBracket) { if (!(inString || inChar || lineComment || blockComment)) { bracketStack.Push(i); } } else if (ch == closingBracket) { if (!(inString || inChar || lineComment || blockComment)) { if (bracketStack.Count > 0) bracketStack.Pop(); } } break; } } if (bracketStack.Count > 0 && !inString && !inChar && !lineComment && !blockComment) return (int)bracketStack.Pop(); if (inString || inChar || lineComment || blockComment) return -2; return -1; }
private int QuickSearchBracketForward(ICSharpCode.AvalonEdit.Document.ITextSource document, int offset, char openBracket, char closingBracket) { int brackets = 1; // try "quick find" - find the matching bracket if there is no string/comment in the way for (int i = offset; i < document.TextLength; ++i) { char ch = document.GetCharAt(i); if (ch == openBracket) { ++brackets; } else if (ch == closingBracket) { --brackets; if (brackets == 0) return i; } else if (ch == '"') { break; } else if (ch == '\'') { break; } else if (ch == '/' && i > 0) { if (document.GetCharAt(i - 1) == '/') break; } else if (ch == '-' && i > 0) { if (document.GetCharAt(i - 1) == '-') break; } else if (ch == '*' && i > 0) { if (document.GetCharAt(i - 1) == '/') break; } } return -1; }
private static int ScanLineStart(ICSharpCode.AvalonEdit.Document.ITextSource document, int offset) { for (int i = offset - 1; i > 0; --i) { if (document.GetCharAt(i) == '\n') return i + 1; } return 0; }