use of com.maddyhome.idea.vim.command.Command in project ideavim by JetBrains.
the class EditorActionHandlerBase method execute.
public final void execute(@NotNull Editor editor, @NotNull DataContext context) {
editor = InjectedLanguageUtil.getTopLevelEditor(editor);
logger.debug("execute");
if (!VimPlugin.isEnabled()) {
return;
}
final CommandState state = CommandState.getInstance(editor);
final Command cmd = state.getCommand();
if (cmd == null || !execute(editor, context, cmd)) {
VimPlugin.indicateError();
}
}
use of com.maddyhome.idea.vim.command.Command in project ideavim by JetBrains.
the class MarkGroup method updateMarkFromDelete.
/**
* This updates all the marks for a file whenever text is deleted from the file. If the line that contains a mark
* is completely deleted then the mark is deleted too. If the deleted text is before the marked line, the mark is
* moved up by the number of deleted lines.
*
* @param editor The modified editor
* @param marks The editor's marks to update
* @param delStartOff The offset within the editor where the deletion occurred
* @param delLength The length of the deleted text
*/
public static void updateMarkFromDelete(@Nullable Editor editor, @Nullable HashMap<Character, Mark> marks, int delStartOff, int delLength) {
// Skip all this work if there are no marks
if (marks != null && marks.size() > 0 && editor != null) {
// Calculate the logical position of the start and end of the deleted text
int delEndOff = delStartOff + delLength - 1;
LogicalPosition delStart = editor.offsetToLogicalPosition(delStartOff);
LogicalPosition delEnd = editor.offsetToLogicalPosition(delEndOff + 1);
if (logger.isDebugEnabled())
logger.debug("mark delete. delStart = " + delStart + ", delEnd = " + delEnd);
// Now analyze each mark to determine if it needs to be updated or removed
for (Character ch : marks.keySet()) {
Mark mark = marks.get(ch);
if (logger.isDebugEnabled())
logger.debug("mark = " + mark);
// proper number of lines.
if (delEnd.line < mark.getLogicalLine()) {
int lines = delEnd.line - delStart.line;
if (logger.isDebugEnabled())
logger.debug("Shifting mark by " + lines + " lines");
mark.setLogicalLine(mark.getLogicalLine() - lines);
} else // If the deleted text begins before the mark and ends after the mark then it may be shifted or deleted
if (delStart.line <= mark.getLogicalLine() && delEnd.line >= mark.getLogicalLine()) {
int markLineStartOff = EditorHelper.getLineStartOffset(editor, mark.getLogicalLine());
int markLineEndOff = EditorHelper.getLineEndOffset(editor, mark.getLogicalLine(), true);
Command command = CommandState.getInstance(editor).getCommand();
// If text is being changed from the start of the mark line (a special case for mark deletion)
boolean changeFromMarkLineStart = command != null && command.getType() == Command.Type.CHANGE && delStartOff == markLineStartOff;
// If the marked line is completely within the deleted text, remove the mark (except the special case)
if (delStartOff <= markLineStartOff && delEndOff >= markLineEndOff && !changeFromMarkLineStart) {
VimPlugin.getMark().removeMark(ch, mark);
logger.debug("Removed mark");
} else // on a line prior to the marked line (which means the deletion must end on the marked line).
if (delStart.line < mark.getLogicalLine()) {
// shift mark
mark.setLogicalLine(delStart.line);
if (logger.isDebugEnabled())
logger.debug("Shifting mark to line " + delStart.line);
}
}
}
}
}
use of com.maddyhome.idea.vim.command.Command in project ideavim by JetBrains.
the class KeyHandler method handleArgumentNode.
private boolean handleArgumentNode(@NotNull Editor editor, @NotNull KeyStroke key, @NotNull DataContext context, @NotNull CommandState editorState, @NotNull ArgumentNode node) {
// Create a new command based on what the user has typed so far, excluding this keystroke.
Command cmd = new Command(count, node.getActionId(), node.getAction(), node.getCmdType(), node.getFlags());
cmd.setKeys(keys);
currentCmd.push(cmd);
// What type of argument does this command expect?
switch(node.getArgType()) {
case DIGRAPH:
//digraphState = 0;
digraph = new DigraphSequence();
// No break - fall through
case CHARACTER:
case MOTION:
state = State.NEW_COMMAND;
currentArg = node.getArgType();
// commands
if ((node.getFlags() & Command.FLAG_OP_PEND) != 0) {
editorState.pushState(editorState.getMode(), editorState.getSubMode(), MappingMode.OP_PENDING);
}
break;
case EX_STRING:
break;
default:
// Oops - we aren't expecting any other type of argument
state = State.ERROR;
}
// handle the argument
if (currentArg != Argument.Type.NONE) {
partialReset(editor);
handleKey(editor, key, context);
return false;
}
return true;
}
use of com.maddyhome.idea.vim.command.Command in project ideavim by JetBrains.
the class KeyHandler method handleCommandNode.
private void handleCommandNode(@NotNull Editor editor, @NotNull DataContext context, @NotNull CommandNode node) {
// If all does well we are ready to process this command
state = State.READY;
// Did we just get the completed sequence for a motion command argument?
if (currentArg == Argument.Type.MOTION) {
// We have been expecting a motion argument - is this one?
if (node.getCmdType() == Command.Type.MOTION) {
// Create the motion command and add it to the stack
Command cmd = new Command(count, node.getActionId(), node.getAction(), node.getCmdType(), node.getFlags());
cmd.setKeys(keys);
currentCmd.push(cmd);
} else if (node.getCmdType() == Command.Type.RESET) {
currentCmd.clear();
Command cmd = new Command(1, node.getActionId(), node.getAction(), node.getCmdType(), node.getFlags());
cmd.setKeys(keys);
currentCmd.push(cmd);
} else {
// Oops - this wasn't a motion command. The user goofed and typed something else
state = State.BAD_COMMAND;
}
} else if (currentArg == Argument.Type.EX_STRING && (node.getFlags() & Command.FLAG_COMPLETE_EX) != 0) {
String text = VimPlugin.getProcess().endSearchCommand(editor, context);
Argument arg = new Argument(text);
Command cmd = currentCmd.peek();
cmd.setArgument(arg);
CommandState.getInstance(editor).popState();
} else // The user entered a valid command that doesn't take any arguments
{
// Create the command and add it to the stack
Command cmd = new Command(count, node.getActionId(), node.getAction(), node.getCmdType(), node.getFlags());
cmd.setKeys(keys);
currentCmd.push(cmd);
// programmer made a typo or forgot to add the action to the plugin.xml file
if (cmd.getAction() == null) {
state = State.ERROR;
}
}
}
use of com.maddyhome.idea.vim.command.Command in project ideavim by JetBrains.
the class KeyHandler method executeCommand.
private void executeCommand(@NotNull Editor editor, @NotNull KeyStroke key, @NotNull DataContext context, @NotNull CommandState editorState) {
// Let's go through the command stack and merge it all into one command. At this time there should never
// be more than two commands on the stack - one is the actual command and the other would be a motion
// command argument needed by the first command
Command cmd = currentCmd.pop();
while (currentCmd.size() > 0) {
Command top = currentCmd.pop();
top.setArgument(new Argument(cmd));
cmd = top;
}
// If we have a command and a motion command argument, both could possibly have their own counts. We
// need to adjust the counts so the motion gets the product of both counts and the count associated with
// the command gets reset. Example 3c2w (change 2 words, three times) becomes c6w (change 6 words)
final Argument arg = cmd.getArgument();
if (arg != null && arg.getType() == Argument.Type.MOTION) {
final Command mot = arg.getMotion();
// the motion gets the product of both.
if (mot != null) {
int cnt = cmd.getRawCount() == 0 && mot.getRawCount() == 0 ? 0 : cmd.getCount() * mot.getCount();
mot.setCount(cnt);
}
cmd.setCount(0);
}
// If we were in "operator pending" mode, reset back to normal mode.
if (editorState.getMappingMode() == MappingMode.OP_PENDING) {
editorState.popState();
}
// Save off the command we are about to execute
editorState.setCommand(cmd);
lastWasBS = ((cmd.getFlags() & Command.FLAG_IS_BACKSPACE) != 0);
Project project = editor.getProject();
if (cmd.getType().isRead() || project == null || EditorHelper.canEdit(project, editor)) {
if (ApplicationManager.getApplication().isDispatchThread()) {
Runnable action = new ActionRunner(editor, context, cmd, key);
String name = cmd.getAction().getTemplatePresentation().getText();
name = name != null ? "Vim " + name : "";
if (cmd.getType().isWrite()) {
RunnableHelper.runWriteCommand(project, action, name, action);
} else {
RunnableHelper.runReadCommand(project, action, name, action);
}
}
} else {
VimPlugin.indicateError();
reset(editor);
}
}
Aggregations