private void gotoLineToolStripMenuItem_Click(object sender, EventArgs e) { using (GotoLineForm frm = new GotoLineForm()) { frm.CurrentLine = textEditorControl.ActiveTextAreaControl.Caret.Line + 1; frm.MaximumLine = textEditorControl.Document.TotalNumberOfLines; if (frm.ShowDialog(this) == DialogResult.OK) { GotoText(frm.CurrentLine, textEditorControl.ActiveTextAreaControl.Caret.Column); } } }
public bool ExecuteKey(KeyEventArgs e) { TextPoint caretPos = caret.GetPosition(true); bool shift = e.Shift; bool ctrl = e.Control; Keys keys = e.KeyData; if (shift) keys = e.KeyData ^ Keys.Shift; if (ctrl) keys = keys ^ Keys.Control; //Only handle special keys switch (keys) { case Keys.Tab: if (IsReadonly) break; if (!TextMarked) { if (!Options.Editor.ReplaceTabsWithSpaces) { lines[caretPos.Line].Text = lines[caretPos.Line].Text.Insert(caretPos.Pos, "\t"); lines[caretPos.Line].Invalidated = true; UndoSys.TextAdded("\t", this, caretPos); caretPos.Pos++; caret.SetPosition(caretPos, true); ExtendedLines(new List<Line>() { lines[caretPos.Line] }); Invalidate(); TextEdited(); CaretMoved(false); return true; } int pos; if (shift) {//Remove spaces up to previous tab int count = 0; while (caretPos.Pos > 0 && lines[caretPos.Line].Text[caretPos.Pos - count - 1] == ' ') { if (caretPos.Pos - count == 0) break; count++; if ((caretPos.Pos - count) % 4 == 0) { break; } } if (count == 0) return true; UndoSys.TextRemoved(lines[caretPos.Line].Text.Substring(caretPos.Pos - count, count), this, new TextPoint(caretPos.Line, caretPos.Pos - count)); lines[caretPos.Line].Text = lines[caretPos.Line].Text.Remove(caretPos.Pos - count, count); lines[caretPos.Line].Invalidated = true; caretPos.Pos -= count; caret.SetPosition(caretPos, true); ShrunkLine(lines[caretPos.Line]); Invalidate(); TextEdited(); CaretMoved(false); return true; } pos = caretPos.Pos + 1; string textInsert = " "; while (pos % 4 > 0) { pos++; textInsert += " "; } lines[caretPos.Line].Text = lines[caretPos.Line].Text.Insert(caretPos.Pos, textInsert); lines[caretPos.Line].Invalidated = true; UndoSys.TextAdded(textInsert, this, caretPos); caretPos.Pos += textInsert.Length; caret.SetPosition(caretPos, true); ExtendedLines(new List<Line>(){lines[caretPos.Line]}); Invalidate(); TextEdited(); CaretMoved(false); return true; } List<Line> modifiedLines = new List<Line>(); int min = Math.Min(caretPos.Line, mouseDownPos.Line); int max = Math.Max(caretPos.Line, mouseDownPos.Line); string oldText = ""; for (int i = min; i <= max; i++) { oldText += lines[i].Text; if (i != max) oldText += "\n"; } string newText; /*if (!Options.Editor.ReplaceTabsWithSpaces) { newText = ""; for (int i = min; i <= max; i++) { lines[i].Indents++; lines[i].Invalidated = true; newText += lines[i].Text; } }*/ int spacesCaret = 0; foreach (char t in lines[caretPos.Line].Text) { if (t == ' ') spacesCaret--; else break; } int spacesMarkStart = 0; foreach (char t in lines[mouseDownPos.Line].Text) { if (t == ' ') spacesMarkStart--; else break; } for (int i = min; i <= max; i++) { modifiedLines.Add(lines[i]); lines[i].Invalidated = true; if (e.Shift) lines[i].Indents--; else lines[i].Indents++; } newText = ""; for (int i = min; i <= max; i++) { newText += lines[i].Text; if (i != max) newText += "\n"; } UndoSys.TextReplaced(oldText, newText, this, new TextPoint(min, 0)); spacesCaret += 4 * lines[caretPos.Line].Indents; if (!Options.Editor.ReplaceTabsWithSpaces && spacesCaret != 0) spacesCaret /= Math.Abs(spacesCaret); if (caretPos.Pos + spacesCaret < 0) spacesCaret = -caretPos.Pos; caretPos = new TextPoint(caretPos.Line, caretPos.Pos + spacesCaret); caret.SetPosition(caretPos, true); spacesMarkStart += 4 * lines[mouseDownPos.Line].Indents; if (!Options.Editor.ReplaceTabsWithSpaces && spacesMarkStart != 0) spacesMarkStart /= Math.Abs(spacesMarkStart); mouseDownPos = new TextPoint(mouseDownPos.Line, mouseDownPos.Pos + spacesMarkStart); ExtendedLines(modifiedLines); Invalidate(); TextEdited(); CaretMoved(false); return true; case Keys.Delete: if (IsReadonly) break; if (TextMarked) { DeleteMarkedText(); caretPos = caret.GetPosition(true); } //Li|ne1 else if (lines[caretPos.Line].Text.Length > caretPos.Pos) { string removedPart = lines[caretPos.Line].Text.Substring(caretPos.Pos, 1); UndoSys.TextRemoved(removedPart, this, new TextPoint(caretPos.Line, caretPos.Pos)); lines[caretPos.Line].Text = lines[caretPos.Line].Text.Remove(caretPos.Pos, 1); lines[caretPos.Line].edited = true; lines[caretPos.Line].Invalidated = true; ShrunkLine(lines[caretPos.Line]); UpdateBlocks(); Invalidate(); TextEdited(); } //Line1| //Line2 else if (lines.Count > caretPos.Line + 1) { UndoSys.TextRemoved("\n", this, new TextPoint(caretPos.Line, caretPos.Pos)); lines[caretPos.Line].Text += lines[caretPos.Line + 1].Text; lines[caretPos.Line].edited = true; lines.RemoveAt(caretPos.Line + 1); //InvalidateAll = true; for (int i = caretPos.Line; i < lines.Count; i++) { lines[i].Invalidated = true; } ExtendedLines(new List<Line>{lines[caretPos.Line]}); UpdateBlocks(); Invalidate(); TextEdited(); } return true; case Keys.Back: if (IsReadonly) break; if (TextMarked) { DeleteMarkedText(); caretPos = caret.GetPosition(true); } //Li|ne1 else if (caretPos.Pos > 0) { string removedPart = lines[caretPos.Line].Text.Substring( caretPos.Pos - 1, 1); lines[caretPos.Line].Text = lines[caretPos.Line].Text.Remove( caretPos.Pos - 1, 1); lines[caretPos.Line].Invalidated = true; lines[caretPos.Line].edited = true; UndoSys.TextRemoved(removedPart, this, new TextPoint(caretPos.Line, caretPos.Pos - 1)); caret.SetPosition(new TextPoint(caretPos.Line, caretPos.Pos - 1), true); ShrunkLine(lines[caretPos.Line]); UpdateBlocks(); Invalidate(); TextEdited(); } //Line1 //|Line2 else if (caretPos.Line > 0) { TextPoint newPos = new TextPoint(caretPos.Line - 1, lines[caretPos.Line - 1].Text.Length); lines[caretPos.Line - 1].Text += lines[caretPos.Line].Text; lines.RemoveAt(caretPos.Line); //InvalidateAll = true; for (int l = caretPos.Line - 1; l < lines.Count; l++) { lines[l].Invalidated = true; } UndoSys.TextRemoved("\n", this, new TextPoint(newPos.Line, newPos.Pos)); caret.SetPosition(newPos, true); lines[newPos.Line].edited = true; ExtendedLines(new List<Line> { lines[newPos.Line] }); UpdateBlocks(); Invalidate(); TextEdited(); CaretMoved(); return true; } CaretMoved(); return true; case Keys.Return: if (IsReadonly) break; DeleteMarkedText(); caretPos = caret.GetPosition(true); List<Line> newLines = new List<Line>(); Line newLine = new Line(lines[caretPos.Line].Text.Substring(caretPos.Pos)); newLines.Add(newLine); Line extraNewLine = null; string undoText = "\n"; //If the next char was an }, move that to its own line if (newLine.Text.Length > 0 && newLine.Text[0] == '}') { extraNewLine = new Line(newLine.Text); newLines.Add(extraNewLine); lines.Insert(caretPos.Line + 1, extraNewLine); newLine.Text = ""; } string oldNewLineText = newLine.Text; lines.Insert(caretPos.Line + 1, newLine); lines[caretPos.Line].Text = lines[caretPos.Line].Text.Substring(0, caretPos.Pos); lines[caretPos.Line].edited = true; lines[caretPos.Line].Restyle(fonts, lines, caretPos.Line); newLine.Indents = newLine.GetWantedIndents(fonts, lines, caretPos.Line + 1); if (newLine.Text.Length - oldNewLineText.Length >= 0 && oldNewLineText.Length > 0) undoText += newLine.Text.Remove(newLine.Text.Length - oldNewLineText.Length); else undoText += newLine.Text; if (extraNewLine != null) { oldNewLineText = extraNewLine.Text; extraNewLine.Indents = extraNewLine.GetWantedIndents(fonts, lines, caretPos.Line + 2); if (extraNewLine.Text.Length - oldNewLineText.Length >= 0 && oldNewLineText.Length > 0) undoText += "\n" + extraNewLine.Text.Remove(extraNewLine.Text.Length - oldNewLineText.Length); else undoText += "\n" + extraNewLine.Text; } caret.SetPosition(new TextPoint(caretPos.Line + 1, Options.Editor.ReplaceTabsWithSpaces ? newLine.Indents*4 : newLine.Indents), true); //InvalidateAll = true; for (int l = caretPos.Line; l < lines.Count; l++) { lines[l].Invalidated = true; } ShrunkLine(lines[caretPos.Line]); ExtendedLines(newLines); UndoSys.TextAdded(undoText, this, caretPos); UpdateBlocks(); Invalidate(); TextEdited(); CaretMoved(); return true; case Keys.Right: if (!TextMarked) { TextMarked = shift; mouseDownPos = caretPos; } //if (!shift) // TextMarked = false; while (true) { if (lines[caretPos.Line].Text.Length > caretPos.Pos) { lines[caretPos.Line].Invalidated = true; int pos = caretPos.Pos + 1; if (ctrl) { List<Token> tokens = new List<Token>(); Lexer lexer = new Lexer(new StringReader(lines[caretPos.Line].Text)); { Token token; while (!((token = lexer.Next()) is EOF)) { if (token is TWhiteSpace) continue; tokens.Add(token); } } bool moved = false; foreach (Token token in tokens) { if (token.Pos - 1 >= pos) { pos = token.Pos - 1; moved = true; break; } } if (!moved) { caretPos.Pos = lines[caretPos.Line].Text.Length; continue; } } caret.SetPosition(new TextPoint(caretPos.Line, pos), true); Invalidate(); } else if (lines.Count > caretPos.Line + 1) { lines[caretPos.Line].Invalidated = true; //Skip over any potential hidden lines caret.SetPosition(new TextPoint(caret.GetPosition(false).Line + 1, 0), false); if (ctrl) { caretPos = caret.GetPosition(true); int pos = caretPos.Pos; List<Token> tokens = new List<Token>(); Lexer lexer = new Lexer(new StringReader(lines[caretPos.Line].Text)); { Token token; while (!((token = lexer.Next()) is EOF)) { if (token is TWhiteSpace) continue; tokens.Add(token); } } if (tokens.Count > 0) { Token token = tokens[0]; pos = token.Pos - 1; } else pos = lines[caretPos.Line].Text.Length; caret.SetPosition(new TextPoint(caretPos.Line, pos), true); } Invalidate(); } break; } CaretMoved(!shift); return true; case Keys.Left: if (!TextMarked) { TextMarked = shift; mouseDownPos = caretPos; } //if (!shift) // TextMarked = false; while (true) { if (caretPos.Pos > 0) { lines[caretPos.Line].Invalidated = true; int pos = caretPos.Pos - 1; if (ctrl) { List<Token> tokens = new List<Token>(); Lexer lexer = new Lexer(new StringReader(lines[caretPos.Line].Text)); { Token token; while (!((token = lexer.Next()) is EOF)) { if (token is TWhiteSpace) continue; tokens.Add(token); } } bool moved = false; for (int i = tokens.Count - 1; i >= 0; i--) { Token token = tokens[i]; if (token.Pos - 1 <= pos) { pos = token.Pos - 1; moved = true; break; } } if (!moved) { caretPos.Pos = 0; continue; } } caret.SetPosition(new TextPoint(caretPos.Line, pos), true); Invalidate(); } else if (caretPos.Line > 0) { lines[caretPos.Line].Invalidated = true; //Skip over any potential hidden lines caret.SetPosition(new TextPoint(caret.GetPosition(false).Line - 1, 0), false); caretPos = caret.GetPosition(true); caret.SetPosition(new TextPoint(caretPos.Line, lines[caretPos.Line].Text.Length), true); if (ctrl) { caretPos = caret.GetPosition(true); int pos = caretPos.Pos; List<Token> tokens = new List<Token>(); Lexer lexer = new Lexer(new StringReader(lines[caretPos.Line].Text)); { Token token; while (!((token = lexer.Next()) is EOF)) { if (token is TWhiteSpace) continue; tokens.Add(token); } } if (tokens.Count > 0) { Token token = tokens[tokens.Count - 1]; pos = token.Pos - 1 + token.Text.Length; } caret.SetPosition(new TextPoint(caretPos.Line, pos), true); } Invalidate(); } break; } CaretMoved(!shift); return true; case Keys.Up: if (!TextMarked) { TextMarked = shift; mouseDownPos = caretPos; } //if (!shift) // TextMarked = false; if (caretPos.Line > 0) { lines[caretPos.Line].Invalidated = true; lines[caretPos.Line - 1].Invalidated = true; int oldPos = 0; for (int i = 0; i < caretPos.Pos; i++) { oldPos++; if (lines[caretPos.Line].Text[i] == '\t') oldPos += 3; else if (lines[caretPos.Line].Text[i] > 0xFF) oldPos++; } caret.SetPosition(new TextPoint(caret.GetPosition(false).Line - 1, 0), false); caretPos = caret.GetPosition(true); int newPos = 0; for (newPos = 0; newPos < lines[caretPos.Line].Text.Length; newPos++) { if (oldPos <= 0) break; if (lines[caretPos.Line].Text[newPos] == '\t') { oldPos -= 4; if (oldPos < -2) { newPos--; } } else if (lines[caretPos.Line].Text[newPos] > 0xFF) oldPos -= 2; else oldPos--; } caret.SetPosition(new TextPoint(caretPos.Line, /*Math.Min(lines[caretPos.Line].Text.Length, oldPos)*/newPos), true); Invalidate(); } CaretMoved(!shift); return true; case Keys.Down: if (!TextMarked) { TextMarked = shift; mouseDownPos = caretPos; } //if (!shift) // TextMarked = false; if (caretPos.Line + 1 < lines.Count) { lines[caretPos.Line].Invalidated = true; lines[caretPos.Line + 1].Invalidated = true; int oldPos = 0; for (int i = 0; i < caretPos.Pos; i++) { oldPos++; if (lines[caretPos.Line].Text[i] == '\t') oldPos += 3; else if (lines[caretPos.Line].Text[i] > 0xFF) oldPos++; } caret.SetPosition(new TextPoint(caret.GetPosition(false).Line + 1, 0), false); caretPos = caret.GetPosition(true); int newPos = 0; for (newPos = 0; newPos < lines[caretPos.Line].Text.Length; newPos++) { if (oldPos <= 0) break; if (lines[caretPos.Line].Text[newPos] == '\t') { oldPos -= 4; if (oldPos < -2) { newPos--; } } else if (lines[caretPos.Line].Text[newPos] > 0xFF) oldPos -= 2; else oldPos--; } caret.SetPosition(new TextPoint(caretPos.Line, /*Math.Min(lines[caretPos.Line].Text.Length, oldPos)*/newPos), true); Invalidate(); } CaretMoved(!shift); return true; case Keys.End: if (!TextMarked) { TextMarked = true; mouseDownPos = caretPos; } if (!shift) TextMarked = false; if (caretPos.Pos < lines[caretPos.Line].Text.Length) { lines[caretPos.Line].Invalidated = true; caret.SetPosition(new TextPoint(caretPos.Line, lines[caretPos.Line].Text.Length), true); Invalidate(); } CaretMoved(!shift); return true; case Keys.Home: if (!TextMarked) { TextMarked = true; mouseDownPos = caretPos; } if (!shift) TextMarked = false; if (caretPos.Pos > 0) { lines[caretPos.Line].Invalidated = true; caret.SetPosition(new TextPoint(caretPos.Line, 0), true); Invalidate(); } CaretMoved(!shift); return true; case Keys.PageUp: if (!TextMarked) { TextMarked = true; mouseDownPos = caretPos; } if (!shift) TextMarked = false; if (caretPos.Line > 0) { lines[caretPos.Line].Invalidated = true; int line = caretPos.Line; int subtractedLines = 40; while (line > 0 && subtractedLines > 0) { line--; if (lines[line].LineVisible) subtractedLines--; } int pos = caretPos.Pos; if (pos > lines[line].Text.Length) pos = lines[line].Text.Length; caret.SetPosition(new TextPoint(line, pos), true); } CaretMoved(!shift); return true; case Keys.PageDown: if (!TextMarked) { TextMarked = true; mouseDownPos = caretPos; } if (!shift) TextMarked = false; if (caretPos.Line + 1 < lines.Count) { lines[caretPos.Line].Invalidated = true; int line = caretPos.Line; int addedLines = 40; while (line < lines.Count - 1 && addedLines > 0) { line++; if (lines[line].LineVisible) addedLines--; } int pos = caretPos.Pos; if (pos > lines[line].Text.Length) pos = lines[line].Text.Length; caret.SetPosition(new TextPoint(line, pos), true); } CaretMoved(!shift); return true; } //Handle ctrl commands if (e.Modifiers == Keys.Control) { //Copy if (e.KeyValue != 17) e = e; if (e.KeyValue == 'C' || e.KeyValue == 'X') { Copy(e.KeyValue == 'X'); return true; } //Paste if (e.KeyValue == 'V' && !IsReadonly) { Paste(); return true; } //Goto line if (e.KeyValue == 'G') { GotoLineForm dialog = new GotoLineForm(caretPos.Line + 1, lines.Count); if (dialog.ShowDialog(parentForm) == DialogResult.OK) { caret.SetPosition(new TextPoint(dialog.SelectedLine - 1, 0), true); EnsureLineVisible(dialog.SelectedLine - 1); CaretMoved(); } return true; } if (e.KeyValue == 'A') { mouseDownPos = new TextPoint(0, 0); caret.SetPosition(new TextPoint(lines.Count - 1, lines[lines.Count - 1].Text.Length), true); TextMarked = true; InvalidateAll = true; CaretMoved(false); return true; } if (e.KeyValue == 'F' || e.KeyValue == 'R') { //FindAndReplaceForm.form.SetStart(((Form1.OpenFileData)Tag).File, caretPos); OpenFindAndReplace(); return true; } if (e.KeyValue == 'Z') { UndoSys.Undo(); return true; } if (e.KeyValue == 'Y') { UndoSys.Redo(); return true; } } return false; }