From c44bc54dafb630869f893ed87187bef3b3cf9480 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 20 Feb 2024 08:37:33 -0800 Subject: [PATCH] terminal/new: store full style id --- src/terminal/new/Screen.zig | 8 ++++++++ src/terminal/new/Terminal.zig | 13 ++++++++++--- src/terminal/new/page.zig | 9 ++++++--- src/terminal/new/size.zig | 4 ++-- src/terminal/new/style.zig | 8 ++++++++ 5 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/terminal/new/Screen.zig b/src/terminal/new/Screen.zig index 4675bfbcd..69680071b 100644 --- a/src/terminal/new/Screen.zig +++ b/src/terminal/new/Screen.zig @@ -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, diff --git a/src/terminal/new/Terminal.zig b/src/terminal/new/Terminal.zig index 111723fb1..a7cf7ecfd 100644 --- a/src/terminal/new/Terminal.zig +++ b/src/terminal/new/Terminal.zig @@ -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 diff --git a/src/terminal/new/page.zig b/src/terminal/new/page.zig index 8d1bda336..4f6be3a8f 100644 --- a/src/terminal/new/page.zig +++ b/src/terminal/new/page.zig @@ -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 { diff --git a/src/terminal/new/size.zig b/src/terminal/new/size.zig index 092dcd72d..977fe54d2 100644 --- a/src/terminal/new/size.zig +++ b/src/terminal/new/size.zig @@ -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" { diff --git a/src/terminal/new/style.zig b/src/terminal/new/style.zig index 668e9f7c8..3de581676 100644 --- a/src/terminal/new/style.zig +++ b/src/terminal/new/style.zig @@ -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.