Skip to content

Commit

Permalink
Partial implementation of virtualedit config
Browse files Browse the repository at this point in the history
This does not support all config settings,
but does add the 'onemore' option.

This partly addresses https://youtrack.jetbrains.com/issue/VIM-844
  • Loading branch information
i-e-b committed Aug 26, 2020
1 parent e597e06 commit 6be6e7f
Show file tree
Hide file tree
Showing 20 changed files with 293 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import com.maddyhome.idea.vim.command.Argument
import com.maddyhome.idea.vim.command.MotionType
import com.maddyhome.idea.vim.handler.NonShiftedSpecialKeyHandler
import com.maddyhome.idea.vim.helper.StringHelper.parseKeys
import com.maddyhome.idea.vim.helper.commandState
import com.maddyhome.idea.vim.helper.isEndAllowed
import java.awt.event.KeyEvent
import javax.swing.KeyStroke

Expand All @@ -39,7 +41,8 @@ class MotionArrowRightAction : NonShiftedSpecialKeyHandler(), ComplicatedKeysAct
)

override fun offset(editor: Editor, caret: Caret, context: DataContext, count: Int, rawCount: Int, argument: Argument?): Int {
return VimPlugin.getMotion().moveCaretHorizontal(editor, caret, count, false)
val allowPastEnd = editor.commandState.isEndAllowed
return VimPlugin.getMotion().moveCaretHorizontal(editor, caret, count, allowPastEnd)
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import com.maddyhome.idea.vim.command.MotionType
import com.maddyhome.idea.vim.handler.NonShiftedSpecialKeyHandler
import com.maddyhome.idea.vim.helper.EditorHelper
import com.maddyhome.idea.vim.helper.StringHelper.parseKeys
import com.maddyhome.idea.vim.helper.inNormalMode
import java.awt.event.KeyEvent
import javax.swing.KeyStroke

Expand All @@ -40,7 +41,7 @@ class MotionArrowDownAction : NonShiftedSpecialKeyHandler(), ComplicatedKeysActi
private var col: Int = 0

override fun offset(editor: Editor, caret: Caret, context: DataContext, count: Int, rawCount: Int, argument: Argument?): Int {
return VimPlugin.getMotion().moveCaretVertical(editor, caret, count)
return VimPlugin.getMotion().moveCaretVertical(editor, caret, count, editor.inNormalMode);
}

override fun preOffsetComputation(editor: Editor, caret: Caret, context: DataContext, cmd: Command): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import com.maddyhome.idea.vim.command.MotionType
import com.maddyhome.idea.vim.handler.NonShiftedSpecialKeyHandler
import com.maddyhome.idea.vim.helper.EditorHelper
import com.maddyhome.idea.vim.helper.StringHelper.parseKeys
import com.maddyhome.idea.vim.helper.inNormalMode
import java.awt.event.KeyEvent
import javax.swing.KeyStroke

Expand All @@ -40,7 +41,7 @@ class MotionArrowUpAction : NonShiftedSpecialKeyHandler(), ComplicatedKeysAction
private var col: Int = 0

override fun offset(editor: Editor, caret: Caret, context: DataContext, count: Int, rawCount: Int, argument: Argument?): Int {
return VimPlugin.getMotion().moveCaretVertical(editor, caret, -count)
return VimPlugin.getMotion().moveCaretVertical(editor, caret, -count, editor.inNormalMode);
}

override fun preOffsetComputation(editor: Editor, caret: Caret, context: DataContext, cmd: Command): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import com.maddyhome.idea.vim.command.Command
import com.maddyhome.idea.vim.command.MotionType
import com.maddyhome.idea.vim.handler.MotionActionHandler
import com.maddyhome.idea.vim.helper.EditorHelper
import com.maddyhome.idea.vim.helper.inNormalMode

sealed class MotionDownBase : MotionActionHandler.ForEachCaret() {
private var col: Int = 0
Expand All @@ -50,7 +51,7 @@ open class MotionDownAction : MotionDownBase() {
override val motionType: MotionType = MotionType.LINE_WISE

override fun getOffset(editor: Editor, caret: Caret, context: DataContext, count: Int, rawCount: Int, argument: Argument?): Int {
return VimPlugin.getMotion().moveCaretVertical(editor, caret, count)
return VimPlugin.getMotion().moveCaretVertical(editor, caret, count, editor.inNormalMode)
}
}

Expand All @@ -75,6 +76,6 @@ class MotionDownNotLineWiseAction : MotionDownBase() {
override val motionType: MotionType = MotionType.EXCLUSIVE

override fun getOffset(editor: Editor, caret: Caret, context: DataContext, count: Int, rawCount: Int, argument: Argument?): Int {
return VimPlugin.getMotion().moveCaretVertical(editor, caret, count)
return VimPlugin.getMotion().moveCaretVertical(editor, caret, count, editor.inNormalMode)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.command.Command
import com.maddyhome.idea.vim.group.MotionGroup
import com.maddyhome.idea.vim.handler.ShiftedArrowKeyHandler
import com.maddyhome.idea.vim.helper.EditorHelper
import com.maddyhome.idea.vim.helper.vimForEachCaret
import com.maddyhome.idea.vim.helper.*

/**
* @author Alex Plate
Expand All @@ -37,7 +36,7 @@ class MotionShiftDownAction : ShiftedArrowKeyHandler() {

override fun motionWithKeyModel(editor: Editor, context: DataContext, cmd: Command) {
editor.vimForEachCaret { caret ->
val vertical = VimPlugin.getMotion().moveCaretVertical(editor, caret, cmd.count)
val vertical = VimPlugin.getMotion().moveCaretVertical(editor, caret, cmd.count, editor.inNormalMode)
val col = EditorHelper.prepareLastColumn(editor, caret)
MotionGroup.moveCaret(editor, caret, vertical)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.command.Command
import com.maddyhome.idea.vim.group.MotionGroup
import com.maddyhome.idea.vim.handler.ShiftedArrowKeyHandler
import com.maddyhome.idea.vim.helper.EditorHelper
import com.maddyhome.idea.vim.helper.vimForEachCaret
import com.maddyhome.idea.vim.helper.*

/**
* @author Alex Plate
Expand All @@ -37,7 +36,7 @@ class MotionShiftUpAction : ShiftedArrowKeyHandler() {

override fun motionWithKeyModel(editor: Editor, context: DataContext, cmd: Command) {
editor.vimForEachCaret { caret ->
val vertical = VimPlugin.getMotion().moveCaretVertical(editor, caret, -cmd.count)
val vertical = VimPlugin.getMotion().moveCaretVertical(editor, caret, -cmd.count, editor.inNormalMode)
val col = EditorHelper.prepareLastColumn(editor, caret)
MotionGroup.moveCaret(editor, caret, vertical)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import com.maddyhome.idea.vim.command.Command
import com.maddyhome.idea.vim.command.MotionType
import com.maddyhome.idea.vim.handler.MotionActionHandler
import com.maddyhome.idea.vim.helper.EditorHelper
import com.maddyhome.idea.vim.helper.inNormalMode

sealed class MotionUpBase : MotionActionHandler.ForEachCaret() {
private var col: Int = 0
Expand All @@ -49,7 +50,7 @@ open class MotionUpAction : MotionUpBase() {
override val motionType: MotionType = MotionType.LINE_WISE

override fun getOffset(editor: Editor, caret: Caret, context: DataContext, count: Int, rawCount: Int, argument: Argument?): Int {
return VimPlugin.getMotion().moveCaretVertical(editor, caret, -count)
return VimPlugin.getMotion().moveCaretVertical(editor, caret, -count, editor.inNormalMode)
}
}

Expand All @@ -73,6 +74,6 @@ class MotionUpNotLineWiseAction : MotionUpBase() {
override val motionType: MotionType = MotionType.EXCLUSIVE

override fun getOffset(editor: Editor, caret: Caret, context: DataContext, count: Int, rawCount: Int, argument: Argument?): Int {
return VimPlugin.getMotion().moveCaretVertical(editor, caret, -count)
return VimPlugin.getMotion().moveCaretVertical(editor, caret, -count, editor.inNormalMode)
}
}
12 changes: 7 additions & 5 deletions src/com/maddyhome/idea/vim/command/CommandState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,8 @@ import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.diagnostic.debug
import com.intellij.openapi.editor.Editor
import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.command.CommandState
import com.maddyhome.idea.vim.helper.DigraphResult
import com.maddyhome.idea.vim.helper.DigraphSequence
import com.maddyhome.idea.vim.helper.noneOfEnum
import com.maddyhome.idea.vim.helper.vimCommandState
import com.maddyhome.idea.vim.action.motion.updown.*
import com.maddyhome.idea.vim.helper.*
import com.maddyhome.idea.vim.key.CommandPartNode
import com.maddyhome.idea.vim.option.OptionsManager.showmode
import org.jetbrains.annotations.ApiStatus
Expand Down Expand Up @@ -61,6 +58,8 @@ class CommandState private constructor() {
var executingCommand: Command? = null
private set

var previousCommand: Command? = null

// Keep the compatibility with the IdeaVim-EasyMotion plugin before the stable release
@get:Deprecated("")
@get:ApiStatus.ScheduledForRemoval(inVersion = "0.58")
Expand All @@ -75,6 +74,9 @@ class CommandState private constructor() {
}

fun setExecutingCommand(cmd: Command) {
if (previousCommand != null && !cmd.isUpDownMotion){
previousCommand = executingCommand // track the previous motion command for some edge cases around '$'
}
executingCommand = cmd
}

Expand Down
27 changes: 19 additions & 8 deletions src/com/maddyhome/idea/vim/group/ChangeGroup.java
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ public void insertNewLineAbove(final @NotNull Editor editor, @NotNull DataContex
firstLiners.add(caret);
}
else {
MotionGroup.moveCaret(editor, caret, VimPlugin.getMotion().moveCaretVertical(editor, caret, -1));
MotionGroup.moveCaret(editor, caret, VimPlugin.getMotion().moveCaretVertical(editor, caret, -1, false));
MotionGroup.moveCaret(editor, caret, VimPlugin.getMotion().moveCaretToLineEnd(editor, caret));
}
}
Expand All @@ -183,7 +183,7 @@ public void insertNewLineAbove(final @NotNull Editor editor, @NotNull DataContex

for (Caret caret : editor.getCaretModel().getAllCarets()) {
if (firstLiners.contains(caret)) {
MotionGroup.moveCaret(editor, caret, VimPlugin.getMotion().moveCaretVertical(editor, caret, -1));
MotionGroup.moveCaret(editor, caret, VimPlugin.getMotion().moveCaretVertical(editor, caret, -1, false));
}
}
}
Expand All @@ -204,15 +204,15 @@ private void insertNewLineAbove(@NotNull Editor editor, @NotNull Caret caret, in
firstLiner = true;
}
else {
MotionGroup.moveCaret(editor, caret, VimPlugin.getMotion().moveCaretVertical(editor, caret, -1));
MotionGroup.moveCaret(editor, caret, VimPlugin.getMotion().moveCaretVertical(editor, caret, -1, false));
MotionGroup.moveCaret(editor, caret, VimPlugin.getMotion().moveCaretToLineEnd(editor, caret));
}

UserDataManager.setVimChangeActionSwitchMode(editor, CommandState.Mode.INSERT);
insertText(editor, caret, "\n" + IndentConfig.create(editor).createIndentBySize(col));

if (firstLiner) {
MotionGroup.moveCaret(editor, caret, VimPlugin.getMotion().moveCaretVertical(editor, caret, -1));
MotionGroup.moveCaret(editor, caret, VimPlugin.getMotion().moveCaretVertical(editor, caret, -1, false));
}
}

Expand Down Expand Up @@ -766,15 +766,26 @@ public void beforeProcessKey(final @NotNull Editor editor,
* @return true if able to delete the text, false if not
*/
public boolean deleteEndOfLine(@NotNull Editor editor, @NotNull Caret caret, int count) {
int initialOffset = caret.getOffset();
int offset = VimPlugin.getMotion().moveCaretToLineEndOffset(editor, caret, count - 1, true);

int startOffset = initialOffset;
if (offset == initialOffset) startOffset--; // handle delete from virtual space

if (offset != -1) {
final TextRange rangeToDelete = new TextRange(caret.getOffset(), offset);
final TextRange rangeToDelete = new TextRange(startOffset, offset);
editor.getCaretModel().getAllCarets().stream().filter(c -> c != caret && rangeToDelete.contains(c.getOffset()))
.forEach(c -> editor.getCaretModel().removeCaret(c));
boolean res = deleteText(editor, rangeToDelete, SelectionType.CHARACTER_WISE);
int pos = VimPlugin.getMotion().moveCaretHorizontal(editor, caret, -1, false);
if (pos != -1) {
MotionGroup.moveCaret(editor, caret, pos);

if (CommandStateHelper.getUsesVirtualSpace()) {
MotionGroup.moveCaret(editor, caret, startOffset);
}
else {
int pos = VimPlugin.getMotion().moveCaretHorizontal(editor, caret, -1, false);
if (pos != -1) {
MotionGroup.moveCaret(editor, caret, pos);
}
}

return res;
Expand Down
24 changes: 21 additions & 3 deletions src/com/maddyhome/idea/vim/group/MotionGroup.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@
import com.intellij.openapi.vfs.VirtualFileSystem;
import com.maddyhome.idea.vim.KeyHandler;
import com.maddyhome.idea.vim.VimPlugin;
import com.maddyhome.idea.vim.action.motion.leftright.MotionLastColumnAction;
import com.maddyhome.idea.vim.command.*;
import com.maddyhome.idea.vim.common.Jump;
import com.maddyhome.idea.vim.common.Mark;
import com.maddyhome.idea.vim.common.TextRange;
import com.maddyhome.idea.vim.ex.ExOutputModel;
import com.maddyhome.idea.vim.group.visual.VimSelection;
import com.maddyhome.idea.vim.group.visual.VisualGroupKt;
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase;
import com.maddyhome.idea.vim.handler.MotionActionHandler;
import com.maddyhome.idea.vim.handler.TextObjectActionHandler;
import com.maddyhome.idea.vim.helper.*;
Expand Down Expand Up @@ -1150,7 +1152,7 @@ private void scrollLineToScreenLocation(@NotNull Editor editor,
else {
offset = moveCaretVertical(editor, editor.getCaretModel().getPrimaryCaret(),
EditorHelper.visualLineToLogicalLine(editor, visualLine) -
editor.getCaretModel().getLogicalPosition().line);
editor.getCaretModel().getLogicalPosition().line, false);
}

moveCaret(editor, editor.getCaretModel().getPrimaryCaret(), offset);
Expand Down Expand Up @@ -1184,7 +1186,7 @@ public int moveCaretGotoNextTab(@NotNull Editor editor, @NotNull DataContext con
return editor.getCaretModel().getOffset();
}

public int moveCaretVertical(@NotNull Editor editor, @NotNull Caret caret, int count) {
public int moveCaretVertical(@NotNull Editor editor, @NotNull Caret caret, int count, boolean useEndOfLineTracking) {
VisualPosition pos = caret.getVisualPosition();
final LogicalPosition logicalPosition = caret.getLogicalPosition();
if ((pos.line == 0 && count < 0) || (pos.line >= EditorHelper.getVisualLineCount(editor) - 1 && count > 0)) {
Expand Down Expand Up @@ -1217,12 +1219,28 @@ public int moveCaretVertical(@NotNull Editor editor, @NotNull Caret caret, int c
col = EditorHelper
.normalizeVisualColumn(editor, line, col, CommandStateHelper.isEndAllowed(CommandStateHelper.getMode(editor)));
col += newInlineElements;
VisualPosition newPos = new VisualPosition(line, col);

if (useEndOfLineTracking && InLastColumnMode(editor) && !caret.hasSelection()) {
// we're in 'last column' mode (after pressing '$'); Run to last column
int newLastColumn = EditorHelper.lastColumnForLine(editor, line, CommandStateHelper.isEndAllowed(mode));
col = newLastColumn;
}

VisualPosition newPos = new VisualPosition(line, col);
return EditorHelper.visualPositionToOffset(editor, newPos);
}
}

private boolean InLastColumnMode(@NotNull Editor editor) {
Command state = CommandStateHelper.getPreviousCommand(editor);
if (state == null) return false;

EditorActionHandlerBase action = state.getAction();
if (action == null) return false;

return action instanceof MotionLastColumnAction;
}

public int moveCaretToLinePercent(@NotNull Editor editor, int count) {
if (count > 100) count = 100;

Expand Down
10 changes: 6 additions & 4 deletions src/com/maddyhome/idea/vim/handler/EditorActionHandlerBase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,11 @@ import com.intellij.openapi.editor.Caret
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.actionSystem.CaretSpecificDataContext
import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.action.motion.updown.*
import com.maddyhome.idea.vim.command.Argument
import com.maddyhome.idea.vim.command.Command
import com.maddyhome.idea.vim.command.CommandFlags
import com.maddyhome.idea.vim.helper.StringHelper
import com.maddyhome.idea.vim.helper.commandState
import com.maddyhome.idea.vim.helper.getTopLevelEditor
import com.maddyhome.idea.vim.helper.noneOfEnum
import com.maddyhome.idea.vim.helper.*
import java.util.*
import javax.swing.KeyStroke

Expand Down Expand Up @@ -91,6 +89,10 @@ abstract class EditorActionHandlerBase(private val myRunForEachCaret: Boolean) {
}

if (!baseExecute(editor, caret, CaretSpecificDataContext(context, caret), cmd)) VimPlugin.indicateError()

if (!cmd.isUpDownMotion){
editor.previousCommand = cmd // track the previous motion command for some edge cases
}
}

open fun process(cmd: Command) {
Expand Down
12 changes: 4 additions & 8 deletions src/com/maddyhome/idea/vim/handler/MotionActionHandler.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,13 @@ import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.event.CaretEvent
import com.intellij.openapi.editor.event.CaretListener
import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.action.motion.updown.*
import com.maddyhome.idea.vim.command.Argument
import com.maddyhome.idea.vim.command.Command
import com.maddyhome.idea.vim.command.CommandFlags
import com.maddyhome.idea.vim.command.MotionType
import com.maddyhome.idea.vim.group.MotionGroup
import com.maddyhome.idea.vim.helper.EditorHelper
import com.maddyhome.idea.vim.helper.inBlockSubMode
import com.maddyhome.idea.vim.helper.inVisualMode
import com.maddyhome.idea.vim.helper.isEndAllowed
import com.maddyhome.idea.vim.helper.mode
import com.maddyhome.idea.vim.helper.vimSelectionStart
import com.maddyhome.idea.vim.helper.*

/**
* @author Alex Plate
Expand Down Expand Up @@ -140,7 +136,7 @@ sealed class MotionActionHandler : EditorActionHandlerBase(false) {
if (CommandFlags.FLAG_SAVE_JUMP in cmd.flags) {
VimPlugin.getMark().saveJumpLocation(editor)
}
if (!editor.mode.isEndAllowed) {
if (!editor.commandState.isEndAllowed) {
offset = EditorHelper.normalizeOffset(editor, offset, false)
}
preMove(editor, context, cmd)
Expand Down Expand Up @@ -179,7 +175,7 @@ sealed class MotionActionHandler : EditorActionHandlerBase(false) {
if (CommandFlags.FLAG_SAVE_JUMP in cmd.flags) {
VimPlugin.getMark().saveJumpLocation(editor)
}
if (!editor.mode.isEndAllowed) {
if (!editor.commandState.isEndAllowed) {
offset = EditorHelper.normalizeOffset(editor, offset, false)
}
preMove(editor, caret, context, cmd)
Expand Down
Loading

0 comments on commit 6be6e7f

Please sign in to comment.