mirror of
https://github.com/JakeWharton/mosaic.git
synced 2025-10-28 04:35:17 +08:00
Parse system theme events (#539)
This commit is contained in:
@ -24,6 +24,14 @@ public final class com/jakewharton/mosaic/terminal/event/BracketedPasteEvent : c
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class com/jakewharton/mosaic/terminal/event/DeviceStatusReportEvent : com/jakewharton/mosaic/terminal/event/Event {
|
||||
public fun <init> (Ljava/lang/String;)V
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getData ()Ljava/lang/String;
|
||||
public fun hashCode ()I
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public abstract interface class com/jakewharton/mosaic/terminal/event/Event {
|
||||
}
|
||||
|
||||
@ -43,6 +51,14 @@ public final class com/jakewharton/mosaic/terminal/event/PrimaryDeviceAttributes
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class com/jakewharton/mosaic/terminal/event/SystemThemeEvent : com/jakewharton/mosaic/terminal/event/Event {
|
||||
public fun <init> (Z)V
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public fun hashCode ()I
|
||||
public final fun isDark ()Z
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class com/jakewharton/mosaic/terminal/event/UnknownEvent : com/jakewharton/mosaic/terminal/event/Event {
|
||||
public fun <init> (Ljava/lang/String;[B)V
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
|
||||
@ -19,6 +19,17 @@ final class com.jakewharton.mosaic.terminal.event/BracketedPasteEvent : com.jake
|
||||
final fun toString(): kotlin/String // com.jakewharton.mosaic.terminal.event/BracketedPasteEvent.toString|toString(){}[0]
|
||||
}
|
||||
|
||||
final class com.jakewharton.mosaic.terminal.event/DeviceStatusReportEvent : com.jakewharton.mosaic.terminal.event/Event { // com.jakewharton.mosaic.terminal.event/DeviceStatusReportEvent|null[0]
|
||||
constructor <init>(kotlin/String) // com.jakewharton.mosaic.terminal.event/DeviceStatusReportEvent.<init>|<init>(kotlin.String){}[0]
|
||||
|
||||
final val data // com.jakewharton.mosaic.terminal.event/DeviceStatusReportEvent.data|{}data[0]
|
||||
final fun <get-data>(): kotlin/String // com.jakewharton.mosaic.terminal.event/DeviceStatusReportEvent.data.<get-data>|<get-data>(){}[0]
|
||||
|
||||
final fun equals(kotlin/Any?): kotlin/Boolean // com.jakewharton.mosaic.terminal.event/DeviceStatusReportEvent.equals|equals(kotlin.Any?){}[0]
|
||||
final fun hashCode(): kotlin/Int // com.jakewharton.mosaic.terminal.event/DeviceStatusReportEvent.hashCode|hashCode(){}[0]
|
||||
final fun toString(): kotlin/String // com.jakewharton.mosaic.terminal.event/DeviceStatusReportEvent.toString|toString(){}[0]
|
||||
}
|
||||
|
||||
final class com.jakewharton.mosaic.terminal.event/FocusEvent : com.jakewharton.mosaic.terminal.event/Event { // com.jakewharton.mosaic.terminal.event/FocusEvent|null[0]
|
||||
constructor <init>(kotlin/Boolean) // com.jakewharton.mosaic.terminal.event/FocusEvent.<init>|<init>(kotlin.Boolean){}[0]
|
||||
|
||||
@ -41,6 +52,17 @@ final class com.jakewharton.mosaic.terminal.event/PrimaryDeviceAttributesEvent :
|
||||
final fun toString(): kotlin/String // com.jakewharton.mosaic.terminal.event/PrimaryDeviceAttributesEvent.toString|toString(){}[0]
|
||||
}
|
||||
|
||||
final class com.jakewharton.mosaic.terminal.event/SystemThemeEvent : com.jakewharton.mosaic.terminal.event/Event { // com.jakewharton.mosaic.terminal.event/SystemThemeEvent|null[0]
|
||||
constructor <init>(kotlin/Boolean) // com.jakewharton.mosaic.terminal.event/SystemThemeEvent.<init>|<init>(kotlin.Boolean){}[0]
|
||||
|
||||
final val isDark // com.jakewharton.mosaic.terminal.event/SystemThemeEvent.isDark|{}isDark[0]
|
||||
final fun <get-isDark>(): kotlin/Boolean // com.jakewharton.mosaic.terminal.event/SystemThemeEvent.isDark.<get-isDark>|<get-isDark>(){}[0]
|
||||
|
||||
final fun equals(kotlin/Any?): kotlin/Boolean // com.jakewharton.mosaic.terminal.event/SystemThemeEvent.equals|equals(kotlin.Any?){}[0]
|
||||
final fun hashCode(): kotlin/Int // com.jakewharton.mosaic.terminal.event/SystemThemeEvent.hashCode|hashCode(){}[0]
|
||||
final fun toString(): kotlin/String // com.jakewharton.mosaic.terminal.event/SystemThemeEvent.toString|toString(){}[0]
|
||||
}
|
||||
|
||||
final class com.jakewharton.mosaic.terminal.event/UnknownEvent : com.jakewharton.mosaic.terminal.event/Event { // com.jakewharton.mosaic.terminal.event/UnknownEvent|null[0]
|
||||
constructor <init>(kotlin/String, kotlin/ByteArray) // com.jakewharton.mosaic.terminal.event/UnknownEvent.<init>|<init>(kotlin.String;kotlin.ByteArray){}[0]
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ package com.jakewharton.mosaic.terminal
|
||||
import com.jakewharton.mosaic.terminal.event.BracketedPasteEvent
|
||||
import com.jakewharton.mosaic.terminal.event.CodepointEvent
|
||||
import com.jakewharton.mosaic.terminal.event.DecModeReport
|
||||
import com.jakewharton.mosaic.terminal.event.DeviceStatusReportString
|
||||
import com.jakewharton.mosaic.terminal.event.DeviceStatusReportEvent
|
||||
import com.jakewharton.mosaic.terminal.event.Event
|
||||
import com.jakewharton.mosaic.terminal.event.FocusEvent
|
||||
import com.jakewharton.mosaic.terminal.event.KeyEscape
|
||||
@ -11,6 +11,7 @@ import com.jakewharton.mosaic.terminal.event.KittyGraphicsEvent
|
||||
import com.jakewharton.mosaic.terminal.event.MouseEvent
|
||||
import com.jakewharton.mosaic.terminal.event.PrimaryDeviceAttributesEvent
|
||||
import com.jakewharton.mosaic.terminal.event.ResizeEvent
|
||||
import com.jakewharton.mosaic.terminal.event.SystemThemeEvent
|
||||
import com.jakewharton.mosaic.terminal.event.UnknownEvent
|
||||
|
||||
private const val BufferSize = 8 * 1024
|
||||
@ -333,6 +334,38 @@ public class TerminalParser(
|
||||
)
|
||||
}
|
||||
|
||||
'n'.code -> {
|
||||
if (buffer[b3Index].toInt() == '?'.code) {
|
||||
val delimiter = buffer.indexOfOrDefault(';'.code.toByte(), start + 3, finalIndex, finalIndex)
|
||||
when (buffer.parseIntDigits(start + 3, delimiter)) {
|
||||
997 -> {
|
||||
if (delimiter + 2 == finalIndex) {
|
||||
val p2 = buffer[delimiter + 1].toInt()
|
||||
if (p2 == '1'.code) {
|
||||
return SystemThemeEvent(isDark = true)
|
||||
}
|
||||
if (p2 == '2'.code) {
|
||||
return SystemThemeEvent(isDark = false)
|
||||
}
|
||||
}
|
||||
return UnknownEvent(
|
||||
context = "CSI ? 997 ; p2 n sequence has invalid p2",
|
||||
bytes = buffer.copyOfRange(start, end),
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
return DeviceStatusReportEvent(
|
||||
data = buffer.decodeToString(start + 3, finalIndex),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
return UnknownEvent(
|
||||
context = "CSI .. n sequence without leading ?",
|
||||
bytes = buffer.copyOfRange(start, end),
|
||||
)
|
||||
}
|
||||
|
||||
'c'.code -> {
|
||||
if (buffer[b3Index].toInt() == '?'.code) {
|
||||
val data = buffer.decodeToString(start + 3, finalIndex)
|
||||
@ -417,7 +450,7 @@ public class TerminalParser(
|
||||
buffer[start + 2].toInt() == '>'.code &&
|
||||
buffer[start + 3].toInt() == '|'.code
|
||||
) {
|
||||
DeviceStatusReportString(
|
||||
DeviceStatusReportEvent(
|
||||
data = buffer.decodeToString(start + 4, stIndex),
|
||||
)
|
||||
} else {
|
||||
|
||||
@ -29,6 +29,8 @@ internal inline fun ByteArray.indexOfFirstOrElse(
|
||||
}
|
||||
|
||||
internal fun ByteArray.parseIntDigits(start: Int, end: Int): Int {
|
||||
// TODO This needs an orElse path for parsing failure on non-digits.
|
||||
|
||||
var value = 0
|
||||
for (i in start until end) {
|
||||
value *= 10
|
||||
|
||||
@ -84,8 +84,14 @@ public class PrimaryDeviceAttributesEvent(
|
||||
public val data: String,
|
||||
) : Event
|
||||
|
||||
internal data class DeviceStatusReportString(
|
||||
val data: String,
|
||||
@Poko
|
||||
public class DeviceStatusReportEvent(
|
||||
public val data: String,
|
||||
) : Event
|
||||
|
||||
@Poko
|
||||
public class SystemThemeEvent(
|
||||
public val isDark: Boolean,
|
||||
) : Event
|
||||
|
||||
internal data class KittyGraphicsEvent(
|
||||
|
||||
@ -0,0 +1,58 @@
|
||||
package com.jakewharton.mosaic.terminal
|
||||
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.isEqualTo
|
||||
import com.jakewharton.mosaic.terminal.event.SystemThemeEvent
|
||||
import com.jakewharton.mosaic.terminal.event.UnknownEvent
|
||||
import kotlin.test.AfterTest
|
||||
import kotlin.test.Test
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
class TerminalParserCsiSystemThemeEventTest {
|
||||
private val writer = Tty.stdinWriter()
|
||||
private val parser = TerminalParser(writer.reader, true)
|
||||
|
||||
@AfterTest fun after() {
|
||||
writer.close()
|
||||
}
|
||||
|
||||
@Test fun dark() {
|
||||
writer.writeHex("1b5b3f3939373b316e")
|
||||
assertThat(parser.next()).isEqualTo(SystemThemeEvent(isDark = true))
|
||||
}
|
||||
|
||||
@Test fun light() {
|
||||
writer.writeHex("1b5b3f3939373b326e")
|
||||
assertThat(parser.next()).isEqualTo(SystemThemeEvent(isDark = false))
|
||||
}
|
||||
|
||||
@Test fun missingP2() {
|
||||
writer.writeHex("1b5b3f3939373b6e")
|
||||
assertThat(parser.next()).isEqualTo(
|
||||
UnknownEvent(
|
||||
context = "CSI ? 997 ; p2 n sequence has invalid p2",
|
||||
bytes = "1b5b3f3939373b6e".hexToByteArray(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Test fun unknownP2() {
|
||||
writer.writeHex("1b5b3f3939373b346e")
|
||||
assertThat(parser.next()).isEqualTo(
|
||||
UnknownEvent(
|
||||
context = "CSI ? 997 ; p2 n sequence has invalid p2",
|
||||
bytes = "1b5b3f3939373b346e".hexToByteArray(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Test fun tooLongP2() {
|
||||
writer.writeHex("1b5b3f3939373b31316e")
|
||||
assertThat(parser.next()).isEqualTo(
|
||||
UnknownEvent(
|
||||
context = "CSI ? 997 ; p2 n sequence has invalid p2",
|
||||
bytes = "1b5b3f3939373b31316e".hexToByteArray(),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -75,6 +75,7 @@ private class RawModeEchoCommand : CliktCommand("raw-mode-echo") {
|
||||
}
|
||||
if (all || colorQuery) {
|
||||
print("\u001b[?996n") // Color scheme request
|
||||
print("\u001b[?2031h") // Color scheme enable
|
||||
}
|
||||
|
||||
val reader = Tty.stdinReader()
|
||||
|
||||
Reference in New Issue
Block a user