diff --git a/src/config.zig b/src/config.zig index 4d4a078..7d9c377 100644 --- a/src/config.zig +++ b/src/config.zig @@ -10,6 +10,7 @@ enable_terminal_cursor: bool = true, enable_terminal_color_scheme: bool = builtin.os.tag != .windows, highlight_current_line: bool = true, highlight_current_line_gutter: bool = true, +highlight_columns: []const u8 = "", whitespace_mode: []const u8 = "none", inline_diagnostics: bool = true, animation_min_lag: usize = 0, //milliseconds diff --git a/src/tui/editor.zig b/src/tui/editor.zig index cd29e72..41e21be 100644 --- a/src/tui/editor.zig +++ b/src/tui/editor.zig @@ -914,6 +914,7 @@ pub const Editor = struct { match_idx: usize = 0, theme: *const Widget.Theme, hl_row: ?usize, + hl_cols: []const usize, leading: bool = true, cell_map: CellMap, @@ -965,6 +966,8 @@ pub const Editor = struct { 9 => .tab, else => .character, }; + for (ctx.hl_cols) |hl_col| if (hl_col == ctx.buf_col) + self_.render_column_highlight_cell(ctx.theme, c); if (ctx.hl_row) |hl_row| if (hl_row == ctx.buf_row) self_.render_line_highlight_cell(ctx.theme, c); self_.render_matches(&ctx.match_idx, ctx.theme, c); @@ -989,6 +992,8 @@ pub const Editor = struct { if (ctx.x >= view.cols) break; var cell_ = n.cell_init(); const c_ = &cell_; + for (ctx.hl_cols) |hl_col| if (hl_col == ctx.buf_col) + self_.render_column_highlight_cell(ctx.theme, c); if (ctx.hl_row) |hl_row| if (hl_row == ctx.buf_row) self_.render_line_highlight_cell(ctx.theme, c_); self_.render_matches(&ctx.match_idx, ctx.theme, c_); @@ -1006,12 +1011,16 @@ pub const Editor = struct { if (leaf.eol) { if (ctx.buf_col >= view.col) { var c = ctx.self.render_eol(n); + for (ctx.hl_cols) |hl_col| if (hl_col == ctx.buf_col) + self_.render_column_highlight_cell(ctx.theme, &c); if (ctx.hl_row) |hl_row| if (hl_row == ctx.buf_row) self_.render_line_highlight_cell(ctx.theme, &c); self_.render_matches(&ctx.match_idx, ctx.theme, &c); self_.render_selections(ctx.theme, &c); _ = n.putc(&c) catch {}; var term_cell = render_terminator(n, ctx.theme); + for (ctx.hl_cols) |hl_col| if (hl_col == ctx.buf_col + 1) + self_.render_column_highlight_cell(ctx.theme, &term_cell); if (ctx.hl_row) |hl_row| if (hl_row == ctx.buf_row) self_.render_line_highlight_cell(ctx.theme, &term_cell); _ = n.putc(&term_cell) catch {}; @@ -1036,11 +1045,25 @@ pub const Editor = struct { break :blk null; break :blk self.get_primary().cursor.row; } else null; + const highlight_columns = tui.config().highlight_columns; + var highlight_columns_buf: [6]usize = undefined; + const hl_cols: []const usize = if (highlight_columns.len > 0) blk: { + var idx: usize = 0; + var it = std.mem.splitScalar(u8, highlight_columns, ' '); + while (it.next()) |arg| { + var col = std.fmt.parseInt(usize, arg, 10) catch 1; + if (col > 0) col -= 1; + highlight_columns_buf[idx] = col; + idx += 1; + } + break :blk highlight_columns_buf[0..idx]; + } else &.{}; var ctx_: ctx = .{ .self = self, .buf_row = self.view.row, .theme = theme, .hl_row = hl_row, + .hl_cols = hl_cols, .cell_map = CellMap.init(self.allocator, self.view.rows, self.view.cols) catch @panic("OOM"), }; defer ctx_.cell_map.deinit(self.allocator); @@ -1052,6 +1075,8 @@ pub const Editor = struct { self.plane.set_base_style(theme.editor); self.plane.erase(); + for (hl_cols) |hl_col| + self.render_column_highlight(hl_col, theme) catch {}; if (hl_row) |_| self.render_line_highlight(&self.get_primary().cursor, theme) catch {}; self.plane.home(); @@ -1130,6 +1155,16 @@ pub const Editor = struct { cell_map.set_yx(y, x, .{ .cursor = true, .cell_type = cell_type }); } + fn render_column_highlight(self: *Self, col: usize, theme: *const Widget.Theme) !void { + for (0..self.view.rows) |row| { + self.plane.cursor_move_yx(@intCast(row), @intCast(col)) catch return; + var cell = self.plane.cell_init(); + _ = self.plane.at_cursor_cell(&cell) catch return; + self.render_column_highlight_cell(theme, &cell); + _ = self.plane.putc(&cell) catch {}; + } + } + fn render_line_highlight(self: *Self, cursor: *const Cursor, theme: *const Widget.Theme) !void { const row_min = self.view.row; const row_max = row_min + self.view.rows; @@ -1235,6 +1270,10 @@ pub const Editor = struct { cell.set_style_bg(if (match.style) |style| style else theme.editor_match); } + inline fn render_column_highlight_cell(_: *const Self, theme: *const Widget.Theme, cell: *Cell) void { + cell.set_style_bg(theme.editor_line_highlight); + } + inline fn render_line_highlight_cell(_: *const Self, theme: *const Widget.Theme, cell: *Cell) void { cell.set_style_bg(theme.editor_line_highlight); } diff --git a/src/tui/tui.zig b/src/tui/tui.zig index 8bd8cbd..4229f0c 100644 --- a/src/tui/tui.zig +++ b/src/tui/tui.zig @@ -109,6 +109,7 @@ fn init(allocator: Allocator) InitError!*Self { conf.top_bar = try allocator.dupe(u8, conf.top_bar); conf.bottom_bar = try allocator.dupe(u8, conf.bottom_bar); conf.include_files = try allocator.dupe(u8, conf.include_files); + conf.highlight_columns = try allocator.dupe(u8, conf.highlight_columns); if (build_options.gui) conf.enable_terminal_cursor = false; const frame_rate: usize = @intCast(tp.env.get().num("frame-rate"));