mirror of
https://github.com/chylex/IntelliJ-IdeaVim.git
synced 2025-06-05 22:34:03 +02:00
Fix(VIM-3376): Refactor the way IdeaVim executes actions
Now instead of a few hacks, we use a special function from the platform
This commit is contained in:
parent
ff44596c1a
commit
24514039e1
.teamcity/_Self
gradle.propertiessrc
main/java/com/maddyhome/idea/vim
test/java/org/jetbrains/plugins/ideavim/action
16
.teamcity/_Self/Constants.kt
vendored
16
.teamcity/_Self/Constants.kt
vendored
@ -5,13 +5,13 @@ object Constants {
|
|||||||
const val EAP_CHANNEL = "eap"
|
const val EAP_CHANNEL = "eap"
|
||||||
const val DEV_CHANNEL = "Dev"
|
const val DEV_CHANNEL = "Dev"
|
||||||
|
|
||||||
const val GITHUB_TESTS = "2024.1.1"
|
const val GITHUB_TESTS = "2024.1.2"
|
||||||
const val NVIM_TESTS = "2024.1.1"
|
const val NVIM_TESTS = "2024.1.2"
|
||||||
const val PROPERTY_TESTS = "2024.1.1"
|
const val PROPERTY_TESTS = "2024.1.2"
|
||||||
const val LONG_RUNNING_TESTS = "2024.1.1"
|
const val LONG_RUNNING_TESTS = "2024.1.2"
|
||||||
const val QODANA_TESTS = "2024.1.1"
|
const val QODANA_TESTS = "2024.1.2"
|
||||||
const val RELEASE = "2024.1.1"
|
const val RELEASE = "2024.1.2"
|
||||||
|
|
||||||
const val RELEASE_DEV = "2024.1.1"
|
const val RELEASE_DEV = "2024.1.2"
|
||||||
const val RELEASE_EAP = "2024.1.1"
|
const val RELEASE_EAP = "2024.1.2"
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
# https://data.services.jetbrains.com/products?code=IC
|
# https://data.services.jetbrains.com/products?code=IC
|
||||||
# Maven releases are here: https://www.jetbrains.com/intellij-repository/releases
|
# Maven releases are here: https://www.jetbrains.com/intellij-repository/releases
|
||||||
# And snapshots: https://www.jetbrains.com/intellij-repository/snapshots
|
# And snapshots: https://www.jetbrains.com/intellij-repository/snapshots
|
||||||
ideaVersion=2024.1.1
|
ideaVersion=2024.1.2
|
||||||
# Values for type: https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#intellij-extension-type
|
# Values for type: https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#intellij-extension-type
|
||||||
ideaType=IC
|
ideaType=IC
|
||||||
instrumentPluginCode=true
|
instrumentPluginCode=true
|
||||||
|
@ -36,6 +36,7 @@ import com.maddyhome.idea.vim.helper.isPrimaryEditor
|
|||||||
import com.maddyhome.idea.vim.helper.updateCaretsVisualAttributes
|
import com.maddyhome.idea.vim.helper.updateCaretsVisualAttributes
|
||||||
import com.maddyhome.idea.vim.newapi.actionStartedFromVim
|
import com.maddyhome.idea.vim.newapi.actionStartedFromVim
|
||||||
import com.maddyhome.idea.vim.newapi.globalIjOptions
|
import com.maddyhome.idea.vim.newapi.globalIjOptions
|
||||||
|
import com.maddyhome.idea.vim.newapi.runningIJAction
|
||||||
import com.maddyhome.idea.vim.newapi.vim
|
import com.maddyhome.idea.vim.newapi.vim
|
||||||
import com.maddyhome.idea.vim.state.mode.Mode
|
import com.maddyhome.idea.vim.state.mode.Mode
|
||||||
import java.awt.event.KeyEvent
|
import java.awt.event.KeyEvent
|
||||||
@ -164,6 +165,7 @@ internal abstract class OctopusHandler(private val nextHandler: EditorActionHand
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dataContext?.actionStartedFromVim == true) return true
|
if (dataContext?.actionStartedFromVim == true) return true
|
||||||
|
if (runningIJAction) return true
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
package com.maddyhome.idea.vim.helper
|
package com.maddyhome.idea.vim.helper
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.ActionGroup
|
|
||||||
import com.intellij.openapi.actionSystem.ActionManager
|
import com.intellij.openapi.actionSystem.ActionManager
|
||||||
import com.intellij.openapi.actionSystem.ActionPlaces
|
import com.intellij.openapi.actionSystem.ActionPlaces
|
||||||
import com.intellij.openapi.actionSystem.AnAction
|
import com.intellij.openapi.actionSystem.AnAction
|
||||||
@ -17,6 +16,7 @@ import com.intellij.openapi.actionSystem.AnActionResult
|
|||||||
import com.intellij.openapi.actionSystem.DataContextWrapper
|
import com.intellij.openapi.actionSystem.DataContextWrapper
|
||||||
import com.intellij.openapi.actionSystem.EmptyAction
|
import com.intellij.openapi.actionSystem.EmptyAction
|
||||||
import com.intellij.openapi.actionSystem.IdeActions
|
import com.intellij.openapi.actionSystem.IdeActions
|
||||||
|
import com.intellij.openapi.actionSystem.PlatformCoreDataKeys
|
||||||
import com.intellij.openapi.actionSystem.PlatformDataKeys
|
import com.intellij.openapi.actionSystem.PlatformDataKeys
|
||||||
import com.intellij.openapi.actionSystem.ex.ActionManagerEx
|
import com.intellij.openapi.actionSystem.ex.ActionManagerEx
|
||||||
import com.intellij.openapi.actionSystem.ex.ActionUtil
|
import com.intellij.openapi.actionSystem.ex.ActionUtil
|
||||||
@ -24,10 +24,13 @@ import com.intellij.openapi.actionSystem.impl.ProxyShortcutSet
|
|||||||
import com.intellij.openapi.command.CommandProcessor
|
import com.intellij.openapi.command.CommandProcessor
|
||||||
import com.intellij.openapi.command.UndoConfirmationPolicy
|
import com.intellij.openapi.command.UndoConfirmationPolicy
|
||||||
import com.intellij.openapi.components.Service
|
import com.intellij.openapi.components.Service
|
||||||
|
import com.intellij.openapi.diagnostic.logger
|
||||||
import com.intellij.openapi.editor.actionSystem.DocCommandGroupId
|
import com.intellij.openapi.editor.actionSystem.DocCommandGroupId
|
||||||
import com.intellij.openapi.project.IndexNotReadyException
|
import com.intellij.openapi.project.IndexNotReadyException
|
||||||
import com.intellij.openapi.ui.popup.JBPopupFactory
|
import com.intellij.openapi.util.ActionCallback
|
||||||
import com.intellij.openapi.util.NlsContexts
|
import com.intellij.openapi.util.NlsContexts
|
||||||
|
import com.intellij.openapi.util.await
|
||||||
|
import com.intellij.openapi.util.registry.Registry
|
||||||
import com.intellij.util.SlowOperations
|
import com.intellij.util.SlowOperations
|
||||||
import com.maddyhome.idea.vim.RegisterActions
|
import com.maddyhome.idea.vim.RegisterActions
|
||||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||||
@ -39,10 +42,11 @@ import com.maddyhome.idea.vim.handler.EditorActionHandlerBase
|
|||||||
import com.maddyhome.idea.vim.newapi.IjNativeAction
|
import com.maddyhome.idea.vim.newapi.IjNativeAction
|
||||||
import com.maddyhome.idea.vim.newapi.ij
|
import com.maddyhome.idea.vim.newapi.ij
|
||||||
import com.maddyhome.idea.vim.newapi.runFromVimKey
|
import com.maddyhome.idea.vim.newapi.runFromVimKey
|
||||||
|
import com.maddyhome.idea.vim.newapi.runningIJAction
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.jetbrains.annotations.NonNls
|
import org.jetbrains.annotations.NonNls
|
||||||
import java.awt.Component
|
import java.awt.Component
|
||||||
import javax.swing.JComponent
|
import javax.swing.JComponent
|
||||||
import javax.swing.SwingUtilities
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
internal class IjActionExecutor : VimActionExecutor {
|
internal class IjActionExecutor : VimActionExecutor {
|
||||||
@ -77,45 +81,54 @@ internal class IjActionExecutor : VimActionExecutor {
|
|||||||
val dataContext = DataContextWrapper(context.ij)
|
val dataContext = DataContextWrapper(context.ij)
|
||||||
dataContext.putUserData(runFromVimKey, true)
|
dataContext.putUserData(runFromVimKey, true)
|
||||||
|
|
||||||
val actionId = ActionManager.getInstance().getId(ijAction)
|
val contextComponent = PlatformCoreDataKeys.CONTEXT_COMPONENT.getData(dataContext)
|
||||||
val event = AnActionEvent(
|
?: editor?.ij?.component ?: run {
|
||||||
null,
|
LOG.error("Can't get the context component")
|
||||||
dataContext,
|
return false
|
||||||
ActionPlaces.KEYBOARD_SHORTCUT,
|
|
||||||
ijAction.templatePresentation.clone(),
|
|
||||||
ActionManager.getInstance(),
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
// beforeActionPerformedUpdate should be called to update the action. It fixes some rider-specific problems.
|
|
||||||
// because rider use async update method. See VIM-1819.
|
|
||||||
// This method executes inside of lastUpdateAndCheckDumb
|
|
||||||
// Another related issue: VIM-2604
|
|
||||||
|
|
||||||
// This is a hack to fix the tests and fix VIM-3332
|
|
||||||
// We should get rid of it in VIM-3376
|
|
||||||
if (actionId == "RunClass" || actionId == IdeActions.ACTION_COMMENT_LINE || actionId == IdeActions.ACTION_COMMENT_BLOCK) {
|
|
||||||
ijAction.beforeActionPerformedUpdate(event)
|
|
||||||
if (!event.presentation.isEnabled) return false
|
|
||||||
} else {
|
|
||||||
if (!ActionUtil.lastUpdateAndCheckDumb(ijAction, event, false)) return false
|
|
||||||
}
|
|
||||||
if (ijAction is ActionGroup && !event.presentation.isPerformGroup) {
|
|
||||||
// Some ActionGroups should not be performed, but shown as a popup
|
|
||||||
val popup = JBPopupFactory.getInstance()
|
|
||||||
.createActionGroupPopup(event.presentation.text, ijAction, dataContext, false, null, -1)
|
|
||||||
val component = dataContext.getData(PlatformDataKeys.CONTEXT_COMPONENT)
|
|
||||||
if (component != null) {
|
|
||||||
val window = SwingUtilities.getWindowAncestor(component)
|
|
||||||
if (window != null) {
|
|
||||||
popup.showInCenterOf(window)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
popup.showInFocusCenter()
|
|
||||||
return true
|
val result = withRunningAction {
|
||||||
} else {
|
val result = withStringRegistryOption {
|
||||||
performDumbAwareWithCallbacks(ijAction, event) { ijAction.actionPerformed(event) }
|
ActionManager.getInstance()
|
||||||
return true
|
.tryToExecute(ijAction, null, contextComponent, ActionPlaces.KEYBOARD_SHORTCUT, true)
|
||||||
|
}
|
||||||
|
result.wait()
|
||||||
|
}
|
||||||
|
return result.isDone
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <T> withRunningAction(block: () -> T): T {
|
||||||
|
runningIJAction = true
|
||||||
|
try {
|
||||||
|
return block()
|
||||||
|
} finally {
|
||||||
|
runningIJAction = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ActionCallback.wait(): ActionCallback {
|
||||||
|
runBlocking {
|
||||||
|
try {
|
||||||
|
await()
|
||||||
|
} catch (_: RuntimeException) {
|
||||||
|
// Nothing
|
||||||
|
// The exception happens when the action is rejected
|
||||||
|
// and the exception message explains the reason for rejection
|
||||||
|
// At the moment, we don't process this information
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("SameParameterValue")
|
||||||
|
private fun <T> withStringRegistryOption(block: () -> T): T {
|
||||||
|
val registry = Registry.get("actionSystem.update.beforeActionPerformedUpdate")
|
||||||
|
val oldValue = registry.asString()
|
||||||
|
registry.setValue("on")
|
||||||
|
try {
|
||||||
|
return block()
|
||||||
|
} finally {
|
||||||
|
registry.setValue(oldValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,4 +258,8 @@ internal class IjActionExecutor : VimActionExecutor {
|
|||||||
override fun getActionIdList(idPrefix: String): List<String> {
|
override fun getActionIdList(idPrefix: String): List<String> {
|
||||||
return ActionManager.getInstance().getActionIdList(idPrefix)
|
return ActionManager.getInstance().getActionIdList(idPrefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val LOG = logger<IjActionExecutor>()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,11 @@ internal open class IjEditorExecutionContext(override val context: DataContext)
|
|||||||
// This key is stored in data context when the action is started from vim
|
// This key is stored in data context when the action is started from vim
|
||||||
internal val runFromVimKey = Key.create<Boolean>("RunFromVim")
|
internal val runFromVimKey = Key.create<Boolean>("RunFromVim")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sometimes we can't rely on [runFromVimKey] because the data context is created after the execution
|
||||||
|
*/
|
||||||
|
internal var runningIJAction: Boolean = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the action with this data context was started from Vim
|
* Check if the action with this data context was started from Vim
|
||||||
*/
|
*/
|
||||||
|
@ -16,7 +16,6 @@ import org.jetbrains.plugins.ideavim.SkipNeovimReason
|
|||||||
import org.jetbrains.plugins.ideavim.TestWithoutNeovim
|
import org.jetbrains.plugins.ideavim.TestWithoutNeovim
|
||||||
import org.jetbrains.plugins.ideavim.VimBehaviorDiffers
|
import org.jetbrains.plugins.ideavim.VimBehaviorDiffers
|
||||||
import org.jetbrains.plugins.ideavim.VimTestCase
|
import org.jetbrains.plugins.ideavim.VimTestCase
|
||||||
import org.junit.jupiter.api.Disabled
|
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,7 +50,6 @@ class MotionActionTest : VimTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Disabled("VIM-3376")
|
|
||||||
fun testEscapeInCommand() {
|
fun testEscapeInCommand() {
|
||||||
val content = """
|
val content = """
|
||||||
on${c}e two
|
on${c}e two
|
||||||
|
@ -13,7 +13,6 @@ import org.jetbrains.plugins.ideavim.SkipNeovimReason
|
|||||||
import org.jetbrains.plugins.ideavim.TestWithoutNeovim
|
import org.jetbrains.plugins.ideavim.TestWithoutNeovim
|
||||||
import org.jetbrains.plugins.ideavim.VimBehaviorDiffers
|
import org.jetbrains.plugins.ideavim.VimBehaviorDiffers
|
||||||
import org.jetbrains.plugins.ideavim.VimTestCase
|
import org.jetbrains.plugins.ideavim.VimTestCase
|
||||||
import org.junit.jupiter.api.Disabled
|
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -74,7 +73,6 @@ class SelectKeyHandlerTest : VimTestCase() {
|
|||||||
|
|
||||||
@TestWithoutNeovim(SkipNeovimReason.SELECT_MODE)
|
@TestWithoutNeovim(SkipNeovimReason.SELECT_MODE)
|
||||||
@Test
|
@Test
|
||||||
@Disabled("VIM-3376")
|
|
||||||
fun `test char mode backspace`() {
|
fun `test char mode backspace`() {
|
||||||
this.doTest(
|
this.doTest(
|
||||||
listOf("gh", "<BS>"),
|
listOf("gh", "<BS>"),
|
||||||
@ -100,7 +98,6 @@ class SelectKeyHandlerTest : VimTestCase() {
|
|||||||
|
|
||||||
@TestWithoutNeovim(SkipNeovimReason.SELECT_MODE)
|
@TestWithoutNeovim(SkipNeovimReason.SELECT_MODE)
|
||||||
@Test
|
@Test
|
||||||
@Disabled("VIM-3376")
|
|
||||||
fun `test char mode delete`() {
|
fun `test char mode delete`() {
|
||||||
this.doTest(
|
this.doTest(
|
||||||
listOf("gh", "<DEL>"),
|
listOf("gh", "<DEL>"),
|
||||||
|
Loading…
Reference in New Issue
Block a user