Skip to content

Commit

Permalink
Restarting the lsp-server after changing the settings
Browse files Browse the repository at this point in the history
  • Loading branch information
kizeevov committed Dec 16, 2023
1 parent efd8d05 commit 6c1fc9d
Show file tree
Hide file tree
Showing 20 changed files with 446 additions and 126 deletions.
1 change: 0 additions & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
- Added folding imports
- Added a handler for brackets and buckets
- Added property autocomplete
- Support relative-font-size (rem)
- Support relative-font-size (rem)
- Added settings for import paths
- Added lsp-server settings
- Restarting the lsp-server after changing the settings

### Fixed
- Fixed linear marker preview
Expand Down
13 changes: 5 additions & 8 deletions src/main/kotlin/dev/slint/ideaplugin/ide/actions/LspAction.kt
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
package dev.slint.ideaplugin.ide.actions

import com.intellij.json.JsonLanguage
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.psi.util.elementType
import dev.slint.ideaplugin.ide.lsp.SlintLspServer
import dev.slint.ideaplugin.lang.SlintLanguage
import dev.slint.ideaplugin.lang.psi.SlintFileElementType
import com.intellij.openapi.components.service
import com.intellij.platform.lsp.api.LspServer
import dev.slint.ideaplugin.ide.services.SlintServerService
import javax.swing.Icon


abstract class LspAction(text: String, description: String?, icon: Icon?) : AnAction(text, description, icon) {
override fun actionPerformed(e: AnActionEvent) {
val project = e.project ?: return

val servers = SlintLspServer.getInstances(project)
val servers = project.service<SlintServerService>().getServers()
if (servers.isEmpty()) {
return
}
actionPerformed(e, servers)
}

abstract fun actionPerformed(e: AnActionEvent, servers: List<SlintLspServer>)
abstract fun actionPerformed(e: AnActionEvent, servers: List<LspServer>)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.actionSystem.CommonDataKeys.VIRTUAL_FILE
import com.intellij.platform.lsp.api.LspServer
import dev.slint.ideaplugin.ide.lsp.SlintLspServer
import dev.slint.ideaplugin.ide.lsp.requests.PreviewMessageRequest
import dev.slint.ideaplugin.lang.SlintLanguage
import kotlin.io.path.Path
Expand All @@ -19,12 +18,12 @@ internal class PreviewAction(private val notification: Notification? = null) :
e.presentation.isEnabledAndVisible = psiFile.language.isKindOf(SlintLanguage.INSTANCE)
}

