feat: add highlight_columns initial basic implementation

closes #208
This commit is contained in:
CJ van den Berg 2025-04-08 23:14:27 +02:00
parent 5199dcdd27
commit 33d4eb044a
Signed by: neurocyte
GPG key ID: 8EB1E1BB660E3FB9
3 changed files with 41 additions and 0 deletions

View file

@ -10,6 +10,7 @@ enable_terminal_cursor: bool = true,
enable_terminal_color_scheme: bool = builtin.os.tag != .windows, enable_terminal_color_scheme: bool = builtin.os.tag != .windows,
highlight_current_line: bool = true, highlight_current_line: bool = true,
highlight_current_line_gutter: bool = true, highlight_current_line_gutter: bool = true,
highlight_columns: []const u8 = "",
whitespace_mode: []const u8 = "none", whitespace_mode: []const u8 = "none",
inline_diagnostics: bool = true, inline_diagnostics: bool = true,
animation_min_lag: usize = 0, //milliseconds animation_min_lag: usize = 0, //milliseconds

View file

@ -914,6 +914,7 @@ pub const Editor = struct {
match_idx: usize = 0, match_idx: usize = 0,
theme: *const Widget.Theme, theme: *const Widget.Theme,
hl_row: ?usize, hl_row: ?usize,
hl_cols: []const usize,
leading: bool = true, leading: bool = true,
cell_map: CellMap, cell_map: CellMap,
@ -965,6 +966,8 @@ pub const Editor = struct {
9 => .tab, 9 => .tab,
else => .character, 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) if (ctx.hl_row) |hl_row| if (hl_row == ctx.buf_row)
self_.render_line_highlight_cell(ctx.theme, c); self_.render_line_highlight_cell(ctx.theme, c);
self_.render_matches(&ctx.match_idx, 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; if (ctx.x >= view.cols) break;
var cell_ = n.cell_init(); var cell_ = n.cell_init();
const c_ = &cell_; 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) if (ctx.hl_row) |hl_row| if (hl_row == ctx.buf_row)
self_.render_line_highlight_cell(ctx.theme, c_); self_.render_line_highlight_cell(ctx.theme, c_);
self_.render_matches(&ctx.match_idx, ctx.theme, c_); self_.render_matches(&ctx.match_idx, ctx.theme, c_);
@ -1006,12 +1011,16 @@ pub const Editor = struct {
if (leaf.eol) { if (leaf.eol) {
if (ctx.buf_col >= view.col) { if (ctx.buf_col >= view.col) {
var c = ctx.self.render_eol(n); 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) if (ctx.hl_row) |hl_row| if (hl_row == ctx.buf_row)
self_.render_line_highlight_cell(ctx.theme, &c); self_.render_line_highlight_cell(ctx.theme, &c);
self_.render_matches(&ctx.match_idx, ctx.theme, &c); self_.render_matches(&ctx.match_idx, ctx.theme, &c);
self_.render_selections(ctx.theme, &c); self_.render_selections(ctx.theme, &c);
_ = n.putc(&c) catch {}; _ = n.putc(&c) catch {};
var term_cell = render_terminator(n, ctx.theme); 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) if (ctx.hl_row) |hl_row| if (hl_row == ctx.buf_row)
self_.render_line_highlight_cell(ctx.theme, &term_cell); self_.render_line_highlight_cell(ctx.theme, &term_cell);
_ = n.putc(&term_cell) catch {}; _ = n.putc(&term_cell) catch {};
@ -1036,11 +1045,25 @@ pub const Editor = struct {
break :blk null; break :blk null;
break :blk self.get_primary().cursor.row; break :blk self.get_primary().cursor.row;
} else null; } 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 = .{ var ctx_: ctx = .{
.self = self, .self = self,
.buf_row = self.view.row, .buf_row = self.view.row,
.theme = theme, .theme = theme,
.hl_row = hl_row, .hl_row = hl_row,
.hl_cols = hl_cols,
.cell_map = CellMap.init(self.allocator, self.view.rows, self.view.cols) catch @panic("OOM"), .cell_map = CellMap.init(self.allocator, self.view.rows, self.view.cols) catch @panic("OOM"),
}; };
defer ctx_.cell_map.deinit(self.allocator); defer ctx_.cell_map.deinit(self.allocator);
@ -1052,6 +1075,8 @@ pub const Editor = struct {
self.plane.set_base_style(theme.editor); self.plane.set_base_style(theme.editor);
self.plane.erase(); self.plane.erase();
for (hl_cols) |hl_col|
self.render_column_highlight(hl_col, theme) catch {};
if (hl_row) |_| if (hl_row) |_|
self.render_line_highlight(&self.get_primary().cursor, theme) catch {}; self.render_line_highlight(&self.get_primary().cursor, theme) catch {};
self.plane.home(); self.plane.home();
@ -1130,6 +1155,16 @@ pub const Editor = struct {
cell_map.set_yx(y, x, .{ .cursor = true, .cell_type = cell_type }); 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 { fn render_line_highlight(self: *Self, cursor: *const Cursor, theme: *const Widget.Theme) !void {
const row_min = self.view.row; const row_min = self.view.row;
const row_max = row_min + self.view.rows; 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); 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 { inline fn render_line_highlight_cell(_: *const Self, theme: *const Widget.Theme, cell: *Cell) void {
cell.set_style_bg(theme.editor_line_highlight); cell.set_style_bg(theme.editor_line_highlight);
} }

View file

@ -109,6 +109,7 @@ fn init(allocator: Allocator) InitError!*Self {
conf.top_bar = try allocator.dupe(u8, conf.top_bar); conf.top_bar = try allocator.dupe(u8, conf.top_bar);
conf.bottom_bar = try allocator.dupe(u8, conf.bottom_bar); conf.bottom_bar = try allocator.dupe(u8, conf.bottom_bar);
conf.include_files = try allocator.dupe(u8, conf.include_files); 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; if (build_options.gui) conf.enable_terminal_cursor = false;
const frame_rate: usize = @intCast(tp.env.get().num("frame-rate")); const frame_rate: usize = @intCast(tp.env.get().num("frame-rate"));