Compare commits
32 commits
Author | SHA1 | Date | |
---|---|---|---|
5e1f2e4bb2 | |||
ce9692ecdb | |||
c726efc858 | |||
150d85f96e | |||
3dfe8731cc | |||
f41b0f2e3d | |||
db85b56084 | |||
3954ff8ff5 | |||
06f933a69c | |||
dd9c6daae7 | |||
9176cdd439 | |||
1450dd76eb | |||
8a7a5aa1cb | |||
0ec03d6030 | |||
add259d506 | |||
c209294479 | |||
0a7d5cb4c6 | |||
b360873857 | |||
808f45bb35 | |||
456425f35a | |||
b4cb04dcde | |||
062aeaaa97 | |||
655f05c3b8 | |||
d3755fbc70 | |||
323ba12fbc | |||
808d82b44f | |||
e63ad21db7 | |||
90744797b6 | |||
24e886f13c | |||
72eaae23fa | |||
fb29d221a9 | |||
c2e20b7f0f |
37 changed files with 69 additions and 300 deletions
|
@ -152,7 +152,6 @@ Changelog structure reference:
|
||||||
|
|
||||||
- Project
|
- Project
|
||||||
- Occasional "AWT events are not allowed inside write action" error coming from LSP
|
- Occasional "AWT events are not allowed inside write action" error coming from LSP
|
||||||
- IllegalStateException coming from the standard library handler
|
|
||||||
|
|
||||||
## [22.0.0]
|
## [22.0.0]
|
||||||
|
|
||||||
|
@ -195,8 +194,6 @@ This (and newer) versions of the plugin will automatically upgrade tasks from 21
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Zig
|
|
||||||
- Changing the zig standard library path in the project settings now properly updates the dependency
|
|
||||||
- ZLS
|
- ZLS
|
||||||
- All of the config options are now exposed in the GUI
|
- All of the config options are now exposed in the GUI
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm") version "2.1.10" apply false
|
kotlin("jvm") version "1.9.22" apply false
|
||||||
kotlin("plugin.serialization") version "2.1.10" apply false
|
kotlin("plugin.serialization") version "1.9.22" apply false
|
||||||
id("org.jetbrains.intellij.platform") version "2.5.0"
|
id("org.jetbrains.intellij.platform") version "2.5.0"
|
||||||
id("org.jetbrains.changelog") version "2.2.1"
|
id("org.jetbrains.changelog") version "2.2.1"
|
||||||
id("org.jetbrains.grammarkit") version "2022.3.2.2" apply false
|
id("org.jetbrains.grammarkit") version "2022.3.2.2" apply false
|
||||||
|
@ -90,7 +90,6 @@ allprojects {
|
||||||
|
|
||||||
intellijPlatform {
|
intellijPlatform {
|
||||||
defaultRepositories()
|
defaultRepositories()
|
||||||
snapshots()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,8 +58,7 @@ class ZigClionDebuggerDriverConfigurationProvider: ZigDebuggerDriverConfiguratio
|
||||||
return when(toolchain.debuggerKind) {
|
return when(toolchain.debuggerKind) {
|
||||||
CPPDebugger.Kind.BUNDLED_GDB,
|
CPPDebugger.Kind.BUNDLED_GDB,
|
||||||
CPPDebugger.Kind.CUSTOM_GDB -> CLionGDBDriverConfiguration(project, toolchain, isEmulateTerminal = emulateTerminal)
|
CPPDebugger.Kind.CUSTOM_GDB -> CLionGDBDriverConfiguration(project, toolchain, isEmulateTerminal = emulateTerminal)
|
||||||
CPPDebugger.Kind.BUNDLED_LLDB,
|
CPPDebugger.Kind.BUNDLED_LLDB -> CLionLLDBDriverConfiguration(project, toolchain, isEmulateTerminal = emulateTerminal)
|
||||||
CPPDebugger.Kind.CUSTOM_LLDB -> CLionLLDBDriverConfiguration(project, toolchain, isEmulateTerminal = emulateTerminal)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,7 +211,7 @@ abstract class DAPDriver<Server : IDebugProtocolServer, Client : IDebugProtocolC
|
||||||
val cli = installer.install()
|
val cli = installer.install()
|
||||||
val args = HashMap<String, Any>()
|
val args = HashMap<String, Any>()
|
||||||
args["program"] = Util.toWinPath(cli.exePath)
|
args["program"] = Util.toWinPath(cli.exePath)
|
||||||
args["cmd"] = cli.workingDirectory.toString()
|
args["cmd"] = cli.workDirectory.toString()
|
||||||
args["name"] = "CPP Debug"
|
args["name"] = "CPP Debug"
|
||||||
args["type"] = "cppvsdbg"
|
args["type"] = "cppvsdbg"
|
||||||
args["request"] = "launch"
|
args["request"] = "launch"
|
||||||
|
@ -954,7 +954,7 @@ abstract class DAPDriver<Server : IDebugProtocolServer, Client : IDebugProtocolC
|
||||||
cli.withCharset(Charsets.UTF_8)
|
cli.withCharset(Charsets.UTF_8)
|
||||||
val cwd = args.cwd?.ifBlank { null }?.toNioPathOrNull()
|
val cwd = args.cwd?.ifBlank { null }?.toNioPathOrNull()
|
||||||
if (cwd != null) {
|
if (cwd != null) {
|
||||||
cli.withWorkingDirectory(cwd)
|
cli.withWorkDirectory(cwd.toFile())
|
||||||
}
|
}
|
||||||
val childProcess = ZigProcessHandler(cli)
|
val childProcess = ZigProcessHandler(cli)
|
||||||
this@DAPDriver.childProcess = childProcess
|
this@DAPDriver.childProcess = childProcess
|
||||||
|
|
|
@ -34,7 +34,7 @@ class ZigProfileStateBinary(environment: ExecutionEnvironment, configuration: Zi
|
||||||
override suspend fun getCommandLine(toolchain: ZigToolchain, debug: Boolean): GeneralCommandLine {
|
override suspend fun getCommandLine(toolchain: ZigToolchain, debug: Boolean): GeneralCommandLine {
|
||||||
val cli = GeneralCommandLine()
|
val cli = GeneralCommandLine()
|
||||||
val cfg = configuration
|
val cfg = configuration
|
||||||
cfg.workingDirectory.path?.let { cli.withWorkingDirectory(it) }
|
cfg.workingDirectory.path?.let { cli.withWorkDirectory(it.toFile()) }
|
||||||
cli.withExePath(cfg.exePath.path?.pathString ?: throw ExecutionException(ZigDebugBundle.message("exception.missing-exe-path")))
|
cli.withExePath(cfg.exePath.path?.pathString ?: throw ExecutionException(ZigDebugBundle.message("exception.missing-exe-path")))
|
||||||
cli.withCharset(Charsets.UTF_8)
|
cli.withCharset(Charsets.UTF_8)
|
||||||
cli.addParameters(cfg.args.args)
|
cli.addParameters(cfg.args.args)
|
||||||
|
|
|
@ -41,7 +41,7 @@ class ZigDebugEmitBinaryInstaller<ProfileState: ZigProfileState<*>>(
|
||||||
override fun install(): GeneralCommandLine {
|
override fun install(): GeneralCommandLine {
|
||||||
val cfg = profileState.configuration
|
val cfg = profileState.configuration
|
||||||
val cli = PtyCommandLine().withConsoleMode(false).withExePath(executableFile.absolutePath)
|
val cli = PtyCommandLine().withConsoleMode(false).withExePath(executableFile.absolutePath)
|
||||||
cfg.workingDirectory.path?.let { x -> cli.withWorkingDirectory(x) }
|
cfg.workingDirectory.path?.let { x -> cli.withWorkDirectory(x.toFile()) }
|
||||||
cli.addParameters(exeArgs)
|
cli.addParameters(exeArgs)
|
||||||
cli.withCharset(Charsets.UTF_8)
|
cli.withCharset(Charsets.UTF_8)
|
||||||
cli.withRedirectErrorStream(true)
|
cli.withRedirectErrorStream(true)
|
||||||
|
|
|
@ -29,7 +29,6 @@ import com.intellij.openapi.options.SimpleConfigurable
|
||||||
import com.intellij.util.xmlb.XmlSerializerUtil
|
import com.intellij.util.xmlb.XmlSerializerUtil
|
||||||
import com.intellij.xdebugger.settings.DebuggerSettingsCategory
|
import com.intellij.xdebugger.settings.DebuggerSettingsCategory
|
||||||
import com.intellij.xdebugger.settings.XDebuggerSettings
|
import com.intellij.xdebugger.settings.XDebuggerSettings
|
||||||
import java.util.function.Supplier
|
|
||||||
|
|
||||||
class ZigDebuggerSettings: XDebuggerSettings<ZigDebuggerSettings>("Zig") {
|
class ZigDebuggerSettings: XDebuggerSettings<ZigDebuggerSettings>("Zig") {
|
||||||
var debuggerKind = DebuggerKind.default
|
var debuggerKind = DebuggerKind.default
|
||||||
|
@ -59,10 +58,9 @@ class ZigDebuggerSettings: XDebuggerSettings<ZigDebuggerSettings>("Zig") {
|
||||||
GENERAL_SETTINGS_ID,
|
GENERAL_SETTINGS_ID,
|
||||||
ZigDebugBundle.message("settings.debugger.title"),
|
ZigDebugBundle.message("settings.debugger.title"),
|
||||||
ZigDebuggerGeneralSettingsConfigurableUi::class.java,
|
ZigDebuggerGeneralSettingsConfigurableUi::class.java,
|
||||||
Supplier {
|
) {
|
||||||
instance
|
instance
|
||||||
}
|
}
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
@ -29,12 +29,12 @@ import com.falsepattern.zigbrains.debugger.toolchain.ZigDebuggerToolchainService
|
||||||
import com.falsepattern.zigbrains.shared.coroutine.withCurrentEDTModalityContext
|
import com.falsepattern.zigbrains.shared.coroutine.withCurrentEDTModalityContext
|
||||||
import com.intellij.notification.Notification
|
import com.intellij.notification.Notification
|
||||||
import com.intellij.notification.NotificationType
|
import com.intellij.notification.NotificationType
|
||||||
import com.intellij.openapi.progress.coroutineToIndicator
|
|
||||||
import com.intellij.openapi.ui.DialogBuilder
|
import com.intellij.openapi.ui.DialogBuilder
|
||||||
import com.intellij.platform.util.progress.withProgressText
|
import com.intellij.platform.util.progress.withProgressText
|
||||||
import com.intellij.ui.components.JBLabel
|
import com.intellij.ui.components.JBLabel
|
||||||
import com.intellij.ui.components.JBPanel
|
import com.intellij.ui.components.JBPanel
|
||||||
import com.intellij.util.download.DownloadableFileService
|
import com.intellij.util.download.DownloadableFileService
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.sync.withLock
|
||||||
import kotlinx.coroutines.withTimeoutOrNull
|
import kotlinx.coroutines.withTimeoutOrNull
|
||||||
|
@ -96,7 +96,7 @@ private suspend fun downloadMSVCProps(): Properties {
|
||||||
val downloader = service.createDownloader(listOf(desc), "Debugger metadata downloading")
|
val downloader = service.createDownloader(listOf(desc), "Debugger metadata downloading")
|
||||||
val downloadDirectory = downloadPath().toFile()
|
val downloadDirectory = downloadPath().toFile()
|
||||||
val prop = Properties()
|
val prop = Properties()
|
||||||
val downloadResults = coroutineToIndicator {
|
val downloadResults = runBlocking {
|
||||||
downloader.download(downloadDirectory)
|
downloader.download(downloadDirectory)
|
||||||
}
|
}
|
||||||
for (result in downloadResults) {
|
for (result in downloadResults) {
|
||||||
|
|
|
@ -30,7 +30,7 @@ import com.intellij.openapi.application.PathManager
|
||||||
import com.intellij.openapi.components.Service
|
import com.intellij.openapi.components.Service
|
||||||
import com.intellij.openapi.components.service
|
import com.intellij.openapi.components.service
|
||||||
import com.intellij.openapi.diagnostic.logger
|
import com.intellij.openapi.diagnostic.logger
|
||||||
import com.intellij.openapi.progress.coroutineToIndicator
|
import com.intellij.openapi.progress.blockingContext
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.ui.DialogBuilder
|
import com.intellij.openapi.ui.DialogBuilder
|
||||||
import com.intellij.openapi.util.SystemInfo
|
import com.intellij.openapi.util.SystemInfo
|
||||||
|
@ -222,7 +222,7 @@ class ZigDebuggerToolchainService {
|
||||||
val downloader = service.createDownloader(descriptions, "Debugger downloading")
|
val downloader = service.createDownloader(descriptions, "Debugger downloading")
|
||||||
val downloadDirectory = downloadPath().toFile()
|
val downloadDirectory = downloadPath().toFile()
|
||||||
val downloadResults = reporter.sizedStep(100) {
|
val downloadResults = reporter.sizedStep(100) {
|
||||||
coroutineToIndicator {
|
blockingContext {
|
||||||
downloader.download(downloadDirectory)
|
downloader.download(downloadDirectory)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -233,7 +233,7 @@ class ZigDebuggerToolchainService {
|
||||||
val propertyName = binaryToDownload.propertyName
|
val propertyName = binaryToDownload.propertyName
|
||||||
val archiveFile = result.first
|
val archiveFile = result.first
|
||||||
reporter.indeterminateStep {
|
reporter.indeterminateStep {
|
||||||
coroutineToIndicator {
|
blockingContext {
|
||||||
Unarchiver.unarchive(archiveFile.toPath(), baseDir, binaryToDownload.prefix)
|
Unarchiver.unarchive(archiveFile.toPath(), baseDir, binaryToDownload.prefix)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ abstract class MSVCDriverConfiguration: DAPDebuggerDriverConfiguration() {
|
||||||
val cli = GeneralCommandLine()
|
val cli = GeneralCommandLine()
|
||||||
cli.withExePath(path.pathString)
|
cli.withExePath(path.pathString)
|
||||||
cli.addParameters("--interpreter=vscode", "--extconfigdir=%USERPROFILE%\\.cppvsdbg\\extensions")
|
cli.addParameters("--interpreter=vscode", "--extconfigdir=%USERPROFILE%\\.cppvsdbg\\extensions")
|
||||||
cli.withWorkingDirectory(path.parent)
|
cli.withWorkDirectory(path.parent.toFile())
|
||||||
return cli
|
return cli
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ class DirenvService(val project: Project): SerializablePersistentStateComponent<
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun run(workDir: Path, vararg args: String): DirenvOutput {
|
private suspend fun run(workDir: Path, vararg args: String): DirenvOutput {
|
||||||
val cli = GeneralCommandLine("direnv", *args).withWorkingDirectory(workDir)
|
val cli = GeneralCommandLine("direnv", *args).withWorkDirectory(workDir.toFile())
|
||||||
|
|
||||||
val (process, exitCode) = withProgressText("Running ${cli.commandLineString}") {
|
val (process, exitCode) = withProgressText("Running ${cli.commandLineString}") {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
|
|
|
@ -160,6 +160,7 @@ class WorkDirectoryConfigurable(@Transient override val serializedName: String)
|
||||||
class WorkDirectoryConfigModule(private val serializedName: String) : PathConfigModule<WorkDirectoryConfigurable>() {
|
class WorkDirectoryConfigModule(private val serializedName: String) : PathConfigModule<WorkDirectoryConfigurable>() {
|
||||||
private val field = textFieldWithBrowseButton(
|
private val field = textFieldWithBrowseButton(
|
||||||
null,
|
null,
|
||||||
|
ZigBrainsBundle.message("dialog.title.working-directory"),
|
||||||
FileChooserDescriptorFactory.createSingleFolderDescriptor().withTitle(ZigBrainsBundle.message("dialog.title.working-directory"))
|
FileChooserDescriptorFactory.createSingleFolderDescriptor().withTitle(ZigBrainsBundle.message("dialog.title.working-directory"))
|
||||||
).also { Disposer.register(this, it) }
|
).also { Disposer.register(this, it) }
|
||||||
|
|
||||||
|
@ -198,7 +199,8 @@ class FilePathConfigurable(
|
||||||
class FilePathConfigModule(private val serializedName: String, @Nls private val label: String) : PathConfigModule<FilePathConfigurable>() {
|
class FilePathConfigModule(private val serializedName: String, @Nls private val label: String) : PathConfigModule<FilePathConfigurable>() {
|
||||||
private val field = textFieldWithBrowseButton(
|
private val field = textFieldWithBrowseButton(
|
||||||
null,
|
null,
|
||||||
FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor(),
|
null,
|
||||||
|
FileChooserDescriptorFactory.createSingleFileDescriptor(),
|
||||||
)
|
)
|
||||||
|
|
||||||
override var stringValue by field::text
|
override var stringValue by field::text
|
||||||
|
|
|
@ -66,7 +66,7 @@ abstract class ZigProfileState<T: ZigExecConfig<T>> (
|
||||||
|
|
||||||
val cli = PtyCommandLine().withConsoleMode(false)
|
val cli = PtyCommandLine().withConsoleMode(false)
|
||||||
cli.withExePath(zigExePath.pathString)
|
cli.withExePath(zigExePath.pathString)
|
||||||
workingDir.path?.let { cli.withWorkingDirectory(it) }
|
workingDir.path?.let { cli.withWorkDirectory(it.toFile()) }
|
||||||
cli.withCharset(Charsets.UTF_8)
|
cli.withCharset(Charsets.UTF_8)
|
||||||
cli.addParameters(configuration.buildCommandLineArgs(debug))
|
cli.addParameters(configuration.buildCommandLineArgs(debug))
|
||||||
return configuration.patchCommandLine(cli)
|
return configuration.patchCommandLine(cli)
|
||||||
|
|
|
@ -68,7 +68,7 @@ class ZigModuleBuilder: ModuleBuilder() {
|
||||||
internal val peer = ZigProjectGeneratorPeer(true).also { Disposer.register(parent ?: return@also) {it.dispose()} }
|
internal val peer = ZigProjectGeneratorPeer(true).also { Disposer.register(parent ?: return@also) {it.dispose()} }
|
||||||
|
|
||||||
override fun getComponent(): JComponent {
|
override fun getComponent(): JComponent {
|
||||||
return peer.myComponent.withBorder()
|
return peer.component.withBorder()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun disposeUIResources() {
|
override fun disposeUIResources() {
|
||||||
|
|
|
@ -50,7 +50,7 @@ class ZigNewProjectWizard: LanguageGeneratorNewProjectWizard {
|
||||||
|
|
||||||
override fun setupUI(builder: Panel): Unit = with(builder) {
|
override fun setupUI(builder: Panel): Unit = with(builder) {
|
||||||
row {
|
row {
|
||||||
cell(peer.myComponent).align(AlignX.FILL)
|
cell(peer.component).align(AlignX.FILL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
package com.falsepattern.zigbrains.project.newproject
|
package com.falsepattern.zigbrains.project.newproject
|
||||||
|
|
||||||
import com.intellij.ide.util.projectWizard.SettingsStep
|
import com.intellij.ide.util.projectWizard.SettingsStep
|
||||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton
|
|
||||||
import com.intellij.openapi.ui.ValidationInfo
|
import com.intellij.openapi.ui.ValidationInfo
|
||||||
import com.intellij.platform.ProjectGeneratorPeer
|
import com.intellij.platform.ProjectGeneratorPeer
|
||||||
import com.intellij.ui.dsl.builder.panel
|
import com.intellij.ui.dsl.builder.panel
|
||||||
|
@ -33,13 +32,12 @@ class ZigProjectGeneratorPeer(var handleGit: Boolean): ProjectGeneratorPeer<ZigP
|
||||||
val newProjectPanel by lazy {
|
val newProjectPanel by lazy {
|
||||||
ZigNewProjectPanel(handleGit)
|
ZigNewProjectPanel(handleGit)
|
||||||
}
|
}
|
||||||
val myComponent: JComponent by lazy {
|
private val myComponent: JComponent by lazy {
|
||||||
panel {
|
panel {
|
||||||
newProjectPanel.attach(this)
|
newProjectPanel.attach(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
override fun getComponent(): JComponent {
|
||||||
override fun getComponent(myLocationField: TextFieldWithBrowseButton, checkValid: Runnable): JComponent {
|
|
||||||
return myComponent
|
return myComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,33 +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.stdlib
|
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.openapi.roots.AdditionalLibraryRootsProvider
|
|
||||||
import com.intellij.openapi.roots.SyntheticLibrary
|
|
||||||
|
|
||||||
class ZigLibraryRootProvider: AdditionalLibraryRootsProvider() {
|
|
||||||
override fun getAdditionalProjectLibraries(project: Project): Collection<SyntheticLibrary> {
|
|
||||||
return setOf(ZigSyntheticLibrary(project))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,190 +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.stdlib
|
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.Icons
|
|
||||||
import com.falsepattern.zigbrains.project.toolchain.ZigToolchainService
|
|
||||||
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
|
||||||
import com.falsepattern.zigbrains.project.toolchain.local.LocalZigToolchain
|
|
||||||
import com.intellij.navigation.ItemPresentation
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.openapi.project.guessProjectDir
|
|
||||||
import com.intellij.openapi.roots.SyntheticLibrary
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
|
||||||
import com.intellij.openapi.vfs.refreshAndFindVirtualDirectory
|
|
||||||
import com.intellij.platform.backend.workspace.WorkspaceModel
|
|
||||||
import com.intellij.platform.backend.workspace.toVirtualFileUrl
|
|
||||||
import com.intellij.platform.workspace.jps.entities.*
|
|
||||||
import com.intellij.project.isDirectoryBased
|
|
||||||
import com.intellij.project.stateStore
|
|
||||||
import com.intellij.workspaceModel.ide.legacyBridge.LegacyBridgeJpsEntitySourceFactory
|
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
import java.util.*
|
|
||||||
import javax.swing.Icon
|
|
||||||
|
|
||||||
class ZigSyntheticLibrary(val project: Project) : SyntheticLibrary(), ItemPresentation {
|
|
||||||
private var toolchain: ZigToolchain? = ZigToolchainService.getInstance(project).toolchain
|
|
||||||
private val roots by lazy {
|
|
||||||
runBlocking {getRoot(toolchain, project)}?.let { setOf(it) } ?: emptySet()
|
|
||||||
}
|
|
||||||
|
|
||||||
private val name by lazy {
|
|
||||||
getName(toolchain, project)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
|
||||||
if (other !is ZigSyntheticLibrary)
|
|
||||||
return false
|
|
||||||
|
|
||||||
return toolchain == other.toolchain
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
|
||||||
return Objects.hash(roots)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getPresentableText(): String {
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getIcon(unused: Boolean): Icon {
|
|
||||||
return Icons.Zig
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getSourceRoots(): Collection<VirtualFile> {
|
|
||||||
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 workspaceModel = WorkspaceModel.getInstance(project)
|
|
||||||
val libRoot = LibraryRoot(root.toVirtualFileUrl(workspaceModel.getVirtualFileUrlManager()), LibraryRootTypeId.SOURCES)
|
|
||||||
|
|
||||||
var baseModuleDirFile: VirtualFile? = null
|
|
||||||
if (project.isDirectoryBased) {
|
|
||||||
baseModuleDirFile = project.stateStore.directoryStorePath?.refreshAndFindVirtualDirectory()
|
|
||||||
}
|
|
||||||
if (baseModuleDirFile == null) {
|
|
||||||
baseModuleDirFile = project.guessProjectDir()
|
|
||||||
}
|
|
||||||
val baseModuleDir = baseModuleDirFile?.toVirtualFileUrl(workspaceModel.getVirtualFileUrlManager()) ?: return
|
|
||||||
workspaceModel.update("Update Zig std") { builder ->
|
|
||||||
builder.resolve(moduleId)?.let { moduleEntity ->
|
|
||||||
builder.removeEntity(moduleEntity)
|
|
||||||
}
|
|
||||||
val moduleEntitySource = LegacyBridgeJpsEntitySourceFactory.getInstance(project)
|
|
||||||
.createEntitySourceForModule(baseModuleDir, null)
|
|
||||||
|
|
||||||
val moduleEntity = builder.addEntity(ModuleEntity(ZIG_MODULE_ID, emptyList(), moduleEntitySource))
|
|
||||||
|
|
||||||
builder.resolve(libraryId)?.let { libraryEntity ->
|
|
||||||
builder.removeEntity(libraryEntity)
|
|
||||||
}
|
|
||||||
val libraryEntitySource = LegacyBridgeJpsEntitySourceFactory
|
|
||||||
.getInstance(project)
|
|
||||||
.createEntitySourceForProjectLibrary(null)
|
|
||||||
val libraryEntity = LibraryEntity(
|
|
||||||
ZIG_LIBRARY_ID,
|
|
||||||
libraryTableId, emptyList(),
|
|
||||||
libraryEntitySource
|
|
||||||
) {
|
|
||||||
roots.add(libRoot)
|
|
||||||
}
|
|
||||||
builder.addEntity(libraryEntity)
|
|
||||||
builder.modifyModuleEntity(moduleEntity) {
|
|
||||||
val dep = LibraryDependency(libraryId, false, DependencyScope.COMPILE)
|
|
||||||
dependencies.clear()
|
|
||||||
dependencies.add(dep)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getName(
|
|
||||||
toolchain: ZigToolchain?,
|
|
||||||
project: Project
|
|
||||||
): String {
|
|
||||||
val tc = toolchain ?: return "Zig"
|
|
||||||
toolchain.name?.let { return it }
|
|
||||||
runBlocking { tc.zig.getEnv(project) }
|
|
||||||
.mapCatching { it.version }
|
|
||||||
.getOrNull()
|
|
||||||
?.let { return "Zig $it" }
|
|
||||||
return "Zig"
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun getRoot(
|
|
||||||
toolchain: ZigToolchain?,
|
|
||||||
project: Project
|
|
||||||
): VirtualFile? {
|
|
||||||
//TODO universal
|
|
||||||
if (toolchain !is LocalZigToolchain) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
if (toolchain.std != null) run {
|
|
||||||
val ePath = toolchain.std
|
|
||||||
if (ePath.isAbsolute) {
|
|
||||||
val roots = ePath.refreshAndFindVirtualDirectory() ?: return@run
|
|
||||||
return roots
|
|
||||||
}
|
|
||||||
val stdPath = toolchain.location.resolve(ePath)
|
|
||||||
if (stdPath.isAbsolute) {
|
|
||||||
val roots = stdPath.refreshAndFindVirtualDirectory() ?: return@run
|
|
||||||
return roots
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val stdPath = toolchain.zig.getEnv(project).mapCatching { it.stdPath(toolchain, project) }.getOrNull() ?: return null
|
|
||||||
val roots = stdPath.refreshAndFindVirtualDirectory() ?: return null
|
|
||||||
return roots
|
|
||||||
}
|
|
|
@ -22,16 +22,11 @@
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.project.toolchain
|
package com.falsepattern.zigbrains.project.toolchain
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.project.stdlib.ZigSyntheticLibrary
|
|
||||||
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||||
import com.falsepattern.zigbrains.shared.asUUID
|
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.*
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.util.xmlb.annotations.Attribute
|
import com.intellij.util.xmlb.annotations.Attribute
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@Service(Service.Level.PROJECT)
|
@Service(Service.Level.PROJECT)
|
||||||
|
@ -55,9 +50,6 @@ class ZigToolchainService(private val project: Project): SerializablePersistentS
|
||||||
updateState {
|
updateState {
|
||||||
it.copy(toolchain = value?.toString() ?: "")
|
it.copy(toolchain = value?.toString() ?: "")
|
||||||
}
|
}
|
||||||
zigCoroutineScope.launch(Dispatchers.EDT) {
|
|
||||||
ZigSyntheticLibrary.reload(project, toolchain)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val toolchain: ZigToolchain?
|
val toolchain: ZigToolchain?
|
||||||
|
|
|
@ -56,7 +56,7 @@ class LocalToolchainSelector(component: Component): LocalSelector<LocalZigToolch
|
||||||
} else {
|
} else {
|
||||||
val existingToolchain = zigToolchainList
|
val existingToolchain = zigToolchainList
|
||||||
.mapNotNull { it.second as? LocalZigToolchain }
|
.mapNotNull { it.second as? LocalZigToolchain }
|
||||||
.firstOrNull { it.location == tc.location }
|
.firstOrNull { it.location == tc!!.location }
|
||||||
if (existingToolchain != null) {
|
if (existingToolchain != null) {
|
||||||
result = VerifyResult(
|
result = VerifyResult(
|
||||||
null,
|
null,
|
||||||
|
|
|
@ -27,7 +27,7 @@ import com.falsepattern.zigbrains.shared.downloader.VersionInfo
|
||||||
import com.falsepattern.zigbrains.shared.downloader.VersionInfo.Tarball
|
import com.falsepattern.zigbrains.shared.downloader.VersionInfo.Tarball
|
||||||
import com.falsepattern.zigbrains.shared.downloader.getTarballIfCompatible
|
import com.falsepattern.zigbrains.shared.downloader.getTarballIfCompatible
|
||||||
import com.falsepattern.zigbrains.shared.downloader.tempPluginDir
|
import com.falsepattern.zigbrains.shared.downloader.tempPluginDir
|
||||||
import com.intellij.openapi.progress.coroutineToIndicator
|
import com.intellij.openapi.progress.blockingContext
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
import com.intellij.util.asSafely
|
import com.intellij.util.asSafely
|
||||||
import com.intellij.util.download.DownloadableFileService
|
import com.intellij.util.download.DownloadableFileService
|
||||||
|
@ -54,7 +54,7 @@ data class ZigVersionInfo(
|
||||||
val tempFile = FileUtil.createTempFile(tempPluginDir, "index", ".json", false, false)
|
val tempFile = FileUtil.createTempFile(tempPluginDir, "index", ".json", false, false)
|
||||||
val desc = service.createFileDescription("https://ziglang.org/download/index.json", tempFile.name)
|
val desc = service.createFileDescription("https://ziglang.org/download/index.json", tempFile.name)
|
||||||
val downloader = service.createDownloader(listOf(desc), ZigBrainsBundle.message("settings.toolchain.downloader.service.index"))
|
val downloader = service.createDownloader(listOf(desc), ZigBrainsBundle.message("settings.toolchain.downloader.service.index"))
|
||||||
val downloadResults = coroutineToIndicator {
|
val downloadResults = blockingContext {
|
||||||
downloader.download(tempPluginDir)
|
downloader.download(tempPluginDir)
|
||||||
}
|
}
|
||||||
if (downloadResults.isEmpty())
|
if (downloadResults.isEmpty())
|
||||||
|
|
|
@ -47,7 +47,8 @@ import kotlin.io.path.pathString
|
||||||
class LocalZigToolchainPanel() : ImmutableNamedElementPanelBase<LocalZigToolchain>() {
|
class LocalZigToolchainPanel() : ImmutableNamedElementPanelBase<LocalZigToolchain>() {
|
||||||
private val pathToToolchain = textFieldWithBrowseButton(
|
private val pathToToolchain = textFieldWithBrowseButton(
|
||||||
null,
|
null,
|
||||||
FileChooserDescriptorFactory.createSingleFolderDescriptor().withTitle(ZigBrainsBundle.message("dialog.title.zig-toolchain"))
|
ZigBrainsBundle.message("dialog.title.zig-toolchain"),
|
||||||
|
FileChooserDescriptorFactory.createSingleFolderDescriptor()
|
||||||
).also {
|
).also {
|
||||||
it.textField.document.addDocumentListener(object : DocumentAdapter() {
|
it.textField.document.addDocumentListener(object : DocumentAdapter() {
|
||||||
override fun textChanged(e: DocumentEvent) {
|
override fun textChanged(e: DocumentEvent) {
|
||||||
|
@ -69,7 +70,8 @@ class LocalZigToolchainPanel() : ImmutableNamedElementPanelBase<LocalZigToolchai
|
||||||
}
|
}
|
||||||
private val pathToStd = textFieldWithBrowseButton(
|
private val pathToStd = textFieldWithBrowseButton(
|
||||||
null,
|
null,
|
||||||
FileChooserDescriptorFactory.createSingleFolderDescriptor().withTitle(ZigBrainsBundle.message("dialog.title.zig-std"))
|
ZigBrainsBundle.message("dialog.title.zig-std"),
|
||||||
|
FileChooserDescriptorFactory.createSingleFolderDescriptor()
|
||||||
).also { Disposer.register(this, it) }
|
).also { Disposer.register(this, it) }
|
||||||
private var debounce: Job? = null
|
private var debounce: Job? = null
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ import com.intellij.icons.AllIcons
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.ui.SimpleTextAttributes
|
import com.intellij.ui.SimpleTextAttributes
|
||||||
import com.intellij.ui.icons.EMPTY_ICON
|
import com.intellij.ui.icons.EMPTY_ICON
|
||||||
|
import com.intellij.util.ui.EmptyIcon
|
||||||
import javax.swing.JList
|
import javax.swing.JList
|
||||||
|
|
||||||
class TCComboBox(model: ZBModel<ZigToolchain>): ZBComboBox<ZigToolchain>(model, ::TCCellRenderer)
|
class TCComboBox(model: ZBModel<ZigToolchain>): ZBComboBox<ZigToolchain>(model, ::TCCellRenderer)
|
||||||
|
@ -67,7 +68,7 @@ class TCCellRenderer(getModel: () -> ZBModel<ZigToolchain>): ZBCellRenderer<ZigT
|
||||||
append(ZigBrainsBundle.message("settings.toolchain.model.from-disk.text"))
|
append(ZigBrainsBundle.message("settings.toolchain.model.from-disk.text"))
|
||||||
}
|
}
|
||||||
is ListElem.Pending -> {
|
is ListElem.Pending -> {
|
||||||
icon = AllIcons.Empty
|
icon = EMPTY_ICON
|
||||||
append(ZigBrainsBundle.message("settings.toolchain.model.loading.text"), SimpleTextAttributes.GRAYED_ATTRIBUTES)
|
append(ZigBrainsBundle.message("settings.toolchain.model.loading.text"), SimpleTextAttributes.GRAYED_ATTRIBUTES)
|
||||||
}
|
}
|
||||||
is ListElem.None, null -> {
|
is ListElem.None, null -> {
|
||||||
|
@ -77,4 +78,5 @@ class TCCellRenderer(getModel: () -> ZBModel<ZigToolchain>): ZBCellRenderer<ZigT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
private val EMPTY_ICON = EmptyIcon.create(16, 16)
|
|
@ -123,7 +123,7 @@ fun createCommandLineSafe(
|
||||||
return Result.failure(IllegalArgumentException("file is a directory: ${exe.pathString}"))
|
return Result.failure(IllegalArgumentException("file is a directory: ${exe.pathString}"))
|
||||||
val cli = GeneralCommandLine()
|
val cli = GeneralCommandLine()
|
||||||
.withExePath(exe.toString())
|
.withExePath(exe.toString())
|
||||||
.withWorkingDirectory(workingDirectory)
|
.withWorkDirectory(workingDirectory?.toFile())
|
||||||
.withParameters(*parameters)
|
.withParameters(*parameters)
|
||||||
.withCharset(Charsets.UTF_8)
|
.withCharset(Charsets.UTF_8)
|
||||||
return Result.success(cli)
|
return Result.success(cli)
|
||||||
|
|
|
@ -33,7 +33,7 @@ import kotlinx.coroutines.*
|
||||||
import java.awt.Component
|
import java.awt.Component
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
inline fun <T> runModalOrBlocking(taskOwnerFactory: () -> ModalTaskOwner, titleFactory: () -> String, cancellationFactory: () -> TaskCancellation = {TaskCancellation.cancellable()}, noinline action: suspend CoroutineScope.() -> T): T {
|
inline fun <T> runModalOrBlocking(taskOwnerFactory: () -> ModalTaskOwner, titleFactory: () -> String, cancellationFactory: () -> TaskCancellation = TaskCancellation::cancellable, noinline action: suspend CoroutineScope.() -> T): T {
|
||||||
return if (application.isDispatchThread) {
|
return if (application.isDispatchThread) {
|
||||||
runWithModalProgressBlocking(taskOwnerFactory(), titleFactory(), cancellationFactory(), action)
|
runWithModalProgressBlocking(taskOwnerFactory(), titleFactory(), cancellationFactory(), action)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -96,7 +96,7 @@ abstract class Downloader<T, V: VersionInfo>(val component: Component) {
|
||||||
value?.let { append(it.version.rawVersion) }
|
value?.let { append(it.version.rawVersion) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val outputPath = textFieldWithBrowseButton(null, selector.descriptor)
|
val outputPath = textFieldWithBrowseButton(null, selector.descriptor.title, selector.descriptor)
|
||||||
Disposer.register(dialog, outputPath)
|
Disposer.register(dialog, outputPath)
|
||||||
outputPath.textField.columns = 50
|
outputPath.textField.columns = 50
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ abstract class LocalSelector<T>(val component: Component) {
|
||||||
private suspend fun doBrowseFromDisk(preSelected: Path?): T? {
|
private suspend fun doBrowseFromDisk(preSelected: Path?): T? {
|
||||||
val dialog = DialogBuilder()
|
val dialog = DialogBuilder()
|
||||||
val name = JBTextField().also { it.columns = 25 }
|
val name = JBTextField().also { it.columns = 25 }
|
||||||
val path = textFieldWithBrowseButton(null, descriptor)
|
val path = textFieldWithBrowseButton(null, descriptor.title, descriptor)
|
||||||
Disposer.register(dialog, path)
|
Disposer.register(dialog, path)
|
||||||
lateinit var errorMessageBox: JBLabel
|
lateinit var errorMessageBox: JBLabel
|
||||||
suspend fun verifyAndUpdate(path: Path?) {
|
suspend fun verifyAndUpdate(path: Path?) {
|
||||||
|
|
|
@ -28,7 +28,7 @@ import com.falsepattern.zigbrains.shared.downloader.VersionInfo.Tarball
|
||||||
import com.intellij.openapi.application.PathManager
|
import com.intellij.openapi.application.PathManager
|
||||||
import com.intellij.openapi.progress.EmptyProgressIndicator
|
import com.intellij.openapi.progress.EmptyProgressIndicator
|
||||||
import com.intellij.openapi.progress.ProgressManager
|
import com.intellij.openapi.progress.ProgressManager
|
||||||
import com.intellij.openapi.progress.coroutineToIndicator
|
import com.intellij.openapi.progress.blockingContext
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
import com.intellij.openapi.util.io.toNioPathOrNull
|
import com.intellij.openapi.util.io.toNioPathOrNull
|
||||||
import com.intellij.platform.util.progress.ProgressReporter
|
import com.intellij.platform.util.progress.ProgressReporter
|
||||||
|
@ -83,7 +83,7 @@ suspend fun downloadTarball(dist: Tarball, into: Path, reporter: ProgressReporte
|
||||||
val desc = service.createFileDescription(dist.tarball, tempFile.name)
|
val desc = service.createFileDescription(dist.tarball, tempFile.name)
|
||||||
val downloader = service.createDownloader(listOf(desc), ZigBrainsBundle.message("settings.toolchain.downloader.service.tarball"))
|
val downloader = service.createDownloader(listOf(desc), ZigBrainsBundle.message("settings.toolchain.downloader.service.tarball"))
|
||||||
val downloadResults = reporter.sizedStep(100) {
|
val downloadResults = reporter.sizedStep(100) {
|
||||||
coroutineToIndicator {
|
blockingContext {
|
||||||
downloader.download(into.toFile())
|
downloader.download(into.toFile())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ suspend fun flattenDownloadDir(dir: Path, reporter: ProgressReporter) {
|
||||||
if (contents.size == 1 && contents[0].isDirectory()) {
|
if (contents.size == 1 && contents[0].isDirectory()) {
|
||||||
val src = contents[0]
|
val src = contents[0]
|
||||||
reporter.indeterminateStep {
|
reporter.indeterminateStep {
|
||||||
coroutineToIndicator {
|
blockingContext {
|
||||||
val indicator = ProgressManager.getInstance().progressIndicator ?: EmptyProgressIndicator()
|
val indicator = ProgressManager.getInstance().progressIndicator ?: EmptyProgressIndicator()
|
||||||
indicator.isIndeterminate = true
|
indicator.isIndeterminate = true
|
||||||
indicator.text = ZigBrainsBundle.message("settings.toolchain.downloader.progress.flatten")
|
indicator.text = ZigBrainsBundle.message("settings.toolchain.downloader.progress.flatten")
|
||||||
|
@ -121,7 +121,7 @@ suspend fun unpackTarball(tarball: Path, into: Path, reporter: ProgressReporter)
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
reporter.indeterminateStep {
|
reporter.indeterminateStep {
|
||||||
coroutineToIndicator {
|
blockingContext {
|
||||||
Unarchiver.unarchive(tarball, into)
|
Unarchiver.unarchive(tarball, into)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ abstract class UUIDMapSelector<T>(val driver: UUIDComboBoxDriver<T>): Disposable
|
||||||
val actual = item is ListElem.One.Actual<*>
|
val actual = item is ListElem.One.Actual<*>
|
||||||
editButton?.isEnabled = actual
|
editButton?.isEnabled = actual
|
||||||
editButton?.repaint()
|
editButton?.repaint()
|
||||||
onSelection(if (actual) item.uuid else null)
|
onSelection(if (actual) (item as ListElem.One.Actual<*>).uuid else null)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun itemStateChanged(event: ItemEvent) {
|
private fun itemStateChanged(event: ItemEvent) {
|
||||||
|
|
|
@ -76,9 +76,13 @@ private fun <T : PsiElement> ZigMultilineAssistant<T>.preprocessEnter(
|
||||||
val indentPost = parts[1].measureSpaces()
|
val indentPost = parts[1].measureSpaces()
|
||||||
val newLine = StringBuilder(1 + indentPre + prefix.length + indentPost)
|
val newLine = StringBuilder(1 + indentPre + prefix.length + indentPost)
|
||||||
.append('\n')
|
.append('\n')
|
||||||
.repeat(' '.code, indentPre)
|
for (i in 0..<indentPre) {
|
||||||
.append(prefix)
|
newLine.append(' ')
|
||||||
.repeat(' '.code, indentPost)
|
}
|
||||||
|
newLine.append(prefix)
|
||||||
|
for (i in 0..<indentPost) {
|
||||||
|
newLine.append(' ')
|
||||||
|
}
|
||||||
document.insertString(offset, newLine)
|
document.insertString(offset, newLine)
|
||||||
PsiDocumentManager.getInstance(project).commitDocument(document)
|
PsiDocumentManager.getInstance(project).commitDocument(document)
|
||||||
editor.caretModel.moveToOffset(offset + newLine.length)
|
editor.caretModel.moveToOffset(offset + newLine.length)
|
||||||
|
|
|
@ -165,10 +165,6 @@
|
||||||
implementation="com.falsepattern.zigbrains.project.console.ZigSourceFileFilter"
|
implementation="com.falsepattern.zigbrains.project.console.ZigSourceFileFilter"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<additionalLibraryRootsProvider
|
|
||||||
implementation="com.falsepattern.zigbrains.project.stdlib.ZigLibraryRootProvider"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!--suppress PluginXmlValidity -->
|
<!--suppress PluginXmlValidity -->
|
||||||
<toolWindow
|
<toolWindow
|
||||||
factoryClass="com.falsepattern.zigbrains.project.steps.ui.BuildToolWindowFactory"
|
factoryClass="com.falsepattern.zigbrains.project.steps.ui.BuildToolWindowFactory"
|
||||||
|
|
|
@ -3,13 +3,13 @@ pluginRepositoryUrl=https://github.com/FalsePattern/ZigBrains
|
||||||
|
|
||||||
pluginVersion=25.2.0
|
pluginVersion=25.2.0
|
||||||
|
|
||||||
pluginSinceBuild=251
|
pluginSinceBuild=241
|
||||||
pluginUntilBuild=
|
pluginUntilBuild=241.*
|
||||||
|
|
||||||
ideaCommunityVersion=2025.1
|
ideaCommunityVersion=2024.1.7
|
||||||
clionVersion=2025.1
|
clionVersion=2024.1.6
|
||||||
useInstaller=true
|
useInstaller=true
|
||||||
javaVersion=21
|
javaVersion=17
|
||||||
# ideaCommunity / clion
|
# ideaCommunity / clion
|
||||||
runIdeTarget=clion
|
runIdeTarget=clion
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ lsp4jVersion=0.21.1
|
||||||
lsp4ijVersion=0.12.0
|
lsp4ijVersion=0.12.0
|
||||||
lsp4ijNightly=false
|
lsp4ijNightly=false
|
||||||
|
|
||||||
serializationVersion=1.7.3
|
serializationVersion=1.6.3
|
||||||
|
|
||||||
kotlin.stdlib.default.dependency=false
|
kotlin.stdlib.default.dependency=false
|
||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
|
|
|
@ -46,7 +46,7 @@ class ZLSStreamConnectionProvider private constructor(private val project: Proje
|
||||||
companion object {
|
companion object {
|
||||||
suspend fun create(project: Project): ZLSStreamConnectionProvider {
|
suspend fun create(project: Project): ZLSStreamConnectionProvider {
|
||||||
val projectDir = project.guessProjectDir()?.toNioPathOrNull()
|
val projectDir = project.guessProjectDir()?.toNioPathOrNull()
|
||||||
val commandLine = getCommand(project)?.let { GeneralCommandLine(it) }?.withWorkingDirectory(projectDir)
|
val commandLine = getCommand(project)?.let { GeneralCommandLine(it) }?.withWorkDirectory(projectDir?.toFile())
|
||||||
return ZLSStreamConnectionProvider(project, commandLine)
|
return ZLSStreamConnectionProvider(project, commandLine)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,8 +43,8 @@ import javax.swing.text.PlainDocument
|
||||||
class ZLSSettingsPanel() : ImmutableElementPanel<ZLSSettings> {
|
class ZLSSettingsPanel() : ImmutableElementPanel<ZLSSettings> {
|
||||||
private val zlsConfigPath = textFieldWithBrowseButton(
|
private val zlsConfigPath = textFieldWithBrowseButton(
|
||||||
null,
|
null,
|
||||||
|
ZLSBundle.message("settings.zls-config-path.browse.title"),
|
||||||
FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor()
|
FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor()
|
||||||
.withTitle(ZLSBundle.message("settings.zls-config-path.browse.title"))
|
|
||||||
).also { Disposer.register(this, it) }
|
).also { Disposer.register(this, it) }
|
||||||
private val inlayHints = JBCheckBox()
|
private val inlayHints = JBCheckBox()
|
||||||
private val inlayHintsMaxFileSize = ExtendableTextField(5).also { (it.document as PlainDocument).documentFilter = object: DocumentFilter() {
|
private val inlayHintsMaxFileSize = ExtendableTextField(5).also { (it.document as PlainDocument).documentFilter = object: DocumentFilter() {
|
||||||
|
|
|
@ -49,7 +49,8 @@ import kotlin.io.path.pathString
|
||||||
class ZLSPanel() : ImmutableNamedElementPanelBase<ZLSVersion>() {
|
class ZLSPanel() : ImmutableNamedElementPanelBase<ZLSVersion>() {
|
||||||
private val pathToZLS = textFieldWithBrowseButton(
|
private val pathToZLS = textFieldWithBrowseButton(
|
||||||
null,
|
null,
|
||||||
FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor().withTitle(ZLSBundle.message("dialog.title.zls"))
|
ZLSBundle.message("dialog.title.zls"),
|
||||||
|
FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor()
|
||||||
).also {
|
).also {
|
||||||
it.textField.document.addDocumentListener(object : DocumentAdapter() {
|
it.textField.document.addDocumentListener(object : DocumentAdapter() {
|
||||||
override fun textChanged(e: DocumentEvent) {
|
override fun textChanged(e: DocumentEvent) {
|
||||||
|
|
|
@ -28,7 +28,7 @@ import com.falsepattern.zigbrains.shared.downloader.VersionInfo
|
||||||
import com.falsepattern.zigbrains.shared.downloader.VersionInfo.Tarball
|
import com.falsepattern.zigbrains.shared.downloader.VersionInfo.Tarball
|
||||||
import com.falsepattern.zigbrains.shared.downloader.getTarballIfCompatible
|
import com.falsepattern.zigbrains.shared.downloader.getTarballIfCompatible
|
||||||
import com.falsepattern.zigbrains.shared.downloader.tempPluginDir
|
import com.falsepattern.zigbrains.shared.downloader.tempPluginDir
|
||||||
import com.intellij.openapi.progress.coroutineToIndicator
|
import com.intellij.openapi.progress.blockingContext
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
import com.intellij.util.asSafely
|
import com.intellij.util.asSafely
|
||||||
|
@ -52,7 +52,7 @@ data class ZLSVersionInfo(
|
||||||
return withContext(Dispatchers.IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
val single = toolchain != null
|
val single = toolchain != null
|
||||||
val url = if (single) {
|
val url = if (single) {
|
||||||
getToolchainURL(toolchain, project) ?: return@withContext emptyList()
|
getToolchainURL(toolchain!!, project) ?: return@withContext emptyList()
|
||||||
} else {
|
} else {
|
||||||
multiURL
|
multiURL
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ data class ZLSVersionInfo(
|
||||||
val tempFile = FileUtil.createTempFile(tempPluginDir, "zls_version_info", ".json", false, false)
|
val tempFile = FileUtil.createTempFile(tempPluginDir, "zls_version_info", ".json", false, false)
|
||||||
val desc = service.createFileDescription(url, tempFile.name)
|
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), ZLSBundle.message("settings.downloader.service.index"))
|
||||||
val downloadResults = coroutineToIndicator {
|
val downloadResults = blockingContext {
|
||||||
downloader.download(tempPluginDir)
|
downloader.download(tempPluginDir)
|
||||||
}
|
}
|
||||||
if (downloadResults.isEmpty())
|
if (downloadResults.isEmpty())
|
||||||
|
|
|
@ -30,6 +30,7 @@ import com.intellij.icons.AllIcons
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.ui.SimpleTextAttributes
|
import com.intellij.ui.SimpleTextAttributes
|
||||||
import com.intellij.ui.icons.EMPTY_ICON
|
import com.intellij.ui.icons.EMPTY_ICON
|
||||||
|
import com.intellij.util.ui.EmptyIcon
|
||||||
import javax.swing.JList
|
import javax.swing.JList
|
||||||
import kotlin.io.path.pathString
|
import kotlin.io.path.pathString
|
||||||
|
|
||||||
|
@ -70,7 +71,7 @@ class ZLSCellRenderer(getModel: () -> ZBModel<ZLSVersion>): ZBCellRenderer<ZLSVe
|
||||||
append(ZLSBundle.message("settings.model.from-disk.text"))
|
append(ZLSBundle.message("settings.model.from-disk.text"))
|
||||||
}
|
}
|
||||||
is ListElem.Pending -> {
|
is ListElem.Pending -> {
|
||||||
icon = AllIcons.Empty
|
icon = EMPTY_ICON
|
||||||
append(ZLSBundle.message("settings.model.loading.text"), SimpleTextAttributes.GRAYED_ATTRIBUTES)
|
append(ZLSBundle.message("settings.model.loading.text"), SimpleTextAttributes.GRAYED_ATTRIBUTES)
|
||||||
}
|
}
|
||||||
is ListElem.None, null -> {
|
is ListElem.None, null -> {
|
||||||
|
@ -80,4 +81,5 @@ class ZLSCellRenderer(getModel: () -> ZBModel<ZLSVersion>): ZBCellRenderer<ZLSVe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
private val EMPTY_ICON = EmptyIcon.create(16, 16)
|
Loading…
Add table
Reference in a new issue