-
Notifications
You must be signed in to change notification settings - Fork 321
feat(core): add indexed color (0-255) and OSC palette control #559
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- Extend RGBA class with colorType, index properties and fromIndex() method
- Add parseColor() support for 'ansi:N' format, numeric indices, and {index: N} objects
- Add indexToApproximateRgb() for converting indexed colors to RGB approximations
- Extend Zig Cell structure with fg/bg color type and index tracking
- Add indexed color ANSI escape sequence output (ESC[38;5;Nm / ESC[48;5;Nm)
- Add default color support (ESC[39m / ESC[49m)
- Add terminal palette set/reset methods for OSC 4/10/11/12 color control
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This pull request adds support for terminal indexed colors (0-255) and OSC-based palette control to enable dynamic terminal color modification. However, the implementation has a critical architectural issue: the color type metadata (indexed vs RGB vs default) is not transmitted across the FFI boundary between TypeScript and Zig, rendering the indexed color feature non-functional in practice.
Changes:
- Extended RGBA class with color type tracking (indexed, RGB, default) and added parsing support for numeric indices and "ansi:N" format
- Added OSC palette control methods for dynamically setting and resetting terminal colors
- Extended Zig buffer Cell struct with color type fields and updated renderer to output appropriate ANSI sequences based on color type
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/core/src/lib/RGBA.ts | Added color type tracking, indexed color support, and extended ColorInput type |
| packages/core/src/lib/terminal-palette.ts | Added OSC sequence methods for setting/resetting palette colors |
| packages/core/src/renderables/EditBufferRenderable.ts | Updated type annotations to use expanded ColorInput type |
| packages/core/src/zig/ansi.zig | Added ColorType enum, Color struct, and indexed color output functions |
| packages/core/src/zig/buffer.zig | Extended Cell and OptimizedBuffer with color type fields and added setCellWithColorType method |
| packages/core/src/zig/renderer.zig | Updated rendering logic to output indexed/default color ANSI codes based on cell color type |
Comments suppressed due to low confidence (1)
packages/core/src/zig/buffer.zig:925
- When creating Cell structs in drawChar and setCellWithAlphaBlending, the color type fields are not specified, causing them to default to .rgb with index 0. This means indexed and default colors passed from TypeScript will be converted to RGB during rendering. These methods need to either receive color type parameters or extract them from an extended FFI interface.
pub fn drawChar(
self: *OptimizedBuffer,
char: u32,
x: u32,
y: u32,
fg: RGBA,
bg: RGBA,
attributes: u32,
) !void {
if (!self.isPointInScissor(@intCast(x), @intCast(y))) return;
if (isRGBAWithAlpha(bg) or isRGBAWithAlpha(fg)) {
try self.setCellWithAlphaBlending(x, y, char, fg, bg, attributes);
} else {
self.set(x, y, Cell{
.char = char,
.fg = fg,
.bg = bg,
.attributes = attributes,
});
}
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
… add tests - Add FFI functions to pass color type + index metadata to Zig - Update buffer.ts to use new FFI when colors have type info - Add parseColor context param for correct default fg/bg handling - Add hex validation in normalizeHex() with clear error messages - Remove unused Zig Color struct - Add tests for OSC palette methods and indexed color parsing
Keep colorType/index through styled text, box borders/fills, and renderer background so ANSI palette theming (e.g. pywal) works consistently.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 22 out of 22 changed files in this pull request and generated 12 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Normalize colorType/index before passing to Zig and add RGBA coverage for default/indexed inputs.
Summary
Adds full support for terminal indexed colors (0-255) and OSC-based terminal palette control, enabling the use of the standard 256-color palette and dynamic color modification via ANSI/OSC escape sequences.
Makes this possible (with tools like pywal et al):

Changes
TypeScript (RGBA.ts)
COLOR_TYPE_RGB,COLOR_TYPE_INDEXED,COLOR_TYPE_DEFAULTconstantsRGBAclass withcolorType,indexpropertiesRGBA.fromIndex(index),RGBA.defaultForeground(),RGBA.defaultBackground()static methodsisIndexed(),isDefault(),isRgb()instance methodsindexToApproximateRgb()function with standard 256-color palette mappingColorInputtype to acceptstring | RGBA | IndexedColor | numberparseColor()to handle"ansi:N"format, numeric indices, and{index: N}objectsTypeScript (terminal-palette.ts) - OSC Palette Control
setPaletteColor(index, hex)- dynamically set any of the 256 palette colors (OSC 4)setForeground(hex)- set terminal default foreground color (OSC 10)setBackground(hex)- set terminal default background color (OSC 11)setCursorColor(hex)- set cursor color (OSC 12)resetPaletteColor(index)- reset palette color to terminal default (OSC 104)resetForeground()- reset foreground to default (OSC 110)resetBackground()- reset background to default (OSC 111)resetCursorColor()- reset cursor color to default (OSC 112)Zig (ansi.zig)
ColorTypeenum:rgb,indexed,defaultColorstruct combining RGBA with type and indexindexToApproximateRgba(),fgIndexedColorOutput(),bgIndexedColorOutput()fgDefaultOutput(),bgDefaultOutput()for default color resetZig (buffer.zig)
Cellstruct withfg_color_type,bg_color_type,fg_index,bg_indexOptimizedBufferZig (renderer.zig)
\x1b[38;5;Nm/\x1b[48;5;Nmfor indexed colors\x1b[39m/\x1b[49mfor default colorsUsage Examples
Indexed Colors
OSC Palette Control
Testing