1
0
mirror of https://github.com/chylex/IntelliJ-IdeaVim.git synced 2025-04-21 16:15:46 +02:00

feat: add mini-ai extension

This commit is contained in:
Osvaldo Cordova Aburto 2025-01-17 14:30:43 -06:00 committed by Alex Pláte
parent ee548b52db
commit 31a6d8174a
8 changed files with 951 additions and 45 deletions
doc
src
main
java/com/maddyhome/idea/vim
extension/miniai
statistic
resources/META-INF/includes
test/java/org/jetbrains/plugins/ideavim/ex/implementation/commands
tests/java-tests/src/test/kotlin/org/jetbrains/plugins/ideavim/extension/miniai

View File

@ -423,6 +423,24 @@ https://plugins.jetbrains.com/plugin/19417-ideavim-quickscope
</details>
<details>
<summary><h2>Mini.ai: Extend and create a/i textobjects (IMPORTANT: The plugin is not related with artificial intelligence)</h2></summary>
### Features:
Provides additional text object motions for handling quotes and brackets. The following motions are included:
- aq: Around any quotes.
- iq: Inside any quotes.
- ab: Around any parentheses, curly braces, and square brackets.
- ib: Inside any parentheses, curly braces, and square brackets.
Original plugin: [mini.ai](https://github.com/echasnovski/mini.ai).
### Setup:
- Add the following command to `~/.ideavimrc`: `set mini-ai`
</details>
<details>
<summary><h2>Which-Key</h2></summary>
@ -484,4 +502,3 @@ or restart the IDE.
https://plugins.jetbrains.com/plugin/25899-vim-switch
</details>

View File

@ -0,0 +1,230 @@
/*
* Copyright 2003-2023 The IdeaVim authors
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE.txt file or at
* https://opensource.org/licenses/MIT.
*/
package com.maddyhome.idea.vim.extension.miniai
import com.maddyhome.idea.vim.KeyHandler
import com.maddyhome.idea.vim.api.ExecutionContext
import com.maddyhome.idea.vim.api.ImmutableVimCaret
import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.command.CommandFlags
import com.maddyhome.idea.vim.command.MappingMode
import com.maddyhome.idea.vim.command.OperatorArguments
import com.maddyhome.idea.vim.command.TextObjectVisualType
import com.maddyhome.idea.vim.common.TextRange
import com.maddyhome.idea.vim.extension.ExtensionHandler
import com.maddyhome.idea.vim.extension.VimExtension
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putExtensionHandlerMapping
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMapping
import com.maddyhome.idea.vim.group.findBlockRange
import com.maddyhome.idea.vim.handler.TextObjectActionHandler
import com.maddyhome.idea.vim.helper.enumSetOf
import com.maddyhome.idea.vim.state.KeyHandlerState
import java.util.*
/**
* Extend and create a/i textobjects
*
* <p>
* mini ai provides the next motions:
* <ul>
* <li>aq around any quotes.</li>
* <li>iq inside any quotes.</li>
* <li>ab around any parentheses, curly braces and square brackets.</li>
* <li>ib inside any parentheses, curly braces and square brackets.</li>
* </ul>
*
* @author Osvaldo Cordova Aburto (@oca159)
*/
internal class MiniAI : VimExtension {
companion object {
// Constants for key mappings
private const val PLUG_AQ = "<Plug>mini-ai-aq"
private const val PLUG_IQ = "<Plug>mini-ai-iq"
private const val PLUG_AB = "<Plug>mini-ai-ab"
private const val PLUG_IB = "<Plug>mini-ai-ib"
// Constants for key sequences
private const val KEY_AQ = "aq"
private const val KEY_IQ = "iq"
private const val KEY_AB = "ab"
private const val KEY_IB = "ib"
}
override fun getName() = "mini-ai"
override fun init() {
registerMappings()
}
private fun registerMappings() {
val mappings = listOf(
PLUG_AQ to AroundAnyQuotesHandler(),
PLUG_IQ to InsideAnyQuotesHandler(),
PLUG_AB to AroundAnyBracketsHandler(),
PLUG_IB to InsideAnyBracketsHandler()
)
mappings.forEach { (key, handler) ->
putExtensionHandlerMapping(MappingMode.XO, injector.parser.parseKeys(key), owner, handler, false)
}
val keyMappings = listOf(
KEY_AQ to PLUG_AQ,
KEY_IQ to PLUG_IQ,
KEY_AB to PLUG_AB,
KEY_IB to PLUG_IB
)
keyMappings.forEach { (key, plug) ->
putKeyMapping(MappingMode.XO, injector.parser.parseKeys(key), owner, injector.parser.parseKeys(plug), true)
}
}
private class InsideAnyQuotesHandler : ExtensionHandler {
override val isRepeatable = true
override fun execute(editor: VimEditor, context: ExecutionContext, operatorArguments: OperatorArguments) {
addAction(MotionInnerAnyQuoteProximityAction())
}
}
private class AroundAnyQuotesHandler : ExtensionHandler {
override val isRepeatable = true
override fun execute(editor: VimEditor, context: ExecutionContext, operatorArguments: OperatorArguments) {
addAction(MotionOuterAnyQuoteProximityAction())
}
}
private class InsideAnyBracketsHandler : ExtensionHandler {
override val isRepeatable = true
override fun execute(editor: VimEditor, context: ExecutionContext, operatorArguments: OperatorArguments) {
addAction(MotionInnerAnyBracketProximityAction())
}
}
private class AroundAnyBracketsHandler : ExtensionHandler {
override val isRepeatable = true
override fun execute(editor: VimEditor, context: ExecutionContext, operatorArguments: OperatorArguments) {
addAction(MotionOuterAnyBracketProximityAction())
}
}
class MotionInnerAnyQuoteProximityAction : TextObjectActionHandler() {
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_TEXT_BLOCK)
override val visualType: TextObjectVisualType = TextObjectVisualType.CHARACTER_WISE
override fun getRange(
editor: VimEditor,
caret: ImmutableVimCaret,
context: ExecutionContext,
count: Int,
rawCount: Int,
): TextRange? {
return findClosestQuoteRange(editor, caret, false)
}
}
class MotionOuterAnyQuoteProximityAction : TextObjectActionHandler() {
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_TEXT_BLOCK)
override val visualType: TextObjectVisualType = TextObjectVisualType.CHARACTER_WISE
override fun getRange(
editor: VimEditor,
caret: ImmutableVimCaret,
context: ExecutionContext,
count: Int,
rawCount: Int,
): TextRange? {
return findClosestQuoteRange(editor, caret, true)
}
}
class MotionInnerAnyBracketProximityAction : TextObjectActionHandler() {
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_TEXT_BLOCK)
override val visualType: TextObjectVisualType = TextObjectVisualType.CHARACTER_WISE
override fun getRange(
editor: VimEditor,
caret: ImmutableVimCaret,
context: ExecutionContext,
count: Int,
rawCount: Int,
): TextRange? {
return findClosestBracketRange(editor, caret, count, false)
}
}
}
class MotionOuterAnyBracketProximityAction : TextObjectActionHandler() {
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_TEXT_BLOCK)
override val visualType: TextObjectVisualType = TextObjectVisualType.CHARACTER_WISE
override fun getRange(
editor: VimEditor,
caret: ImmutableVimCaret,
context: ExecutionContext,
count: Int,
rawCount: Int,
): TextRange? {
return findClosestBracketRange(editor, caret, count, true)
}
}
private fun addAction(action: TextObjectActionHandler) {
val keyHandlerState: KeyHandlerState = KeyHandler.getInstance().keyHandlerState
keyHandlerState.commandBuilder.addAction(action)
}
private fun findClosestBracketRange(
editor: VimEditor,
caret: ImmutableVimCaret,
count: Int,
isOuter: Boolean,
): TextRange? {
return listOf('(', '[', '{')
.mapNotNull { char ->
findBlockRange(editor, caret, char, count, isOuter)?.let { range -> range to char }
}
.minByOrNull { it.first.distanceTo(caret.offset) }?.first
}
private fun findClosestQuoteRange(
editor: VimEditor,
caret: ImmutableVimCaret,
isOuter: Boolean,
): TextRange? {
return listOf('`', '"', '\'')
.mapNotNull { char ->
injector.searchHelper.findBlockQuoteInLineRange(editor, caret, char, isOuter)?.let { range -> range to char }
}
.minByOrNull { it.first.distanceTo(caret.offset) }?.first
}
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
}
}

