diff --git a/src/main/java/com/maddyhome/idea/vim/extension/surround/VimSurroundExtension.kt b/src/main/java/com/maddyhome/idea/vim/extension/surround/VimSurroundExtension.kt index 335c06947..f13128548 100644 --- a/src/main/java/com/maddyhome/idea/vim/extension/surround/VimSurroundExtension.kt +++ b/src/main/java/com/maddyhome/idea/vim/extension/surround/VimSurroundExtension.kt @@ -176,7 +176,9 @@ internal class VimSurroundExtension : VimExtension { val currentSurrounding = getCurrentSurrounding(it.caret, pick(charFrom)) if (currentSurrounding != null) { it.caret.moveToOffset(currentSurrounding.startOffset) - editor.deleteString(currentSurrounding) + injector.application.runWriteAction { + editor.deleteString(currentSurrounding) + } } val registerValue = getRegisterForCaret(editor, context, REGISTER, it.caret) diff --git a/src/main/java/com/maddyhome/idea/vim/group/ChangeGroup.kt b/src/main/java/com/maddyhome/idea/vim/group/ChangeGroup.kt index 26380de23..1acf3da41 100644 --- a/src/main/java/com/maddyhome/idea/vim/group/ChangeGroup.kt +++ b/src/main/java/com/maddyhome/idea/vim/group/ChangeGroup.kt @@ -130,7 +130,9 @@ class ChangeGroup : VimChangeGroupBase() { val project = (editor as IjVimEditor).editor.project ?: return val file = PsiUtilBase.getPsiFileInEditor(editor.editor, project) ?: return val textRange = com.intellij.openapi.util.TextRange.create(start, end) - CodeStyleManager.getInstance(project).reformatText(file, listOf(textRange)) + injector.application.runWriteAction { + CodeStyleManager.getInstance(project).reformatText(file, listOf(textRange)) + } } override fun autoIndentRange( diff --git a/src/main/java/com/maddyhome/idea/vim/helper/RunnableHelper.kt b/src/main/java/com/maddyhome/idea/vim/helper/RunnableHelper.kt deleted file mode 100644 index 6299ff091..000000000 --- a/src/main/java/com/maddyhome/idea/vim/helper/RunnableHelper.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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.helper - -import com.intellij.openapi.application.ApplicationManager -import com.intellij.openapi.command.CommandProcessor -import com.intellij.openapi.diagnostic.debug -import com.intellij.openapi.diagnostic.logger -import com.intellij.openapi.project.Project - -/** - * This provides some helper methods to run code as a command and an application write action - */ -internal object RunnableHelper { - private val logger = logger<RunnableHelper>() - - @JvmStatic - fun runReadCommand(project: Project?, cmd: Runnable, name: String?, groupId: Any?) { - logger.debug { "Run read command: $name" } - CommandProcessor.getInstance() - .executeCommand(project, { ApplicationManager.getApplication().runReadAction(cmd) }, name, groupId) - } - - @JvmStatic - fun runWriteCommand(project: Project?, cmd: Runnable, name: String?, groupId: Any?) { - logger.debug { "Run write command: $name" } - CommandProcessor.getInstance() - .executeCommand(project, { ApplicationManager.getApplication().runWriteAction(cmd) }, name, groupId) - } -} diff --git a/src/main/java/com/maddyhome/idea/vim/newapi/IjVimApplication.kt b/src/main/java/com/maddyhome/idea/vim/newapi/IjVimApplication.kt index aa2805311..7fed24cd4 100644 --- a/src/main/java/com/maddyhome/idea/vim/newapi/IjVimApplication.kt +++ b/src/main/java/com/maddyhome/idea/vim/newapi/IjVimApplication.kt @@ -16,7 +16,6 @@ import com.intellij.util.ExceptionUtil import com.maddyhome.idea.vim.api.VimApplicationBase import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.diagnostic.vimLogger -import com.maddyhome.idea.vim.helper.RunnableHelper import java.awt.Component import java.awt.Toolkit import java.awt.Window @@ -58,14 +57,6 @@ internal class IjVimApplication : VimApplicationBase() { } } - override fun runWriteCommand(editor: VimEditor, name: String?, groupId: Any?, command: Runnable) { - RunnableHelper.runWriteCommand((editor as IjVimEditor).editor.project, command, name, groupId) - } - - override fun runReadCommand(editor: VimEditor, name: String?, groupId: Any?, command: Runnable) { - RunnableHelper.runReadCommand((editor as IjVimEditor).editor.project, command, name, groupId) - } - override fun <T> runWriteAction(action: () -> T): T { return ApplicationManager.getApplication().runWriteAction(Computable(action)) } diff --git a/src/test/java/org/jetbrains/plugins/ideavim/group/SearchGroupTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/group/SearchGroupTest.kt index 81ea45e7c..7f3a788e1 100644 --- a/src/test/java/org/jetbrains/plugins/ideavim/group/SearchGroupTest.kt +++ b/src/test/java/org/jetbrains/plugins/ideavim/group/SearchGroupTest.kt @@ -14,7 +14,6 @@ import com.intellij.openapi.util.Ref import com.maddyhome.idea.vim.VimPlugin import com.maddyhome.idea.vim.action.motion.search.SearchWholeWordForwardAction import com.maddyhome.idea.vim.common.Direction -import com.maddyhome.idea.vim.helper.RunnableHelper import com.maddyhome.idea.vim.newapi.vim import com.maddyhome.idea.vim.state.mode.Mode import com.maddyhome.idea.vim.state.mode.SelectionType @@ -913,21 +912,13 @@ class SearchGroupTest : VimTestCase() { private fun search(pattern: String, input: String): Int { configureByText(input) val editor = fixture.editor - val project = fixture.project val searchGroup = VimPlugin.getSearch() val ref = Ref.create(-1) ApplicationManager.getApplication().invokeAndWait { ApplicationManager.getApplication().runWriteIntentReadAction<Any, Throwable> { - RunnableHelper.runReadCommand( - project, - { - // Does not move the caret! - val n = searchGroup.processSearchCommand(editor.vim, pattern, fixture.caretOffset, 1, Direction.FORWARDS) - ref.set(n?.first ?: -1) - }, - null, - null, - ) + // Does not move the caret! + val n = searchGroup.processSearchCommand(editor.vim, pattern, fixture.caretOffset, 1, Direction.FORWARDS) + ref.set(n?.first ?: -1) } } return ref.get() diff --git a/src/testFixtures/kotlin/org/jetbrains/plugins/ideavim/VimTestCase.kt b/src/testFixtures/kotlin/org/jetbrains/plugins/ideavim/VimTestCase.kt index 1e157ba5a..448553b91 100644 --- a/src/testFixtures/kotlin/org/jetbrains/plugins/ideavim/VimTestCase.kt +++ b/src/testFixtures/kotlin/org/jetbrains/plugins/ideavim/VimTestCase.kt @@ -70,7 +70,6 @@ import com.maddyhome.idea.vim.group.IjOptions import com.maddyhome.idea.vim.group.visual.VimVisualTimer.swingTimer import com.maddyhome.idea.vim.handler.isOctopusEnabled import com.maddyhome.idea.vim.helper.EditorHelper -import com.maddyhome.idea.vim.helper.RunnableHelper.runWriteCommand import com.maddyhome.idea.vim.helper.TestInputModel import com.maddyhome.idea.vim.helper.getGuiCursorMode import com.maddyhome.idea.vim.key.MappingOwner @@ -1063,8 +1062,8 @@ abstract class VimTestCase { val keyHandler = KeyHandler.getInstance() val dataContext = injector.executionContextManager.getEditorExecutionContext(editor.vim) TestInputModel.getInstance(editor).setKeyStrokes(keys.filterNotNull()) - runWriteCommand( - project, + injector.actionExecutor.executeCommand( + editor.vim, Runnable { val inputModel = TestInputModel.getInstance(editor) var key = inputModel.nextKeyStroke() diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/KeyHandler.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/KeyHandler.kt index 1f1080f25..0c5f89b9a 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/KeyHandler.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/KeyHandler.kt @@ -245,13 +245,7 @@ class KeyHandler { val action: Runnable = ActionRunner(editor, context, command, keyState, operatorArguments) val cmdAction = command.action val name = cmdAction.id - if (type.isWrite) { - injector.application.runWriteCommand(editor, name, action, action) - } else if (type.isRead) { - injector.application.runReadCommand(editor, name, action, action) - } else { - injector.actionExecutor.executeCommand(editor, action, name, action) - } + injector.actionExecutor.executeCommand(editor, action, name, action) } } diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/change/insert/InsertCharacterAroundCursorAction.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/change/insert/InsertCharacterAroundCursorAction.kt index 439c41de8..212f364a5 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/change/insert/InsertCharacterAroundCursorAction.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/change/insert/InsertCharacterAroundCursorAction.kt @@ -79,7 +79,9 @@ private fun insertCharacterAroundCursor(editor: VimEditor, caret: VimCaret, dir: val charsSequence = editor.text() if (offset < charsSequence.length) { val ch = charsSequence[offset] - (editor as MutableVimEditor).insertText(caret, caret.offset, ch.toString()) + injector.application.runWriteAction { + (editor as MutableVimEditor).insertText(caret, caret.offset, ch.toString()) + } caret.moveToMotion(injector.motion.getHorizontalMotion(editor, caret, 1, true)) res = true } diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimApplication.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimApplication.kt index 4bf9f4881..147a919ee 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimApplication.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimApplication.kt @@ -18,9 +18,6 @@ interface VimApplication { fun isInternal(): Boolean fun postKey(stroke: KeyStroke, editor: VimEditor) - fun runWriteCommand(editor: VimEditor, name: String?, groupId: Any?, command: Runnable) - fun runReadCommand(editor: VimEditor, name: String?, groupId: Any?, command: Runnable) - fun <T> runWriteAction(action: () -> T): T fun <T> runReadAction(action: () -> T): T diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimChangeGroupBase.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimChangeGroupBase.kt index 7a5836450..5781cfa97 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimChangeGroupBase.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimChangeGroupBase.kt @@ -197,7 +197,9 @@ abstract class VimChangeGroupBase : VimChangeGroup { editor, LineDeleteShift.NL_ON_END ) ?: continue - editor.deleteString(TextRange(newRange.first, newRange.second)) + injector.application.runWriteAction { + editor.deleteString(TextRange(newRange.first, newRange.second)) + } } if (type != null) { val start = updatedRange.startOffset @@ -215,7 +217,9 @@ abstract class VimChangeGroupBase : VimChangeGroup { * @param str The text to insert */ override fun insertText(editor: VimEditor, caret: VimCaret, offset: Int, str: String): VimCaret { - (editor as MutableVimEditor).insertText(caret, offset, str) + injector.application.runWriteAction { + (editor as MutableVimEditor).insertText(caret, offset, str) + } val newCaret = caret.moveToInlayAwareOffset(offset + str.length) injector.markService.setMark(newCaret, MARK_CHANGE_POS, offset) @@ -1003,7 +1007,9 @@ abstract class VimChangeGroupBase : VimChangeGroup { var processedCaret = editor.findLastVersionOfCaret(caret) ?: caret if (removeLastNewLine) { val textLength = editor.fileSize().toInt() - editor.deleteString(TextRange(textLength - 1, textLength)) + injector.application.runWriteAction { + editor.deleteString(TextRange(textLength - 1, textLength)) + } processedCaret = editor.findLastVersionOfCaret(caret) ?: caret } @@ -1189,7 +1195,9 @@ abstract class VimChangeGroupBase : VimChangeGroup { * @param str The new text */ override fun replaceText(editor: VimEditor, caret: VimCaret, start: Int, end: Int, str: String) { - (editor as MutableVimEditor).replaceString(start, end, str) + injector.application.runWriteAction { + (editor as MutableVimEditor).replaceString(start, end, str) + } val newEnd = start + str.length injector.markService.setChangeMarks(caret, TextRange(start, newEnd)) diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimEditor.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimEditor.kt index e0da3b899..a0918f44d 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimEditor.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimEditor.kt @@ -11,6 +11,7 @@ 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.common.VimEditorReplaceMask +import com.maddyhome.idea.vim.helper.RWLockLabel import com.maddyhome.idea.vim.state.mode.Mode import com.maddyhome.idea.vim.state.mode.SelectionType @@ -152,6 +153,7 @@ interface VimEditor { } fun getVirtualFile(): VirtualFile? + @RWLockLabel.Writable fun deleteString(range: TextRange) fun getLineText(line: Int): String { @@ -241,7 +243,9 @@ interface VimEditor { interface MutableVimEditor : VimEditor { fun addLine(atPosition: Int): Int? + @RWLockLabel.Writable fun insertText(caret: VimCaret, atPosition: Int, text: CharSequence) + @RWLockLabel.Writable fun replaceString(start: Int, end: Int, newString: String) } diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimSearchGroupBase.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimSearchGroupBase.kt index 967d31307..b0b09237c 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimSearchGroupBase.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimSearchGroupBase.kt @@ -903,7 +903,7 @@ abstract class VimSearchGroupBase : VimSearchGroup { } override fun executeInput(input: ReplaceConfirmationChoice, editor: VimEditor, context: ExecutionContext) { - injector.application.runWriteCommand(editor, "substitute-with-confirmation", modalInput) { + injector.actionExecutor.executeCommand(editor, { highlight.remove() injector.jumpService.saveJumpLocation(editor) val matchRange = nextSubstitute.first.range @@ -931,7 +931,7 @@ abstract class VimSearchGroupBase : VimSearchGroup { options ) closeModalInputPrompt() - return@runWriteCommand + return@executeCommand } ReplaceConfirmationChoice.QUIT -> { @@ -965,7 +965,7 @@ abstract class VimSearchGroupBase : VimSearchGroup { column = replaceResult.column goToNextIteration() - } + }, "substitute-with-confirmation", modalInput) } private fun goToNextIteration() { diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/stubs/VimApplicationStub.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/stubs/VimApplicationStub.kt index b7187637e..8f26d6db0 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/stubs/VimApplicationStub.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/stubs/VimApplicationStub.kt @@ -42,14 +42,6 @@ class VimApplicationStub : VimApplicationBase() { TODO("Not yet implemented") } - override fun runWriteCommand(editor: VimEditor, name: String?, groupId: Any?, command: Runnable) { - TODO("Not yet implemented") - } - - override fun runReadCommand(editor: VimEditor, name: String?, groupId: Any?, command: Runnable) { - TODO("Not yet implemented") - } - override fun <T> runWriteAction(action: () -> T): T { TODO("Not yet implemented") } diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/command/Command.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/command/Command.kt index ca13d2539..db709c900 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/command/Command.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/command/Command.kt @@ -96,12 +96,11 @@ data class Command( MODE_CHANGE, ; - val isRead: Boolean - get() = when (this) { - MOTION, COPY, OTHER_READONLY, MODE_CHANGE -> true - else -> false - } - + /** + * Deprecated because not only this set of commands can be writable. + * A different way of detecting if a command is going to write something is needed. + */ + @Deprecated("") val isWrite: Boolean get() = when (this) { INSERT, DELETE, CHANGE, PASTE, OTHER_WRITABLE -> true diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/commands/MoveTextCommand.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/commands/MoveTextCommand.kt index f4daccdeb..d5777b219 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/commands/MoveTextCommand.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/commands/MoveTextCommand.kt @@ -93,7 +93,9 @@ data class MoveTextCommand(val range: Range, val modifier: CommandModifier, val val dropNewLineInEnd = (line + linesMoved == editor.lineCount() - 1 && text.last() == '\n') || (lineRange.endLine == editor.lineCount() - 1) - editor.deleteString(range) + injector.application.runWriteAction { + editor.deleteString(range) + } val putData = if (line == -1) { // Special case. Move text to below the line before the first line caret.moveToOffset(0) @@ -113,7 +115,9 @@ data class MoveTextCommand(val range: Range, val modifier: CommandModifier, val if (dropNewLineInEnd) { assert(editor.text().last() == '\n') - editor.deleteString(TextRange(editor.text().length - 1, editor.text().length)) + injector.application.runWriteAction { + editor.deleteString(TextRange(editor.text().length - 1, editor.text().length)) + } } globalMarks.forEach { shiftGlobalMark(editor, it, shift) }