Compare commits
No commits in common. "master" and "25.1.0" have entirely different histories.
14 changed files with 36 additions and 155 deletions
17
CHANGELOG.md
17
CHANGELOG.md
|
@ -17,23 +17,6 @@ Changelog structure reference:
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
## [25.2.0]
|
||||
|
||||
### Added
|
||||
|
||||
- Debugger
|
||||
- Notify the user if zig run / zig test debugging starts, but a build.zig is present
|
||||
|
||||
### Changed
|
||||
|
||||
- Project
|
||||
- Line marker task suggestions for main/test now defer to Zig Build if build.zig file is detected.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Debugger
|
||||
- Compilation failures did not open the terminal properly and suppressed the error message
|
||||
|
||||
## [25.1.0]
|
||||
|
||||
### Added
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
package com.falsepattern.zigbrains.debugger.runner.base
|
||||
|
||||
import com.falsepattern.zigbrains.project.run.ZigProcessHandler
|
||||
import com.falsepattern.zigbrains.shared.cli.startIPCAwareProcess
|
||||
import com.intellij.execution.ExecutionException
|
||||
import com.intellij.execution.configurations.GeneralCommandLine
|
||||
|
@ -41,7 +40,7 @@ import kotlinx.coroutines.withContext
|
|||
class PreLaunchProcessListener(val console: ConsoleView) : ProcessListener {
|
||||
var isBuildFailed: Boolean = false
|
||||
private set
|
||||
lateinit var processHandler: ZigProcessHandler.IPCAware
|
||||
lateinit var processHandler: ProcessHandler
|
||||
private set
|
||||
|
||||
@Throws(ExecutionException::class)
|
||||
|
@ -51,7 +50,7 @@ class PreLaunchProcessListener(val console: ConsoleView) : ProcessListener {
|
|||
this@PreLaunchProcessListener.processHandler = processHandler
|
||||
hook(processHandler)
|
||||
processHandler.startNotify()
|
||||
withContext(Dispatchers.IO) {
|
||||
withContext(Dispatchers.Default) {
|
||||
processHandler.process.awaitExit()
|
||||
}
|
||||
runInterruptible {
|
||||
|
|
|
@ -27,7 +27,6 @@ import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
|||
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||
import com.intellij.execution.ExecutionException
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.util.io.toNioPathOrNull
|
||||
import com.intellij.platform.util.progress.withProgressText
|
||||
import com.intellij.util.containers.orNull
|
||||
import com.jetbrains.cidr.execution.debugger.backend.DebuggerDriverConfiguration
|
||||
|
@ -37,7 +36,6 @@ import java.io.File
|
|||
import java.nio.file.Files
|
||||
import kotlin.io.path.absolutePathString
|
||||
import kotlin.io.path.isExecutable
|
||||
import kotlin.io.path.pathString
|
||||
|
||||
abstract class ZigDebugParametersEmitBinaryBase<ProfileState: ZigProfileState<*>>(
|
||||
driverConfiguration: DebuggerDriverConfiguration,
|
||||
|
@ -51,14 +49,13 @@ abstract class ZigDebugParametersEmitBinaryBase<ProfileState: ZigProfileState<*>
|
|||
@Throws(ExecutionException::class)
|
||||
private suspend fun compileExe(listener: PreLaunchProcessListener): File {
|
||||
val commandLine = profileState.getCommandLine(toolchain, true)
|
||||
val cliString = commandLine.getCommandLineString(commandLine.exePath.toNioPathOrNull()?.fileName?.pathString)
|
||||
val tmpDir = FileUtil.createTempDirectory("zigbrains_debug", "", true).toPath()
|
||||
|
||||
val exe = tmpDir.resolve("executable")
|
||||
commandLine.addParameters("-femit-bin=${exe.absolutePathString()}")
|
||||
|
||||
if (listener.executeCommandLineWithHook(profileState.environment.project, commandLine))
|
||||
throw ExecutionException(ZigDebugBundle.message("debug.base.compile.failed.generic", cliString))
|
||||
throw ExecutionException(ZigDebugBundle.message("debug.base.compile.failed.generic"))
|
||||
|
||||
return withContext(Dispatchers.IO) {
|
||||
Files.list(tmpDir).use { stream ->
|
||||
|
|
|
@ -24,7 +24,6 @@ package com.falsepattern.zigbrains.debugger.runner.base
|
|||
|
||||
import com.falsepattern.zigbrains.debugbridge.ZigDebuggerDriverConfigurationProviderBase
|
||||
import com.falsepattern.zigbrains.debugger.ZigLocalDebugProcess
|
||||
import com.falsepattern.zigbrains.debugger.runner.build.ZigDebugRunnerBuild
|
||||
import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
||||
import com.falsepattern.zigbrains.project.run.ZigProgramRunner
|
||||
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||
|
@ -42,7 +41,6 @@ import com.intellij.execution.ui.ConsoleView
|
|||
import com.intellij.execution.ui.ConsoleViewContentType
|
||||
import com.intellij.execution.ui.RunContentDescriptor
|
||||
import com.intellij.openapi.application.ModalityState
|
||||
import com.intellij.openapi.project.guessProjectDir
|
||||
import com.intellij.platform.util.progress.reportProgress
|
||||
import com.intellij.xdebugger.XDebugProcess
|
||||
import com.intellij.xdebugger.XDebugProcessStarter
|
||||
|
@ -84,13 +82,11 @@ abstract class ZigDebugRunnerBase<ProfileState : ZigProfileState<*>> : ZigProgra
|
|||
}
|
||||
} catch (e: ExecutionException) {
|
||||
console.print("\n", ConsoleViewContentType.ERROR_OUTPUT)
|
||||
e.message?.let { listener.console.print(it, ConsoleViewContentType.ERROR_OUTPUT) }
|
||||
if (this !is ZigDebugRunnerBuild && environment.project.guessProjectDir()?.children?.any { it.name == "build.zig" } == true) {
|
||||
console.print("\n Warning: build.zig file detected in project.\n Did you want to use a Zig Build task instead?", ConsoleViewContentType.ERROR_OUTPUT)
|
||||
}
|
||||
e.message?.let { listener.console.print(it, ConsoleViewContentType.SYSTEM_OUTPUT) }
|
||||
throw e;
|
||||
}
|
||||
if (listener.isBuildFailed) {
|
||||
val executionResult = DefaultExecutionResult(console, listener.processHandler.unwrap())
|
||||
val executionResult = DefaultExecutionResult(console, listener.processHandler)
|
||||
return@reportProgress withEDTContext(ModalityState.any()) {
|
||||
val runContentBuilder = RunContentBuilder(executionResult, environment)
|
||||
runContentBuilder.showRunContent(null)
|
||||
|
|
|
@ -15,7 +15,7 @@ debugger.run.unavailable.reason.download.button=Download
|
|||
debugger.run.unavailable.reason.update=Debugger is outdated
|
||||
debugger.run.unavailable.reason.update.button=Update
|
||||
debug.build.compile.failed.boilerplate={0}\nPlease edit this intellij build configuration and specify the path of the executable created by "zig build" directly!
|
||||
debug.base.compile.failed.generic=Failed to compile executable with command: {0}
|
||||
debug.base.compile.failed.generic=Failed to compile executable
|
||||
debug.base.compile.failed.no-exe=Failed to find compiled binary
|
||||
debug.build.compile.failed.multiple-exe=Multiple compiled binaries found
|
||||
debug.build.compile.failed.no-workdir=Cannot find working directory to run debugged executable
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.falsepattern.zigbrains.project.execution.base
|
||||
|
||||
import com.falsepattern.zigbrains.zig.psi.ZigContainerMembers
|
||||
import com.falsepattern.zigbrains.zig.psi.ZigFile
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.isFile
|
||||
import com.intellij.psi.util.childrenOfType
|
||||
|
||||
fun ZigFile.hasMainFunction(): Boolean {
|
||||
val members = childrenOfType<ZigContainerMembers>().firstOrNull() ?: return false
|
||||
return members.containerDeclarationList.any { it.decl?.fnProto?.identifier?.textMatches("main") == true }
|
||||
}
|
||||
|
||||
fun ZigFile.hasTests(): Boolean {
|
||||
val members = childrenOfType<ZigContainerMembers>().firstOrNull() ?: return false
|
||||
return members.containerDeclarationList.any { it.testDecl != null }
|
||||
}
|
||||
|
||||
fun VirtualFile.findBuildZig(): VirtualFile? {
|
||||
var parent = this.parent
|
||||
while (parent != null) {
|
||||
parent.children.forEach {
|
||||
if (it.isFile && it.name == "build.zig") {
|
||||
return it
|
||||
}
|
||||
}
|
||||
parent = parent.parent
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun VirtualFile.isBuildZig(): Boolean {
|
||||
return name == "build.zig"
|
||||
}
|
|
@ -24,16 +24,12 @@ 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.base.findBuildZig
|
||||
import com.falsepattern.zigbrains.project.execution.base.isBuildZig
|
||||
import com.falsepattern.zigbrains.project.execution.firstConfigFactory
|
||||
import com.falsepattern.zigbrains.zig.psi.ZigFile
|
||||
import com.falsepattern.zigbrains.zig.psi.ZigTypes
|
||||
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.elementType
|
||||
import java.nio.file.Path
|
||||
|
||||
class ZigConfigProducerBuild: ZigConfigProducer<ZigExecConfigBuild>() {
|
||||
|
@ -42,42 +38,17 @@ class ZigConfigProducerBuild: ZigConfigProducer<ZigExecConfigBuild>() {
|
|||
}
|
||||
|
||||
override fun setupConfigurationFromContext(configuration: ZigExecConfigBuild, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean {
|
||||
if (theFile.isBuildZig()) {
|
||||
configuration.name = ZigBrainsBundle.message("configuration.build.marker-run")
|
||||
configuration.buildSteps.args = "run"
|
||||
configuration.debugBuildSteps.args = "install"
|
||||
return true
|
||||
}
|
||||
val buildZig = theFile.findBuildZig() ?: return false
|
||||
configuration.workingDirectory.path = buildZig.parent.toNioPath()
|
||||
if (element.elementType == ZigTypes.KEYWORD_TEST) {
|
||||
configuration.name = ZigBrainsBundle.message("configuration.build.marker-test")
|
||||
configuration.buildSteps.args = "test"
|
||||
configuration.debugBuildSteps.args = "install_test"
|
||||
return true
|
||||
} else {
|
||||
configuration.name = ZigBrainsBundle.message("configuration.build.marker-run")
|
||||
configuration.buildSteps.args = "run"
|
||||
configuration.debugBuildSteps.args = "install"
|
||||
return true
|
||||
}
|
||||
if (theFile.name != "build.zig")
|
||||
return false
|
||||
configuration.name = ZigBrainsBundle.message("configuration.build.marker-name")
|
||||
return true
|
||||
}
|
||||
|
||||
override fun isConfigurationFromContext(configuration: ZigExecConfigBuild, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean {
|
||||
val dir = configuration.workingDirectory.path ?: return false
|
||||
if (theFile.isBuildZig()) {
|
||||
return filePath.parent == dir
|
||||
} else {
|
||||
if (element.elementType == ZigTypes.KEYWORD_TEST) {
|
||||
if (configuration.buildSteps.args != "test")
|
||||
return false
|
||||
}
|
||||
val buildZig = theFile.findBuildZig() ?: return false
|
||||
return buildZig.parent.toNioPath() == dir
|
||||
}
|
||||
return filePath.parent == (configuration.workingDirectory.path ?: return false)
|
||||
}
|
||||
|
||||
override fun shouldReplace(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean {
|
||||
return self.configurationType is ZigConfigTypeBuild
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,14 +23,14 @@
|
|||
package com.falsepattern.zigbrains.project.execution.run
|
||||
|
||||
import com.falsepattern.zigbrains.project.execution.base.ZigConfigProducer
|
||||
import com.falsepattern.zigbrains.project.execution.base.findBuildZig
|
||||
import com.falsepattern.zigbrains.project.execution.base.hasMainFunction
|
||||
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<ZigExecConfigRun>() {
|
||||
|
@ -39,10 +39,8 @@ class ZigConfigProducerRun: ZigConfigProducer<ZigExecConfigRun>() {
|
|||
}
|
||||
|
||||
override fun setupConfigurationFromContext(configuration: ZigExecConfigRun, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean {
|
||||
if (!psiFile.hasMainFunction()) {
|
||||
return false
|
||||
}
|
||||
if (theFile.findBuildZig() != null) {
|
||||
val members = psiFile.childrenOfType<ZigContainerMembers>().firstOrNull() ?: return false
|
||||
if (members.containerDeclarationList.none { it.decl?.fnProto?.identifier?.textMatches("main") == true }) {
|
||||
return false
|
||||
}
|
||||
configuration.filePath.path = filePath
|
||||
|
@ -58,3 +56,5 @@ class ZigConfigProducerRun: ZigConfigProducer<ZigExecConfigRun>() {
|
|||
return self.configurationType is ZigConfigTypeRun
|
||||
}
|
||||
}
|
||||
|
||||
private val LINE_MARKER = ZigLineMarkerRun()
|
|
@ -24,14 +24,14 @@ 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.base.findBuildZig
|
||||
import com.falsepattern.zigbrains.project.execution.base.hasTests
|
||||
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<ZigExecConfigTest>() {
|
||||
|
@ -40,10 +40,8 @@ class ZigConfigProducerTest: ZigConfigProducer<ZigExecConfigTest>() {
|
|||
}
|
||||
|
||||
override fun setupConfigurationFromContext(configuration: ZigExecConfigTest, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean {
|
||||
if (!psiFile.hasTests()) {
|
||||
return false
|
||||
}
|
||||
if (theFile.findBuildZig() != null) {
|
||||
val members = psiFile.childrenOfType<ZigContainerMembers>().firstOrNull() ?: return false
|
||||
if (members.containerDeclarationList.none { it.testDecl != null }) {
|
||||
return false
|
||||
}
|
||||
configuration.filePath.path = filePath
|
||||
|
|
|
@ -28,25 +28,14 @@ import com.intellij.execution.process.KillableProcessHandler
|
|||
import com.pty4j.PtyProcess
|
||||
import java.nio.charset.Charset
|
||||
|
||||
open class ZigProcessHandler : KillableProcessHandler {
|
||||
class ZigProcessHandler : KillableProcessHandler {
|
||||
constructor(commandLine: GeneralCommandLine) : super(commandLine) {
|
||||
setHasPty(commandLine is PtyCommandLine)
|
||||
setShouldDestroyProcessRecursively(!hasPty())
|
||||
}
|
||||
|
||||
protected constructor (process: Process, commandLine: String, charset: Charset) : super(process, commandLine, charset) {
|
||||
constructor (process: Process, commandLine: String, charset: Charset) : super(process, commandLine, charset) {
|
||||
setHasPty(process is PtyProcess)
|
||||
setShouldDestroyProcessRecursively(!hasPty())
|
||||
}
|
||||
|
||||
class IPCAware : ZigProcessHandler {
|
||||
val originalCommandLine: String
|
||||
constructor(originalCommandLine: String, commandLine: GeneralCommandLine) : super(commandLine) {
|
||||
this.originalCommandLine = originalCommandLine
|
||||
}
|
||||
|
||||
fun unwrap(): ZigProcessHandler {
|
||||
return ZigProcessHandler(this.process, this.originalCommandLine, this.charset ?: Charsets.UTF_8)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -130,14 +130,13 @@ fun createCommandLineSafe(
|
|||
}
|
||||
|
||||
@Throws(ExecutionException::class)
|
||||
suspend fun GeneralCommandLine.startIPCAwareProcess(project: Project?, emulateTerminal: Boolean = false): ZigProcessHandler.IPCAware {
|
||||
val original = this.commandLineString
|
||||
suspend fun GeneralCommandLine.startIPCAwareProcess(project: Project?, emulateTerminal: Boolean = false): ZigProcessHandler {
|
||||
val ipc = if (project != null && !emulateTerminal) IPCUtil.wrapWithIPC(this) else null
|
||||
val cli = ipc?.cli ?: this
|
||||
if (emulateTerminal && OS.CURRENT != OS.Windows && !cli.environment.contains("TERM")) {
|
||||
cli.withEnvironment("TERM", "xterm-256color")
|
||||
}
|
||||
val handler = ZigProcessHandler.IPCAware(original, cli)
|
||||
val handler = ZigProcessHandler(cli)
|
||||
ProcessTerminatedListener.attach(handler)
|
||||
|
||||
if (ipc != null) {
|
||||
|
|
|
@ -91,8 +91,7 @@ configuration.test.marker-name=all tests in {0}
|
|||
configuration.build.name=Zig build
|
||||
configuration.build.suggested-name=Build
|
||||
configuration.build.description=Execute "zig build" with custom steps
|
||||
configuration.build.marker-run=Build and Run
|
||||
configuration.build.marker-test=Build and Test
|
||||
configuration.build.marker-name=Build and Run
|
||||
settings.project.group.title=Zig Settings
|
||||
settings.project.label.direnv=Use direnv
|
||||
settings.project.label.toolchain=Toolchain location
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
pluginName=ZigBrains
|
||||
pluginRepositoryUrl=https://github.com/FalsePattern/ZigBrains
|
||||
|
||||
pluginVersion=25.2.0
|
||||
pluginVersion=25.1.0
|
||||
|
||||
pluginSinceBuild=251
|
||||
pluginUntilBuild=
|
||||
|
|
8
push.sh
8
push.sh
|
@ -23,6 +23,8 @@
|
|||
|
||||
set -e
|
||||
|
||||
declare -a branches=("dev" "master" "243" "242" "241")
|
||||
|
||||
die () {
|
||||
echo >&2 "$@"
|
||||
exit 1
|
||||
|
@ -30,4 +32,8 @@ die () {
|
|||
|
||||
[ "$#" -eq 1 ] || die "1 argument required, $# provided"
|
||||
|
||||
git push --atomic "$1" "dev" "master" "243" "242" "241"
|
||||
for i in "${branches[@]}"
|
||||
do
|
||||
echo "Pushing branch $i"
|
||||
git push "$1" "$i"
|
||||
done
|
Loading…
Add table
Reference in a new issue