diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bea6c20..2babbc7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,9 @@ Changelog structure reference: ### Fixed +- LSP + - Changing ZLS configs would not restart ZLS + - Project - Occasional "AWT events are not allowed inside write action" error coming from LSP - IllegalStateException coming from the standard library handler diff --git a/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSStartup.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSStartup.kt index f126be57..370a2408 100644 --- a/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSStartup.kt +++ b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSStartup.kt @@ -55,6 +55,9 @@ class ZLSStartup: ProjectActivity { EditorNotifications.getInstance(project).updateAllNotifications() } currentState = running + if (handleStartLSP(project)) { + EditorNotifications.getInstance(project).updateAllNotifications() + } delay(1000) } } diff --git a/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZigLanguageServerFactory.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZigLanguageServerFactory.kt index d1c61d49..c46e9ac7 100644 --- a/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZigLanguageServerFactory.kt +++ b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZigLanguageServerFactory.kt @@ -39,8 +39,11 @@ import com.redhat.devtools.lsp4ij.client.features.LSPClientFeatures import com.redhat.devtools.lsp4ij.client.features.LSPFormattingFeature import com.redhat.devtools.lsp4ij.client.features.LSPInlayHintFeature import com.redhat.devtools.lsp4ij.server.StreamConnectionProvider +import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock class ZigLanguageServerFactory: LanguageServerFactory, LanguageServerEnablementSupport { override fun createConnectionProvider(project: Project): StreamConnectionProvider { @@ -93,35 +96,67 @@ fun Project.zlsEnabled(value: Boolean) { suspend fun Project.zlsRunningAsync(): Boolean { if (!zlsEnabledAsync()) return false - return zlsRunningLsp4ij() + return lsm.isRunning } fun Project.zlsRunningSync(): Boolean { if (!zlsEnabledSync()) return false - return zlsRunningLsp4ij() + return lsm.isRunning } -private fun Project.zlsRunningLsp4ij(): Boolean { - val manager = service() - val status = manager.getServerStatus("ZigBrains") +private val Project.lsm get() = service() + +private val LanguageServerManager.isRunning get(): Boolean { + val status = getServerStatus("ZigBrains") return status == ServerStatus.started || status == ServerStatus.starting } +private val START_MUTEX = Mutex() + class ZLSStarter: LanguageServerStarter { override fun startLSP(project: Project, restart: Boolean) { project.zigCoroutineScope.launch { - val manager = project.service() - val status = manager.getServerStatus("ZigBrains") - if ((status == ServerStatus.started || status == ServerStatus.starting) && !restart) - return@launch - manager.stop("ZigBrains") - if (project.zlsSettings.validateAsync()) { - manager.start("ZigBrains") + START_MUTEX.withLock { + if (restart) { + project.putUserData(RESTART_KEY, Unit) + } else { + project.putUserData(START_KEY, Unit) + } } } } - } -private val ENABLED_KEY = Key.create("ZLS_ENABLED") \ No newline at end of file +private suspend fun doStart(project: Project, restart: Boolean) { + if (!restart && project.lsm.isRunning) + return + while (!project.isDisposed && project.lsm.isRunning) { + project.lsm.stop("ZigBrains") + delay(250) + } + if (project.zlsSettings.validateAsync()) { + delay(250) + project.lsm.start("ZigBrains") + } +} + +suspend fun handleStartLSP(project: Project) = START_MUTEX.withLock { + if (project.getUserData(RESTART_KEY) != null) { + project.putUserData(RESTART_KEY, null) + project.putUserData(START_KEY, null) + doStart(project, true) + true + } else if (project.getUserData(START_KEY) != null) { + project.putUserData(START_KEY, null) + doStart(project, false) + true + } else { + false + } +} + +private val ENABLED_KEY = Key.create("ZLS_ENABLED") + +private val RESTART_KEY = Key.create("ZLS_RESTART_REQUEST") +private val START_KEY = Key.create("ZLS_START_REQUEST") diff --git a/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsConfigurable.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsConfigurable.kt index edb49349..85363a92 100644 --- a/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsConfigurable.kt +++ b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsConfigurable.kt @@ -22,7 +22,6 @@ package com.falsepattern.zigbrains.lsp.settings -import com.falsepattern.zigbrains.lsp.startLSP import com.falsepattern.zigbrains.shared.SubConfigurable import com.intellij.openapi.project.Project import com.intellij.openapi.util.Disposer diff --git a/lsp/src/main/resources/META-INF/zigbrains-lsp.xml b/lsp/src/main/resources/META-INF/zigbrains-lsp.xml index a9c5f872..d07aaa59 100644 --- a/lsp/src/main/resources/META-INF/zigbrains-lsp.xml +++ b/lsp/src/main/resources/META-INF/zigbrains-lsp.xml @@ -88,10 +88,10 @@ /> - + - + \ No newline at end of file