Skip to content

Commit

Permalink
Automatic restart of the LSP-server if it crashed or shutdown
Browse files Browse the repository at this point in the history
  • Loading branch information
kizeevov committed Mar 17, 2024
1 parent 52e3b78 commit 0ae5847
Show file tree
Hide file tree
Showing 14 changed files with 418 additions and 221 deletions.
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@

### Attention

- The current version is not compatible with previous plugin settings
- The current version is not compatible with previous plugin settings!

### Added

- Binary executable files of lsp-server are embedded
- Automatic restart of the LSP-server if it crashed or shutdown
- New action for manually restarting the LSP-server
- Widget for indicating the LSP-server current status

### Fixed

- Fixed ternary expressions
- Binary executable files of lsp-server are embedded

## [0.3.1] - 2023-12-16

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package dev.slint.ideaplugin.ide.actions

import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.components.service
import com.intellij.openapi.project.DumbAware
import dev.slint.ideaplugin.ide.services.SlintServerService

class RestartLspAction: AnAction(), DumbAware {
override fun actionPerformed(e: AnActionEvent) {
val project = e.project ?: return
val slintServerService = project.service<SlintServerService>()
slintServerService.restartServer()
}

companion object {
const val ID: String = "Slint.RestartLspAction"
}
}
94 changes: 94 additions & 0 deletions src/main/kotlin/dev/slint/ideaplugin/ide/lsp/CommandLineHandler.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package dev.slint.ideaplugin.ide.lsp

import com.intellij.execution.configurations.GeneralCommandLine
import com.intellij.ide.plugins.PluginManager
import com.intellij.openapi.extensions.PluginId
import com.intellij.openapi.util.SystemInfo
import dev.slint.ideaplugin.ide.settings.SlintBackend
import dev.slint.ideaplugin.ide.settings.SlintSettingsState
import dev.slint.ideaplugin.ide.settings.SlintStyle
import java.nio.file.Path