override fun actionPerformed(e: AnActionEvent, servers: List<SlintLspServer>) {
override fun actionPerformed(e: AnActionEvent, servers: List<LspServer>) {
val virtualFile = e.getData(VIRTUAL_FILE) ?: return
val uriFile = Path(virtualFile.path).toUri()

val request = PreviewMessageRequest(servers.first(), uriFile.toString(), "")
(servers.first() as LspServer).requestExecutor.sendRequestSync(request)
servers.first().requestExecutor.sendRequestSync(request)

notification?.expire()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import com.intellij.notification.Notification
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.platform.lsp.api.LspServer
import dev.slint.ideaplugin.ide.lsp.SlintLspServer
import dev.slint.ideaplugin.ide.lsp.requests.PreviewMessageRequest
import kotlin.io.path.Path

Expand All @@ -15,12 +14,12 @@ internal class PreviewComponentAction(
) :
LspAction("Show Component Preview", null, AllIcons.Actions.ShowCode)
{
override fun actionPerformed(e: AnActionEvent, servers: List<SlintLspServer>) {
override fun actionPerformed(e: AnActionEvent, servers: List<LspServer>) {
val virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE) ?: return
val uriFile = Path(virtualFile.path).toUri()

val request = PreviewMessageRequest(servers.first(), uriFile.toString(), componentName)
(servers.first() as LspServer).requestExecutor.sendRequestSync(request)
servers.first().requestExecutor.sendRequestSync(request)

notification?.expire()
}
Expand Down
96 changes: 66 additions & 30 deletions src/main/kotlin/dev/slint/ideaplugin/ide/lsp/LspLanguageClient.kt
Original file line number Diff line number Diff line change
@@ -1,40 +1,76 @@
package dev.slint.ideaplugin.ide.lsp

import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import com.google.gson.annotations.JsonAdapter
import com.intellij.notification.NotificationGroupManager
import com.intellij.notification.NotificationType
import com.intellij.openapi.project.Project
import com.intellij.platform.lsp.api.Lsp4jClient
import com.intellij.platform.lsp.api.LspServerNotificationsHandler
import org.eclipse.lsp4j.MessageActionItem
import org.eclipse.lsp4j.MessageParams
import org.eclipse.lsp4j.PublishDiagnosticsParams
import org.eclipse.lsp4j.ShowMessageRequestParams
import dev.slint.ideaplugin.SlintBundle
import org.eclipse.lsp4j.jsonrpc.services.JsonNotification
import org.eclipse.lsp4j.services.LanguageClient
import java.util.concurrent.CompletableFuture
import java.lang.reflect.Type

class LspLanguageClient(serverNotificationsHandler: LspServerNotificationsHandler) :
Lsp4jClient(serverNotificationsHandler)
class LspLanguageClient(
serverNotificationsHandler: LspServerNotificationsHandler,
private val project: Project
) : Lsp4jClient(serverNotificationsHandler)
{
@JsonNotification("experimental/serverStatus")
fun serverStatus(params: Any) {
println("status")
println(params)
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)
val health: Health,
val message: String,
val quiescent: Boolean,
)

enum class Health {
OK,
WARNING,
ERROR;
}

class EnumDeserializer<T : Enum<T>>() : JsonDeserializer<T> {
override fun deserialize(json: JsonElement?, typeOfT: Type?,
context: JsonDeserializationContext?): T? {
return json?.asString?.let {
if (it.isNotEmpty()) {
val enumClass = typeOfT as? Class<T>
return enumClass?.enumConstants?.first {
enumValue -> enumValue.name.equals(it, true) }
} else {
return null
}
}
}
}
// override fun telemetryEvent(p0: Any?) {
// TODO("Not yet implemented")
// }
//
// override fun publishDiagnostics(p0: PublishDiagnosticsParams?) {
// TODO("Not yet implemented")
// }
//
// override fun showMessage(p0: MessageParams?) {
// TODO("Not yet implemented")
// }
//
// override fun showMessageRequest(p0: ShowMessageRequestParams?): CompletableFuture<MessageActionItem> {
// TODO("Not yet implemented")
// }
//
// override fun logMessage(p0: MessageParams?) {
// TODO("Not yet implemented")
// }
}
40 changes: 0 additions & 40 deletions src/main/kotlin/dev/slint/ideaplugin/ide/lsp/SlintLspServer.kt

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import com.intellij.platform.lsp.api.LspServerListener
import com.intellij.platform.lsp.api.LspServerNotificationsHandler
import com.intellij.platform.lsp.api.ProjectWideLspServerDescriptor
import com.intellij.platform.lsp.api.customization.LspCompletionSupport
import dev.slint.ideaplugin.ide.settings.SlintBackend
import dev.slint.ideaplugin.ide.settings.SlintState
import dev.slint.ideaplugin.ide.settings.SlintStyle
import dev.slint.ideaplugin.lang.SlintFileType
import org.eclipse.lsp4j.services.LanguageServer

Expand All @@ -19,15 +21,44 @@ class SlintLspServerDescriptor(project: Project) : ProjectWideLspServerDescripto

override fun createCommandLine(): GeneralCommandLine {
val settingState = SlintState.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")
}

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

override fun createInitializationOptions(): Any = SlintState.getInstance().lspSettings

override fun createLsp4jClient(handler: LspServerNotificationsHandler): Lsp4jClient = LspLanguageClient(handler)
override fun createLsp4jClient(handler: LspServerNotificationsHandler): Lsp4jClient = LspLanguageClient(handler, project)

override val lsp4jServerClass: Class<out LanguageServer> = SlintLanguageServer::class.java
override val lspServerListener: LspServerListener = SlintLspServerListener(project)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,5 @@ import com.intellij.openapi.project.Project
class SlintLspServerListener(val project: Project) : LspServerListener {
override fun serverInitialized(params: InitializeResult) {
super.serverInitialized(params)

val servers = SlintLspServer.getInstances(project)
if (servers.isEmpty()) {
return
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package dev.slint.ideaplugin.ide.lsp.requests

import com.intellij.platform.lsp.api.LspServer
import com.intellij.platform.lsp.api.requests.LspRequest
import dev.slint.ideaplugin.ide.lsp.SlintLspServer
import org.eclipse.lsp4j.ExecuteCommandParams
import java.util.concurrent.CompletableFuture

class PreviewMessageRequest(private val server: SlintLspServer, private val path: String, private val component: String) : LspRequest<Any, Any>(server) {
class PreviewMessageRequest(private val server: LspServer, private val path: String, private val component: String) : LspRequest<Any, Any>(server) {
override fun preprocessResponse(serverResponse: Any): Any {
return serverResponse
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package dev.slint.ideaplugin.ide.services

import com.intellij.notification.NotificationGroupManager
import com.intellij.notification.NotificationType
import com.intellij.openapi.components.Service
import com.intellij.openapi.project.Project
import com.intellij.platform.lsp.api.LspServer
import com.intellij.platform.lsp.api.LspServerManager
import dev.slint.ideaplugin.SlintBundle
import dev.slint.ideaplugin.ide.lsp.SlintLanguageServer
import dev.slint.ideaplugin.ide.lsp.SlintLspServerSupportProvider

@Service(Service.Level.PROJECT)
class SlintServerService(private val project: Project) {
fun restartServer() {
LspServerManager.getInstance(project)

Check warning on line 16 in src/main/kotlin/dev/slint/ideaplugin/ide/services/SlintServerService.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'com.intellij.platform.lsp.api.LspServerManager.Companion' is declared in unstable 'com.intellij.platform.lsp.api.LspServerManager' marked with @ApiStatus.Experimental

Check warning on line 16 in src/main/kotlin/dev/slint/ideaplugin/ide/services/SlintServerService.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'getInstance(com.intellij.openapi.project.Project)' is declared in unstable 'com.intellij.platform.lsp.api.LspServerManager' marked with @ApiStatus.Experimental
.stopAndRestartIfNeeded(SlintLspServerSupportProvider::class.java)

Check warning on line 17 in src/main/kotlin/dev/slint/ideaplugin/ide/services/SlintServerService.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'stopAndRestartIfNeeded(java.lang.Class)' is declared in unstable 'com.intellij.platform.lsp.api.LspServerManager' marked with @ApiStatus.Experimental
}

fun notifyRestart() {
NotificationGroupManager.getInstance()
.getNotificationGroup("Slint")
.createNotification(
SlintBundle.message("slint.language.server.restarted"),
"",
NotificationType.INFORMATION
)
.notify(project)
}

fun getServers(): List<LspServer> {
val servers = LspServerManager.getInstance(project)

Check warning on line 32 in src/main/kotlin/dev/slint/ideaplugin/ide/services/SlintServerService.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'com.intellij.platform.lsp.api.LspServerManager.Companion' is declared in unstable 'com.intellij.platform.lsp.api.LspServerManager' marked with @ApiStatus.Experimental

Check warning on line 32 in src/main/kotlin/dev/slint/ideaplugin/ide/services/SlintServerService.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'getInstance(com.intellij.openapi.project.Project)' is declared in unstable 'com.intellij.platform.lsp.api.LspServerManager' marked with @ApiStatus.Experimental
.getServersForProvider(SlintLspServerSupportProvider::class.java)

Check warning on line 33 in src/main/kotlin/dev/slint/ideaplugin/ide/services/SlintServerService.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'getServersForProvider(java.lang.Class)' is declared in unstable 'com.intellij.platform.lsp.api.LspServerManager' marked with @ApiStatus.Experimental

return servers.filter { it.lsp4jServer is SlintLanguageServer }
}
}
Loading

0 comments on commit 6c1fc9d

Please sign in to comment.