1
0
mirror of https://github.com/chylex/IntelliJ-IdeaVim.git synced 2025-05-06 21:34:02 +02:00

Add more wrappings for read actions

This commit is contained in:
Alex Plate 2025-03-04 15:36:18 +02:00
parent 84df5451b3
commit f88a1cbe06
No known key found for this signature in database
GPG Key ID: 0B97153C8FFEC09F
7 changed files with 34 additions and 8 deletions
src/main/java/com/maddyhome/idea/vim
vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api

View File

@ -12,12 +12,14 @@ import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.diagnostic.trace
import com.intellij.openapi.editor.Editor
import com.intellij.util.concurrency.annotations.RequiresReadLock
import com.maddyhome.idea.vim.KeyHandler
import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.api.options
import com.maddyhome.idea.vim.group.visual.IdeaSelectionControl.controlNonVimSelectionChange
import com.maddyhome.idea.vim.group.visual.IdeaSelectionControl.predictMode
import com.maddyhome.idea.vim.helper.RWLockLabel
import com.maddyhome.idea.vim.helper.exitSelectMode
import com.maddyhome.idea.vim.helper.exitVisualMode
import com.maddyhome.idea.vim.helper.hasVisualSelection
@ -89,7 +91,8 @@ internal object IdeaSelectionControl {
editor.vim.mode = Mode.NORMAL()
activateMode(editor, chooseSelectionMode(editor, selectionSource, true))
val mode = injector.application.runReadAction { chooseSelectionMode(editor, selectionSource, true) }
activateMode(editor, mode)
} else {
logger.debug("None of carets have selection. State before adjustment: ${editor.vim.mode}")
if (editor.vim.inVisualMode) editor.vim.exitVisualMode()
@ -115,6 +118,8 @@ internal object IdeaSelectionControl {
* This method is created to improve user experience. It allows avoiding delay in some operations
* (because [controlNonVimSelectionChange] is not executed immediately)
*/
@RWLockLabel.Readonly
@RequiresReadLock
fun predictMode(editor: Editor, selectionSource: VimListenerManager.SelectionSource): Mode {
if (editor.selectionModel.hasSelection(true)) {
if (dontChangeMode(editor)) return editor.vim.mode
@ -148,6 +153,8 @@ internal object IdeaSelectionControl {
return Mode.NORMAL()
}
@RWLockLabel.Readonly
@RequiresReadLock
private fun chooseSelectionMode(
editor: Editor,
selectionSource: VimListenerManager.SelectionSource,

View File

@ -16,6 +16,7 @@ import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.api.getLineEndForOffset
import com.maddyhome.idea.vim.api.getLineStartForOffset
import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor
import com.maddyhome.idea.vim.newapi.IjEditorExecutionContext
import com.maddyhome.idea.vim.newapi.IjVimCaret
@ -31,7 +32,8 @@ internal fun Editor.exitSelectMode(adjustCaretPosition: Boolean) {
vimEditor.mode = vimEditor.mode.returnTo
SelectionVimListenerSuppressor.lock().use {
this.caretModel.allCarets.forEach {
it.removeSelection()
// NOTE: I think it should be write action, but the exception shows only an absence of the read action
injector.application.runReadAction { it.removeSelection() }
it.vim.vimSelectionStartClear()
if (adjustCaretPosition && !vimEditor.isEndAllowed) {
val lineEnd = IjVimEditor(this).getLineEndForOffset(it.offset)
@ -52,7 +54,8 @@ internal fun VimEditor.exitSelectMode(adjustCaretPosition: Boolean) {
SelectionVimListenerSuppressor.lock().use {
carets().forEach { vimCaret ->
val caret = (vimCaret as IjVimCaret).caret
caret.removeSelection()
// NOTE: I think it should be write action, but the exception shows only an absence of the read action
injector.application.runReadAction { caret.removeSelection() }
caret.vim.vimSelectionStartClear()
if (adjustCaretPosition && !isEndAllowed) {
val lineEnd = IjVimEditor((this as IjVimEditor).editor).getLineEndForOffset(caret.offset)

View File

@ -19,6 +19,7 @@ import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.event.CaretEvent
import com.intellij.openapi.editor.event.CaretListener
import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.group.visual.IdeaSelectionControl
import com.maddyhome.idea.vim.group.visual.moveCaretOneCharLeftFromSelectionEnd
import com.maddyhome.idea.vim.helper.getTopLevelEditor
@ -47,8 +48,12 @@ internal class RiderActionListener : AnActionListener {
override fun caretPositionChanged(event: CaretEvent) {
val eventEditor = event.editor.getTopLevelEditor()
if (!eventEditor.isIdeaVimDisabledHere) {
val predictedMode =
IdeaSelectionControl.predictMode(eventEditor, VimListenerManager.SelectionSource.OTHER)
val predictedMode = injector.application.runReadAction {
IdeaSelectionControl.predictMode(
eventEditor,
VimListenerManager.SelectionSource.OTHER
)
}
moveCaretOneCharLeftFromSelectionEnd(eventEditor, predictedMode)
}
eventEditor.caretModel.removeCaretListener(this)

View File

@ -762,7 +762,8 @@ internal object VimListenerManager {
logger.debug("Release mouse after dragging")
val editor = event.editor
SelectionVimListenerSuppressor.lock().use {
val predictedMode = IdeaSelectionControl.predictMode(editor, SelectionSource.MOUSE)
val predictedMode = injector.application
.runReadAction { IdeaSelectionControl.predictMode(editor, SelectionSource.MOUSE) }
IdeaSelectionControl.controlNonVimSelectionChange(editor, SelectionSource.MOUSE)
// TODO: This should only be for 'selection'=inclusive
moveCaretOneCharLeftFromSelectionEnd(editor, predictedMode)
@ -840,7 +841,9 @@ internal object VimListenerManager {
override fun mousePressed(e: MouseEvent?) {
val editor = (e?.component as? EditorComponentImpl)?.editor ?: return
if (editor.isIdeaVimDisabledHere) return
val predictedMode = IdeaSelectionControl.predictMode(editor, SelectionSource.MOUSE)
val predictedMode = injector.application.runReadAction {
IdeaSelectionControl.predictMode(editor, SelectionSource.MOUSE)
}
when (e.clickCount) {
1 -> {
// If you click after the line, the caret is placed by IJ after the last symbol.

View File

@ -14,10 +14,12 @@ import com.intellij.codeInsight.lookup.LookupManager
import com.intellij.codeInsight.lookup.impl.LookupImpl
import com.intellij.codeInsight.template.impl.TemplateManagerImpl
import com.intellij.openapi.editor.Editor
import com.intellij.util.concurrency.annotations.RequiresReadLock
import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.group.IjOptionConstants
import com.maddyhome.idea.vim.helper.RWLockLabel
import com.maddyhome.idea.vim.helper.hasBlockOrUnderscoreCaret
import com.maddyhome.idea.vim.helper.hasVisualSelection
import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor
@ -83,6 +85,8 @@ internal object IdeaRefactorModeHelper {
}
}
@RWLockLabel.Readonly
@RequiresReadLock
fun calculateCorrections(editor: Editor): List<Action> {
val corrections = mutableListOf<Action>()
val mode = editor.vim.mode
@ -112,7 +116,7 @@ internal object IdeaRefactorModeHelper {
}
fun correctSelection(editor: Editor) {
val corrections = calculateCorrections(editor)
val corrections = injector.application.runReadAction { calculateCorrections(editor) }
applyCorrections(corrections, editor)
}
}

View File

@ -8,6 +8,7 @@
package com.maddyhome.idea.vim.api
import com.maddyhome.idea.vim.helper.RWLockLabel
import com.maddyhome.idea.vim.state.mode.Mode
import com.maddyhome.idea.vim.state.mode.SelectionType
@ -92,5 +93,6 @@ interface VimVisualMotionGroup {
*
* If the IDE changes the selection, this function can be used to understand what the current selection type is.
*/
@RWLockLabel.Readonly
fun detectSelectionType(editor: VimEditor): SelectionType
}

View File

@ -13,6 +13,7 @@ import com.maddyhome.idea.vim.group.visual.VisualOperation
import com.maddyhome.idea.vim.group.visual.vimLeadSelectionOffset
import com.maddyhome.idea.vim.group.visual.vimSetSelection
import com.maddyhome.idea.vim.group.visual.vimUpdateEditorSelection
import com.maddyhome.idea.vim.helper.RWLockLabel
import com.maddyhome.idea.vim.helper.exitVisualMode
import com.maddyhome.idea.vim.state.mode.Mode
import com.maddyhome.idea.vim.state.mode.SelectionType
@ -201,6 +202,7 @@ abstract class VimVisualMotionGroupBase : VimVisualMotionGroup {
}
}
@RWLockLabel.Readonly
override fun detectSelectionType(editor: VimEditor): SelectionType {
if (editor.carets().size > 1 && seemsLikeBlockMode(editor)) {
return SelectionType.BLOCK_WISE