diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimVisualMotionGroup.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimVisualMotionGroup.kt index 36d79169a..085d33712 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimVisualMotionGroup.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimVisualMotionGroup.kt @@ -19,8 +19,21 @@ interface VimVisualMotionGroup { * Enters Visual mode, ensuring that the caret's selection start offset is correctly set * * Use this to programmatically enter Visual mode. Note that it does not modify the editor's selection. + * + * This overload needs to remain for compatibility with external IdeaVim extensions */ - fun enterVisualMode(editor: VimEditor, selectionType: SelectionType): Boolean + fun enterVisualMode(editor: VimEditor, selectionType: SelectionType): Boolean { + return enterVisualMode(editor, selectionType, Mode.NORMAL()) + } + + /** + * Enters Visual mode, ensuring that the caret's selection start offset is correctly set + * + * Use this to programmatically enter Visual mode. Note that it does not modify the editor's selection. You can + * specify the mode to return to when Visual command exits. Typically, this is [Mode.NORMAL], but can be [Mode.INSERT] + * or [Mode.REPLACE] for "Insert Visual" or [Mode.SELECT] when processing a single Visual command in Select mode. + */ + fun enterVisualMode(editor: VimEditor, selectionType: SelectionType, returnTo: Mode): Boolean /** * Enter Select mode with the given selection type diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimVisualMotionGroupBase.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimVisualMotionGroupBase.kt index 572e92b2a..1056ba04f 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimVisualMotionGroupBase.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimVisualMotionGroupBase.kt @@ -31,8 +31,8 @@ abstract class VimVisualMotionGroupBase : VimVisualMotionGroup { * * Use this to programmatically enter Visual mode. Note that it does not modify the editor's selection. */ - override fun enterVisualMode(editor: VimEditor, selectionType: SelectionType): Boolean { - editor.mode = Mode.VISUAL(selectionType) + override fun enterVisualMode(editor: VimEditor, selectionType: SelectionType, returnTo: Mode): Boolean { + editor.mode = Mode.VISUAL(selectionType, returnTo) // vimLeadSelectionOffset requires read action injector.application.runReadAction { diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/handler/SpecialKeyHandlers.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/handler/SpecialKeyHandlers.kt index 79a83f9b1..6a4f30170 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/handler/SpecialKeyHandlers.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/handler/SpecialKeyHandlers.kt @@ -61,7 +61,7 @@ abstract class ShiftedSpecialKeyHandler : VimActionHandler.ConditionalMulticaret if (injector.globalOptions().selectmode.contains(OptionConstants.selectmode_key)) { injector.visualMotionGroup.enterSelectMode(editor, SelectionType.CHARACTER_WISE) } else { - injector.visualMotionGroup.toggleVisual(editor, 1, 0, SelectionType.CHARACTER_WISE) + injector.visualMotionGroup.enterVisualMode(editor, SelectionType.CHARACTER_WISE) } } return true @@ -97,10 +97,10 @@ abstract class ShiftedArrowKeyHandler(private val runBothCommandsAsMulticaret: B injector.visualMotionGroup.enterSelectMode(editor, SelectionType.CHARACTER_WISE) } else { if (editor.isInsertionAllowed) { - // Enter Insert/Replace Visual mode - injector.visualMotionGroup.toggleVisual(editor, 1, 0, SelectionType.CHARACTER_WISE, editor.mode) + // Enter Insert/Replace Visual mode, passing in the current Insert/Replace mode as pending + injector.visualMotionGroup.enterVisualMode(editor, SelectionType.CHARACTER_WISE, editor.mode) } else { - injector.visualMotionGroup.toggleVisual(editor, 1, 0, SelectionType.CHARACTER_WISE) + injector.visualMotionGroup.enterVisualMode(editor, SelectionType.CHARACTER_WISE) } } }