Search in sources :

Example 1 with Command

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();
    }
}
Also used : Command(com.maddyhome.idea.vim.command.Command) CommandState(com.maddyhome.idea.vim.command.CommandState)

Example 2 with Command

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);
                }
            }
        }
    }
}
Also used : LogicalPosition(com.intellij.openapi.editor.LogicalPosition) Command(com.maddyhome.idea.vim.command.Command) Mark(com.maddyhome.idea.vim.common.Mark)

Example 3 with Command

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;
}
Also used : Command(com.maddyhome.idea.vim.command.Command)

Example 4 with Command

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;
        }
    }
}
Also used : Argument(com.maddyhome.idea.vim.command.Argument) Command(com.maddyhome.idea.vim.command.Command)

Example 5 with Command

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);
    }
}
Also used : Project(com.intellij.openapi.project.Project) Argument(com.maddyhome.idea.vim.command.Argument) Command(com.maddyhome.idea.vim.command.Command)

Aggregations

Command (com.maddyhome.idea.vim.command.Command)7 Argument (com.maddyhome.idea.vim.command.Argument)3 LogicalPosition (com.intellij.openapi.editor.LogicalPosition)1 Project (com.intellij.openapi.project.Project)1 CommandState (com.maddyhome.idea.vim.command.CommandState)1 Mark (com.maddyhome.idea.vim.common.Mark)1 TextRange (com.maddyhome.idea.vim.common.TextRange)1