1
0
mirror of https://github.com/chylex/IntelliJ-IdeaVim.git synced 2025-02-20 14:46:02 +01:00

Revert per-caret registers

This commit is contained in:
chylex 2024-07-08 02:53:01 +02:00
parent 8d51537f79
commit 5f59b47b19
Signed by: chylex
GPG Key ID: 4DE42C8F19A80548
27 changed files with 184 additions and 292 deletions

View File

@ -68,7 +68,8 @@ object VimExtensionFacade {
@JvmStatic
@Deprecated("Use VimPlugin.getKey().putKeyMapping(modes, fromKeys, pluginOwner, extensionHandler, recursive)",
@Deprecated(
"Use VimPlugin.getKey().putKeyMapping(modes, fromKeys, pluginOwner, extensionHandler, recursive)",
ReplaceWith(
"VimPlugin.getKey().putKeyMapping(modes, fromKeys, pluginOwner, extensionHandler, recursive)",
"com.maddyhome.idea.vim.VimPlugin"
@ -194,7 +195,7 @@ object VimExtensionFacade {
@JvmStatic
fun getRegisterForCaret(register: Char, caret: VimCaret): List<KeyStroke>? {
val reg = caret.registerStorage.getRegister(register) ?: return null
val reg = injector.registerGroup.getRegister(register) ?: return null
return reg.keys
}
@ -207,7 +208,7 @@ object VimExtensionFacade {
/** Set the current contents of the given register */
@JvmStatic
fun setRegisterForCaret(register: Char, caret: ImmutableVimCaret, keys: List<KeyStroke?>?) {
caret.registerStorage.setKeys(register, keys?.filterNotNull() ?: emptyList())
injector.registerGroup.setKeys(register, keys?.filterNotNull() ?: emptyList())
}
/** Set the current contents of the given register */
@ -276,4 +277,4 @@ fun VimExtensionFacade.exportOperatorFunction(name: String, function: OperatorFu
fun interface ScriptFunction {
fun execute(editor: VimEditor, context: ExecutionContext, args: Map<String, VimDataType>): ExecutionResult
}
}

View File

@ -144,7 +144,7 @@ internal class ReplaceWithRegister : VimExtension {
private fun doReplace(editor: Editor, context: DataContext, caret: ImmutableVimCaret, visualSelection: PutData.VisualSelection) {
val registerGroup = injector.registerGroup
val lastRegisterChar = if (editor.caretModel.caretCount == 1) registerGroup.currentRegister else registerGroup.getCurrentRegisterForMulticaret()
val savedRegister = caret.registerStorage.getRegister(lastRegisterChar) ?: return
val savedRegister = registerGroup.getRegister(lastRegisterChar) ?: return
var usedType = savedRegister.type
var usedText = savedRegister.text
@ -180,4 +180,4 @@ private fun doReplace(editor: Editor, context: DataContext, caret: ImmutableVimC
saveToRegister = false
)
}
}
}

View File

@ -18,13 +18,12 @@ import com.intellij.openapi.editor.VisualPosition
import com.intellij.openapi.editor.markup.RangeHighlighter
import com.intellij.openapi.util.Key
import com.intellij.openapi.util.UserDataHolder
import com.maddyhome.idea.vim.api.CaretRegisterStorageBase
import com.maddyhome.idea.vim.api.LocalMarkStorage
import com.maddyhome.idea.vim.api.SelectionInfo
import com.maddyhome.idea.vim.common.InsertSequence
import com.maddyhome.idea.vim.ex.ExOutputModel
import com.maddyhome.idea.vim.group.visual.VisualChange
import com.maddyhome.idea.vim.group.visual.vimLeadSelectionOffset
import com.maddyhome.idea.vim.common.InsertSequence
import com.maddyhome.idea.vim.newapi.vim
import com.maddyhome.idea.vim.state.VimStateMachine
import com.maddyhome.idea.vim.state.mode.Mode
@ -96,7 +95,6 @@ internal var Caret.vimInsertStart: RangeMarker by userDataOr {
}
// TODO: Data could be lost during visual block motion
internal var Caret.registerStorage: CaretRegisterStorageBase? by userDataCaretToEditor()
internal var Caret.markStorage: LocalMarkStorage? by userDataCaretToEditor()
internal var Caret.lastSelectionInfo: SelectionInfo? by userDataCaretToEditor()

View File

@ -12,8 +12,6 @@ import com.intellij.openapi.editor.Caret
import com.intellij.openapi.editor.LogicalPosition
import com.intellij.openapi.editor.VisualPosition
import com.maddyhome.idea.vim.api.BufferPosition
import com.maddyhome.idea.vim.api.CaretRegisterStorage
import com.maddyhome.idea.vim.api.CaretRegisterStorageBase
import com.maddyhome.idea.vim.api.ImmutableVimCaret
import com.maddyhome.idea.vim.api.LocalMarkStorage
import com.maddyhome.idea.vim.api.SelectionInfo
@ -29,7 +27,6 @@ import com.maddyhome.idea.vim.helper.insertHistory
import com.maddyhome.idea.vim.helper.lastSelectionInfo
import com.maddyhome.idea.vim.helper.markStorage
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
import com.maddyhome.idea.vim.helper.registerStorage
import com.maddyhome.idea.vim.helper.resetVimLastColumn
import com.maddyhome.idea.vim.helper.vimInsertStart
import com.maddyhome.idea.vim.helper.vimLastColumn
@ -41,17 +38,6 @@ import com.maddyhome.idea.vim.state.mode.SelectionType
internal class IjVimCaret(val caret: Caret) : VimCaretBase() {
override val registerStorage: CaretRegisterStorage
get() {
var storage = this.caret.registerStorage
if (storage == null) {
storage = CaretRegisterStorageBase(this)
this.caret.registerStorage = storage
} else if (storage.caret != this) {
storage.caret = this
}
return storage
}
override val markStorage: LocalMarkStorage
get() {
var storage = this.caret.markStorage

View File

@ -151,21 +151,40 @@ internal class IjVimEditor(editor: Editor) : MutableLinearEditor() {
return editor.caretModel.allCarets.map { IjVimCaret(it) }
}
override var isFirstCaret = false
override var isReversingCarets = false
@Suppress("ideavimRunForEachCaret")
override fun forEachCaret(action: (VimCaret) -> Unit) {
if (editor.vim.inBlockSelection) {
action(IjVimCaret(editor.caretModel.primaryCaret))
} else {
editor.caretModel.runForEachCaret({
if (it.isValid) {
action(IjVimCaret(it))
}
}, false)
isFirstCaret = true
try {
editor.caretModel.runForEachCaret({
if (it.isValid) {
action(IjVimCaret(it))
isFirstCaret = false
}
}, false)
} finally {
isFirstCaret = false
}
}
}
override fun forEachNativeCaret(action: (VimCaret) -> Unit, reverse: Boolean) {
editor.caretModel.runForEachCaret({ action(IjVimCaret(it)) }, reverse)
isFirstCaret = true
isReversingCarets = reverse
try {
editor.caretModel.runForEachCaret({
action(IjVimCaret(it))
isFirstCaret = false
}, reverse)
} finally {
isFirstCaret = false
isReversingCarets = false
}
}
override fun isInForEachCaretScope(): Boolean {
@ -516,4 +535,4 @@ internal class InsertTimeRecorder: ModeChangeListener {
editor.forEachCaret { undo.endInsertSequence(it, it.offset, nanoTime) }
}
}
}
}

View File

@ -13,7 +13,6 @@ import com.maddyhome.idea.vim.action.motion.search.SearchWholeWordForwardAction
import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.common.TextRange
import com.maddyhome.idea.vim.newapi.IjVimEditor
import com.maddyhome.idea.vim.newapi.vim
import com.maddyhome.idea.vim.state.mode.SelectionType
import org.jetbrains.plugins.ideavim.VimBehaviorDiffers
import org.jetbrains.plugins.ideavim.VimTestCase
@ -2173,7 +2172,7 @@ rtyfg${c}hzxc"""
val editor = configureByText(before)
injector.registerGroup.storeText('*', "fgh")
VimPlugin.getRegister()
.storeText(IjVimEditor(editor), editor.vim.primaryCaret(), TextRange(16, 19), SelectionType.CHARACTER_WISE, false)
.storeText(IjVimEditor(editor), TextRange(16, 19), SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("\"*P"))
val after = "fg${c}hqfg${c}hwe asd zxc rty fg${c}hfgh vbn"
assertState(after)

View File

@ -33,7 +33,7 @@ class IdeaPutNotificationsTest : VimTestCase() {
appReadySetup(false)
val vimEditor = fixture.editor.vim
VimPlugin.getRegister()
.storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "legendary", SelectionType.CHARACTER_WISE, false)
.storeText(vimEditor, before rangeOf "legendary", SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("p"))
val notification = notifications().last()
@ -53,7 +53,7 @@ class IdeaPutNotificationsTest : VimTestCase() {
appReadySetup(false)
val vimEditor = fixture.editor.vim
VimPlugin.getRegister()
.storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "legendary", SelectionType.CHARACTER_WISE, false)
.storeText(vimEditor, before rangeOf "legendary", SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("p"))
val notifications = notifications()
@ -71,7 +71,7 @@ class IdeaPutNotificationsTest : VimTestCase() {
appReadySetup(true)
val vimEditor = fixture.editor.vim
VimPlugin.getRegister()
.storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "legendary", SelectionType.CHARACTER_WISE, false)
.storeText(vimEditor, before rangeOf "legendary", SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("p"))
val notifications = EventLog.getLogModel(fixture.project).notifications

View File

@ -88,7 +88,7 @@ class PutTestAfterCursorActionTest : VimTestCase() {
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister()
.storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
.storeText(vimEditor, before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
typeText(injector.parser.parseKeys("p"))
val after = """
A Discovery
@ -127,7 +127,6 @@ class PutTestAfterCursorActionTest : VimTestCase() {
val vimEditor = editor.vim
injector.registerGroup.storeText(
vimEditor,
vimEditor.primaryCaret(),
before rangeOf "I found it in a legendary land\n",
SelectionType.LINE_WISE,
false,
@ -157,7 +156,7 @@ class PutTestAfterCursorActionTest : VimTestCase() {
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister()
.storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "Discovery", SelectionType.CHARACTER_WISE, false)
.storeText(vimEditor, before rangeOf "Discovery", SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("vep"))
val after = """
A Discovery

View File

@ -31,7 +31,7 @@ class PutTextBeforeCursorActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
injector.registerGroup.storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "Discovery", SelectionType.CHARACTER_WISE, false)
injector.registerGroup.storeText(vimEditor, before rangeOf "Discovery", SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("V" + "P"))
typeText(injector.parser.parseKeys("V" + "P"))
val after = """

View File

@ -54,7 +54,7 @@ class PutViaIdeaTest : VimTestCase() {
val vimEditor = fixture.editor.vim
VimPlugin.getRegister()
.storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "legendary", SelectionType.CHARACTER_WISE, false)
.storeText(vimEditor, before rangeOf "legendary", SelectionType.CHARACTER_WISE, false)
typeText("ppp")
val after = "Ilegendarylegendarylegendar${c}y found it in a legendary land"
@ -74,7 +74,6 @@ class PutViaIdeaTest : VimTestCase() {
VimPlugin.getRegister()
.storeText(
vimEditor,
vimEditor.primaryCaret(),
before rangeOf "legendary$randomUUID",
SelectionType.CHARACTER_WISE,
false,
@ -100,7 +99,6 @@ class PutViaIdeaTest : VimTestCase() {
val vimEditor = fixture.editor.vim
VimPlugin.getRegister().storeText(
vimEditor,
vimEditor.primaryCaret(),
before rangeOf "\nLorem ipsum dolor sit amet,\n",
SelectionType.CHARACTER_WISE,
false,

View File

@ -75,7 +75,7 @@ class PutVisualTextActionTest : VimTestCase() {
val before = "${c}I found it in a legendary land"
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "legendary", SelectionType.CHARACTER_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, before rangeOf "legendary", SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("ve" + "p"))
val after = "legendar${c}y it in a legendary land"
assertState(after)
@ -87,7 +87,7 @@ class PutVisualTextActionTest : VimTestCase() {
val before = "${c}I found it in a legendary land"
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "legendary", SelectionType.CHARACTER_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, before rangeOf "legendary", SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("v2e" + "2p"))
val after = "legendarylegendar${c}y in a legendary land"
assertState(after)
@ -99,7 +99,7 @@ class PutVisualTextActionTest : VimTestCase() {
val before = "${c}I found it in a legendary land"
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "legendary", SelectionType.CHARACTER_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, before rangeOf "legendary", SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("v$" + "2p"))
val after = "legendarylegendar${c}y"
assertState(after)
@ -133,7 +133,7 @@ class PutVisualTextActionTest : VimTestCase() {
val before = "I foun${c}d it in a legendary land"
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "legendary", SelectionType.CHARACTER_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, before rangeOf "legendary", SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("vb" + "p"))
val after = "I legendar${c}y it in a legendary land"
assertState(after)
@ -154,7 +154,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
typeText(injector.parser.parseKeys("ve" + "p"))
val after = """
A Discovery
@ -182,7 +182,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
typeText(injector.parser.parseKeys("ve" + "p"))
val after = """
A Discovery
@ -210,7 +210,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
typeText(injector.parser.parseKeys("ve" + "p"))
val after = """
A Discovery
@ -238,7 +238,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
typeText(injector.parser.parseKeys("v$" + "p"))
val after = """
A Discovery
@ -455,7 +455,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), editor.rangeOf("|found|", 2), SelectionType.BLOCK_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, editor.rangeOf("|found|", 2), SelectionType.BLOCK_WISE, false)
typeText(injector.parser.parseKeys("ve" + "p"))
val after = """
A Discovery
@ -491,7 +491,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), editor.rangeOf("|found|", 2), SelectionType.BLOCK_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, editor.rangeOf("|found|", 2), SelectionType.BLOCK_WISE, false)
typeText(injector.parser.parseKeys("ve" + "p"))
val after = """
A Discovery
@ -529,7 +529,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), editor.rangeOf("|found|", 2), SelectionType.BLOCK_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, editor.rangeOf("|found|", 2), SelectionType.BLOCK_WISE, false)
typeText(injector.parser.parseKeys("ve" + "2p"))
val after = """
A Discovery
@ -640,7 +640,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "Discovery", SelectionType.CHARACTER_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, before rangeOf "Discovery", SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("V" + "p"))
val after = """
A Discovery
@ -666,7 +666,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "Discovery", SelectionType.CHARACTER_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, before rangeOf "Discovery", SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("V" + "2p"))
val after = """
A Discovery
@ -703,7 +703,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "Discovery", SelectionType.CHARACTER_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, before rangeOf "Discovery", SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("V" + "p"))
val after = """
A Discovery
@ -876,7 +876,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
typeText(injector.parser.parseKeys("V" + "p"))
val after = """
A Discovery
@ -902,7 +902,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
typeText(injector.parser.parseKeys("V" + "2p"))
val after = """
A Discovery
@ -939,7 +939,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
typeText(injector.parser.parseKeys("V" + "p"))
val after = """
A Discovery
@ -1117,7 +1117,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), editor.rangeOf("|found|", 2), SelectionType.BLOCK_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, editor.rangeOf("|found|", 2), SelectionType.BLOCK_WISE, false)
typeText(injector.parser.parseKeys("V" + "p"))
val after = """
A Discovery
@ -1172,7 +1172,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), editor.rangeOf("|found|", 2), SelectionType.BLOCK_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, editor.rangeOf("|found|", 2), SelectionType.BLOCK_WISE, false)
typeText(injector.parser.parseKeys("V" + "p"))
val after = """
A Discovery
@ -1233,7 +1233,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), editor.rangeOf("|found|", 2), SelectionType.BLOCK_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, editor.rangeOf("|found|", 2), SelectionType.BLOCK_WISE, false)
typeText(injector.parser.parseKeys("V" + "2p"))
val after = """
A Discovery
@ -1409,7 +1409,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "Discovery", SelectionType.CHARACTER_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, before rangeOf "Discovery", SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("<C-V>2e2j" + "p"))
val after = """
A Discovery
@ -1435,7 +1435,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "Discovery", SelectionType.CHARACTER_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, before rangeOf "Discovery", SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("<C-V>3e2k" + "p"))
val after = """
A Discovery
@ -1461,7 +1461,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "Discovery", SelectionType.CHARACTER_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, before rangeOf "Discovery", SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("<C-V>2e2j" + "2p"))
val after = """
A Discovery
@ -1487,7 +1487,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "Discovery", SelectionType.CHARACTER_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, before rangeOf "Discovery", SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("<C-V>3j$" + "p"))
val after = """
A Discovery
@ -1526,7 +1526,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
typeText(injector.parser.parseKeys("<C-V>2e2j" + "p"))
val after = """
A Discovery
@ -1554,7 +1554,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
typeText(injector.parser.parseKeys("<C-V>2e2j" + "P"))
val after = """
A Discovery
@ -1593,7 +1593,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
typeText(injector.parser.parseKeys("<C-V>2e2j" + "2p"))
val after = """
A Discovery
@ -1633,7 +1633,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
typeText(injector.parser.parseKeys("<C-V>2e3j" + "p"))
val after = """
A Discovery
@ -1672,7 +1672,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
typeText(injector.parser.parseKeys("<C-V>2j$" + "p"))
val after = """
A Discovery
@ -1707,7 +1707,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), editor.rangeOf("|found|", 2), SelectionType.BLOCK_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, editor.rangeOf("|found|", 2), SelectionType.BLOCK_WISE, false)
typeText(injector.parser.parseKeys("<C-V>2e2j" + "p"))
val after = """
A Discovery
@ -1743,7 +1743,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), editor.rangeOf("|found|", 2), SelectionType.BLOCK_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, editor.rangeOf("|found|", 2), SelectionType.BLOCK_WISE, false)
typeText(injector.parser.parseKeys("<C-V>2e3j" + "p"))
val after = """
A Discovery
@ -1779,7 +1779,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), editor.rangeOf("|found|", 2), SelectionType.BLOCK_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, editor.rangeOf("|found|", 2), SelectionType.BLOCK_WISE, false)
typeText(injector.parser.parseKeys("<C-V>2ej" + "p"))
val after = """
A Discovery
@ -1815,7 +1815,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), editor.rangeOf("|found|", 2), SelectionType.BLOCK_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, editor.rangeOf("|found|", 2), SelectionType.BLOCK_WISE, false)
typeText(injector.parser.parseKeys("<C-V>elj" + "p"))
val after = """
A Discovery
@ -1852,7 +1852,7 @@ class PutVisualTextActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), editor.rangeOf("|found|", 2), SelectionType.BLOCK_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, editor.rangeOf("|found|", 2), SelectionType.BLOCK_WISE, false)
typeText(injector.parser.parseKeys("<C-V>2j$" + "p"))
val after = """
A Discovery

