All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.kotlinx.jupyter.commands.CommandsProcessing.kt Maven / Gradle / Ivy

Go to download

Implementation of REPL compiler and preprocessor for Jupyter dialect of Kotlin (IDE-compatible)

There is a newer version: 0.12.0-290
Show newest version
package org.jetbrains.kotlinx.jupyter.commands

import jupyter.kotlin.JavaRuntime
import jupyter.kotlin.variablesReportAsHTML
import org.jetbrains.kotlinx.jupyter.api.textResult
import org.jetbrains.kotlinx.jupyter.common.ReplCommand
import org.jetbrains.kotlinx.jupyter.common.ReplLineMagic
import org.jetbrains.kotlinx.jupyter.common.assertLooksLikeReplCommand
import org.jetbrains.kotlinx.jupyter.common.replCommandOrNull
import org.jetbrains.kotlinx.jupyter.compiler.util.SourceCodeImpl
import org.jetbrains.kotlinx.jupyter.config.currentKernelVersion
import org.jetbrains.kotlinx.jupyter.config.currentKotlinVersion
import org.jetbrains.kotlinx.jupyter.messaging.AbortJupyterResponse
import org.jetbrains.kotlinx.jupyter.messaging.JupyterResponse
import org.jetbrains.kotlinx.jupyter.messaging.OkJupyterResponse
import org.jetbrains.kotlinx.jupyter.repl.CompletionResult
import org.jetbrains.kotlinx.jupyter.repl.KotlinCompleter
import org.jetbrains.kotlinx.jupyter.repl.ListErrorsResult
import org.jetbrains.kotlinx.jupyter.repl.ReplForJupyter
import kotlin.script.experimental.api.ScriptDiagnostic
import kotlin.script.experimental.api.SourceCode
import kotlin.script.experimental.api.SourceCodeCompletionVariant
import kotlin.script.experimental.jvm.util.toSourceCodePosition

fun  Iterable.joinToStringIndented(transform: ((T) -> CharSequence)? = null) = joinToString("\n|    ", prefix = "    ", transform = transform)

fun reportCommandErrors(code: String): ListErrorsResult {
    val (command, commandString) = replCommandOrNull(code)
    if (command != null) return ListErrorsResult(code)

    val sourceCode = SourceCodeImpl(0, code)
    val location = SourceCode.Location(
        0.toSourceCodePosition(sourceCode),
        (commandString.length + 1).toSourceCodePosition(sourceCode),
    )
    return ListErrorsResult(
        code,
        sequenceOf(
            ScriptDiagnostic(ScriptDiagnostic.unspecifiedError, "Unknown command", location = location),
        ),
    )
}

fun doCommandCompletion(code: String, cursor: Int): CompletionResult {
    assertLooksLikeReplCommand(code)
    val prefix = code.substring(1, cursor)
    val suitableCommands = ReplCommand.entries.filter { it.nameForUser.startsWith(prefix) }
    val completions = suitableCommands.map {
        SourceCodeCompletionVariant(it.nameForUser, it.nameForUser, "command", "command")
    }
    return KotlinCompleter.getResult(code, cursor, completions)
}

fun runCommand(code: String, repl: ReplForJupyter): JupyterResponse {
    assertLooksLikeReplCommand(code)
    val args = code.trim().substring(1).split(" ")
    val cmd = ReplCommand.valueOfOrNull(args[0])?.value
        ?: return AbortJupyterResponse("Unknown command: $code\nTo see available commands, enter :help")
    return when (cmd) {
        ReplCommand.CLASSPATH -> {
            val cp = repl.currentClasspath
            OkJupyterResponse(textResult("Current classpath (${cp.count()} paths):\n${cp.joinToString("\n")}"))
        }
        ReplCommand.VARS -> {
            OkJupyterResponse(repl.notebook.variablesReportAsHTML)
        }
        ReplCommand.HELP -> {
            val commands = ReplCommand.entries.asIterable().joinToStringIndented { ":${it.nameForUser} - ${it.desc}" }
            val magics = ReplLineMagic.entries.asIterable().filter { it.visibleInHelp }.joinToStringIndented {
                var s = "%${it.nameForUser} - ${it.desc}"
                if (it.argumentsUsage != null) s += "\n        Usage: %${it.nameForUser} ${it.argumentsUsage}"
                s
            }
            val libraryDescriptors = repl.libraryDescriptorsProvider.getDescriptors()
            val libraries = libraryDescriptors.map { (libraryName, descriptor) ->
                val link = if (descriptor.link != null) " (${descriptor.link})" else ""
                val description = if (descriptor.description != null) " - ${descriptor.description}" else ""
                "$libraryName$link$description"
            }.joinToStringIndented()
            OkJupyterResponse(
                textResult(
                    """ |Kotlin Jupyter kernel.
                        |Kernel version: $currentKernelVersion
                        |Kotlin version: $currentKotlinVersion
                        |JVM version: ${JavaRuntime.version}
                        |
                        |Commands:
                        |$commands
                        |
                        |Magics:
                        |$magics
                        |
                        |Supported libraries:
                        |$libraries
                    """.trimMargin("|"),
                ),
            )
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy