Compare commits
3 commits
Author | SHA1 | Date | |
---|---|---|---|
fd9cb9626a | |||
8209e688fc | |||
85aacf0b96 |
23 changed files with 223 additions and 42 deletions
26
CHANGELOG.md
26
CHANGELOG.md
|
@ -17,6 +17,32 @@ Changelog structure reference:
|
||||||
|
|
||||||
## [Unreleased]
|
## [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
|
||||||
|
|
||||||
|
- IDEA 2025.1 support
|
||||||
|
|
||||||
|
- LSP
|
||||||
|
- Configurable inlay hints file size limit to reduce IDE lag
|
||||||
|
|
||||||
## [25.0.2]
|
## [25.0.2]
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
|
@ -15,6 +15,7 @@ through the built-in plugin browser:
|
||||||
1. Go to `Settings -> Plugins`
|
1. Go to `Settings -> Plugins`
|
||||||
2. To the right of the `Installed` button at the top, click on the `...` dropdown menu, then select `Manage Plugin Repositories...`
|
2. To the right of the `Installed` button at the top, click on the `...` dropdown menu, then select `Manage Plugin Repositories...`
|
||||||
3. Click the add button, and then enter the ZigBrains updater URL, based on your IDE version:
|
3. Click the add button, and then enter the ZigBrains updater URL, based on your IDE version:
|
||||||
|
- `2025.1.*` or newer: https://falsepattern.com/zigbrains/updatePlugins-251.xml
|
||||||
- `2024.3.*`: https://falsepattern.com/zigbrains/updatePlugins-243.xml
|
- `2024.3.*`: https://falsepattern.com/zigbrains/updatePlugins-243.xml
|
||||||
- `2024.2.*`: https://falsepattern.com/zigbrains/updatePlugins-242.xml
|
- `2024.2.*`: https://falsepattern.com/zigbrains/updatePlugins-242.xml
|
||||||
- `2024.1.*`: https://falsepattern.com/zigbrains/updatePlugins-241.xml
|
- `2024.1.*`: https://falsepattern.com/zigbrains/updatePlugins-241.xml
|
||||||
|
|
|
@ -14,7 +14,7 @@ plugins {
|
||||||
idea
|
idea
|
||||||
`maven-publish`
|
`maven-publish`
|
||||||
}
|
}
|
||||||
val publishVersions = listOf("241", "242", "243")
|
val publishVersions = listOf("241", "242", "243", "251")
|
||||||
val pluginVersionFull get() = "$pluginVersion-$pluginSinceBuild"
|
val pluginVersionFull get() = "$pluginVersion-$pluginSinceBuild"
|
||||||
val pluginVersion: String by project
|
val pluginVersion: String by project
|
||||||
val pluginSinceBuild: String by project
|
val pluginSinceBuild: String by project
|
||||||
|
|
2
build.sh
2
build.sh
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
declare -a branches=("master" "242" "241")
|
declare -a branches=("master" "243" "242" "241")
|
||||||
|
|
||||||
DEFAULT_BRANCH="${branches[0]}"
|
DEFAULT_BRANCH="${branches[0]}"
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.debugger.runner.base
|
package com.falsepattern.zigbrains.debugger.runner.base
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.project.run.ZigProcessHandler
|
||||||
import com.falsepattern.zigbrains.shared.cli.startIPCAwareProcess
|
import com.falsepattern.zigbrains.shared.cli.startIPCAwareProcess
|
||||||
import com.intellij.execution.ExecutionException
|
import com.intellij.execution.ExecutionException
|
||||||
import com.intellij.execution.configurations.GeneralCommandLine
|
import com.intellij.execution.configurations.GeneralCommandLine
|
||||||
|
@ -40,7 +41,7 @@ import kotlinx.coroutines.withContext
|
||||||
class PreLaunchProcessListener(val console: ConsoleView) : ProcessListener {
|
class PreLaunchProcessListener(val console: ConsoleView) : ProcessListener {
|
||||||
var isBuildFailed: Boolean = false
|
var isBuildFailed: Boolean = false
|
||||||
private set
|
private set
|
||||||
lateinit var processHandler: ProcessHandler
|
lateinit var processHandler: ZigProcessHandler.IPCAware
|
||||||
private set
|
private set
|
||||||
|
|
||||||
@Throws(ExecutionException::class)
|
@Throws(ExecutionException::class)
|
||||||
|
@ -50,7 +51,7 @@ class PreLaunchProcessListener(val console: ConsoleView) : ProcessListener {
|
||||||
this@PreLaunchProcessListener.processHandler = processHandler
|
this@PreLaunchProcessListener.processHandler = processHandler
|
||||||
hook(processHandler)
|
hook(processHandler)
|
||||||
processHandler.startNotify()
|
processHandler.startNotify()
|
||||||
withContext(Dispatchers.Default) {
|
withContext(Dispatchers.IO) {
|
||||||
processHandler.process.awaitExit()
|
processHandler.process.awaitExit()
|
||||||
}
|
}
|
||||||
runInterruptible {
|
runInterruptible {
|
||||||
|
|
|
@ -27,6 +27,7 @@ import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
||||||
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||||
import com.intellij.execution.ExecutionException
|
import com.intellij.execution.ExecutionException
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
|
import com.intellij.openapi.util.io.toNioPathOrNull
|
||||||
import com.intellij.platform.util.progress.withProgressText
|
import com.intellij.platform.util.progress.withProgressText
|
||||||
import com.intellij.util.containers.orNull
|
import com.intellij.util.containers.orNull
|
||||||
import com.jetbrains.cidr.execution.debugger.backend.DebuggerDriverConfiguration
|
import com.jetbrains.cidr.execution.debugger.backend.DebuggerDriverConfiguration
|
||||||
|
@ -36,6 +37,7 @@ import java.io.File
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import kotlin.io.path.absolutePathString
|
import kotlin.io.path.absolutePathString
|
||||||
import kotlin.io.path.isExecutable
|
import kotlin.io.path.isExecutable
|
||||||
|
import kotlin.io.path.pathString
|
||||||
|
|
||||||
abstract class ZigDebugParametersEmitBinaryBase<ProfileState: ZigProfileState<*>>(
|
abstract class ZigDebugParametersEmitBinaryBase<ProfileState: ZigProfileState<*>>(
|
||||||
driverConfiguration: DebuggerDriverConfiguration,
|
driverConfiguration: DebuggerDriverConfiguration,
|
||||||
|
@ -49,13 +51,14 @@ abstract class ZigDebugParametersEmitBinaryBase<ProfileState: ZigProfileState<*>
|
||||||
@Throws(ExecutionException::class)
|
@Throws(ExecutionException::class)
|
||||||
private suspend fun compileExe(listener: PreLaunchProcessListener): File {
|
private suspend fun compileExe(listener: PreLaunchProcessListener): File {
|
||||||
val commandLine = profileState.getCommandLine(toolchain, true)
|
val commandLine = profileState.getCommandLine(toolchain, true)
|
||||||
|
val cliString = commandLine.getCommandLineString(commandLine.exePath.toNioPathOrNull()?.fileName?.pathString)
|
||||||
val tmpDir = FileUtil.createTempDirectory("zigbrains_debug", "", true).toPath()
|
val tmpDir = FileUtil.createTempDirectory("zigbrains_debug", "", true).toPath()
|
||||||
|
|
||||||
val exe = tmpDir.resolve("executable")
|
val exe = tmpDir.resolve("executable")
|
||||||
commandLine.addParameters("-femit-bin=${exe.absolutePathString()}")
|
commandLine.addParameters("-femit-bin=${exe.absolutePathString()}")
|
||||||
|
|
||||||
if (listener.executeCommandLineWithHook(profileState.environment.project, commandLine))
|
if (listener.executeCommandLineWithHook(profileState.environment.project, commandLine))
|
||||||
throw ExecutionException(ZigDebugBundle.message("debug.base.compile.failed.generic"))
|
throw ExecutionException(ZigDebugBundle.message("debug.base.compile.failed.generic", cliString))
|
||||||
|
|
||||||
return withContext(Dispatchers.IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
Files.list(tmpDir).use { stream ->
|
Files.list(tmpDir).use { stream ->
|
||||||
|
|
|
@ -24,6 +24,7 @@ package com.falsepattern.zigbrains.debugger.runner.base
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.debugbridge.ZigDebuggerDriverConfigurationProviderBase
|
import com.falsepattern.zigbrains.debugbridge.ZigDebuggerDriverConfigurationProviderBase
|
||||||
import com.falsepattern.zigbrains.debugger.ZigLocalDebugProcess
|
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.execution.base.ZigProfileState
|
||||||
import com.falsepattern.zigbrains.project.run.ZigProgramRunner
|
import com.falsepattern.zigbrains.project.run.ZigProgramRunner
|
||||||
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||||
|
@ -41,6 +42,7 @@ import com.intellij.execution.ui.ConsoleView
|
||||||
import com.intellij.execution.ui.ConsoleViewContentType
|
import com.intellij.execution.ui.ConsoleViewContentType
|
||||||
import com.intellij.execution.ui.RunContentDescriptor
|
import com.intellij.execution.ui.RunContentDescriptor
|
||||||
import com.intellij.openapi.application.ModalityState
|
import com.intellij.openapi.application.ModalityState
|
||||||
|
import com.intellij.openapi.project.guessProjectDir
|
||||||
import com.intellij.platform.util.progress.reportProgress
|
import com.intellij.platform.util.progress.reportProgress
|
||||||
import com.intellij.xdebugger.XDebugProcess
|
import com.intellij.xdebugger.XDebugProcess
|
||||||
import com.intellij.xdebugger.XDebugProcessStarter
|
import com.intellij.xdebugger.XDebugProcessStarter
|
||||||
|
@ -82,11 +84,13 @@ abstract class ZigDebugRunnerBase<ProfileState : ZigProfileState<*>> : ZigProgra
|
||||||
}
|
}
|
||||||
} catch (e: ExecutionException) {
|
} catch (e: ExecutionException) {
|
||||||
console.print("\n", ConsoleViewContentType.ERROR_OUTPUT)
|
console.print("\n", ConsoleViewContentType.ERROR_OUTPUT)
|
||||||
e.message?.let { listener.console.print(it, ConsoleViewContentType.SYSTEM_OUTPUT) }
|
e.message?.let { listener.console.print(it, ConsoleViewContentType.ERROR_OUTPUT) }
|
||||||
throw e;
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (listener.isBuildFailed) {
|
if (listener.isBuildFailed) {
|
||||||
val executionResult = DefaultExecutionResult(console, listener.processHandler)
|
val executionResult = DefaultExecutionResult(console, listener.processHandler.unwrap())
|
||||||
return@reportProgress withEDTContext(ModalityState.any()) {
|
return@reportProgress withEDTContext(ModalityState.any()) {
|
||||||
val runContentBuilder = RunContentBuilder(executionResult, environment)
|
val runContentBuilder = RunContentBuilder(executionResult, environment)
|
||||||
runContentBuilder.showRunContent(null)
|
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=Debugger is outdated
|
||||||
debugger.run.unavailable.reason.update.button=Update
|
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.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
|
debug.base.compile.failed.generic=Failed to compile executable with command: {0}
|
||||||
debug.base.compile.failed.no-exe=Failed to find compiled binary
|
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.multiple-exe=Multiple compiled binaries found
|
||||||
debug.build.compile.failed.no-workdir=Cannot find working directory to run debugged executable
|
debug.build.compile.failed.no-workdir=Cannot find working directory to run debugged executable
|
||||||
|
|
|
@ -9,12 +9,15 @@ plugins {
|
||||||
|
|
||||||
val ideaCommunityVersion: String by project
|
val ideaCommunityVersion: String by project
|
||||||
val useInstaller = property("useInstaller").toString().toBoolean()
|
val useInstaller = property("useInstaller").toString().toBoolean()
|
||||||
|
val serializationVersion: String by project
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
intellijPlatform {
|
intellijPlatform {
|
||||||
create(IntelliJPlatformType.IntellijIdeaCommunity, ideaCommunityVersion, useInstaller = useInstaller)
|
create(IntelliJPlatformType.IntellijIdeaCommunity, ideaCommunityVersion, useInstaller = useInstaller)
|
||||||
}
|
}
|
||||||
compileOnly("org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.3")
|
compileOnly("org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:$serializationVersion") {
|
||||||
|
isTransitive = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//region grammars
|
//region grammars
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* 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,12 +24,16 @@ package com.falsepattern.zigbrains.project.execution.build
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.ZigBrainsBundle
|
import com.falsepattern.zigbrains.ZigBrainsBundle
|
||||||
import com.falsepattern.zigbrains.project.execution.base.ZigConfigProducer
|
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.project.execution.firstConfigFactory
|
||||||
import com.falsepattern.zigbrains.zig.psi.ZigFile
|
import com.falsepattern.zigbrains.zig.psi.ZigFile
|
||||||
|
import com.falsepattern.zigbrains.zig.psi.ZigTypes
|
||||||
import com.intellij.execution.actions.ConfigurationFromContext
|
import com.intellij.execution.actions.ConfigurationFromContext
|
||||||
import com.intellij.execution.configurations.ConfigurationFactory
|
import com.intellij.execution.configurations.ConfigurationFactory
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.util.elementType
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
|
||||||
class ZigConfigProducerBuild: ZigConfigProducer<ZigExecConfigBuild>() {
|
class ZigConfigProducerBuild: ZigConfigProducer<ZigExecConfigBuild>() {
|
||||||
|
@ -38,14 +42,39 @@ class ZigConfigProducerBuild: ZigConfigProducer<ZigExecConfigBuild>() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setupConfigurationFromContext(configuration: ZigExecConfigBuild, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean {
|
override fun setupConfigurationFromContext(configuration: ZigExecConfigBuild, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean {
|
||||||
if (theFile.name != "build.zig")
|
if (theFile.isBuildZig()) {
|
||||||
return false
|
configuration.name = ZigBrainsBundle.message("configuration.build.marker-run")
|
||||||
configuration.name = ZigBrainsBundle.message("configuration.build.marker-name")
|
configuration.buildSteps.args = "run"
|
||||||
return true
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isConfigurationFromContext(configuration: ZigExecConfigBuild, element: PsiElement, psiFile: ZigFile, 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)
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun shouldReplace(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean {
|
override fun shouldReplace(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean {
|
||||||
|
|
|
@ -23,14 +23,14 @@
|
||||||
package com.falsepattern.zigbrains.project.execution.run
|
package com.falsepattern.zigbrains.project.execution.run
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.project.execution.base.ZigConfigProducer
|
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.project.execution.firstConfigFactory
|
||||||
import com.falsepattern.zigbrains.zig.psi.ZigContainerMembers
|
|
||||||
import com.falsepattern.zigbrains.zig.psi.ZigFile
|
import com.falsepattern.zigbrains.zig.psi.ZigFile
|
||||||
import com.intellij.execution.actions.ConfigurationFromContext
|
import com.intellij.execution.actions.ConfigurationFromContext
|
||||||
import com.intellij.execution.configurations.ConfigurationFactory
|
import com.intellij.execution.configurations.ConfigurationFactory
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.util.childrenOfType
|
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
|
||||||
class ZigConfigProducerRun: ZigConfigProducer<ZigExecConfigRun>() {
|
class ZigConfigProducerRun: ZigConfigProducer<ZigExecConfigRun>() {
|
||||||
|
@ -39,8 +39,10 @@ class ZigConfigProducerRun: ZigConfigProducer<ZigExecConfigRun>() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setupConfigurationFromContext(configuration: ZigExecConfigRun, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean {
|
override fun setupConfigurationFromContext(configuration: ZigExecConfigRun, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean {
|
||||||
val members = psiFile.childrenOfType<ZigContainerMembers>().firstOrNull() ?: return false
|
if (!psiFile.hasMainFunction()) {
|
||||||
if (members.containerDeclarationList.none { it.decl?.fnProto?.identifier?.textMatches("main") == true }) {
|
return false
|
||||||
|
}
|
||||||
|
if (theFile.findBuildZig() != null) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
configuration.filePath.path = filePath
|
configuration.filePath.path = filePath
|
||||||
|
@ -56,5 +58,3 @@ class ZigConfigProducerRun: ZigConfigProducer<ZigExecConfigRun>() {
|
||||||
return self.configurationType is ZigConfigTypeRun
|
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.ZigBrainsBundle
|
||||||
import com.falsepattern.zigbrains.project.execution.base.ZigConfigProducer
|
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.project.execution.firstConfigFactory
|
||||||
import com.falsepattern.zigbrains.zig.psi.ZigContainerMembers
|
|
||||||
import com.falsepattern.zigbrains.zig.psi.ZigFile
|
import com.falsepattern.zigbrains.zig.psi.ZigFile
|
||||||
import com.intellij.execution.actions.ConfigurationFromContext
|
import com.intellij.execution.actions.ConfigurationFromContext
|
||||||
import com.intellij.execution.configurations.ConfigurationFactory
|
import com.intellij.execution.configurations.ConfigurationFactory
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.util.childrenOfType
|
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
|
||||||
class ZigConfigProducerTest: ZigConfigProducer<ZigExecConfigTest>() {
|
class ZigConfigProducerTest: ZigConfigProducer<ZigExecConfigTest>() {
|
||||||
|
@ -40,8 +40,10 @@ class ZigConfigProducerTest: ZigConfigProducer<ZigExecConfigTest>() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setupConfigurationFromContext(configuration: ZigExecConfigTest, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean {
|
override fun setupConfigurationFromContext(configuration: ZigExecConfigTest, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean {
|
||||||
val members = psiFile.childrenOfType<ZigContainerMembers>().firstOrNull() ?: return false
|
if (!psiFile.hasTests()) {
|
||||||
if (members.containerDeclarationList.none { it.testDecl != null }) {
|
return false
|
||||||
|
}
|
||||||
|
if (theFile.findBuildZig() != null) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
configuration.filePath.path = filePath
|
configuration.filePath.path = filePath
|
||||||
|
|
|
@ -28,14 +28,25 @@ import com.intellij.execution.process.KillableProcessHandler
|
||||||
import com.pty4j.PtyProcess
|
import com.pty4j.PtyProcess
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
|
|
||||||
class ZigProcessHandler : KillableProcessHandler {
|
open class ZigProcessHandler : KillableProcessHandler {
|
||||||
constructor(commandLine: GeneralCommandLine) : super(commandLine) {
|
constructor(commandLine: GeneralCommandLine) : super(commandLine) {
|
||||||
setHasPty(commandLine is PtyCommandLine)
|
setHasPty(commandLine is PtyCommandLine)
|
||||||
setShouldDestroyProcessRecursively(!hasPty())
|
setShouldDestroyProcessRecursively(!hasPty())
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor (process: Process, commandLine: String, charset: Charset) : super(process, commandLine, charset) {
|
protected constructor (process: Process, commandLine: String, charset: Charset) : super(process, commandLine, charset) {
|
||||||
setHasPty(process is PtyProcess)
|
setHasPty(process is PtyProcess)
|
||||||
setShouldDestroyProcessRecursively(!hasPty())
|
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,13 +130,14 @@ fun createCommandLineSafe(
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(ExecutionException::class)
|
@Throws(ExecutionException::class)
|
||||||
suspend fun GeneralCommandLine.startIPCAwareProcess(project: Project?, emulateTerminal: Boolean = false): ZigProcessHandler {
|
suspend fun GeneralCommandLine.startIPCAwareProcess(project: Project?, emulateTerminal: Boolean = false): ZigProcessHandler.IPCAware {
|
||||||
|
val original = this.commandLineString
|
||||||
val ipc = if (project != null && !emulateTerminal) IPCUtil.wrapWithIPC(this) else null
|
val ipc = if (project != null && !emulateTerminal) IPCUtil.wrapWithIPC(this) else null
|
||||||
val cli = ipc?.cli ?: this
|
val cli = ipc?.cli ?: this
|
||||||
if (emulateTerminal && OS.CURRENT != OS.Windows && !cli.environment.contains("TERM")) {
|
if (emulateTerminal && OS.CURRENT != OS.Windows && !cli.environment.contains("TERM")) {
|
||||||
cli.withEnvironment("TERM", "xterm-256color")
|
cli.withEnvironment("TERM", "xterm-256color")
|
||||||
}
|
}
|
||||||
val handler = ZigProcessHandler(cli)
|
val handler = ZigProcessHandler.IPCAware(original, cli)
|
||||||
ProcessTerminatedListener.attach(handler)
|
ProcessTerminatedListener.attach(handler)
|
||||||
|
|
||||||
if (ipc != null) {
|
if (ipc != null) {
|
||||||
|
|
|
@ -91,7 +91,8 @@ configuration.test.marker-name=all tests in {0}
|
||||||
configuration.build.name=Zig build
|
configuration.build.name=Zig build
|
||||||
configuration.build.suggested-name=Build
|
configuration.build.suggested-name=Build
|
||||||
configuration.build.description=Execute "zig build" with custom steps
|
configuration.build.description=Execute "zig build" with custom steps
|
||||||
configuration.build.marker-name=Build and Run
|
configuration.build.marker-run=Build and Run
|
||||||
|
configuration.build.marker-test=Build and Test
|
||||||
settings.project.group.title=Zig Settings
|
settings.project.group.title=Zig Settings
|
||||||
settings.project.label.direnv=Use direnv
|
settings.project.label.direnv=Use direnv
|
||||||
settings.project.label.toolchain=Toolchain location
|
settings.project.label.toolchain=Toolchain location
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
pluginName=ZigBrains
|
pluginName=ZigBrains
|
||||||
pluginRepositoryUrl=https://github.com/FalsePattern/ZigBrains
|
pluginRepositoryUrl=https://github.com/FalsePattern/ZigBrains
|
||||||
|
|
||||||
pluginVersion=25.0.2
|
pluginVersion=25.2.0
|
||||||
|
|
||||||
pluginSinceBuild=243
|
pluginSinceBuild=243
|
||||||
pluginUntilBuild=
|
pluginUntilBuild=243.*
|
||||||
|
|
||||||
ideaCommunityVersion=2024.3
|
ideaCommunityVersion=2024.3
|
||||||
clionVersion=2024.3
|
clionVersion=2024.3
|
||||||
|
@ -17,6 +17,8 @@ lsp4jVersion=0.21.1
|
||||||
lsp4ijVersion=0.12.0
|
lsp4ijVersion=0.12.0
|
||||||
lsp4ijNightly=false
|
lsp4ijNightly=false
|
||||||
|
|
||||||
|
serializationVersion=1.6.3
|
||||||
|
|
||||||
kotlin.stdlib.default.dependency=false
|
kotlin.stdlib.default.dependency=false
|
||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
org.gradle.configuration-cache=true
|
org.gradle.configuration-cache=true
|
||||||
|
|
|
@ -8,12 +8,15 @@ val lsp4ijVersion: String by project
|
||||||
val lsp4jVersion: String by project
|
val lsp4jVersion: String by project
|
||||||
val ideaCommunityVersion: String by project
|
val ideaCommunityVersion: String by project
|
||||||
val useInstaller = property("useInstaller").toString().toBoolean()
|
val useInstaller = property("useInstaller").toString().toBoolean()
|
||||||
|
val serializationVersion: String by project
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
intellijPlatform {
|
intellijPlatform {
|
||||||
create(IntelliJPlatformType.IntellijIdeaCommunity, ideaCommunityVersion, useInstaller = useInstaller)
|
create(IntelliJPlatformType.IntellijIdeaCommunity, ideaCommunityVersion, useInstaller = useInstaller)
|
||||||
}
|
}
|
||||||
compileOnly("org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.3")
|
compileOnly("org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:$serializationVersion") {
|
||||||
|
isTransitive = false
|
||||||
|
}
|
||||||
compileOnly("com.redhat.devtools.intellij:lsp4ij:$lsp4ijVersion")
|
compileOnly("com.redhat.devtools.intellij:lsp4ij:$lsp4ijVersion")
|
||||||
compileOnly("org.eclipse.lsp4j:org.eclipse.lsp4j:$lsp4jVersion")
|
compileOnly("org.eclipse.lsp4j:org.eclipse.lsp4j:$lsp4jVersion")
|
||||||
implementation(project(":core")) {
|
implementation(project(":core")) {
|
||||||
|
|
|
@ -68,7 +68,14 @@ class ZigLanguageServerFactory: LanguageServerFactory, LanguageServerEnablementS
|
||||||
}
|
}
|
||||||
features.inlayHintFeature = object: LSPInlayHintFeature() {
|
features.inlayHintFeature = object: LSPInlayHintFeature() {
|
||||||
override fun isEnabled(file: PsiFile): Boolean {
|
override fun isEnabled(file: PsiFile): Boolean {
|
||||||
return project.zls?.settings?.inlayHints == true
|
val settings = project.zls?.settings ?: return false
|
||||||
|
if (!settings.inlayHints)
|
||||||
|
return false
|
||||||
|
val maxFileSizeKb = settings.inlayHintsMaxFileSizeKb
|
||||||
|
if (maxFileSizeKb == 0)
|
||||||
|
return true
|
||||||
|
val fileSizeKb = file.fileDocument.textLength / 1024
|
||||||
|
return fileSizeKb <= maxFileSizeKb
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return features
|
return features
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.jetbrains.annotations.NonNls
|
||||||
data class ZLSSettings(
|
data class ZLSSettings(
|
||||||
@JvmField @Attribute val zlsConfigPath: @NonNls String = "",
|
@JvmField @Attribute val zlsConfigPath: @NonNls String = "",
|
||||||
@JvmField @Attribute val inlayHints: Boolean = true,
|
@JvmField @Attribute val inlayHints: Boolean = true,
|
||||||
|
@JvmField @Attribute val inlayHintsMaxFileSizeKb: Int = 128,
|
||||||
@JvmField @Attribute val enable_snippets: Boolean = true,
|
@JvmField @Attribute val enable_snippets: Boolean = true,
|
||||||
@JvmField @Attribute val enable_argument_placeholders: Boolean = true,
|
@JvmField @Attribute val enable_argument_placeholders: Boolean = true,
|
||||||
@JvmField @Attribute val completion_label_details: Boolean = true,
|
@JvmField @Attribute val completion_label_details: Boolean = true,
|
||||||
|
|
|
@ -35,6 +35,9 @@ import com.intellij.ui.dsl.builder.AlignX
|
||||||
import com.intellij.ui.dsl.builder.Panel
|
import com.intellij.ui.dsl.builder.Panel
|
||||||
import com.intellij.ui.dsl.builder.Row
|
import com.intellij.ui.dsl.builder.Row
|
||||||
import org.jetbrains.annotations.PropertyKey
|
import org.jetbrains.annotations.PropertyKey
|
||||||
|
import javax.swing.text.AttributeSet
|
||||||
|
import javax.swing.text.DocumentFilter
|
||||||
|
import javax.swing.text.PlainDocument
|
||||||
|
|
||||||
@Suppress("PrivatePropertyName")
|
@Suppress("PrivatePropertyName")
|
||||||
class ZLSSettingsPanel() : ImmutableElementPanel<ZLSSettings> {
|
class ZLSSettingsPanel() : ImmutableElementPanel<ZLSSettings> {
|
||||||
|
@ -44,6 +47,27 @@ class ZLSSettingsPanel() : ImmutableElementPanel<ZLSSettings> {
|
||||||
.withTitle(ZLSBundle.message("settings.zls-config-path.browse.title"))
|
.withTitle(ZLSBundle.message("settings.zls-config-path.browse.title"))
|
||||||
).also { Disposer.register(this, it) }
|
).also { Disposer.register(this, it) }
|
||||||
private val inlayHints = JBCheckBox()
|
private val inlayHints = JBCheckBox()
|
||||||
|
private val inlayHintsMaxFileSize = ExtendableTextField(5).also { (it.document as PlainDocument).documentFilter = object: DocumentFilter() {
|
||||||
|
override fun insertString(fb: FilterBypass?, offset: Int, string: String?, attr: AttributeSet?) {
|
||||||
|
if (string != null && !string.isEmpty() && string.toIntOrNull() == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
super.insertString(fb, offset, string, attr)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun replace(
|
||||||
|
fb: FilterBypass?,
|
||||||
|
offset: Int,
|
||||||
|
length: Int,
|
||||||
|
text: String?,
|
||||||
|
attrs: AttributeSet?
|
||||||
|
) {
|
||||||
|
if (text != null && !text.isEmpty() && text.toIntOrNull() == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
super.replace(fb, offset, length, text, attrs)
|
||||||
|
}
|
||||||
|
} }
|
||||||
private val enable_snippets = JBCheckBox()
|
private val enable_snippets = JBCheckBox()
|
||||||
private val enable_argument_placeholders = JBCheckBox()
|
private val enable_argument_placeholders = JBCheckBox()
|
||||||
private val completion_label_details = JBCheckBox()
|
private val completion_label_details = JBCheckBox()
|
||||||
|
@ -99,6 +123,13 @@ class ZLSSettingsPanel() : ImmutableElementPanel<ZLSSettings> {
|
||||||
"settings.inlay-hints-enable.label",
|
"settings.inlay-hints-enable.label",
|
||||||
"settings.inlay-hints-enable.tooltip"
|
"settings.inlay-hints-enable.tooltip"
|
||||||
) { cell(inlayHints) }
|
) { cell(inlayHints) }
|
||||||
|
fancyRow(
|
||||||
|
"settings.inlay-hints-max-size.label",
|
||||||
|
"settings.inlay-hints-max-size.tooltip",
|
||||||
|
) {
|
||||||
|
cell(inlayHintsMaxFileSize)
|
||||||
|
text(ZLSBundle.message("settings.inlay-hints-max-size.unit"))
|
||||||
|
}
|
||||||
fancyRow(
|
fancyRow(
|
||||||
"settings.inlay_hints_show_variable_type_hints.label",
|
"settings.inlay_hints_show_variable_type_hints.label",
|
||||||
"settings.inlay_hints_show_variable_type_hints.tooltip"
|
"settings.inlay_hints_show_variable_type_hints.tooltip"
|
||||||
|
@ -174,6 +205,7 @@ class ZLSSettingsPanel() : ImmutableElementPanel<ZLSSettings> {
|
||||||
get() = ZLSSettings(
|
get() = ZLSSettings(
|
||||||
zlsConfigPath.text,
|
zlsConfigPath.text,
|
||||||
inlayHints.isSelected,
|
inlayHints.isSelected,
|
||||||
|
inlayHintsMaxFileSize.text.toIntOrNull() ?: 128,
|
||||||
enable_snippets.isSelected,
|
enable_snippets.isSelected,
|
||||||
enable_argument_placeholders.isSelected,
|
enable_argument_placeholders.isSelected,
|
||||||
completion_label_details.isSelected,
|
completion_label_details.isSelected,
|
||||||
|
@ -198,6 +230,7 @@ class ZLSSettingsPanel() : ImmutableElementPanel<ZLSSettings> {
|
||||||
set(value) {
|
set(value) {
|
||||||
zlsConfigPath.text = value.zlsConfigPath
|
zlsConfigPath.text = value.zlsConfigPath
|
||||||
inlayHints.isSelected = value.inlayHints
|
inlayHints.isSelected = value.inlayHints
|
||||||
|
inlayHintsMaxFileSize.text = value.inlayHintsMaxFileSizeKb.toString()
|
||||||
enable_snippets.isSelected = value.enable_snippets
|
enable_snippets.isSelected = value.enable_snippets
|
||||||
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
|
||||||
|
|
|
@ -4,6 +4,9 @@ settings.zls-config-path.browse.title=Path to the Custom ZLS Config File (Option
|
||||||
settings.inlay-hints-group.label=Inlay Hints
|
settings.inlay-hints-group.label=Inlay Hints
|
||||||
settings.inlay-hints-enable.label=Enable
|
settings.inlay-hints-enable.label=Enable
|
||||||
settings.inlay-hints-enable.tooltip=Toggle this to enable/disable all inlay hints
|
settings.inlay-hints-enable.tooltip=Toggle this to enable/disable all inlay hints
|
||||||
|
settings.inlay-hints-max-size.label=Maximum Size
|
||||||
|
settings.inlay-hints-max-size.tooltip=The maximum size of a zig file to show inlay hints for.\nInlay hints in very large files make the IDE lag.\nSet to 0 to disable.
|
||||||
|
settings.inlay-hints-max-size.unit=KB
|
||||||
settings.enable_snippets.label=Enable snippets
|
settings.enable_snippets.label=Enable snippets
|
||||||
settings.enable_snippets.tooltip=Enables snippet completions when the client also supports them
|
settings.enable_snippets.tooltip=Enables snippet completions when the client also supports them
|
||||||
settings.enable_argument_placeholders.label=Enable argument placeholders
|
settings.enable_argument_placeholders.label=Enable argument placeholders
|
||||||
|
|
8
push.sh
8
push.sh
|
@ -23,8 +23,6 @@
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
declare -a branches=("dev" "master" "242" "241")
|
|
||||||
|
|
||||||
die () {
|
die () {
|
||||||
echo >&2 "$@"
|
echo >&2 "$@"
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -32,8 +30,4 @@ die () {
|
||||||
|
|
||||||
[ "$#" -eq 1 ] || die "1 argument required, $# provided"
|
[ "$#" -eq 1 ] || die "1 argument required, $# provided"
|
||||||
|
|
||||||
for i in "${branches[@]}"
|
git push --atomic "$1" "dev" "master" "243" "242" "241"
|
||||||
do
|
|
||||||
echo "Pushing branch $i"
|
|
||||||
git push "$1" "$i"
|
|
||||||
done
|
|
Loading…
Add table
Reference in a new issue