View File

@ -45,7 +45,8 @@ internal class PluginState : ApplicationUsagesCollector() {
"surround",
"commentary",
"matchit",
"textobj-indent"
"textobj-indent",
"mini-ai"
)
internal val enabledExtensions = HashSet<String>()
}

View File

@ -49,6 +49,15 @@
</aliases>
</vimExtension>
<vimExtension implementation="com.maddyhome.idea.vim.extension.miniai.MiniAI"
name="mini-ai">
<aliases>
<alias name="https://github.com/echasnovski/mini.ai"/>
<alias name="echasnovski/mini.ai"/>
</aliases>
</vimExtension>
<vimExtension implementation="com.maddyhome.idea.vim.extension.argtextobj.VimArgTextObjExtension"
name="argtextobj">
<aliases>

View File

@ -183,20 +183,21 @@ class SetCommandTest : VimTestCase() {
"set all",
"""
|--- Options ---
|noargtextobj ideamarks scroll=0 nosurround
|nobomb ideawrite=all scrolljump=1 notextobj-entire
|nobreakindent noignorecase scrolloff=0 notextobj-indent
| colorcolumn= noincsearch selectmode= textwidth=0
|nocommentary nolist shellcmdflag=-x timeout
|nocursorline nomatchit shellxescape=@ timeoutlen=1000
|nodigraph maxmapdepth=20 shellxquote={ notrackactionids
|noexchange more showcmd undolevels=1000
| fileformat=unix nomultiple-cursors showmode virtualedit=
|nogdefault noNERDTree sidescroll=0 novisualbell
|nohighlightedyank nrformats=hex sidescrolloff=0 visualdelay=100
| history=50 nonumber nosmartcase whichwrap=b,s
|nohlsearch operatorfunc= nosneak wrap
|noideajoin norelativenumber startofline wrapscan
|noargtextobj ideawrite=all scrolljump=1 notextobj-indent
|nobomb noignorecase scrolloff=0 textwidth=0
|nobreakindent noincsearch selectmode= timeout
| colorcolumn= nolist shellcmdflag=-x timeoutlen=1000
|nocommentary nomatchit shellxescape=@ notrackactionids
|nocursorline maxmapdepth=20 shellxquote={ undolevels=1000
|nodigraph nomini-ai showcmd virtualedit=
|noexchange more showmode novisualbell
| fileformat=unix nomultiple-cursors sidescroll=0 visualdelay=100
|nogdefault noNERDTree sidescrolloff=0 whichwrap=b,s
|nohighlightedyank nrformats=hex nosmartcase wrap
| history=50 nonumber nosneak wrapscan
|nohlsearch operatorfunc= startofline
|noideajoin norelativenumber nosurround
| ideamarks scroll=0 notextobj-entire
| clipboard=ideaput,autoselect
| fileencoding=utf-8
| guicursor=n-v-c:block-Cursor/lCursor,ve:ver35-Cursor,o:hor50-Cursor,i-ci:ver25-Cursor/lCursor,r-cr:hor20-Cursor/lCursor,sm:block-Cursor-blinkwait175-blinkoff150-blinkon175
@ -288,6 +289,7 @@ class SetCommandTest : VimTestCase() {
|nomatchit
| matchpairs=(:),{:},[:]
| maxmapdepth=20
|nomini-ai
| more
|nomultiple-cursors
|noNERDTree

View File

@ -432,21 +432,21 @@ class SetglobalCommandTest : VimTestCase() {
assertCommandOutput(
"setglobal all", """
|--- Global option values ---
|noargtextobj ideamarks scrolljump=1 notextobj-indent
|nobomb ideawrite=all scrolloff=0 textwidth=0
|nobreakindent noignorecase selectmode= timeout
| colorcolumn= noincsearch shellcmdflag=-x timeoutlen=1000
|nocommentary nolist shellxescape=@ notrackactionids
|nocursorline nomatchit shellxquote={ undolevels=1000
|nodigraph maxmapdepth=20 showcmd virtualedit=
|noexchange more showmode novisualbell
| fileencoding= nomultiple-cursors sidescroll=0 visualdelay=100
| fileformat=unix noNERDTree sidescrolloff=0 whichwrap=b,s
|nogdefault nrformats=hex nosmartcase wrap
|nohighlightedyank nonumber nosneak wrapscan
| history=50 operatorfunc= startofline
|nohlsearch norelativenumber nosurround
|noideajoin scroll=0 notextobj-entire
|noargtextobj ideamarks scroll=0 notextobj-entire
|nobomb ideawrite=all scrolljump=1 notextobj-indent
|nobreakindent noignorecase scrolloff=0 textwidth=0
| colorcolumn= noincsearch selectmode= timeout
|nocommentary nolist shellcmdflag=-x timeoutlen=1000
|nocursorline nomatchit shellxescape=@ notrackactionids
|nodigraph maxmapdepth=20 shellxquote={ undolevels=1000
|noexchange nomini-ai showcmd virtualedit=
| fileencoding= more showmode novisualbell
| fileformat=unix nomultiple-cursors sidescroll=0 visualdelay=100
|nogdefault noNERDTree sidescrolloff=0 whichwrap=b,s
|nohighlightedyank nrformats=hex nosmartcase wrap
| history=50 nonumber nosneak wrapscan
|nohlsearch operatorfunc= startofline
|noideajoin norelativenumber nosurround
| clipboard=ideaput,autoselect
| guicursor=n-v-c:block-Cursor/lCursor,ve:ver35-Cursor,o:hor50-Cursor,i-ci:ver25-Cursor/lCursor,r-cr:hor20-Cursor/lCursor,sm:block-Cursor-blinkwait175-blinkoff150-blinkon175
| ide=IntelliJ IDEA Community Edition
@ -539,6 +539,7 @@ class SetglobalCommandTest : VimTestCase() {
|nomatchit
| matchpairs=(:),{:},[:]
| maxmapdepth=20
|nomini-ai
| more
|nomultiple-cursors
|noNERDTree

View File

@ -483,20 +483,21 @@ class SetlocalCommandTest : VimTestCase() {
assertCommandOutput(
"setlocal all", """
|--- Local option values ---
|noargtextobj ideamarks norelativenumber startofline
|nobomb idearefactormode= scroll=0 nosurround
|nobreakindent ideawrite=all scrolljump=1 notextobj-entire
| colorcolumn= noignorecase scrolloff=-1 notextobj-indent
|nocommentary noincsearch selectmode= textwidth=0
|nocursorline nolist shellcmdflag=-x timeout
|nodigraph nomatchit shellxescape=@ timeoutlen=1000
|noexchange maxmapdepth=20 shellxquote={ notrackactionids
| fileformat=unix more showcmd virtualedit=
|nogdefault nomultiple-cursors showmode novisualbell
|nohighlightedyank noNERDTree sidescroll=0 visualdelay=100
| history=50 nrformats=hex sidescrolloff=-1 whichwrap=b,s
|nohlsearch nonumber nosmartcase wrap
|--ideajoin operatorfunc= nosneak wrapscan
|noargtextobj idearefactormode= scroll=0 notextobj-entire
|nobomb ideawrite=all scrolljump=1 notextobj-indent
|nobreakindent noignorecase scrolloff=-1 textwidth=0
| colorcolumn= noincsearch selectmode= timeout
|nocommentary nolist shellcmdflag=-x timeoutlen=1000
|nocursorline nomatchit shellxescape=@ notrackactionids
|nodigraph maxmapdepth=20 shellxquote={ virtualedit=
|noexchange nomini-ai showcmd novisualbell
| fileformat=unix more showmode visualdelay=100
|nogdefault nomultiple-cursors sidescroll=0 whichwrap=b,s
|nohighlightedyank noNERDTree sidescrolloff=-1 wrap
| history=50 nrformats=hex nosmartcase wrapscan
|nohlsearch nonumber nosneak
|--ideajoin operatorfunc= startofline
| ideamarks norelativenumber nosurround
| clipboard=ideaput,autoselect
| fileencoding=utf-8
| guicursor=n-v-c:block-Cursor/lCursor,ve:ver35-Cursor,o:hor50-Cursor,i-ci:ver25-Cursor/lCursor,r-cr:hor20-Cursor/lCursor,sm:block-Cursor-blinkwait175-blinkoff150-blinkon175
@ -588,6 +589,7 @@ class SetlocalCommandTest : VimTestCase() {
|nomatchit
| matchpairs=(:),{:},[:]
| maxmapdepth=20
|nomini-ai
| more
|nomultiple-cursors
|noNERDTree

View File

@ -0,0 +1,644 @@
/*
* Copyright 2003-2024 The IdeaVim authors
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE.txt file or at
* https://opensource.org/licenses/MIT.
*/
package org.jetbrains.plugins.ideavim.extension.miniai
import com.intellij.ide.highlighter.JavaFileType
import com.maddyhome.idea.vim.state.mode.Mode
import org.jetbrains.plugins.ideavim.VimJavaTestCase
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInfo
@Suppress("SpellCheckingInspection")
class MiniAIExtensionTest : VimJavaTestCase() {
@BeforeEach
override fun setUp(testInfo: TestInfo) {
super.setUp(testInfo)
enableExtensions("mini-ai")
}
@Test
fun testChangeInsideSingleQuote() {
doTest(
"ciq",
"<caret>This is a 'simple' test",
"This is a '<caret>' test",
Mode.INSERT,
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testChangeInsideSingleQuoteNotBalanced() {
doTest(
"ciq",
"<caret>This is a 'simple test",
"<caret>This is a 'simple test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testChangeInsideDoubleQuote() {
doTest(
"ciq",
"<caret>This is a \"simple\" test",
"This is a \"<caret>\" test",
Mode.INSERT,
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testChangeInsideDoubleQuoteNotBalanced() {
doTest(
"ciq",
"<caret>This is a \"simple test",
"<caret>This is a \"simple test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testChangeInsideBackQuote() {
doTest(
"ciq",
"<caret>This is a `simple` test",
"This is a `<caret>` test",
Mode.INSERT,
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testChangeInsideBackQuoteNotBalanced() {
doTest(
"ciq",
"<caret>This is a `simple test",
"<caret>This is a `simple test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testChangeAroundSingleQuote() {
doTest(
"caq",
"<caret>This is a 'simple' test",
"This is a <caret> test",
Mode.INSERT,
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testChangeAroundSingleQuoteNotBalanced() {
doTest(
"caq",
"<caret>This is a 'simple test",
"<caret>This is a 'simple test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testChangeAroundDoubleQuote() {
doTest(
"caq",
"<caret>This is a \"simple\" test",
"This is a <caret> test",
Mode.INSERT,
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testChangeAroundDoubleQuoteNotBalanced() {
doTest(
"caq",
"<caret>This is a \"simple test",
"<caret>This is a \"simple test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testChangeAroundBackQuote() {
doTest(
"caq",
"<caret>This is a `simple` test",
"This is a <caret> test",
Mode.INSERT,
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testChangeAroundBackQuoteNotBalanced() {
doTest(
"caq",
"<caret>This is a `simple test",
"<caret>This is a `simple test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testChangeInsideRoundBrackets() {
doTest(
"cib",
"<caret>This is a (simple) test",
"This is a (<caret>) test",
Mode.INSERT,
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testChangeInsideRoundBracketsNotBalanced() {
doTest(
"cib",
"<caret>This is a (simple test",
"<caret>This is a (simple test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testChangeInsideSquareBrackets() {
doTest(
"cib",
"<caret>This is a [simple] test",
"This is a [<caret>] test",
Mode.INSERT,
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testChangeInsideSquareBracketsNotBalanced() {
doTest(
"cib",
"<caret>This is a [simple test",
"<caret>This is a [simple test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testChangeInsideCurlyBrackets() {
doTest(
"cib",
"<caret>This is a {simple} test",
"This is a {<caret>} test",
Mode.INSERT,
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testChangeInsideCurlyBracketsNotBalanced() {
doTest(
"cib",
"<caret>This is a {simple test",
"<caret>This is a {simple test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testChangeAroundRoundBrackets() {
doTest(
"cab",
"<caret>This is a (simple) test",
"This is a <caret> test",
Mode.INSERT,
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testChangeAroundRoundBracketsNotBalanced() {
doTest(
"cab",
"<caret>This is a (simple test",
"<caret>This is a (simple test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testChangeAroundSquareBrackets() {
doTest(
"cab",
"<caret>This is a [simple] test",
"This is a <caret> test",
Mode.INSERT,
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testChangeAroundSquareBracketsNotBalanced() {
doTest(
"cab",
"<caret>This is a [simple test",
"<caret>This is a [simple test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testChangeAroundCurlyBrackets() {
doTest(
"cab",
"<caret>This is a {simple} test",
"This is a <caret> test",
Mode.INSERT,
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testChangeAroundCurlyBracketsNotBalanced() {
doTest(
"cab",
"<caret>This is a {simple test",
"<caret>This is a {simple test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
// DELETE tests
@Test
fun testDeleteInsideSingleQuote() {
doTest(
"diq",
"<caret>This is a 'simple' test",
"This is a '<caret>' test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testDeleteInsideSingleQuoteNotBalanced() {
doTest(
"diq",
"<caret>This is a 'simple test",
"<caret>This is a 'simple test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testDeleteInsideDoubleQuote() {
doTest(
"diq",
"<caret>This is a \"simple\" test",
"This is a \"<caret>\" test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testDeleteInsideDoubleQuoteNotBalanced() {
doTest(
"diq",
"<caret>This is a \"simple test",
"<caret>This is a \"simple test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testDeleteInsideBackQuote() {
doTest(
"diq",
"<caret>This is a `simple` test",
"This is a `<caret>` test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testDeleteInsideBackQuoteNotBalanced() {
doTest(
"diq",
"<caret>This is a `simple test",
"<caret>This is a `simple test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testDeleteAroundSingleQuote() {
doTest(
"daq",
"<caret>This is a 'simple' test",
"This is a <caret> test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testDeleteAroundSingleQuoteNotBalanced() {
doTest(
"daq",
"<caret>This is a 'simple test",
"<caret>This is a 'simple test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testDeleteAroundDoubleQuote() {
doTest(
"daq",
"<caret>This is a \"simple\" test",
"This is a <caret> test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testDeleteAroundDoubleQuoteNotBalanced() {
doTest(
"daq",
"<caret>This is a \"simple test",
"<caret>This is a \"simple test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testDeleteAroundBackQuote() {
doTest(
"daq",
"<caret>This is a `simple` test",
"This is a <caret> test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testDeleteAroundBackQuoteNotBalanced() {
doTest(
"daq",
"<caret>This is a `simple test",
"<caret>This is a `simple test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testDeleteInsideRoundBrackets() {
doTest(
"dib",
"<caret>This is a (simple) test",
"This is a (<caret>) test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testDeleteInsideRoundBracketsNotBalanced() {
doTest(
"dib",
"<caret>This is a (simple test",
"<caret>This is a (simple test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testDeleteInsideSquareBrackets() {
doTest(
"dib",
"<caret>This is a [simple] test",
"This is a [<caret>] test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testDeleteInsideSquareBracketsNotBalanced() {
doTest(
"dib",
"<caret>This is a [simple test",
"<caret>This is a [simple test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testDeleteInsideCurlyBrackets() {
doTest(
"dib",
"<caret>This is a {simple} test",
"This is a {<caret>} test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testDeleteInsideCurlyBracketsNotBalanced() {
doTest(
"dib",
"<caret>This is a {simple test",
"<caret>This is a {simple test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testDeleteAroundRoundBrackets() {
doTest(
"dab",
"<caret>This is a (simple) test",
"This is a <caret> test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testDeleteAroundRoundBracketsNotBalanced() {
doTest(
"dab",
"<caret>This is a (simple test",
"<caret>This is a (simple test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testDeleteAroundSquareBrackets() {
doTest(
"dab",
"<caret>This is a [simple] test",
"This is a <caret> test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testDeleteAroundSquareBracketsNotBalanced() {
doTest(
"dab",
"<caret>This is a [simple test",
"<caret>This is a [simple test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testDeleteAroundCurlyBrackets() {
doTest(
"dab",
"<caret>This is a {simple} test",
"This is a <caret> test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
@Test
fun testDeleteAroundCurlyBracketsNotBalanced() {
doTest(
"dab",
"<caret>This is a {simple test",
"<caret>This is a {simple test",
Mode.NORMAL(),
JavaFileType.INSTANCE,
)
assertSelection(null)
}
}