acejump / AceJump

🅰️ single character search, select, and jump
https://plugins.jetbrains.com/plugin/7086-acejump
GNU General Public License v3.0
1.23k stars 91 forks source link

Try to fix "Read access is allowed from inside read-action <...> only" #448

Closed h0tk3y closed 1 year ago

h0tk3y commented 1 year ago

Fix obvious manifestations of https://github.com/acejump/AceJump/issues/447. There may be more, so the fix needs more extensive testing.

h0tk3y commented 1 year ago

I tried to patch the two manifestations of the issue that showed up in my daily usage. I looked up the solution but, given my almost total absence of experience with IJ plugins, I cannot be sure that I fixed everything or that the fixes are correct.

@breandan, if you think I can help by doing something else, I'd gladly do that with your guidance.

h0tk3y commented 1 year ago

I think I saw one more exception with IJ 2023.3 EAP even after this fix, but it was in a live demo session where I could not get distracted, so I failed to save it or find it later. I'll continue observations.

UPD: I remember that the exception's message said something about something that was already disposed. I guess it is related to the fix, so the proper solution would be to check if the accessed model is still valid, as told in the IJ docs.

h0tk3y commented 1 year ago

Not sure if it is related to the original issue or my attempted fix:

Base highlighter RangeHighlighter: (1055,1075); layer:-1; tooltip: HighlightInfo(1055,1075) text=''; severity=ELEMENT_UNDER_CARET; group=236(invalid) is invalid, mirror RangeMarker(1055,1075) 91121(prev state: 1055-1075) is valid after DocumentEventImpl[myOffset=1075, myOldLength=10, myNewLength=0].

