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; } } }
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(); } } }