Ejemplo n.º 1
0
        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);
                }
            }
        }
Ejemplo n.º 2
0
        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;
        }