feat: add line number styles
This commit is contained in:
		
							parent
							
								
									c4986d5900
								
							
						
					
					
						commit
						b3a10d7346
					
				
					 4 changed files with 88 additions and 8 deletions
				
			
		| 
						 | 
				
			
			@ -5,6 +5,7 @@ theme: []const u8 = "default",
 | 
			
		|||
input_mode: []const u8 = "flow",
 | 
			
		||||
gutter_line_numbers: bool = true,
 | 
			
		||||
gutter_line_numbers_relative: bool = false,
 | 
			
		||||
gutter_line_numbers_style: LineNumberStyle = .ascii,
 | 
			
		||||
gutter_symbols: bool = true,
 | 
			
		||||
enable_terminal_cursor: bool = true,
 | 
			
		||||
enable_terminal_color_scheme: bool = builtin.os.tag != .windows,
 | 
			
		||||
| 
						 | 
				
			
			@ -25,3 +26,10 @@ bottom_bar: []const u8 = "mode file log selection diagnostics keybind linenumber
 | 
			
		|||
lsp_request_timeout: usize = 10,
 | 
			
		||||
 | 
			
		||||
include_files: []const u8 = "",
 | 
			
		||||
 | 
			
		||||
pub const LineNumberStyle = enum {
 | 
			
		||||
    ascii,
 | 
			
		||||
    digital,
 | 
			
		||||
    subscript,
 | 
			
		||||
    superscript,
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -99,6 +99,7 @@
 | 
			
		|||
            ["alt+down", "pull_down"],
 | 
			
		||||
            ["alt+enter", "insert_line"],
 | 
			
		||||
            ["alt+f10", "gutter_mode_next"],
 | 
			
		||||
            ["alt+shift+f10", "gutter_style_next"],
 | 
			
		||||
            ["alt+f12", "goto_declaration"],
 | 
			
		||||
            ["alt+shift+p", "open_command_palette"],
 | 
			
		||||
            ["alt+shift+d", "dupe_up"],
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,6 +16,7 @@ const Widget = @import("Widget.zig");
 | 
			
		|||
const MessageFilter = @import("MessageFilter.zig");
 | 
			
		||||
const tui = @import("tui.zig");
 | 
			
		||||
const ed = @import("editor.zig");
 | 
			
		||||
const LineNumberStyle = @import("config").LineNumberStyle;
 | 
			
		||||
 | 
			
		||||
allocator: Allocator,
 | 
			
		||||
plane: Plane,
 | 
			
		||||
| 
						 | 
				
			
			@ -27,6 +28,7 @@ row: u32 = 1,
 | 
			
		|||
line: usize = 0,
 | 
			
		||||
linenum: bool,
 | 
			
		||||
relative: bool,
 | 
			
		||||
render_style: LineNumberStyle,
 | 
			
		||||
highlight: bool,
 | 
			
		||||
symbols: bool,
 | 
			
		||||
width: usize = 4,
 | 
			
		||||
| 
						 | 
				
			
			@ -47,6 +49,7 @@ pub fn create(allocator: Allocator, parent: Widget, event_source: Widget, editor
 | 
			
		|||
        .parent = parent,
 | 
			
		||||
        .linenum = tui.config().gutter_line_numbers,
 | 
			
		||||
        .relative = tui.config().gutter_line_numbers_relative,
 | 
			
		||||
        .render_style = tui.config().gutter_line_numbers_style,
 | 
			
		||||
        .highlight = tui.config().highlight_current_line_gutter,
 | 
			
		||||
        .symbols = tui.config().gutter_symbols,
 | 
			
		||||
        .editor = editor,
 | 
			
		||||
| 
						 | 
				
			
			@ -93,6 +96,8 @@ pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool {
 | 
			
		|||
 | 
			
		||||
    if (try m.match(.{ "B", input.event.press, @intFromEnum(input.mouse.BUTTON1), tp.any, tp.any, tp.extract(&y), tp.any, tp.extract(&ypx) }))
 | 
			
		||||
        return self.primary_click(y);
 | 
			
		||||
    if (try m.match(.{ "B", input.event.press, @intFromEnum(input.mouse.BUTTON2), tp.any, tp.any, tp.extract(&y), tp.any, tp.extract(&ypx) }))
 | 
			
		||||
        return self.middle_click();
 | 
			
		||||
    if (try m.match(.{ "B", input.event.press, @intFromEnum(input.mouse.BUTTON3), tp.any, tp.any, tp.extract(&y), tp.any, tp.extract(&ypx) }))
 | 
			
		||||
        return self.secondary_click();
 | 
			
		||||
    if (try m.match(.{ "D", input.event.press, @intFromEnum(input.mouse.BUTTON1), tp.any, tp.any, tp.extract(&y), tp.any, tp.extract(&ypx) }))
 | 
			
		||||
| 
						 | 
				
			
			@ -107,9 +112,8 @@ pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool {
 | 
			
		|||
 | 
			
		||||
fn update_width(self: *Self) void {
 | 
			
		||||
    if (!self.linenum) return;
 | 
			
		||||
    var buf: [31]u8 = undefined;
 | 
			
		||||
    const tmp = std.fmt.bufPrint(&buf, "{d}", .{self.lines}) catch return;
 | 
			
		||||
    self.width = if (self.relative and tmp.len > 4) 4 else @max(tmp.len, 2);
 | 
			
		||||
    const width = int_width(self.lines);
 | 
			
		||||
    self.width = if (self.relative and width > 4) 4 else @max(width, 2);
 | 
			
		||||
    self.width += if (self.symbols) 3 else 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -163,7 +167,6 @@ pub fn render_linear(self: *Self, theme: *const Widget.Theme) void {
 | 
			
		|||
    var linenum = self.row + 1;
 | 
			
		||||
    var rows = self.rows;
 | 
			
		||||
    var diff_symbols = self.diff_symbols.items;
 | 
			
		||||
    var buf: [31:0]u8 = undefined;
 | 
			
		||||
    while (rows > 0) : (rows -= 1) {
 | 
			
		||||
        if (linenum > self.lines) return;
 | 
			
		||||
        if (linenum == self.line + 1) {
 | 
			
		||||
| 
						 | 
				
			
			@ -173,7 +176,8 @@ pub fn render_linear(self: *Self, theme: *const Widget.Theme) void {
 | 
			
		|||
            self.plane.set_style(.{ .fg = theme.editor_gutter.fg });
 | 
			
		||||
            self.plane.off_styles(style.bold);
 | 
			
		||||
        }
 | 
			
		||||
        _ = self.plane.print_aligned_right(@intCast(pos), "{s}", .{std.fmt.bufPrintZ(&buf, "{d} ", .{linenum}) catch return}) catch {};
 | 
			
		||||
        try self.plane.cursor_move_yx(@intCast(pos), 0);
 | 
			
		||||
        try self.print_digits(linenum, self.render_style);
 | 
			
		||||
        if (self.highlight and linenum == self.line + 1)
 | 
			
		||||
            self.render_line_highlight(pos, theme);
 | 
			
		||||
        self.render_diff_symbols(&diff_symbols, pos, linenum, theme);
 | 
			
		||||
| 
						 | 
				
			
			@ -190,13 +194,17 @@ pub fn render_relative(self: *Self, theme: *const Widget.Theme) void {
 | 
			
		|||
    var abs_linenum = self.row + 1;
 | 
			
		||||
    var rows = self.rows;
 | 
			
		||||
    var diff_symbols = self.diff_symbols.items;
 | 
			
		||||
    var buf: [31:0]u8 = undefined;
 | 
			
		||||
    while (rows > 0) : (rows -= 1) {
 | 
			
		||||
        if (pos > self.lines - @as(u32, @intCast(row))) return;
 | 
			
		||||
        self.plane.set_style(if (linenum == 0) theme.editor_gutter_active else theme.editor_gutter);
 | 
			
		||||
        const val = @abs(if (linenum == 0) line else linenum);
 | 
			
		||||
        const fmt = std.fmt.bufPrintZ(&buf, "{d} ", .{val}) catch return;
 | 
			
		||||
        _ = self.plane.print_aligned_right(@intCast(pos), "{s}", .{if (fmt.len > 6) "==> " else fmt}) catch {};
 | 
			
		||||
 | 
			
		||||
        try self.plane.cursor_move_yx(@intCast(pos), 0);
 | 
			
		||||
        if (val > 999999)
 | 
			
		||||
            _ = self.plane.print_aligned_right(@intCast(pos), "==> ", .{}) catch {}
 | 
			
		||||
        else
 | 
			
		||||
            self.print_digits(val, self.render_style) catch {};
 | 
			
		||||
 | 
			
		||||
        if (self.highlight and linenum == 0)
 | 
			
		||||
            self.render_line_highlight(pos, theme);
 | 
			
		||||
        self.render_diff_symbols(&diff_symbols, pos, abs_linenum, theme);
 | 
			
		||||
| 
						 | 
				
			
			@ -296,6 +304,11 @@ fn secondary_click(_: *Self) error{Exit}!bool {
 | 
			
		|||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn middle_click(_: *Self) error{Exit}!bool {
 | 
			
		||||
    try command.executeName("gutter_style_next", .{});
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn mouse_click_button4(_: *Self) error{Exit}!bool {
 | 
			
		||||
    try command.executeName("scroll_up_pageup", .{});
 | 
			
		||||
    return true;
 | 
			
		||||
| 
						 | 
				
			
			@ -399,3 +412,45 @@ pub fn filter_receive(self: *Self, _: tp.pid_ref, m: tp.message) MessageFilter.E
 | 
			
		|||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn int_width(n_: usize) usize {
 | 
			
		||||
    var n = n_;
 | 
			
		||||
    var size: usize = 1;
 | 
			
		||||
    while (true) {
 | 
			
		||||
        n /= 10;
 | 
			
		||||
        if (n == 0) return size;
 | 
			
		||||
        size += 1;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn print_digits(self: *Self, n_: anytype, style_: LineNumberStyle) !void {
 | 
			
		||||
    var n = n_;
 | 
			
		||||
    var buf: [12][]const u8 = undefined;
 | 
			
		||||
    var digits: std.ArrayListUnmanaged([]const u8) = .initBuffer(&buf);
 | 
			
		||||
    while (true) {
 | 
			
		||||
        digits.addOneAssumeCapacity().* = get_digit(n % 10, style_);
 | 
			
		||||
        n /= 10;
 | 
			
		||||
        if (n == 0) break;
 | 
			
		||||
    }
 | 
			
		||||
    std.mem.reverse([]const u8, digits.items);
 | 
			
		||||
    try self.plane.cursor_move_yx(@intCast(self.plane.cursor_y()), @intCast(self.width - digits.items.len - 1));
 | 
			
		||||
    for (digits.items) |digit| _ = try self.plane.putstr(digit);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn print_digit(plane: *Plane, n: anytype, style_: LineNumberStyle) !void {
 | 
			
		||||
    _ = try plane.putstr(get_digit(n, style_));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn get_digit(n: anytype, style_: LineNumberStyle) []const u8 {
 | 
			
		||||
    return switch (style_) {
 | 
			
		||||
        .ascii => digits_ascii[n],
 | 
			
		||||
        .digital => digits_digtl[n],
 | 
			
		||||
        .subscript => digits_subsc[n],
 | 
			
		||||
        .superscript => digits_super[n],
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const digits_ascii: [10][]const u8 = .{ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
 | 
			
		||||
const digits_digtl: [10][]const u8 = .{ "🯰", "🯱", "🯲", "🯳", "🯴", "🯵", "🯶", "🯷", "🯸", "🯹" };
 | 
			
		||||
const digits_subsc: [10][]const u8 = .{ "₀", "₁", "₂", "₃", "₄", "₅", "₆", "₇", "₈", "₉" };
 | 
			
		||||
const digits_super: [10][]const u8 = .{ "⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹" };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -578,6 +578,22 @@ const cmds = struct {
 | 
			
		|||
    }
 | 
			
		||||
    pub const gutter_mode_next_meta = .{ .description = "Next gutter mode" };
 | 
			
		||||
 | 
			
		||||
    pub fn gutter_style_next(self: *Self, _: Ctx) Result {
 | 
			
		||||
        const config = tui.config_mut();
 | 
			
		||||
        config.gutter_line_numbers_style = switch (config.gutter_line_numbers_style) {
 | 
			
		||||
            .ascii => .digital,
 | 
			
		||||
            .digital => .subscript,
 | 
			
		||||
            .subscript => .superscript,
 | 
			
		||||
            .superscript => .ascii,
 | 
			
		||||
        };
 | 
			
		||||
        try tui.save_config();
 | 
			
		||||
        if (self.widgets.get("editor_gutter")) |gutter_widget| {
 | 
			
		||||
            const gutter = gutter_widget.dynamic_cast(@import("editor_gutter.zig")) orelse return;
 | 
			
		||||
            gutter.render_style = config.gutter_line_numbers_style;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    pub const gutter_style_next_meta: Meta = .{ .description = "Next line number style" };
 | 
			
		||||
 | 
			
		||||
    pub fn goto_next_file_or_diagnostic(self: *Self, ctx: Ctx) Result {
 | 
			
		||||
        if (self.is_panel_view_showing(filelist_view)) {
 | 
			
		||||
            switch (self.file_list_type) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue