private void ProcessParserCommand(out string viShortcut, out bool scrollToCursor)
        {
            viShortcut     = null;
            scrollToCursor = true;
            ViMoves.IMove move  = null;
            int           count = parser.FictiveCount;

            switch (parser.move.Index)
            {
            case 'f' + ViChar.ControlIndex:
                move = new ViMoves.PageUpDown(false);
                break;

            case 'b' + ViChar.ControlIndex:
                move = new ViMoves.PageUpDown(true);
                break;

            case 'h':
                move = new ViMoves.MoveStep(Direction.Left);
                break;

            case 'l':
                move = new ViMoves.MoveStep(Direction.Right);
                break;

            case 'j':
                if (parser.moveChar.c == 'g')
                {
                    move = new ViMoves.SublineMoveStep(Direction.Down);
                }
                else
                {
                    move = new ViMoves.MoveStep(Direction.Down);
                }
                break;

            case 'k':
                if (parser.moveChar.c == 'g')
                {
                    move = new ViMoves.SublineMoveStep(Direction.Up);
                }
                else
                {
                    move = new ViMoves.MoveStep(Direction.Up);
                }
                break;

            case 'w':
                move = new ViMoves.MoveWord(Direction.Right);
                break;

            case 'b':
                move = new ViMoves.MoveWord(Direction.Left);
                break;

            case 'e':
                move = new ViMoves.MoveWordE();
                break;

            case 'f':
            case 'F':
            case 't':
            case 'T':
                move  = new ViMoves.Find(parser.move.c, parser.moveChar.c, count);
                count = 1;
                break;

            case '`':
            case '\'':
                if (ViMoves.JumpBookmark.GetLocalPosition(controller, parser.moveChar.c) == -1)
                {
                    viShortcut = "" + parser.move.c + parser.moveChar.c;
                    return;
                }
                move = new ViMoves.JumpBookmark(parser.move.c, parser.moveChar.c);
                break;

            case '0':
                move = new ViMoves.Home(false);
                break;

            case '^':
                move = new ViMoves.Home(true);
                break;

            case '$':
                move  = new ViMoves.End(count);
                count = 1;
                break;

            case 'G':
                if (parser.rawCount == -1)
                {
                    move = new ViMoves.DocumentEnd();
                }
                else
                {
                    move = new ViMoves.GoToLine(parser.rawCount);
                }
                count = 1;
                break;

            case 'g':
                if (parser.moveChar.IsChar('g'))
                {
                    move  = new ViMoves.DocumentStart();
                    count = 1;
                }
                break;

            case 'i':
            case 'a':
                move  = new ViMoves.MoveObject(parser.moveChar.c, parser.move.c == 'i', count);
                count = 1;
                break;

            case 'n':
                move = new ViMoves.FindForwardPattern();
                break;

            case 'N':
                move = new ViMoves.FindBackwardPattern();
                break;

            case '%':
                move = new ViMoves.FindPairBracket();
                break;
            }
            ViCommands.ICommand command = null;
            int  deltaX           = -1;
            int  deltaY           = -1;
            bool needViMode       = false;
            bool forceLastCommand = false;

            if (move != null)
            {
                for (int i = 0; i < count; i++)
                {
                    move.Move(controller, true, MoveMode.Move);
                }
            }
            else
            {
                if (lines.LastSelection.Count > 0)
                {
                    Place anchorPlace = lines.PlaceOf(lines.LastSelection.anchor);
                    Place caretPlace  = lines.PlaceOf(lines.LastSelection.caret);
                    deltaX = caretPlace.iChar - anchorPlace.iChar;
                    deltaY = caretPlace.iLine - anchorPlace.iLine;
                }
                else
                {
                    deltaX = 0;
                    deltaY = 0;
                }
                switch (parser.action.Index)
                {
                case 'u':
                    controller.ViStoreSelections();
                    controller.ChangeCase(false);
                    controller.MoveLeft(false);
                    context.SetState(new ViReceiver(null, false));
                    count = 1;
                    break;

                case 'U':
                    controller.ViStoreSelections();
                    controller.ChangeCase(true);
                    controller.MoveLeft(false);
                    context.SetState(new ViReceiver(null, false));
                    count = 1;
                    break;

                case 'r':
                    command    = new ViCommands.ReplaceChar(parser.moveChar.c, count);
                    needViMode = true;
                    count      = 1;
                    break;

                case ' ':
                    context.SetState(new ViJumpReceiver(parser.moveChar.c,
                                                        _lineMode ? ViJumpReceiver.Mode.LinesSelection : ViJumpReceiver.Mode.Selection));
                    scrollToCursor = false;
                    break;

                case 'p':
                    command = new ViCommands.Paste(Direction.Right, parser.register, count);
                    count   = 1;
                    break;

                case 'P':
                    command = new ViCommands.Paste(Direction.Left, parser.register, count);
                    count   = 1;
                    break;

                case 'J':
                    command = new ViCommands.J();
                    break;

                case 'd':
                case 'x':
                    if (controller.isReadonly)
                    {
                        viShortcut = "v_" + parser.GetFictiveShortcut();
                    }
                    else
                    {
                        if (_lineMode)
                        {
                            controller.ViDeleteLine(parser.register, 1);
                        }
                        else
                        {
                            controller.ViCut(parser.register, true);
                        }
                        SetViMode();
                        forceLastCommand = true;
                    }
                    break;

                case 'c':
                    if (_lineMode)
                    {
                        controller.ViStoreSelections();
                        controller.ViCopyLine('0', 1);
                        controller.ViDeleteLineForChange('0', 1);
                    }
                    else
                    {
                        controller.ViCut(parser.register, false);
                    }
                    context.SetState(new InputReceiver(null, false));
                    break;

                case 'y':
                    if (_lineMode)
                    {
                        controller.ViStoreSelections();
                        controller.ViCopyLine(parser.register, count);
                    }
                    else
                    {
                        controller.ViStoreSelections();
                        controller.ViCopy(parser.register);
                    }
                    controller.ViCollapseSelections();
                    SetViMode();
                    break;

                case 'Y':
                    controller.ViStoreSelections();
                    controller.ViCopyLine(parser.register, count);
                    SetViMode();
                    break;

                case 'd' + ViChar.ControlIndex:
                    controller.SelectNextText();
                    break;

                case 'D' + ViChar.ControlIndex:
                    controller.SelectAllMatches();
                    break;

                case 'J' + ViChar.ControlIndex:
                    controller.PutCursorDown();
                    break;

                case 'K' + ViChar.ControlIndex:
                    controller.PutCursorUp();
                    break;

                case '>':
                    controller.ViShift(count, 1, false);
                    controller.ViCollapseSelections();
                    controller.ViMoveHome(false, true);
                    SetViMode();
                    forceLastCommand = true;
                    break;

                case '<':
                    controller.ViShift(count, 1, true);
                    controller.ViCollapseSelections();
                    controller.ViMoveHome(false, true);
                    SetViMode();
                    forceLastCommand = true;
                    break;

                case 'r' + ViChar.ControlIndex:
                    ProcessRedo(count);
                    break;

                case 's':
                    controller.ViSelectRight(count);
                    controller.EraseSelection();
                    context.SetState(new InputReceiver(new ViReceiverData('s', 1), false));
                    break;

                case 'I':
                    if (!controller.AllSelectionsEmpty)
                    {
                        controller.ViStoreSelections();
                        foreach (Selection selection in controller.Selections)
                        {
                            int left = selection.Left;
                            selection.anchor = left;
                            selection.caret  = left;
                        }
                    }
                    context.SetState(new InputReceiver(new ViReceiverData('i', count), false));
                    break;

                case 'A':
                    if (!controller.AllSelectionsEmpty)
                    {
                        controller.ViStoreSelections();
                        foreach (Selection selection in controller.Selections)
                        {
                            int right = selection.Right;
                            selection.anchor = right;
                            selection.caret  = right;
                        }
                        context.SetState(new InputReceiver(new ViReceiverData('i', count), false));
                    }
                    break;

                case 'o':
                case 'O':
                    foreach (Selection selection in controller.Selections)
                    {
                        int position = selection.anchor;
                        selection.anchor = selection.caret;
                        selection.caret  = position;
                    }
                    break;

                case 'j' + ViChar.ControlIndex:
                    for (int i = 0; i < count; i++)
                    {
                        controller.ScrollRelative(0, 1);
                    }
                    scrollToCursor = false;
                    break;

                case 'k' + ViChar.ControlIndex:
                    for (int i = 0; i < count; i++)
                    {
                        controller.ScrollRelative(0, -1);
                    }
                    scrollToCursor = false;
                    break;

                case 'v':
                    if (_lineMode)
                    {
                        context.SetState(new ViReceiverVisual(false));
                    }
                    else
                    {
                        SetViMode();
                    }
                    break;

                case 'V':
                    if (!_lineMode)
                    {
                        context.SetState(new ViReceiverVisual(true));
                    }
                    else
                    {
                        SetViMode();
                    }
                    break;

                case '*':
                    if (!controller.LastSelection.Empty)
                    {
                        string text = controller.Lines.GetText(
                            controller.LastSelection.Left, controller.LastSelection.Count);
                        DoFind(new Pattern(text, false, false), false);
                        SetViMode();
                    }
                    else
                    {
                        string text = controller.GetWord(controller.Lines.PlaceOf(controller.LastSelection.caret));
                        if (!string.IsNullOrEmpty(text))
                        {
                            DoFind(new Pattern("\\b" + text + "\\b", true, false), false);
                        }
                        SetViMode();
                    }
                    break;

                case '\b':
                    for (int i = 0; i < count; i++)
                    {
                        if (lines.AllSelectionsEmpty)
                        {
                            controller.Backspace();
                        }
                        else
                        {
                            controller.EraseSelection();
                        }
                    }
                    break;

                case '\r':
                    for (int i = 0; i < count; i++)
                    {
                        controller.InsertLineBreak();
                    }
                    break;
                }
            }
            if (command != null)
            {
                command.Execute(controller);
                controller.ViResetCommandsBatching();
                if (needViMode)
                {
                    SetViMode();
                }
            }
            if (command != null || forceLastCommand)
            {
                if (controller.macrosExecutor != null)
                {
                    controller.macrosExecutor.lastCommand          = parser.GetLastCommand();
                    controller.macrosExecutor.lastCommand.deltaX   = deltaX;
                    controller.macrosExecutor.lastCommand.deltaY   = deltaY;
                    controller.macrosExecutor.lastCommand.lineMode = _lineMode;
                }
            }
        }
