From a4e40c75671400e11eaaeecb83a0c01bbeb818ed Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 24 Nov 2025 13:59:50 -0800 Subject: [PATCH] set proper dirty state to redo viewport search --- src/renderer/generic.zig | 6 ++++++ src/terminal/render.zig | 15 ++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/renderer/generic.zig b/src/renderer/generic.zig index b1a0151a4..fb82efd8d 100644 --- a/src/renderer/generic.zig +++ b/src/renderer/generic.zig @@ -1126,6 +1126,12 @@ pub fn Renderer(comptime GraphicsAPI: type) type { // Update our terminal state try self.terminal_state.update(self.alloc, state.terminal); + // If our terminal state is dirty at all we need to redo + // the viewport search. + if (self.terminal_state.dirty != .false) { + state.terminal.flags.search_viewport_dirty = true; + } + // Get our scrollbar out of the terminal. We synchronize // the scrollbar read with frame data updates because this // naturally limits the number of calls to this method (it diff --git a/src/terminal/render.zig b/src/terminal/render.zig index 49fc5af71..8f4da12eb 100644 --- a/src/terminal/render.zig +++ b/src/terminal/render.zig @@ -656,15 +656,22 @@ pub const RenderState = struct { // of highlights is usually small, and this only happens on the // viewport outside of a locked area. Still, I'd love to see this // improved someday. + + // We need to track whether any row had a match so we can mark + // the dirty state. + var any_dirty: bool = false; + const row_data = self.row_data.slice(); const row_arenas = row_data.items(.arena); + const row_dirties = row_data.items(.dirty); const row_pins = row_data.items(.pin); const row_highlights_slice = row_data.items(.highlights); for ( row_arenas, row_pins, row_highlights_slice, - ) |*row_arena, row_pin, *row_highlights| { + row_dirties, + ) |*row_arena, row_pin, *row_highlights, *dirty| { for (hls) |hl| { const chunks_slice = hl.chunks.slice(); const nodes = chunks_slice.items(.node); @@ -688,9 +695,15 @@ pub const RenderState = struct { if (i == nodes.len - 1) hl.bot_x else self.cols - 1, }, ); + + dirty.* = true; + any_dirty = true; } } } + + // Mark our dirty state. + if (any_dirty and self.dirty == .false) self.dirty = .partial; } pub const StringMap = std.ArrayListUnmanaged(point.Coordinate);