diff --git a/CHANGELOG.md b/CHANGELOG.md index c07b71b4..cd2b9630 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,9 @@ Changelog structure reference: - Debugging - Breakpoints could not be placed inside zig code in Android Studio +- Project + - Zig run/debug configuration command line arguments would lose quotes around arguments + ## [21.1.0] ### Added diff --git a/cidr/src/main/kotlin/com/falsepattern/zigbrains/debugger/execution/binary/ZigExecConfigBinary.kt b/cidr/src/main/kotlin/com/falsepattern/zigbrains/debugger/execution/binary/ZigExecConfigBinary.kt index b7beed30..f6da872e 100644 --- a/cidr/src/main/kotlin/com/falsepattern/zigbrains/debugger/execution/binary/ZigExecConfigBinary.kt +++ b/cidr/src/main/kotlin/com/falsepattern/zigbrains/debugger/execution/binary/ZigExecConfigBinary.kt @@ -39,7 +39,7 @@ class ZigExecConfigBinary(project: Project, factory: ConfigurationFactory) : Zig get() = ZigDebugBundle.message("configuration.binary.suggested-name") override suspend fun buildCommandLineArgs(debug: Boolean): List { - return args.args + return args.argsSplit() } override fun getConfigurables(): List> { diff --git a/cidr/src/main/kotlin/com/falsepattern/zigbrains/debugger/runner/binary/ZigDebugParametersBinary.kt b/cidr/src/main/kotlin/com/falsepattern/zigbrains/debugger/runner/binary/ZigDebugParametersBinary.kt index f253d691..95620485 100644 --- a/cidr/src/main/kotlin/com/falsepattern/zigbrains/debugger/runner/binary/ZigDebugParametersBinary.kt +++ b/cidr/src/main/kotlin/com/falsepattern/zigbrains/debugger/runner/binary/ZigDebugParametersBinary.kt @@ -36,6 +36,6 @@ class ZigDebugParametersBinary @Throws(ExecutionException::class) constructor(dr ZigDebugParametersBase(driverConfiguration, toolchain, profileState) { private val executableFile = profileState.configuration.exePath.path?.toFile() ?: throw ExecutionException(ZigDebugBundle.message("exception.missing-exe-path")) override fun getInstaller(): Installer { - return ZigDebugEmitBinaryInstaller(profileState, toolchain, executableFile, profileState.configuration.args.args) + return ZigDebugEmitBinaryInstaller(profileState, toolchain, executableFile, profileState.configuration.args.argsSplit()) } } \ No newline at end of file diff --git a/cidr/src/main/kotlin/com/falsepattern/zigbrains/debugger/runner/build/ZigDebugParametersBuild.kt b/cidr/src/main/kotlin/com/falsepattern/zigbrains/debugger/runner/build/ZigDebugParametersBuild.kt index a0a3ff76..b8b31068 100644 --- a/cidr/src/main/kotlin/com/falsepattern/zigbrains/debugger/runner/build/ZigDebugParametersBuild.kt +++ b/cidr/src/main/kotlin/com/falsepattern/zigbrains/debugger/runner/build/ZigDebugParametersBuild.kt @@ -53,7 +53,7 @@ class ZigDebugParametersBuild( private lateinit var executableFile: File override fun getInstaller(): Installer { - return ZigDebugEmitBinaryInstaller(profileState, toolchain, executableFile, profileState.configuration.exeArgs.args) + return ZigDebugEmitBinaryInstaller(profileState, toolchain, executableFile, profileState.configuration.exeArgs.argsSplit()) } @Throws(ExecutionException::class) diff --git a/cidr/src/main/kotlin/com/falsepattern/zigbrains/debugger/runner/run/ZigDebugParametersRun.kt b/cidr/src/main/kotlin/com/falsepattern/zigbrains/debugger/runner/run/ZigDebugParametersRun.kt index 1b09d4ec..32558668 100644 --- a/cidr/src/main/kotlin/com/falsepattern/zigbrains/debugger/runner/run/ZigDebugParametersRun.kt +++ b/cidr/src/main/kotlin/com/falsepattern/zigbrains/debugger/runner/run/ZigDebugParametersRun.kt @@ -32,6 +32,6 @@ import com.jetbrains.cidr.execution.debugger.backend.DebuggerDriverConfiguration class ZigDebugParametersRun(driverConfiguration: DebuggerDriverConfiguration, toolchain: AbstractZigToolchain, profileState: ZigProfileStateRun) : ZigDebugParametersEmitBinaryBase(driverConfiguration, toolchain, profileState) { override fun getInstaller(): Installer { - return ZigDebugEmitBinaryInstaller(profileState, toolchain, executableFile, profileState.configuration.exeArgs.args) + return ZigDebugEmitBinaryInstaller(profileState, toolchain, executableFile, profileState.configuration.exeArgs.argsSplit()) } } \ 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 a3bee826..b716b7ca 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 @@ -347,14 +347,18 @@ class ArgsConfigurable( @Transient private val serializedName: String, @Transient @Nls private val guiName: String ) : ZigConfigurable, Cloneable { - var args: List = emptyList() + var args: String = "" override fun readExternal(element: Element) { - args = element.readStrings(serializedName) ?: return + args = element.readString(serializedName) ?: element.readStrings(serializedName)?.joinToString(separator = " ") { if (it.contains(' ')) "\"$it\"" else it } ?: "" + } + + fun argsSplit(): List { + return translateCommandline(args) } override fun writeExternal(element: Element) { - element.writeStrings(serializedName, args) + element.writeString(serializedName, args) } override fun createEditor(): ZigConfigModule { @@ -376,12 +380,12 @@ class ArgsConfigurable( } override fun apply(configurable: ArgsConfigurable): Boolean { - configurable.args = translateCommandline(argsField.text) + configurable.args = argsField.text ?: "" return true } override fun reset(configurable: ArgsConfigurable) { - argsField.text = configurable.args.joinToString(separator = " ") + argsField.text = configurable.args } override fun construct(p: Panel): Unit = with(p) { diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/build/ZigExecConfigBuild.kt b/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/build/ZigExecConfigBuild.kt index 5a0bcb4a..c77c408b 100644 --- a/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/build/ZigExecConfigBuild.kt +++ b/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/build/ZigExecConfigBuild.kt @@ -48,9 +48,10 @@ class ZigExecConfigBuild(project: Project, factory: ConfigurationFactory): ZigEx override suspend fun buildCommandLineArgs(debug: Boolean): List { val result = ArrayList() result.add("build") + val argsSplit = buildSteps.argsSplit() val steps = if (debug) { val truncatedSteps = ArrayList() - for (step in buildSteps.args) { + for (step in argsSplit) { if (step == "run") continue @@ -60,10 +61,10 @@ class ZigExecConfigBuild(project: Project, factory: ConfigurationFactory): ZigEx truncatedSteps.add(step) } truncatedSteps - } else buildSteps.args + } else argsSplit result.addAll(steps) result.addAll(coloredCliFlags(colored.value, debug)) - result.addAll(extraArgs.args) + result.addAll(extraArgs.argsSplit()) return result } diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/run/ZigExecConfigRun.kt b/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/run/ZigExecConfigRun.kt index d68a6dce..b399105d 100644 --- a/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/run/ZigExecConfigRun.kt +++ b/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/run/ZigExecConfigRun.kt @@ -52,10 +52,10 @@ class ZigExecConfigRun(project: Project, factory: ConfigurationFactory): ZigExec if (!debug || optimization.forced) { result.addAll(listOf("-O", optimization.level.name)) } - result.addAll(compilerArgs.args) + result.addAll(compilerArgs.argsSplit()) if (!debug) { result.add("--") - result.addAll(exeArgs.args) + result.addAll(exeArgs.argsSplit()) } return result } diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/test/ZigExecConfigTest.kt b/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/test/ZigExecConfigTest.kt index a5894756..4f37fee3 100644 --- a/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/test/ZigExecConfigTest.kt +++ b/core/src/main/kotlin/com/falsepattern/zigbrains/project/execution/test/ZigExecConfigTest.kt @@ -51,7 +51,7 @@ class ZigExecConfigTest(project: Project, factory: ConfigurationFactory): ZigExe if (!debug || optimization.forced) { result.addAll(listOf("-O", optimization.level.name)) } - result.addAll(compilerArgs.args) + result.addAll(compilerArgs.argsSplit()) if (debug) { result.add("--test-no-exec") } diff --git a/core/src/main/kotlin/com/falsepattern/zigbrains/project/steps/ui/BuildToolWindowContext.kt b/core/src/main/kotlin/com/falsepattern/zigbrains/project/steps/ui/BuildToolWindowContext.kt index 3112ec4e..d2d61dc6 100644 --- a/core/src/main/kotlin/com/falsepattern/zigbrains/project/steps/ui/BuildToolWindowContext.kt +++ b/core/src/main/kotlin/com/falsepattern/zigbrains/project/steps/ui/BuildToolWindowContext.kt @@ -87,7 +87,7 @@ class BuildToolWindowContext(private val project: Project): Disposable { val factory = firstConfigFactory() val newConfig = manager.createConfiguration("zig build $stepName", factory) val config = newConfig.configuration as ZigExecConfigBuild - config.buildSteps.args = listOf(stepName) + config.buildSteps.args = stepName manager.addConfiguration(newConfig) return@run newConfig } @@ -213,7 +213,7 @@ private fun getViewport(project: Project): JBScrollPane? { private fun getExistingRunConfig(manager: RunManager, stepName: String): RunnerAndConfigurationSettings? { for (config in manager.getConfigurationSettingsList(ZigConfigTypeBuild::class.java)) { val build = config.configuration as? ZigExecConfigBuild ?: continue - val steps = build.buildSteps.args + val steps = build.buildSteps.argsSplit() if (steps.size != 1) continue if (steps[0] != stepName) 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 51c29771..48e8bf13 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 @@ -38,7 +38,7 @@ data class ZLSSettings( val enable_argument_placeholders: Boolean = true, val completion_label_details: Boolean = true, val enable_build_on_save: Boolean = false, - val build_on_save_args: List = emptyList(), + val build_on_save_args: String = "", val semantic_tokens: SemanticTokens = SemanticTokens.full, val inlay_hints_show_variable_type_hints: Boolean = true, val inlay_hints_show_struct_literal_field_type: Boolean = true, diff --git a/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsConfigProvider.kt b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsConfigProvider.kt index 5d42ab13..b11e3ab4 100644 --- a/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsConfigProvider.kt +++ b/lsp/src/main/kotlin/com/falsepattern/zigbrains/lsp/settings/ZLSSettingsConfigProvider.kt @@ -24,6 +24,7 @@ package com.falsepattern.zigbrains.lsp.settings import com.falsepattern.zigbrains.lsp.config.ZLSConfig import com.falsepattern.zigbrains.lsp.config.ZLSConfigProvider +import com.falsepattern.zigbrains.shared.cli.translateCommandline import com.intellij.openapi.project.Project class ZLSSettingsConfigProvider: ZLSConfigProvider { @@ -34,7 +35,14 @@ class ZLSSettingsConfigProvider: ZLSConfigProvider { enable_argument_placeholders = state.enable_argument_placeholders, completion_label_details = state.completion_label_details, enable_build_on_save = state.enable_build_on_save, - build_on_save_args = state.build_on_save_args, + build_on_save_args = run { + val args = state.build_on_save_args + return@run if (args.isEmpty()) { + emptyList() + } else { + translateCommandline(args).toList() + } + }, semantic_tokens = state.semantic_tokens, inlay_hints_show_variable_type_hints = state.inlay_hints_show_variable_type_hints, inlay_hints_show_struct_literal_field_type = state.inlay_hints_show_struct_literal_field_type, 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 494c6e15..7843bf6a 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 @@ -207,14 +207,7 @@ class ZLSSettingsPanel(private val project: Project) : ZigProjectConfigurationPr enable_argument_placeholders.isSelected, completion_label_details.isSelected, enable_build_on_save.isSelected, - run { - val args = build_on_save_args.text ?: "" - return@run if (args.isEmpty()) { - emptyList() - } else { - translateCommandline(args).toList() - } - }, + build_on_save_args.text, semantic_tokens.item ?: SemanticTokens.full, inlay_hints_show_variable_type_hints.isSelected, inlay_hints_show_struct_literal_field_type.isSelected, @@ -240,7 +233,7 @@ class ZLSSettingsPanel(private val project: Project) : ZigProjectConfigurationPr enable_argument_placeholders.isSelected = value.enable_argument_placeholders completion_label_details.isSelected = value.completion_label_details enable_build_on_save.isSelected = value.enable_build_on_save - build_on_save_args.text = value.build_on_save_args.joinToString(separator = " ") { it } + build_on_save_args.text = value.build_on_save_args semantic_tokens.item = value.semantic_tokens inlay_hints_show_variable_type_hints.isSelected = value.inlay_hints_show_variable_type_hints inlay_hints_show_struct_literal_field_type.isSelected = value.inlay_hints_show_struct_literal_field_type @@ -294,80 +287,4 @@ private fun Panel.fancyRow( ) = row(ZLSBundle.message(label)) { contextHelp(ZLSBundle.message(tooltip)) cb() -} - - -@Throws(Exception::class) -private fun translateCommandline(toProcess: String): List { - if (toProcess.isEmpty()) { - return emptyList() - } - val normal = 0 - val inQuote = 1 - val inDoubleQuote = 2 - val inEscape = 3 - var state = normal - var escapeState = normal - val tok = StringTokenizer(toProcess, "\\\"' ", true) - val v = ArrayList() - val current = StringBuilder() - - while (tok.hasMoreTokens()) { - val nextTok = tok.nextToken() - when (state) { - inQuote -> if ("'" == nextTok) { - state = normal - } else if ("\\" == nextTok) { - escapeState = inQuote - state = inEscape - } else { - current.append(nextTok) - } - - inDoubleQuote -> if ("\"" == nextTok) { - state = normal - } else if ("\\" == nextTok) { - escapeState = inDoubleQuote - state = inEscape - } else { - current.append(nextTok) - } - - inEscape -> { - current.append(when(nextTok) { - "n" -> "\n" - "r" -> "\r" - "t" -> "\t" - else -> nextTok - }) - state = escapeState - } - - else -> if ("'" == nextTok) { - state = inQuote - } else if ("\"" == nextTok) { - state = inDoubleQuote - } else if (" " == nextTok) { - if (current.isNotEmpty()) { - v.add(current.toString()) - current.setLength(0) - } - } else if ("\\" == nextTok) { - escapeState = normal - state = inEscape - } else { - current.append(nextTok) - } - } - } - - if (current.isNotEmpty()) { - v.add(current.toString()) - } - - if (state != inQuote && state != inDoubleQuote) { - return v - } else { - throw IllegalArgumentException("unbalanced quotes in $toProcess") - } -} +} \ No newline at end of file