/// <summary> /// Ensure that low >= high (swap them if they are not) /// </summary> public static void FixOrder(ref TokenLoc low, ref TokenLoc high) { if (low > high) { TokenLoc temp = low; low = high; high = temp; } }
/// <summary> /// Moves to the next char location. /// </summary> public void Inc() { if (Location.Line >= mLines.Length) { Location = new TokenLoc(); return; } Location.Char++; if (Location.Char > mLines[Location.Line].Length) { Location.Char = 0; Location.Line++; } }
/// <summary> /// Check to see if 'find' matches the text in 'text'. /// Returns TRUE if they match, FALSE if not. /// Changes the current scan locations, does not always set matchEnd /// </summary> bool MatchInternal(Scanner text, Scanner find, ref TokenLoc matchEnd) { // Verify we are at the start of a word (if requested) if (checkMatchWholeWord.Checked) { text.Location.Char--; if (!IsWordSeparator(text.Peek())) { return(false); } text.Location.Char++; } // Scan until we find a match or find the end bool matchCase = checkMatchCase.Checked; bool found = true; while (!find.AtEnd()) { char findPeek = find.Peek(); char textPeek = text.Peek(); if (!matchCase) { findPeek = char.ToUpper(findPeek); textPeek = char.ToUpper(textPeek); } if (findPeek != textPeek) { found = false; break; } find.Inc(); text.Inc(); } // Verify we are at the end of a word (if requested) if (checkMatchWholeWord.Checked && found) { return(IsWordSeparator(text.Peek())); } return(found); }
/// <summary> /// Check to see if 'find' matches the text in 'text'. /// Returns TRUE if they match, FALSE if not. /// Does not change the current scan locations /// </summary> bool Match(Scanner text, Scanner find, ref TokenLoc matchEnd) { // Save original locations TokenLoc textLoc = text.Location; TokenLoc findLoc = find.Location; matchEnd = textLoc; bool found = MatchInternal(text, find, ref matchEnd); // Restore text locations, return result if (found) { matchEnd = text.Location; } text.Location = textLoc; find.Location = findLoc; return(found); }
/// <summary> /// Gets a section of text. /// </summary> public string[] GetText(TokenLoc start, TokenLoc end) { // Bounds check parameters start.Line = Bound(start.Line, 0, mLines.Count - 1); start.Char = Bound(start.Char, 0, mLines[start.Line].Length); end.Line = Bound(end.Line, 0, mLines.Count - 1); end.Char = Bound(end.Char, 0, mLines[end.Line].Length); if (end.Line < start.Line) { end.Line = start.Line; } if (start.Line == end.Line && end.Char < start.Char) { end.Char = start.Char; } int startIndex = start.Char; int endIndex = end.Char; if (start.Line == end.Line && startIndex >= endIndex) { return(new string[0]); } if (start.Line == end.Line) { return(new string[] { mLines[start.Line].Substring(startIndex, endIndex - startIndex) }); } // Break up the first and last line at the start position string [] lines = new string[end.Line - start.Line + 1]; lines[0] = mLines[start.Line].Substring(startIndex); for (int i = 1; i < lines.Length - 1; i++) { lines[i] = mLines[start.Line + i]; } lines[end.Line - start.Line] = mLines[end.Line].Substring(0, endIndex); return(lines); }
/// <summary> /// Call this function to show the search form /// </summary> public static void Show(Form owner, Editor editor) { // Create the form if (mFormSearch == null || mFormSearch.IsDisposed) { mFormSearch = new FormSearch(); } // Display the form (possibly with a new owner) mFormSearch.mEditor = editor; if (owner != mFormSearch.Owner) { mFormSearch.Visible = false; } if (!mFormSearch.Visible) { mFormSearch.Show(owner); } // Take selected text for search box (if any) TokenLoc selStart = editor.SelStart; TokenLoc selEnd = editor.SelEnd; if (selStart != selEnd && selStart.Line == selEnd.Line) { string [] search = editor.Lexer.GetText(selStart, selEnd); if (search.Length == 1) { mFormSearch.textSearch.Text = search[0]; } } // Set search box focus mFormSearch.textSearch.Focus(); mFormSearch.textSearch.SelectAll(); }
/// <summary> /// Start a new search whenever the search text changes /// </summary> private void textSearch_TextChanged(object sender, EventArgs e) { mPreviousSearchLoc = new TokenLoc(-1, -1); }
/// <summary> /// Find Next /// </summary> void FindNext(Form messageBoxParent) { // Find start location (cursor or beginning of selected text) TokenLoc start = mEditor.CursorLoc; if (mEditor.HasSel()) { start = mEditor.SelStart; } // Start new search? if (mPreviousSearchLoc != start) { mPreviousSearchLoc = new TokenLoc(-1, -1); mStartSearchLoc = start; } // Create text scanner Scanner text = new Scanner(mEditor.Lexer.GetText()); text.Location = start; // Create search string scanner List <string> findList = new List <string>(); findList.Add(textSearch.Text); Scanner find = new Scanner(findList.ToArray()); // Skip first char to move past previous search if (mEditor.HasSel()) { text.Inc(); } // Scan for a match TokenLoc matchEnd = new TokenLoc(); bool firstChar = true; bool pastEnd = false; while (true) { // Past end of previous search? if (!firstChar && text.Location == start) { MessageBox.Show(messageBoxParent, "The search text was not found", Text); return; } if (!firstChar && text.Location == mStartSearchLoc) { pastEnd = true; } // Found match? if (Match(text, find, ref matchEnd)) { mEditor.SelSet(text.Location, matchEnd); mEditor.CursorLoc = text.Location; mPreviousSearchLoc = text.Location; if (pastEnd) { MessageBox.Show(messageBoxParent, "Find reached the starting point of the search", Text); } return; } text.Inc(); firstChar = false; } }
/// <summary> /// Replace a section of text. This function is used to insert, /// delete, and change a section of text. It will re-analyze the /// text (replacing all tokens on all lines that were changed) /// and updating the positions of the tokens. /// RETURNS: The new end location of the inserted text /// </summary> public TokenLoc ReplaceText(string[] replacementText, TokenLoc start, TokenLoc end) { // Bounds check parameters start.Line = Bound(start.Line, 0, mLines.Count - 1); start.Char = Bound(start.Char, 0, mLines[start.Line].Length); end.Line = Bound(end.Line, 0, mLines.Count - 1); end.Char = Bound(end.Char, 0, mLines[end.Line].Length); if (end.Line < start.Line) { end.Line = start.Line; } if (start.Line == end.Line && end.Char < start.Char) { end.Char = start.Char; } int startIndex = start.Char; int endIndex = end.Char; // Adjust first line if (start.Line != end.Line || startIndex != endIndex) { mLines[start.Line] = mLines[start.Line].Substring(0, startIndex) + mLines[end.Line].Substring(endIndex); } // Remove unused lines if (start.Line != end.Line) { mLines.RemoveRange(start.Line + 1, end.Line - start.Line); mTokens.RemoveRange(start.Line + 1, end.Line - start.Line); } // Start and end are the same end.Line = start.Line; endIndex = startIndex; // Insert new text if (replacementText != null && replacementText.Length != 0) { // Break up the first line at the start position string startStr = mLines[start.Line].Substring(0, startIndex); string endStr = mLines[start.Line].Substring(startIndex); if (replacementText.Length <= 1) { mLines[start.Line] = startStr + replacementText[0] + endStr; endIndex = startStr.Length + replacementText[0].Length; } else { // Insert new lines mLines[start.Line] = startStr + replacementText[0]; for (int i = 1; i < replacementText.Length; i++) { mLines.Insert(start.Line + i, replacementText[i]); mTokens.Insert(start.Line + i, new List <Token>()); } end.Line = start.Line + replacementText.Length - 1; endIndex = replacementText[replacementText.Length - 1].Length; mLines[end.Line] += endStr; } } // Re-scan the updated text lines for (int i = start.Line; i <= end.Line; i++) { mTokens[i] = ScanLine(mLines[i], i); } // Re-adjust token line positions for (int i = start.Line; i < mTokens.Count; i++) { foreach (Token token in mTokens[i]) { token.Line = i; } } // Calculate end of inserted text end.Char = endIndex; return(end); }