diff --git a/src/main/java/com/maddyhome/idea/vim/extension/miniai/MiniAI.kt b/src/main/java/com/maddyhome/idea/vim/extension/miniai/MiniAI.kt index 2bda28f6c..bf7f84617 100644 --- a/src/main/java/com/maddyhome/idea/vim/extension/miniai/MiniAI.kt +++ b/src/main/java/com/maddyhome/idea/vim/extension/miniai/MiniAI.kt @@ -220,11 +220,16 @@ private fun findClosestQuoteRange( } private fun TextRange.distanceTo(caretOffset: Int): Int { - return if (caretOffset < startOffset) { - startOffset - caretOffset - } else if (caretOffset > endOffset) { - caretOffset - endOffset - } else { - 0 // Caret is inside the range + val rangeLength = endOffset - startOffset + + // If caret is inside the range + if (caretOffset in startOffset..endOffset) { + // Return the length of the range - smaller ranges get priority + return rangeLength } -} \ No newline at end of file + + // If caret is outside, make the distance much larger + val startDistance = kotlin.math.abs(caretOffset - startOffset) + val endDistance = kotlin.math.abs(caretOffset - endOffset) + return (startDistance + endDistance) * 1000 + rangeLength +} diff --git a/tests/java-tests/src/test/kotlin/org/jetbrains/plugins/ideavim/extension/miniai/MiniAIExtensionTest.kt b/tests/java-tests/src/test/kotlin/org/jetbrains/plugins/ideavim/extension/miniai/MiniAIExtensionTest.kt index 03c00adbf..b6105d632 100644 --- a/tests/java-tests/src/test/kotlin/org/jetbrains/plugins/ideavim/extension/miniai/MiniAIExtensionTest.kt +++ b/tests/java-tests/src/test/kotlin/org/jetbrains/plugins/ideavim/extension/miniai/MiniAIExtensionTest.kt @@ -23,6 +23,200 @@ class MiniAIExtensionTest : VimJavaTestCase() { enableExtensions("mini-ai") } + @Test + fun testChangeInsideNestedQuotes() { + doTest( + "ciq", + "this 'simple<caret> \"test\"'", + "this '<caret>'", + Mode.INSERT, + JavaFileType.INSTANCE, + ) + assertSelection(null) + } + + @Test + fun testDeleteInsideNestedQuotes() { + doTest( + "diq", + "this 'simple<caret> \"test\"'", + "this '<caret>'", + Mode.NORMAL(), + JavaFileType.INSTANCE, + ) + assertSelection(null) + } + + @Test + fun testChangeInsideNestedQuotesDoubleInner() { + doTest( + "ciq", + "this \"simple<caret> 'test'\"", + "this \"<caret>\"", + Mode.INSERT, + JavaFileType.INSTANCE, + ) + assertSelection(null) + } + + @Test + fun testDeleteInsideNestedQuotesDoubleInner() { + doTest( + "diq", + "this \"simple<caret> 'test'\"", + "this \"<caret>\"", + Mode.NORMAL(), + JavaFileType.INSTANCE, + ) + assertSelection(null) + } + + @Test + fun testChangeInsideNestedQuotesBackQuote() { + doTest( + "ciq", + "this `simple<caret> \"test\"`", + "this `<caret>`", + Mode.INSERT, + JavaFileType.INSTANCE, + ) + assertSelection(null) + } + + @Test + fun testDeleteInsideNestedQuotesBackQuote() { + doTest( + "diq", + "this `simple<caret> \"test\"`", + "this `<caret>`", + Mode.NORMAL(), + JavaFileType.INSTANCE, + ) + assertSelection(null) + } + + @Test + fun testChangeAroundNestedSingleQuotes() { + doTest( + "caq", + "this 'simple<caret> \"test\"'", + "this <caret>", + Mode.INSERT, + JavaFileType.INSTANCE, + ) + assertSelection(null) + } + + @Test + fun testDeleteAroundNestedSingleQuotes() { + doTest( + "daq", + "this 'simple<caret> \"test\"' test", + "this <caret> test", + Mode.NORMAL(), + JavaFileType.INSTANCE, + ) + assertSelection(null) + } + + @Test + fun testChangeAroundNestedDoubleQuotes() { + doTest( + "caq", + "this \"simple<caret> 'test'\"", + "this <caret>", + Mode.INSERT, + JavaFileType.INSTANCE, + ) + assertSelection(null) + } + + @Test + fun testDeleteAroundNestedDoubleQuotes() { + doTest( + "daq", + "this \"simple<caret> 'test'\" test", + "this <caret> test", + Mode.NORMAL(), + JavaFileType.INSTANCE, + ) + assertSelection(null) + } + + @Test + fun testChangeAroundNestedBackQuotes() { + doTest( + "caq", + "this `simple<caret> \"test\"`", + "this <caret>", + Mode.INSERT, + JavaFileType.INSTANCE, + ) + assertSelection(null) + } + + @Test + fun testDeleteAroundNestedBackQuotes() { + doTest( + "daq", + "this `simple<caret> \"test\"` test", + "this <caret> test", + Mode.NORMAL(), + JavaFileType.INSTANCE, + ) + assertSelection(null) + } + + // Additional edge cases with cursor on different positions + @Test + fun testChangeAroundNestedQuotesOnInnerQuote() { + doTest( + "caq", + "this 'simple \"<caret>test\"'", + "this 'simple <caret>'", + Mode.INSERT, + JavaFileType.INSTANCE, + ) + assertSelection(null) + } + + @Test + fun testDeleteAroundNestedQuotesOnInnerQuote() { + doTest( + "daq", + "this 'simple \"<caret>test\"'", + "this 'simple '", + Mode.NORMAL(), + JavaFileType.INSTANCE, + ) + assertSelection(null) + } + + // Test with multiple levels of nesting + @Test + fun testChangeAroundTripleNestedQuotes() { + doTest( + "caq", + "this 'simple \"nested `<caret>test`\"'", + "this 'simple \"nested <caret>\"'", + Mode.INSERT, + JavaFileType.INSTANCE, + ) + assertSelection(null) + } + + @Test + fun testDeleteAroundTripleNestedQuotes() { + doTest( + "daq", + "this 'simple \"nested `<caret>test`\"'", + "this 'simple \"nested <caret>\"'", + Mode.NORMAL(), + JavaFileType.INSTANCE, + ) + assertSelection(null) + } + @Test fun testChangeInsideSingleQuote() { doTest(