From 0982b3488d7fd6e2f097b7df9b525ef1d9c84a08 Mon Sep 17 00:00:00 2001 From: FalsePattern Date: Tue, 18 Feb 2025 15:36:39 +0100 Subject: [PATCH] chore: separate out lsp logic from core --- build.gradle.kts | 1 + core/build.gradle.kts | 4 -- .../com/falsepattern/zigbrains/ZBStartup.kt | 12 ---- .../project/newproject/ZigNewProjectPanel.kt | 11 ++-- .../newproject/ZigProjectConfigurationData.kt | 15 ++--- .../project/settings/ZigConfigurable.kt | 3 +- .../ZigCoreProjectConfigurationProvider.kt | 42 +++++++++++++ .../settings/ZigProjectConfigurable.kt | 3 +- .../ZigProjectConfigurationProvider.kt | 59 +++++++++++++++++++ .../project/settings/ZigProjectSettings.kt | 9 ++- .../settings/ZigProjectSettingsPanel.kt | 6 +- .../zigbrains/shared/MultiConfigurable.kt | 2 +- .../resources/META-INF/zigbrains-core.xml | 7 +-- lsp/build.gradle.kts | 22 +++++++ .../zigbrains/lsp/LanguageServerStarter.kt | 0 .../falsepattern/zigbrains/lsp/ZLSBundle.kt | 0 .../lsp/ZLSProjectConfigurationProvider.kt | 46 +++++++++++++++ .../falsepattern/zigbrains/lsp/ZLSStartup.kt | 47 +++++++++++++++ .../lsp/ZLSStreamConnectionProvider.kt | 0 .../zigbrains/lsp/ZigLanguageServerFactory.kt | 0 .../zigbrains/lsp/config/ZLSConfig.kt | 0 .../lsp/config/ZLSConfigProviderBase.kt | 0 .../ZLSSemanticTokenColorsProvider.kt | 0 .../highlighting/ZLSSemanticTokenModifiers.kt | 0 .../lsp/highlighting/ZLSSemanticTokenTypes.kt | 0 .../lsp/settings/ZLSProjectSettingsService.kt | 0 .../zigbrains/lsp/settings/ZLSSettings.kt | 8 ++- .../lsp/settings/ZLSSettingsConfigProvider.kt | 0 .../lsp/settings/ZLSSettingsConfigurable.kt | 0 .../lsp/settings/ZLSSettingsPanel.kt | 7 ++- .../toolchain/ToolchainZLSConfigProvider.kt | 1 + .../main/resources/META-INF/zigbrains-lsp.xml | 30 ++++++++++ .../resources/zigbrains/lsp/Bundle.properties | 0 settings.gradle.kts | 1 + src/main/resources/META-INF/plugin.xml | 5 ++ 35 files changed, 291 insertions(+), 50 deletions(-) create mode 100644 core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigCoreProjectConfigurationProvider.kt create mode 100644 core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigProjectConfigurationProvider.kt create mode 100644 lsp/build.gradle.kts rename {core => lsp}/src/main/kotlin/com/falsepattern/zigbrains/lsp/LanguageServerStarter.kt (100%) rename {core => lsp}/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSBundle.kt (100%) create mode 100644 lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSProjectConfigurationProvider.kt create mode 100644 lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSStartup.kt rename {core => lsp}/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSStreamConnectionProvider.kt (100%) rename {core => lsp}/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZigLanguageServerFactory.kt (100%) rename {core => lsp}/src/main/kotlin/com/falsepattern/zigbrains/lsp/config/ZLSConfig.kt (100%) rename {core => lsp}/src/main/kotlin/com/falsepattern/zigbrains/lsp/config/ZLSConfigProviderBase.kt (100%) rename {core => lsp}/src/main/kotlin/com/falsepattern/zigbrains/lsp/highlighting/ZLSSemanticTokenColorsProvider.kt (100%) rename {core => lsp}/src/main/kotlin/com/falsepattern/zigbrains/lsp/highlighting/ZLSSemanticTokenModifiers.kt (100%) rename {core => lsp}/src/main/kotlin/com/falsepattern/zigbrains/lsp/highlighting/ZLSSemanticTokenTypes.kt (100%) rename {core => lsp}/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSProjectSettingsService.kt (100%) rename {core => lsp}/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettings.kt (84%) rename {core => lsp}/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsConfigProvider.kt (100%) rename {core => lsp}/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsConfigurable.kt (100%) rename {core => lsp}/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsPanel.kt (96%) rename {core => lsp}/src/main/kotlin/com/falsepattern/zigbrains/project/toolchain/ToolchainZLSConfigProvider.kt (99%) rename {core => lsp}/src/main/resources/META-INF/zigbrains-lsp.xml (64%) rename {core => lsp}/src/main/resources/zigbrains/lsp/Bundle.properties (100%) diff --git a/build.gradle.kts b/build.gradle.kts index 64e9fc2c..d824e308 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -110,6 +110,7 @@ dependencies { runtimeOnly(project(":core")) runtimeOnly(project(":cidr")) + runtimeOnly(project(":lsp")) } intellijPlatform { diff --git a/core/build.gradle.kts b/core/build.gradle.kts index bcdb0b64..32259f17 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -7,8 +7,6 @@ plugins { kotlin("plugin.serialization") } -val lsp4ijVersion: String by project -val lsp4jVersion: String by project val ideaCommunityVersion: String by project val useInstaller = property("useInstaller").toString().toBoolean() @@ -16,8 +14,6 @@ dependencies { intellijPlatform { create(IntelliJPlatformType.IntellijIdeaCommunity, ideaCommunityVersion, useInstaller = useInstaller) } - compileOnly("com.redhat.devtools.intellij:lsp4ij:$lsp4ijVersion") - compileOnly("org.eclipse.lsp4j:org.eclipse.lsp4j:$lsp4jVersion") compileOnly("org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.3") } diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/ZBStartup.kt b/core/src/main/kotlin/com/falsepattern/zigbrains/ZBStartup.kt index 941ab93a..d9780011 100644 --- a/core/src/main/kotlin/com/falsepattern/zigbrains/ZBStartup.kt +++ b/core/src/main/kotlin/com/falsepattern/zigbrains/ZBStartup.kt @@ -25,7 +25,6 @@ package com.falsepattern.zigbrains import com.falsepattern.zigbrains.direnv.DirenvCmd import com.falsepattern.zigbrains.direnv.emptyEnv import com.falsepattern.zigbrains.direnv.getDirenv -import com.falsepattern.zigbrains.lsp.settings.zlsSettings import com.falsepattern.zigbrains.project.settings.zigProjectSettings import com.falsepattern.zigbrains.project.toolchain.LocalZigToolchain import com.falsepattern.zigbrains.project.toolchain.ZigToolchainProvider @@ -89,17 +88,6 @@ class ZBStartup: ProjectActivity { project.zigProjectSettings.state = zigProjectState } } - val zlsState = project.zlsSettings.state - if (zlsState.zlsPath.isBlank()) { - val env = if (DirenvCmd.direnvInstalled() && !project.isDefault && zlsState.direnv) - project.getDirenv() - else - emptyEnv - env.findExecutableOnPATH("zls")?.let { - zlsState.zlsPath = it.pathString - project.zlsSettings.state = zlsState - } - } } } diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/project/newproject/ZigNewProjectPanel.kt b/core/src/main/kotlin/com/falsepattern/zigbrains/project/newproject/ZigNewProjectPanel.kt index febc60fc..1297acc1 100644 --- a/core/src/main/kotlin/com/falsepattern/zigbrains/project/newproject/ZigNewProjectPanel.kt +++ b/core/src/main/kotlin/com/falsepattern/zigbrains/project/newproject/ZigNewProjectPanel.kt @@ -22,8 +22,7 @@ package com.falsepattern.zigbrains.project.newproject -import com.falsepattern.zigbrains.lsp.settings.ZLSSettingsPanel -import com.falsepattern.zigbrains.project.settings.ZigProjectSettingsPanel +import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvider import com.falsepattern.zigbrains.project.template.ZigExecutableTemplate import com.falsepattern.zigbrains.project.template.ZigInitTemplate import com.falsepattern.zigbrains.project.template.ZigLibraryTemplate @@ -44,8 +43,7 @@ import javax.swing.ListSelectionModel class ZigNewProjectPanel(private var handleGit: Boolean): Disposable { private val git = JBCheckBox() - private val projConf = ZigProjectSettingsPanel(null).also { Disposer.register(this, it) } - private val zlsConf = ZLSSettingsPanel(null).also { Disposer.register(this, it) } + private val panels = ZigProjectConfigurationProvider.createNewProjectSettingsPanels().onEach { Disposer.register(this, it) } private val templateList = JBList(JBList.createDefaultListModel(defaultTemplates)).apply { selectionMode = ListSelectionModel.SINGLE_SELECTION selectedIndex = 0 @@ -68,7 +66,7 @@ class ZigNewProjectPanel(private var handleGit: Boolean): Disposable { fun getData(): ZigProjectConfigurationData { val selectedTemplate = templateList.selectedValue - return ZigProjectConfigurationData(handleGit && git.isSelected, projConf.data, zlsConf.data, selectedTemplate) + return ZigProjectConfigurationData(handleGit && git.isSelected, panels.map { it.data }, selectedTemplate) } fun attach(p: Panel): Unit = with(p) { @@ -85,8 +83,7 @@ class ZigNewProjectPanel(private var handleGit: Boolean): Disposable { .align(AlignY.FILL) } } - projConf.attach(p) - zlsConf.attach(p) + panels.forEach { it.attach(p) } } override fun dispose() { diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/project/newproject/ZigProjectConfigurationData.kt b/core/src/main/kotlin/com/falsepattern/zigbrains/project/newproject/ZigProjectConfigurationData.kt index 715c5225..595555c2 100644 --- a/core/src/main/kotlin/com/falsepattern/zigbrains/project/newproject/ZigProjectConfigurationData.kt +++ b/core/src/main/kotlin/com/falsepattern/zigbrains/project/newproject/ZigProjectConfigurationData.kt @@ -22,10 +22,7 @@ package com.falsepattern.zigbrains.project.newproject -import com.falsepattern.zigbrains.lsp.settings.ZLSSettings -import com.falsepattern.zigbrains.lsp.settings.zlsSettings -import com.falsepattern.zigbrains.project.settings.ZigProjectSettings -import com.falsepattern.zigbrains.project.settings.zigProjectSettings +import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvider import com.falsepattern.zigbrains.project.template.ZigInitTemplate import com.falsepattern.zigbrains.project.template.ZigProjectTemplate import com.falsepattern.zigbrains.shared.zigCoroutineScope @@ -45,21 +42,21 @@ import kotlinx.coroutines.launch @JvmRecord data class ZigProjectConfigurationData( val git: Boolean, - val projConf: ZigProjectSettings, - val zlsConf: ZLSSettings, + val conf: List, val selectedTemplate: ZigProjectTemplate ) { @RequiresBackgroundThread suspend fun generateProject(requestor: Any, project: Project, baseDir: VirtualFile, forceGitignore: Boolean): Boolean { return reportProgress { reporter -> - project.zigProjectSettings.loadState(projConf) - project.zlsSettings.loadState(zlsConf) + conf.forEach { it.apply(project) } val template = selectedTemplate if (!reporter.indeterminateStep("Initializing project") { if (template is ZigInitTemplate) { - val toolchain = projConf.toolchain ?: run { + val toolchain = conf + .mapNotNull { it as? ZigProjectConfigurationProvider.ToolchainProvider } + .firstNotNullOfOrNull { it.toolchain } ?: run { Notification( "zigbrains", "Tried to generate project with zig init, but zig toolchain is invalid", diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigConfigurable.kt b/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigConfigurable.kt index a863dda3..e16b058f 100644 --- a/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigConfigurable.kt +++ b/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigConfigurable.kt @@ -22,11 +22,10 @@ package com.falsepattern.zigbrains.project.settings -import com.falsepattern.zigbrains.lsp.settings.ZLSSettingsConfigurable import com.falsepattern.zigbrains.shared.MultiConfigurable import com.intellij.openapi.project.Project -class ZigConfigurable(project: Project): MultiConfigurable(ZigProjectConfigurable(project), ZLSSettingsConfigurable(project)) { +class ZigConfigurable(project: Project): MultiConfigurable(ZigProjectConfigurationProvider.createConfigurables(project)) { override fun getDisplayName(): String { return "Zig" } diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigCoreProjectConfigurationProvider.kt b/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigCoreProjectConfigurationProvider.kt new file mode 100644 index 00000000..7c39a25e --- /dev/null +++ b/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigCoreProjectConfigurationProvider.kt @@ -0,0 +1,42 @@ +/* + * This file is part of ZigBrains. + * + * Copyright (C) 2023-2025 FalsePattern + * All Rights Reserved + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * ZigBrains is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, only version 3 of the License. + * + * ZigBrains is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with ZigBrains. If not, see . + */ + +package com.falsepattern.zigbrains.project.settings + +import com.falsepattern.zigbrains.shared.SubConfigurable +import com.intellij.openapi.project.Project + +class ZigCoreProjectConfigurationProvider: ZigProjectConfigurationProvider { + override fun handleMainConfigChanged(project: Project) { + } + + override fun createConfigurable(project: Project): SubConfigurable { + return ZigProjectConfigurable(project) + } + + override fun createNewProjectSettingsPanel(): ZigProjectConfigurationProvider.SettingsPanel { + return ZigProjectSettingsPanel(null) + } + + override val priority: Int + get() = 0 +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigProjectConfigurable.kt b/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigProjectConfigurable.kt index b6bda354..c45adba7 100644 --- a/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigProjectConfigurable.kt +++ b/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigProjectConfigurable.kt @@ -22,7 +22,6 @@ package com.falsepattern.zigbrains.project.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 @@ -45,7 +44,7 @@ class ZigProjectConfigurable(private val project: Project): SubConfigurable { val modified = service.isModified(data) service.state = data if (modified) { - startLSP(project, true) + ZigProjectConfigurationProvider.mainConfigChanged(project) } } diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigProjectConfigurationProvider.kt b/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigProjectConfigurationProvider.kt new file mode 100644 index 00000000..0dc7cfc6 --- /dev/null +++ b/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigProjectConfigurationProvider.kt @@ -0,0 +1,59 @@ +/* + * This file is part of ZigBrains. + * + * Copyright (C) 2023-2025 FalsePattern + * All Rights Reserved + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * ZigBrains is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, only version 3 of the License. + * + * ZigBrains is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with ZigBrains. If not, see . + */ + +package com.falsepattern.zigbrains.project.settings + +import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain +import com.falsepattern.zigbrains.shared.SubConfigurable +import com.intellij.openapi.Disposable +import com.intellij.openapi.extensions.ExtensionPointName +import com.intellij.openapi.project.Project +import com.intellij.ui.dsl.builder.Panel + +interface ZigProjectConfigurationProvider { + fun handleMainConfigChanged(project: Project) + fun createConfigurable(project: Project): SubConfigurable + fun createNewProjectSettingsPanel(): SettingsPanel + val priority: Int + companion object { + private val EXTENSION_POINT_NAME = ExtensionPointName.create("com.falsepattern.zigbrains.projectConfigProvider") + fun mainConfigChanged(project: Project) { + EXTENSION_POINT_NAME.extensionList.forEach { it.handleMainConfigChanged(project) } + } + fun createConfigurables(project: Project): List { + return EXTENSION_POINT_NAME.extensionList.sortedBy { it.priority }.map { it.createConfigurable(project) } + } + fun createNewProjectSettingsPanels(): List { + return EXTENSION_POINT_NAME.extensionList.sortedBy { it.priority }.map { it.createNewProjectSettingsPanel() } + } + } + interface SettingsPanel: Disposable { + val data: Settings + fun attach(p: Panel) + } + interface Settings { + fun apply(project: Project) + } + interface ToolchainProvider { + val toolchain: AbstractZigToolchain? + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigProjectSettings.kt b/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigProjectSettings.kt index 621de582..00fb67e0 100644 --- a/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigProjectSettings.kt +++ b/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigProjectSettings.kt @@ -23,6 +23,7 @@ package com.falsepattern.zigbrains.project.settings import com.falsepattern.zigbrains.project.toolchain.LocalZigToolchain +import com.intellij.openapi.project.Project import com.intellij.openapi.util.io.toNioPathOrNull import com.intellij.util.xmlb.annotations.Transient import kotlin.io.path.pathString @@ -32,10 +33,14 @@ data class ZigProjectSettings( var overrideStdPath: Boolean = false, var explicitPathToStd: String? = null, var toolchainPath: String? = null -) { +): ZigProjectConfigurationProvider.Settings, ZigProjectConfigurationProvider.ToolchainProvider { + override fun apply(project: Project) { + project.zigProjectSettings.loadState(this) + } + @get:Transient @set:Transient - var toolchain: LocalZigToolchain? + override var toolchain: LocalZigToolchain? get() = toolchainPath?.toNioPathOrNull()?.let { LocalZigToolchain(it) } set(value) { toolchainPath = value?.location?.pathString diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigProjectSettingsPanel.kt b/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigProjectSettingsPanel.kt index abd83e2e..8ea8374e 100644 --- a/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigProjectSettingsPanel.kt +++ b/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigProjectSettingsPanel.kt @@ -52,7 +52,7 @@ import kotlinx.coroutines.launch import javax.swing.event.DocumentEvent import kotlin.io.path.pathString -class ZigProjectSettingsPanel(private val project: Project?) : Disposable { +class ZigProjectSettingsPanel(private val project: Project?) : ZigProjectConfigurationProvider.SettingsPanel { private val direnv = JBCheckBox(ZigBrainsBundle.message("settings.project.label.direnv")).apply { addActionListener { dispatchAutodetect(true) } } @@ -107,7 +107,7 @@ class ZigProjectSettingsPanel(private val project: Project?) : Disposable { } } - var data + override var data get() = ZigProjectSettings( direnv.isSelected, stdFieldOverride.isSelected, @@ -123,7 +123,7 @@ class ZigProjectSettingsPanel(private val project: Project?) : Disposable { dispatchUpdateUI() } - fun attach(p: Panel): Unit = with(p) { + override fun attach(p: Panel): Unit = with(p) { val project = project ?: ProjectManager.getInstance().defaultProject data = project.zigProjectSettings.state group(ZigBrainsBundle.message("settings.project.group.title")) { diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/shared/MultiConfigurable.kt b/core/src/main/kotlin/com/falsepattern/zigbrains/shared/MultiConfigurable.kt index f14eb879..97c22e0a 100644 --- a/core/src/main/kotlin/com/falsepattern/zigbrains/shared/MultiConfigurable.kt +++ b/core/src/main/kotlin/com/falsepattern/zigbrains/shared/MultiConfigurable.kt @@ -27,7 +27,7 @@ import com.intellij.openapi.util.Disposer import com.intellij.ui.dsl.builder.panel import javax.swing.JComponent -abstract class MultiConfigurable(private vararg val configurables: SubConfigurable): Configurable { +abstract class MultiConfigurable(private val configurables: List): Configurable { override fun createComponent(): JComponent? { return panel { for (configurable in configurables) { diff --git a/core/src/main/resources/META-INF/zigbrains-core.xml b/core/src/main/resources/META-INF/zigbrains-core.xml index 3a333a95..0a005035 100644 --- a/core/src/main/resources/META-INF/zigbrains-core.xml +++ b/core/src/main/resources/META-INF/zigbrains-core.xml @@ -184,13 +184,12 @@ - - + diff --git a/lsp/build.gradle.kts b/lsp/build.gradle.kts new file mode 100644 index 00000000..cb94ceee --- /dev/null +++ b/lsp/build.gradle.kts @@ -0,0 +1,22 @@ +import org.jetbrains.grammarkit.tasks.GenerateLexerTask +import org.jetbrains.grammarkit.tasks.GenerateParserTask +import org.jetbrains.intellij.platform.gradle.IntelliJPlatformType + +plugins { + kotlin("plugin.serialization") +} + +val lsp4ijVersion: String by project +val lsp4jVersion: String by project +val ideaCommunityVersion: String by project +val useInstaller = property("useInstaller").toString().toBoolean() + +dependencies { + intellijPlatform { + create(IntelliJPlatformType.IntellijIdeaCommunity, ideaCommunityVersion, useInstaller = useInstaller) + } + compileOnly("org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.3") + compileOnly("com.redhat.devtools.intellij:lsp4ij:$lsp4ijVersion") + compileOnly("org.eclipse.lsp4j:org.eclipse.lsp4j:$lsp4jVersion") + implementation(project(":core")) +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/lsp/LanguageServerStarter.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/LanguageServerStarter.kt similarity index 100% rename from core/src/main/kotlin/com/falsepattern/zigbrains/lsp/LanguageServerStarter.kt rename to lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/LanguageServerStarter.kt diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSBundle.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSBundle.kt similarity index 100% rename from core/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSBundle.kt rename to lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSBundle.kt diff --git a/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSProjectConfigurationProvider.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSProjectConfigurationProvider.kt new file mode 100644 index 00000000..52702747 --- /dev/null +++ b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSProjectConfigurationProvider.kt @@ -0,0 +1,46 @@ +/* + * This file is part of ZigBrains. + * + * Copyright (C) 2023-2025 FalsePattern + * All Rights Reserved + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * ZigBrains is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, only version 3 of the License. + * + * ZigBrains is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with ZigBrains. If not, see . + */ + +package com.falsepattern.zigbrains.lsp + +import com.falsepattern.zigbrains.lsp.settings.ZLSSettingsConfigurable +import com.falsepattern.zigbrains.lsp.settings.ZLSSettingsPanel +import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvider +import com.falsepattern.zigbrains.shared.SubConfigurable +import com.intellij.openapi.project.Project + +class ZLSProjectConfigurationProvider: ZigProjectConfigurationProvider { + override fun handleMainConfigChanged(project: Project) { + startLSP(project, true) + } + + override fun createConfigurable(project: Project): SubConfigurable { + return ZLSSettingsConfigurable(project) + } + + override fun createNewProjectSettingsPanel(): ZigProjectConfigurationProvider.SettingsPanel { + return ZLSSettingsPanel(null) + } + + override val priority: Int + get() = 1000 +} \ No newline at end of file diff --git a/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSStartup.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSStartup.kt new file mode 100644 index 00000000..6c79451d --- /dev/null +++ b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSStartup.kt @@ -0,0 +1,47 @@ +/* + * This file is part of ZigBrains. + * + * Copyright (C) 2023-2025 FalsePattern + * All Rights Reserved + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * ZigBrains is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, only version 3 of the License. + * + * ZigBrains is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with ZigBrains. If not, see . + */ + +package com.falsepattern.zigbrains.lsp + +import com.falsepattern.zigbrains.direnv.DirenvCmd +import com.falsepattern.zigbrains.direnv.emptyEnv +import com.falsepattern.zigbrains.direnv.getDirenv +import com.falsepattern.zigbrains.lsp.settings.zlsSettings +import com.intellij.openapi.project.Project +import com.intellij.openapi.startup.ProjectActivity +import kotlin.io.path.pathString + +class ZLSStartup: ProjectActivity { + override suspend fun execute(project: Project) { + val zlsState = project.zlsSettings.state + if (zlsState.zlsPath.isBlank()) { + val env = if (DirenvCmd.direnvInstalled() && !project.isDefault && zlsState.direnv) + project.getDirenv() + else + emptyEnv + env.findExecutableOnPATH("zls")?.let { + zlsState.zlsPath = it.pathString + project.zlsSettings.state = zlsState + } + } + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSStreamConnectionProvider.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSStreamConnectionProvider.kt similarity index 100% rename from core/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSStreamConnectionProvider.kt rename to lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSStreamConnectionProvider.kt diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZigLanguageServerFactory.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZigLanguageServerFactory.kt similarity index 100% rename from core/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZigLanguageServerFactory.kt rename to lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZigLanguageServerFactory.kt diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/lsp/config/ZLSConfig.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/config/ZLSConfig.kt similarity index 100% rename from core/src/main/kotlin/com/falsepattern/zigbrains/lsp/config/ZLSConfig.kt rename to lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/config/ZLSConfig.kt diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/lsp/config/ZLSConfigProviderBase.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/config/ZLSConfigProviderBase.kt similarity index 100% rename from core/src/main/kotlin/com/falsepattern/zigbrains/lsp/config/ZLSConfigProviderBase.kt rename to lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/config/ZLSConfigProviderBase.kt diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/lsp/highlighting/ZLSSemanticTokenColorsProvider.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/highlighting/ZLSSemanticTokenColorsProvider.kt similarity index 100% rename from core/src/main/kotlin/com/falsepattern/zigbrains/lsp/highlighting/ZLSSemanticTokenColorsProvider.kt rename to lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/highlighting/ZLSSemanticTokenColorsProvider.kt diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/lsp/highlighting/ZLSSemanticTokenModifiers.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/highlighting/ZLSSemanticTokenModifiers.kt similarity index 100% rename from core/src/main/kotlin/com/falsepattern/zigbrains/lsp/highlighting/ZLSSemanticTokenModifiers.kt rename to lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/highlighting/ZLSSemanticTokenModifiers.kt diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/lsp/highlighting/ZLSSemanticTokenTypes.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/highlighting/ZLSSemanticTokenTypes.kt similarity index 100% rename from core/src/main/kotlin/com/falsepattern/zigbrains/lsp/highlighting/ZLSSemanticTokenTypes.kt rename to lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/highlighting/ZLSSemanticTokenTypes.kt diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSProjectSettingsService.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSProjectSettingsService.kt similarity index 100% rename from core/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSProjectSettingsService.kt rename to lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSProjectSettingsService.kt diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettings.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettings.kt similarity index 84% rename from core/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettings.kt rename to lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettings.kt index c6e18e84..acac2a9e 100644 --- a/core/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettings.kt +++ b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettings.kt @@ -22,6 +22,8 @@ package com.falsepattern.zigbrains.lsp.settings +import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvider +import com.intellij.openapi.project.Project import org.jetbrains.annotations.NonNls data class ZLSSettings( @@ -36,4 +38,8 @@ data class ZLSSettings( var comptimeInterpreter: Boolean = false, var inlayHints: Boolean = true, var inlayHintsCompact: Boolean = true -) +): ZigProjectConfigurationProvider.Settings { + override fun apply(project: Project) { + project.zlsSettings.loadState(this) + } +} diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsConfigProvider.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsConfigProvider.kt similarity index 100% rename from core/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsConfigProvider.kt rename to lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsConfigProvider.kt diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsConfigurable.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsConfigurable.kt similarity index 100% rename from core/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsConfigurable.kt rename to lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsConfigurable.kt diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsPanel.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsPanel.kt similarity index 96% rename from core/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsPanel.kt rename to lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsPanel.kt index 5f83abfa..6860f372 100644 --- a/core/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsPanel.kt +++ b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsPanel.kt @@ -27,6 +27,7 @@ import com.falsepattern.zigbrains.direnv.Env import com.falsepattern.zigbrains.direnv.emptyEnv import com.falsepattern.zigbrains.direnv.getDirenv import com.falsepattern.zigbrains.lsp.ZLSBundle +import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvider import com.falsepattern.zigbrains.shared.coroutine.launchWithEDT import com.falsepattern.zigbrains.shared.zigCoroutineScope import com.intellij.openapi.Disposable @@ -43,7 +44,7 @@ import com.intellij.ui.dsl.builder.AlignX import com.intellij.ui.dsl.builder.Panel import kotlin.io.path.pathString -class ZLSSettingsPanel(private val project: Project?) : Disposable { +class ZLSSettingsPanel(private val project: Project?) : ZigProjectConfigurationProvider.SettingsPanel { private val zlsPath = textFieldWithBrowseButton( project, FileChooserDescriptorFactory.createSingleFileDescriptor().withTitle(ZLSBundle.message("settings.zls-path.browse.title")), @@ -66,7 +67,7 @@ class ZLSSettingsPanel(private val project: Project?) : Disposable { dispatchAutodetect(true) } } - fun attach(panel: Panel) = with(panel) { + override fun attach(panel: Panel) = with(panel) { group(ZLSBundle.message("settings.group.title")) { row(ZLSBundle.message("settings.zls-path.label")) { cell(zlsPath).resizableColumn().align(AlignX.FILL) @@ -89,7 +90,7 @@ class ZLSSettingsPanel(private val project: Project?) : Disposable { dispatchAutodetect(false) } - var data + override var data get() = ZLSSettings( direnv.isSelected, zlsPath.text, diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/project/toolchain/ToolchainZLSConfigProvider.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/project/toolchain/ToolchainZLSConfigProvider.kt similarity index 99% rename from core/src/main/kotlin/com/falsepattern/zigbrains/project/toolchain/ToolchainZLSConfigProvider.kt rename to lsp/src/main/kotlin/com/falsepattern/zigbrains/project/toolchain/ToolchainZLSConfigProvider.kt index 427f768b..067cd34d 100644 --- a/core/src/main/kotlin/com/falsepattern/zigbrains/project/toolchain/ToolchainZLSConfigProvider.kt +++ b/lsp/src/main/kotlin/com/falsepattern/zigbrains/project/toolchain/ToolchainZLSConfigProvider.kt @@ -32,6 +32,7 @@ import com.intellij.openapi.util.UserDataHolderBase import com.intellij.openapi.util.io.toNioPathOrNull import kotlin.io.path.pathString + class ToolchainZLSConfigProvider: SuspendingZLSConfigProvider { override suspend fun getEnvironment(project: Project, previous: ZLSConfig): ZLSConfig { val svc = project.zigProjectSettings diff --git a/core/src/main/resources/META-INF/zigbrains-lsp.xml b/lsp/src/main/resources/META-INF/zigbrains-lsp.xml similarity index 64% rename from core/src/main/resources/META-INF/zigbrains-lsp.xml rename to lsp/src/main/resources/META-INF/zigbrains-lsp.xml index c94809ff..22e47143 100644 --- a/core/src/main/resources/META-INF/zigbrains-lsp.xml +++ b/lsp/src/main/resources/META-INF/zigbrains-lsp.xml @@ -1,3 +1,25 @@ + + zigbrains.lsp.Bundle @@ -22,12 +44,20 @@ bundle="zigbrains.lsp.Bundle" key="notification.group.zigbrains-lsp" /> + + + diff --git a/core/src/main/resources/zigbrains/lsp/Bundle.properties b/lsp/src/main/resources/zigbrains/lsp/Bundle.properties similarity index 100% rename from core/src/main/resources/zigbrains/lsp/Bundle.properties rename to lsp/src/main/resources/zigbrains/lsp/Bundle.properties diff --git a/settings.gradle.kts b/settings.gradle.kts index c8123580..0c52557a 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -4,4 +4,5 @@ plugins { rootProject.name = "ZigBrains" include("core") +include("lsp") include("cidr") diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 34748968..5258b9f7 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -17,6 +17,11 @@ dynamic="true" name="zlsConfigProvider" /> +