chore: cache suggestion paths

This commit is contained in:
FalsePattern 2025-04-16 00:31:25 +02:00
parent 91747319aa
commit 5efc28ae18
Signed by: falsepattern
GPG key ID: E930CDEC50C50E23
6 changed files with 41 additions and 41 deletions

View file

@ -24,15 +24,15 @@ package com.falsepattern.zigbrains.project.toolchain.downloader
import com.falsepattern.zigbrains.ZigBrainsBundle import com.falsepattern.zigbrains.ZigBrainsBundle
import com.falsepattern.zigbrains.project.toolchain.local.LocalZigToolchain import com.falsepattern.zigbrains.project.toolchain.local.LocalZigToolchain
import com.falsepattern.zigbrains.project.toolchain.local.getSuggestedLocalToolchainPath import com.falsepattern.zigbrains.project.toolchain.local.suggestedLocalToolchainPath
import com.falsepattern.zigbrains.shared.downloader.Downloader import com.falsepattern.zigbrains.shared.downloader.Downloader
import java.awt.Component import java.awt.Component
class LocalToolchainDownloader(component: Component) : Downloader<LocalZigToolchain, ZigVersionInfo>(component) { class LocalToolchainDownloader(component: Component) : Downloader<LocalZigToolchain, ZigVersionInfo>(component) {
override val windowTitle get() = ZigBrainsBundle.message("settings.toolchain.downloader.title") override val windowTitle get() = ZigBrainsBundle.message("settings.toolchain.downloader.title")
override val versionInfoFetchTitle get() = ZigBrainsBundle.message("settings.toolchain.downloader.progress.fetch") 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 downloadProgressTitle(version: ZigVersionInfo) = ZigBrainsBundle.message("settings.toolchain.downloader.progress.install", version.version.rawVersion)
override fun localSelector() = LocalToolchainSelector(component) override fun localSelector() = LocalToolchainSelector(component)
override suspend fun downloadVersionList() = ZigVersionInfo.downloadVersionList() override suspend fun downloadVersionList() = ZigVersionInfo.downloadVersionList()
override fun getSuggestedPath() = getSuggestedLocalToolchainPath()
} }

View file

@ -28,18 +28,18 @@ import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvid
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchainConfigurable import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchainConfigurable
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchainProvider 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.falsepattern.zigbrains.shared.ui.renderPathNameComponent
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.util.UserDataHolder import com.intellij.openapi.util.UserDataHolder
import com.intellij.openapi.util.io.toNioPathOrNull import com.intellij.openapi.util.io.toNioPathOrNull
import com.intellij.ui.SimpleColoredComponent import com.intellij.ui.SimpleColoredComponent
import com.intellij.util.system.OS
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
import java.util.* import java.util.*
import kotlin.io.path.isDirectory
import kotlin.io.path.pathString import kotlin.io.path.pathString
class LocalZigToolchainProvider: ZigToolchainProvider { class LocalZigToolchainProvider: ZigToolchainProvider {
@ -93,7 +93,7 @@ class LocalZigToolchainProvider: ZigToolchainProvider {
Env.empty Env.empty
} }
val pathToolchains = env.findAllExecutablesOnPATH("zig").mapNotNull { it.parent } val pathToolchains = env.findAllExecutablesOnPATH("zig").mapNotNull { it.parent }
val wellKnown = getWellKnown().asFlow().flatMapConcat { dir -> val wellKnown = wellKnown.asFlow().flatMapConcat { dir ->
runCatching { runCatching {
Files.newDirectoryStream(dir).use { stream -> Files.newDirectoryStream(dir).use { stream ->
stream.toList().filterNotNull().asFlow() stream.toList().filterNotNull().asFlow()
@ -112,8 +112,8 @@ class LocalZigToolchainProvider: ZigToolchainProvider {
} }
} }
fun getSuggestedLocalToolchainPath(): Path? { val suggestedLocalToolchainPath: Path? by lazy {
return getWellKnown().getOrNull(0) wellKnown.getOrNull(0)
} }
/** /**
@ -130,18 +130,12 @@ fun getSuggestedLocalToolchainPath(): Path? {
* *
* and HOME is the user home path * and HOME is the user home path
*/ */
private fun getWellKnown(): List<Path> { private val wellKnown: List<Path> by lazy {
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>() val res = ArrayList<Path>()
if (xdgDataHome != null && xdgDataHome.isDirectory()) { xdgDataHome?.let {
res.add(xdgDataHome.resolve("zig")) res.add(it.resolve("zig"))
res.add(xdgDataHome.resolve("zigup")) res.add(it.resolve("zigup"))
} }
res.add(home.resolve(".zig")) homePath?.let { res.add(it.resolve(".zig")) }
return res res
} }

View file

@ -76,10 +76,10 @@ abstract class Downloader<T, V: VersionInfo>(val component: Component) {
protected abstract val windowTitle: String protected abstract val windowTitle: String
protected abstract val versionInfoFetchTitle: @NlsContexts.ProgressTitle 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 downloadProgressTitle(version: V): @NlsContexts.ProgressTitle String
protected abstract fun localSelector(): LocalSelector<T> protected abstract fun localSelector(): LocalSelector<T>
protected abstract suspend fun downloadVersionList(): List<V> protected abstract suspend fun downloadVersionList(): List<V>
protected abstract fun getSuggestedPath(): Path?
@RequiresEdt @RequiresEdt
private fun selectVersion(info: List<V>, selector: LocalSelector<T>): Pair<Path, V>? { 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 var archiveSizeCell: Cell<*>? = null
fun detect(item: V) { fun detect(item: V) {
outputPath.text = getSuggestedPath()?.resolve(item.version.rawVersion)?.pathString ?: "" outputPath.text = suggestedPath?.resolve(item.version.rawVersion)?.pathString ?: ""
val size = item.dist.size val size = item.dist.size
val sizeMb = size / (1024f * 1024f) val sizeMb = size / (1024f * 1024f)
archiveSizeCell?.comment?.text = ZigBrainsBundle.message("settings.shared.downloader.archive-size.text", "%.2fMB".format(sizeMb)) archiveSizeCell?.comment?.text = ZigBrainsBundle.message("settings.shared.downloader.archive-size.text", "%.2fMB".format(sizeMb))

View file

@ -41,11 +41,13 @@ import com.intellij.ui.components.textFieldWithBrowseButton
import com.intellij.ui.dsl.builder.AlignX import com.intellij.ui.dsl.builder.AlignX
import com.intellij.ui.dsl.builder.panel import com.intellij.ui.dsl.builder.panel
import com.intellij.util.concurrency.annotations.RequiresEdt import com.intellij.util.concurrency.annotations.RequiresEdt
import com.intellij.util.system.OS
import java.awt.Component import java.awt.Component
import java.nio.file.Path import java.nio.file.Path
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
import javax.swing.Icon import javax.swing.Icon
import javax.swing.event.DocumentEvent import javax.swing.event.DocumentEvent
import kotlin.io.path.isDirectory
import kotlin.io.path.pathString import kotlin.io.path.pathString
abstract class LocalSelector<T>(val component: Component) { abstract class LocalSelector<T>(val component: Component) {
@ -136,3 +138,15 @@ abstract class LocalSelector<T>(val component: Component) {
val errorText: String, 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() }
}

View file

@ -24,7 +24,7 @@ package com.falsepattern.zigbrains.lsp.zls.downloader
import com.falsepattern.zigbrains.lsp.ZLSBundle import com.falsepattern.zigbrains.lsp.ZLSBundle
import com.falsepattern.zigbrains.lsp.zls.ZLSVersion import com.falsepattern.zigbrains.lsp.zls.ZLSVersion
import com.falsepattern.zigbrains.lsp.zls.ui.getSuggestedZLSPath import com.falsepattern.zigbrains.lsp.zls.ui.suggestedZLSPath
import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvider import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvider
import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvider.IUserDataBridge import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvider.IUserDataBridge
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchainConfigurable import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchainConfigurable
@ -34,6 +34,7 @@ import java.awt.Component
class ZLSDownloader(component: Component, private val data: IUserDataBridge?) : Downloader<ZLSVersion, ZLSVersionInfo>(component) { class ZLSDownloader(component: Component, private val data: IUserDataBridge?) : Downloader<ZLSVersion, ZLSVersionInfo>(component) {
override val windowTitle get() = ZLSBundle.message("settings.downloader.title") override val windowTitle get() = ZLSBundle.message("settings.downloader.title")
override val versionInfoFetchTitle get() = ZLSBundle.message("settings.downloader.progress.fetch") 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 fun downloadProgressTitle(version: ZLSVersionInfo) = ZLSBundle.message("settings.downloader.progress.install", version.version.rawVersion)
override fun localSelector() = ZLSLocalSelector(component) override fun localSelector() = ZLSLocalSelector(component)
override suspend fun downloadVersionList(): List<ZLSVersionInfo> { override suspend fun downloadVersionList(): List<ZLSVersionInfo> {
@ -41,5 +42,4 @@ class ZLSDownloader(component: Component, private val data: IUserDataBridge?) :
val project = data?.getUserData(ZigProjectConfigurationProvider.PROJECT_KEY) val project = data?.getUserData(ZigProjectConfigurationProvider.PROJECT_KEY)
return ZLSVersionInfo.downloadVersionInfoFor(toolchain, project) return ZLSVersionInfo.downloadVersionInfoFor(toolchain, project)
} }
override fun getSuggestedPath() = getSuggestedZLSPath()
} }

View file

@ -33,14 +33,14 @@ import com.falsepattern.zigbrains.lsp.zls.zlsInstallations
import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvider import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvider
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchainConfigurable.Companion.TOOLCHAIN_KEY import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchainConfigurable.Companion.TOOLCHAIN_KEY
import com.falsepattern.zigbrains.shared.UUIDMapSerializable 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.*
import com.falsepattern.zigbrains.shared.ui.ListElem.One.Actual import com.falsepattern.zigbrains.shared.ui.ListElem.One.Actual
import com.falsepattern.zigbrains.shared.withUniqueName import com.falsepattern.zigbrains.shared.withUniqueName
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.NamedConfigurable import com.intellij.openapi.ui.NamedConfigurable
import com.intellij.openapi.util.SystemInfo 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 com.intellij.util.text.SemVer
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@ -146,7 +146,7 @@ private fun suggestZLSVersions(project: Project? = null, data: ZigProjectConfigu
emitIfCompatible(path, toolchainVersion) emitIfCompatible(path, toolchainVersion)
} }
val exe = if (SystemInfo.isWindows) "zls.exe" else "zls" val exe = if (SystemInfo.isWindows) "zls.exe" else "zls"
getWellKnownZLS().forEach { wellKnown -> wellKnownZLS.forEach { wellKnown ->
runCatching { runCatching {
Files.newDirectoryStream(wellKnown).use { stream -> Files.newDirectoryStream(wellKnown).use { stream ->
stream.asSequence().filterNotNull().forEach { dir -> stream.asSequence().filterNotNull().forEach { dir ->
@ -192,8 +192,8 @@ private fun numericVersionEquals(a: SemVer, b: SemVer): Boolean {
} }
fun getSuggestedZLSPath(): Path? { val suggestedZLSPath: Path? by lazy {
return getWellKnownZLS().getOrNull(0) wellKnownZLS.getOrNull(0)
} }
/** /**
@ -209,17 +209,9 @@ fun getSuggestedZLSPath(): Path? {
* *
* and HOME is the user home path * and HOME is the user home path
*/ */
private fun getWellKnownZLS(): List<Path> { private val wellKnownZLS: List<Path> by lazy {
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>() val res = ArrayList<Path>()
if (xdgDataHome != null && xdgDataHome.isDirectory()) { xdgDataHome?.let { res.add(it.resolve("zls")) }
res.add(xdgDataHome.resolve("zls")) homePath?.let { res.add(it.resolve(".zls")) }
} res
res.add(home.resolve(".zls"))
return res
} }