terminal/new: store full style id

This commit is contained in:
Mitchell Hashimoto
2024-02-20 08:37:33 -08:00
parent dc6de51472
commit c44bc54daf
5 changed files with 34 additions and 8 deletions

View File

@ -7,6 +7,8 @@ const unicode = @import("../../unicode/main.zig");
const PageList = @import("PageList.zig");
const pagepkg = @import("page.zig");
const point = @import("point.zig");
const size = @import("size.zig");
const style = @import("style.zig");
const Page = pagepkg.Page;
/// The general purpose allocator to use for all memory allocations.
@ -29,6 +31,12 @@ const Cursor = struct {
/// next character print will force a soft-wrap.
pending_wrap: bool = false,
/// The currently active style. The style is page-specific so when
/// we change pages we need to ensure that we update that page with
/// our style when used.
style_id: style.Id = style.default_id,
style_ref: ?*size.CellCountInt = null,
/// The pointers into the page list where the cursor is currently
/// located. This makes it faster to move the cursor.
page_offset: PageList.RowOffset,

View File

@ -20,6 +20,7 @@ const color = @import("../color.zig");
const mouse_shape = @import("../mouse_shape.zig");
const pagepkg = @import("page.zig");
const style = @import("style.zig");
const Screen = @import("Screen.zig");
const Cell = pagepkg.Cell;
const Row = pagepkg.Row;
@ -303,9 +304,15 @@ fn printCell(self: *Terminal, unmapped_c: u21) void {
//if (cell.attrs.grapheme) row.clearGraphemes(self.screen.cursor.x);
// Write
self.screen.cursor.page_cell.* = .{ .codepoint = c };
//cell.* = self.screen.cursor.pen;
//cell.char = @intCast(c);
self.screen.cursor.page_cell.* = .{
.style_id = self.screen.cursor.style_id,
.codepoint = c,
};
// If we have non-default style then we need to update the ref count.
if (self.screen.cursor.style_ref) |ref| {
ref.* += 1;
}
}
/// Return the current string value of the terminal. Newlines are

View File

@ -175,7 +175,9 @@ pub const Page = struct {
}
};
pub const Row = packed struct(u18) {
pub const Row = packed struct(u64) {
_padding: u30 = 0,
/// The cells in the row offset from the page.
cells: Offset(Cell),
@ -195,9 +197,10 @@ pub const Row = packed struct(u18) {
///
/// The zero value of this struct must be a valid cell representing empty,
/// since we zero initialize the backing memory for a page.
pub const Cell = packed struct(u32) {
pub const Cell = packed struct(u64) {
style_id: style.Id = 0,
codepoint: u21 = 0,
_padding: u11 = 0,
_padding: u27 = 0,
/// Returns true if the set of cells has text in it.
pub fn hasText(cells: []const Cell) bool {

View File

@ -5,7 +5,7 @@ const assert = std.debug.assert;
/// smaller bit size by Zig is upgraded anyways to a u16 on mainstream
/// CPU architectures, and because 65KB is a reasonable page size. To
/// support better configurability, we derive everything from this.
pub const max_page_size = 65_536;
pub const max_page_size = std.math.maxInt(u32);
/// The int type that can contain the maximum memory offset in bytes,
/// derived from the maximum terminal page size.
@ -138,7 +138,7 @@ test "Offset" {
// This test is here so that if Offset changes, we can be very aware
// of this effect and think about the implications of it.
const testing = std.testing;
try testing.expect(OffsetInt == u16);
try testing.expect(OffsetInt == u32);
}
test "Offset ptr u8" {

View File

@ -2,6 +2,7 @@ const std = @import("std");
const assert = std.debug.assert;
const color = @import("../color.zig");
const sgr = @import("../sgr.zig");
const page = @import("page.zig");
const size = @import("size.zig");
const Offset = size.Offset;
const OffsetBuf = size.OffsetBuf;
@ -12,6 +13,9 @@ const AutoOffsetHashMap = hash_map.AutoOffsetHashMap;
/// that can fit into a terminal page.
pub const Id = size.CellCountInt;
/// The Id to use for default styling.
pub const default_id: Id = 0;
/// The style attributes for a cell.
pub const Style = struct {
/// Various colors, all self-explanatory.
@ -82,6 +86,10 @@ pub const Set = struct {
/// When this overflows we'll begin returning an IdOverflow
/// error and the caller must manually compact the style
/// set.
///
/// Id zero is reserved and always is the default style. The
/// default style isn't present in the map, its dependent on
/// the terminal configuration.
next_id: Id = 1,
/// Maps a style definition to metadata about that style.