mirai/frontend/mirai-console-terminal/src/ConsoleInputImpl.kt
2020-10-30 10:28:18 +08:00

74 lines
2.9 KiB
Kotlin

/*
* 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 through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.console.terminal
import kotlinx.coroutines.CancellableContinuation
import kotlinx.coroutines.suspendCancellableCoroutine
import net.mamoe.mirai.console.util.ConsoleInput
import org.fusesource.jansi.Ansi
import org.jline.reader.EndOfFileException
import java.time.Instant
import java.time.LocalDateTime
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.util.concurrent.Executors
import kotlin.coroutines.resumeWithException
internal object ConsoleInputImpl : ConsoleInput {
private val format = DateTimeFormatter.ofPattern("HH:mm:ss")
internal val thread = Executors.newSingleThreadExecutor { task ->
Thread(task, "Mirai Console Input Thread").also {
it.isDaemon = false
}
}
internal var executingCoroutine: CancellableContinuation<String>? = null
override suspend fun requestInput(hint: String): String {
return suspendCancellableCoroutine { coroutine ->
if (thread.isShutdown || thread.isTerminated) {
coroutine.resumeWithException(EndOfFileException())
return@suspendCancellableCoroutine
}
executingCoroutine = coroutine
kotlin.runCatching {
thread.submit {
kotlin.runCatching {
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 "> "
)
}.let { result ->
executingCoroutine = null
coroutine.resumeWith(result)
}
}
}.onFailure { error ->
executingCoroutine = null
kotlin.runCatching { coroutine.resumeWithException(EndOfFileException(error)) }
}
}
}
}