View File

@ -34,7 +34,7 @@ class PutVisualTextMoveCursorActionTest : VimTestCase() {
val before = "${c}I found it in a legendary land"
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), TextRange(16, 25), SelectionType.CHARACTER_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, TextRange(16, 25), SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("v2e" + "2gp"))
val after = "legendarylegendary$c in a legendary land"
assertState(after)
@ -46,7 +46,7 @@ class PutVisualTextMoveCursorActionTest : VimTestCase() {
val before = "${c}I found it in a legendary land"
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), TextRange(16, 25), SelectionType.LINE_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, TextRange(16, 25), SelectionType.LINE_WISE, false)
typeText(injector.parser.parseKeys("v2e" + "gp"))
val after = """
@ -62,7 +62,7 @@ class PutVisualTextMoveCursorActionTest : VimTestCase() {
val before = "${c}I found it in a legendary land"
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), TextRange(16, 25), SelectionType.CHARACTER_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, TextRange(16, 25), SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("V" + "gp"))
val after = "legendary\n$c"
assertState(after)
@ -89,7 +89,7 @@ class PutVisualTextMoveCursorActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(file)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), TextRange(2, 11), SelectionType.LINE_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, TextRange(2, 11), SelectionType.LINE_WISE, false)
typeText(injector.parser.parseKeys("V" + "gp"))
assertState(newFile)
}
@ -135,7 +135,7 @@ class PutVisualTextMoveCursorActionTest : VimTestCase() {
val before = "${c}I found it in a legendary land"
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), TextRange(16, 25), SelectionType.LINE_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, TextRange(16, 25), SelectionType.LINE_WISE, false)
typeText(injector.parser.parseKeys("v2e" + "gP"))
val after = """
@ -151,7 +151,7 @@ class PutVisualTextMoveCursorActionTest : VimTestCase() {
val before = "${c}I found it in a legendary land"
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), TextRange(16, 25), SelectionType.CHARACTER_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, TextRange(16, 25), SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("v2e" + "2gP"))
val after = "legendarylegendary$c in a legendary land"
assertState(after)
@ -163,7 +163,7 @@ class PutVisualTextMoveCursorActionTest : VimTestCase() {
val before = "${c}I found it in a legendary land"
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), TextRange(16, 25), SelectionType.CHARACTER_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, TextRange(16, 25), SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("v$" + "2gP"))
val after = "legendarylegendar${c}y"
assertState(after)
@ -175,7 +175,7 @@ class PutVisualTextMoveCursorActionTest : VimTestCase() {
val before = "${c}I found it in a legendary land"
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), TextRange(16, 25), SelectionType.CHARACTER_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, TextRange(16, 25), SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("V" + "gP"))
val after = "legendary\n$c"
assertState(after)
@ -274,7 +274,7 @@ class PutVisualTextMoveCursorActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), TextRange(16, 19), SelectionType.BLOCK_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, TextRange(16, 19), SelectionType.BLOCK_WISE, false)
typeText(injector.parser.parseKeys("<S-v>" + "gp"))
val after = """
${c}fgh
@ -300,7 +300,7 @@ class PutVisualTextMoveCursorActionTest : VimTestCase() {
""".trimIndent()
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), TextRange(16, 19), SelectionType.LINE_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, TextRange(16, 19), SelectionType.LINE_WISE, false)
typeText(injector.parser.parseKeys("<C-v>" + "h" + "gp"))
val after = """
q
@ -323,7 +323,7 @@ class PutVisualTextMoveCursorActionTest : VimTestCase() {
val before = "${c}qwe asd ${c}zxc rty ${c}fgh vbn"
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister().storeText(vimEditor, vimEditor.primaryCaret(), TextRange(16, 19), SelectionType.CHARACTER_WISE, false)
VimPlugin.getRegister().storeText(vimEditor, TextRange(16, 19), SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("v2e" + "2gp"))
val after = "fghfgh$c fghfgh$c fghfgh$c"
assertState(after)

View File

@ -91,7 +91,7 @@ class YankVisualActionTest : VimTestCase() {
typeText(injector.parser.parseKeys("viw" + "y"))
val editor = fixture.editor.vim
val lastRegister = injector.registerGroup.lastRegisterChar
val registers = editor.carets().map { it.registerStorage.getRegister(lastRegister)?.rawText }
val registers = editor.carets().map { injector.registerGroup.getRegister(lastRegister)?.rawText }
kotlin.test.assertEquals(listOf("found", "was"), registers)
}
@ -172,7 +172,7 @@ class YankVisualActionTest : VimTestCase() {
typeText(injector.parser.parseKeys("V" + "y"))
val editor = fixture.editor.vim
val lastRegister = injector.registerGroup.lastRegisterChar
val registers = editor.carets().map { it.registerStorage.getRegister(lastRegister)?.rawText }
val registers = editor.carets().map { injector.registerGroup.getRegister(lastRegister)?.rawText }
kotlin.test.assertEquals(
listOf("all rocks and lavender and tufted grass,\n", "hard by the torrent of a mountain pass.\n"),
registers,

View File

@ -130,7 +130,7 @@ class MultipleCaretsTest : VimTestCase() {
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister()
.storeText(vimEditor, vimEditor.primaryCaret(), TextRange(16, 19), SelectionType.CHARACTER_WISE, false)
.storeText(vimEditor, TextRange(16, 19), SelectionType.CHARACTER_WISE, false)
typeText(commandToKeys("pu"))
val after = """
qwe
@ -165,7 +165,7 @@ class MultipleCaretsTest : VimTestCase() {
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister()
.storeText(vimEditor, vimEditor.primaryCaret(), TextRange(16, 19), SelectionType.CHARACTER_WISE, false)
.storeText(vimEditor, TextRange(16, 19), SelectionType.CHARACTER_WISE, false)
typeText(commandToKeys("pu"))
val after = """
qwe
@ -201,7 +201,7 @@ class MultipleCaretsTest : VimTestCase() {
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister()
.storeText(vimEditor, vimEditor.primaryCaret(), TextRange(16, 19), SelectionType.CHARACTER_WISE, false)
.storeText(vimEditor, TextRange(16, 19), SelectionType.CHARACTER_WISE, false)
typeText(commandToKeys("4pu"))
val after = """
qwe
@ -237,7 +237,7 @@ class MultipleCaretsTest : VimTestCase() {
val editor = configureByText(before)
val vimEditor = editor.vim
VimPlugin.getRegister()
.storeText(vimEditor, vimEditor.primaryCaret(), TextRange(16, 19), SelectionType.CHARACTER_WISE, false)
.storeText(vimEditor, TextRange(16, 19), SelectionType.CHARACTER_WISE, false)
typeText(commandToKeys("4pu"))
val after = """
qwe
@ -258,7 +258,7 @@ class MultipleCaretsTest : VimTestCase() {
val before = "${c}qwe\n" + "rty\n" + "as${c}d\n" + "fgh\n" + "zxc\n" + "vbn\n"
val editor = configureByText(before)
VimPlugin.getRegister()
.storeText(editor.vim, editor.vim.primaryCaret(), TextRange(16, 19), SelectionType.CHARACTER_WISE, false)
.storeText(editor.vim, TextRange(16, 19), SelectionType.CHARACTER_WISE, false)
typeText("vj")
typeText(commandToKeys("pu"))

View File

@ -9,7 +9,6 @@
package org.jetbrains.plugins.ideavim.ex.implementation.commands
import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.newapi.vim
import com.maddyhome.idea.vim.register.RegisterConstants
import org.jetbrains.plugins.ideavim.VimTestCase
import org.junit.jupiter.api.Test
@ -303,33 +302,4 @@ class YankLinesCommandTest : VimTestCase() {
|Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
|""".trimMargin())
}
@Test
fun `test multicaret yank`() {
configureByText(
"""
|Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|${c}Morbi nec luctus tortor, id venenatis lacus.
|${c}Nunc sit amet tellus vel purus cursus posuere et at purus.
|${c}Ut id dapibus augue.
|Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
|Pellentesque orci dolor, tristique quis rutrum non, scelerisque id dui.
""".trimMargin()
)
enterCommand("y")
val carets = fixture.editor.vim.carets()
assertEquals(3, carets.size)
assertEquals(
"Morbi nec luctus tortor, id venenatis lacus.\n",
carets[0].registerStorage.getRegister(RegisterConstants.UNNAMED_REGISTER)?.text
)
assertEquals(
"Nunc sit amet tellus vel purus cursus posuere et at purus.\n",
carets[1].registerStorage.getRegister(RegisterConstants.UNNAMED_REGISTER)?.text
)
assertEquals(
"Ut id dapibus augue.\n",
carets[2].registerStorage.getRegister(RegisterConstants.UNNAMED_REGISTER)?.text
)
}
}

