fix: Only split args when passing them to a cmdline, store them as fixed strings
This commit is contained in:
parent
05ff125c1d
commit
91ee38e922
13 changed files with 38 additions and 105 deletions
|
@ -27,6 +27,9 @@ Changelog structure reference:
|
||||||
- Debugging
|
- Debugging
|
||||||
- Breakpoints could not be placed inside zig code in Android Studio
|
- 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]
|
## [21.1.0]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -39,7 +39,7 @@ class ZigExecConfigBinary(project: Project, factory: ConfigurationFactory) : Zig
|
||||||
get() = ZigDebugBundle.message("configuration.binary.suggested-name")
|
get() = ZigDebugBundle.message("configuration.binary.suggested-name")
|
||||||
|
|
||||||
override suspend fun buildCommandLineArgs(debug: Boolean): List<String> {
|
override suspend fun buildCommandLineArgs(debug: Boolean): List<String> {
|
||||||
return args.args
|
return args.argsSplit()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getConfigurables(): List<ZigConfigurable<*>> {
|
override fun getConfigurables(): List<ZigConfigurable<*>> {
|
||||||
|
|
|
@ -36,6 +36,6 @@ class ZigDebugParametersBinary @Throws(ExecutionException::class) constructor(dr
|
||||||
ZigDebugParametersBase<ZigProfileStateBinary>(driverConfiguration, toolchain, profileState) {
|
ZigDebugParametersBase<ZigProfileStateBinary>(driverConfiguration, toolchain, profileState) {
|
||||||
private val executableFile = profileState.configuration.exePath.path?.toFile() ?: throw ExecutionException(ZigDebugBundle.message("exception.missing-exe-path"))
|
private val executableFile = profileState.configuration.exePath.path?.toFile() ?: throw ExecutionException(ZigDebugBundle.message("exception.missing-exe-path"))
|
||||||
override fun getInstaller(): Installer {
|
override fun getInstaller(): Installer {
|
||||||
return ZigDebugEmitBinaryInstaller(profileState, toolchain, executableFile, profileState.configuration.args.args)
|
return ZigDebugEmitBinaryInstaller(profileState, toolchain, executableFile, profileState.configuration.args.argsSplit())
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -53,7 +53,7 @@ class ZigDebugParametersBuild(
|
||||||
private lateinit var executableFile: File
|
private lateinit var executableFile: File
|
||||||
|
|
||||||
override fun getInstaller(): Installer {
|
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)
|
@Throws(ExecutionException::class)
|
||||||
|
|
|
@ -32,6 +32,6 @@ import com.jetbrains.cidr.execution.debugger.backend.DebuggerDriverConfiguration
|
||||||
class ZigDebugParametersRun(driverConfiguration: DebuggerDriverConfiguration, toolchain: AbstractZigToolchain, profileState: ZigProfileStateRun) :
|
class ZigDebugParametersRun(driverConfiguration: DebuggerDriverConfiguration, toolchain: AbstractZigToolchain, profileState: ZigProfileStateRun) :
|
||||||
ZigDebugParametersEmitBinaryBase<ZigProfileStateRun>(driverConfiguration, toolchain, profileState) {
|
ZigDebugParametersEmitBinaryBase<ZigProfileStateRun>(driverConfiguration, toolchain, profileState) {
|
||||||
override fun getInstaller(): Installer {
|
override fun getInstaller(): Installer {
|
||||||
return ZigDebugEmitBinaryInstaller(profileState, toolchain, executableFile, profileState.configuration.exeArgs.args)
|
return ZigDebugEmitBinaryInstaller(profileState, toolchain, executableFile, profileState.configuration.exeArgs.argsSplit())
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -347,14 +347,18 @@ class ArgsConfigurable(
|
||||||
@Transient private val serializedName: String,
|
@Transient private val serializedName: String,
|
||||||
@Transient @Nls private val guiName: String
|
@Transient @Nls private val guiName: String
|
||||||
) : ZigConfigurable<ArgsConfigurable>, Cloneable {
|
) : ZigConfigurable<ArgsConfigurable>, Cloneable {
|
||||||
var args: List<String> = emptyList()
|
var args: String = ""
|
||||||
|
|
||||||
override fun readExternal(element: Element) {
|
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<String> {
|
||||||
|
return translateCommandline(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun writeExternal(element: Element) {
|
override fun writeExternal(element: Element) {
|
||||||
element.writeStrings(serializedName, args)
|
element.writeString(serializedName, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createEditor(): ZigConfigModule<ArgsConfigurable> {
|
override fun createEditor(): ZigConfigModule<ArgsConfigurable> {
|
||||||
|
@ -376,12 +380,12 @@ class ArgsConfigurable(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun apply(configurable: ArgsConfigurable): Boolean {
|
override fun apply(configurable: ArgsConfigurable): Boolean {
|
||||||
configurable.args = translateCommandline(argsField.text)
|
configurable.args = argsField.text ?: ""
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun reset(configurable: ArgsConfigurable) {
|
override fun reset(configurable: ArgsConfigurable) {
|
||||||
argsField.text = configurable.args.joinToString(separator = " ")
|
argsField.text = configurable.args
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun construct(p: Panel): Unit = with(p) {
|
override fun construct(p: Panel): Unit = with(p) {
|
||||||
|
|
|
@ -48,9 +48,10 @@ class ZigExecConfigBuild(project: Project, factory: ConfigurationFactory): ZigEx
|
||||||
override suspend fun buildCommandLineArgs(debug: Boolean): List<String> {
|
override suspend fun buildCommandLineArgs(debug: Boolean): List<String> {
|
||||||
val result = ArrayList<String>()
|
val result = ArrayList<String>()
|
||||||
result.add("build")
|
result.add("build")
|
||||||
|
val argsSplit = buildSteps.argsSplit()
|
||||||
val steps = if (debug) {
|
val steps = if (debug) {
|
||||||
val truncatedSteps = ArrayList<String>()
|
val truncatedSteps = ArrayList<String>()
|
||||||
for (step in buildSteps.args) {
|
for (step in argsSplit) {
|
||||||
if (step == "run")
|
if (step == "run")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -60,10 +61,10 @@ class ZigExecConfigBuild(project: Project, factory: ConfigurationFactory): ZigEx
|
||||||
truncatedSteps.add(step)
|
truncatedSteps.add(step)
|
||||||
}
|
}
|
||||||
truncatedSteps
|
truncatedSteps
|
||||||
} else buildSteps.args
|
} else argsSplit
|
||||||
result.addAll(steps)
|
result.addAll(steps)
|
||||||
result.addAll(coloredCliFlags(colored.value, debug))
|
result.addAll(coloredCliFlags(colored.value, debug))
|
||||||
result.addAll(extraArgs.args)
|
result.addAll(extraArgs.argsSplit())
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,10 +52,10 @@ class ZigExecConfigRun(project: Project, factory: ConfigurationFactory): ZigExec
|
||||||
if (!debug || optimization.forced) {
|
if (!debug || optimization.forced) {
|
||||||
result.addAll(listOf("-O", optimization.level.name))
|
result.addAll(listOf("-O", optimization.level.name))
|
||||||
}
|
}
|
||||||
result.addAll(compilerArgs.args)
|
result.addAll(compilerArgs.argsSplit())
|
||||||
if (!debug) {
|
if (!debug) {
|
||||||
result.add("--")
|
result.add("--")
|
||||||
result.addAll(exeArgs.args)
|
result.addAll(exeArgs.argsSplit())
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ class ZigExecConfigTest(project: Project, factory: ConfigurationFactory): ZigExe
|
||||||
if (!debug || optimization.forced) {
|
if (!debug || optimization.forced) {
|
||||||
result.addAll(listOf("-O", optimization.level.name))
|
result.addAll(listOf("-O", optimization.level.name))
|
||||||
}
|
}
|
||||||
result.addAll(compilerArgs.args)
|
result.addAll(compilerArgs.argsSplit())
|
||||||
if (debug) {
|
if (debug) {
|
||||||
result.add("--test-no-exec")
|
result.add("--test-no-exec")
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ class BuildToolWindowContext(private val project: Project): Disposable {
|
||||||
val factory = firstConfigFactory<ZigConfigTypeBuild>()
|
val factory = firstConfigFactory<ZigConfigTypeBuild>()
|
||||||
val newConfig = manager.createConfiguration("zig build $stepName", factory)
|
val newConfig = manager.createConfiguration("zig build $stepName", factory)
|
||||||
val config = newConfig.configuration as ZigExecConfigBuild
|
val config = newConfig.configuration as ZigExecConfigBuild
|
||||||
config.buildSteps.args = listOf(stepName)
|
config.buildSteps.args = stepName
|
||||||
manager.addConfiguration(newConfig)
|
manager.addConfiguration(newConfig)
|
||||||
return@run newConfig
|
return@run newConfig
|
||||||
}
|
}
|
||||||
|
@ -213,7 +213,7 @@ private fun getViewport(project: Project): JBScrollPane? {
|
||||||
private fun getExistingRunConfig(manager: RunManager, stepName: String): RunnerAndConfigurationSettings? {
|
private fun getExistingRunConfig(manager: RunManager, stepName: String): RunnerAndConfigurationSettings? {
|
||||||
for (config in manager.getConfigurationSettingsList(ZigConfigTypeBuild::class.java)) {
|
for (config in manager.getConfigurationSettingsList(ZigConfigTypeBuild::class.java)) {
|
||||||
val build = config.configuration as? ZigExecConfigBuild ?: continue
|
val build = config.configuration as? ZigExecConfigBuild ?: continue
|
||||||
val steps = build.buildSteps.args
|
val steps = build.buildSteps.argsSplit()
|
||||||
if (steps.size != 1)
|
if (steps.size != 1)
|
||||||
continue
|
continue
|
||||||
if (steps[0] != stepName)
|
if (steps[0] != stepName)
|
||||||
|
|
|
@ -38,7 +38,7 @@ data class ZLSSettings(
|
||||||
val enable_argument_placeholders: Boolean = true,
|
val enable_argument_placeholders: Boolean = true,
|
||||||
val completion_label_details: Boolean = true,
|
val completion_label_details: Boolean = true,
|
||||||
val enable_build_on_save: Boolean = false,
|
val enable_build_on_save: Boolean = false,
|
||||||
val build_on_save_args: List<String> = emptyList(),
|
val build_on_save_args: String = "",
|
||||||
val semantic_tokens: SemanticTokens = SemanticTokens.full,
|
val semantic_tokens: SemanticTokens = SemanticTokens.full,
|
||||||
val inlay_hints_show_variable_type_hints: Boolean = true,
|
val inlay_hints_show_variable_type_hints: Boolean = true,
|
||||||
val inlay_hints_show_struct_literal_field_type: Boolean = true,
|
val inlay_hints_show_struct_literal_field_type: Boolean = true,
|
||||||
|
|
|
@ -24,6 +24,7 @@ package com.falsepattern.zigbrains.lsp.settings
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.lsp.config.ZLSConfig
|
import com.falsepattern.zigbrains.lsp.config.ZLSConfig
|
||||||
import com.falsepattern.zigbrains.lsp.config.ZLSConfigProvider
|
import com.falsepattern.zigbrains.lsp.config.ZLSConfigProvider
|
||||||
|
import com.falsepattern.zigbrains.shared.cli.translateCommandline
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
|
||||||
class ZLSSettingsConfigProvider: ZLSConfigProvider {
|
class ZLSSettingsConfigProvider: ZLSConfigProvider {
|
||||||
|
@ -34,7 +35,14 @@ class ZLSSettingsConfigProvider: ZLSConfigProvider {
|
||||||
enable_argument_placeholders = state.enable_argument_placeholders,
|
enable_argument_placeholders = state.enable_argument_placeholders,
|
||||||
completion_label_details = state.completion_label_details,
|
completion_label_details = state.completion_label_details,
|
||||||
enable_build_on_save = state.enable_build_on_save,
|
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,
|
semantic_tokens = state.semantic_tokens,
|
||||||
inlay_hints_show_variable_type_hints = state.inlay_hints_show_variable_type_hints,
|
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,
|
inlay_hints_show_struct_literal_field_type = state.inlay_hints_show_struct_literal_field_type,
|
||||||
|
|
|
@ -207,14 +207,7 @@ class ZLSSettingsPanel(private val project: Project) : ZigProjectConfigurationPr
|
||||||
enable_argument_placeholders.isSelected,
|
enable_argument_placeholders.isSelected,
|
||||||
completion_label_details.isSelected,
|
completion_label_details.isSelected,
|
||||||
enable_build_on_save.isSelected,
|
enable_build_on_save.isSelected,
|
||||||
run {
|
build_on_save_args.text,
|
||||||
val args = build_on_save_args.text ?: ""
|
|
||||||
return@run if (args.isEmpty()) {
|
|
||||||
emptyList()
|
|
||||||
} else {
|
|
||||||
translateCommandline(args).toList()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
semantic_tokens.item ?: SemanticTokens.full,
|
semantic_tokens.item ?: SemanticTokens.full,
|
||||||
inlay_hints_show_variable_type_hints.isSelected,
|
inlay_hints_show_variable_type_hints.isSelected,
|
||||||
inlay_hints_show_struct_literal_field_type.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
|
enable_argument_placeholders.isSelected = value.enable_argument_placeholders
|
||||||
completion_label_details.isSelected = value.completion_label_details
|
completion_label_details.isSelected = value.completion_label_details
|
||||||
enable_build_on_save.isSelected = value.enable_build_on_save
|
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
|
semantic_tokens.item = value.semantic_tokens
|
||||||
inlay_hints_show_variable_type_hints.isSelected = value.inlay_hints_show_variable_type_hints
|
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
|
inlay_hints_show_struct_literal_field_type.isSelected = value.inlay_hints_show_struct_literal_field_type
|
||||||
|
@ -295,79 +288,3 @@ private fun Panel.fancyRow(
|
||||||
contextHelp(ZLSBundle.message(tooltip))
|
contextHelp(ZLSBundle.message(tooltip))
|
||||||
cb()
|
cb()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Throws(Exception::class)
|
|
||||||
private fun translateCommandline(toProcess: String): List<String> {
|
|
||||||
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<String>()
|
|
||||||
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")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue