diff --git a/CHANGELOG.md b/CHANGELOG.md index 42227a6a..dccfca61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,11 @@ Changelog structure reference: ## [Unreleased] +### Fixed + +- LSP + - IDE warning when renaming symbols + ## [23.1.1] ### Fixed diff --git a/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/notification/ZigEditorNotificationProvider.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/notification/ZigEditorNotificationProvider.kt index b72dde64..a812b8b8 100644 --- a/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/notification/ZigEditorNotificationProvider.kt +++ b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/notification/ZigEditorNotificationProvider.kt @@ -24,7 +24,8 @@ package com.falsepattern.zigbrains.lsp.notification import com.falsepattern.zigbrains.lsp.ZLSBundle import com.falsepattern.zigbrains.lsp.settings.zlsSettings -import com.falsepattern.zigbrains.lsp.zlsRunningSync +import com.falsepattern.zigbrains.lsp.zlsRunningAsync +import com.falsepattern.zigbrains.shared.zigCoroutineScope import com.falsepattern.zigbrains.zig.ZigFileType import com.falsepattern.zigbrains.zon.ZonFileType import com.intellij.openapi.fileEditor.FileEditor @@ -33,6 +34,8 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.VirtualFile import com.intellij.ui.EditorNotificationPanel import com.intellij.ui.EditorNotificationProvider +import kotlinx.coroutines.async +import kotlinx.coroutines.runBlocking import java.util.function.Function import javax.swing.JComponent @@ -45,13 +48,21 @@ class ZigEditorNotificationProvider: EditorNotificationProvider, DumbAware { ZigFileType, ZonFileType -> {} else -> return null } - if (project.zlsRunningSync()) { - return null + val task = project.zigCoroutineScope.async { + if (project.zlsRunningAsync()) { + return@async null + } else { + return@async project.zlsSettings.validateAsync() + } } return Function { editor -> val status: EditorNotificationPanel.Status val message: String - if (!project.zlsSettings.validateSync()) { + val result = runBlocking { task.await() } + if (result == null) + return@Function null + + if (!result) { status = EditorNotificationPanel.Status.Error message = ZLSBundle.message("notification.banner.zls-bad-config") } else { diff --git a/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSProjectSettingsService.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSProjectSettingsService.kt index 18039240..819a0bc2 100644 --- a/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSProjectSettingsService.kt +++ b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSProjectSettingsService.kt @@ -27,6 +27,7 @@ import com.falsepattern.zigbrains.direnv.getDirenv import com.falsepattern.zigbrains.lsp.ZLSBundle import com.falsepattern.zigbrains.lsp.startLSP import com.falsepattern.zigbrains.project.settings.zigProjectSettings +import com.intellij.ide.IdeEventQueue import com.intellij.openapi.components.* import com.intellij.openapi.project.Project import com.intellij.openapi.util.io.toNioPathOrNull @@ -83,17 +84,55 @@ class ZLSProjectSettingsService(val project: Project): PersistentStateComponent< } } - fun validateSync() = if (application.isDispatchThread && !application.isWriteAccessAllowed) { - runWithModalProgressBlocking(ModalTaskOwner.project(project), ZLSBundle.message("progress.title.validate")) { - validateAsync() + fun validateSync(): Boolean { + val isValid: Boolean? = runBlocking { + mutex.withLock { + if (dirty) + null + else + valid + } } - } else { - runBlocking { - validateAsync() + if (isValid != null) { + return isValid + } + return if (useModalProgress()) { + runWithModalProgressBlocking(ModalTaskOwner.project(project), ZLSBundle.message("progress.title.validate")) { + validateAsync() + } + } else { + runBlocking { + validateAsync() + } } } } +private val prohibitClass: Class<*>? = runCatching { + Class.forName("com_intellij_ide_ProhibitAWTEvents".replace('_', '.')) +}.getOrNull() + +private val postProcessors: List<*>? = runCatching { + if (prohibitClass == null) + return@runCatching null + val postProcessorsField = IdeEventQueue::class.java.getDeclaredField("postProcessors") + postProcessorsField.isAccessible = true + postProcessorsField.get(IdeEventQueue.getInstance()) as? List<*> +}.getOrNull() + +private fun useModalProgress(): Boolean { + if (!application.isDispatchThread) + return false + + if (application.isWriteAccessAllowed) + return false + + if (postProcessors == null) + return true + + return postProcessors.none { prohibitClass!!.isInstance(it) } +} + private suspend fun doValidate(project: Project, state: ZLSSettings): Boolean { val zlsPath: Path = state.zlsPath.let { zlsPath -> if (zlsPath.isEmpty()) {