Search in sources :

Example 1 with TextObjectAction

use of com.maddyhome.idea.vim.action.motion.TextObjectAction in project ideavim by JetBrains.

the class MotionGroup method getMotionRange.

/**
   * This helper method calculates the complete range a motion will move over taking into account whether
   * the motion is FLAG_MOT_LINEWISE or FLAG_MOT_CHARACTERWISE (FLAG_MOT_INCLUSIVE or FLAG_MOT_EXCLUSIVE).
   *
   * @param editor     The editor the motion takes place in
   * @param context    The data context
   * @param count      The count applied to the motion
   * @param rawCount   The actual count entered by the user
   * @param argument   Any argument needed by the motion
   * @param incNewline True if to include newline
   * @return The motion's range
   */
@Nullable
public static TextRange getMotionRange(@NotNull Editor editor, DataContext context, int count, int rawCount, @NotNull Argument argument, boolean incNewline) {
    final Command cmd = argument.getMotion();
    if (cmd == null) {
        return null;
    }
    // Normalize the counts between the command and the motion argument
    int cnt = cmd.getCount() * count;
    int raw = rawCount == 0 && cmd.getRawCount() == 0 ? 0 : cnt;
    int start = 0;
    int end = 0;
    if (cmd.getAction() instanceof MotionEditorAction) {
        MotionEditorAction action = (MotionEditorAction) cmd.getAction();
        // This is where we are now
        start = editor.getCaretModel().getOffset();
        // Execute the motion (without moving the cursor) and get where we end
        end = action.getOffset(editor, context, cnt, raw, cmd.getArgument());
        // Invalid motion
        if (end == -1) {
            return null;
        }
    } else if (cmd.getAction() instanceof TextObjectAction) {
        TextObjectAction action = (TextObjectAction) cmd.getAction();
        TextRange range = action.getRange(editor, context, cnt, raw, cmd.getArgument());
        if (range == null) {
            return null;
        }
        start = range.getStartOffset();
        end = range.getEndOffset();
    }
    // If we are a linewise motion we need to normalize the start and stop then move the start to the beginning
    // of the line and move the end to the end of the line.
    int flags = cmd.getFlags();
    if ((flags & Command.FLAG_MOT_LINEWISE) != 0) {
        if (start > end) {
            int t = start;
            start = end;
            end = t;
        }
        start = EditorHelper.getLineStartForOffset(editor, start);
        end = Math.min(EditorHelper.getLineEndForOffset(editor, end) + (incNewline ? 1 : 0), EditorHelper.getFileSize(editor));
    } else // If characterwise and inclusive, add the last character to the range
    if ((flags & Command.FLAG_MOT_INCLUSIVE) != 0) {
        end++;
    }
    // Normalize the range
    if (start > end) {
        int t = start;
        start = end;
        end = t;
    }
    return new TextRange(start, end);
}
Also used : MotionEditorAction(com.maddyhome.idea.vim.action.motion.MotionEditorAction) TextObjectAction(com.maddyhome.idea.vim.action.motion.TextObjectAction) TextRange(com.maddyhome.idea.vim.common.TextRange) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

MotionEditorAction (com.maddyhome.idea.vim.action.motion.MotionEditorAction)1 TextObjectAction (com.maddyhome.idea.vim.action.motion.TextObjectAction)1 TextRange (com.maddyhome.idea.vim.common.TextRange)1 Nullable (org.jetbrains.annotations.Nullable)1