/// <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); }
public static string GetWordAround(this TextDocument doc, int offset) { if (offset < 0 || offset >= doc.TextLength) { return(string.Empty); } int start, end; //find start for (start = offset; start >= 0; start--) { var c = doc.GetCharAt(start); if (!char.IsLetterOrDigit(c) && c != '_') { start++; break; } } if (start < 0) { start = 0; } //find end for (end = start; end < doc.TextLength; end++) { var c = doc.GetCharAt(end); if (!char.IsLetterOrDigit(c) && c != '_') { break; } } return(doc.GetText(start, end - start)); }
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)); }
/// <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); }
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> /// Marks the method whose block starts at the given offset. /// </summary> /// <param name="document">The document.</param> /// <param name="offset">The offset of the method body ('{').</param> /// <param name="folds">The fold markers.</param> /// <returns>The index of the next character after the method.</returns> private static int MarkMethod(TextDocument document, int offset, ICollection <NewFolding> folds) { if (offset >= document.TextLength) { return(offset); } int startOffset = offset; while (startOffset - 1 > 0 && Char.IsWhiteSpace(document.GetCharAt(startOffset - 1))) { startOffset--; } int offsetOfClosingBracket = TextUtilities.FindClosingBracket(document, offset + 1, '{', '}'); if (offsetOfClosingBracket > 0) { // Check whether next character is ';' int offsetOfNextCharacter = TextUtilities.FindFirstNonWhitespace(document, offsetOfClosingBracket + 1); if (offsetOfNextCharacter < document.TextLength && document.GetCharAt(offsetOfNextCharacter) == ';') { return(offset + 1); } AddFold(document, folds, startOffset, offsetOfClosingBracket + 1, "{...}"); // Skip to offset after '}'. (Ignore nested blocks.) offset = offsetOfClosingBracket + 1; return(offset); } return(offset + 1); }
public static IEnumerable <string> GetAllSqfIdents(this TextDocument doc, int minLength = 2) { var builder = new StringBuilder(); bool isString = false; bool isInComment = false; bool isInMultiLineComment = false; char stringchar = '\0'; for (int i = 0; i < doc.TextLength; i++) { var c = doc.GetCharAt(i); if (isInMultiLineComment) { if (c == '*' && doc.GetCharAt(i + 1) == '/') { isInMultiLineComment = false; } } else if (isInComment) { if (c == '\n') { isInComment = false; } } else if (isString) { if (c == stringchar) { isString = false; } } else if ((builder.Length == 0 ? char.IsLetter(c) : char.IsLetterOrDigit(c)) || c == '_') { builder.Append(c); } else if (c == '"' || c == '\'') { stringchar = c; isString = true; } else if (c == '/' && doc.GetCharAt(i + 1) == '*') { isInMultiLineComment = true; } else if (c == '/' && doc.GetCharAt(i + 1) == '/') { isInComment = true; } else { if (builder.Length >= minLength) { yield return(builder.ToString()); } builder.Clear(); } } }
char ITextDocument.this [int offset] { get { return(document.GetCharAt(offset)); } set { document.Replace(offset, 1, value.ToString()); } }
/// <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> static int GetStartType(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 '"': 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 && !verbatim) || inChar) { ++i; // skip next character } break; } } return((inString || inChar) ? 2 : result); }
/// <summary> /// Marks the block that starts at the current offset. /// </summary> /// <param name="document">The document.</param> /// <param name="offset">The offset of the identifier.</param> /// <param name="foldMarkers">The fold markers.</param> /// <returns>The index of the next character after the block.</returns> private static int MarkBlock(TextDocument document, int offset, ICollection <NewFolding> foldMarkers) { if (offset >= document.TextLength) { return(offset); } string word = TextUtilities.GetIdentifierAt(document, offset); if (Blocks.ContainsKey(word)) { offset += word.Length; while (offset < document.TextLength) { char c = document.GetCharAt(offset); if (c == '}' || c == ';') { offset++; break; } if (c == '{') { int startOffset = offset; while (Char.IsWhiteSpace(document.GetCharAt(startOffset - 1))) { startOffset--; } int offsetOfClosingBracket = TextUtilities.FindClosingBracket(document, offset + 1, '{', '}'); if (offsetOfClosingBracket > 0) { AddFold(document, foldMarkers, startOffset, offsetOfClosingBracket + 1, "{...}"); // Skip to offset after '{'. offset++; break; } } offset++; } } else { if (word.Length > 0) { // Skip to next word offset += word.Length; } else { // Skip to next character offset++; } } return(offset); }
/// <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; }
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.EndOffset; 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)); } } DocumentLine nextLine2 = doc.GetLine(line + 2); if (nextLine2 != null) { for (int i = nextLine2.Offset; i < nextLine2.EndOffset; i++) { char ch = doc.GetCharAt(i); if (!char.IsWhiteSpace(ch)) { // case3: one blank line return(new InsertionPoint(new DocumentLocation(line + 1, 1), NewLineInsertion.Eol, NewLineInsertion.Eol)); } } } // case4: more than 1 blank line return(new InsertionPoint(new DocumentLocation(line + 1, 1), NewLineInsertion.Eol, NewLineInsertion.None)); }
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); startChunk.Next = n; startChunk.Length = n.Offset - startChunk.Offset; }
void VisitElementValue(XElement element, MSBuildLanguageElement resolved) { if (element.IsSelfClosing || !element.IsEnded) { return; } var begin = TextDocument.LocationToOffset(element.Region.End); int end = begin; if (element.IsClosed && element.FirstChild == null) { end = TextDocument.LocationToOffset(element.ClosingTag.Region.Begin); } else { //HACK: in some cases GetCharAt can throw at the end of the document even with TextDocument.Length check try { for (; end < (TextDocument.Length + 1) && TextDocument.GetCharAt(end) != '<'; end++) { } } catch { end--; } } var text = TextDocument.GetTextBetween(begin, end); VisitElementValue(element, resolved, text, begin); }
static void AppendHtmlText (StringBuilder htmlText, TextDocument doc, ITextEditorOptions options, int start, int end) { for (int i = start; i < end; i++) { char ch = doc.GetCharAt (i); switch (ch) { case ' ': htmlText.Append (" "); break; case '\t': for (int i2 = 0; i2 < options.TabSize; i2++) htmlText.Append (" "); break; case '<': htmlText.Append ("<"); break; case '>': htmlText.Append (">"); break; case '&': htmlText.Append ("&"); break; case '"': htmlText.Append ("""); break; default: htmlText.Append (ch); break; } } }
static void AppendRtfText (StringBuilder rtfText, TextDocument doc, int start, int end, ref bool appendSpace) { 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; } } }
static void AppendRtfText(StringBuilder rtfText, TextDocument doc, int start, int end, ref bool appendSpace) { 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; } } }
public BracketSearchResult SearchBracket(TextDocument document, int offset) { BracketSearchResult result; if (offset > 0) { var charAt = document.GetCharAt(offset - 1); var num = "([{".IndexOf(charAt); var num2 = -1; if (num > -1) { num2 = SearchBracketForward(document, offset, "([{"[num], ")]}"[num]); } num = ")]}".IndexOf(charAt); if (num > -1) { num2 = SearchBracketBackward(document, offset - 2, "([{"[num], ")]}"[num]); } if (num2 > -1) { result = new BracketSearchResult(Math.Min(offset - 1, num2), 1, Math.Max(offset - 1, num2), 1); return(result); } } result = null; return(result); }
public IEnumerable <NewFolding> CreateNewFoldings(TextDocument document) { var newFoldings = new List <NewFolding>(); var startOffsets = new Stack <int>(); var lastNewLineOffset = 0; for (var i = 0; i < document.TextLength; i++) { var c = document.GetCharAt(i); if (c == this.OpeningBrace) { startOffsets.Push(i); continue; } if (c == this.ClosingBrace && startOffsets.Any()) { // 対応する括弧が異なる行であれば折り畳む var startOffset = startOffsets.Pop(); if (startOffset < lastNewLineOffset) { newFoldings.Add(new NewFolding(startOffset, i + 1)); } continue; } if (c == '\n' || c == '\r') { lastNewLineOffset = i + 1; } } return(newFoldings.OrderBy(f => f.StartOffset)); }
public BracketSearchResult SearchBrackets(TextDocument document, int offset) { if (offset <= 0 || offset > document.TextLength) { return(null); } var cha = document.GetCharAt(offset - 1); var index = openBrackets.IndexOf(cha); var other = -1; if (index >= 0) { other = SearchBracketForward(document, offset, openBrackets.ElementAt(index), closeBrackets.ElementAt(index)); } index = closeBrackets.IndexOf(cha); if (index >= 0) { other = SearchBracketBackward(document, offset - 2, openBrackets.ElementAt(index), closeBrackets.ElementAt(index)); } return((other >= 0) ? new BracketSearchResult(Math.Min(offset - 1, other), 1, Math.Max(offset - 1, other), 1) : null); }
public BracketSearchResult SearchBracket(TextDocument document, int offset) { if (offset > 0) { var 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) { var result = new BracketSearchResult( Math.Min(offset - 1, otherOffset), Math.Max(offset - 1, otherOffset)); SearchDefinition(document, result); return(result); } } return(null); }
/// <summary> /// Breaks the lines into words in the form of a list of <see cref="TextSegment">TextSegments</see>. A 'word' is defined as an identifier (a series of letters, digits or underscores) /// or a single non-identifier character (including white space characters) /// </summary> /// <returns> /// The list of segments representing the 'words' in the lines /// </returns> /// <param name='document'> /// The document to get the words from /// </param> /// <param name='startLine'> /// The first line in the documents to get the words from /// </param> /// <param name='lineCount'> /// The number of lines to get words from /// </param> public static List<TextSegment> BreakLinesIntoWords (TextDocument document, int startLine, int lineCount, bool includeDelimiter = true) { var result = new List<TextSegment> (); for (int line = startLine; line < startLine + lineCount; line++) { var lineSegment = document.GetLine (line); int offset = lineSegment.Offset; bool wasIdentifierPart = false; int lastWordEnd = 0; for (int i = 0; i < lineSegment.Length; i++) { char ch = document.GetCharAt (offset + i); bool isIdentifierPart = char.IsLetterOrDigit (ch) || ch == '_'; if (!isIdentifierPart) { if (wasIdentifierPart) { result.Add (new TextSegment (offset + lastWordEnd, i - lastWordEnd)); } result.Add (new TextSegment (offset + i, 1)); lastWordEnd = i + 1; } wasIdentifierPart = isIdentifierPart; } if (lastWordEnd != lineSegment.Length) { result.Add (new TextSegment (offset + lastWordEnd, lineSegment.Length - lastWordEnd)); } if (includeDelimiter && lineSegment.DelimiterLength > 0) result.Add (new TextSegment (lineSegment.Offset + lineSegment.Length, lineSegment.DelimiterLength)); } return result; }
/// <summary> /// Create <see cref="NewFolding"/>s for the specified document. /// </summary> public IEnumerable <NewFolding> CreateNewFoldings(TextDocument document) { List <NewFolding> newFoldings = new List <NewFolding>(); Stack <int> startOffsets = new Stack <int>(); int lastNewLineOffset = 0; char openingBrace = this.OpeningBrace; char closingBrace = this.ClosingBrace; for (int i = 0; i < document.TextLength; i++) { char c = document.GetCharAt(i); if (c == openingBrace) { startOffsets.Push(i); } else if (c == closingBrace && startOffsets.Count > 0) { int startOffset = startOffsets.Pop(); // don't fold if opening and closing brace are on the same line if (startOffset < lastNewLineOffset) { newFoldings.Add(new NewFolding(startOffset, i + 1)); } } else if (c == '\n' || c == '\r') { lastNewLineOffset = i + 1; } } newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset)); return(newFoldings); }
private void CreateMethodFold(TextDocument textDocument) { // TODO: Find a way to fold just functions brackets. this.startOffsets.Push(this.currentOffset); this.bracketSearcher.OpeningBrackets = "{"; this.bracketSearcher.ClosingBrackets = "}"; BracketSearchResult result = this.bracketSearcher.SearchBracket(textDocument, this.currentOffset + 1); if (result != null) { int startOffset = startOffsets.Pop(); // Skip empty spaces. for (int i = startOffset - 1; i > 0; i--) { char character = textDocument.GetCharAt(i); if (char.IsWhiteSpace(character) == false && character != '\n' && character != '\r') { startOffset = i + 1; break; } } this.foldings.Foldings.Add(new NewFolding(startOffset, result.ClosingBracketOffset + 1) { Name = "..." }); } }
static void ConvertSpacesToTabs(TextArea textArea, ISegment segment) { TextDocument document = textArea.Document; int endOffset = segment.EndOffset; int indentationSize = textArea.Options.IndentationSize; int spacesCount = 0; for (int offset = segment.Offset; offset < endOffset; offset++) { if (document.GetCharAt(offset) == ' ') { spacesCount++; if (spacesCount == indentationSize) { document.Replace(offset - (indentationSize - 1), indentationSize, "\t", OffsetChangeMappingType.CharacterReplace); spacesCount = 0; offset -= indentationSize - 1; endOffset -= indentationSize - 1; } } else { spacesCount = 0; } } }
public MatchingFarenthesisFinder(TextDocument document, TextLocation location) { var currentLetter = document.GetCharAt(document.GetOffset(location)); TurgetLetter = new CharLocationTuple(currentLetter, location); _charFinder = new TextDocumentCharFinder(document, location); }
/// <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; }
int QuickSearchBracketForward(TextDocument 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; } } } return(-1); }
public static string GetXmlIdentifierBeforeIndex(TextDocument document, int index) { if (document == null) { throw new ArgumentNullException(nameof(document)); } if (index < 0 || index > document.TextLength) { throw new ArgumentOutOfRangeException(nameof(index), index, "Value must be between 0 and " + document.TextLength); } var i = index - 1; while (i >= 0 && IsXmlNameChar(document.GetCharAt(i)) && document.GetCharAt(i) != '/') { i--; } return(document.GetText(i + 1, index - i - 1)); }
private int QuickSearchBracketForward(TextDocument document, int offset, char openBracket, char closeBracket) { var brackets = 1; for (int i = offset; i < document.TextLength; ++i) { var cha = document.GetCharAt(i); if (cha == openBracket) { ++brackets; } else if (cha == closeBracket) { --brackets; if (brackets == 0) { return(i); } } else if (cha == '"') { break; } else if (cha == '\'') { break; } else if (cha == '/' && i > 0) { if (document.GetCharAt(i - 1) == '/') { break; } } else if (cha == '*' && i > 0) { if (document.GetCharAt(i - 1) == '/') { break; } } } return(-1); }
private void CloseBracket(TextEditor.TextEditor editor, TextDocument document, string text) { if (text[0].IsCloseBracketChar() && editor.CaretIndex < document.TextLength && editor.CaretIndex > 0) { if (document.GetCharAt(editor.CaretIndex) == text[0]) { document.Replace(editor.CaretIndex - 1, 1, string.Empty); } } }
static List<FoldSegment> GetFoldSegments (TextDocument doc) { List<FoldSegment> result = new List<FoldSegment> (); Stack<FoldSegment> foldSegments = new Stack<FoldSegment> (); for (int i = 0; i < doc.TextLength - 1; ++i) { char ch = doc.GetCharAt (i); if ((ch == '+' || ch == '-') && doc.GetCharAt(i + 1) == '[') { FoldSegment segment = new FoldSegment (doc, "...", i, 0, FoldingType.None); segment.IsFolded = ch == '+'; foldSegments.Push (segment); } else if (ch == ']' && foldSegments.Count > 0) { FoldSegment segment = foldSegments.Pop (); segment.Length = i - segment.Offset; result.Add (segment); } } return result; }
private void CreateCommentFold(TextDocument textDocument) { this.startOffsets.Push(this.currentOffset - 1); for (; this.currentOffset < textDocument.TextLength; this.currentOffset++) { char character = textDocument.GetCharAt(this.currentOffset); if (character == '*' && textDocument.GetCharAt(++this.currentOffset) == '/') { this.currentOffset++; foldings.Foldings.Add(new NewFolding(startOffsets.Pop(), this.currentOffset) { Name = "/* ..." }); break; } } }
static int ScanLineStart(TextDocument document, int offset) { for (int i = offset - 1; i > 0; --i) { if (document.GetCharAt(i) == '\n') { return(i + 1); } } return(0); }
/// <summary> /// Breaks the lines into words in the form of a list of <see cref="TextSegment">TextSegments</see>. A 'word' is defined as an identifier (a series of letters, digits or underscores) /// or a single non-identifier character (including white space characters) /// </summary> /// <returns> /// The list of segments representing the 'words' in the lines /// </returns> /// <param name='document'> /// The document to get the words from /// </param> /// <param name='startLine'> /// The first line in the documents to get the words from /// </param> /// <param name='lineCount'> /// The number of lines to get words from /// </param> public static List <ISegment> BreakLinesIntoWords(TextDocument document, int startLine, int lineCount, bool includeDelimiter = true) { if (document is null) { throw new ArgumentNullException(nameof(document)); } if (startLine < 1) { throw new ArgumentOutOfRangeException(nameof(startLine), "startLine >= 1, was " + startLine); } if (startLine - 1 + lineCount > document.LineCount) { throw new ArgumentOutOfRangeException(nameof(startLine), "startLine + lineCount <= " + (document.LineCount + 1) + ", was " + startLine); } var result = new List <ISegment> (); for (int line = startLine; line < startLine + lineCount; line++) { var lineSegment = document.GetLine(line); if (lineSegment == null) { continue; } int offset = lineSegment.Offset; bool wasIdentifierPart = false; int lastWordEnd = 0; for (int i = 0; i < lineSegment.Length; i++) { char ch = document.GetCharAt(offset + i); bool isIdentifierPart = char.IsLetterOrDigit(ch) || ch == '_'; if (!isIdentifierPart) { if (wasIdentifierPart) { result.Add(new TextSegment(offset + lastWordEnd, i - lastWordEnd)); } result.Add(new TextSegment(offset + i, 1)); lastWordEnd = i + 1; } wasIdentifierPart = isIdentifierPart; } if (lastWordEnd != lineSegment.Length) { result.Add(new TextSegment(offset + lastWordEnd, lineSegment.Length - lastWordEnd)); } if (includeDelimiter && lineSegment.DelimiterLength > 0) { result.Add(new TextSegment(lineSegment.Offset + lineSegment.Length, lineSegment.DelimiterLength)); } } return(result); }
static void AppendRtfText (StringBuilder rtfText, TextDocument doc, int start, int end, ref bool appendSpace) { 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; } int unicodeCh = (int)ch; if (0x7F < unicodeCh && unicodeCh <= 0xFF) { rtfText.Append(@"\u" + unicodeCh); } else if (0xFF < unicodeCh && unicodeCh <= 0x8000) { rtfText.Append(@"\uc1\u" + unicodeCh + "*"); } else if (0x8000 < unicodeCh && unicodeCh <= 0xFFFF) { rtfText.Append(@"\uc1\u" + (unicodeCh - 0x10000) + "*"); } else { rtfText.Append (ch); } break; } } }
/// <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> /// This method gets the line indentation. /// </summary> /// <param name="doc"> /// The <see cref="TextDocument"/> 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 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); }
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); }
/// <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; }
public static string GenerateRtf (TextDocument doc, Mono.TextEditor.Highlighting.ISyntaxMode mode, Mono.TextEditor.Highlighting.ColorScheme style, ITextEditorOptions options) { var rtfText = new StringBuilder (); var 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 (var 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); var 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 (); } var 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 (CreateColorTable (colorList)); 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("}"); return rtf.ToString (); }