From 2868516c215a96d9e1e933ded7ac5744ec16c368 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Thu, 1 Oct 2026 19:20:19 -0300 Subject: Tab N sets a tab's width in cells, 1 through 16, in every pane, drawn and counted (wrapping, clicks, the cursor); bare Tab says it; the ctl read and a Dump keep it A session setting, not acme's per window: the width is read by File's pure width functions (~130 callers that are given no pane), so it is one value, config.tab_now, that Runtime.apply sets and a new session resets. A file:L:C column counts runes, as compilers do, and never depended on it. Co-Authored-By: Claude Opus 5.5 --- src/config.zig | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src/config.zig') diff --git a/src/config.zig b/src/config.zig index 375b4c69..89e5f813 100644 --- a/src/config.zig +++ b/src/config.zig @@ -61,6 +61,7 @@ pub const leader_path = paths: { .Get = null, .Putall = null, .Incl = null, + .Tab = null, .ClipYank = "y", .ClipYankMain = "Y", .ClipPaste = "p", @@ -405,6 +406,11 @@ pub const PREFIX_W: u16 = 5; pub const default_incl = [_][]const u8{ "/usr/include", "/usr/local/include" }; pub const tab_width: u16 = 4; +/// The width a tab is drawn and counted at now: `Tab N` (Runtime.tab) sets +/// it, a new session starts it at tab_width. ponytail: one for the process, +/// as the session's setting is one; per pane would mean handing a pane to +/// every width function (File.graphemeDisplayWidth and its ~130 callers). +pub var tab_now: u16 = tab_width; comptime { if (tab_width == 0) @compileError("config.tab_width must be greater than zero"); } @@ -802,6 +808,9 @@ pub const Runtime = struct { /// the focused pane's file first, other files only once those run out /// that way; `all`, every place in the order it was jumped to. jump_scope: JumpScope = .file, + /// acme's Tab: a tab's width in cells, in every pane (config.tab_now + /// is what the drawing and the column arithmetic read). + tab: u16 = tab_width, pub const ShaderAnimation = enum { off, on, always }; pub const Placement = enum { acme, pardes }; @@ -999,6 +1008,7 @@ pub const Runtime = struct { /// A percentage, 0 through 100. inactive_dim, grip_width, + tab, transition: animation.Transition, scene: Scene, /// A Shadertoy file into the post chain or out of it; `off` empties @@ -1082,6 +1092,7 @@ pub const Runtime = struct { .{ .word = "PagerColor", .action = .{ .toggle = .pager_color }, .doc = "A +Pager keeps its program's colours, on or off; for the next text paged." }, .{ .word = "TermImages", .action = .{ .choice = .term_images }, .doc = "How a new terminal draws its program's kitty graphics: real, as pixels where it can, or petscii, as glyph art." }, .{ .word = "JumpScope", .action = .{ .choice = .jump_scope }, .doc = "What Back and Forward keep to: file, the focused pane's file until it runs out that way, or all, every place in order." }, + .{ .word = "Tab", .action = .tab, .doc = "A tab's width in cells, 1 through 16, in every pane; bare, it says the width." }, }; pub fn find(name: []const u8) ?Setting { @@ -1282,6 +1293,13 @@ pub const Runtime = struct { if (percent < 50 or percent > 300) return false; state.grip_width = percent; }, + .tab => { + const text = std.mem.trim(u8, argument orelse return false, " \t\r\n"); + const width = std.fmt.parseInt(u16, text, 10) catch return false; + if (width < 1 or width > 16) return false; + state.tab = width; + tab_now = width; + }, .theme, .font => return false, } return true; @@ -1317,6 +1335,7 @@ pub const Runtime = struct { return choices(action) orelse switch (action) { .inactive_dim, .window_opacity, .window_blur => "0-100 (a percentage)", .grip_width => "50-300 (a percentage)", + .tab => "1-16 (cells)", .tagline_size => std.fmt.comptimePrint("{d}-{d} (a percentage)", .{ tagline_percent_min, tagline_percent_max }), .message_ms => std.fmt.comptimePrint("0-{d} (milliseconds)", .{message_ms_max}), .shell => "a path of at most 255 bytes; bare, $SHELL, else /bin/sh", @@ -1479,6 +1498,7 @@ pub const Runtime = struct { try out.print("# {s} unsupported\n", .{setting.word}), .motion => try out.print("{s} {s}\n", .{ setting.word, @tagName(state.motion) }), .inactive_dim => try out.print("{s} {d}\n", .{ setting.word, state.inactive_dim }), + .tab => try out.print("{s} {d}\n", .{ setting.word, state.tab }), .grip_width => if (setting.enabled(context.capabilities)) try out.print("{s} {d}\n", .{ setting.word, state.grip_width }) else @@ -1775,6 +1795,7 @@ pub const Runtime = struct { .motion => "playful", .inactive_dim => "35", .grip_width => "200", + .tab => "8", else => null, }; try std.testing.expect(apply(&state, setting, argument)); @@ -1849,6 +1870,7 @@ pub const Runtime = struct { .motion => "Motion playful\n", .inactive_dim => "InactiveDim 35\n", .grip_width => "GripWidth 200\n", + .tab => "Tab 8\n", .theme, .font => unreachable, }; try std.testing.expect(std.mem.indexOf(u8, report, expected) != null); -- cgit v1.3