mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
connect setAttribute
This commit is contained in:
@ -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 }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user