connect setAttribute

This commit is contained in:
Mitchell Hashimoto
2022-05-12 16:34:38 -07:00
parent 8400b683c4
commit ccaf75193b
3 changed files with 55 additions and 32 deletions

View File

@ -584,3 +584,12 @@ pub fn setMode(self: *Window, mode: terminal.Mode, enabled: bool) !void {
else => if (enabled) log.warn("unimplemented mode: {}", .{mode}), else => if (enabled) log.warn("unimplemented mode: {}", .{mode}),
} }
} }
pub fn setAttribute(self: *Window, attr: terminal.Attribute) !void {
switch (attr) {
.unknown => |unk| log.warn("unimplemented or unknown attribute: {any}", .{unk}),
else => self.terminal.setAttribute(attr) catch |err|
log.warn("error setting attribute {}: {}", .{ attr, err }),
}
}

View File

@ -10,6 +10,7 @@ const testing = std.testing;
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const ansi = @import("ansi.zig"); const ansi = @import("ansi.zig");
const csi = @import("csi.zig"); const csi = @import("csi.zig");
const sgr = @import("sgr.zig");
const Tabstops = @import("Tabstops.zig"); const Tabstops = @import("Tabstops.zig");
const trace = @import("../tracy/tracy.zig").trace; const trace = @import("../tracy/tracy.zig").trace;
@ -52,7 +53,9 @@ const Cell = struct {
/// Each cell contains exactly one character. The character is UTF-8 encoded. /// Each cell contains exactly one character. The character is UTF-8 encoded.
char: u32, char: u32,
// TODO(mitchellh): this is where we'll track fg/bg and other attrs. /// Foreground and background color. null means to use the default.
fg: ?RGB = null,
bg: ?RGB = null,
/// True if the cell should be skipped for drawing /// True if the cell should be skipped for drawing
pub fn empty(self: Cell) bool { pub fn empty(self: Cell) bool {
@ -66,9 +69,14 @@ const Cursor = struct {
x: usize, x: usize,
y: usize, y: usize,
// Bold specifies that text written should be bold // pen is the current cell styling to apply to new cells.
// TODO: connect to render pen: Cell = .{ .char = 0 },
bold: bool = false, };
pub const RGB = struct {
r: u8,
g: u8,
b: u8,
}; };
/// Initialize a new terminal. /// Initialize a new terminal.
@ -125,15 +133,42 @@ pub fn plainString(self: Terminal, alloc: Allocator) ![]const u8 {
return buffer[0..i]; return buffer[0..i];
} }
/// TODO: test
pub fn setAttribute(self: *Terminal, attr: sgr.Attribute) !void {
switch (attr) {
.unset => {
self.cursor.pen.fg = null;
self.cursor.pen.bg = null;
},
.direct_color_fg => |rgb| {
self.cursor.pen.fg = .{
.r = rgb.r,
.g = rgb.g,
.b = rgb.g,
};
},
.direct_color_bg => |rgb| {
self.cursor.pen.bg = .{
.r = rgb.r,
.g = rgb.g,
.b = rgb.g,
};
},
else => return error.InvalidAttribute,
}
}
pub fn print(self: *Terminal, alloc: Allocator, c: u8) !void { pub fn print(self: *Terminal, alloc: Allocator, c: u8) !void {
const tracy = trace(@src()); const tracy = trace(@src());
defer tracy.end(); defer tracy.end();
// Build our cell // Build our cell
const cell = try self.getOrPutCell(alloc, self.cursor.x, self.cursor.y); const cell = try self.getOrPutCell(alloc, self.cursor.x, self.cursor.y);
cell.* = .{ cell.* = self.cursor.pen;
.char = @intCast(u32, c), cell.char = @intCast(u32, c);
};
// Move the cursor // Move the cursor
self.cursor.x += 1; self.cursor.x += 1;
@ -144,18 +179,6 @@ pub fn print(self: *Terminal, alloc: Allocator, c: u8) !void {
} }
} }
pub fn selectGraphicRendition(self: *Terminal, aspect: ansi.RenditionAspect) !void {
switch (aspect) {
.default => self.cursor.bold = false,
.bold => self.cursor.bold = true,
.default_fg => {}, // TODO
.default_bg => {}, // TODO
else => {
//log.warn("invalid or unimplemented rendition aspect: {}", .{aspect});
},
}
}
// TODO: test // TODO: test
pub fn reverseIndex(self: *Terminal, alloc: Allocator) !void { pub fn reverseIndex(self: *Terminal, alloc: Allocator) !void {
if (self.cursor.y == 0) if (self.cursor.y == 0)

View File

@ -3,6 +3,7 @@ const testing = std.testing;
const Parser = @import("Parser.zig"); const Parser = @import("Parser.zig");
const ansi = @import("ansi.zig"); const ansi = @import("ansi.zig");
const csi = @import("csi.zig"); const csi = @import("csi.zig");
const sgr = @import("sgr.zig");
const trace = @import("../tracy/tracy.zig").trace; const trace = @import("../tracy/tracy.zig").trace;
const log = std.log.scoped(.stream); const log = std.log.scoped(.stream);
@ -251,19 +252,9 @@ pub fn Stream(comptime Handler: type) type {
} else log.warn("unimplemented CSI callback: {}", .{action}), } else log.warn("unimplemented CSI callback: {}", .{action}),
// SGR - Select Graphic Rendition // SGR - Select Graphic Rendition
'm' => if (@hasDecl(T, "selectGraphicRendition")) { 'm' => if (@hasDecl(T, "setAttribute")) {
if (action.params.len == 0) { var p: sgr.Parser = .{ .params = action.params };
// No values defaults to code 0 while (p.next()) |attr| try self.handler.setAttribute(attr);
try self.handler.selectGraphicRendition(.default);
} else {
// Each parameter sets a separate aspect
for (action.params) |param| {
try self.handler.selectGraphicRendition(@intToEnum(
ansi.RenditionAspect,
param,
));
}
}
} else log.warn("unimplemented CSI callback: {}", .{action}), } else log.warn("unimplemented CSI callback: {}", .{action}),
// DECSTBM - Set Top and Bottom Margins // DECSTBM - Set Top and Bottom Margins