Compare commits
No commits in common. "master" and "toolchains" have entirely different histories.
master
...
toolchains
74 changed files with 352 additions and 474 deletions
49
CHANGELOG.md
49
CHANGELOG.md
|
@ -17,55 +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
|
||||
|
||||
- IDEA 2025.1 support
|
||||
|
||||
- LSP
|
||||
- Configurable inlay hints file size limit to reduce IDE lag
|
||||
|
||||
## [25.0.2]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Project
|
||||
- ZLS settings not scrollable in the language server list
|
||||
|
||||
## [25.0.1]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Project
|
||||
- Zig.iml file created in every project
|
||||
|
||||
### Changed
|
||||
|
||||
- Project
|
||||
- BREAKING MAJOR UPDATE: Fully reworked toolchain and language server management
|
||||
The configuration menu is now very similar to the intellij java toolchain management,
|
||||
with proper toolchain selection, detection, downloading, etc. This change will require
|
||||
you to re-configure your toolchains!
|
||||
- Zig external library root is now no longer shown if zig is not configured
|
||||
|
||||
## [24.0.1]
|
||||
|
||||
### Added
|
||||
|
|
|
@ -15,7 +15,6 @@ through the built-in plugin browser:
|
|||
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...`
|
||||
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.2.*`: https://falsepattern.com/zigbrains/updatePlugins-242.xml
|
||||
- `2024.1.*`: https://falsepattern.com/zigbrains/updatePlugins-241.xml
|
||||
|
@ -72,7 +71,11 @@ excellent example on how to write debugger support that doesn't depend on CLion.
|
|||
<!-- Plugin description -->
|
||||
Adds support for the Zig Language, utilizing the ZLS language server for advanced coding assistance.
|
||||
|
||||
Before you can properly use the plugin, you need to select or download the Zig toolchain and language server in `Settings` -> `Languages & Frameworks` -> `Zig`.
|
||||
## Quick setup guide for Zig and ZLS
|
||||
|
||||
1. Download the latest version of Zig from https://ziglang.org/download
|
||||
2. Download and compile the ZLS language server, available at https://github.com/zigtools/zls
|
||||
3. Go to `Settings` -> `Languages & Frameworks` -> `Zig`, and point the `Toolchain Location` and `ZLS path` to the correct places
|
||||
|
||||
## Debugging
|
||||
|
||||
|
@ -86,7 +89,6 @@ Debugging Zig code is supported in any native debugging capable IDE. The followi
|
|||
- RustRover (including the non-commercial free version too)
|
||||
- GoLand
|
||||
- PyCharm Professional
|
||||
- Android Studio
|
||||
|
||||
Additionally, in CLion, the plugin uses the C++ Toolchains for sourcing the debugger (this can be toggled off in the settings).
|
||||
|
||||
|
|
|
@ -6,15 +6,15 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
|
|||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
|
||||
|
||||
plugins {
|
||||
kotlin("jvm") version "2.1.10" apply false
|
||||
kotlin("plugin.serialization") version "2.1.10" apply false
|
||||
kotlin("jvm") version "2.0.21" apply false
|
||||
kotlin("plugin.serialization") version "2.0.21" apply false
|
||||
id("org.jetbrains.intellij.platform") version "2.5.0"
|
||||
id("org.jetbrains.changelog") version "2.2.1"
|
||||
id("org.jetbrains.grammarkit") version "2022.3.2.2" apply false
|
||||
idea
|
||||
`maven-publish`
|
||||
}
|
||||
val publishVersions = listOf("241", "242", "243", "251")
|
||||
val publishVersions = listOf("241", "242", "243")
|
||||
val pluginVersionFull get() = "$pluginVersion-$pluginSinceBuild"
|
||||
val pluginVersion: String by project
|
||||
val pluginSinceBuild: String by project
|
||||
|
|
2
build.sh
2
build.sh
|
@ -23,7 +23,7 @@
|
|||
|
||||
set -e
|
||||
|
||||
declare -a branches=("master" "243" "242" "241")
|
||||
declare -a branches=("master" "242" "241")
|
||||
|
||||
DEFAULT_BRANCH="${branches[0]}"
|
||||
|
||||
|
|
|
@ -14,8 +14,6 @@ sourceSets["main"].resources.srcDir(genOutputDir)
|
|||
|
||||
tasks {
|
||||
register<Download>("downloadProps") {
|
||||
onlyIfModified(true)
|
||||
useETag(true)
|
||||
src("https://falsepattern.com/zigbrains/msvc.properties")
|
||||
dest(genOutputDir.map { it.file("msvc.properties") })
|
||||
}
|
||||
|
|
|
@ -58,8 +58,7 @@ class ZigClionDebuggerDriverConfigurationProvider: ZigDebuggerDriverConfiguratio
|
|||
return when(toolchain.debuggerKind) {
|
||||
CPPDebugger.Kind.BUNDLED_GDB,
|
||||
CPPDebugger.Kind.CUSTOM_GDB -> CLionGDBDriverConfiguration(project, toolchain, isEmulateTerminal = emulateTerminal)
|
||||
CPPDebugger.Kind.BUNDLED_LLDB,
|
||||
CPPDebugger.Kind.CUSTOM_LLDB -> CLionLLDBDriverConfiguration(project, toolchain, isEmulateTerminal = emulateTerminal)
|
||||
CPPDebugger.Kind.BUNDLED_LLDB -> CLionLLDBDriverConfiguration(project, toolchain, isEmulateTerminal = emulateTerminal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@ 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.ipc.IPCUtil
|
||||
import com.falsepattern.zigbrains.shared.ipc.ipc
|
||||
import com.intellij.execution.ExecutionException
|
||||
import com.intellij.execution.configurations.GeneralCommandLine
|
||||
import com.intellij.execution.process.ProcessEvent
|
||||
|
@ -41,7 +43,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 +53,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)
|
||||
|
|
|
@ -48,6 +48,7 @@ import com.jetbrains.cidr.execution.debugger.CidrDebuggerPathManager
|
|||
import com.jetbrains.cidr.execution.debugger.backend.bin.UrlProvider
|
||||
import com.jetbrains.cidr.execution.debugger.backend.lldb.LLDBDriverConfiguration
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runInterruptible
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.IOException
|
||||
import java.net.URL
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -9,15 +9,12 @@ plugins {
|
|||
|
||||
val ideaCommunityVersion: String by project
|
||||
val useInstaller = property("useInstaller").toString().toBoolean()
|
||||
val serializationVersion: String by project
|
||||
|
||||
dependencies {
|
||||
intellijPlatform {
|
||||
create(IntelliJPlatformType.IntellijIdeaCommunity, ideaCommunityVersion, useInstaller = useInstaller)
|
||||
}
|
||||
compileOnly("org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:$serializationVersion") {
|
||||
isTransitive = false
|
||||
}
|
||||
compileOnly("org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.3")
|
||||
}
|
||||
|
||||
//region grammars
|
||||
|
|
|
@ -26,6 +26,7 @@ import com.intellij.openapi.util.SystemInfo
|
|||
import com.intellij.openapi.util.io.toNioPathOrNull
|
||||
import com.intellij.util.EnvironmentUtil
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import org.jetbrains.annotations.NonNls
|
||||
|
|
|
@ -26,6 +26,7 @@ import com.intellij.execution.filters.TextConsoleBuilderImpl
|
|||
import com.intellij.execution.ui.ConsoleView
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.terminal.TerminalExecutionConsole
|
||||
import java.nio.file.Path
|
||||
|
||||
class ZigConsoleBuilder(private val project: Project, private val emulateTerminal: Boolean = false): TextConsoleBuilderImpl(project) {
|
||||
override fun createConsole(): ConsoleView {
|
||||
|
|
|
@ -35,6 +35,8 @@ import com.intellij.execution.configurations.PtyCommandLine
|
|||
import com.intellij.execution.process.ProcessHandler
|
||||
import com.intellij.execution.runners.ExecutionEnvironment
|
||||
import com.intellij.platform.ide.progress.ModalTaskOwner
|
||||
import com.intellij.platform.util.progress.reportProgress
|
||||
import com.intellij.platform.util.progress.reportRawProgress
|
||||
import kotlin.io.path.pathString
|
||||
|
||||
abstract class ZigProfileState<T: ZigExecConfig<T>> (
|
||||
|
|
|
@ -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,39 +38,14 @@ 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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -23,8 +23,10 @@
|
|||
package com.falsepattern.zigbrains.project.newproject
|
||||
|
||||
import com.intellij.ide.util.projectWizard.SettingsStep
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton
|
||||
import com.intellij.openapi.ui.ValidationInfo
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.platform.ProjectGeneratorPeer
|
||||
import com.intellij.ui.dsl.builder.panel
|
||||
import javax.swing.JComponent
|
||||
|
|
|
@ -24,29 +24,21 @@ package com.falsepattern.zigbrains.project.run
|
|||
|
||||
import com.intellij.execution.configurations.GeneralCommandLine
|
||||
import com.intellij.execution.configurations.PtyCommandLine
|
||||
import com.intellij.execution.process.AnsiEscapeDecoder.ColoredTextAcceptor
|
||||
import com.intellij.execution.process.KillableColoredProcessHandler
|
||||
import com.intellij.execution.process.KillableProcessHandler
|
||||
import com.intellij.openapi.util.Key
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -75,40 +75,16 @@ class ZigSyntheticLibrary(val project: Project) : SyntheticLibrary(), ItemPresen
|
|||
return roots
|
||||
}
|
||||
|
||||
override fun isShowInExternalLibrariesNode(): Boolean {
|
||||
return !roots.isEmpty()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val ZIG_LIBRARY_ID = "Zig SDK"
|
||||
private const val ZIG_MODULE_ID = "ZigBrains"
|
||||
private val libraryTableId = LibraryTableId.ProjectLibraryTableId
|
||||
private val libraryId = LibraryId(ZIG_LIBRARY_ID, libraryTableId)
|
||||
private val moduleId = ModuleId(ZIG_MODULE_ID)
|
||||
suspend fun reload(project: Project, toolchain: ZigToolchain?) {
|
||||
val root = getRoot(toolchain, project)
|
||||
if (root != null) {
|
||||
add(project, root)
|
||||
} else {
|
||||
remove(project)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun remove(project: Project) {
|
||||
val workspaceModel = WorkspaceModel.getInstance(project)
|
||||
workspaceModel.update("Update Zig std") { builder ->
|
||||
builder.resolve(moduleId)?.let { moduleEntity ->
|
||||
builder.removeEntity(moduleEntity)
|
||||
}
|
||||
builder.resolve(libraryId)?.let { libraryEntity ->
|
||||
builder.removeEntity(libraryEntity)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun add(project: Project, root: VirtualFile) {
|
||||
val moduleId = ModuleId(ZIG_MODULE_ID)
|
||||
val workspaceModel = WorkspaceModel.getInstance(project)
|
||||
val root = getRoot(toolchain, project) ?: return
|
||||
val libRoot = LibraryRoot(root.toVirtualFileUrl(workspaceModel.getVirtualFileUrlManager()), LibraryRootTypeId.SOURCES)
|
||||
val libraryTableId = LibraryTableId.ProjectLibraryTableId
|
||||
val libraryId = LibraryId(ZIG_LIBRARY_ID, libraryTableId)
|
||||
|
||||
var baseModuleDirFile: VirtualFile? = null
|
||||
if (project.isDirectoryBased) {
|
||||
|
|
|
@ -28,10 +28,7 @@ import com.falsepattern.zigbrains.project.toolchain.base.resolve
|
|||
import com.falsepattern.zigbrains.project.toolchain.base.toRef
|
||||
import com.falsepattern.zigbrains.shared.UUIDMapSerializable
|
||||
import com.falsepattern.zigbrains.shared.UUIDStorage
|
||||
import com.intellij.openapi.components.Service
|
||||
import com.intellij.openapi.components.State
|
||||
import com.intellij.openapi.components.Storage
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.components.*
|
||||
|
||||
@Service(Service.Level.APP)
|
||||
@State(
|
||||
|
|
|
@ -27,12 +27,16 @@ import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
|||
import com.falsepattern.zigbrains.shared.asUUID
|
||||
import com.falsepattern.zigbrains.shared.zigCoroutineScope
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.components.*
|
||||
import com.intellij.openapi.components.SerializablePersistentStateComponent
|
||||
import com.intellij.openapi.components.Service
|
||||
import com.intellij.openapi.components.State
|
||||
import com.intellij.openapi.components.Storage
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.util.xmlb.annotations.Attribute
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.*
|
||||
import java.util.UUID
|
||||
|
||||
@Service(Service.Level.PROJECT)
|
||||
@State(
|
||||
|
|
|
@ -26,7 +26,9 @@ import com.falsepattern.zigbrains.project.toolchain.tools.ZigCompilerTool
|
|||
import com.falsepattern.zigbrains.shared.NamedObject
|
||||
import com.intellij.execution.configurations.GeneralCommandLine
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.util.xmlb.annotations.Attribute
|
||||
import com.intellij.util.xmlb.annotations.MapAnnotation
|
||||
import java.nio.file.Path
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,12 +25,12 @@ package com.falsepattern.zigbrains.project.toolchain.base
|
|||
import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvider
|
||||
import com.falsepattern.zigbrains.project.toolchain.ui.ImmutableElementPanel
|
||||
import com.falsepattern.zigbrains.project.toolchain.zigToolchainList
|
||||
import com.falsepattern.zigbrains.shared.ui.UUIDComboBoxDriver.Companion.wrapModal
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.ui.NamedConfigurable
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.openapi.util.NlsContexts
|
||||
import com.intellij.ui.dsl.builder.panel
|
||||
import java.util.*
|
||||
import java.util.UUID
|
||||
import java.util.function.Supplier
|
||||
import javax.swing.JComponent
|
||||
|
||||
|
@ -38,7 +38,7 @@ abstract class ZigToolchainConfigurable<T: ZigToolchain>(
|
|||
val uuid: UUID,
|
||||
tc: T,
|
||||
val data: ZigProjectConfigurationProvider.IUserDataBridge?,
|
||||
private val modal: Boolean
|
||||
val modal: Boolean
|
||||
): NamedConfigurable<UUID>() {
|
||||
var toolchain: T = tc
|
||||
set(value) {
|
||||
|
@ -65,7 +65,7 @@ abstract class ZigToolchainConfigurable<T: ZigToolchain>(
|
|||
views.forEach { it.attach(this@panel) }
|
||||
}.withMinimumWidth(20)
|
||||
views.forEach { it.reset(toolchain) }
|
||||
return wrapModal(p, modal)
|
||||
return p
|
||||
}
|
||||
|
||||
override fun getEditableObject(): UUID? {
|
||||
|
|
|
@ -31,8 +31,13 @@ import com.intellij.openapi.util.UserDataHolder
|
|||
import com.intellij.ui.SimpleColoredComponent
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.*
|
||||
import java.util.*
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.asFlow
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.flatMapConcat
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import java.util.UUID
|
||||
import kotlin.collections.none
|
||||
|
||||
private val EXTENSION_POINT_NAME = ExtensionPointName.create<ZigToolchainProvider>("com.falsepattern.zigbrains.toolchainProvider")
|
||||
|
||||
|
|
|
@ -24,15 +24,18 @@ package com.falsepattern.zigbrains.project.toolchain.downloader
|
|||
|
||||
import com.falsepattern.zigbrains.ZigBrainsBundle
|
||||
import com.falsepattern.zigbrains.project.toolchain.local.LocalZigToolchain
|
||||
import com.falsepattern.zigbrains.project.toolchain.local.suggestedLocalToolchainPath
|
||||
import com.falsepattern.zigbrains.project.toolchain.local.getSuggestedLocalToolchainPath
|
||||
import com.falsepattern.zigbrains.shared.downloader.Downloader
|
||||
import com.falsepattern.zigbrains.shared.downloader.LocalSelector
|
||||
import com.intellij.openapi.util.NlsContexts
|
||||
import java.awt.Component
|
||||
import java.nio.file.Path
|
||||
|
||||
class LocalToolchainDownloader(component: Component) : Downloader<LocalZigToolchain, ZigVersionInfo>(component) {
|
||||
override val windowTitle get() = ZigBrainsBundle.message("settings.toolchain.downloader.title")
|
||||
override val versionInfoFetchTitle get() = ZigBrainsBundle.message("settings.toolchain.downloader.progress.fetch")
|
||||
override val suggestedPath get() = suggestedLocalToolchainPath
|
||||
override fun downloadProgressTitle(version: ZigVersionInfo) = ZigBrainsBundle.message("settings.toolchain.downloader.progress.install", version.version.rawVersion)
|
||||
override fun localSelector() = LocalToolchainSelector(component)
|
||||
override suspend fun downloadVersionList() = ZigVersionInfo.downloadVersionList()
|
||||
override fun getSuggestedPath() = getSuggestedLocalToolchainPath()
|
||||
}
|
|
@ -23,18 +23,37 @@
|
|||
package com.falsepattern.zigbrains.project.toolchain.downloader
|
||||
|
||||
import com.falsepattern.zigbrains.ZigBrainsBundle
|
||||
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||
import com.falsepattern.zigbrains.project.toolchain.local.LocalZigToolchain
|
||||
import com.falsepattern.zigbrains.project.toolchain.zigToolchainList
|
||||
import com.falsepattern.zigbrains.shared.coroutine.asContextElement
|
||||
import com.falsepattern.zigbrains.shared.coroutine.launchWithEDT
|
||||
import com.falsepattern.zigbrains.shared.coroutine.withEDTContext
|
||||
import com.falsepattern.zigbrains.shared.downloader.LocalSelector
|
||||
import com.falsepattern.zigbrains.shared.withUniqueName
|
||||
import com.falsepattern.zigbrains.shared.zigCoroutineScope
|
||||
import com.intellij.icons.AllIcons
|
||||
import com.intellij.openapi.application.ModalityState
|
||||
import com.intellij.openapi.fileChooser.FileChooser
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptor
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory
|
||||
import com.intellij.openapi.ui.DialogBuilder
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.platform.ide.progress.ModalTaskOwner
|
||||
import com.intellij.platform.ide.progress.TaskCancellation
|
||||
import com.intellij.platform.ide.progress.withModalProgress
|
||||
import com.intellij.ui.DocumentAdapter
|
||||
import com.intellij.ui.components.JBLabel
|
||||
import com.intellij.ui.components.JBTextField
|
||||
import com.intellij.ui.components.textFieldWithBrowseButton
|
||||
import com.intellij.ui.dsl.builder.AlignX
|
||||
import com.intellij.ui.dsl.builder.panel
|
||||
import com.intellij.util.concurrency.annotations.RequiresEdt
|
||||
import java.awt.Component
|
||||
import java.nio.file.Path
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import javax.swing.event.DocumentEvent
|
||||
import kotlin.io.path.pathString
|
||||
|
||||
class LocalToolchainSelector(component: Component): LocalSelector<LocalZigToolchain>(component) {
|
||||
override val windowTitle: String
|
||||
|
|
|
@ -23,19 +23,46 @@
|
|||
package com.falsepattern.zigbrains.project.toolchain.downloader
|
||||
|
||||
import com.falsepattern.zigbrains.ZigBrainsBundle
|
||||
import com.falsepattern.zigbrains.shared.Unarchiver
|
||||
import com.falsepattern.zigbrains.shared.downloader.VersionInfo
|
||||
import com.falsepattern.zigbrains.shared.downloader.VersionInfo.Tarball
|
||||
import com.falsepattern.zigbrains.shared.downloader.downloadTarball
|
||||
import com.falsepattern.zigbrains.shared.downloader.flattenDownloadDir
|
||||
import com.falsepattern.zigbrains.shared.downloader.getTarballIfCompatible
|
||||
import com.falsepattern.zigbrains.shared.downloader.tempPluginDir
|
||||
import com.falsepattern.zigbrains.shared.downloader.unpackTarball
|
||||
import com.intellij.openapi.application.PathManager
|
||||
import com.intellij.openapi.progress.EmptyProgressIndicator
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.progress.coroutineToIndicator
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.util.io.toNioPathOrNull
|
||||
import com.intellij.platform.util.progress.*
|
||||
import com.intellij.util.asSafely
|
||||
import com.intellij.util.download.DownloadableFileService
|
||||
import com.intellij.util.io.createDirectories
|
||||
import com.intellij.util.io.delete
|
||||
import com.intellij.util.io.move
|
||||
import com.intellij.util.system.CpuArch
|
||||
import com.intellij.util.system.OS
|
||||
import com.intellij.util.text.SemVer
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.json.*
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
import kotlinx.serialization.json.JsonPrimitive
|
||||
import kotlinx.serialization.json.decodeFromJsonElement
|
||||
import kotlinx.serialization.json.decodeFromStream
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.ExperimentalPathApi
|
||||
import kotlin.io.path.deleteRecursively
|
||||
import kotlin.io.path.isDirectory
|
||||
import kotlin.io.path.name
|
||||
|
||||
@JvmRecord
|
||||
data class ZigVersionInfo(
|
||||
|
|
|
@ -28,8 +28,11 @@ import com.intellij.execution.ExecutionException
|
|||
import com.intellij.execution.configurations.GeneralCommandLine
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.project.guessProjectDir
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
import com.intellij.openapi.util.io.toNioPathOrNull
|
||||
import com.intellij.openapi.vfs.toNioPathOrNull
|
||||
import com.intellij.util.keyFMap.KeyFMap
|
||||
import java.nio.file.Path
|
||||
|
||||
@JvmRecord
|
||||
|
|
|
@ -24,7 +24,7 @@ package com.falsepattern.zigbrains.project.toolchain.local
|
|||
|
||||
import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvider
|
||||
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchainConfigurable
|
||||
import java.util.*
|
||||
import java.util.UUID
|
||||
|
||||
class LocalZigToolchainConfigurable(
|
||||
uuid: UUID,
|
||||
|
|
|
@ -73,8 +73,8 @@ class LocalZigToolchainPanel() : ImmutableNamedElementPanelBase<LocalZigToolchai
|
|||
).also { Disposer.register(this, it) }
|
||||
private var debounce: Job? = null
|
||||
|
||||
override fun attach(panel: Panel): Unit = with(panel) {
|
||||
super.attach(panel)
|
||||
override fun attach(p: Panel): Unit = with(p) {
|
||||
super.attach(p)
|
||||
row(ZigBrainsBundle.message("settings.toolchain.local.path.label")) {
|
||||
cell(pathToToolchain).resizableColumn().align(AlignX.FILL)
|
||||
}
|
||||
|
@ -87,23 +87,23 @@ class LocalZigToolchainPanel() : ImmutableNamedElementPanelBase<LocalZigToolchai
|
|||
}
|
||||
}
|
||||
|
||||
override fun isModified(elem: LocalZigToolchain): Boolean {
|
||||
override fun isModified(toolchain: LocalZigToolchain): Boolean {
|
||||
val name = nameFieldValue ?: return false
|
||||
val location = this.pathToToolchain.text.ifBlank { null }?.toNioPathOrNull() ?: return false
|
||||
val std = if (stdFieldOverride.isSelected) pathToStd.text.ifBlank { null }?.toNioPathOrNull() else null
|
||||
return name != elem.name || elem.location != location || elem.std != std
|
||||
return name != toolchain.name || toolchain.location != location || toolchain.std != std
|
||||
}
|
||||
|
||||
override fun apply(elem: LocalZigToolchain): LocalZigToolchain? {
|
||||
override fun apply(toolchain: LocalZigToolchain): LocalZigToolchain? {
|
||||
val location = this.pathToToolchain.text.ifBlank { null }?.toNioPathOrNull() ?: return null
|
||||
val std = if (stdFieldOverride.isSelected) pathToStd.text.ifBlank { null }?.toNioPathOrNull() else null
|
||||
return elem.copy(location = location, std = std, name = nameFieldValue ?: "")
|
||||
return toolchain.copy(location = location, std = std, name = nameFieldValue ?: "")
|
||||
}
|
||||
|
||||
override fun reset(elem: LocalZigToolchain?) {
|
||||
nameFieldValue = elem?.name ?: ""
|
||||
this.pathToToolchain.text = elem?.location?.pathString ?: ""
|
||||
val std = elem?.std
|
||||
override fun reset(toolchain: LocalZigToolchain?) {
|
||||
nameFieldValue = toolchain?.name ?: ""
|
||||
this.pathToToolchain.text = toolchain?.location?.pathString ?: ""
|
||||
val std = toolchain?.std
|
||||
if (std != null) {
|
||||
stdFieldOverride.isSelected = true
|
||||
pathToStd.text = std.pathString
|
||||
|
|
|
@ -28,18 +28,27 @@ import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvid
|
|||
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchainConfigurable
|
||||
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchainProvider
|
||||
import com.falsepattern.zigbrains.shared.downloader.homePath
|
||||
import com.falsepattern.zigbrains.shared.downloader.xdgDataHome
|
||||
import com.falsepattern.zigbrains.shared.ui.renderPathNameComponent
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.UserDataHolder
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.util.io.toNioPathOrNull
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.ui.SimpleColoredComponent
|
||||
import com.intellij.ui.SimpleTextAttributes
|
||||
import com.intellij.util.system.OS
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.asFlow
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
import kotlinx.coroutines.flow.flatMapConcat
|
||||
import kotlinx.coroutines.flow.flattenConcat
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.mapNotNull
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.util.*
|
||||
import java.util.UUID
|
||||
import kotlin.io.path.isDirectory
|
||||
import kotlin.io.path.pathString
|
||||
|
||||
class LocalZigToolchainProvider: ZigToolchainProvider {
|
||||
|
@ -93,7 +102,7 @@ class LocalZigToolchainProvider: ZigToolchainProvider {
|
|||
Env.empty
|
||||
}
|
||||
val pathToolchains = env.findAllExecutablesOnPATH("zig").mapNotNull { it.parent }
|
||||
val wellKnown = wellKnown.asFlow().flatMapConcat { dir ->
|
||||
val wellKnown = getWellKnown().asFlow().flatMapConcat { dir ->
|
||||
runCatching {
|
||||
Files.newDirectoryStream(dir).use { stream ->
|
||||
stream.toList().filterNotNull().asFlow()
|
||||
|
@ -112,8 +121,8 @@ class LocalZigToolchainProvider: ZigToolchainProvider {
|
|||
}
|
||||
}
|
||||
|
||||
val suggestedLocalToolchainPath: Path? by lazy {
|
||||
wellKnown.getOrNull(0)
|
||||
fun getSuggestedLocalToolchainPath(): Path? {
|
||||
return getWellKnown().getOrNull(0)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -130,12 +139,18 @@ val suggestedLocalToolchainPath: Path? by lazy {
|
|||
*
|
||||
* and HOME is the user home path
|
||||
*/
|
||||
private val wellKnown: List<Path> by lazy {
|
||||
val res = ArrayList<Path>()
|
||||
xdgDataHome?.let {
|
||||
res.add(it.resolve("zig"))
|
||||
res.add(it.resolve("zigup"))
|
||||
private fun getWellKnown(): List<Path> {
|
||||
val home = System.getProperty("user.home")?.toNioPathOrNull() ?: return emptyList()
|
||||
val xdgDataHome = when(OS.CURRENT) {
|
||||
OS.macOS -> home.resolve("Library")
|
||||
OS.Windows -> System.getenv("LOCALAPPDATA")?.toNioPathOrNull()
|
||||
else -> System.getenv("XDG_DATA_HOME")?.toNioPathOrNull() ?: home.resolve(Path.of(".local", "share"))
|
||||
}
|
||||
homePath?.let { res.add(it.resolve(".zig")) }
|
||||
res
|
||||
val res = ArrayList<Path>()
|
||||
if (xdgDataHome != null && xdgDataHome.isDirectory()) {
|
||||
res.add(xdgDataHome.resolve("zig"))
|
||||
res.add(xdgDataHome.resolve("zigup"))
|
||||
}
|
||||
res.add(home.resolve(".zig"))
|
||||
return res
|
||||
}
|
|
@ -24,6 +24,7 @@ package com.falsepattern.zigbrains.project.toolchain.tools
|
|||
|
||||
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||
import com.intellij.openapi.project.Project
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.serialization.SerializationException
|
||||
import kotlinx.serialization.json.Json
|
||||
import java.nio.file.Path
|
||||
|
|
|
@ -26,7 +26,7 @@ import com.intellij.openapi.Disposable
|
|||
import com.intellij.ui.dsl.builder.Panel
|
||||
|
||||
interface ImmutableElementPanel<T>: Disposable {
|
||||
fun attach(panel: Panel)
|
||||
fun attach(p: Panel)
|
||||
fun isModified(elem: T): Boolean
|
||||
/**
|
||||
* Returned object must be the exact same class as the provided one.
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
package com.falsepattern.zigbrains.project.toolchain.ui
|
||||
|
||||
import com.falsepattern.zigbrains.ZigBrainsBundle
|
||||
import com.falsepattern.zigbrains.shared.NamedObject
|
||||
import com.intellij.ui.components.JBTextField
|
||||
import com.intellij.ui.dsl.builder.AlignX
|
||||
import com.intellij.ui.dsl.builder.Panel
|
||||
|
@ -34,7 +35,7 @@ abstract class ImmutableNamedElementPanelBase<T>: ImmutableElementPanel<T> {
|
|||
get() = nameField.text.ifBlank { null }
|
||||
set(value) {nameField.text = value ?: ""}
|
||||
|
||||
override fun attach(panel: Panel): Unit = with(panel) {
|
||||
override fun attach(p: Panel): Unit = with(p) {
|
||||
row(ZigBrainsBundle.message("settings.toolchain.base.name.label")) {
|
||||
cell(nameField).resizableColumn().align(AlignX.FILL)
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ import com.falsepattern.zigbrains.shared.ui.ListElem
|
|||
import com.falsepattern.zigbrains.shared.withUniqueName
|
||||
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
|
||||
import java.awt.Component
|
||||
import java.util.*
|
||||
import java.util.UUID
|
||||
|
||||
internal object ZigToolchainComboBoxHandler {
|
||||
@RequiresBackgroundThread
|
||||
|
|
|
@ -29,10 +29,20 @@ import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
|||
import com.falsepattern.zigbrains.project.toolchain.base.createNamedConfigurable
|
||||
import com.falsepattern.zigbrains.project.toolchain.base.suggestZigToolchains
|
||||
import com.falsepattern.zigbrains.project.toolchain.zigToolchainList
|
||||
import com.falsepattern.zigbrains.shared.ui.*
|
||||
import com.falsepattern.zigbrains.shared.ui.ListElem
|
||||
import com.falsepattern.zigbrains.shared.ui.ListElemIn
|
||||
import com.falsepattern.zigbrains.shared.ui.Separator
|
||||
import com.falsepattern.zigbrains.shared.ui.UUIDComboBoxDriver
|
||||
import com.falsepattern.zigbrains.shared.ui.ZBComboBox
|
||||
import com.falsepattern.zigbrains.shared.ui.ZBContext
|
||||
import com.falsepattern.zigbrains.shared.ui.ZBModel
|
||||
import com.falsepattern.zigbrains.shared.ui.asActual
|
||||
import com.falsepattern.zigbrains.shared.ui.asPending
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.ui.NamedConfigurable
|
||||
import com.intellij.openapi.util.UserDataHolder
|
||||
import java.awt.Component
|
||||
import java.util.*
|
||||
import java.util.UUID
|
||||
|
||||
sealed interface ZigToolchainDriver: UUIDComboBoxDriver<ZigToolchain> {
|
||||
override val theMap get() = zigToolchainList
|
||||
|
|
|
@ -39,7 +39,7 @@ import com.intellij.openapi.project.ProjectManager
|
|||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.ui.dsl.builder.Panel
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.*
|
||||
import java.util.UUID
|
||||
import java.util.function.Supplier
|
||||
|
||||
class ZigToolchainEditor(private val sharedState: ZigProjectConfigurationProvider.IUserDataBridge):
|
||||
|
@ -60,7 +60,7 @@ class ZigToolchainEditor(private val sharedState: ZigProjectConfigurationProvide
|
|||
}
|
||||
|
||||
|
||||
override fun attach(panel: Panel): Unit = with(panel) {
|
||||
override fun attach(p: Panel): Unit = with(p) {
|
||||
row(ZigBrainsBundle.message(
|
||||
if (sharedState.getUserData(PROJECT_KEY)?.isDefault == true)
|
||||
"settings.toolchain.editor.toolchain-default.label"
|
||||
|
@ -75,7 +75,7 @@ class ZigToolchainEditor(private val sharedState: ZigProjectConfigurationProvide
|
|||
views.addAll(createZigToolchainExtensionPanels(sharedState, PanelState.ProjectEditor))
|
||||
myViews = views
|
||||
}
|
||||
views.forEach { it.attach(panel) }
|
||||
views.forEach { it.attach(p) }
|
||||
}
|
||||
|
||||
override fun onSelection(uuid: UUID?) {
|
||||
|
@ -89,8 +89,6 @@ class ZigToolchainEditor(private val sharedState: ZigProjectConfigurationProvide
|
|||
}
|
||||
|
||||
override fun isModified(context: Project): Boolean {
|
||||
if (isEmpty)
|
||||
return false
|
||||
val uuid = selectedUUID
|
||||
if (ZigToolchainService.getInstance(context).toolchainUUID != selectedUUID) {
|
||||
return true
|
||||
|
|
|
@ -26,7 +26,11 @@ import com.falsepattern.zigbrains.Icons
|
|||
import com.falsepattern.zigbrains.ZigBrainsBundle
|
||||
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||
import com.falsepattern.zigbrains.project.toolchain.base.render
|
||||
import com.falsepattern.zigbrains.shared.ui.*
|
||||
import com.falsepattern.zigbrains.shared.ui.ListElem
|
||||
import com.falsepattern.zigbrains.shared.ui.ZBCellRenderer
|
||||
import com.falsepattern.zigbrains.shared.ui.ZBComboBox
|
||||
import com.falsepattern.zigbrains.shared.ui.ZBContext
|
||||
import com.falsepattern.zigbrains.shared.ui.ZBModel
|
||||
import com.intellij.icons.AllIcons
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.ui.SimpleTextAttributes
|
||||
|
|
|
@ -27,6 +27,7 @@ import com.intellij.openapi.options.Configurable
|
|||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.ui.dsl.builder.Panel
|
||||
import com.intellij.ui.dsl.builder.panel
|
||||
import java.util.ArrayList
|
||||
import javax.swing.JComponent
|
||||
|
||||
interface SubConfigurable<T>: Disposable {
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
package com.falsepattern.zigbrains.shared
|
||||
|
||||
import java.util.*
|
||||
import java.util.UUID
|
||||
|
||||
fun String.asUUID(): UUID? = UUID.fromString(this)
|
||||
fun UUID.asString(): String = toString()
|
|
@ -26,7 +26,8 @@ import com.intellij.openapi.components.SerializablePersistentStateComponent
|
|||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.*
|
||||
import java.util.UUID
|
||||
import kotlin.collections.any
|
||||
|
||||
typealias UUIDStorage<T> = Map<String, T>
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -45,7 +45,7 @@ import com.intellij.ui.dsl.builder.panel
|
|||
import com.intellij.util.concurrency.annotations.RequiresEdt
|
||||
import java.awt.Component
|
||||
import java.nio.file.Path
|
||||
import java.util.*
|
||||
import java.util.Vector
|
||||
import javax.swing.DefaultComboBoxModel
|
||||
import javax.swing.JList
|
||||
import javax.swing.event.DocumentEvent
|
||||
|
@ -76,10 +76,10 @@ abstract class Downloader<T, V: VersionInfo>(val component: Component) {
|
|||
|
||||
protected abstract val windowTitle: String
|
||||
protected abstract val versionInfoFetchTitle: @NlsContexts.ProgressTitle String
|
||||
protected abstract val suggestedPath: Path?
|
||||
protected abstract fun downloadProgressTitle(version: V): @NlsContexts.ProgressTitle String
|
||||
protected abstract fun localSelector(): LocalSelector<T>
|
||||
protected abstract suspend fun downloadVersionList(): List<V>
|
||||
protected abstract fun getSuggestedPath(): Path?
|
||||
|
||||
@RequiresEdt
|
||||
private fun selectVersion(info: List<V>, selector: LocalSelector<T>): Pair<Path, V>? {
|
||||
|
@ -131,7 +131,7 @@ abstract class Downloader<T, V: VersionInfo>(val component: Component) {
|
|||
})
|
||||
var archiveSizeCell: Cell<*>? = null
|
||||
fun detect(item: V) {
|
||||
outputPath.text = suggestedPath?.resolve(item.version.rawVersion)?.pathString ?: ""
|
||||
outputPath.text = getSuggestedPath()?.resolve(item.version.rawVersion)?.pathString ?: ""
|
||||
val size = item.dist.size
|
||||
val sizeMb = size / (1024f * 1024f)
|
||||
archiveSizeCell?.comment?.text = ZigBrainsBundle.message("settings.shared.downloader.archive-size.text", "%.2fMB".format(sizeMb))
|
||||
|
|
|
@ -41,13 +41,11 @@ import com.intellij.ui.components.textFieldWithBrowseButton
|
|||
import com.intellij.ui.dsl.builder.AlignX
|
||||
import com.intellij.ui.dsl.builder.panel
|
||||
import com.intellij.util.concurrency.annotations.RequiresEdt
|
||||
import com.intellij.util.system.OS
|
||||
import java.awt.Component
|
||||
import java.nio.file.Path
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import javax.swing.Icon
|
||||
import javax.swing.event.DocumentEvent
|
||||
import kotlin.io.path.isDirectory
|
||||
import kotlin.io.path.pathString
|
||||
|
||||
abstract class LocalSelector<T>(val component: Component) {
|
||||
|
@ -138,15 +136,3 @@ abstract class LocalSelector<T>(val component: Component) {
|
|||
val errorText: String,
|
||||
)
|
||||
}
|
||||
|
||||
val homePath: Path? by lazy {
|
||||
System.getProperty("user.home")?.toNioPathOrNull()?.takeIf { it.isDirectory() }
|
||||
}
|
||||
|
||||
val xdgDataHome: Path? by lazy {
|
||||
when(OS.CURRENT) {
|
||||
OS.macOS -> homePath?.resolve("Library")
|
||||
OS.Windows -> System.getenv("LOCALAPPDATA")?.toNioPathOrNull()
|
||||
else -> System.getenv("XDG_DATA_HOME")?.toNioPathOrNull() ?: homePath?.resolve(Path.of(".local", "share"))
|
||||
}?.takeIf { it.isDirectory() }
|
||||
}
|
|
@ -23,6 +23,7 @@
|
|||
package com.falsepattern.zigbrains.shared.downloader
|
||||
|
||||
import com.falsepattern.zigbrains.ZigBrainsBundle
|
||||
import com.falsepattern.zigbrains.project.toolchain.downloader.ZigVersionInfo
|
||||
import com.falsepattern.zigbrains.shared.Unarchiver
|
||||
import com.falsepattern.zigbrains.shared.downloader.VersionInfo.Tarball
|
||||
import com.intellij.openapi.application.PathManager
|
||||
|
|
|
@ -24,11 +24,8 @@ package com.falsepattern.zigbrains.shared.ui
|
|||
|
||||
import com.falsepattern.zigbrains.shared.UUIDMapSerializable
|
||||
import com.intellij.openapi.ui.NamedConfigurable
|
||||
import com.intellij.ui.components.JBScrollPane
|
||||
import java.awt.Component
|
||||
import java.awt.Dimension
|
||||
import java.util.*
|
||||
import javax.swing.JComponent
|
||||
import java.util.UUID
|
||||
|
||||
interface UUIDComboBoxDriver<T> {
|
||||
val theMap: UUIDMapSerializable.Converting<T, *, *>
|
||||
|
@ -37,15 +34,4 @@ interface UUIDComboBoxDriver<T> {
|
|||
fun createComboBox(model: ZBModel<T>): ZBComboBox<T>
|
||||
suspend fun resolvePseudo(context: Component, elem: ListElem.Pseudo<T>): UUID?
|
||||
fun createNamedConfigurable(uuid: UUID, elem: T): NamedConfigurable<UUID>
|
||||
|
||||
companion object {
|
||||
fun wrapModal(component: JComponent, modal: Boolean): JComponent {
|
||||
if (modal) {
|
||||
component.preferredSize = Dimension(640, 480)
|
||||
return component
|
||||
} else {
|
||||
return JBScrollPane(component)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -39,7 +39,7 @@ import com.intellij.util.IconUtil
|
|||
import com.intellij.util.asSafely
|
||||
import com.intellij.util.concurrency.annotations.RequiresEdt
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.*
|
||||
import java.util.UUID
|
||||
import javax.swing.JComponent
|
||||
import javax.swing.tree.DefaultTreeModel
|
||||
|
||||
|
|
|
@ -28,10 +28,12 @@ import com.falsepattern.zigbrains.shared.StorageChangeListener
|
|||
import com.falsepattern.zigbrains.shared.coroutine.asContextElement
|
||||
import com.falsepattern.zigbrains.shared.coroutine.launchWithEDT
|
||||
import com.falsepattern.zigbrains.shared.coroutine.withEDTContext
|
||||
import com.falsepattern.zigbrains.shared.ui.ListElem
|
||||
import com.falsepattern.zigbrains.shared.zigCoroutineScope
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.application.ModalityState
|
||||
import com.intellij.openapi.application.runInEdt
|
||||
import com.intellij.openapi.observable.util.whenListChanged
|
||||
import com.intellij.openapi.options.ShowSettingsUtil
|
||||
import com.intellij.openapi.ui.DialogWrapper
|
||||
|
@ -39,11 +41,12 @@ import com.intellij.ui.dsl.builder.AlignX
|
|||
import com.intellij.ui.dsl.builder.Row
|
||||
import com.intellij.util.concurrency.annotations.RequiresEdt
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Runnable
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.awt.event.ItemEvent
|
||||
import java.util.*
|
||||
import java.util.UUID
|
||||
import javax.swing.JButton
|
||||
|
||||
abstract class UUIDMapSelector<T>(val driver: UUIDComboBoxDriver<T>): Disposable {
|
||||
|
@ -79,8 +82,6 @@ abstract class UUIDMapSelector<T>(val driver: UUIDComboBoxDriver<T>): Disposable
|
|||
}
|
||||
}
|
||||
|
||||
protected val isEmpty: Boolean get() = model.isEmpty
|
||||
|
||||
protected open fun onSelection(uuid: UUID?) {}
|
||||
|
||||
private fun refreshButtonState(item: ListElem<*>) {
|
||||
|
@ -161,7 +162,7 @@ abstract class UUIDMapSelector<T>(val driver: UUIDComboBoxDriver<T>): Disposable
|
|||
|
||||
protected fun attachComboBoxRow(row: Row): Unit = with(row) {
|
||||
cell(comboBox).resizableColumn().align(AlignX.FILL)
|
||||
button(ZigBrainsBundle.message("settings.toolchain.editor.toolchain.edit-button.name")) {
|
||||
button(ZigBrainsBundle.message("settings.toolchain.editor.toolchain.edit-button.name")) { e ->
|
||||
zigCoroutineScope.launchWithEDT(comboBox.asContextElement()) {
|
||||
var selectedUUID = comboBox.selectedUUID ?: return@launchWithEDT
|
||||
val elem = driver.theMap[selectedUUID] ?: return@launchWithEDT
|
||||
|
|
|
@ -24,7 +24,7 @@ package com.falsepattern.zigbrains.shared.ui
|
|||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import java.util.*
|
||||
import java.util.UUID
|
||||
|
||||
|
||||
sealed interface ListElemIn<T>
|
||||
|
|
|
@ -31,7 +31,12 @@ import com.intellij.openapi.project.Project
|
|||
import com.intellij.openapi.ui.ComboBox
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.ui.*
|
||||
import com.intellij.ui.CellRendererPanel
|
||||
import com.intellij.ui.CollectionComboBoxModel
|
||||
import com.intellij.ui.ColoredListCellRenderer
|
||||
import com.intellij.ui.GroupHeaderSeparator
|
||||
import com.intellij.ui.SimpleColoredComponent
|
||||
import com.intellij.ui.SimpleTextAttributes
|
||||
import com.intellij.ui.components.panels.OpaquePanel
|
||||
import com.intellij.ui.popup.list.ComboBoxPopup
|
||||
import com.intellij.util.concurrency.annotations.RequiresEdt
|
||||
|
@ -42,11 +47,13 @@ import kotlinx.coroutines.Dispatchers
|
|||
import kotlinx.coroutines.launch
|
||||
import java.awt.BorderLayout
|
||||
import java.awt.Component
|
||||
import java.util.*
|
||||
import java.util.IdentityHashMap
|
||||
import java.util.UUID
|
||||
import java.util.function.Consumer
|
||||
import javax.accessibility.AccessibleContext
|
||||
import javax.swing.JList
|
||||
import javax.swing.border.Border
|
||||
import kotlin.io.path.pathString
|
||||
|
||||
class ZBComboBoxPopup<T>(
|
||||
context: ZBContext<T>,
|
||||
|
@ -250,16 +257,16 @@ abstract class ZBCellRenderer<T>(val getModel: () -> ZBModel<T>) : ColoredListCe
|
|||
}
|
||||
|
||||
fun renderPathNameComponent(path: String, name: String?, nameFallback: String, component: SimpleColoredComponent, isSuggestion: Boolean, isSelected: Boolean) {
|
||||
val thePath = presentDetectedPath(path)
|
||||
val path = presentDetectedPath(path)
|
||||
val primary: String
|
||||
var secondary: String?
|
||||
val tooltip: String?
|
||||
if (isSuggestion) {
|
||||
primary = thePath
|
||||
primary = path
|
||||
secondary = name
|
||||
} else {
|
||||
primary = name ?: nameFallback
|
||||
secondary = thePath
|
||||
secondary = path
|
||||
}
|
||||
if (isSelected) {
|
||||
tooltip = secondary
|
||||
|
@ -277,12 +284,12 @@ fun renderPathNameComponent(path: String, name: String?, nameFallback: String, c
|
|||
|
||||
fun presentDetectedPath(home: String, maxLength: Int = 50, suffixLength: Int = 30): String {
|
||||
//for macOS, let's try removing Bundle internals
|
||||
var theHome = home
|
||||
theHome = StringUtil.trimEnd(theHome, "/Contents/Home") //NON-NLS
|
||||
theHome = StringUtil.trimEnd(theHome, "/Contents/MacOS") //NON-NLS
|
||||
theHome = FileUtil.getLocationRelativeToUserHome(theHome, false)
|
||||
theHome = StringUtil.shortenTextWithEllipsis(theHome, maxLength, suffixLength)
|
||||
return theHome
|
||||
var home = home
|
||||
home = StringUtil.trimEnd(home, "/Contents/Home") //NON-NLS
|
||||
home = StringUtil.trimEnd(home, "/Contents/MacOS") //NON-NLS
|
||||
home = FileUtil.getLocationRelativeToUserHome(home, false)
|
||||
home = StringUtil.shortenTextWithEllipsis(home, maxLength, suffixLength)
|
||||
return home
|
||||
}
|
||||
|
||||
private val EMPTY_ICON = EmptyIcon.create(1, 16)
|
|
@ -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,13 +1,13 @@
|
|||
pluginName=ZigBrains
|
||||
pluginRepositoryUrl=https://github.com/FalsePattern/ZigBrains
|
||||
|
||||
pluginVersion=25.2.0
|
||||
pluginVersion=24.0.1
|
||||
|
||||
pluginSinceBuild=251
|
||||
pluginSinceBuild=243
|
||||
pluginUntilBuild=
|
||||
|
||||
ideaCommunityVersion=2025.1
|
||||
clionVersion=2025.1
|
||||
ideaCommunityVersion=2024.3
|
||||
clionVersion=2024.3
|
||||
useInstaller=true
|
||||
javaVersion=21
|
||||
# ideaCommunity / clion
|
||||
|
@ -17,8 +17,6 @@ lsp4jVersion=0.21.1
|
|||
lsp4ijVersion=0.12.0
|
||||
lsp4ijNightly=false
|
||||
|
||||
serializationVersion=1.7.3
|
||||
|
||||
kotlin.stdlib.default.dependency=false
|
||||
kotlin.code.style=official
|
||||
org.gradle.configuration-cache=true
|
||||
|
|
|
@ -8,15 +8,12 @@ val lsp4ijVersion: String by project
|
|||
val lsp4jVersion: String by project
|
||||
val ideaCommunityVersion: String by project
|
||||
val useInstaller = property("useInstaller").toString().toBoolean()
|
||||
val serializationVersion: String by project
|
||||
|
||||
dependencies {
|
||||
intellijPlatform {
|
||||
create(IntelliJPlatformType.IntellijIdeaCommunity, ideaCommunityVersion, useInstaller = useInstaller)
|
||||
}
|
||||
compileOnly("org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:$serializationVersion") {
|
||||
isTransitive = false
|
||||
}
|
||||
compileOnly("org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.3")
|
||||
compileOnly("com.redhat.devtools.intellij:lsp4ij:$lsp4ijVersion")
|
||||
compileOnly("org.eclipse.lsp4j:org.eclipse.lsp4j:$lsp4jVersion")
|
||||
implementation(project(":core")) {
|
||||
|
|
|
@ -24,6 +24,7 @@ package com.falsepattern.zigbrains.lsp
|
|||
|
||||
import com.falsepattern.zigbrains.lsp.config.ZLSConfigProviderBase
|
||||
import com.falsepattern.zigbrains.lsp.zls.zls
|
||||
import com.falsepattern.zigbrains.project.toolchain.ZigToolchainService
|
||||
import com.intellij.execution.configurations.GeneralCommandLine
|
||||
import com.intellij.notification.Notification
|
||||
import com.intellij.notification.NotificationType
|
||||
|
|
|
@ -68,14 +68,7 @@ class ZigLanguageServerFactory: LanguageServerFactory, LanguageServerEnablementS
|
|||
}
|
||||
features.inlayHintFeature = object: LSPInlayHintFeature() {
|
||||
override fun isEnabled(file: PsiFile): Boolean {
|
||||
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 project.zls?.settings?.inlayHints == true
|
||||
}
|
||||
}
|
||||
return features
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
package com.falsepattern.zigbrains.lsp.settings
|
||||
|
||||
import com.falsepattern.zigbrains.lsp.config.SemanticTokens
|
||||
import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvider
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.util.xmlb.annotations.Attribute
|
||||
import org.jetbrains.annotations.NonNls
|
||||
|
||||
|
@ -30,7 +32,6 @@ import org.jetbrains.annotations.NonNls
|
|||
data class ZLSSettings(
|
||||
@JvmField @Attribute val zlsConfigPath: @NonNls String = "",
|
||||
@JvmField @Attribute val inlayHints: Boolean = true,
|
||||
@JvmField @Attribute val inlayHintsMaxFileSizeKb: Int = 128,
|
||||
@JvmField @Attribute val enable_snippets: Boolean = true,
|
||||
@JvmField @Attribute val enable_argument_placeholders: Boolean = true,
|
||||
@JvmField @Attribute val completion_label_details: Boolean = true,
|
||||
|
|
|
@ -35,9 +35,6 @@ import com.intellij.ui.dsl.builder.AlignX
|
|||
import com.intellij.ui.dsl.builder.Panel
|
||||
import com.intellij.ui.dsl.builder.Row
|
||||
import org.jetbrains.annotations.PropertyKey
|
||||
import javax.swing.text.AttributeSet
|
||||
import javax.swing.text.DocumentFilter
|
||||
import javax.swing.text.PlainDocument
|
||||
|
||||
@Suppress("PrivatePropertyName")
|
||||
class ZLSSettingsPanel() : ImmutableElementPanel<ZLSSettings> {
|
||||
|
@ -47,27 +44,6 @@ class ZLSSettingsPanel() : ImmutableElementPanel<ZLSSettings> {
|
|||
.withTitle(ZLSBundle.message("settings.zls-config-path.browse.title"))
|
||||
).also { Disposer.register(this, it) }
|
||||
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_argument_placeholders = JBCheckBox()
|
||||
private val completion_label_details = JBCheckBox()
|
||||
|
@ -89,7 +65,7 @@ class ZLSSettingsPanel() : ImmutableElementPanel<ZLSSettings> {
|
|||
private val build_runner_path = ExtendableTextField()
|
||||
private val global_cache_path = ExtendableTextField()
|
||||
|
||||
override fun attach(panel: Panel): Unit = with(panel) {
|
||||
override fun attach(p: Panel): Unit = with(p) {
|
||||
fancyRow(
|
||||
"settings.zls-config-path.label",
|
||||
"settings.zls-config-path.tooltip"
|
||||
|
@ -123,13 +99,6 @@ class ZLSSettingsPanel() : ImmutableElementPanel<ZLSSettings> {
|
|||
"settings.inlay-hints-enable.label",
|
||||
"settings.inlay-hints-enable.tooltip"
|
||||
) { 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(
|
||||
"settings.inlay_hints_show_variable_type_hints.label",
|
||||
"settings.inlay_hints_show_variable_type_hints.tooltip"
|
||||
|
@ -205,7 +174,6 @@ class ZLSSettingsPanel() : ImmutableElementPanel<ZLSSettings> {
|
|||
get() = ZLSSettings(
|
||||
zlsConfigPath.text,
|
||||
inlayHints.isSelected,
|
||||
inlayHintsMaxFileSize.text.toIntOrNull() ?: 128,
|
||||
enable_snippets.isSelected,
|
||||
enable_argument_placeholders.isSelected,
|
||||
completion_label_details.isSelected,
|
||||
|
@ -230,7 +198,6 @@ class ZLSSettingsPanel() : ImmutableElementPanel<ZLSSettings> {
|
|||
set(value) {
|
||||
zlsConfigPath.text = value.zlsConfigPath
|
||||
inlayHints.isSelected = value.inlayHints
|
||||
inlayHintsMaxFileSize.text = value.inlayHintsMaxFileSizeKb.toString()
|
||||
enable_snippets.isSelected = value.enable_snippets
|
||||
enable_argument_placeholders.isSelected = value.enable_argument_placeholders
|
||||
completion_label_details.isSelected = value.completion_label_details
|
||||
|
|
|
@ -22,14 +22,15 @@
|
|||
|
||||
package com.falsepattern.zigbrains.lsp.zls
|
||||
|
||||
import com.falsepattern.zigbrains.shared.ui.UUIDComboBoxDriver.Companion.wrapModal
|
||||
import com.intellij.openapi.ui.NamedConfigurable
|
||||
import com.intellij.openapi.util.NlsContexts
|
||||
import com.intellij.openapi.util.NlsSafe
|
||||
import com.intellij.ui.dsl.builder.panel
|
||||
import java.util.*
|
||||
import java.awt.Dimension
|
||||
import java.util.UUID
|
||||
import javax.swing.JComponent
|
||||
|
||||
class ZLSConfigurable(val uuid: UUID, zls: ZLSVersion, private val modal: Boolean): NamedConfigurable<UUID>() {
|
||||
class ZLSConfigurable(val uuid: UUID, zls: ZLSVersion): NamedConfigurable<UUID>() {
|
||||
var zls: ZLSVersion = zls
|
||||
set(value) {
|
||||
zlsInstallations[uuid] = value
|
||||
|
@ -59,7 +60,8 @@ class ZLSConfigurable(val uuid: UUID, zls: ZLSVersion, private val modal: Boolea
|
|||
val p = panel {
|
||||
view.attach(this@panel)
|
||||
}
|
||||
return wrapModal(p, modal)
|
||||
p.preferredSize = Dimension(640, 480)
|
||||
return p
|
||||
}
|
||||
|
||||
override fun getDisplayName(): @NlsContexts.ConfigurableName String? {
|
||||
|
|
|
@ -25,10 +25,7 @@ package com.falsepattern.zigbrains.lsp.zls
|
|||
import com.falsepattern.zigbrains.lsp.zls.ZLSInstallationsService.MyState
|
||||
import com.falsepattern.zigbrains.shared.UUIDMapSerializable
|
||||
import com.falsepattern.zigbrains.shared.UUIDStorage
|
||||
import com.intellij.openapi.components.Service
|
||||
import com.intellij.openapi.components.State
|
||||
import com.intellij.openapi.components.Storage
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.components.*
|
||||
|
||||
@Service(Service.Level.APP)
|
||||
@State(
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
|
||||
package com.falsepattern.zigbrains.lsp.zls
|
||||
|
||||
import com.falsepattern.zigbrains.lsp.ZLSBundle
|
||||
import com.falsepattern.zigbrains.lsp.settings.ZLSSettingsPanel
|
||||
import com.falsepattern.zigbrains.project.toolchain.local.LocalZigToolchain
|
||||
import com.falsepattern.zigbrains.project.toolchain.ui.ImmutableNamedElementPanelBase
|
||||
import com.falsepattern.zigbrains.shared.cli.call
|
||||
import com.falsepattern.zigbrains.shared.cli.createCommandLineSafe
|
||||
|
@ -49,7 +49,7 @@ import kotlin.io.path.pathString
|
|||
class ZLSPanel() : ImmutableNamedElementPanelBase<ZLSVersion>() {
|
||||
private val pathToZLS = textFieldWithBrowseButton(
|
||||
null,
|
||||
FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor().withTitle(ZLSBundle.message("dialog.title.zls"))
|
||||
FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor().withTitle("Path to the zls executable")
|
||||
).also {
|
||||
it.textField.document.addDocumentListener(object : DocumentAdapter() {
|
||||
override fun textChanged(e: DocumentEvent) {
|
||||
|
@ -62,36 +62,36 @@ class ZLSPanel() : ImmutableNamedElementPanelBase<ZLSVersion>() {
|
|||
private var settingsPanel: ZLSSettingsPanel? = null
|
||||
private var debounce: Job? = null
|
||||
|
||||
override fun attach(panel: Panel): Unit = with(panel) {
|
||||
super.attach(panel)
|
||||
row(ZLSBundle.message("settings.panel.path.label")) {
|
||||
override fun attach(p: Panel): Unit = with(p) {
|
||||
super.attach(p)
|
||||
row("Path:") {
|
||||
cell(pathToZLS).resizableColumn().align(AlignX.FILL)
|
||||
}
|
||||
row(ZLSBundle.message("settings.panel.version.label")) {
|
||||
row("Version:") {
|
||||
cell(zlsVersion)
|
||||
}
|
||||
val sp = ZLSSettingsPanel()
|
||||
panel.collapsibleGroup(ZLSBundle.message("settings.panel.settings.group.label"), indent = false) {
|
||||
p.collapsibleGroup("Settings", indent = false) {
|
||||
sp.attach(this@collapsibleGroup)
|
||||
}
|
||||
settingsPanel = sp
|
||||
}
|
||||
|
||||
override fun isModified(elem: ZLSVersion): Boolean {
|
||||
override fun isModified(version: ZLSVersion): Boolean {
|
||||
val name = nameFieldValue ?: return false
|
||||
val path = this.pathToZLS.text.ifBlank { null }?.toNioPathOrNull() ?: return false
|
||||
return name != elem.name || elem.path != path || settingsPanel?.isModified(elem.settings) == true
|
||||
return name != version.name || version.path != path || settingsPanel?.isModified(version.settings) == true
|
||||
}
|
||||
|
||||
override fun apply(elem: ZLSVersion): ZLSVersion? {
|
||||
override fun apply(version: ZLSVersion): ZLSVersion? {
|
||||
val path = this.pathToZLS.text.ifBlank { null }?.toNioPathOrNull() ?: return null
|
||||
return elem.copy(path = path, name = nameFieldValue ?: "", settings = settingsPanel?.apply(elem.settings) ?: elem.settings)
|
||||
return version.copy(path = path, name = nameFieldValue ?: "", settings = settingsPanel?.apply(version.settings) ?: version.settings)
|
||||
}
|
||||
|
||||
override fun reset(elem: ZLSVersion?) {
|
||||
nameFieldValue = elem?.name ?: ""
|
||||
this.pathToZLS.text = elem?.path?.pathString ?: ""
|
||||
settingsPanel?.reset(elem?.settings)
|
||||
override fun reset(version: ZLSVersion?) {
|
||||
nameFieldValue = version?.name ?: ""
|
||||
this.pathToZLS.text = version?.path?.pathString ?: ""
|
||||
settingsPanel?.reset(version?.settings)
|
||||
dispatchUpdateUI()
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ import com.falsepattern.zigbrains.project.toolchain.base.withExtraData
|
|||
import com.falsepattern.zigbrains.shared.asString
|
||||
import com.falsepattern.zigbrains.shared.asUUID
|
||||
import com.intellij.openapi.project.Project
|
||||
import java.util.*
|
||||
import java.util.UUID
|
||||
|
||||
fun <T: ZigToolchain> T.withZLS(uuid: UUID?): T {
|
||||
return withExtraData("zls_uuid", uuid?.asString())
|
||||
|
|
|
@ -26,11 +26,12 @@ import com.falsepattern.zigbrains.lsp.settings.ZLSSettings
|
|||
import com.falsepattern.zigbrains.shared.NamedObject
|
||||
import com.falsepattern.zigbrains.shared.cli.call
|
||||
import com.falsepattern.zigbrains.shared.cli.createCommandLineSafe
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
import com.intellij.openapi.util.io.toNioPathOrNull
|
||||
import com.intellij.util.text.SemVer
|
||||
import com.intellij.util.xmlb.annotations.Attribute
|
||||
import com.intellij.util.xmlb.annotations.Tag
|
||||
import java.nio.file.Path
|
||||
import com.intellij.util.xmlb.annotations.Attribute
|
||||
import kotlin.io.path.isDirectory
|
||||
import kotlin.io.path.isExecutable
|
||||
import kotlin.io.path.isRegularFile
|
||||
import kotlin.io.path.pathString
|
||||
|
@ -81,7 +82,6 @@ data class ZLSVersion(val path: Path, override val name: String? = null, val set
|
|||
@Attribute
|
||||
val name: String? = "",
|
||||
@JvmField
|
||||
@Tag
|
||||
val settings: ZLSSettings = ZLSSettings()
|
||||
) {
|
||||
fun resolve(): ZLSVersion? {
|
||||
|
|
|
@ -22,24 +22,27 @@
|
|||
|
||||
package com.falsepattern.zigbrains.lsp.zls.downloader
|
||||
|
||||
import com.falsepattern.zigbrains.lsp.ZLSBundle
|
||||
import com.falsepattern.zigbrains.lsp.zls.ZLSVersion
|
||||
import com.falsepattern.zigbrains.lsp.zls.ui.suggestedZLSPath
|
||||
import com.falsepattern.zigbrains.lsp.zls.ui.getSuggestedZLSPath
|
||||
import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvider
|
||||
import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvider.IUserDataBridge
|
||||
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchainConfigurable
|
||||
import com.falsepattern.zigbrains.shared.downloader.Downloader
|
||||
import com.intellij.openapi.util.io.toNioPathOrNull
|
||||
import com.intellij.util.system.OS
|
||||
import java.awt.Component
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.isDirectory
|
||||
|
||||
class ZLSDownloader(component: Component, private val data: IUserDataBridge?) : Downloader<ZLSVersion, ZLSVersionInfo>(component) {
|
||||
override val windowTitle get() = ZLSBundle.message("settings.downloader.title")
|
||||
override val versionInfoFetchTitle get() = ZLSBundle.message("settings.downloader.progress.fetch")
|
||||
override val suggestedPath get() = suggestedZLSPath
|
||||
override fun downloadProgressTitle(version: ZLSVersionInfo) = ZLSBundle.message("settings.downloader.progress.install", version.version.rawVersion)
|
||||
override val windowTitle get() = "Install ZLS"
|
||||
override val versionInfoFetchTitle get() = "Fetching zls version information"
|
||||
override fun downloadProgressTitle(version: ZLSVersionInfo) = "Installing ZLS ${version.version.rawVersion}"
|
||||
override fun localSelector() = ZLSLocalSelector(component)
|
||||
override suspend fun downloadVersionList(): List<ZLSVersionInfo> {
|
||||
val toolchain = data?.getUserData(ZigToolchainConfigurable.TOOLCHAIN_KEY)?.get()
|
||||
val project = data?.getUserData(ZigProjectConfigurationProvider.PROJECT_KEY)
|
||||
return ZLSVersionInfo.downloadVersionInfoFor(toolchain, project)
|
||||
}
|
||||
override fun getSuggestedPath() = getSuggestedZLSPath()
|
||||
}
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
package com.falsepattern.zigbrains.lsp.zls.downloader
|
||||
|
||||
import com.falsepattern.zigbrains.lsp.ZLSBundle
|
||||
import com.falsepattern.zigbrains.lsp.zls.ZLSVersion
|
||||
import com.falsepattern.zigbrains.lsp.zls.zlsInstallations
|
||||
import com.falsepattern.zigbrains.shared.downloader.LocalSelector
|
||||
|
@ -37,9 +36,9 @@ import kotlin.io.path.isDirectory
|
|||
|
||||
class ZLSLocalSelector(component: Component) : LocalSelector<ZLSVersion>(component) {
|
||||
override val windowTitle: String
|
||||
get() = ZLSBundle.message("settings.local-selector.title")
|
||||
get() = "Select ZLS from disk"
|
||||
override val descriptor: FileChooserDescriptor
|
||||
get() = FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor().withTitle(ZLSBundle.message("settings.local-selector.chooser.title"))
|
||||
get() = FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor().withTitle("ZLS binary")
|
||||
|
||||
override suspend fun browse(preSelected: Path?): ZLSVersion? {
|
||||
if (preSelected?.isDirectory() == true) {
|
||||
|
@ -55,12 +54,12 @@ class ZLSLocalSelector(component: Component) : LocalSelector<ZLSVersion>(compone
|
|||
null,
|
||||
false,
|
||||
AllIcons.General.Error,
|
||||
ZLSBundle.message("settings.local-selector.state.invalid"),
|
||||
"Invalid ZLS path",
|
||||
) else VerifyResult(
|
||||
null,
|
||||
true,
|
||||
AllIcons.General.Information,
|
||||
ZLSBundle.message("settings.local-selector.state.ok")
|
||||
"ZLS path OK"
|
||||
)
|
||||
if (zls != null) {
|
||||
zls = zlsInstallations.withUniqueName(zls)
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
|
||||
package com.falsepattern.zigbrains.lsp.zls.downloader
|
||||
|
||||
import com.falsepattern.zigbrains.lsp.ZLSBundle
|
||||
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||
import com.falsepattern.zigbrains.project.toolchain.downloader.ZigVersionInfo
|
||||
import com.falsepattern.zigbrains.shared.downloader.VersionInfo
|
||||
import com.falsepattern.zigbrains.shared.downloader.VersionInfo.Tarball
|
||||
import com.falsepattern.zigbrains.shared.downloader.getTarballIfCompatible
|
||||
|
@ -37,7 +37,12 @@ import com.intellij.util.text.SemVer
|
|||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.json.*
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
import kotlinx.serialization.json.JsonPrimitive
|
||||
import kotlinx.serialization.json.decodeFromJsonElement
|
||||
import kotlinx.serialization.json.decodeFromStream
|
||||
import java.net.URLEncoder
|
||||
|
||||
@JvmRecord
|
||||
|
@ -59,7 +64,7 @@ data class ZLSVersionInfo(
|
|||
val service = DownloadableFileService.getInstance()
|
||||
val tempFile = FileUtil.createTempFile(tempPluginDir, "zls_version_info", ".json", false, false)
|
||||
val desc = service.createFileDescription(url, tempFile.name)
|
||||
val downloader = service.createDownloader(listOf(desc), ZLSBundle.message("settings.downloader.service.index"))
|
||||
val downloader = service.createDownloader(listOf(desc), "ZLS version information")
|
||||
val downloadResults = coroutineToIndicator {
|
||||
downloader.download(tempPluginDir)
|
||||
}
|
||||
|
|
|
@ -33,14 +33,21 @@ import com.falsepattern.zigbrains.lsp.zls.zlsInstallations
|
|||
import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvider
|
||||
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchainConfigurable.Companion.TOOLCHAIN_KEY
|
||||
import com.falsepattern.zigbrains.shared.UUIDMapSerializable
|
||||
import com.falsepattern.zigbrains.shared.downloader.homePath
|
||||
import com.falsepattern.zigbrains.shared.downloader.xdgDataHome
|
||||
import com.falsepattern.zigbrains.shared.ui.*
|
||||
import com.falsepattern.zigbrains.shared.ui.ListElem
|
||||
import com.falsepattern.zigbrains.shared.ui.ListElem.One.Actual
|
||||
import com.falsepattern.zigbrains.shared.ui.ListElemIn
|
||||
import com.falsepattern.zigbrains.shared.ui.Separator
|
||||
import com.falsepattern.zigbrains.shared.ui.UUIDComboBoxDriver
|
||||
import com.falsepattern.zigbrains.shared.ui.ZBComboBox
|
||||
import com.falsepattern.zigbrains.shared.ui.ZBContext
|
||||
import com.falsepattern.zigbrains.shared.ui.ZBModel
|
||||
import com.falsepattern.zigbrains.shared.ui.asPending
|
||||
import com.falsepattern.zigbrains.shared.withUniqueName
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.ui.NamedConfigurable
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
import com.intellij.openapi.util.io.toNioPathOrNull
|
||||
import com.intellij.util.system.OS
|
||||
import com.intellij.util.text.SemVer
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
@ -50,7 +57,7 @@ import kotlinx.coroutines.flow.flowOn
|
|||
import java.awt.Component
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.util.*
|
||||
import java.util.UUID
|
||||
import kotlin.io.path.isDirectory
|
||||
import kotlin.io.path.isExecutable
|
||||
import kotlin.io.path.isRegularFile
|
||||
|
@ -67,6 +74,10 @@ sealed interface ZLSDriver: UUIDComboBoxDriver<ZLSVersion> {
|
|||
return ZLSComboBox(model)
|
||||
}
|
||||
|
||||
override fun createNamedConfigurable(uuid: UUID, elem: ZLSVersion): NamedConfigurable<UUID> {
|
||||
return ZLSConfigurable(uuid, elem)
|
||||
}
|
||||
|
||||
override suspend fun resolvePseudo(
|
||||
context: Component,
|
||||
elem: ListElem.Pseudo<ZLSVersion>
|
||||
|
@ -89,10 +100,6 @@ sealed interface ZLSDriver: UUIDComboBoxDriver<ZLSVersion> {
|
|||
return res
|
||||
}
|
||||
|
||||
override fun createNamedConfigurable(uuid: UUID, elem: ZLSVersion): NamedConfigurable<UUID> {
|
||||
return ZLSConfigurable(uuid, elem, false)
|
||||
}
|
||||
|
||||
override val data: ZigProjectConfigurationProvider.IUserDataBridge?
|
||||
get() = null
|
||||
}
|
||||
|
@ -113,10 +120,6 @@ sealed interface ZLSDriver: UUIDComboBoxDriver<ZLSVersion> {
|
|||
res.add(suggestZLSVersions(project, data, toolchainVersion).asPending())
|
||||
return res
|
||||
}
|
||||
|
||||
override fun createNamedConfigurable(uuid: UUID, elem: ZLSVersion): NamedConfigurable<UUID> {
|
||||
return ZLSConfigurable(uuid, elem, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,16 +149,16 @@ private fun suggestZLSVersions(project: Project? = null, data: ZigProjectConfigu
|
|||
emitIfCompatible(path, toolchainVersion)
|
||||
}
|
||||
val exe = if (SystemInfo.isWindows) "zls.exe" else "zls"
|
||||
wellKnownZLS.forEach { wellKnown ->
|
||||
getWellKnownZLS().forEach { wellKnown ->
|
||||
runCatching {
|
||||
Files.newDirectoryStream(wellKnown).use { stream ->
|
||||
stream.asSequence().filterNotNull().forEach streamForEach@{ dir ->
|
||||
stream.asSequence().filterNotNull().forEach { dir ->
|
||||
val path = dir.resolve(exe)
|
||||
if (!path.isRegularFile() || !path.isExecutable()) {
|
||||
return@streamForEach
|
||||
return@forEach
|
||||
}
|
||||
if (existing.any { it.path == path }) {
|
||||
return@streamForEach
|
||||
return@forEach
|
||||
}
|
||||
emitIfCompatible(path, toolchainVersion)
|
||||
}
|
||||
|
@ -192,8 +195,8 @@ private fun numericVersionEquals(a: SemVer, b: SemVer): Boolean {
|
|||
}
|
||||
|
||||
|
||||
val suggestedZLSPath: Path? by lazy {
|
||||
wellKnownZLS.getOrNull(0)
|
||||
fun getSuggestedZLSPath(): Path? {
|
||||
return getWellKnownZLS().getOrNull(0)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -209,9 +212,17 @@ val suggestedZLSPath: Path? by lazy {
|
|||
*
|
||||
* and HOME is the user home path
|
||||
*/
|
||||
private val wellKnownZLS: List<Path> by lazy {
|
||||
private fun getWellKnownZLS(): List<Path> {
|
||||
val home = System.getProperty("user.home")?.toNioPathOrNull() ?: return emptyList()
|
||||
val xdgDataHome = when(OS.CURRENT) {
|
||||
OS.macOS -> home.resolve("Library")
|
||||
OS.Windows -> System.getenv("LOCALAPPDATA")?.toNioPathOrNull()
|
||||
else -> System.getenv("XDG_DATA_HOME")?.toNioPathOrNull() ?: home.resolve(Path.of(".local", "share"))
|
||||
}
|
||||
val res = ArrayList<Path>()
|
||||
xdgDataHome?.let { res.add(it.resolve("zls")) }
|
||||
homePath?.let { res.add(it.resolve(".zls")) }
|
||||
res
|
||||
if (xdgDataHome != null && xdgDataHome.isDirectory()) {
|
||||
res.add(xdgDataHome.resolve("zls"))
|
||||
}
|
||||
res.add(home.resolve(".zls"))
|
||||
return res
|
||||
}
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
package com.falsepattern.zigbrains.lsp.zls.ui
|
||||
|
||||
import com.falsepattern.zigbrains.lsp.ZLSStarter
|
||||
import com.falsepattern.zigbrains.lsp.startLSP
|
||||
import com.falsepattern.zigbrains.lsp.zls.ZLSVersion
|
||||
import com.falsepattern.zigbrains.lsp.zls.withZLS
|
||||
import com.falsepattern.zigbrains.lsp.zls.zlsUUID
|
||||
|
@ -55,21 +57,19 @@ class ZLSEditor<T: ZigToolchain>(private val sharedState: ZigProjectConfiguratio
|
|||
}
|
||||
}
|
||||
|
||||
override fun isModified(elem: T): Boolean {
|
||||
if (isEmpty)
|
||||
return false
|
||||
return elem.zlsUUID != selectedUUID
|
||||
override fun isModified(toolchain: T): Boolean {
|
||||
return toolchain.zlsUUID != selectedUUID
|
||||
}
|
||||
|
||||
override fun apply(elem: T): T {
|
||||
return elem.withZLS(selectedUUID)
|
||||
override fun apply(toolchain: T): T {
|
||||
return toolchain.withZLS(selectedUUID)
|
||||
}
|
||||
|
||||
override fun reset(elem: T?) {
|
||||
selectedUUID = elem?.zlsUUID
|
||||
override fun reset(toolchain: T?) {
|
||||
selectedUUID = toolchain?.zlsUUID
|
||||
zigCoroutineScope.launch {
|
||||
listChanged()
|
||||
selectedUUID = elem?.zlsUUID
|
||||
selectedUUID = toolchain?.zlsUUID
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,12 @@ package com.falsepattern.zigbrains.lsp.zls.ui
|
|||
import com.falsepattern.zigbrains.lsp.LSPIcons
|
||||
import com.falsepattern.zigbrains.lsp.ZLSBundle
|
||||
import com.falsepattern.zigbrains.lsp.zls.ZLSVersion
|
||||
import com.falsepattern.zigbrains.shared.ui.*
|
||||
import com.falsepattern.zigbrains.shared.ui.ListElem
|
||||
import com.falsepattern.zigbrains.shared.ui.ZBCellRenderer
|
||||
import com.falsepattern.zigbrains.shared.ui.ZBComboBox
|
||||
import com.falsepattern.zigbrains.shared.ui.ZBContext
|
||||
import com.falsepattern.zigbrains.shared.ui.ZBModel
|
||||
import com.falsepattern.zigbrains.shared.ui.renderPathNameComponent
|
||||
import com.intellij.icons.AllIcons
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.ui.SimpleTextAttributes
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
settings.group.title=ZLS Settings
|
||||
settings.zls-path.label=Executable path
|
||||
settings.zls-path.tooltip=Path to the ZLS Binary
|
||||
settings.zls-path.browse.title=Path to the ZLS Binary
|
||||
settings.zls-version.label=Detected ZLS version
|
||||
settings.zls-config-path.label=Config path
|
||||
settings.zls-config-path.tooltip=Leave empty to use built-in config generated from the settings below
|
||||
settings.zls-config-path.browse.title=Path to the Custom ZLS Config File (Optional)
|
||||
settings.inlay-hints-group.label=Inlay Hints
|
||||
settings.inlay-hints-enable.label=Enable
|
||||
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.tooltip=Enables snippet completions when the client also supports them
|
||||
settings.enable_argument_placeholders.label=Enable argument placeholders
|
||||
|
@ -48,6 +50,8 @@ settings.build_runner_path.tooltip=Specify a custom build runner to resolve buil
|
|||
settings.global_cache_path.label=Global cache path
|
||||
settings.global_cache_path.tooltip=Path to a directory that will be used as zig's cache. Will default to `${KnownFolders.Cache}/zls`.
|
||||
notification.group.zigbrains-lsp=ZigBrains LSP Integration
|
||||
notification.message.could-not-detect.content=Could not detect ZLS binary, please configure it
|
||||
notification.message.zls-exe-path-invalid.content=ZLS executable path could not be parsed: {0}
|
||||
notification.message.zls-exe-not-exists.content=ZLS executable does not exist: {0}
|
||||
notification.message.zls-exe-not-executable.content=ZLS executable is not an executable file: {0}
|
||||
notification.message.zls-config-not-exists.content=ZLS config file does not exist: {0}
|
||||
|
@ -57,6 +61,7 @@ notification.message.zls-config-autogen-failed.content=Failed to autogenerate ZL
|
|||
notification.banner.zls-not-running=Zig Language Server is not running. Check the [Language Servers] tool menu!
|
||||
notification.banner.zls-bad-config=Zig Language Server is misconfigured. Check [Settings | Languages \\& Frameworks | Zig]!
|
||||
progress.title.create-connection-provider=Creating ZLS connection provider
|
||||
progress.title.validate=Validating ZLS
|
||||
# suppress inspection "UnusedProperty"
|
||||
lsp.zls.name=Zig Language Server
|
||||
# suppress inspection "UnusedProperty"
|
||||
|
@ -68,15 +73,3 @@ settings.model.none.text=<No ZLS>
|
|||
settings.model.loading.text=Loading\u2026
|
||||
settings.model.from-disk.text=Add ZLS from disk\u2026
|
||||
settings.model.download.text=Download ZLS\u2026
|
||||
settings.downloader.title=Install ZLS
|
||||
settings.downloader.progress.fetch=Fetching ZLS version information
|
||||
settings.downloader.progress.install=Installing ZLS {}
|
||||
settings.downloader.service.index=ZLS version information
|
||||
settings.local-selector.title=Select ZLS from disk
|
||||
settings.local-selector.chooser.title=ZLS Binary
|
||||
settings.local-selector.state.invalid=Invalid ZLS path
|
||||
settings.local-selector.state.ok=ZLS path OK
|
||||
dialog.title.zls=Path to the ZLS Executable
|
||||
settings.panel.path.label=Path:
|
||||
settings.panel.version.label=Version:
|
||||
settings.panel.settings.group.label=Settings:
|
8
push.sh
8
push.sh
|
@ -23,6 +23,8 @@
|
|||
|
||||
set -e
|
||||
|
||||
declare -a branches=("dev" "master" "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
|
|
@ -4,7 +4,7 @@
|
|||
<vendor>FalsePattern</vendor>
|
||||
|
||||
<depends config-file="zigbrains-core.xml">com.intellij.modules.platform</depends>
|
||||
<depends config-file="zigbrains-lsp.xml">com.redhat.devtools.lsp4ij</depends>
|
||||
<depends config-file="zigbrains-lsp.xml" optional="true">com.redhat.devtools.lsp4ij</depends>
|
||||
<depends config-file="zigbrains-debugger.xml" optional="true">com.intellij.modules.cidr.debugger</depends>
|
||||
<depends config-file="zigbrains-cidr.xml" optional="true">com.intellij.cidr.base</depends>
|
||||
<depends config-file="zigbrains-clion.xml" optional="true">com.intellij.clion</depends>
|
||||
|
|
Loading…
Add table
Reference in a new issue