java.lang.Throwable
    at com.intellij.idea.IdeaLogger.error(IdeaLogger.java:130)
    at com.intellij.openapi.diagnostic.Logger.error(Logger.java:388)
    at com.intellij.openapi.editor.impl.ErrorStripeMarkerImpl.reportError(ErrorStripeMarkerImpl.java:70)
    at com.intellij.openapi.editor.impl.ErrorStripeMarkerImpl.validateState(ErrorStripeMarkerImpl.java:61)
    at com.intellij.openapi.editor.impl.ErrorStripeMarkerImpl.changedUpdateImpl(ErrorStripeMarkerImpl.java:40)
    at com.intellij.openapi.editor.impl.RangeMarkerImpl.onDocumentChanged(RangeMarkerImpl.java:213)
    at com.intellij.openapi.editor.impl.RangeMarkerTree.updateAffectedNodes(RangeMarkerTree.java:253)
    at com.intellij.openapi.editor.impl.RangeMarkerTree.updateMarkersOnChange(RangeMarkerTree.java:215)
    at com.intellij.openapi.editor.impl.RangeMarkerTree.documentChanged(RangeMarkerTree.java:187)
    at com.intellij.openapi.editor.impl.DocumentImpl.lambda$changedUpdate$1(DocumentImpl.java:913)
    at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$executeNonCancelableSection$2(CoreProgressManager.java:228)
    at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:685)
    at com.intellij.openapi.progress.impl.CoreProgressManager.computeUnderProgress(CoreProgressManager.java:641)
    at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$computeInNonCancelableSection$3(CoreProgressManager.java:236)
    at com.intellij.openapi.progress.Cancellation.computeInNonCancelableSection(Cancellation.java:57)
    at com.intellij.openapi.progress.impl.CoreProgressManager.computeInNonCancelableSection(CoreProgressManager.java:236)
    at com.intellij.openapi.progress.impl.CoreProgressManager.executeNonCancelableSection(CoreProgressManager.java:227)
    at com.intellij.openapi.editor.impl.DocumentImpl.changedUpdate(DocumentImpl.java:910)
    at com.intellij.openapi.editor.impl.DocumentImpl.updateText(DocumentImpl.java:814)
    at com.intellij.openapi.editor.impl.DocumentImpl.deleteString(DocumentImpl.java:570)
    at com.intellij.openapi.editor.EditorModificationUtilEx.deleteSelectedText(EditorModificationUtilEx.java:34)
    at com.intellij.openapi.editor.actions.DeleteSelectionHandler.lambda$executeWriteAction$0(DeleteSelectionHandler.java:28)
    at com.intellij.openapi.editor.impl.CaretModelImpl.lambda$runForEachCaret$3(CaretModelImpl.java:302)
    at com.intellij.openapi.editor.impl.CaretModelImpl.doWithCaretMerging(CaretModelImpl.java:411)
    at com.intellij.openapi.editor.impl.CaretModelImpl.runForEachCaret(CaretModelImpl.java:311)
    at com.intellij.openapi.editor.impl.CaretModelImpl.runForEachCaret(CaretModelImpl.java:288)
    at com.intellij.openapi.editor.actions.DeleteSelectionHandler.executeWriteAction(DeleteSelectionHandler.java:29)
    at com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler$1.run(EditorWriteActionHandler.java:42)
    at com.intellij.openapi.application.impl.ApplicationImpl.runWriteAction(ApplicationImpl.java:994)
    at com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler.doExecute(EditorWriteActionHandler.java:56)
    at com.intellij.openapi.editor.actionSystem.EditorActionHandler.lambda$execute$4(EditorActionHandler.java:199)
    at com.intellij.openapi.editor.actionSystem.EditorActionHandler.doIfEnabled(EditorActionHandler.java:89)
    at com.intellij.openapi.editor.actionSystem.EditorActionHandler.execute(EditorActionHandler.java:198)
    at com.intellij.codeInsight.lookup.impl.BackspaceHandler.doExecute(BackspaceHandler.java:25)
    at com.intellij.openapi.editor.actionSystem.EditorActionHandler.lambda$execute$4(EditorActionHandler.java:199)
    at com.intellij.openapi.editor.actionSystem.EditorActionHandler.doIfEnabled(EditorActionHandler.java:89)
    at com.intellij.openapi.editor.actionSystem.EditorActionHandler.execute(EditorActionHandler.java:198)
    at org.acejump.action.AceEditorAction.doExecute(AceEditorAction.kt:24)
    at com.intellij.openapi.editor.actionSystem.DynamicEditorActionHandler.doExecute(DynamicEditorActionHandler.java:63)
    at com.intellij.openapi.editor.actionSystem.EditorActionHandler.lambda$execute$4(EditorActionHandler.java:199)
    at com.intellij.openapi.editor.actionSystem.EditorActionHandler.doIfEnabled(EditorActionHandler.java:89)
    at com.intellij.openapi.editor.actionSystem.EditorActionHandler.execute(EditorActionHandler.java:198)
    at com.intellij.openapi.editor.actionSystem.EditorAction.lambda$actionPerformed$0(EditorAction.java:92)
    at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:224)
    at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:176)
    at com.intellij.openapi.editor.actionSystem.EditorAction.actionPerformed(EditorAction.java:101)
    at com.intellij.openapi.editor.actionSystem.EditorAction.actionPerformed(EditorAction.java:77)
    at com.intellij.openapi.actionSystem.ex.ActionUtil.doPerformActionOrShowPopup(ActionUtil.java:350)
    at com.intellij.openapi.keymap.impl.ActionProcessor.performAction(ActionProcessor.java:32)
    at com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher$myActionProcessor$1.performAction(IdeKeyEventDispatcher.kt:496)
    at com.intellij.openapi.keymap.impl.IdeKeyEventDispatcherKt.doPerformActionInner$lambda$4$lambda$3(IdeKeyEventDispatcher.kt:831)
    at com.intellij.openapi.application.TransactionGuardImpl.performActivity(TransactionGuardImpl.java:106)
    at com.intellij.openapi.application.TransactionGuardImpl.performUserActivity(TransactionGuardImpl.java:95)
    at com.intellij.openapi.keymap.impl.IdeKeyEventDispatcherKt.doPerformActionInner$lambda$4(IdeKeyEventDispatcher.kt:831)
    at com.intellij.openapi.actionSystem.ex.ActionUtil.performDumbAwareWithCallbacks(ActionUtil.java:374)
    at com.intellij.openapi.keymap.impl.IdeKeyEventDispatcherKt.doPerformActionInner(IdeKeyEventDispatcher.kt:829)
    at com.intellij.openapi.keymap.impl.IdeKeyEventDispatcherKt.access$doPerformActionInner(IdeKeyEventDispatcher.kt:1)
    at com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher.processAction$intellij_platform_ide_impl(IdeKeyEventDispatcher.kt:559)
    at com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher.processAction(IdeKeyEventDispatcher.kt:509)
    at com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher.processActionOrWaitSecondStroke(IdeKeyEventDispatcher.kt:448)
    at com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher.inInitState(IdeKeyEventDispatcher.kt:441)
    at com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher.dispatchKeyEvent(IdeKeyEventDispatcher.kt:303)
    at com.intellij.ide.IdeEventQueue.dispatchKeyEvent(IdeEventQueue.kt:620)
    at com.intellij.ide.IdeEventQueue._dispatchEvent$lambda$11(IdeEventQueue.kt:581)
    at com.intellij.openapi.application.impl.RwLockHolder.runWithEnabledImplicitRead(RwLockHolder.kt:75)
    at com.intellij.openapi.application.impl.RwLockHolder.runWithImplicitRead(RwLockHolder.kt:67)
    at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.kt:581)
    at com.intellij.ide.IdeEventQueue.access$_dispatchEvent(IdeEventQueue.kt:72)
    at com.intellij.ide.IdeEventQueue$dispatchEvent$processEventRunnable$1$1$1.compute(IdeEventQueue.kt:355)
    at com.intellij.ide.IdeEventQueue$dispatchEvent$processEventRunnable$1$1$1.compute(IdeEventQueue.kt:354)
    at com.intellij.openapi.progress.impl.CoreProgressManager.computePrioritized(CoreProgressManager.java:793)
    at com.intellij.ide.IdeEventQueue$dispatchEvent$processEventRunnable$1$1.invoke(IdeEventQueue.kt:354)
    at com.intellij.ide.IdeEventQueue$dispatchEvent$processEventRunnable$1$1.invoke(IdeEventQueue.kt:349)
    at com.intellij.ide.IdeEventQueueKt.performActivity$lambda$1(IdeEventQueue.kt:1014)
    at com.intellij.openapi.application.TransactionGuardImpl.performActivity(TransactionGuardImpl.java:114)
    at com.intellij.ide.IdeEventQueueKt.performActivity(IdeEventQueue.kt:1014)
    at com.intellij.ide.IdeEventQueue.dispatchEvent$lambda$7(IdeEventQueue.kt:349)
    at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:867)
    at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.kt:391)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:207)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:92)
breandan commented 1 year ago

LGTM. I added some helper functions for reading and writing to the AceUtil.kt file here in case you want to call them: https://github.com/acejump/AceJump/blob/73a37df7e25efff824fa412dc8ff8bb8b3c400eb/src/main/kotlin/org/acejump/AceUtil.kt#L256-L261

There used to be an endpoint in the IntelliJ Platform which did the same thing, but it is now obsolete for some reason. I am somewhat reluctant to switch to the recommended alternative readAction { ... } as calling it requires polluting the entire codebase with suspend. To be honest with you, I'm unsure exactly what benefit all this colorful indirection provides.

breandan commented 1 year ago

I have bundled these changes in the latest update and acknowledged your contribution in the change notes. Thanks again.