static IEnumerable <KeyValuePair <char, int> > GetTextWithoutCommentsAndStrings(Mono.TextEditor.TextDocument doc, int start, int end) { bool isInString = false, isInChar = false; bool isInLineComment = false, isInBlockComment = false; for (int pos = start; pos < end; pos++) { char ch = doc.GetCharAt(pos); switch (ch) { case '\r': case '\n': isInLineComment = false; break; case '/': if (isInBlockComment) { if (pos > 0 && doc.GetCharAt(pos - 1) == '*') { isInBlockComment = false; } } else if (!isInString && !isInChar && pos + 1 < doc.TextLength) { char nextChar = doc.GetCharAt(pos + 1); if (nextChar == '/') { isInLineComment = true; } if (!isInLineComment && nextChar == '*') { isInBlockComment = true; } } break; case '"': if (!(isInChar || isInLineComment || isInBlockComment)) { isInString = !isInString; } break; case '\'': if (!(isInString || isInLineComment || isInBlockComment)) { isInChar = !isInChar; } break; default: if (!(isInString || isInChar || isInLineComment || isInBlockComment)) { yield return(new KeyValuePair <char, int> (ch, pos)); } break; } } }
int FindNextWordOffset (TextDocument doc, int offset, bool subword) { int lineNumber = doc.OffsetToLineNumber (offset); DocumentLine line = doc.GetLine (lineNumber); if (line == null) return offset; int result = offset; int endOffset = line.Offset + line.Length; if (result == endOffset) { line = doc.GetLine (lineNumber + 1); if (line != null) result = line.Offset; return result; } CharacterClass current = GetCharacterClass (doc.GetCharAt (result), subword, false); while (result < endOffset) { CharacterClass next = GetCharacterClass (doc.GetCharAt (result), subword, false); if (next != current) { // camelCase and PascalCase handling bool camelSkip = false; if (next == CharacterClass.LowercaseLetter && current == CharacterClass.UppercaseLetter) { if (result-2 > line.Offset) { CharacterClass previous = GetCharacterClass (doc.GetCharAt (result-2), subword, false); if (previous == CharacterClass.UppercaseLetter && result-2 > offset) result--; else camelSkip = true; } } if (!camelSkip) break; } current = next; result++; } while (result < endOffset && GetCharacterClass (doc.GetCharAt (result), subword, false) == CharacterClass.Whitespace) { result++; } return result; }
int FindNextWordOffset (TextDocument doc, int offset, bool subword) { if (offset + 1 >= doc.TextLength) return doc.TextLength; int result = offset + 1; CC previous = SW.GetCharacterClass (doc.GetCharAt (result), subword, includeUnderscore); bool inIndentifier = previous != CC.Unknown && previous != CC.Whitespace; while (result < doc.TextLength) { char ch = doc.GetCharAt (result); CC current = SW.GetCharacterClass (ch, subword, includeUnderscore); //camelCase / PascalCase splitting if (subword) { if (current == CC.Digit && (previous != CC.Digit || (result-1 == offset && !Char.IsDigit (doc.GetCharAt (result-1))))) { break; } else if (previous == CC.Digit && current != CC.Digit) { break; } else if (current == CC.UppercaseLetter && previous != CC.UppercaseLetter) { break; } else if (current == CC.LowercaseLetter && previous == CC.UppercaseLetter && result - 2 > 0 && SW.GetCharacterClass (doc.GetCharAt (result - 2), subword, includeUnderscore) != CC.LowercaseLetter) { result--; break; } } //else break at end of identifiers if (previous != CC.Unknown && previous != CC.Whitespace) { inIndentifier = true; } else if (inIndentifier) { result--; break; } previous = current; result++; } foreach (FoldSegment segment in doc.GetFoldingsFromOffset (result)) { if (segment.IsFolded) result = System.Math.Max (result, segment.EndLine.Offset + segment.EndColumn); } return result; }
public static int FindNextSubwordEndOffset(TextDocument doc, int offset) { int myoffset = offset + 1; if (!OffsetIsWithinBounds (doc, myoffset)) { return myoffset; } char c = doc.GetCharAt (myoffset); // skip whitespace while (char.IsWhiteSpace (c)) { if (OffsetIsWithinBounds (doc, ++myoffset)) { c = doc.GetCharAt (myoffset); } else { return offset; } } var initialClass = ViWordFindStrategy.GetCharacterClass (c); while (ViWordFindStrategy.GetCharacterClass (c) == initialClass && 0 <= myoffset && doc.TextLength-1 > myoffset) { c = doc.GetCharAt (++myoffset); } return System.Math.Max (offset, myoffset - 1); }
public override void Analyze(TextDocument doc, DocumentLine line, Chunk startChunk, int startOffset, int endOffset) { // Check line start int o = line.Offset; char c = '\0'; for (; o < line.EndOffset && char.IsWhiteSpace(c = doc.GetCharAt(o)); o++) ; if (c != '-' && c != '#') return; DSyntax.Document = doc; var spanParser = new SpanParser(DSyntax, new CloneableStack<Span>()); var chunkP = new ChunkParser(DSyntax, spanParser, Ide.IdeApp.Workbench.ActiveDocument.Editor.ColorStyle, line); var n = chunkP.GetChunks(startOffset, endOffset - startOffset); if (n == null) return; startChunk.Next = n; startChunk.Length = n.Offset - startChunk.Offset; }
static int ScanWord (TextDocument doc, int offset, bool forwardDirection) { if (offset < 0 || offset >= doc.TextLength) return offset; var line = doc.GetLineByOffset (offset); char first = doc.GetCharAt (offset); if (char.IsPunctuation (first)) return forwardDirection ? System.Math.Min (line.Offset + line.Length, offset + 1) : System.Math.Max (line.Offset, offset - 1); while (offset >= line.Offset && offset < line.Offset + line.Length) { char ch = doc.GetCharAt (offset); if (char.IsWhiteSpace (first) && !char.IsWhiteSpace (ch) || WordFindStrategy.IsNoIdentifierPart (first) && !WordFindStrategy.IsNoIdentifierPart (ch) || (char.IsLetterOrDigit (first) || first == '_') && !(char.IsLetterOrDigit (ch) || ch == '_')) break; offset = forwardDirection ? offset + 1 : offset - 1; } return System.Math.Min (line.Offset + line.Length, System.Math.Max (line.Offset, offset + (forwardDirection ? 0 : 1))); }
static string GenerateRtf (TextDocument doc, Mono.TextEditor.Highlighting.ISyntaxMode mode, Mono.TextEditor.Highlighting.ColorScheme style, ITextEditorOptions options) { StringBuilder rtfText = new StringBuilder (); List<Gdk.Color> colorList = new List<Gdk.Color> (); var selection = new TextSegment (0, doc.TextLength); int startLineNumber = doc.OffsetToLineNumber (selection.Offset); int endLineNumber = doc.OffsetToLineNumber (selection.EndOffset); bool isItalic = false; bool isBold = false; int curColor = -1; foreach (var line in doc.GetLinesBetween (startLineNumber, endLineNumber)) { bool appendSpace = false; foreach (Chunk chunk in mode.GetChunks (style, line, line.Offset, line.Length)) { int start = System.Math.Max (selection.Offset, chunk.Offset); int end = System.Math.Min (chunk.EndOffset, selection.EndOffset); ChunkStyle chunkStyle = style.GetChunkStyle (chunk); if (start < end) { if (isBold != chunkStyle.Bold) { rtfText.Append (chunkStyle.Bold ? @"\b" : @"\b0"); isBold = chunkStyle.Bold; appendSpace = true; } if (isItalic != chunkStyle.Italic) { rtfText.Append (chunkStyle.Italic ? @"\i" : @"\i0"); isItalic = chunkStyle.Italic; appendSpace = true; } if (!colorList.Contains (chunkStyle.Color)) colorList.Add (chunkStyle.Color); int color = colorList.IndexOf (chunkStyle.Color); if (curColor != color) { curColor = color; rtfText.Append (@"\cf" + (curColor + 1)); appendSpace = true; } for (int i = start; i < end; i++) { char ch = doc.GetCharAt (i); switch (ch) { case '\\': rtfText.Append (@"\\"); break; case '{': rtfText.Append (@"\{"); break; case '}': rtfText.Append (@"\}"); break; case '\t': rtfText.Append (@"\tab"); appendSpace = true; break; default: if (appendSpace) { rtfText.Append (' '); appendSpace = false; } rtfText.Append (ch); break; } } } } rtfText.Append (@"\par"); rtfText.AppendLine (); } // color table StringBuilder colorTable = new StringBuilder (); colorTable.Append (@"{\colortbl ;"); for (int i = 0; i < colorList.Count; i++) { Gdk.Color color = colorList[i]; colorTable.Append (@"\red"); colorTable.Append (color.Red / 256); colorTable.Append (@"\green"); colorTable.Append (color.Green / 256); colorTable.Append (@"\blue"); colorTable.Append (color.Blue / 256); colorTable.Append (";"); } colorTable.Append ("}"); StringBuilder rtf = new StringBuilder(); rtf.Append (@"{\rtf1\ansi\deff0\adeflang1025"); // font table rtf.Append (@"{\fonttbl"); rtf.Append (@"{\f0\fnil\fprq1\fcharset128 " + options.Font.Family + ";}"); rtf.Append ("}"); rtf.Append (colorTable.ToString ()); rtf.Append (@"\viewkind4\uc1\pard"); rtf.Append (@"\f0"); try { string fontName = options.Font.ToString (); double fontSize = Double.Parse (fontName.Substring (fontName.LastIndexOf (' ') + 1), System.Globalization.CultureInfo.InvariantCulture) * 2; rtf.Append (@"\fs"); rtf.Append (fontSize); } catch (Exception) {}; rtf.Append (@"\cf1"); rtf.Append (rtfText.ToString ()); rtf.Append("}"); // System.Console.WriteLine(rtf); return rtf.ToString (); }
public ErrorMarker (TextDocument doc, Error info, DocumentLine line) { Info = info; LineSegment = line; // may be null if no line is assigned to the error. Wave = true; ColorName = info.ErrorType == ErrorType.Warning ? Mono.TextEditor.Highlighting.ColorScheme.WarningUnderlineString : Mono.TextEditor.Highlighting.ColorScheme.ErrorUnderlineString; StartCol = Info.Region.BeginColumn + 1; if (Info.Region.EndColumn > StartCol) { EndCol = Info.Region.EndColumn; } else { if (line == null) { EndCol = StartCol + 1; return; } var start = line.Offset + StartCol - 1; int o = start + 1; while (o < line.EndOffset) { char ch = doc.GetCharAt (o); if (!(char.IsLetterOrDigit (ch) || ch == '_')) break; o++; } EndCol = Info.Region.BeginColumn + o - start + 1; } }
public char GetCharAt(int position) { return(document.GetCharAt(position)); }
/// <summary> /// This method gets the line indentation. /// </summary> /// <param name="doc"> /// The <see cref="Document"/> the line belongs to. /// </param> /// <returns> /// The indentation of the line (all whitespace chars up to the first non ws char). /// </returns> public string GetIndentation (TextDocument doc) { var result = new StringBuilder (); int offset = Offset; int max = System.Math.Min (offset + LengthIncludingDelimiter, doc.TextLength); for (int i = offset; i < max; i++) { char ch = doc.GetCharAt (i); if (ch != ' ' && ch != '\t') break; result.Append (ch); } return result.ToString (); }
public int SearchMatchingBracketForward (System.ComponentModel.BackgroundWorker worker, TextDocument document, int offset, char openBracket, char closingBracket) { bool isInBlockComment = false; bool isInLineComment = false; int curStringQuote = -1; bool startsInLineComment = StartsInLineComment (document, offset); List<string> lineComments = GetList (document, "LineComment"); List<string> blockCommentStarts = GetList (document, "BlockCommentStart"); List<string> blockCommentEnds = GetList (document, "BlockCommentEnd"); List<string> stringQuotes = GetList (document, "StringQuote"); int depth = -1; while (offset >= 0 && offset < document.TextLength) { if (worker != null && worker.CancellationPending) return -1; if (curStringQuote < 0) { // check line comments if (!isInBlockComment && !isInLineComment) isInLineComment = StartsWithListMember (document, lineComments, offset) >= 0; // check block comments if (!isInLineComment) { if (!isInBlockComment) { isInBlockComment = StartsWithListMember (document, blockCommentStarts, offset) >= 0; } else { isInBlockComment = StartsWithListMember (document, blockCommentEnds, offset) < 0; } } } if (!isInBlockComment && !isInLineComment) { int i = StartsWithListMember (document, stringQuotes, offset); if (i >= 0) { if (curStringQuote >= 0) { if (curStringQuote == i) curStringQuote = -1; } else { curStringQuote = i; } } } char ch = document.GetCharAt (offset); switch (ch) { case '\n': case '\r': if (startsInLineComment) return -1; isInLineComment = false; break; default : if (ch == closingBracket) { if (!(isInLineComment || curStringQuote >= 0 || isInBlockComment)) --depth; } else if (ch == openBracket) { if (!(isInLineComment || curStringQuote >= 0 || isInBlockComment)) { ++depth; if (depth == 0) return offset; } } break; } offset++; } return -1; }
public static int FindNextWordEndOffset(TextDocument doc, int offset) { int myoffset = offset + 1; if (!OffsetIsWithinBounds (doc, myoffset)) { return myoffset; } char c = doc.GetCharAt (myoffset); // skip whitespace while (char.IsWhiteSpace (c)) { if (OffsetIsWithinBounds (doc, ++myoffset)) { c = doc.GetCharAt (myoffset); } else { return offset; } } while (!char.IsWhiteSpace (c) && 0 <= myoffset && doc.TextLength-1 > myoffset) { c = doc.GetCharAt (++myoffset); } return System.Math.Max (offset, myoffset - 1); }
/// <summary> /// Move to end of previous whitespace group. /// </summary> public override int FindPrevWordOffset(TextDocument doc, int offset) { --offset; if (0 > offset || doc.TextLength-1 <= offset){ return offset; } for (char c = doc.GetCharAt (offset); char.IsWhiteSpace (c) && 0 < offset && doc.TextLength > offset; c = doc.GetCharAt (--offset)); for (char c = doc.GetCharAt (offset); !char.IsWhiteSpace (c) && 0 < offset && doc.TextLength > offset; c = doc.GetCharAt (--offset)); return (0 == offset)? offset: offset+1; }
/// <summary> /// Move to previous non-whitespace change in character class. /// </summary> public override int FindPrevSubwordOffset(TextDocument doc, int offset) { int myoffset = offset-1; char c; if (0 > myoffset || doc.TextLength-1 <= myoffset){ return myoffset; } for (c = doc.GetCharAt (myoffset); char.IsWhiteSpace (c) && 0 <= myoffset && doc.TextLength-1 > myoffset; c = doc.GetCharAt (--myoffset)); CharacterClass initialClass = GetCharacterClass (c); for (; GetCharacterClass (c) == initialClass && 0 <= myoffset && doc.TextLength-1 > myoffset; c = doc.GetCharAt (--myoffset)); return (0 == myoffset)? myoffset: myoffset+1; }
/// <summary> /// Move past next whitespace group. /// </summary> public override int FindNextWordOffset(TextDocument doc, int offset) { int myoffset = offset; if (0 > myoffset || doc.TextLength-1 <= myoffset){ return myoffset; } for (char c = doc.GetCharAt (myoffset); !char.IsWhiteSpace (c) && 0 <= myoffset && doc.TextLength-1 > myoffset; c = doc.GetCharAt (++myoffset)); for (char c = doc.GetCharAt (myoffset); char.IsWhiteSpace (c) && 0 <= myoffset && doc.TextLength-1 > myoffset; c = doc.GetCharAt (++myoffset)); return (myoffset == offset)? myoffset+1: myoffset; }
/// <summary> /// Move to next non-whitespace change in character class. /// </summary> public override int FindNextSubwordOffset(TextDocument doc, int offset) { int myoffset = offset; if (0 > myoffset || doc.TextLength-1 <= myoffset){ return myoffset; } char c = doc.GetCharAt (myoffset); CharacterClass initialClass = GetCharacterClass (c); while (GetCharacterClass (c) == initialClass && 0 <= myoffset && doc.TextLength-1 > myoffset) { c = doc.GetCharAt (++myoffset); } for (c = doc.GetCharAt (myoffset); char.IsWhiteSpace (c) && 0 <= myoffset && doc.TextLength-1 > myoffset; c = doc.GetCharAt (++myoffset)); return (myoffset == offset)? myoffset+1: myoffset; }
static InsertionPoint GetInsertionPosition (TextDocument doc, int line, int column) { int bodyEndOffset = doc.LocationToOffset (line, column) + 1; DocumentLine curLine = doc.GetLine (line); if (curLine != null) { if (bodyEndOffset < curLine.Offset + curLine.Length) { // case1: positition is somewhere inside the start line return new InsertionPoint (new DocumentLocation (line, column + 1), NewLineInsertion.Eol, NewLineInsertion.BlankLine); } } // -> if position is at line end check next line DocumentLine nextLine = doc.GetLine (line + 1); if (nextLine == null) // check for 1 line case. return new InsertionPoint (new DocumentLocation (line, column + 1), NewLineInsertion.BlankLine, NewLineInsertion.BlankLine); for (int i = nextLine.Offset; i < nextLine.Offset + nextLine.Length; i++) { char ch = doc.GetCharAt (i); if (!char.IsWhiteSpace (ch)) { // case2: next line contains non ws chars. return new InsertionPoint (new DocumentLocation (line + 1, 1), NewLineInsertion.Eol, NewLineInsertion.BlankLine); } } // case3: whitespace line return new InsertionPoint (new DocumentLocation (line + 1, 1), NewLineInsertion.Eol, NewLineInsertion.None); }
int FindPrevWordOffset (TextDocument doc, int offset, bool subword) { int lineNumber = doc.OffsetToLineNumber (offset); DocumentLine line = doc.GetLine (lineNumber); if (line == null) return offset; int result = offset; if (result == line.Offset) { line = doc.GetLine (lineNumber - 1); if (line != null) result = line.Offset + line.Length; return result; } CharacterClass current = GetCharacterClass (doc.GetCharAt (result - 1), subword, false); if (current == CharacterClass.Whitespace && result - 1 > line.Offset) { result--; current = GetCharacterClass (doc.GetCharAt (result - 2), subword, false); } while (result > line.Offset) { CharacterClass prev = GetCharacterClass (doc.GetCharAt (result - 1), subword, false); if (prev != current) { // camelCase and PascalCase handling bool camelSkip = false; if (prev == CharacterClass.UppercaseLetter && current == CharacterClass.LowercaseLetter) { if (result-2 > line.Offset) { CharacterClass back2 = GetCharacterClass (doc.GetCharAt (result-2), subword, false); if (back2 == CharacterClass.UppercaseLetter) result--; else camelSkip = true; } } if (!camelSkip) break; } current = prev; result--; } return result; }
public ErrorMarker (TextDocument doc, Error info, DocumentLine line) { Info = info; LineSegment = line; // may be null if no line is assigned to the error. Wave = true; StartCol = Info.Region.BeginColumn; if (line != null) { var startOffset = line.Offset; if (startOffset + StartCol - 1 >= 0) { while (StartCol < line.Length) { char ch = doc.GetCharAt (startOffset + StartCol - 1); if (!char.IsWhiteSpace (ch)) break; StartCol++; } } } if (Info.Region.EndColumn > StartCol) { EndCol = Info.Region.EndColumn; } else { if (line == null) { EndCol = StartCol + 1; return; } var start = line.Offset + StartCol - 1; int o = start + 1; while (o < line.EndOffset) { char ch = doc.GetCharAt (o); if (!(char.IsLetterOrDigit (ch) || ch == '_')) break; o++; } EndCol = Info.Region.BeginColumn + o - start + 1; } }
public char this[int o] { get { return(doc.GetCharAt(o)); } }
static int GetHomeMark (TextDocument document, DocumentLine line) { int result; for (result = 0; result < line.Length; result++) if (!Char.IsWhiteSpace (document.GetCharAt (line.Offset + result))) return result + 1; return result + 1; }
int FindPrevWordOffset (TextDocument doc, int offset, bool subword) { if (offset <= 0) return 0; int result = offset - 1; CC previous = SW.GetCharacterClass (doc.GetCharAt (result), subword, treat_); bool inIndentifier = previous != CC.Unknown && previous != CC.Whitespace; while (result > 0) { char ch = doc.GetCharAt (result); CC current = SW.GetCharacterClass (ch, subword, treat_); //camelCase / PascalCase splitting if (subword) { if (current == CC.Digit && previous != CC.Digit) { result++; break; } else if (previous == CC.Digit && current != CC.Digit) { result++; break; } else if (current == CC.UppercaseLetter && previous != CC.UppercaseLetter) { break; } else if (current == CC.LowercaseLetter && previous == CC.UppercaseLetter && result + 2 < doc.TextLength && SW.GetCharacterClass (doc.GetCharAt (result + 2), subword, treat_) != CC.LowercaseLetter) { result++; break; } } //else break at end of identifiers if (previous != CC.Unknown && previous != CC.Whitespace) { inIndentifier = true; } else if (inIndentifier) { result += 2; break; } previous = current; result--; } foreach (FoldSegment segment in doc.GetFoldingsFromOffset (result)) { if (segment.IsFolded) result = System.Math.Min (result, segment.StartLine.Offset + segment.Column); } return result; }