diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4c4c0d34..6e591a8d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,18 @@ Changelog structure reference:
## [Unreleased]
+## [23.1.0]
+
+### Added
+
+- Project
+ - Support running file main/tests with hotkey (default: ctrl+shift+f10)
+
+### Changed
+
+- Direnv
+ - Centralized all direnv toggling into a single project-level option
+
## [23.0.2]
### Fixed
diff --git a/build.gradle.kts b/build.gradle.kts
index 32aa7621..c19f1955 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -205,6 +205,7 @@ publishVersions.forEach {
archiveFile = distFile(it)
token = providers.environmentVariable("IJ_PUBLISH_TOKEN")
channels = if (pluginVersion.contains("-")) listOf("nightly") else listOf("default")
+ setDependsOn(dependsOn.filter { if (it is TaskProvider<*>) it.name != "signPlugin" && it.name != "buildPlugin" else true })
}
tasks.named("publish").configure {
dependsOn("jbpublish-$it")
diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/project/actions/ZigRunFileAction.kt b/core/src/main/kotlin/com/falsepattern/zigbrains/project/actions/ZigRunFileAction.kt
new file mode 100644
index 00000000..27aaa33b
--- /dev/null
+++ b/core/src/main/kotlin/com/falsepattern/zigbrains/project/actions/ZigRunFileAction.kt
@@ -0,0 +1,90 @@
+/*
+ * 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.actions
+
+import com.falsepattern.zigbrains.project.execution.base.ZigExecConfig
+import com.falsepattern.zigbrains.project.execution.run.ZigConfigProducerRun
+import com.falsepattern.zigbrains.project.execution.run.ZigExecConfigRun
+import com.falsepattern.zigbrains.project.execution.test.ZigConfigProducerTest
+import com.falsepattern.zigbrains.project.execution.test.ZigExecConfigTest
+import com.intellij.execution.ExecutionManager
+import com.intellij.execution.actions.ConfigurationContext
+import com.intellij.execution.actions.RunConfigurationProducer
+import com.intellij.execution.executors.DefaultRunExecutor
+import com.intellij.execution.runners.ExecutionEnvironmentBuilder
+import com.intellij.openapi.actionSystem.ActionUpdateThread
+import com.intellij.openapi.actionSystem.AnActionEvent
+import com.intellij.openapi.actionSystem.CommonDataKeys
+import com.intellij.openapi.project.DumbAwareAction
+
+class ZigRunFileAction: DumbAwareAction() {
+ override fun actionPerformed(e: AnActionEvent) {
+ val file = e.getData(CommonDataKeys.PSI_FILE) ?: return
+ val config = getConfig(e) ?: return
+ val project = file.project
+ val builder = ExecutionEnvironmentBuilder.createOrNull(DefaultRunExecutor.getRunExecutorInstance(), config) ?: return
+ ExecutionManager.getInstance(project).restartRunProfile(builder.build())
+ }
+
+ private fun getConfig(e: AnActionEvent): ZigExecConfig<*>? {
+ val context = ConfigurationContext.getFromContext(e.dataContext, e.place)
+ return getRunConfiguration(context) ?: getTestConfiguration(context)
+ }
+
+ override fun update(e: AnActionEvent) {
+ e.presentation.isEnabledAndVisible = getConfig(e) != null
+ }
+
+ private fun getRunConfiguration(context: ConfigurationContext): ZigExecConfigRun? {
+ try {
+ val configProducer = RunConfigurationProducer.getInstance(ZigConfigProducerRun::class.java)
+ val settings = configProducer.findExistingConfiguration(context)
+ if (settings != null) {
+ return settings.configuration as? ZigExecConfigRun
+ }
+ val fromContext = configProducer.createConfigurationFromContext(context)
+ if (fromContext != null) {
+ return fromContext.configuration as? ZigExecConfigRun
+ }
+ } catch (_: NullPointerException) {}
+ return null
+ }
+ private fun getTestConfiguration(context: ConfigurationContext): ZigExecConfigTest? {
+ try {
+ val configProducer = RunConfigurationProducer.getInstance(ZigConfigProducerTest::class.java)
+ val settings = configProducer.findExistingConfiguration(context)
+ if (settings != null) {
+ return settings.configuration as? ZigExecConfigTest
+ }
+ val fromContext = configProducer.createConfigurationFromContext(context)
+ if (fromContext != null) {
+ return fromContext.configuration as? ZigExecConfigTest
+ }
+ } catch (_: NullPointerException) {}
+ return null
+ }
+
+ override fun getActionUpdateThread(): ActionUpdateThread {
+ return ActionUpdateThread.BGT
+ }
+}
\ No newline at end of file
diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/base/Configuration.kt b/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/base/Configuration.kt
index 62e524f5..913fe604 100644
--- a/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/base/Configuration.kt
+++ b/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/base/Configuration.kt
@@ -280,12 +280,6 @@ class ColoredConfigurable(serializedName: String): CheckboxConfigurable(serializ
}
}
-class DirenvConfigurable(serializedName: String, project: Project): CheckboxConfigurable(serializedName, ZigBrainsBundle.message("exec.option.label.direnv"), project.zigProjectSettings.state.direnv) {
- override fun clone(): DirenvConfigurable {
- return super.clone() as DirenvConfigurable
- }
-}
-
class OptimizationConfigurable(
@Transient private val serializedName: String,
var level: OptimizationLevel = OptimizationLevel.Debug,
diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/base/ZigConfigProducer.kt b/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/base/ZigConfigProducer.kt
index 8f9c50df..8d4c1ab6 100644
--- a/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/base/ZigConfigProducer.kt
+++ b/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/base/ZigConfigProducer.kt
@@ -41,7 +41,7 @@ abstract class ZigConfigProducer>: LazyRunConfigurationProdu
val psiFile = element.containingFile as? ZigFile ?: return false
val theFile = psiFile.virtualFile ?: return false
val filePath = theFile.toNioPathOrNull() ?: return false
- return setupConfigurationFromContext(configuration, element, filePath, theFile)
+ return setupConfigurationFromContext(configuration, element, psiFile, filePath, theFile)
}
override fun isConfigurationFromContext(configuration: T, context: ConfigurationContext): Boolean {
@@ -49,7 +49,7 @@ abstract class ZigConfigProducer>: LazyRunConfigurationProdu
val psiFile = element.containingFile as? ZigFile ?: return false
val theFile = psiFile.virtualFile ?: return false
val filePath = theFile.toNioPathOrNull() ?: return false
- return isConfigurationFromContext(configuration, element, filePath, theFile)
+ return isConfigurationFromContext(configuration, element, psiFile, filePath, theFile)
}
/*
@@ -78,7 +78,7 @@ abstract class ZigConfigProducer>: LazyRunConfigurationProdu
}
*/
- protected abstract fun setupConfigurationFromContext(configuration: T, element: PsiElement, filePath: Path, theFile: VirtualFile): Boolean
- protected abstract fun isConfigurationFromContext(configuration: T, element: PsiElement, filePath: Path, theFile: VirtualFile): Boolean
+ protected abstract fun setupConfigurationFromContext(configuration: T, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean
+ protected abstract fun isConfigurationFromContext(configuration: T, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean
abstract override fun shouldReplace(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean
}
\ No newline at end of file
diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/base/ZigExecConfig.kt b/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/base/ZigExecConfig.kt
index ab1ab23b..b03b16ad 100644
--- a/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/base/ZigExecConfig.kt
+++ b/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/base/ZigExecConfig.kt
@@ -24,6 +24,7 @@ package com.falsepattern.zigbrains.project.execution.base
import com.falsepattern.zigbrains.ZigBrainsBundle
import com.falsepattern.zigbrains.direnv.DirenvCmd
+import com.falsepattern.zigbrains.project.settings.zigProjectSettings
import com.intellij.execution.ExecutionException
import com.intellij.execution.Executor
import com.intellij.execution.configurations.ConfigurationFactory
@@ -44,8 +45,6 @@ abstract class ZigExecConfig>(project: Project, factory: Con
private set
var pty = CheckboxConfigurable("pty", ZigBrainsBundle.message("exec.option.label.emulate-terminal"), false)
private set
- var direnv = DirenvConfigurable("direnv", project)
- private set
abstract val suggestedName: @ActionText String
@Throws(ExecutionException::class)
@@ -68,7 +67,7 @@ abstract class ZigExecConfig>(project: Project, factory: Con
suspend fun patchCommandLine(commandLine: GeneralCommandLine): GeneralCommandLine {
- if (direnv.value) {
+ if (project.zigProjectSettings.state.direnv) {
commandLine.withEnvironment(DirenvCmd.importDirenv(project).env)
}
return commandLine
@@ -82,10 +81,9 @@ abstract class ZigExecConfig>(project: Project, factory: Con
val myClone = super.clone() as ZigExecConfig<*>
myClone.workingDirectory = workingDirectory.clone()
myClone.pty = pty.clone()
- myClone.direnv = direnv.clone()
@Suppress("UNCHECKED_CAST")
return myClone as T
}
- open fun getConfigurables(): List> = listOf(workingDirectory, pty, direnv)
+ open fun getConfigurables(): List> = listOf(workingDirectory, pty)
}
\ No newline at end of file
diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/build/ZigConfigProducerBuild.kt b/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/build/ZigConfigProducerBuild.kt
index 2d027c88..db3675f3 100644
--- a/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/build/ZigConfigProducerBuild.kt
+++ b/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/build/ZigConfigProducerBuild.kt
@@ -25,6 +25,7 @@ package com.falsepattern.zigbrains.project.execution.build
import com.falsepattern.zigbrains.ZigBrainsBundle
import com.falsepattern.zigbrains.project.execution.base.ZigConfigProducer
import com.falsepattern.zigbrains.project.execution.firstConfigFactory
+import com.falsepattern.zigbrains.zig.psi.ZigFile
import com.intellij.execution.actions.ConfigurationFromContext
import com.intellij.execution.configurations.ConfigurationFactory
import com.intellij.openapi.vfs.VirtualFile
@@ -36,21 +37,18 @@ class ZigConfigProducerBuild: ZigConfigProducer() {
return firstConfigFactory()
}
- override fun setupConfigurationFromContext(configuration: ZigExecConfigBuild, element: PsiElement, filePath: Path, theFile: VirtualFile): Boolean {
- if (LINE_MARKER.elementMatches(element)) {
- configuration.name = ZigBrainsBundle.message("configuration.build.marker-name")
- return true
- }
- return false
+ override fun setupConfigurationFromContext(configuration: ZigExecConfigBuild, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean {
+ if (theFile.name != "build.zig")
+ return false
+ configuration.name = ZigBrainsBundle.message("configuration.build.marker-name")
+ return true
}
- override fun isConfigurationFromContext(configuration: ZigExecConfigBuild, element: PsiElement, filePath: Path, theFile: VirtualFile): Boolean {
+ override fun isConfigurationFromContext(configuration: ZigExecConfigBuild, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean {
return filePath.parent == (configuration.workingDirectory.path ?: return false)
}
override fun shouldReplace(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean {
return self.configurationType is ZigConfigTypeBuild
}
-}
-
-private val LINE_MARKER = ZigLineMarkerBuild()
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/run/ZigConfigProducerRun.kt b/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/run/ZigConfigProducerRun.kt
index 65c98081..684058d4 100644
--- a/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/run/ZigConfigProducerRun.kt
+++ b/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/run/ZigConfigProducerRun.kt
@@ -24,10 +24,13 @@ package com.falsepattern.zigbrains.project.execution.run
import com.falsepattern.zigbrains.project.execution.base.ZigConfigProducer
import com.falsepattern.zigbrains.project.execution.firstConfigFactory
+import com.falsepattern.zigbrains.zig.psi.ZigContainerMembers
+import com.falsepattern.zigbrains.zig.psi.ZigFile
import com.intellij.execution.actions.ConfigurationFromContext
import com.intellij.execution.configurations.ConfigurationFactory
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiElement
+import com.intellij.psi.util.childrenOfType
import java.nio.file.Path
class ZigConfigProducerRun: ZigConfigProducer() {
@@ -35,16 +38,17 @@ class ZigConfigProducerRun: ZigConfigProducer() {
return firstConfigFactory()
}
- override fun setupConfigurationFromContext(configuration: ZigExecConfigRun, element: PsiElement, filePath: Path, theFile: VirtualFile): Boolean {
- if (LINE_MARKER.elementMatches(element)) {
- configuration.filePath.path = filePath
- configuration.name = theFile.presentableName
- return true
+ override fun setupConfigurationFromContext(configuration: ZigExecConfigRun, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean {
+ val members = psiFile.childrenOfType().firstOrNull() ?: return false
+ if (members.containerDeclarationList.none { it.decl?.fnProto?.identifier?.textMatches("main") == true }) {
+ return false
}
- return false
+ configuration.filePath.path = filePath
+ configuration.name = theFile.presentableName
+ return true
}
- override fun isConfigurationFromContext(configuration: ZigExecConfigRun, element: PsiElement, filePath: Path, theFile: VirtualFile): Boolean {
+ override fun isConfigurationFromContext(configuration: ZigExecConfigRun, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean {
return filePath == configuration.filePath.path
}
diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/test/ZigConfigProducerTest.kt b/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/test/ZigConfigProducerTest.kt
index 73d01aad..e215785e 100644
--- a/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/test/ZigConfigProducerTest.kt
+++ b/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/test/ZigConfigProducerTest.kt
@@ -25,10 +25,13 @@ package com.falsepattern.zigbrains.project.execution.test
import com.falsepattern.zigbrains.ZigBrainsBundle
import com.falsepattern.zigbrains.project.execution.base.ZigConfigProducer
import com.falsepattern.zigbrains.project.execution.firstConfigFactory
+import com.falsepattern.zigbrains.zig.psi.ZigContainerMembers
+import com.falsepattern.zigbrains.zig.psi.ZigFile
import com.intellij.execution.actions.ConfigurationFromContext
import com.intellij.execution.configurations.ConfigurationFactory
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiElement
+import com.intellij.psi.util.childrenOfType
import java.nio.file.Path
class ZigConfigProducerTest: ZigConfigProducer() {
@@ -36,22 +39,21 @@ class ZigConfigProducerTest: ZigConfigProducer() {
return firstConfigFactory()
}
- override fun setupConfigurationFromContext(configuration: ZigExecConfigTest, element: PsiElement, filePath: Path, theFile: VirtualFile): Boolean {
- if (LINE_MARKER.elementMatches(element)) {
- configuration.filePath.path = filePath
- configuration.name = ZigBrainsBundle.message("configuration.test.marker-name", theFile.presentableName)
- return true
+ override fun setupConfigurationFromContext(configuration: ZigExecConfigTest, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean {
+ val members = psiFile.childrenOfType().firstOrNull() ?: return false
+ if (members.containerDeclarationList.none { it.testDecl != null }) {
+ return false
}
- return false
+ configuration.filePath.path = filePath
+ configuration.name = ZigBrainsBundle.message("configuration.test.marker-name", theFile.presentableName)
+ return true
}
- override fun isConfigurationFromContext(configuration: ZigExecConfigTest, element: PsiElement, filePath: Path, theFile: VirtualFile): Boolean {
+ override fun isConfigurationFromContext(configuration: ZigExecConfigTest, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean {
return filePath == configuration.filePath.path
}
override fun shouldReplace(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean {
return self.configurationType is ZigConfigTypeTest
}
-}
-
-private val LINE_MARKER = ZigLineMarkerTest()
\ No newline at end of file
+}
\ No newline at end of file
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 6418285b..ac1abd24 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
@@ -39,9 +39,9 @@ import com.intellij.util.ui.JBUI
import javax.swing.JList
import javax.swing.ListSelectionModel
-class ZigNewProjectPanel(private var handleGit: Boolean): Disposable {
+class ZigNewProjectPanel(private var handleGit: Boolean): Disposable, ZigProjectConfigurationProvider.SettingsPanelHolder {
private val git = JBCheckBox()
- private val panels = ZigProjectConfigurationProvider.createNewProjectSettingsPanels().onEach { Disposer.register(this, it) }
+ override val panels = ZigProjectConfigurationProvider.createNewProjectSettingsPanels(this).onEach { Disposer.register(this, it) }
private val templateList = JBList(JBList.createDefaultListModel(defaultTemplates)).apply {
selectionMode = ListSelectionModel.SINGLE_SELECTION
selectedIndex = 0
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
index d8a76a88..207da863 100644
--- a/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigCoreProjectConfigurationProvider.kt
+++ b/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigCoreProjectConfigurationProvider.kt
@@ -34,8 +34,8 @@ class ZigCoreProjectConfigurationProvider: ZigProjectConfigurationProvider {
return ZigProjectConfigurable(project)
}
- override fun createNewProjectSettingsPanel(): ZigProjectConfigurationProvider.SettingsPanel {
- return ZigProjectSettingsPanel(ProjectManager.getInstance().defaultProject)
+ override fun createNewProjectSettingsPanel(holder: ZigProjectConfigurationProvider.SettingsPanelHolder): ZigProjectConfigurationProvider.SettingsPanel {
+ return ZigProjectSettingsPanel(holder, ProjectManager.getInstance().defaultProject)
}
override val priority: Int
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 c45adba7..ff333f79 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
@@ -29,9 +29,11 @@ import com.intellij.ui.dsl.builder.Panel
class ZigProjectConfigurable(private val project: Project): SubConfigurable {
private var settingsPanel: ZigProjectSettingsPanel? = null
- override fun createComponent(panel: Panel) {
+ override fun createComponent(holder: ZigProjectConfigurationProvider.SettingsPanelHolder, panel: Panel): ZigProjectConfigurationProvider.SettingsPanel {
settingsPanel?.let { Disposer.dispose(it) }
- settingsPanel = ZigProjectSettingsPanel(project).apply { attach(panel) }.also { Disposer.register(this, it) }
+ val sp = ZigProjectSettingsPanel(holder, project).apply { attach(panel) }.also { Disposer.register(this, it) }
+ settingsPanel = sp
+ return sp
}
override fun isModified(): Boolean {
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
index 058e18b6..a609a3ee 100644
--- a/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigProjectConfigurationProvider.kt
+++ b/core/src/main/kotlin/com/falsepattern/zigbrains/project/settings/ZigProjectConfigurationProvider.kt
@@ -32,7 +32,7 @@ import com.intellij.ui.dsl.builder.Panel
interface ZigProjectConfigurationProvider {
fun handleMainConfigChanged(project: Project)
fun createConfigurable(project: Project): SubConfigurable
- fun createNewProjectSettingsPanel(): SettingsPanel?
+ fun createNewProjectSettingsPanel(holder: SettingsPanelHolder): SettingsPanel?
val priority: Int
companion object {
private val EXTENSION_POINT_NAME = ExtensionPointName.create("com.falsepattern.zigbrains.projectConfigProvider")
@@ -42,13 +42,17 @@ interface ZigProjectConfigurationProvider {
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 }.mapNotNull { it.createNewProjectSettingsPanel() }
+ fun createNewProjectSettingsPanels(holder: SettingsPanelHolder): List {
+ return EXTENSION_POINT_NAME.extensionList.sortedBy { it.priority }.mapNotNull { it.createNewProjectSettingsPanel(holder) }
}
}
interface SettingsPanel: Disposable {
val data: Settings
fun attach(p: Panel)
+ fun direnvChanged(state: Boolean)
+ }
+ interface SettingsPanelHolder {
+ val panels: List
}
interface Settings {
fun apply(project: Project)
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 b248e9ae..7a8fa6cc 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,9 +52,9 @@ import kotlinx.coroutines.launch
import javax.swing.event.DocumentEvent
import kotlin.io.path.pathString
-class ZigProjectSettingsPanel(private val project: Project) : ZigProjectConfigurationProvider.SettingsPanel {
+class ZigProjectSettingsPanel(private val holder: ZigProjectConfigurationProvider.SettingsPanelHolder, private val project: Project) : ZigProjectConfigurationProvider.SettingsPanel {
private val direnv = JBCheckBox(ZigBrainsBundle.message("settings.project.label.direnv")).apply { addActionListener {
- dispatchAutodetect(true)
+ dispatchDirenvUpdate()
} }
private val pathToToolchain = textFieldWithBrowseButton(
project,
@@ -86,6 +86,16 @@ class ZigProjectSettingsPanel(private val project: Project) : ZigProjectConfigur
).also { Disposer.register(this, it) }
private var debounce: Job? = null
+ private fun dispatchDirenvUpdate() {
+ holder.panels.forEach {
+ it.direnvChanged(direnv.isSelected)
+ }
+ }
+
+ override fun direnvChanged(state: Boolean) {
+ dispatchAutodetect(true)
+ }
+
private fun dispatchAutodetect(force: Boolean) {
project.zigCoroutineScope.launchWithEDT {
withModalProgress(ModalTaskOwner.component(pathToToolchain), "Detecting Zig...", TaskCancellation.cancellable()) {
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 97c22e0a..36c30c13 100644
--- a/core/src/main/kotlin/com/falsepattern/zigbrains/shared/MultiConfigurable.kt
+++ b/core/src/main/kotlin/com/falsepattern/zigbrains/shared/MultiConfigurable.kt
@@ -22,17 +22,19 @@
package com.falsepattern.zigbrains.shared
+import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvider
import com.intellij.openapi.options.Configurable
import com.intellij.openapi.util.Disposer
import com.intellij.ui.dsl.builder.panel
import javax.swing.JComponent
-abstract class MultiConfigurable(private val configurables: List): Configurable {
+abstract class MultiConfigurable(val configurables: List): Configurable, ZigProjectConfigurationProvider.SettingsPanelHolder {
+ final override var panels: List = emptyList()
+ private set
+
override fun createComponent(): JComponent? {
return panel {
- for (configurable in configurables) {
- configurable.createComponent(this)
- }
+ panels = configurables.map { it.createComponent(this@MultiConfigurable, this@panel) }
}
}
@@ -50,5 +52,6 @@ abstract class MultiConfigurable(private val configurables: List
+ icon="com.falsepattern.zigbrains.Icons.Zig">
+
+
diff --git a/core/src/main/resources/zigbrains/Bundle.properties b/core/src/main/resources/zigbrains/Bundle.properties
index 68fc69a0..62f99988 100644
--- a/core/src/main/resources/zigbrains/Bundle.properties
+++ b/core/src/main/resources/zigbrains/Bundle.properties
@@ -53,16 +53,6 @@ zig.color-settings.variable-decl-depr=Variable//Declaration//Deprecated
zig.color-settings.variable-ref=Variable//Reference
zig.color-settings.variable-ref-depr=Variable//Reference//Deprecated
zon.file.description=Zig object notation file
-configurable.name.zon-color-settings-page=Zon
-zon.color-settings.eq=Equals
-zon.color-settings.id=Identifier
-zon.color-settings.comment=Comment
-zon.color-settings.bad_char=Bad value
-zon.color-settings.string=String
-zon.color-settings.comma=Comma
-zon.color-settings.dot=Dot
-zon.color-settings.boolean=Boolean
-zon.color-settings.brace=Braces
notification.group.zigbrains=ZigBrains
notification.title.native-debug=Zig native debugger
notification.content.native-debug=You need to install the "Native Debugging Support" plugin for Zig debugging in this IDE!
diff --git a/gradle.properties b/gradle.properties
index baf9fddf..40695cd4 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,7 +1,7 @@
pluginName=ZigBrains
pluginRepositoryUrl=https://github.com/FalsePattern/ZigBrains
-pluginVersion=23.0.2
+pluginVersion=23.1.0
pluginSinceBuild=242
pluginUntilBuild=242.*
diff --git a/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSProjectConfigurationProvider.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSProjectConfigurationProvider.kt
index 5ce04806..5a1b423a 100644
--- a/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSProjectConfigurationProvider.kt
+++ b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSProjectConfigurationProvider.kt
@@ -38,7 +38,7 @@ class ZLSProjectConfigurationProvider: ZigProjectConfigurationProvider {
return ZLSSettingsConfigurable(project)
}
- override fun createNewProjectSettingsPanel(): ZigProjectConfigurationProvider.SettingsPanel {
+ override fun createNewProjectSettingsPanel(holder: ZigProjectConfigurationProvider.SettingsPanelHolder): ZigProjectConfigurationProvider.SettingsPanel {
return ZLSSettingsPanel(ProjectManager.getInstance().defaultProject)
}
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 370a2408..d197dd30 100644
--- a/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSStartup.kt
+++ b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSStartup.kt
@@ -26,6 +26,7 @@ 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.shared.zigCoroutineScope
import com.intellij.openapi.project.Project
import com.intellij.openapi.startup.ProjectActivity
@@ -38,7 +39,7 @@ 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)
+ val env = if (DirenvCmd.direnvInstalled() && !project.isDefault && project.zigProjectSettings.state.direnv)
project.getDirenv()
else
emptyEnv
diff --git a/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSStreamConnectionProvider.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSStreamConnectionProvider.kt
index b542353d..6470d863 100644
--- a/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSStreamConnectionProvider.kt
+++ b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/ZLSStreamConnectionProvider.kt
@@ -26,6 +26,7 @@ import com.falsepattern.zigbrains.direnv.emptyEnv
import com.falsepattern.zigbrains.direnv.getDirenv
import com.falsepattern.zigbrains.lsp.config.ZLSConfigProviderBase
import com.falsepattern.zigbrains.lsp.settings.zlsSettings
+import com.falsepattern.zigbrains.project.settings.zigProjectSettings
import com.intellij.execution.configurations.GeneralCommandLine
import com.intellij.notification.Notification
import com.intellij.notification.NotificationType
@@ -58,7 +59,7 @@ class ZLSStreamConnectionProvider private constructor(private val project: Proje
val state = svc.state
val zlsPath: Path = state.zlsPath.let { zlsPath ->
if (zlsPath.isEmpty()) {
- val env = if (state.direnv) project.getDirenv() else emptyEnv
+ val env = if (project.zigProjectSettings.state.direnv) project.getDirenv() else emptyEnv
env.findExecutableOnPATH("zls") ?: run {
Notification(
"zigbrains-lsp",
diff --git a/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSProjectSettingsService.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSProjectSettingsService.kt
index 5536bf4a..18039240 100644
--- a/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSProjectSettingsService.kt
+++ b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSProjectSettingsService.kt
@@ -26,6 +26,7 @@ import com.falsepattern.zigbrains.direnv.emptyEnv
import com.falsepattern.zigbrains.direnv.getDirenv
import com.falsepattern.zigbrains.lsp.ZLSBundle
import com.falsepattern.zigbrains.lsp.startLSP
+import com.falsepattern.zigbrains.project.settings.zigProjectSettings
import com.intellij.openapi.components.*
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.io.toNioPathOrNull
@@ -96,7 +97,7 @@ class ZLSProjectSettingsService(val project: Project): PersistentStateComponent<
private suspend fun doValidate(project: Project, state: ZLSSettings): Boolean {
val zlsPath: Path = state.zlsPath.let { zlsPath ->
if (zlsPath.isEmpty()) {
- val env = if (state.direnv) project.getDirenv() else emptyEnv
+ val env = if (project.zigProjectSettings.state.direnv) project.getDirenv() else emptyEnv
env.findExecutableOnPATH("zls") ?: run {
return false
}
diff --git a/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettings.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettings.kt
index 388e2007..d7f2f26e 100644
--- a/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettings.kt
+++ b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettings.kt
@@ -29,7 +29,6 @@ import org.jetbrains.annotations.NonNls
@Suppress("PropertyName")
data class ZLSSettings(
- var direnv: Boolean = false,
var zlsPath: @NonNls String = "",
var zlsConfigPath: @NonNls String = "",
val inlayHints: Boolean = true,
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 85363a92..fad06b27 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,6 +22,7 @@
package com.falsepattern.zigbrains.lsp.settings
+import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvider
import com.falsepattern.zigbrains.shared.SubConfigurable
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Disposer
@@ -29,8 +30,10 @@ import com.intellij.ui.dsl.builder.Panel
class ZLSSettingsConfigurable(private val project: Project): SubConfigurable {
private var appSettingsComponent: ZLSSettingsPanel? = null
- override fun createComponent(panel: Panel) {
- appSettingsComponent = ZLSSettingsPanel(project).apply { attach(panel) }.also { Disposer.register(this, it) }
+ override fun createComponent(holder: ZigProjectConfigurationProvider.SettingsPanelHolder, panel: Panel): ZigProjectConfigurationProvider.SettingsPanel {
+ val settingsPanel = ZLSSettingsPanel(project).apply { attach(panel) }.also { Disposer.register(this, it) }
+ appSettingsComponent = settingsPanel
+ return settingsPanel
}
override fun isModified(): Boolean {
diff --git a/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsPanel.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsPanel.kt
index e96a0f29..06def51b 100644
--- a/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsPanel.kt
+++ b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsPanel.kt
@@ -29,6 +29,7 @@ import com.falsepattern.zigbrains.direnv.getDirenv
import com.falsepattern.zigbrains.lsp.ZLSBundle
import com.falsepattern.zigbrains.lsp.config.SemanticTokens
import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvider
+import com.falsepattern.zigbrains.project.settings.zigProjectSettings
import com.falsepattern.zigbrains.shared.cli.call
import com.falsepattern.zigbrains.shared.cli.createCommandLineSafe
import com.falsepattern.zigbrains.shared.coroutine.launchWithEDT
@@ -87,6 +88,8 @@ class ZLSSettingsPanel(private val project: Project) : ZigProjectConfigurationPr
private var debounce: Job? = null
+ private var direnv: Boolean = project.zigProjectSettings.state.direnv
+
private val inlayHints = JBCheckBox()
private val enable_snippets = JBCheckBox()
private val enable_argument_placeholders = JBCheckBox()
@@ -109,12 +112,6 @@ class ZLSSettingsPanel(private val project: Project) : ZigProjectConfigurationPr
private val build_runner_path = ExtendableTextField()
private val global_cache_path = ExtendableTextField()
- private val direnv = JBCheckBox(ZLSBundle.message("settings.zls-path.use-direnv.label")).apply {
- addActionListener {
- dispatchAutodetect(true)
- }
- }
-
override fun attach(p: Panel) = with(p) {
if (!project.isDefault) {
group(ZLSBundle.message("settings.group.title")) {
@@ -123,9 +120,6 @@ class ZLSSettingsPanel(private val project: Project) : ZigProjectConfigurationPr
"settings.zls-path.tooltip"
) {
cell(zlsPath).resizableColumn().align(AlignX.FILL)
- if (DirenvCmd.direnvInstalled()) {
- cell(direnv)
- }
}
row(ZLSBundle.message("settings.zls-version.label")) {
cell(zlsVersion)
@@ -225,9 +219,13 @@ class ZLSSettingsPanel(private val project: Project) : ZigProjectConfigurationPr
dispatchAutodetect(false)
}
+ override fun direnvChanged(state: Boolean) {
+ direnv = state
+ dispatchAutodetect(true)
+ }
+
override var data
get() = ZLSSettings(
- direnv.isSelected,
zlsPath.text,
zlsConfigPath.text,
inlayHints.isSelected,
@@ -253,7 +251,6 @@ class ZLSSettingsPanel(private val project: Project) : ZigProjectConfigurationPr
global_cache_path.text?.ifBlank { null },
)
set(value) {
- direnv.isSelected = value.direnv
zlsPath.text = value.zlsPath
zlsConfigPath.text = value.zlsConfigPath
inlayHints.isSelected = value.inlayHints
@@ -305,7 +302,7 @@ class ZLSSettingsPanel(private val project: Project) : ZigProjectConfigurationPr
}
private suspend fun getDirenv(): Env {
- if (!project.isDefault && DirenvCmd.direnvInstalled() && direnv.isSelected)
+ if (!project.isDefault && DirenvCmd.direnvInstalled() && direnv)
return project.getDirenv()
return emptyEnv
}