diff options
| author | Gabriel Schneider <[email protected]> | 2026-06-21 18:46:33 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-06-21 22:07:05 -0300 |
| commit | ef5b907d3077c1d00e5468f3b3c4935b3f51b923 (patch) | |
| tree | 64236abcb6d9da1347fb54cc98563878dc5d1839 | |
| parent | 48cdaa01f2024e92109daa0bfbf0653588215c5f (diff) | |
| download | pardes-ef5b907d3077c1d00e5468f3b3c4935b3f51b923.tar.gz pardes-ef5b907d3077c1d00e5468f3b3c4935b3f51b923.zip | |
colors now?
| -rw-r--r-- | main.zig | 149 |
1 files changed, 138 insertions, 11 deletions
@@ -174,6 +174,61 @@ fn loadFile( rendered_lines.* = splitLines(lines, text); } +fn ghostColor(color: ghostty_vt.Style.Color) vaxis.Color { + return switch (color) { + .none => .default, + .palette => |idx| .{ .index = idx }, + .rgb => |rgb| .{ .rgb = .{ rgb.r, rgb.g, rgb.b } }, + }; +} + +fn cellStyle(cell_info: ghostty_vt.PageList.Cell) vaxis.Style { + const style = cell_info.style(); + var vstyle: vaxis.Style = .{}; + vstyle.fg = ghostColor(style.fg_color); + vstyle.bg = ghostColor(style.bg_color); + vstyle.bold = style.flags.bold; + vstyle.dim = style.flags.faint; + vstyle.italic = style.flags.italic; + vstyle.blink = style.flags.blink; + vstyle.reverse = style.flags.inverse; + vstyle.invisible = style.flags.invisible; + vstyle.strikethrough = style.flags.strikethrough; + vstyle.ul_style = switch (style.flags.underline) { + .none => .off, + .single => .single, + .double => .double, + .curly => .curly, + .dotted => .dotted, + .dashed => .dashed, + }; + + switch (cell_info.cell.content_tag) { + .bg_color_palette => vstyle.bg = .{ .index = cell_info.cell.content.color_palette.data }, + .bg_color_rgb => { + const rgb = cell_info.cell.content.color_rgb; + vstyle.bg = .{ .rgb = .{ rgb.r, rgb.g, rgb.b } }; + }, + else => {}, + } + + return vstyle; +} + +fn appendCp(buf: *[MAX_LINE_LEN]u8, len: *usize, cp: u21) void { + if (cp == 0) { + if (len.* < buf.len) { + buf[len.*] = ' '; + len.* += 1; + } + return; + } + + if (len.* + 4 > buf.len) return; + const n = std.unicode.utf8Encode(cp, buf[len.*..]) catch return; + len.* += n; +} + const nrows = 64; const ncols = 100; @@ -192,6 +247,7 @@ pub fn main(init: std.process.Init) !void { var tty_buf: [0x10000]u8 = undefined; var display_lines: [2][MAX_LINES][MAX_LINE_LEN]u8 = undefined; + var tty_render_lines: [MAX_LINES][MAX_LINE_LEN]u8 = undefined; var rendered_lines = [_]usize{ 0, 0 }; var line_nums: [MAX_LINES][8]u8 = undefined; var file_scroll: usize = 0; @@ -242,6 +298,10 @@ pub fn main(init: std.process.Init) !void { defer _ = pty_reader.cancel(io) catch {}; defer pty_master.close(io); + var mouse_seen = false; + var mouse_row: i16 = 0; + var mouse_col: i16 = 0; + while (true) { const event = try loop.nextEvent(); const win = vx.window(); @@ -249,6 +309,10 @@ pub fn main(init: std.process.Init) !void { const right_x: i16 = @intCast(left_outer_width); switch (event) { .mouse => |mouse| { + mouse_seen = true; + mouse_row = mouse.row; + mouse_col = mouse.col; + const mouse_on_left = mouse.col < right_x; if (mouse.button == .wheel_down) { @@ -271,12 +335,14 @@ pub fn main(init: std.process.Init) !void { var selected_word: ?[]const u8 = null; if (mouse_on_left) { - const line_idx = @as(usize, @intCast(@max(mouse.row, 0))) + file_scroll; - if (line_idx < rendered_lines[FILE_PANE] and mouse.col >= 5) { - const len = std.mem.findSentinel(u8, 0, @ptrCast(&display_lines[FILE_PANE][line_idx])); - const selected_col: usize = @intCast(mouse.col - 5); - const selected_line = display_lines[FILE_PANE][line_idx][0..len]; - selected_word = extractWord(selected_line, selected_col); + if (mouse.row > 0 and mouse.col >= 5) { + const line_idx = @as(usize, @intCast(mouse.row - 1)) + file_scroll; + if (line_idx < rendered_lines[FILE_PANE]) { + const len = std.mem.findSentinel(u8, 0, @ptrCast(&display_lines[FILE_PANE][line_idx])); + const selected_col: usize = @intCast(mouse.col - 5); + const selected_line = display_lines[FILE_PANE][line_idx][0..len]; + selected_word = extractWord(selected_line, selected_col); + } } } else { const line_idx: usize = @intCast(@max(mouse.row, 0)); @@ -421,14 +487,75 @@ pub fn main(init: std.process.Init) !void { } i = 0; - while (i < win_term.height and i < rendered_lines[TTY_PANE]) : (i += 1) { - const len = std.mem.findSentinel(u8, 0, @ptrCast(&display_lines[TTY_PANE][i])); - _ = win_term.printSegment(.{ .text = display_lines[TTY_PANE][i][0..len] }, .{ - .row_offset = @intCast(i), + while (i < win_term.height and i < MAX_LINES) : (i += 1) { + var len: usize = 0; + var span_start: usize = 0; + var span_col: usize = 0; + var span_style: vaxis.Style = .{}; + var span_open = false; + + var col: usize = 0; + while (col < win_term.width and col < ncols and len < MAX_LINE_LEN - 4) : (col += 1) { + const cell_info = term.screens.active.pages.getCell(.{ .viewport = .{ + .x = @intCast(col), + .y = @intCast(i), + } }) orelse continue; + + if (cell_info.cell.wide == .spacer_tail) continue; + + const style = cellStyle(cell_info); + if (!span_open) { + span_open = true; + span_start = len; + span_col = col; + span_style = style; + } else if (!vaxis.Style.eql(span_style, style)) { + _ = win_term.printSegment(.{ + .text = tty_render_lines[i][span_start..len], + .style = span_style, + }, .{ + .row_offset = @intCast(i), + .col_offset = @intCast(span_col), + .wrap = .none, + }); + span_start = len; + span_col = col; + span_style = style; + } + + switch (cell_info.cell.content_tag) { + .codepoint, .codepoint_grapheme => { + appendCp(&tty_render_lines[i], &len, cell_info.cell.codepoint()); + if (cell_info.cell.hasGrapheme()) { + if (cell_info.node.data.lookupGrapheme(cell_info.cell)) |grapheme| { + for (grapheme) |cp| appendCp(&tty_render_lines[i], &len, cp); + } + } + }, + .bg_color_palette, .bg_color_rgb => appendCp(&tty_render_lines[i], &len, ' '), + } + } + + if (span_open and len > span_start) { + _ = win_term.printSegment(.{ + .text = tty_render_lines[i][span_start..len], + .style = span_style, + }, .{ + .row_offset = @intCast(i), + .col_offset = @intCast(span_col), + .wrap = .none, + }); + } + } + win_term.showCursor(term.screens.active.cursor.x, term.screens.active.cursor.y); + + if (mouse_seen and mouse_row >= 0 and mouse_col >= 0 and mouse_row < win.height and mouse_col < win.width) { + _ = win.printSegment(.{ .text = "@", .style = .{ .reverse = true, .bold = true } }, .{ + .row_offset = @intCast(mouse_row), + .col_offset = @intCast(mouse_col), .wrap = .none, }); } - win_term.showCursor(term.screens.active.cursor.x, term.screens.active.cursor.y); try vx.render(tty.writer()); } |