object CommandLineHandler {
fun createCommandLine(): GeneralCommandLine {
val settingState = SlintSettingsState.getInstance().lspSettings

val parameters = mutableListOf<String>()
if (settingState.args.isNotEmpty()) {
val args = settingState.args.split("\\s+".toRegex())
parameters.addAll(args)
}

if (settingState.includePaths.isNotEmpty()) {
parameters.add("-I")
settingState.includePaths.forEach {
parameters.add("'${it}'")
}
}

if (settingState.backend != SlintBackend.DEFAULT) {
parameters.add("--backend")
parameters.add(settingState.backend.toString())
}

if (settingState.style != SlintStyle.DEFAULT) {
parameters.add("--style")
parameters.add(settingState.style.toString())
}

if (settingState.noToolbar) {
parameters.add("--no-toolbar")
}

val path = if (settingState.useExternalLsp) {
settingState.path
} else {
getEmbeddedLspPath().toString()
}

return GeneralCommandLine(path).apply {
addParameters(parameters)
withParentEnvironmentType(GeneralCommandLine.ParentEnvironmentType.CONSOLE)
withCharset(Charsets.UTF_8)
}
}

private fun getEmbeddedLspPath(): Path? {
val pluginPath = PluginManager
.getInstance()
.findEnabledPlugin(PluginId.getId(dev.slint.ideaplugin.SLINT_PLUGIN_ID))
?.pluginPath

val programName: String

if (SystemInfo.isMac) {
programName = "Slint Live Preview.app/Contents/MacOS/slint-lsp"
} else if (SystemInfo.isLinux) {
programName = when (SystemInfo.OS_ARCH) {
"x64" -> {
"slint-lsp-x86_64-unknown-linux-gnu"
}

"arm" -> {
"slint-lsp-armv7-unknown-linux-gnueabihf"
}

"arm64" -> {
"slint-lsp-aarch64-unknown-linux-gnu"
}

else -> {
return null
}
}
} else if (SystemInfo.isWindows) {
programName = "slint-lsp-x86_64-pc-windows-msvc.exe"
} else {
return null
}

return pluginPath
?.resolve("language-server/bin")
?.resolve(programName)
}
}
55 changes: 28 additions & 27 deletions src/main/kotlin/dev/slint/ideaplugin/ide/lsp/LspLanguageClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,33 +18,34 @@ class LspLanguageClient(
private val project: Project
) : Lsp4jClient(serverNotificationsHandler)
{
@JsonNotification("experimental/serverStatus")
fun serverStatus(status: ServerStatus) {
when (status.health) {
Health.WARNING -> {
NotificationGroupManager.getInstance()
.getNotificationGroup("Slint")
.createNotification(
SlintBundle.message("slint.language.server.status"),
status.message,
NotificationType.WARNING
)
.notify(project)
}
Health.ERROR -> {
NotificationGroupManager.getInstance()
.getNotificationGroup("Slint")
.createNotification(
SlintBundle.message("slint.language.server.status"),
status.message,
NotificationType.ERROR
)
.notify(project)
}

Health.OK -> {}
}
}
// when editing, it flaps with notifications
// @JsonNotification("experimental/serverStatus")
// fun serverStatus(status: ServerStatus) {
// when (status.health) {
// Health.WARNING -> {
// NotificationGroupManager.getInstance()
// .getNotificationGroup("Slint")
// .createNotification(
// SlintBundle.message("slint.language.server.status"),
// status.message,
// NotificationType.WARNING
// )
// .notify(project)
// }
// Health.ERROR -> {
// NotificationGroupManager.getInstance()
// .getNotificationGroup("Slint")
// .createNotification(
// SlintBundle.message("slint.language.server.status"),
// status.message,
// NotificationType.ERROR
// )
// .notify(project)
// }
//
// Health.OK -> {}
// }
// }

data class ServerStatus(
@JsonAdapter(EnumDeserializer::class)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package dev.slint.ideaplugin.ide.lsp

import com.intellij.execution.process.OSProcessHandler
import com.intellij.execution.process.ProcessAdapter
import com.intellij.execution.process.ProcessEvent
import com.intellij.openapi.components.service
import com.intellij.openapi.project.Project
import dev.slint.ideaplugin.ide.services.SlintServerService
import dev.slint.ideaplugin.ide.settings.SlintSettingsState
import java.util.*
import kotlin.concurrent.schedule

object ServerProcessHandler {
fun addListeners(handler: OSProcessHandler, project: Project): OSProcessHandler {
handler.addProcessListener(object : ProcessAdapter() {
override fun processTerminated(event: ProcessEvent) {
super.processTerminated(event)

val slintServerService = project.service<SlintServerService>()
if (slintServerService.isRestarting) {
return
}

slintServerService.setTerminatingStatus()

val settingState = SlintSettingsState.getInstance().lspSettings
if (!settingState.isRestartLsp) {
return
}

Timer().schedule(3000) {
slintServerService.restartServer()
}
}

override fun processNotStarted() {
super.processNotStarted()

val slintServerService = project.service<SlintServerService>()
slintServerService.setTerminatingStatus()
}

override fun startNotified(event: ProcessEvent) {
super.startNotified(event)

val slintServerService = project.service<SlintServerService>()
slintServerService.setRunningStatus()
}
})

return handler
}
}

fun startServerProcessHandler(handler: OSProcessHandler, project: Project): OSProcessHandler {
handler.addProcessListener(object : ProcessAdapter() {
override fun processTerminated(event: ProcessEvent) {
super.processTerminated(event)

val slintServerService = project.service<SlintServerService>()
if (slintServerService.isRestarting) {
return
}

slintServerService.setTerminatingStatus()

val settingState = SlintSettingsState.getInstance().lspSettings
if (!settingState.isRestartLsp) {
return
}

Timer().schedule(3000) {
slintServerService.restartServer()
}
}

override fun processNotStarted() {
super.processNotStarted()

val slintServerService = project.service<SlintServerService>()
slintServerService.setTerminatingStatus()
}

override fun startNotified(event: ProcessEvent) {
super.startNotified(event)

val slintServerService = project.service<SlintServerService>()
slintServerService.setRunningStatus()
}
})

return handler
}
Loading

0 comments on commit 0ae5847

Please sign in to comment.