feat: add optional tab padding

This commit is contained in:
CJ van den Berg 2025-10-09 17:11:07 +02:00
parent 94adc72283
commit 52e29b7825
Signed by: neurocyte
GPG key ID: 8EB1E1BB660E3FB9

View file

@ -17,6 +17,10 @@ const default_min_tabs = 2;
const @"style.config" = struct { const @"style.config" = struct {
default_minimum_tabs_shown: usize = 2, default_minimum_tabs_shown: usize = 2,
padding: []const u8 = " ",
padding_left: usize = 2,
padding_right: usize = 1,
dirty_indicator: []const u8 = "", dirty_indicator: []const u8 = "",
dirty_indicator_fg: ?colors = null, dirty_indicator_fg: ?colors = null,
close_icon: []const u8 = "󰅖", close_icon: []const u8 = "󰅖",
@ -471,6 +475,7 @@ const Tab = struct {
const buffer_manager = tui.get_buffer_manager() orelse @panic("tabs no buffer manager"); const buffer_manager = tui.get_buffer_manager() orelse @panic("tabs no buffer manager");
const buffer_ = buffer_manager.buffer_from_ref(self.buffer_ref); const buffer_ = buffer_manager.buffer_from_ref(self.buffer_ref);
const is_dirty = if (buffer_) |buffer| buffer.is_dirty() else false; const is_dirty = if (buffer_) |buffer| buffer.is_dirty() else false;
self.render_padding(&btn.plane, .left);
if (self.tab_style.file_type_icon) if (buffer_) |buffer| if (buffer.file_type_icon) |icon| { if (self.tab_style.file_type_icon) if (buffer_) |buffer| if (buffer.file_type_icon) |icon| {
const color_: ?u24 = if (buffer.file_type_color) |color| if (!(color == 0xFFFFFF or color == 0x000000 or color == 0x000001)) color else null else null; const color_: ?u24 = if (buffer.file_type_color) |color| if (!(color == 0xFFFFFF or color == 0x000000 or color == 0x000001)) color else null else null;
if (color_) |color| if (color_) |color|
@ -492,6 +497,15 @@ const Tab = struct {
} else { } else {
_ = btn.plane.putstr(" ") catch {}; _ = btn.plane.putstr(" ") catch {};
} }
self.render_padding(&btn.plane, .right);
}
fn render_padding(self: *@This(), plane: *Plane, side: enum { left, right }) void {
var padding: usize = switch (side) {
.left => self.tab_style.padding_left,
.right => self.tab_style.padding_right,
};
while (padding > 0) : (padding -= 1) _ = plane.putstr(self.tab_style.padding) catch {};
} }
fn layout(self: *@This(), btn: *Button.State(@This())) Widget.Layout { fn layout(self: *@This(), btn: *Button.State(@This())) Widget.Layout {
@ -504,11 +518,12 @@ const Tab = struct {
} }
fn padding_len(plane: Plane, tab_style: Style, active: bool, dirty: bool) usize { fn padding_len(plane: Plane, tab_style: Style, active: bool, dirty: bool) usize {
const len_padding = plane.egc_chunk_width(tab_style.padding, 0, 1) * (tab_style.padding_left + tab_style.padding_right);
const len_file_icon: usize = if (tab_style.file_type_icon) 3 else 0; const len_file_icon: usize = if (tab_style.file_type_icon) 3 else 0;
const len_close_icon = plane.egc_chunk_width(tab_style.close_icon, 0, 1); const len_close_icon = plane.egc_chunk_width(tab_style.close_icon, 0, 1);
const len_dirty_indicator = if (dirty) plane.egc_chunk_width(tab_style.dirty_indicator, 0, 1) else 0; const len_dirty_indicator = if (dirty) plane.egc_chunk_width(tab_style.dirty_indicator, 0, 1) else 0;
const len_dirty_close = @max(len_close_icon, len_dirty_indicator) + 1; // +1 for the leading space const len_dirty_close = @max(len_close_icon, len_dirty_indicator) + 1; // +1 for the leading space
return len_file_icon + len_dirty_close + if (active) return len_padding + len_file_icon + len_dirty_close + if (active)
plane.egc_chunk_width(tab_style.active_left, 0, 1) + plane.egc_chunk_width(tab_style.active_left, 0, 1) +
plane.egc_chunk_width(tab_style.active_right, 0, 1) plane.egc_chunk_width(tab_style.active_right, 0, 1)
else else