I’m relatively new to Zig and am working on an ANSI escape sequence module for easy terminal coloring, styling, etc. Basic sequences are just const values, but parameterized sequences (e.g. RGB, cursor movement) are created via functions, which currently use bufPrint to format the output.
Here are my foreground RGB/Hex functions (in a file called color.zig):
pub const csi = "\x1b[";
pub fn rgb(r: u8, g: u8, b: u8) []const u8 {
var buf: [25]u8 = undefined;
return std.fmt.bufPrint(&buf, csi ++ "38;2;{d};{d};{d}m", .{ r, g, b }) catch unreachable;
}
pub fn hex(hexcode: u24) []const u8 {
var buf: [25]u8 = undefined;
const r: u8 = @intCast((hexcode & 0xff0000) >> 16);
const g: u8 = @intCast((hexcode & 0x00ff00) >> 8);
const b: u8 = @intCast(hexcode & 0x0000ff);
return std.fmt.bufPrint(&buf, csi ++ "38;2;{d};{d};{d}m", .{ r, g, b }) catch unreachable;
}
This works as expected in most cases but acts strange with the following code (in main.zig, rgb and hex fn’s are imported):
const reset = "\x1b[0m";
const rgb = color.fg.rgb(234, 126, 19);
const hex = color.fg.hex(0xea7e13);
try unbuf_stdout.print("{s}rgb{s}\n", .{rgb, reset});
try unbuf_stdout.print("{s}hex{s}\n", .{hex, reset});
Here’s the weird output:

If I comment out the rgb or hex lines, the correct foreground coloring is output.
It feels like there’s something about the buffers that I’m failing to understand, is there some overlap happening or something? I’m also open to alternative suggestions if there’s a better way to do this. Thank you!
UPDATE:
Changing the order of the print statements results in expected output:
// This results in expected output
const reset = "\x1b[0m";
const rgb = color.fg.rgb(234, 126, 19);
try unbuf_stdout.print("{s}rgb{s}\n", .{rgb, reset});
const hex = color.fg.hex(0xea7e13);
try unbuf_stdout.print("{s}hex{s}\n", .{hex, reset});
// This results in the same first line as the weird output,
// but the second line is colored correctly
const reset = "\x1b[0m";
const rgb = color.fg.rgb(234, 126, 19);
const hex = color.fg.hex(0xea7e13);
try unbuf_stdout.print("{s}rgb{s}\n{s}hex{s}\n", .{rgb, reset, hex, reset});
What’s the scoop here? Appreciate the help o7