Skip to content

Commit b29bbb0

Browse files
committed
feat: added colors module for color handling
1 parent f056fee commit b29bbb0

8 files changed

Lines changed: 1302 additions & 0 deletions

File tree

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Two variants are available:
88

99
And then we have utility modules:
1010
- **[`ansiparser`](ansiparser/README.md)** — compact ANSI escape sequence parser
11+
- **[`colors`](colors/README.md)** — terminal colour palette querying and setting
1112
- **[`mousetrack`](mousetrack/README.md)** — terminal mouse-tracking helpers and event parser
1213
- **[`termcap`](termcap/README.md)** — terminal capability detection
1314

@@ -95,6 +96,16 @@ if (caps.colors() >= 256) {
9596
}
9697
```
9798

99+
### Query colors
100+
101+
```java
102+
Color bg = TermColors.queryBackground(terminal, () -> terminal.read(500));
103+
if (bg != null) {
104+
// luminance check for dark/light theme detection
105+
boolean dark = (0.299 * bg.r8() + 0.587 * bg.g8() + 0.114 * bg.b8()) < 128;
106+
}
107+
```
108+
98109
## Modules
99110

100111
Three artifacts are published independently:
@@ -106,6 +117,7 @@ Three artifacts are published independently:
106117
| [`ansiparser`](ansiparser/README.md) | Compact ANSI escape sequence parser, Java 8+ |
107118
| [`mousetrack`](mousetrack/README.md) | Terminal mouse-tracking helpers and event parser, Java 8+ |
108119
| [`termcap`](termcap/README.md) | Terminal capability detection, Java 8+ |
120+
| [`colors`](colors/README.md) | Terminal colour palette querying and setting via OSC sequences, Java 8+ |
109121

110122
For dependency coordinates (Maven, Gradle, JBang) and module-specific usage details, see the individual module READMEs linked above.
111123

colors/README.md

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
# colors
2+
3+
`colors` is a small Java 8+ library for querying and setting terminal colour palettes via OSC escape sequences, part of the [java-miniterm](../README.md) project.
4+
5+
It supports reading the full 256-entry palette in a single burst, querying the foreground/background/cursor colours, redefining palette entries, and resetting them to the profile defaults.
6+
7+
## Usage
8+
9+
### Query foreground and background
10+
11+
```java
12+
Color fg = TermColors.queryForeground(terminal, in);
13+
Color bg = TermColors.queryBackground(terminal, in);
14+
Color cursor = TermColors.queryCursor(terminal, in);
15+
16+
if (bg != null) {
17+
// luminance check for dark/light theme detection
18+
boolean dark = (0.299 * bg.r8() + 0.587 * bg.g8() + 0.114 * bg.b8()) < 128;
19+
}
20+
```
21+
22+
Returns `null` if the terminal does not respond within the timeout.
23+
24+
### Query a single palette entry
25+
26+
```java
27+
Color color1 = TermColors.queryColor(terminal, in, 1); // ANSI red
28+
```
29+
30+
### Query the full 256-entry palette (burst)
31+
32+
All 256 queries are sent at once; responses are collected until a read timeout indicates the terminal has no more data:
33+
34+
```java
35+
Color[] palette = TermColors.queryPalette(terminal, in);
36+
// palette[n] is null if the terminal did not respond for that index
37+
```
38+
39+
Query a specific subset:
40+
41+
```java
42+
// Query only the 16 ANSI colours
43+
int[] ansi16 = new int[16];
44+
for (int i = 0; i < 16; i++) ansi16[i] = i;
45+
Color[] result = TermColors.queryPalette(terminal, in, ansi16);
46+
```
47+
48+
### Set colours
49+
50+
```java
51+
TermColors.setForeground(terminal, Color.ofRgb8(220, 220, 220));
52+
TermColors.setBackground(terminal, Color.ofRgb8(30, 30, 30));
53+
TermColors.setCursor(terminal, Color.ofRgb8(255, 165, 0));
54+
55+
TermColors.setColor(terminal, 1, Color.ofRgb8(204, 0, 0)); // redefine ANSI red
56+
```
57+
58+
Set the full palette from an array (null entries are skipped):
59+
60+
```java
61+
Color[] palette = buildThemePalette(); // Color[256]
62+
TermColors.setPalette(terminal, palette);
63+
```
64+
65+
### Reset to profile defaults
66+
67+
```java
68+
TermColors.resetForeground(terminal); // OSC 110
69+
TermColors.resetBackground(terminal); // OSC 111
70+
TermColors.resetCursor(terminal); // OSC 112
71+
72+
TermColors.resetColor(terminal, 1); // reset single palette entry (OSC 104)
73+
TermColors.resetPalette(terminal); // reset all 256 entries (OSC 104)
74+
```
75+
76+
## Concepts
77+
78+
### `TermColors`
79+
80+
All methods are static. Query methods require the terminal in **raw mode** and an `IntReader` that returns negative values on timeout or EOF:
81+
82+
```java
83+
terminal.enableRawMode();
84+
IntReader in = () -> terminal.read(500); // 500 ms timeout per read
85+
```
86+
87+
### `Color`
88+
89+
An immutable 16-bit-per-channel RGB colour, matching the precision used in the X11 `rgb:` colour specification that terminals return in OSC responses.
90+
91+
```java
92+
Color red = Color.of(0xFFFF, 0x0000, 0x0000); // 16-bit channels
93+
Color green = Color.ofRgb8(0, 255, 0); // 8-bit, expanded
94+
Color blue = Color.parse("rgb:0000/0000/FFFF"); // from OSC string
95+
```
96+
97+
Conversion helpers:
98+
99+
```java
100+
color.r8() // red channel downsampled to 8 bits (0-255)
101+
color.toRgb8() // packed 0xRRGGBB int
102+
color.toString() // "rgb:RRRR/GGGG/BBBB" — ready for use in OSC sequences
103+
```
104+
105+
## OSC sequence reference
106+
107+
| Operation | Sequence |
108+
|---|---|
109+
| Query foreground | `OSC 10 ; ? BEL` |
110+
| Query background | `OSC 11 ; ? BEL` |
111+
| Query cursor colour | `OSC 12 ; ? BEL` |
112+
| Query palette entry *n* | `OSC 4 ; n ; ? BEL` |
113+
| Set foreground | `OSC 10 ; rgb:RRRR/GGGG/BBBB BEL` |
114+
| Set background | `OSC 11 ; rgb:RRRR/GGGG/BBBB BEL` |
115+
| Set cursor colour | `OSC 12 ; rgb:RRRR/GGGG/BBBB BEL` |
116+
| Set palette entry *n* | `OSC 4 ; n ; rgb:RRRR/GGGG/BBBB BEL` |
117+
| Reset foreground | `OSC 110 BEL` |
118+
| Reset background | `OSC 111 BEL` |
119+
| Reset cursor colour | `OSC 112 BEL` |
120+
| Reset palette entry *n* | `OSC 104 ; n BEL` |
121+
| Reset all palette entries | `OSC 104 BEL` |
122+
123+
## Dependency
124+
125+
### JBang
126+
127+
```java
128+
//DEPS org.codejive.miniterm:colors:0.1.1
129+
```
130+
131+
### Maven
132+
133+
```xml
134+
<dependency>
135+
<groupId>org.codejive.miniterm</groupId>
136+
<artifactId>colors</artifactId>
137+
<version>0.1.1</version>
138+
</dependency>
139+
```
140+
141+
### Gradle
142+
143+
```kotlin
144+
implementation("org.codejive.miniterm:colors:0.1.1")
145+
```
146+
147+
`colors` requires `ansiparser` (included transitively) for parsing OSC responses.

colors/pom.xml

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<parent>
8+
<groupId>org.codejive.miniterm</groupId>
9+
<artifactId>miniterm-parent</artifactId>
10+
<version>0.1.2-SNAPSHOT</version>
11+
</parent>
12+
13+
<artifactId>colors</artifactId>
14+
<name>colors</name>
15+
<description>Terminal colour palette querying and setting via OSC sequences</description>
16+
<url>https://github.com/codejive/miniterm</url>
17+
18+
<properties>
19+
<maven.compiler.release>8</maven.compiler.release>
20+
<javaModuleName>org.codejive.miniterm.colors</javaModuleName>
21+
</properties>
22+
23+
<dependencies>
24+
<dependency>
25+
<groupId>org.codejive.miniterm</groupId>
26+
<artifactId>ansiparser</artifactId>
27+
<version>${project.version}</version>
28+
</dependency>
29+
30+
<dependency>
31+
<groupId>org.junit.jupiter</groupId>
32+
<artifactId>junit-jupiter</artifactId>
33+
<scope>test</scope>
34+
</dependency>
35+
<dependency>
36+
<groupId>org.assertj</groupId>
37+
<artifactId>assertj-core</artifactId>
38+
<version>${version.assertj}</version>
39+
<scope>test</scope>
40+
</dependency>
41+
</dependencies>
42+
43+
<build>
44+
<plugins>
45+
<plugin>
46+
<groupId>org.apache.maven.plugins</groupId>
47+
<artifactId>maven-compiler-plugin</artifactId>
48+
<configuration>
49+
<release>8</release>
50+
</configuration>
51+
</plugin>
52+
<plugin>
53+
<groupId>org.apache.maven.plugins</groupId>
54+
<artifactId>maven-jar-plugin</artifactId>
55+
<configuration>
56+
<archive>
57+
<manifestEntries>
58+
<Automatic-Module-Name>${javaModuleName}</Automatic-Module-Name>
59+
</manifestEntries>
60+
<addMavenDescriptor>false</addMavenDescriptor>
61+
<index>false</index>
62+
</archive>
63+
</configuration>
64+
</plugin>
65+
<plugin>
66+
<groupId>com.diffplug.spotless</groupId>
67+
<artifactId>spotless-maven-plugin</artifactId>
68+
<configuration>
69+
<formats>
70+
<format>
71+
<includes>
72+
<include>**/*.md</include>
73+
<include>**/*.txt</include>
74+
<include>.gitignore</include>
75+
<include>.gitattributes</include>
76+
</includes>
77+
<excludes>
78+
<exclude>**/target/**</exclude>
79+
</excludes>
80+
<lineEndings>UNIX</lineEndings>
81+
<trimTrailingWhitespace />
82+
<endWithNewline />
83+
<indent>
84+
<spaces>true</spaces>
85+
<spacesPerTab>4</spacesPerTab>
86+
</indent>
87+
</format>
88+
</formats>
89+
<java>
90+
<includes>
91+
<include>src/main/java/**/*.java</include>
92+
<include>src/test/java/**/*.java</include>
93+
</includes>
94+
<googleJavaFormat>
95+
<version>${version.google-java-format}</version>
96+
<style>AOSP</style>
97+
</googleJavaFormat>
98+
<toggleOffOn />
99+
</java>
100+
</configuration>
101+
<executions>
102+
<execution>
103+
<phase>verify</phase>
104+
<goals>
105+
<goal>check</goal>
106+
</goals>
107+
</execution>
108+
</executions>
109+
</plugin>
110+
</plugins>
111+
</build>
112+
</project>

0 commit comments

Comments
 (0)