Example #2
0
        private void ProcessParserCommand(out string viShortcut, out bool scrollToCursor)
        {
            viShortcut     = null;
            scrollToCursor = true;
            ViMoves.IMove move            = null;
            bool          needHistoryMove = true;
            int           count           = parser.FictiveCount;
            bool          needInput       = false;

            switch (parser.move.Index)
            {
            case 'f' + ViChar.ControlIndex:
                move = new ViMoves.PageUpDown(false);
                break;

            case 'b' + ViChar.ControlIndex:
                move = new ViMoves.PageUpDown(true);
                break;

            case 'h':
                if (controller.AllSelectionsEmpty || count > 1)
                {
                    move            = new ViMoves.MoveStep(Direction.Left);
                    needHistoryMove = count > 1;
                }
                else
                {
                    controller.ViStoreSelections();
                    controller.MoveLeft(false);
                }
                break;

            case 'l':
                if (controller.AllSelectionsEmpty || count > 1)
                {
                    move            = new ViMoves.MoveStep(Direction.Right);
                    needHistoryMove = count > 1;
                }
                else
                {
                    controller.ViStoreSelections();
                    controller.MoveRight(false);
                    controller.ViFixPositions(false);
                }
                break;

            case 'j':
                if (parser.moveChar.c == 'g')
                {
                    move = new ViMoves.SublineMoveStep(Direction.Down);
                }
                else
                {
                    move = new ViMoves.MoveStep(Direction.Down);
                }
                needHistoryMove = count > 1;
                break;

            case 'k':
                if (parser.moveChar.c == 'g')
                {
                    move = new ViMoves.SublineMoveStep(Direction.Up);
                }
                else
                {
                    move = new ViMoves.MoveStep(Direction.Up);
                }
                needHistoryMove = count > 1;
                break;

            case 'w':
                move = new ViMoves.MoveWord(Direction.Right);
                break;

            case 'W':
                move = new ViMoves.BigMoveWord(Direction.Right);
                break;

            case 'b':
                move = new ViMoves.MoveWord(Direction.Left);
                break;

            case 'B':
                move = new ViMoves.BigMoveWord(Direction.Left);
                break;

            case 'e':
                move = new ViMoves.MoveWordE();
                break;

            case 'E':
                move = new ViMoves.BigMoveWordE();
                break;

            case 'f':
            case 'F':
            case 't':
            case 'T':
                move  = new ViMoves.Find(parser.move.c, parser.moveChar.origin, count);
                count = 1;
                break;

            case '`':
            case '\'':
                if (ViMoves.JumpBookmark.GetLocalPosition(controller, parser.moveChar.c) == -1)
                {
                    viShortcut = "" + parser.move.c + parser.moveChar.c;
                    return;
                }
                move = new ViMoves.JumpBookmark(parser.move.c, parser.moveChar.c);
                break;

            case '0':
                move = new ViMoves.Home(false);
                break;

            case '^':
                move = new ViMoves.Home(true);
                break;

            case '$':
                move  = new ViMoves.End(count);
                count = 1;
                break;

            case 'G':
                if (parser.rawCount == -1)
                {
                    move = new ViMoves.DocumentEnd();
                }
                else
                {
                    move = new ViMoves.GoToLine(parser.rawCount);
                }
                count = 1;
                break;

            case 'g':
                if (parser.moveChar.IsChar('g'))
                {
                    move = new ViMoves.DocumentStart();
                }
                else if (parser.moveChar.IsChar('v'))
                {
                    bool asLines = controller.ViSelectionsAsLines;
                    controller.ViRecoverSelections();
                    if (!controller.AllSelectionsEmpty)
                    {
                        context.SetState(new ViReceiverVisual(asLines));
                    }
                }
                else if (parser.moveChar.IsChar(']'))
                {
                    viShortcut = "" + parser.move.c + parser.moveChar.c;
                    return;
                }
                count = 1;
                break;

            case 'i':
            case 'a':
                move  = new ViMoves.MoveObject(parser.moveChar.c, parser.move.c == 'i', count);
                count = 1;
                break;

            case 'n':
                move = new ViMoves.FindForwardPattern();
                break;

            case 'N':
                move = new ViMoves.FindBackwardPattern();
                break;

            case '%':
                move = new ViMoves.FindPairBracket();
                break;
            }
            ViCommands.ICommand command = null;
            bool forceLastCommand       = false;

            if (move != null)
            {
                switch (parser.action.Index)
                {
                case 'd':
                    command = new ViCommands.Delete(move, count, false, parser.register);
                    break;

                case 'c':
                    command = new ViCommands.Delete(move, count, true, parser.register);
                    context.SetState(new InputReceiver(new ViReceiverData('c', 1), false));
                    break;

                case 'y':
                    for (int i = 0; i < count; i++)
                    {
                        move.Move(controller, true, MoveMode.Copy);
                    }
                    if (move.IsDCLines)
                    {
                        controller.ViCopyLine(parser.register, count);
                    }
                    else
                    {
                        controller.ViCopy(parser.register);
                    }
                    controller.ViCollapseSelections();
                    break;

                default:
                    for (int i = 0; i < count; i++)
                    {
                        move.Move(controller, false, MoveMode.Move);
                    }
                    break;
                }
            }
            else
            {
                switch (parser.action.Index)
                {
                case 'u':
                    ProcessUndo(count);
                    break;

                case 'r':
                    command = new ViCommands.ReplaceChar(parser.moveChar.origin, count);
                    break;

                case ' ':
                    context.SetState(new ViJumpReceiver(parser.moveChar.c, ViJumpReceiver.Mode.Single));
                    scrollToCursor = false;
                    break;

                case ',':
                    if (parser.move.IsChar(' '))
                    {
                        context.SetState(new ViJumpReceiver(parser.moveChar.c, ViJumpReceiver.Mode.New));
                    }
                    break;

                case 'x':
                    command = new ViCommands.Delete(
                        new ViMoves.MoveStep(Direction.Right), count, false, parser.register);
                    break;

                case '~':
                    command = new ViCommands.SwitchUpperLower(
                        new ViMoves.MoveStep(Direction.Right), count);
                    break;

                case 'p':
                    command = new ViCommands.Paste(Direction.Right, parser.register, count);
                    break;

                case 'P':
                    command = new ViCommands.Paste(Direction.Left, parser.register, count);
                    break;

                case 'J':
                    command = new ViCommands.J();
                    command = new ViCommands.Repeat(command, count);
                    break;

                case 'd':
                    if (parser.move.IsChar('d'))
                    {
                        command = new ViCommands.DeleteLine(count, parser.register);
                    }
                    break;

                case 'c':
                    if (parser.move.IsChar('c'))
                    {
                        controller.ViDeleteLineForChange(parser.register, count);
                        context.SetState(new InputReceiver(new ViReceiverData('c', 1), false));
                    }
                    break;

                case 'd' + ViChar.ControlIndex:
                    controller.SelectNextText();
                    if (!controller.AllSelectionsEmpty)
                    {
                        context.SetState(new ViReceiverVisual(false));
                    }
                    break;

                case 'D' + ViChar.ControlIndex:
                    controller.SelectAllMatches();
                    if (!controller.AllSelectionsEmpty)
                    {
                        context.SetState(new ViReceiverVisual(false));
                    }
                    break;

                case 'J' + ViChar.ControlIndex:
                    for (int i = 0; i < count; i++)
                    {
                        controller.PutCursorDown();
                    }
                    break;

                case 'K' + ViChar.ControlIndex:
                    for (int i = 0; i < count; i++)
                    {
                        controller.PutCursorUp();
                    }
                    break;

                case 'y':
                    if (parser.move.IsChar('y'))
                    {
                        controller.ViCopyLine(parser.register, count);
                    }
                    break;

                case 'Y':
                    controller.ViCopyLine(parser.register, count);
                    break;

                case '>':
                    if (parser.move.IsChar('>'))
                    {
                        controller.ViShift(1, count, false);
                        forceLastCommand = true;
                    }
                    break;

                case '<':
                    if (parser.move.IsChar('<'))
                    {
                        controller.ViShift(1, count, true);
                        forceLastCommand = true;
                    }
                    break;

                case '.':
                    if (controller.macrosExecutor != null && controller.macrosExecutor.lastCommand != null)
                    {
                        ViCommandParser.LastCommand lastCommand = null;
                        lastCommand = controller.macrosExecutor.lastCommand;
                        controller.macrosExecutor.lastCommand = null;
                        try
                        {
                            controller.processor.BeginBatch();
                            if (lastCommand.deltaX != -1 || lastCommand.deltaY != -1)
                            {
                                ViReceiverVisual receiver = new ViReceiverVisual(lastCommand.lineMode);
                                context.SetState(receiver);
                                receiver.ProcessLastCommand(lastCommand);
                                scrollToCursor = true;
                            }
                            else
                            {
                                for (int i = 0; i < count; i++)
                                {
                                    parser.SetLastCommand(lastCommand);
                                    string tempShortcut;
                                    bool   tempScrollToCursor;
                                    ProcessParserCommand(out tempShortcut, out tempScrollToCursor);
                                    if (tempScrollToCursor)
                                    {
                                        scrollToCursor = true;
                                    }
                                    if (lastCommand.startData != null)
                                    {
                                        lastCommand.startData.forcedInput = true;
                                        context.SetState(new ViReceiver(lastCommand.startData, true));
                                    }
                                }
                            }
                        }
                        finally
                        {
                            controller.processor.EndBatch();
                        }
                        return;
                    }
                    break;

                case 'r' + ViChar.ControlIndex:
                    ProcessRedo(count);
                    return;

                case 'o' + ViChar.ControlIndex:
                    viShortcut = "C-o";
                    return;

                case 'i' + ViChar.ControlIndex:
                    viShortcut = "C-i";
                    return;

                case 'i':
                    context.SetState(new InputReceiver(new ViReceiverData('i', count), false));
                    forceLastCommand = true;
                    break;

                case 'a':
                    controller.ViMoveRightFromCursor();
                    context.SetState(new InputReceiver(new ViReceiverData('a', count), false));
                    forceLastCommand = true;
                    break;

                case 's':
                    controller.ViSelectRight(count);
                    controller.EraseSelection();
                    context.SetState(new InputReceiver(new ViReceiverData('s', 1), false));
                    forceLastCommand = true;
                    break;

                case 'I':
                    controller.ViMoveHome(false, true);
                    context.SetState(new InputReceiver(new ViReceiverData('I', count), false));
                    forceLastCommand = true;
                    break;

                case 'A':
                    controller.ViMoveEnd(false, 1);
                    controller.ViMoveRightFromCursor();
                    context.SetState(new InputReceiver(new ViReceiverData('A', count), false));
                    forceLastCommand = true;
                    break;

                case 'o':
                    if (!controller.isReadonly)
                    {
                        controller.ViMoveEnd(false, 1);
                        controller.ViMoveRightFromCursor();
                        controller.InsertLineBreak();
                        context.SetState(new InputReceiver(new ViReceiverData('o', count), false));
                    }
                    forceLastCommand = true;
                    break;

                case 'O':
                    if (!controller.isReadonly)
                    {
                        controller.processor.BeginBatch();
                        controller.ViMoveHome(false, true);
                        controller.InsertLineBreak();
                        controller.ViLogicMoveUp(false);
                        if (lines.autoindent)
                        {
                            controller.ViAutoindentByBottom();
                        }
                        controller.processor.EndBatch();
                        context.SetState(new InputReceiver(new ViReceiverData('O', count), false));
                    }
                    forceLastCommand = true;
                    break;

                case 'C':
                    controller.ViMoveEnd(true, parser.FictiveCount);
                    controller.ViCut(parser.register, false);
                    context.SetState(new InputReceiver(new ViReceiverData('C', count), false));
                    forceLastCommand = true;
                    break;

                case 'D':
                    controller.ViMoveEnd(true, parser.FictiveCount);
                    controller.ViCut(parser.register, true);
                    forceLastCommand = true;
                    break;

                case 'j' + ViChar.ControlIndex:
                    controller.ScrollRelative(0, count > 1 ? count : lines.scrollingStep);
                    scrollToCursor = false;
                    break;

                case 'k' + ViChar.ControlIndex:
                    controller.ScrollRelative(0, count > 1 ? -count : -lines.scrollingStep);
                    scrollToCursor = false;
                    break;

                case 'v':
                    context.SetState(new ViReceiverVisual(false));
                    break;

                case 'V':
                    context.SetState(new ViReceiverVisual(true));
                    break;

                case '*':
                case '#':
                    string text = controller.GetWord(controller.Lines.PlaceOf(controller.LastSelection.caret));
                    if (!string.IsNullOrEmpty(text))
                    {
                        DoFind(new Pattern("\\b" + text + "\\b", true, false), parser.action.c == '#');
                    }
                    break;

                case '\b':
                    for (int i = 0; i < count; i++)
                    {
                        if (lines.AllSelectionsEmpty)
                        {
                            controller.Backspace();
                        }
                        else
                        {
                            controller.EraseSelection();
                        }
                    }
                    forceLastCommand = true;
                    break;

                case '\r':
                    for (int i = 0; i < count; i++)
                    {
                        controller.InsertLineBreak();
                    }
                    forceLastCommand = true;
                    break;

                case 'm':
                    if (ViMoves.JumpBookmark.IsFileBased(parser.moveChar.c))
                    {
                        if (controller.macrosExecutor != null)
                        {
                            controller.macrosExecutor.SetBookmark(parser.moveChar.c, controller.Lines.viFullPath, controller.LastSelection.caret);
                        }
                        return;
                    }
                    controller.SetBookmark(parser.moveChar.c, controller.LastSelection.anchor);
                    break;
                }
            }
            if ((move != null || needInput) && controller.macrosExecutor != null)
            {
                controller.ViAddHistoryPosition(needHistoryMove);
            }
            if (command != null)
            {
                command.Execute(controller);
                controller.ViResetCommandsBatching();
                if (needInput)
                {
                    context.SetState(new InputReceiver(null, false));
                }
            }
            if (command != null || forceLastCommand)
            {
                if (controller.macrosExecutor != null)
                {
                    controller.macrosExecutor.lastCommand = parser.GetLastCommand();
                }
                if (controller.isReadonly)
                {
                    viShortcut = parser.GetFictiveShortcut();
                }
            }
        }