Added Vectors and Matrics operations, slicing, docs.
This commit is contained in:
1 parent
a72991d1b7
commit
83d8c8b71f
31 files changed
+1972
-41
No files matched your search
@@ -23,6 +23,8 @@ import com.intellij.execution.ui.ConsoleViewContentType
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.wm.ToolWindow
|
||||
import com.intellij.openapi.wm.ToolWindowAnchor
|
||||
@@ -36,9 +38,10 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.launch
|
||||
import net.sergeych.lyng.idea.LyngIcons
|
||||
import java.io.File
|
||||
|
||||
class RunLyngScriptAction : AnAction(LyngIcons.FILE) {
|
||||
private val scope = CoroutineScope(Dispatchers.Default + SupervisorJob())
|
||||
private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||
|
||||
private fun getPsiFile(e: AnActionEvent): PsiFile? {
|
||||
val project = e.project ?: return null
|
||||
@@ -48,36 +51,99 @@ class RunLyngScriptAction : AnAction(LyngIcons.FILE) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun getRunnableFile(e: AnActionEvent): PsiFile? {
|
||||
val psiFile = getPsiFile(e) ?: return null
|
||||
val virtualFile = psiFile.virtualFile ?: return null
|
||||
if (!virtualFile.isInLocalFileSystem) return null
|
||||
if (!psiFile.name.endsWith(".lyng")) return null
|
||||
return psiFile
|
||||
}
|
||||
|
||||
override fun update(e: AnActionEvent) {
|
||||
val psiFile = getPsiFile(e)
|
||||
val isLyng = psiFile?.name?.endsWith(".lyng") == true
|
||||
e.presentation.isEnabledAndVisible = isLyng
|
||||
if (isLyng) {
|
||||
e.presentation.isEnabled = false
|
||||
e.presentation.text = "Run '${psiFile.name}' (disabled)"
|
||||
e.presentation.description = "Running scripts from the IDE is disabled; use the CLI."
|
||||
val psiFile = getRunnableFile(e)
|
||||
val isRunnable = psiFile != null
|
||||
e.presentation.isEnabledAndVisible = isRunnable
|
||||
if (isRunnable) {
|
||||
e.presentation.text = "Run '${psiFile.name}'"
|
||||
e.presentation.description = "Run the current Lyng script using the Lyng CLI"
|
||||
} else {
|
||||
e.presentation.text = "Run Lyng Script"
|
||||
e.presentation.description = "Run the current Lyng script"
|
||||
}
|
||||
}
|
||||
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
val project = e.project ?: return
|
||||
val psiFile = getPsiFile(e) ?: return
|
||||
val fileName = psiFile.name
|
||||
val psiFile = getRunnableFile(e) ?: return
|
||||
val virtualFile = psiFile.virtualFile ?: return
|
||||
FileDocumentManager.getInstance().getDocument(virtualFile)?.let { document ->
|
||||
FileDocumentManager.getInstance().saveDocument(document)
|
||||
}
|
||||
val filePath = virtualFile.path
|
||||
val workingDir = virtualFile.parent?.path ?: project.basePath ?: File(filePath).parent
|
||||
|
||||
val (console, toolWindow) = getConsoleAndToolWindow(project)
|
||||
console.clear()
|
||||
|
||||
toolWindow.show {
|
||||
scope.launch {
|
||||
console.print("--- Run is disabled ---\n", ConsoleViewContentType.SYSTEM_OUTPUT)
|
||||
console.print("Lyng now runs in bytecode-only mode; the IDE no longer evaluates scripts.\n", ConsoleViewContentType.NORMAL_OUTPUT)
|
||||
console.print("Use the CLI to run scripts, e.g. `lyng run $fileName`.\n", ConsoleViewContentType.NORMAL_OUTPUT)
|
||||
val command = startLyngProcess(filePath, workingDir)
|
||||
if (command == null) {
|
||||
printToConsole(console, "Unable to start Lyng CLI.\n", ConsoleViewContentType.ERROR_OUTPUT)
|
||||
printToConsole(console, "Tried commands: lyng, jlyng.\n", ConsoleViewContentType.ERROR_OUTPUT)
|
||||
printToConsole(console, "Install `lyng` or `jlyng` and make sure it is available on PATH.\n", ConsoleViewContentType.NORMAL_OUTPUT)
|
||||
return@launch
|
||||
}
|
||||
|
||||
printToConsole(
|
||||
console,
|
||||
"Running ${command.commandLine} in ${command.workingDir}\n",
|
||||
ConsoleViewContentType.SYSTEM_OUTPUT
|
||||
)
|
||||
streamProcess(command.process, console)
|
||||
val exitCode = command.process.waitFor()
|
||||
val outputType = if (exitCode == 0) ConsoleViewContentType.SYSTEM_OUTPUT else ConsoleViewContentType.ERROR_OUTPUT
|
||||
printToConsole(console, "\nProcess finished with exit code $exitCode\n", outputType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun streamProcess(process: Process, console: ConsoleView) {
|
||||
val stdout = scope.launch {
|
||||
process.inputStream.bufferedReader().useLines { lines ->
|
||||
lines.forEach { printToConsole(console, "$it\n", ConsoleViewContentType.NORMAL_OUTPUT) }
|
||||
}
|
||||
}
|
||||
val stderr = scope.launch {
|
||||
process.errorStream.bufferedReader().useLines { lines ->
|
||||
lines.forEach { printToConsole(console, "$it\n", ConsoleViewContentType.ERROR_OUTPUT) }
|
||||
}
|
||||
}
|
||||
stdout.join()
|
||||
stderr.join()
|
||||
}
|
||||
|
||||
private fun printToConsole(console: ConsoleView, text: String, type: ConsoleViewContentType) {
|
||||
ApplicationManager.getApplication().invokeLater {
|
||||
console.print(text, type)
|
||||
}
|
||||
}
|
||||
|
||||
private fun startLyngProcess(filePath: String, workingDir: String?): StartedProcess? {
|
||||
val candidates = listOf("lyng", "jlyng")
|
||||
for (candidate in candidates) {
|
||||
try {
|
||||
val process = ProcessBuilder(candidate, filePath)
|
||||
.directory(workingDir?.let(::File))
|
||||
.start()
|
||||
return StartedProcess(process, "$candidate $filePath", workingDir ?: File(filePath).parent.orEmpty())
|
||||
} catch (_: java.io.IOException) {
|
||||
// Try the next candidate when the command is not available.
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun getConsoleAndToolWindow(project: Project): Pair<ConsoleView, ToolWindow> {
|
||||
val toolWindowManager = ToolWindowManager.getInstance(project)
|
||||
var toolWindow = toolWindowManager.getToolWindow(ToolWindowId.RUN)
|
||||
@@ -106,4 +172,10 @@ class RunLyngScriptAction : AnAction(LyngIcons.FILE) {
|
||||
contentManager.setSelectedContent(content)
|
||||
return console to actualToolWindow
|
||||
}
|
||||
|
||||
private data class StartedProcess(
|
||||
val process: Process,
|
||||
val commandLine: String,
|
||||
val workingDir: String
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user