feat: centralize direnv config
This commit is contained in:
parent
612841724c
commit
cc062b533e
17 changed files with 66 additions and 46 deletions
|
@ -17,6 +17,11 @@ Changelog structure reference:
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
### Changed
|
||||
|
||||
- Direnv
|
||||
- Centralized all direnv toggling into a single project-level option
|
||||
|
||||
## [23.0.2]
|
||||
|
||||
### Fixed
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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<T: ZigExecConfig<T>>(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<T: ZigExecConfig<T>>(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<T: ZigExecConfig<T>>(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<ZigConfigurable<*>> = listOf(workingDirectory, pty, direnv)
|
||||
open fun getConfigurables(): List<ZigConfigurable<*>> = listOf(workingDirectory, pty)
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<ZigProjectConfigurationProvider>("com.falsepattern.zigbrains.projectConfigProvider")
|
||||
|
@ -42,13 +42,17 @@ interface ZigProjectConfigurationProvider {
|
|||
fun createConfigurables(project: Project): List<SubConfigurable> {
|
||||
return EXTENSION_POINT_NAME.extensionList.sortedBy { it.priority }.map { it.createConfigurable(project) }
|
||||
}
|
||||
fun createNewProjectSettingsPanels(): List<SettingsPanel> {
|
||||
return EXTENSION_POINT_NAME.extensionList.sortedBy { it.priority }.mapNotNull { it.createNewProjectSettingsPanel() }
|
||||
fun createNewProjectSettingsPanels(holder: SettingsPanelHolder): List<SettingsPanel> {
|
||||
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<SettingsPanel>
|
||||
}
|
||||
interface Settings {
|
||||
fun apply(project: Project)
|
||||
|
|
|
@ -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,
|
||||
|
@ -84,6 +84,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()) {
|
||||
|
|
|
@ -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<SubConfigurable>): Configurable {
|
||||
abstract class MultiConfigurable(val configurables: List<SubConfigurable>): Configurable, ZigProjectConfigurationProvider.SettingsPanelHolder {
|
||||
final override var panels: List<ZigProjectConfigurationProvider.SettingsPanel> = 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<SubConfigurable
|
|||
|
||||
override fun disposeUIResources() {
|
||||
configurables.forEach { Disposer.dispose(it) }
|
||||
panels = emptyList()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,12 +22,14 @@
|
|||
|
||||
package com.falsepattern.zigbrains.shared
|
||||
|
||||
import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvider
|
||||
import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvider.SettingsPanelHolder
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.options.ConfigurationException
|
||||
import com.intellij.ui.dsl.builder.Panel
|
||||
|
||||
interface SubConfigurable: Disposable {
|
||||
fun createComponent(panel: Panel)
|
||||
fun createComponent(holder: SettingsPanelHolder, panel: Panel): ZigProjectConfigurationProvider.SettingsPanel
|
||||
fun isModified(): Boolean
|
||||
@Throws(ConfigurationException::class)
|
||||
fun apply()
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue