1
0
mirror of https://github.com/chylex/IntelliJ-IdeaVim.git synced 2025-05-12 00:34:06 +02:00

Ensure correct caret position when exiting Select

Fixes VIM-3042
This commit is contained in:
Matt Ellis 2025-01-02 14:00:24 +00:00 committed by Alex Pláte
parent 1d5fc01d65
commit 296288f428
3 changed files with 87 additions and 18 deletions
src
main/java/com/maddyhome/idea/vim/helper
test/java/org/jetbrains/plugins/ideavim/action/motion/select

View File

@ -33,7 +33,7 @@ internal fun Editor.exitSelectMode(adjustCaretPosition: Boolean) {
this.caretModel.allCarets.forEach {
it.removeSelection()
it.vim.vimSelectionStartClear()
if (adjustCaretPosition) {
if (adjustCaretPosition && !vimEditor.isEndAllowed) {
val lineEnd = IjVimEditor(this).getLineEndForOffset(it.offset)
val lineStart = IjVimEditor(this).getLineStartForOffset(it.offset)
if (it.offset == lineEnd && it.offset != lineStart) {
@ -54,7 +54,7 @@ internal fun VimEditor.exitSelectMode(adjustCaretPosition: Boolean) {
val caret = (vimCaret as IjVimCaret).caret
caret.removeSelection()
caret.vim.vimSelectionStartClear()
if (adjustCaretPosition) {
if (adjustCaretPosition && !isEndAllowed) {
val lineEnd = IjVimEditor((this as IjVimEditor).editor).getLineEndForOffset(caret.offset)
val lineStart = IjVimEditor(editor).getLineStartForOffset(caret.offset)
if (caret.offset == lineEnd && caret.offset != lineStart) {

View File

@ -6,6 +6,8 @@
* https://opensource.org/licenses/MIT.
*/
@file:Suppress("SpellCheckingInspection")
package org.jetbrains.plugins.ideavim.action.motion.select
import com.maddyhome.idea.vim.state.mode.Mode
@ -164,4 +166,59 @@ class SelectDeleteActionTest : VimTestCase() {
enterCommand("set selectmode=key keymodel=startsel")
}
}
// VIM-3042
// We don't need to test Del and BS separately for this
@Test
fun `test deleting last word of line places caret at correct offset when returning to Normal mode`() {
doTest(
listOf("ve", "<C-G>", "<Del>"),
"""
|Lorem Ipsum
|
|I found it in a legendary${c} land
|consectetur adipiscing elit
|Sed in orci mauris.
|Cras id tellus in ex imperdiet egestas.
""".trimMargin(),
"""
|Lorem Ipsum
|
|I found it in a legendar${c}y
|consectetur adipiscing elit
|Sed in orci mauris.
|Cras id tellus in ex imperdiet egestas.
""".trimMargin(),
Mode.NORMAL()
)
}
// VIM-3042
@Test
fun `test deleting last word of line places caret at correct offset when returning to Insert mode`() {
// Remember that IdeaVim treats Select mode as exclusive, so we need 5x<S-Right> to select " land" and the caret
// will finish up _after_ the word, on the new line char
doTest(
listOf("i", "<S-Right>".repeat(5), "<Del>"),
"""
|Lorem Ipsum
|
|I found it in a legendary${c} land
|consectetur adipiscing elit
|Sed in orci mauris.
|Cras id tellus in ex imperdiet egestas.
""".trimMargin(),
"""
|Lorem Ipsum
|
|I found it in a legendary${c}
|consectetur adipiscing elit
|Sed in orci mauris.
|Cras id tellus in ex imperdiet egestas.
""".trimMargin(),
Mode.INSERT
) {
enterCommand("set selectmode=key keymodel=startsel")
}
}
}

View File

@ -39,7 +39,6 @@ class SelectEscapeActionTest : VimTestCase() {
""".trimIndent(),
Mode.NORMAL(),
)
assertMode(Mode.NORMAL())
}
@TestWithoutNeovim(SkipNeovimReason.SELECT_MODE)
@ -65,12 +64,11 @@ class SelectEscapeActionTest : VimTestCase() {
""".trimIndent(),
Mode.NORMAL(),
)
assertMode(Mode.NORMAL())
}
@TestWithoutNeovim(SkipNeovimReason.SELECT_MODE)
@Test
fun `test exit char mode on line end`() {
fun `test exit char mode on line end puts caret at correct offset when returning to Normal mode`() {
this.doTest(
listOf("gh", "<esc>"),
"""
@ -91,7 +89,33 @@ class SelectEscapeActionTest : VimTestCase() {
""".trimIndent(),
Mode.NORMAL(),
)
assertMode(Mode.NORMAL())
}
@TestWithoutNeovim(SkipNeovimReason.SELECT_MODE)
@Test
fun `test exit char mode on line end puts caret at correct offset when returning to Insert mode`() {
this.doTest(
listOf("i", "<S-Right>", "<esc>"),
"""
A Discovery
I found it in a legendary lan${c}d
all rocks and lavender and tufted grass,
where it was settled on some sodden sand
hard by the torrent of a mountain pass.
""".trimIndent(),
"""
A Discovery
I found it in a legendary land${c}
all rocks and lavender and tufted grass,
where it was settled on some sodden sand
hard by the torrent of a mountain pass.
""".trimIndent(),
Mode.INSERT,
) {
enterCommand("set selectmode=key keymodel=startsel")
}
}
@TestWithoutNeovim(SkipNeovimReason.SELECT_MODE)
@ -117,7 +141,6 @@ class SelectEscapeActionTest : VimTestCase() {
""".trimIndent(),
Mode.NORMAL(),
)
assertMode(Mode.NORMAL())
}
@TestWithoutNeovim(SkipNeovimReason.SELECT_MODE)
@ -143,7 +166,6 @@ class SelectEscapeActionTest : VimTestCase() {
""".trimIndent(),
Mode.NORMAL(),
)
assertMode(Mode.NORMAL())
}
@TestWithoutNeovim(SkipNeovimReason.SELECT_MODE)
@ -169,7 +191,6 @@ class SelectEscapeActionTest : VimTestCase() {
""".trimIndent(),
Mode.NORMAL(),
)
assertMode(Mode.NORMAL())
}
@TestWithoutNeovim(SkipNeovimReason.SELECT_MODE)
@ -195,7 +216,6 @@ class SelectEscapeActionTest : VimTestCase() {
""".trimIndent(),
Mode.NORMAL(),
)
assertMode(Mode.NORMAL())
}
@TestWithoutNeovim(SkipNeovimReason.SELECT_MODE)
@ -221,7 +241,6 @@ class SelectEscapeActionTest : VimTestCase() {
""".trimIndent(),
Mode.NORMAL(),
)
assertMode(Mode.NORMAL())
}
@TestWithoutNeovim(SkipNeovimReason.SELECT_MODE)
@ -247,7 +266,6 @@ class SelectEscapeActionTest : VimTestCase() {
""".trimIndent(),
Mode.NORMAL(),
)
assertMode(Mode.NORMAL())
}
@TestWithoutNeovim(SkipNeovimReason.SELECT_MODE)
@ -273,7 +291,6 @@ class SelectEscapeActionTest : VimTestCase() {
""".trimIndent(),
Mode.NORMAL(),
)
assertMode(Mode.NORMAL())
}
@TestWithoutNeovim(SkipNeovimReason.SELECT_MODE)
@ -299,7 +316,6 @@ class SelectEscapeActionTest : VimTestCase() {
""".trimIndent(),
Mode.NORMAL(),
)
assertMode(Mode.NORMAL())
}
@TestWithoutNeovim(SkipNeovimReason.SELECT_MODE)
@ -328,7 +344,6 @@ class SelectEscapeActionTest : VimTestCase() {
kotlin.test.assertFalse(fixture.editor.caretModel.allCarets.any(Caret::hasSelection))
kotlin.test.assertEquals(1, fixture.editor.caretModel.caretCount)
assertCaretsVisualAttributes()
assertMode(Mode.NORMAL())
}
@TestWithoutNeovim(SkipNeovimReason.SELECT_MODE)
@ -357,7 +372,6 @@ class SelectEscapeActionTest : VimTestCase() {
kotlin.test.assertFalse(fixture.editor.caretModel.allCarets.any(Caret::hasSelection))
kotlin.test.assertEquals(1, fixture.editor.caretModel.caretCount)
assertCaretsVisualAttributes()
assertMode(Mode.NORMAL())
}
@TestWithoutNeovim(SkipNeovimReason.SELECT_MODE)
@ -386,7 +400,6 @@ class SelectEscapeActionTest : VimTestCase() {
kotlin.test.assertFalse(fixture.editor.caretModel.allCarets.any(Caret::hasSelection))
kotlin.test.assertEquals(1, fixture.editor.caretModel.caretCount)
assertCaretsVisualAttributes()
assertMode(Mode.NORMAL())
}
@TestWithoutNeovim(SkipNeovimReason.SELECT_MODE)
@ -415,6 +428,5 @@ class SelectEscapeActionTest : VimTestCase() {
kotlin.test.assertFalse(fixture.editor.caretModel.allCarets.any(Caret::hasSelection))
kotlin.test.assertEquals(1, fixture.editor.caretModel.caretCount)
assertCaretsVisualAttributes()
assertMode(Mode.NORMAL())
}
}