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.Mutex
import kotlinx.coroutines.sync.withLock 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.ConsoleInput
import net.mamoe.mirai.console.util.requestInput
@Suppress("unused") @Suppress("unused")
internal object ConsoleInputImpl : ConsoleInput { internal object ConsoleInputImpl : ConsoleInput {
private val inputLock = Mutex() private val inputLock = Mutex()
override suspend fun requestInput(hint: String): String = 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 package net.mamoe.mirai.console.pure
import kotlinx.coroutines.* import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.cancel
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.runBlocking
import net.mamoe.mirai.console.MiraiConsole import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.command.BuiltInCommands import net.mamoe.mirai.console.command.BuiltInCommands
import net.mamoe.mirai.console.command.Command.Companion.primaryName 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.ConsoleInternalAPI
import net.mamoe.mirai.console.util.requestInput import net.mamoe.mirai.console.util.requestInput
import net.mamoe.mirai.utils.DefaultLogger import net.mamoe.mirai.utils.DefaultLogger
import org.fusesource.jansi.Ansi
import org.jline.reader.UserInterruptException import org.jline.reader.UserInterruptException
import java.util.*
import kotlin.concurrent.thread import kotlin.concurrent.thread
val consoleLogger by lazy { DefaultLogger("console") }
@OptIn(ConsoleInternalAPI::class) @OptIn(ConsoleInternalAPI::class)
internal fun startupConsoleThread() { 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") { val inputThread = thread(start = true, isDaemon = false, name = "Console Input") {
try { try {
@ -109,7 +88,7 @@ internal fun startupConsoleThread() {
inputThread.interrupt() inputThread.interrupt()
}.exceptionOrNull()?.printStackTrace() }.exceptionOrNull()?.printStackTrace()
runCatching { runCatching {
ConsoleUtils.terminal.close() terminal.close()
}.exceptionOrNull()?.printStackTrace() }.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 com.vdurmont.semver4j.Semver
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.withContext
import net.mamoe.mirai.console.ConsoleFrontEndImplementation import net.mamoe.mirai.console.ConsoleFrontEndImplementation
import net.mamoe.mirai.console.MiraiConsole import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.MiraiConsoleFrontEndDescription 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.console.util.ConsoleInternalAPI
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.*
import org.fusesource.jansi.Ansi 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.Path
import java.nio.file.Paths 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.* import java.util.*
/** /**
@ -83,7 +93,51 @@ internal class MiraiConsoleImplementationPure
} }
private object ConsoleInputImpl : ConsoleInput { 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 { private object ConsoleFrontEndDescImpl : MiraiConsoleFrontEndDescription {
@ -96,16 +150,6 @@ private val ANSI_RESET = Ansi().reset().toString()
internal val LoggerCreator: (identity: String?) -> MiraiLogger = { internal val LoggerCreator: (identity: String?) -> MiraiLogger = {
PlatformLogger(identity = it, output = { line -> 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.command.ConsoleCommandSender
import net.mamoe.mirai.console.util.ConsoleInternalAPI import net.mamoe.mirai.console.util.ConsoleInternalAPI
import net.mamoe.mirai.message.data.Message import net.mamoe.mirai.message.data.Message
import net.mamoe.mirai.message.data.content
import net.mamoe.mirai.utils.DefaultLogger import net.mamoe.mirai.utils.DefaultLogger
import java.io.PrintStream import java.io.PrintStream
@ -66,10 +65,9 @@ internal fun overrideSTD() {
internal object ConsoleCommandSenderImpl : ConsoleCommandSender() { internal object ConsoleCommandSenderImpl : ConsoleCommandSender() {
override suspend fun sendMessage(message: Message) { override suspend fun sendMessage(message: Message) {
kotlin.runCatching { kotlin.runCatching {
ConsoleUtils.lineReader.printAbove(message.contentToString()) lineReader.printAbove(message.contentToString())
}.onFailure { }.onFailure {
println(message.content) consoleLogger.error(it)
it.printStackTrace()
} }
} }
} }