From c84aa5128467b631c933c7dd1feec6d9800e53df Mon Sep 17 00:00:00 2001 From: Nicholas Rayburn <52075362+nrayburn-tech@users.noreply.github.com> Date: Tue, 22 Oct 2024 21:11:38 -0500 Subject: [PATCH] feat: Add setting to configure the language server path (#80) --- .../lsp/OxcLspServerDescriptor.kt | 16 +++++-- .../settings/OxcSettingsComponent.kt | 11 ++++- .../settings/OxcSettingsConfigurable.kt | 42 +++++++++++++++++-- .../settings/OxcSettingsState.kt | 3 ++ .../resources/messages/MyBundle.properties | 3 ++ 5 files changed, 68 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/com/github/oxc/project/oxcintellijplugin/lsp/OxcLspServerDescriptor.kt b/src/main/kotlin/com/github/oxc/project/oxcintellijplugin/lsp/OxcLspServerDescriptor.kt index 4ace161..a17f8a3 100644 --- a/src/main/kotlin/com/github/oxc/project/oxcintellijplugin/lsp/OxcLspServerDescriptor.kt +++ b/src/main/kotlin/com/github/oxc/project/oxcintellijplugin/lsp/OxcLspServerDescriptor.kt @@ -1,8 +1,12 @@ package com.github.oxc.project.oxcintellijplugin.lsp +import com.github.oxc.project.oxcintellijplugin.settings.OxcSettingsComponent import com.intellij.execution.configurations.GeneralCommandLine +import com.intellij.openapi.components.PathMacroManager +import com.intellij.openapi.components.service import com.intellij.openapi.diagnostic.thisLogger import com.intellij.openapi.project.Project +import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.vfs.VirtualFile import com.intellij.platform.lsp.api.ProjectWideLspServerDescriptor import com.intellij.platform.lsp.api.customization.LspDiagnosticsSupport @@ -26,9 +30,9 @@ class OxcLspServerDescriptor(project: Project) : ProjectWideLspServerDescriptor( } override fun createCommandLine(): GeneralCommandLine { - thisLogger().debug("Start oxc language server") - - return GeneralCommandLine(findBinary()) + val binary = findBinary() + thisLogger().debug("Creating Oxc command with binary: $binary") + return GeneralCommandLine(binary) } override fun createInitializeParams(): InitializeParams { @@ -38,6 +42,12 @@ class OxcLspServerDescriptor(project: Project) : ProjectWideLspServerDescriptor( } private fun findBinary(): String { + val configuredBinaryPath = project.service().binaryPath + if (!configuredBinaryPath.isNullOrBlank()) { + return FileUtil.toSystemDependentName( + project.service().expandPath(configuredBinaryPath)) + } + val binaryName = "oxc_language_server" val foundBinaries = roots.map { return@map it.findFileByRelativePath("node_modules/.bin/$binaryName") diff --git a/src/main/kotlin/com/github/oxc/project/oxcintellijplugin/settings/OxcSettingsComponent.kt b/src/main/kotlin/com/github/oxc/project/oxcintellijplugin/settings/OxcSettingsComponent.kt index 5112c88..985dca7 100644 --- a/src/main/kotlin/com/github/oxc/project/oxcintellijplugin/settings/OxcSettingsComponent.kt +++ b/src/main/kotlin/com/github/oxc/project/oxcintellijplugin/settings/OxcSettingsComponent.kt @@ -13,10 +13,19 @@ import com.intellij.openapi.project.Project class OxcSettingsComponent(private val project: Project) : SimplePersistentStateComponent(OxcSettingsState()) { + var binaryPath + get() = state.binaryPath + set(value) { + if (value.isNullOrBlank()) { + state.binaryPath = null + return + } + state.binaryPath = value + } + var enable get() = state.enable set(value) { state.enable = value } - } diff --git a/src/main/kotlin/com/github/oxc/project/oxcintellijplugin/settings/OxcSettingsConfigurable.kt b/src/main/kotlin/com/github/oxc/project/oxcintellijplugin/settings/OxcSettingsConfigurable.kt index cc5a6e2..dbf10cd 100644 --- a/src/main/kotlin/com/github/oxc/project/oxcintellijplugin/settings/OxcSettingsConfigurable.kt +++ b/src/main/kotlin/com/github/oxc/project/oxcintellijplugin/settings/OxcSettingsConfigurable.kt @@ -3,12 +3,18 @@ package com.github.oxc.project.oxcintellijplugin.settings import com.github.oxc.project.oxcintellijplugin.MyBundle import com.github.oxc.project.oxcintellijplugin.lsp.OxcLspServerSupportProvider import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.components.PathMacroManager import com.intellij.openapi.components.service +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory import com.intellij.openapi.options.BoundSearchableConfigurable import com.intellij.openapi.project.Project import com.intellij.openapi.ui.DialogPanel +import com.intellij.openapi.ui.TextFieldWithBrowseButton +import com.intellij.openapi.util.io.FileUtil import com.intellij.platform.lsp.api.LspServerManager +import com.intellij.ui.dsl.builder.AlignX import com.intellij.ui.dsl.builder.bindSelected +import com.intellij.ui.dsl.builder.bindText import com.intellij.ui.dsl.builder.panel class OxcSettingsConfigurable(private val project: Project) : @@ -20,17 +26,47 @@ class OxcSettingsConfigurable(private val project: Project) : return panel { row { - checkBox("Enabled").bindSelected(settings::enable) + checkBox(MyBundle.message("oxc.settings.enabled")).bindSelected(settings::enable) + } + row(MyBundle.message("oxc.settings.languageServerPath")) { + val textField = TextFieldWithBrowseButton() + cell(textField).align(AlignX.FILL).applyToComponent { + val fileChooser = FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor() + addBrowseFolderListener(null, + MyBundle.message("oxc.settings.selectPathToLanguageServer"), null, + fileChooser) + }.bindText({ + return@bindText expandToSystemDependentPath(settings.binaryPath) + }, { + settings.binaryPath = collapseToSystemIndependentPath(it) + }) } } } override fun apply() { super.apply() - @Suppress("UnstableApiUsage") - ApplicationManager.getApplication().invokeLater { + @Suppress("UnstableApiUsage") ApplicationManager.getApplication().invokeLater { project.service() .stopAndRestartIfNeeded(OxcLspServerSupportProvider::class.java) } } + + private fun collapseToSystemIndependentPath(path: String?): String { + if (path.isNullOrBlank()) { + return "" + } + + val pathMacroManager = project.service() + return FileUtil.toSystemIndependentName(pathMacroManager.collapsePath(path)) + } + + private fun expandToSystemDependentPath(path: String?): String { + if (path.isNullOrBlank()) { + return "" + } + + val pathMacroManager = project.service() + return FileUtil.toSystemDependentName(pathMacroManager.expandPath(path)) + } } diff --git a/src/main/kotlin/com/github/oxc/project/oxcintellijplugin/settings/OxcSettingsState.kt b/src/main/kotlin/com/github/oxc/project/oxcintellijplugin/settings/OxcSettingsState.kt index 966ef02..a258f74 100644 --- a/src/main/kotlin/com/github/oxc/project/oxcintellijplugin/settings/OxcSettingsState.kt +++ b/src/main/kotlin/com/github/oxc/project/oxcintellijplugin/settings/OxcSettingsState.kt @@ -5,6 +5,9 @@ import com.intellij.util.xml.Attribute class OxcSettingsState : BaseState() { + @get:Attribute("binaryPath") + var binaryPath by string() + @get:Attribute("enable") var enable by property(true) } diff --git a/src/main/resources/messages/MyBundle.properties b/src/main/resources/messages/MyBundle.properties index 8259754..dd747f7 100644 --- a/src/main/resources/messages/MyBundle.properties +++ b/src/main/resources/messages/MyBundle.properties @@ -2,3 +2,6 @@ action.com.github.oxc.project.oxcintellijplugin.actions.RestartLanguageServer.te oxc.name=Oxc oxc.schema.name=Oxc +oxc.settings.enabled=Enabled +oxc.settings.languageServerPath=Oxc Language Server Path +oxc.settings.selectPathToLanguageServer=Select path to Oxc language server