Fix ConsoleInput, cleanup frontend

This commit is contained in:
Him188 2020-08-26 09:03:09 +08:00
parent 1e2ef14639
commit e2e922905b
5 changed files with 67 additions and 95 deletions

View File

@ -11,14 +11,13 @@ package net.mamoe.mirai.console.internal.util
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge
import net.mamoe.mirai.console.util.ConsoleInput
import net.mamoe.mirai.console.util.requestInput
@Suppress("unused")
internal object ConsoleInputImpl : ConsoleInput {
private val inputLock = Mutex()
override suspend fun requestInput(hint: String): String =
inputLock.withLock { MiraiConsole.requestInput(hint) }
inputLock.withLock { MiraiConsoleImplementationBridge.consoleInput.requestInput(hint) }
}

View File

@ -9,9 +9,9 @@
package net.mamoe.mirai.console.pure
import kotlinx.coroutines.*
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.cancel
import kotlinx.coroutines.runBlocking
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.command.BuiltInCommands
import net.mamoe.mirai.console.command.Command.Companion.primaryName
@ -21,34 +21,13 @@ import net.mamoe.mirai.console.command.CommandManager.INSTANCE.executeCommand
import net.mamoe.mirai.console.util.ConsoleInternalAPI
import net.mamoe.mirai.console.util.requestInput
import net.mamoe.mirai.utils.DefaultLogger
import org.fusesource.jansi.Ansi
import org.jline.reader.UserInterruptException
import java.util.*
import kotlin.concurrent.thread
val consoleLogger by lazy { DefaultLogger("console") }
@OptIn(ConsoleInternalAPI::class)
internal fun startupConsoleThread() {
val mutex = Mutex()
ConsoleUtils.miraiLineReader = { hint ->
mutex.withLock {
withContext(Dispatchers.IO) {
ConsoleUtils.lineReader.readLine(
if (hint.isNotEmpty()) {
ConsoleUtils.lineReader.printAbove(
Ansi.ansi()
.fgCyan().a(sdf.format(Date())).a(" ")
.fgMagenta().a(hint)
.reset()
.toString()
)
"$hint > "
} else "> "
)
}
}
}
val consoleLogger = DefaultLogger("console")
val inputThread = thread(start = true, isDaemon = false, name = "Console Input") {
try {
@ -109,7 +88,7 @@ internal fun startupConsoleThread() {
inputThread.interrupt()
}.exceptionOrNull()?.printStackTrace()
runCatching {
ConsoleUtils.terminal.close()
terminal.close()
}.exceptionOrNull()?.printStackTrace()
}
}

View File

@ -1,48 +0,0 @@
/*
* Copyright 2019-2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.console.pure
import org.jline.reader.LineReader
import org.jline.reader.LineReaderBuilder
import org.jline.reader.impl.completer.NullCompleter
import org.jline.terminal.Terminal
import org.jline.terminal.TerminalBuilder
internal object ConsoleUtils {
val lineReader: LineReader
val terminal: Terminal
lateinit var miraiLineReader: suspend (String) -> String
init {
val dumb = System.getProperty("java.class.path")
.contains("idea_rt.jar") || System.getProperty("mirai.idea") !== null || System.getenv("mirai.idea") !== null
terminal = kotlin.runCatching {
TerminalBuilder.builder()
.dumb(dumb)
.build()
}.recoverCatching {
TerminalBuilder.builder()
.jansi(true)
.build()
}.recoverCatching {
TerminalBuilder.builder()
.system(true)
.build()
}.getOrThrow()
lineReader = LineReaderBuilder.builder()
.terminal(terminal)
.completer(NullCompleter())
.build()
}
}

View File

@ -24,7 +24,9 @@ package net.mamoe.mirai.console.pure
import com.vdurmont.semver4j.Semver
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.withContext
import net.mamoe.mirai.console.ConsoleFrontEndImplementation
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.MiraiConsoleFrontEndDescription
@ -40,9 +42,17 @@ import net.mamoe.mirai.console.util.ConsoleInput
import net.mamoe.mirai.console.util.ConsoleInternalAPI
import net.mamoe.mirai.utils.*
import org.fusesource.jansi.Ansi
import org.jline.reader.LineReader
import org.jline.reader.LineReaderBuilder
import org.jline.reader.impl.completer.NullCompleter
import org.jline.terminal.Terminal
import org.jline.terminal.TerminalBuilder
import java.nio.file.Path
import java.nio.file.Paths
import java.text.SimpleDateFormat
import java.time.Instant
import java.time.LocalDateTime
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.util.*
/**
@ -83,7 +93,51 @@ internal class MiraiConsoleImplementationPure
}
private object ConsoleInputImpl : ConsoleInput {
override suspend fun requestInput(hint: String): String = ConsoleUtils.miraiLineReader(hint)
private val format = DateTimeFormatter.ofPattern("HH:mm:ss")
override suspend fun requestInput(hint: String): String {
return withContext(Dispatchers.IO) {
lineReader.readLine(
if (hint.isNotEmpty()) {
lineReader.printAbove(
Ansi.ansi()
.fgCyan().a(LocalDateTime.ofInstant(Instant.now(), ZoneId.systemDefault()).format(format))
.a(" ")
.fgMagenta().a(hint)
.reset()
.toString()
)
"$hint > "
} else "> "
)
}
}
}
val lineReader: LineReader by lazy {
LineReaderBuilder.builder()
.terminal(terminal)
.completer(NullCompleter())
.build()
}
val terminal: Terminal = run {
val dumb = System.getProperty("java.class.path")
.contains("idea_rt.jar") || System.getProperty("mirai.idea") !== null || System.getenv("mirai.idea") !== null
runCatching {
TerminalBuilder.builder()
.dumb(dumb)
.build()
}.recoverCatching {
TerminalBuilder.builder()
.jansi(true)
.build()
}.recoverCatching {
TerminalBuilder.builder()
.system(true)
.build()
}.getOrThrow()
}
private object ConsoleFrontEndDescImpl : MiraiConsoleFrontEndDescription {
@ -96,16 +150,6 @@ private val ANSI_RESET = Ansi().reset().toString()
internal val LoggerCreator: (identity: String?) -> MiraiLogger = {
PlatformLogger(identity = it, output = { line ->
ConsoleUtils.lineReader.printAbove(line + ANSI_RESET)
lineReader.printAbove(line + ANSI_RESET)
})
}
internal val sdf by ThreadLocal.withInitial {
// SimpleDateFormat not thread safe.
SimpleDateFormat("HH:mm:ss")
}
private operator fun <T> ThreadLocal<T>.getValue(thisRef: Any?, property: Any): T {
return this.get()
}

View File

@ -24,7 +24,6 @@ import net.mamoe.mirai.console.MiraiConsoleImplementation.Companion.start
import net.mamoe.mirai.console.command.ConsoleCommandSender
import net.mamoe.mirai.console.util.ConsoleInternalAPI
import net.mamoe.mirai.message.data.Message
import net.mamoe.mirai.message.data.content
import net.mamoe.mirai.utils.DefaultLogger
import java.io.PrintStream
@ -66,10 +65,9 @@ internal fun overrideSTD() {
internal object ConsoleCommandSenderImpl : ConsoleCommandSender() {
override suspend fun sendMessage(message: Message) {
kotlin.runCatching {
ConsoleUtils.lineReader.printAbove(message.contentToString())
lineReader.printAbove(message.contentToString())
}.onFailure {
println(message.content)
it.printStackTrace()
consoleLogger.error(it)
}
}
}