WIP toolchains
This commit is contained in:
parent
d02f3859a1
commit
4a132be408
15 changed files with 657 additions and 0 deletions
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* This file is part of ZigBrains.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023-2024 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
|
||||||
|
|
||||||
|
import com.intellij.openapi.components.Service
|
||||||
|
import com.intellij.openapi.components.service
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
|
||||||
|
@Service(Service.Level.PROJECT)
|
||||||
|
class ZigProjectService(val cs: CoroutineScope)
|
||||||
|
|
||||||
|
val Project.zigService get() = service<ZigProjectService>()
|
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
* This file is part of ZigBrains.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023-2024 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
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.project.execution.VT100Util.translateVT100Escapes
|
||||||
|
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.openapi.util.Key
|
||||||
|
import com.pty4j.PtyProcess
|
||||||
|
import java.nio.charset.Charset
|
||||||
|
|
||||||
|
class ZigProcessHandler : KillableColoredProcessHandler, ColoredTextAcceptor {
|
||||||
|
constructor(commandLine: GeneralCommandLine) : super(commandLine) {
|
||||||
|
setHasPty(commandLine is PtyCommandLine)
|
||||||
|
setShouldDestroyProcessRecursively(!hasPty())
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor (process: Process, commandLine: String, charset: Charset) : super(process, commandLine, charset) {
|
||||||
|
setHasPty(process is PtyProcess)
|
||||||
|
setShouldDestroyProcessRecursively(!hasPty())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun coloredTextAvailable(text: String, attributes: Key<*>) {
|
||||||
|
super.coloredTextAvailable(text.translateVT100Escapes(), attributes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object VT100Util {
|
||||||
|
private val VT100_CHARS = CharArray(256).apply {
|
||||||
|
this.fill(' ')
|
||||||
|
this[0x6A] = '┘';
|
||||||
|
this[0x6B] = '┐';
|
||||||
|
this[0x6C] = '┌';
|
||||||
|
this[0x6D] = '└';
|
||||||
|
this[0x6E] = '┼';
|
||||||
|
this[0x71] = '─';
|
||||||
|
this[0x74] = '├';
|
||||||
|
this[0x75] = '┤';
|
||||||
|
this[0x76] = '┴';
|
||||||
|
this[0x77] = '┬';
|
||||||
|
this[0x78] = '│';
|
||||||
|
}
|
||||||
|
|
||||||
|
private const val VT100_BEGIN_SEQ = "\u001B(0"
|
||||||
|
private const val VT100_END_SEQ = "\u001B(B"
|
||||||
|
private const val VT100_BEGIN_SEQ_LENGTH: Int = VT100_BEGIN_SEQ.length
|
||||||
|
private const val VT100_END_SEQ_LENGTH: Int = VT100_END_SEQ.length
|
||||||
|
|
||||||
|
fun String.translateVT100Escapes(): String {
|
||||||
|
var offset = 0
|
||||||
|
val result = StringBuilder()
|
||||||
|
val textLength = length
|
||||||
|
while (offset < textLength) {
|
||||||
|
val startIndex = indexOf(VT100_BEGIN_SEQ, offset)
|
||||||
|
if (startIndex < 0) {
|
||||||
|
result.append(substring(offset, textLength).replace(VT100_END_SEQ, ""))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
result.append(this, offset, startIndex)
|
||||||
|
val blockOffset = startIndex + VT100_BEGIN_SEQ_LENGTH
|
||||||
|
var endIndex = indexOf(VT100_END_SEQ, blockOffset)
|
||||||
|
if (endIndex < 0) {
|
||||||
|
endIndex = textLength
|
||||||
|
}
|
||||||
|
for (i in blockOffset until endIndex) {
|
||||||
|
val c = this[i].code
|
||||||
|
if (c >= 256) {
|
||||||
|
result.append(c)
|
||||||
|
} else {
|
||||||
|
result.append(VT100_CHARS[c])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
offset = endIndex + VT100_END_SEQ_LENGTH
|
||||||
|
}
|
||||||
|
return result.toString()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* This file is part of ZigBrains.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023-2024 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.intellij.execution.configurations.LocatableConfigurationBase
|
||||||
|
|
||||||
|
abstract class ZigExecConfig<T: ZigExecConfig<T>>: LocatableConfigurationBase {
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* This file is part of ZigBrains.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023-2024 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.intellij.execution.configurations.CommandLineState
|
||||||
|
import com.intellij.execution.runners.ExecutionEnvironment
|
||||||
|
|
||||||
|
abstract class ZigProfileState<T: ZigExecConfig<T>>(
|
||||||
|
environment: ExecutionEnvironment,
|
||||||
|
protected val configuration: T
|
||||||
|
): CommandLineState(environment) {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* This file is part of ZigBrains.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023-2024 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.execution.base
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.zig.psi.ZigTypes
|
||||||
|
import com.intellij.execution.lineMarker.ExecutorAction
|
||||||
|
import com.intellij.execution.lineMarker.RunLineMarkerContributor
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.PsiFile
|
||||||
|
import com.intellij.psi.util.elementType
|
||||||
|
import javax.swing.Icon
|
||||||
|
|
||||||
|
abstract class ZigTopLevelLineMarker: RunLineMarkerContributor() {
|
||||||
|
private fun getParentIfTopLevel(element: PsiElement): PsiElement? {
|
||||||
|
var parent = getDeclaration(element)
|
||||||
|
|
||||||
|
var nestingLevel = 0;
|
||||||
|
while (parent != null && parent !is PsiFile) {
|
||||||
|
if (parent.elementType == ZigTypes.CONTAINER_DECLARATIONS) {
|
||||||
|
if (nestingLevel != 0)
|
||||||
|
return null
|
||||||
|
nestingLevel++
|
||||||
|
}
|
||||||
|
parent = parent.parent
|
||||||
|
}
|
||||||
|
if (nestingLevel != 1)
|
||||||
|
return null
|
||||||
|
return parent
|
||||||
|
}
|
||||||
|
|
||||||
|
fun elementMatches(element: PsiElement): Boolean {
|
||||||
|
return getParentIfTopLevel(element) != null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getInfo(element: PsiElement): Info? {
|
||||||
|
if (!elementMatches(element))
|
||||||
|
return null;
|
||||||
|
val actions = ExecutorAction.getActions(0)
|
||||||
|
return Info(getIcon(element), actions, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract fun getDeclaration(element: PsiElement): PsiElement?
|
||||||
|
|
||||||
|
abstract fun getIcon(element: PsiElement): Icon
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* This file is part of ZigBrains.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023-2024 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.run
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
||||||
|
import com.falsepattern.zigbrains.project.zigService
|
||||||
|
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||||
|
import com.intellij.execution.configurations.RunProfileState
|
||||||
|
import com.intellij.execution.configurations.RunnerSettings
|
||||||
|
import com.intellij.execution.runners.AsyncProgramRunner
|
||||||
|
import com.intellij.execution.runners.ExecutionEnvironment
|
||||||
|
import com.intellij.execution.ui.RunContentDescriptor
|
||||||
|
import com.intellij.openapi.rd.util.toPromise
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.async
|
||||||
|
import org.jetbrains.concurrency.Promise
|
||||||
|
|
||||||
|
abstract class ZigProgramRunner<ProfileState: ZigProfileState<*>>(protected val executorId: String): AsyncProgramRunner<RunnerSettings>() {
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
override fun execute(environment: ExecutionEnvironment, state: RunProfileState): Promise<RunContentDescriptor?> {
|
||||||
|
return environment.project.zigService.cs.async {
|
||||||
|
executeAsync(environment, state)
|
||||||
|
}.toPromise()
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend inline fun executeAsync(environment: ExecutionEnvironment, state: RunProfileState): RunContentDescriptor? {
|
||||||
|
if (state !is ZigProfileState<*>)
|
||||||
|
return null
|
||||||
|
|
||||||
|
val state = castProfileState(state) ?: return null
|
||||||
|
|
||||||
|
execute(state, null, environment)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract fun castProfileState(state: ZigProfileState<*>): ProfileState?
|
||||||
|
|
||||||
|
abstract suspend fun execute(state: ProfileState, toolchain: ZigToolchain, environment: ExecutionEnvironment)
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* This file is part of ZigBrains.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023-2024 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.settings
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.project.toolchain.ZigToolchainConverter
|
||||||
|
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||||
|
import com.intellij.util.xmlb.annotations.OptionTag
|
||||||
|
|
||||||
|
@JvmRecord
|
||||||
|
data class ZigProjectSettings(
|
||||||
|
val direnv: Boolean = true,
|
||||||
|
val overrideStdPath: Boolean = false,
|
||||||
|
val explicitPathToStd: String? = null,
|
||||||
|
@OptionTag(converter = ZigToolchainConverter::class) val toolchain: ZigToolchain? = null
|
||||||
|
)
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* This file is part of ZigBrains.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023-2024 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.settings
|
||||||
|
|
||||||
|
import com.intellij.openapi.components.*
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
|
||||||
|
@Service(Service.Level.PROJECT)
|
||||||
|
@State(
|
||||||
|
name = "ZigProjectSettings",
|
||||||
|
storages = [Storage("zigbrains.xml")]
|
||||||
|
)
|
||||||
|
class ZigProjectSettingsService: PersistentStateComponent<ZigProjectSettings> {
|
||||||
|
@Volatile
|
||||||
|
private var state = ZigProjectSettings()
|
||||||
|
|
||||||
|
override fun getState(): ZigProjectSettings {
|
||||||
|
return state.copy()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setState(value: ZigProjectSettings) {
|
||||||
|
this.state = value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun loadState(state: ZigProjectSettings) {
|
||||||
|
this.state = state
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isModified(otherData: ZigProjectSettings): Boolean {
|
||||||
|
return state != otherData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val Project.zigProjectSettings get() = service<ZigProjectSettingsService>()
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* This file is part of ZigBrains.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023-2024 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.toolchain
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import java.nio.file.Path
|
||||||
|
|
||||||
|
abstract class AbstractZigToolchain(
|
||||||
|
val location: Path,
|
||||||
|
val project: Project?
|
||||||
|
) {
|
||||||
|
abstract fun pathToExecutable(toolName: String): Path
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* This file is part of ZigBrains.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023-2024 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.toolchain
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.io.toNioPathOrNull
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import java.nio.file.Path
|
||||||
|
|
||||||
|
|
||||||
|
@JvmRecord
|
||||||
|
data class ZigToolchainEnvironmentSerializable(
|
||||||
|
@SerialName("zig_exe") val zigExecutable: String,
|
||||||
|
@SerialName("std_dir") val stdDirectory: String,
|
||||||
|
@SerialName("global_cache_dir") val globalCacheDirectory: String,
|
||||||
|
@SerialName("lib_dir") val libDirectory: String,
|
||||||
|
@SerialName("version") val version: String,
|
||||||
|
@SerialName("target") val target: String
|
||||||
|
) {
|
||||||
|
fun stdPath(toolchain: AbstractZigToolchain): Path? {
|
||||||
|
val path = stdDirectory.toNioPathOrNull() ?: return null
|
||||||
|
if (path.isAbsolute)
|
||||||
|
return path
|
||||||
|
|
||||||
|
val resolvedPath = toolchain.location.resolve(path)
|
||||||
|
if (resolvedPath.isAbsolute)
|
||||||
|
return resolvedPath
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* This file is part of ZigBrains.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023-2024 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.toolchain
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.project.toolchain.ZigToolchainProvider.Companion.EXTENSION_POINT_NAME
|
||||||
|
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||||
|
import com.intellij.openapi.extensions.ExtensionPointName
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.util.xmlb.Converter
|
||||||
|
import kotlinx.serialization.json.*
|
||||||
|
|
||||||
|
sealed interface ZigToolchainProvider {
|
||||||
|
suspend fun getToolchain(project: Project?): ZigToolchain?
|
||||||
|
|
||||||
|
val serialMarker: String
|
||||||
|
fun deserialize(data: JsonElement): ZigToolchain?
|
||||||
|
fun canSerialize(toolchain: ZigToolchain): Boolean
|
||||||
|
fun serialize(toolchain: ZigToolchain): JsonElement
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val EXTENSION_POINT_NAME = ExtensionPointName.create<ZigToolchainProvider>("com.falsepattern.zigbrains.toolchainProvider")
|
||||||
|
|
||||||
|
suspend fun findToolchains(project: Project?): ZigToolchain? {
|
||||||
|
return EXTENSION_POINT_NAME.extensionList.firstNotNullOfOrNull { it.getToolchain(project) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ZigToolchainConverter: Converter<ZigToolchain>() {
|
||||||
|
override fun fromString(value: String): ZigToolchain? {
|
||||||
|
val json = Json.parseToJsonElement(value) as? JsonObject ?: return null
|
||||||
|
val marker = (json["marker"] as? JsonPrimitive)?.contentOrNull ?: return null
|
||||||
|
val data = json["data"] ?: return null
|
||||||
|
val provider = EXTENSION_POINT_NAME.extensionList.find { it.serialMarker == marker } ?: return null
|
||||||
|
return provider.deserialize(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(value: ZigToolchain): String? {
|
||||||
|
val provider = EXTENSION_POINT_NAME.extensionList.find { it.canSerialize(value) } ?: return null
|
||||||
|
return buildJsonObject {
|
||||||
|
put("marker", provider.serialMarker)
|
||||||
|
put("data", provider.serialize(value))
|
||||||
|
}.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* This file is part of ZigBrains.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023-2024 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.toolchain.tools
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain
|
||||||
|
import com.falsepattern.zigbrains.project.toolchain.ZigToolchainEnvironmentSerializable
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
|
class ZigCompilerTool(toolchain: AbstractZigToolchain): ZigTool(toolchain) {
|
||||||
|
override val toolName: String
|
||||||
|
get() = "zig"
|
||||||
|
|
||||||
|
suspend fun getEnv(): ZigToolchainEnvironmentSerializable {
|
||||||
|
return Json.decodeFromString<ZigToolchainEnvironmentSerializable>(callWithArgs(toolchain.location, "env").stdout)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* This file is part of ZigBrains.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023-2024 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.toolchain.tools
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain
|
||||||
|
import com.intellij.execution.configurations.GeneralCommandLine
|
||||||
|
import com.intellij.execution.process.ProcessOutput
|
||||||
|
import com.intellij.util.io.awaitExit
|
||||||
|
import com.intellij.util.io.readLineAsync
|
||||||
|
import kotlinx.coroutines.runInterruptible
|
||||||
|
import kotlinx.coroutines.withTimeout
|
||||||
|
import java.nio.file.Path
|
||||||
|
import java.time.Duration
|
||||||
|
|
||||||
|
abstract class ZigTool(val toolchain: AbstractZigToolchain) {
|
||||||
|
abstract val toolName: String
|
||||||
|
|
||||||
|
suspend fun callWithArgs(workingDirectory: Path?, vararg parameters: String): ProcessOutput {
|
||||||
|
val process = createBaseCommandLine(workingDirectory, *parameters).createProcess()
|
||||||
|
val exitCode = process.awaitExit()
|
||||||
|
return runInterruptible {
|
||||||
|
ProcessOutput(
|
||||||
|
process.inputStream.bufferedReader().use { it.readText() },
|
||||||
|
process.errorStream.bufferedReader().use { it.readText() },
|
||||||
|
exitCode,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected suspend fun createBaseCommandLine(workingDirectory: Path?,
|
||||||
|
vararg parameters: String): GeneralCommandLine {
|
||||||
|
return GeneralCommandLine()
|
||||||
|
.withExePath(toolchain.pathToExecutable(toolName).toString())
|
||||||
|
.withWorkDirectory(workingDirectory?.toString())
|
||||||
|
.withParameters(*parameters)
|
||||||
|
.withCharset(Charsets.UTF_8)
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,6 +24,7 @@ package com.falsepattern.zigbrains.lsp.settings
|
||||||
|
|
||||||
import org.jetbrains.annotations.NonNls
|
import org.jetbrains.annotations.NonNls
|
||||||
|
|
||||||
|
@JvmRecord
|
||||||
data class ZLSSettings(
|
data class ZLSSettings(
|
||||||
val direnv: Boolean = true,
|
val direnv: Boolean = true,
|
||||||
val zlsPath: @NonNls String = "",
|
val zlsPath: @NonNls String = "",
|
||||||
|
|
|
@ -14,4 +14,11 @@
|
||||||
dynamic="true"
|
dynamic="true"
|
||||||
name="zlsConfigProvider"/>
|
name="zlsConfigProvider"/>
|
||||||
</extensionPoints>
|
</extensionPoints>
|
||||||
|
<extensionPoints>
|
||||||
|
<extensionPoint
|
||||||
|
interface="com.falsepattern.zigbrains.project.toolchain.ZigToolchainProvider"
|
||||||
|
dynamic="true"
|
||||||
|
name="toolchainProvider"
|
||||||
|
/>
|
||||||
|
</extensionPoints>
|
||||||
</idea-plugin>
|
</idea-plugin>
|
Loading…
Add table
Reference in a new issue