View File

@ -50,7 +50,7 @@ class ReplaceWithRegisterTest : VimTestCase() {
configureByText(text)
val vimEditor = fixture.editor.vim
VimPlugin.getRegister()
.storeText(vimEditor, vimEditor.primaryCaret(), text rangeOf "one", SelectionType.CHARACTER_WISE, false)
.storeText(vimEditor, text rangeOf "one", SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("griw"))
assertState("one on${c}e three")
assertEquals("one", VimPlugin.getRegister().lastRegister?.text)
@ -170,7 +170,7 @@ class ReplaceWithRegisterTest : VimTestCase() {
configureByText(text)
val vimEditor = fixture.editor.vim
VimPlugin.getRegister()
.storeText(vimEditor, vimEditor.primaryCaret(), text rangeOf "one", SelectionType.CHARACTER_WISE, false)
.storeText(vimEditor, text rangeOf "one", SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("3griw"))
assertState("one on${c}e four")
assertEquals("one", VimPlugin.getRegister().lastRegister?.text)
@ -184,7 +184,7 @@ class ReplaceWithRegisterTest : VimTestCase() {
configureByText(text)
val vimEditor = fixture.editor.vim
VimPlugin.getRegister()
.storeText(vimEditor, vimEditor.primaryCaret(), text rangeOf "one", SelectionType.CHARACTER_WISE, false)
.storeText(vimEditor, text rangeOf "one", SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("griw"))
assertState("one two one four")
assertEquals("one", VimPlugin.getRegister().lastRegister?.text)
@ -197,7 +197,7 @@ class ReplaceWithRegisterTest : VimTestCase() {
configureByText(text)
val vimEditor = fixture.editor.vim
VimPlugin.getRegister()
.storeText(vimEditor, vimEditor.primaryCaret(), text rangeOf "one", SelectionType.CHARACTER_WISE, false)
.storeText(vimEditor, text rangeOf "one", SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("griw" + "w" + "."))
assertState("one one on${c}e four")
assertEquals("one", VimPlugin.getRegister().lastRegister?.text)
@ -247,7 +247,7 @@ class ReplaceWithRegisterTest : VimTestCase() {
configureByText(text)
val vimEditor = fixture.editor.vim
VimPlugin.getRegister()
.storeText(vimEditor, vimEditor.primaryCaret(), text rangeOf "legendary", SelectionType.CHARACTER_WISE, false)
.storeText(vimEditor, text rangeOf "legendary", SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("grr"))
assertState(
"""
@ -414,7 +414,7 @@ class ReplaceWithRegisterTest : VimTestCase() {
configureByText(text)
val vimEditor = fixture.editor.vim
VimPlugin.getRegister()
.storeText(vimEditor, vimEditor.primaryCaret(), text rangeOf "legendary", SelectionType.CHARACTER_WISE, false)
.storeText(vimEditor, text rangeOf "legendary", SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("viw" + "gr"))
assertState(
"""
@ -485,7 +485,7 @@ class ReplaceWithRegisterTest : VimTestCase() {
configureByText(text)
val vimEditor = fixture.editor.vim
VimPlugin.getRegister()
.storeText(vimEditor, vimEditor.primaryCaret(), text rangeOf "legendary", SelectionType.CHARACTER_WISE, false)
.storeText(vimEditor, text rangeOf "legendary", SelectionType.CHARACTER_WISE, false)
typeText(injector.parser.parseKeys("V" + "gr"))
assertState(
"""

View File

@ -10,7 +10,6 @@ package com.maddyhome.idea.vim.action.copy
import com.intellij.vim.annotations.CommandOrMotion
import com.intellij.vim.annotations.Mode
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.Argument
@ -36,7 +35,15 @@ sealed class PutTextBaseAction(
val count = operatorArguments.count1
val sortedCarets = editor.sortedCarets()
return if (sortedCarets.size > 1) {
val caretToPutData = sortedCarets.associateWith { getPutDataForCaret(it, count) }
val putData = getPutData(count)
val splitText = putData.textData?.rawText?.split('\n')?.dropLastWhile(String::isEmpty)
val caretToPutData = if (splitText != null && splitText.size == sortedCarets.size) {
sortedCarets.mapIndexed { index, caret -> caret to putData.copy(textData = putData.textData.copy(rawText = splitText[splitText.lastIndex - index])) }.toMap()
} else {
sortedCarets.associateWith { putData }
}
var result = true
injector.application.runWriteAction {
caretToPutData.forEach {
@ -45,28 +52,24 @@ sealed class PutTextBaseAction(
}
result
} else {
val putData = getPutDataForCaret(sortedCarets.single(), count)
injector.put.putText(editor, context, putData, operatorArguments)
injector.put.putText(editor, context, getPutData(count), operatorArguments)
}
}
private fun getPutDataForCaret(caret: ImmutableVimCaret, count: Int): PutData {
val registerService = injector.registerGroup
val registerChar = if (caret.editor.carets().size == 1) {
registerService.currentRegister
} else {
registerService.getCurrentRegisterForMulticaret()
}
val register = caret.registerStorage.getRegister(registerChar)
val textData = register?.let {
TextData(
register.text ?: injector.parser.toPrintableString(register.keys),
register.type,
register.transferableData,
register.name,
)
}
return PutData(textData, null, count, insertTextBeforeCaret, indent, caretAfterInsertedText, -1)
private fun getPutData(count: Int): PutData {
return PutData(getRegisterTextData(), null, count, insertTextBeforeCaret, indent, caretAfterInsertedText, -1)
}
}
fun getRegisterTextData(): TextData? {
val register = injector.registerGroup.getRegister(injector.registerGroup.currentRegister)
return register?.let {
TextData(
register.text ?: injector.parser.toPrintableString(register.keys),
register.type,
register.transferableData,
register.name,
)
}
}

View File

@ -41,7 +41,21 @@ sealed class PutVisualTextBaseAction(
): Boolean {
if (caretsAndSelections.isEmpty()) return false
val count = cmd.count
val caretToPutData = editor.sortedCarets().associateWith { getPutDataForCaret(it, caretsAndSelections[it], count) }
val sortedCarets = editor.sortedCarets()
val textData = getRegisterTextData()
val splitText = textData?.rawText?.split('\n')?.dropLastWhile(String::isEmpty)
val caretToTextData = if (splitText != null && splitText.size == sortedCarets.size) {
sortedCarets.mapIndexed { index, caret -> caret to textData.copy(rawText = splitText[splitText.lastIndex - index]) }.toMap()
} else {
sortedCarets.associateWith { textData }
}
val caretToPutData = caretToTextData.mapValues { (caret, textData) ->
getPutDataForCaret(textData, caret, caretsAndSelections[caret], count)
}
injector.registerGroup.resetRegister()
var result = true
injector.application.runWriteAction {
@ -51,18 +65,8 @@ sealed class PutVisualTextBaseAction(
}
return result
}
private fun getPutDataForCaret(caret: VimCaret, selection: VimSelection?, count: Int): PutData {
val lastRegisterChar = injector.registerGroup.lastRegisterChar
val register = caret.registerStorage.getRegister(lastRegisterChar)
val textData = register?.let {
PutData.TextData(
register.text ?: injector.parser.toPrintableString(register.keys),
register.type,
register.transferableData,
register.name,
)
}
private fun getPutDataForCaret(textData: PutData.TextData?, caret: VimCaret, selection: VimSelection?, count: Int): PutData {
val visualSelection = selection?.let { PutData.VisualSelection(mapOf(caret to it), it.type) }
return PutData(textData, visualSelection, count, insertTextBeforeCaret, indent, caretAfterInsertedText)
}

View File

@ -9,20 +9,16 @@
package com.maddyhome.idea.vim.api
import com.maddyhome.idea.vim.common.LiveRange
import com.maddyhome.idea.vim.common.TextRange
import com.maddyhome.idea.vim.group.visual.VisualChange
import com.maddyhome.idea.vim.group.visual.vimMoveBlockSelectionToOffset
import com.maddyhome.idea.vim.group.visual.vimMoveSelectionToCaret
import com.maddyhome.idea.vim.handler.Motion
import com.maddyhome.idea.vim.helper.StrictMode
import com.maddyhome.idea.vim.helper.exitVisualMode
import com.maddyhome.idea.vim.register.Register
import com.maddyhome.idea.vim.state.mode.SelectionType
import com.maddyhome.idea.vim.state.mode.inBlockSelection
import com.maddyhome.idea.vim.state.mode.inCommandLineMode
import com.maddyhome.idea.vim.state.mode.inSelectMode
import com.maddyhome.idea.vim.state.mode.inVisualMode
import javax.swing.KeyStroke
/**
* Immutable interface of the caret. Immutable caret is an important concept of Fleet.
@ -61,7 +57,6 @@ interface ImmutableVimCaret {
fun hasSelection(): Boolean
var lastSelectionInfo: SelectionInfo
val registerStorage: CaretRegisterStorage
val markStorage: LocalMarkStorage
}
@ -147,21 +142,3 @@ fun VimCaret.moveToMotion(motion: Motion): VimCaret {
this
}
}
interface CaretRegisterStorage {
val caret: ImmutableVimCaret
/**
* Stores text to caret's recordable (named/numbered/unnamed) register
*/
fun storeText(editor: VimEditor, range: TextRange, type: SelectionType, isDelete: Boolean): Boolean
/**
* Gets text from caret's recordable register
* If the register is not recordable - global text state will be returned
*/
fun getRegister(r: Char): Register?
fun setKeys(register: Char, keys: List<KeyStroke>)
fun saveRegister(r: Char, register: Register)
}

View File

@ -8,75 +8,4 @@
package com.maddyhome.idea.vim.api
import com.maddyhome.idea.vim.state.mode.SelectionType
import com.maddyhome.idea.vim.common.TextRange
import com.maddyhome.idea.vim.register.Register
import com.maddyhome.idea.vim.register.RegisterConstants
import com.maddyhome.idea.vim.register.VimRegisterGroupBase
import javax.swing.KeyStroke
abstract class VimCaretBase : VimCaret
open class CaretRegisterStorageBase(override var caret: ImmutableVimCaret) : CaretRegisterStorage, VimRegisterGroupBase() {
companion object {
private const val ALLOWED_TO_STORE_REGISTERS = RegisterConstants.RECORDABLE_REGISTERS +
RegisterConstants.SMALL_DELETION_REGISTER +
RegisterConstants.BLACK_HOLE_REGISTER +
RegisterConstants.LAST_INSERTED_TEXT_REGISTER +
RegisterConstants.LAST_SEARCH_REGISTER
}
override var lastRegisterChar: Char
get() {
return injector.registerGroup.lastRegisterChar
}
set(_) {}
override var isRegisterSpecifiedExplicitly: Boolean
get() {
return injector.registerGroup.isRegisterSpecifiedExplicitly
}
set(_) {}
override fun storeText(editor: VimEditor, range: TextRange, type: SelectionType, isDelete: Boolean): Boolean {
val registerChar = if (caret.editor.carets().size == 1) currentRegister else getCurrentRegisterForMulticaret()
if (caret.isPrimary) {
val registerService = injector.registerGroup
registerService.lastRegisterChar = registerChar
return registerService.storeText(editor, caret, range, type, isDelete)
} else {
if (!ALLOWED_TO_STORE_REGISTERS.contains(registerChar)) {
return false
}
val text = preprocessTextBeforeStoring(editor.getText(range), type)
return storeTextInternal(editor, caret, range, text, type, registerChar, isDelete)
}
}
override fun getRegister(r: Char): Register? {
if (caret.isPrimary || !RegisterConstants.RECORDABLE_REGISTERS.contains(r)) {
return injector.registerGroup.getRegister(r)
}
return super.getRegister(r) ?: injector.registerGroup.getRegister(r)
}
override fun setKeys(register: Char, keys: List<KeyStroke>) {
if (caret.isPrimary) {
injector.registerGroup.setKeys(register, keys)
}
if (!RegisterConstants.RECORDABLE_REGISTERS.contains(register)) {
return
}
return super.setKeys(register, keys)
}
override fun saveRegister(r: Char, register: Register) {
if (caret.isPrimary) {
injector.registerGroup.saveRegister(r, register)
}
if (!RegisterConstants.RECORDABLE_REGISTERS.contains(r)) {
return
}
return super.saveRegister(r, register)
}
}

View File

@ -172,7 +172,7 @@ abstract class VimChangeGroupBase : VimChangeGroup {
if (type == null ||
(mode == Mode.INSERT || mode == Mode.REPLACE) ||
!saveToRegister ||
caret.registerStorage.storeText(editor, updatedRange, type, true)
injector.registerGroup.storeText(editor, updatedRange, type, true, !editor.isFirstCaret, editor.isReversingCarets)
) {
val startOffsets = updatedRange.startOffsets
val endOffsets = updatedRange.endOffsets

View File

@ -188,7 +188,8 @@ interface VimEditor {
* This method should perform caret merging after the operations. This is similar to IJ runForEachCaret
* TODO review
*/
val isFirstCaret: Boolean
val isReversingCarets: Boolean
fun forEachCaret(action: (VimCaret) -> Unit)
fun forEachNativeCaret(action: (VimCaret) -> Unit, reverse: Boolean = false)
fun isInForEachCaretScope(): Boolean
@ -349,4 +350,4 @@ interface VimFoldRegion {
var isExpanded: Boolean
val startOffset: Int
val endOffset: Int
}
}

View File

@ -612,7 +612,13 @@ class VimRegex(pattern: String) {
override fun carets(): List<VimCaret> = emptyList()
override fun nativeCarets(): List<VimCaret> = emptyList()
override val isFirstCaret: Boolean
get() = false
override val isReversingCarets: Boolean
get() = false
override fun forEachCaret(action: (VimCaret) -> Unit) {}
override fun forEachNativeCaret(action: (VimCaret) -> Unit, reverse: Boolean) {}

View File

@ -75,6 +75,11 @@ class Register {
addKeys(injector.parser.stringToKeys(text))
transferableData.clear()
}
fun prependTextAndResetTransferableData(text: String) {
this.keys.addAll(0, injector.parser.stringToKeys(text))
transferableData.clear()
}
fun addKeys(keys: List<KeyStroke>) {
this.keys.addAll(keys)

View File

@ -7,10 +7,9 @@
*/
package com.maddyhome.idea.vim.register
import com.maddyhome.idea.vim.api.ImmutableVimCaret
import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.state.mode.SelectionType
import com.maddyhome.idea.vim.common.TextRange
import com.maddyhome.idea.vim.state.mode.SelectionType
import org.jetbrains.annotations.TestOnly
import javax.swing.KeyStroke
@ -48,10 +47,11 @@ interface VimRegisterGroup {
/** Store text into the last register. */
fun storeText(
editor: VimEditor,
caret: ImmutableVimCaret,
range: TextRange,
type: SelectionType,
isDelete: Boolean,
forceAppend: Boolean = false,
prependInsteadOfAppend: Boolean = false
): Boolean
/**

View File

@ -8,7 +8,6 @@
package com.maddyhome.idea.vim.register
import com.maddyhome.idea.vim.api.ImmutableVimCaret
import com.maddyhome.idea.vim.api.Options
import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.api.getText
@ -171,12 +170,13 @@ abstract class VimRegisterGroupBase : VimRegisterGroup {
fun storeTextInternal(
editor: VimEditor,
caret: ImmutableVimCaret,
range: TextRange,
text: String,
type: SelectionType,
register: Char,
isDelete: Boolean,
forceAppend: Boolean,
prependInsteadOfAppend: Boolean,
): Boolean {
// Null register doesn't get saved, but acts like it was
if (lastRegisterChar == BLACK_HOLE_REGISTER) return true
@ -198,18 +198,29 @@ abstract class VimRegisterGroupBase : VimRegisterGroup {
// If this is an uppercase register, we need to append the text to the corresponding lowercase register
val transferableData: List<Any> =
if (start != -1) injector.clipboardManager.getTransferableData(editor, range, text) else ArrayList()
val processedText =
var processedText =
if (start != -1) injector.clipboardManager.preprocessText(editor, range, text, transferableData) else text
logger.debug {
val transferableClasses = transferableData.joinToString(",") { it.javaClass.name }
"Copy to '$lastRegister' with transferable data: $transferableClasses"
}
if (Character.isUpperCase(register)) {
if (Character.isUpperCase(register) || forceAppend) {
if (forceAppend && type == SelectionType.CHARACTER_WISE) {
processedText = if (prependInsteadOfAppend)
processedText + '\n'
else
'\n' + processedText
}
val lreg = Character.toLowerCase(register)
val r = myRegisters[lreg]
// Append the text if the lowercase register existed
if (r != null) {
r.addTextAndResetTransferableData(processedText)
if (prependInsteadOfAppend) {
r.prependTextAndResetTransferableData(processedText)
}
else {
r.addTextAndResetTransferableData(processedText)
}
} else {
myRegisters[lreg] = Register(lreg, type, processedText, ArrayList(transferableData))
logger.debug { "register '$register' contains: \"$processedText\"" }
@ -290,14 +301,15 @@ abstract class VimRegisterGroupBase : VimRegisterGroup {
*/
override fun storeText(
editor: VimEditor,
caret: ImmutableVimCaret,
range: TextRange,
type: SelectionType,
isDelete: Boolean,
forceAppend: Boolean,
prependInsteadOfAppend: Boolean
): Boolean {
if (isRegisterWritable()) {
val text = preprocessTextBeforeStoring(editor.getText(range), type)
return storeTextInternal(editor, caret, range, text, type, lastRegisterChar, isDelete)
return storeTextInternal(editor, range, text, type, lastRegisterChar, isDelete, forceAppend, prependInsteadOfAppend)
}
return false

View File

@ -10,7 +10,6 @@ package com.maddyhome.idea.vim.yank
import com.maddyhome.idea.vim.action.motion.updown.MotionDownLess1FirstNonSpaceAction
import com.maddyhome.idea.vim.api.ExecutionContext
import com.maddyhome.idea.vim.api.ImmutableVimCaret
import com.maddyhome.idea.vim.api.VimCaret
import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.api.getLineEndForOffset
@ -18,9 +17,9 @@ import com.maddyhome.idea.vim.api.getLineStartForOffset
import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.command.Argument
import com.maddyhome.idea.vim.command.OperatorArguments
import com.maddyhome.idea.vim.state.mode.SelectionType
import com.maddyhome.idea.vim.common.TextRange
import com.maddyhome.idea.vim.listener.VimYankListener
import com.maddyhome.idea.vim.state.mode.SelectionType
import org.jetbrains.annotations.Contract
import kotlin.math.min
@ -29,7 +28,6 @@ open class YankGroupBase : VimYankGroup {
private fun yankRange(
editor: VimEditor,
caretToRange: Map<ImmutableVimCaret, TextRange>,
range: TextRange,
type: SelectionType,
startOffsets: Map<VimCaret, Int>?,
@ -39,12 +37,7 @@ open class YankGroupBase : VimYankGroup {
}
notifyListeners(editor, range)
var result = true
for ((caret, myRange) in caretToRange) {
result = caret.registerStorage.storeText(editor, myRange, type, false) && result
}
return result
return injector.registerGroup.storeText(editor, range, type, false)
}
@Contract("_, _ -> new")
@ -89,7 +82,6 @@ open class YankGroupBase : VimYankGroup {
val nativeCaretCount = editor.nativeCarets().size
if (nativeCaretCount <= 0) return false
val caretToRange = HashMap<ImmutableVimCaret, TextRange>(nativeCaretCount)
val ranges = ArrayList<Pair<Int, Int>>(nativeCaretCount)
// This logic is from original vim
@ -102,7 +94,6 @@ open class YankGroupBase : VimYankGroup {
assert(motionRange.size() == 1)
ranges.add(motionRange.startOffset to motionRange.endOffset)
startOffsets?.put(caret, motionRange.normalize().startOffset)
caretToRange[caret] = TextRange(motionRange.startOffset, motionRange.endOffset)
}
val range = getTextRange(ranges, type) ?: return false
@ -111,7 +102,6 @@ open class YankGroupBase : VimYankGroup {
return yankRange(
editor,
caretToRange,
range,
type,
startOffsets,
@ -128,7 +118,6 @@ open class YankGroupBase : VimYankGroup {
override fun yankLine(editor: VimEditor, count: Int): Boolean {
val caretCount = editor.nativeCarets().size
val ranges = ArrayList<Pair<Int, Int>>(caretCount)
val caretToRange = HashMap<ImmutableVimCaret, TextRange>(caretCount)
for (caret in editor.nativeCarets()) {
val start = injector.motion.moveCaretToCurrentLineStart(editor, caret)
val end = min(injector.motion.moveCaretToRelativeLineEnd(editor, caret, count - 1, true) + 1, editor.fileSize().toInt())
@ -136,11 +125,10 @@ open class YankGroupBase : VimYankGroup {
if (end == -1) continue
ranges.add(start to end)
caretToRange[caret] = TextRange(start, end)
}
val range = getTextRange(ranges, SelectionType.LINE_WISE) ?: return false
return yankRange(editor, caretToRange, range, SelectionType.LINE_WISE, null)
return yankRange(editor, range, SelectionType.LINE_WISE, null)
}
/**
@ -153,7 +141,6 @@ open class YankGroupBase : VimYankGroup {
*/
override fun yankRange(editor: VimEditor, range: TextRange?, type: SelectionType, moveCursor: Boolean): Boolean {
range ?: return false
val caretToRange = HashMap<ImmutableVimCaret, TextRange>()
if (type == SelectionType.LINE_WISE) {
for (i in 0 until range.size()) {
@ -173,19 +160,17 @@ open class YankGroupBase : VimYankGroup {
val startOffsets = HashMap<VimCaret, Int>(editor.nativeCarets().size)
if (type == SelectionType.BLOCK_WISE) {
startOffsets[editor.primaryCaret()] = range.normalize().startOffset
caretToRange[editor.primaryCaret()] = range
} else {
for ((i, caret) in editor.nativeCarets().withIndex()) {
val textRange = TextRange(rangeStartOffsets[i], rangeEndOffsets[i])
startOffsets[caret] = textRange.normalize().startOffset
caretToRange[caret] = textRange
}
}
return if (moveCursor) {
yankRange(editor, caretToRange, range, type, startOffsets)
yankRange(editor, range, type, startOffsets)
} else {
yankRange(editor, caretToRange, range, type, null)
yankRange(editor, range, type, null)
}
}