feat: make indent size and tab width configurable and add indent guide mode
This commit is contained in:
		
							parent
							
								
									55fb6d29a0
								
							
						
					
					
						commit
						d2238bf847
					
				
					 15 changed files with 363 additions and 323 deletions
				
			
		| 
						 | 
				
			
			@ -19,8 +19,9 @@ pub const Metrics = struct {
 | 
			
		|||
    ctx: *const anyopaque,
 | 
			
		||||
    egc_length: egc_length_func,
 | 
			
		||||
    egc_chunk_width: egc_chunk_width_func,
 | 
			
		||||
    pub const egc_length_func = *const fn (ctx: *const anyopaque, egcs: []const u8, colcount: *c_int, abs_col: usize) usize;
 | 
			
		||||
    pub const egc_chunk_width_func = *const fn (self: *const anyopaque, chunk_: []const u8, abs_col_: usize) usize;
 | 
			
		||||
    tab_width: usize,
 | 
			
		||||
    pub const egc_length_func = *const fn (self: Metrics, egcs: []const u8, colcount: *c_int, abs_col: usize) usize;
 | 
			
		||||
    pub const egc_chunk_width_func = *const fn (self: Metrics, chunk_: []const u8, abs_col_: usize) usize;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
arena: std.heap.ArenaAllocator,
 | 
			
		||||
| 
						 | 
				
			
			@ -165,11 +166,11 @@ pub const Leaf = struct {
 | 
			
		|||
        var buf = self.buf;
 | 
			
		||||
        while (buf.len > 0 and pos.* > 0) {
 | 
			
		||||
            if (buf[0] == '\t') {
 | 
			
		||||
                cols = @intCast(8 - (abs_col % 8));
 | 
			
		||||
                cols = @intCast(metrics.tab_width - (abs_col % metrics.tab_width));
 | 
			
		||||
                buf = buf[1..];
 | 
			
		||||
                pos.* -= 1;
 | 
			
		||||
            } else {
 | 
			
		||||
                const bytes = metrics.egc_length(metrics.ctx, buf, &cols, abs_col);
 | 
			
		||||
                const bytes = metrics.egc_length(metrics, buf, &cols, abs_col);
 | 
			
		||||
                buf = buf[bytes..];
 | 
			
		||||
                pos.* -= bytes;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -192,7 +193,7 @@ pub const Leaf = struct {
 | 
			
		|||
        return while (buf.len > 0) {
 | 
			
		||||
            if (col == 0)
 | 
			
		||||
                break @intFromPtr(buf.ptr) - @intFromPtr(self.buf.ptr);
 | 
			
		||||
            const bytes = metrics.egc_length(metrics.ctx, buf, &cols, abs_col);
 | 
			
		||||
            const bytes = metrics.egc_length(metrics, buf, &cols, abs_col);
 | 
			
		||||
            buf = buf[bytes..];
 | 
			
		||||
            if (col < cols)
 | 
			
		||||
                break @intFromPtr(buf.ptr) - @intFromPtr(self.buf.ptr);
 | 
			
		||||
| 
						 | 
				
			
			@ -225,7 +226,7 @@ pub const Leaf = struct {
 | 
			
		|||
                    buf = buf[1..];
 | 
			
		||||
                },
 | 
			
		||||
                else => {
 | 
			
		||||
                    const bytes = metrics.egc_length(metrics.ctx, buf, &cols, 0);
 | 
			
		||||
                    const bytes = metrics.egc_length(metrics, buf, &cols, 0);
 | 
			
		||||
                    var buf_: [4096]u8 = undefined;
 | 
			
		||||
                    try l.appendSlice(try std.fmt.bufPrint(&buf_, "{s}", .{std.fmt.fmtSliceEscapeLower(buf[0..bytes])}));
 | 
			
		||||
                    buf = buf[bytes..];
 | 
			
		||||
| 
						 | 
				
			
			@ -484,7 +485,7 @@ const Node = union(enum) {
 | 
			
		|||
                var buf: []const u8 = leaf.buf;
 | 
			
		||||
                while (buf.len > 0) {
 | 
			
		||||
                    var cols: c_int = undefined;
 | 
			
		||||
                    const bytes = metrics.egc_length(metrics.ctx, buf, &cols, ctx.abs_col);
 | 
			
		||||
                    const bytes = metrics.egc_length(metrics, buf, &cols, ctx.abs_col);
 | 
			
		||||
                    const ret = ctx.walker_f(ctx.walker_ctx, buf[0..bytes], @intCast(cols), metrics);
 | 
			
		||||
                    if (ret.err) |e| return .{ .err = e };
 | 
			
		||||
                    buf = buf[bytes..];
 | 
			
		||||
| 
						 | 
				
			
			@ -849,7 +850,7 @@ const Node = union(enum) {
 | 
			
		|||
                line += 1;
 | 
			
		||||
                col = 0;
 | 
			
		||||
            } else {
 | 
			
		||||
                col += metrics_.egc_chunk_width(metrics_.ctx, chunk, col);
 | 
			
		||||
                col += metrics_.egc_chunk_width(metrics_, chunk, col);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return .{ line, col, self };
 | 
			
		||||
| 
						 | 
				
			
			@ -972,7 +973,7 @@ const Node = union(enum) {
 | 
			
		|||
                    if (ctx.abs_col >= ctx.pos.col) return error.Stop;
 | 
			
		||||
                    if (buf[0] == '\n') return error.Stop;
 | 
			
		||||
                    var cols: c_int = undefined;
 | 
			
		||||
                    const egc_bytes = ctx.metrics.egc_length(ctx.metrics.ctx, buf, &cols, ctx.abs_col);
 | 
			
		||||
                    const egc_bytes = ctx.metrics.egc_length(ctx.metrics, buf, &cols, ctx.abs_col);
 | 
			
		||||
                    ctx.abs_col += @intCast(cols);
 | 
			
		||||
                    ctx.byte_pos += egc_bytes;
 | 
			
		||||
                    buf = buf[egc_bytes..];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,10 +12,13 @@ enable_terminal_cursor: bool = false,
 | 
			
		|||
enable_terminal_color_scheme: bool = builtin.os.tag != .windows,
 | 
			
		||||
highlight_current_line: bool = true,
 | 
			
		||||
highlight_current_line_gutter: bool = true,
 | 
			
		||||
show_whitespace: bool = false,
 | 
			
		||||
whitespace_mode: []const u8 = "none",
 | 
			
		||||
animation_min_lag: usize = 0, //milliseconds
 | 
			
		||||
animation_max_lag: usize = 150, //milliseconds
 | 
			
		||||
enable_format_on_save: bool = false,
 | 
			
		||||
 | 
			
		||||
indent_size: usize = 4,
 | 
			
		||||
tab_width: usize = 8,
 | 
			
		||||
 | 
			
		||||
top_bar: []const u8 = "",
 | 
			
		||||
bottom_bar: []const u8 = "mode file log selection diagnostics linenumber",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -121,7 +121,7 @@ pub fn print_aligned_right(self: *Plane, y: c_int, comptime fmt: anytype, args:
 | 
			
		|||
    var buf: [fmt.len + 4096]u8 = undefined;
 | 
			
		||||
    const width = self.window.width;
 | 
			
		||||
    const text = try std.fmt.bufPrint(&buf, fmt, args);
 | 
			
		||||
    const text_width = self.egc_chunk_width(text, 0);
 | 
			
		||||
    const text_width = self.egc_chunk_width(text, 0, 8);
 | 
			
		||||
    self.row = @intCast(y);
 | 
			
		||||
    self.col = @intCast(if (text_width >= width) 0 else width - text_width);
 | 
			
		||||
    return self.putstr(text);
 | 
			
		||||
| 
						 | 
				
			
			@ -131,7 +131,7 @@ pub fn print_aligned_center(self: *Plane, y: c_int, comptime fmt: anytype, args:
 | 
			
		|||
    var buf: [fmt.len + 4096]u8 = undefined;
 | 
			
		||||
    const width = self.window.width;
 | 
			
		||||
    const text = try std.fmt.bufPrint(&buf, fmt, args);
 | 
			
		||||
    const text_width = self.egc_chunk_width(text, 0);
 | 
			
		||||
    const text_width = self.egc_chunk_width(text, 0, 8);
 | 
			
		||||
    self.row = @intCast(y);
 | 
			
		||||
    self.col = @intCast(if (text_width >= width) 0 else (width - text_width) / 2);
 | 
			
		||||
    return self.putstr(text);
 | 
			
		||||
| 
						 | 
				
			
			@ -230,7 +230,7 @@ pub fn cell_init(self: Plane) Cell {
 | 
			
		|||
 | 
			
		||||
pub fn cell_load(self: *Plane, cell: *Cell, gcluster: [:0]const u8) !usize {
 | 
			
		||||
    var cols: c_int = 0;
 | 
			
		||||
    const bytes = self.egc_length(gcluster, &cols, 0);
 | 
			
		||||
    const bytes = self.egc_length(gcluster, &cols, 0, 1);
 | 
			
		||||
    cell.cell.char.grapheme = self.cache.put(gcluster[0..bytes]);
 | 
			
		||||
    cell.cell.char.width = @intCast(cols);
 | 
			
		||||
    return bytes;
 | 
			
		||||
| 
						 | 
				
			
			@ -334,9 +334,9 @@ inline fn set_font_style(style: *vaxis.Cell.Style, fs: FontStyle) void {
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn egc_length(self: *const Plane, egcs: []const u8, colcount: *c_int, abs_col: usize) usize {
 | 
			
		||||
pub fn egc_length(self: *const Plane, egcs: []const u8, colcount: *c_int, abs_col: usize, tab_width: usize) usize {
 | 
			
		||||
    if (egcs[0] == '\t') {
 | 
			
		||||
        colcount.* = @intCast(8 - abs_col % 8);
 | 
			
		||||
        colcount.* = @intCast(tab_width - (abs_col % tab_width));
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    var iter = self.window.screen.unicode.graphemeIterator(egcs);
 | 
			
		||||
| 
						 | 
				
			
			@ -350,13 +350,13 @@ pub fn egc_length(self: *const Plane, egcs: []const u8, colcount: *c_int, abs_co
 | 
			
		|||
    return s.len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn egc_chunk_width(self: *const Plane, chunk_: []const u8, abs_col_: usize) usize {
 | 
			
		||||
pub fn egc_chunk_width(self: *const Plane, chunk_: []const u8, abs_col_: usize, tab_width: usize) usize {
 | 
			
		||||
    var abs_col = abs_col_;
 | 
			
		||||
    var chunk = chunk_;
 | 
			
		||||
    var colcount: usize = 0;
 | 
			
		||||
    var cols: c_int = 0;
 | 
			
		||||
    while (chunk.len > 0) {
 | 
			
		||||
        const bytes = self.egc_length(chunk, &cols, abs_col);
 | 
			
		||||
        const bytes = self.egc_length(chunk, &cols, abs_col, tab_width);
 | 
			
		||||
        colcount += @intCast(cols);
 | 
			
		||||
        abs_col += @intCast(cols);
 | 
			
		||||
        if (chunk.len < bytes) break;
 | 
			
		||||
| 
						 | 
				
			
			@ -365,21 +365,22 @@ pub fn egc_chunk_width(self: *const Plane, chunk_: []const u8, abs_col_: usize)
 | 
			
		|||
    return colcount;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn metrics(self: *const Plane) Buffer.Metrics {
 | 
			
		||||
pub fn metrics(self: *const Plane, tab_width: usize) Buffer.Metrics {
 | 
			
		||||
    return .{
 | 
			
		||||
        .ctx = self,
 | 
			
		||||
        .egc_length = struct {
 | 
			
		||||
            fn f(ctx: *const anyopaque, egcs: []const u8, colcount: *c_int, abs_col: usize) usize {
 | 
			
		||||
                const self_: *const Plane = @ptrCast(@alignCast(ctx));
 | 
			
		||||
                return self_.egc_length(egcs, colcount, abs_col);
 | 
			
		||||
            fn f(self_: Buffer.Metrics, egcs: []const u8, colcount: *c_int, abs_col: usize) usize {
 | 
			
		||||
                const plane: *const Plane = @ptrCast(@alignCast(self_.ctx));
 | 
			
		||||
                return plane.egc_length(egcs, colcount, abs_col, self_.tab_width);
 | 
			
		||||
            }
 | 
			
		||||
        }.f,
 | 
			
		||||
        .egc_chunk_width = struct {
 | 
			
		||||
            fn f(ctx: *const anyopaque, chunk_: []const u8, abs_col_: usize) usize {
 | 
			
		||||
                const self_: *const Plane = @ptrCast(@alignCast(ctx));
 | 
			
		||||
                return self_.egc_chunk_width(chunk_, abs_col_);
 | 
			
		||||
            fn f(self_: Buffer.Metrics, chunk_: []const u8, abs_col_: usize) usize {
 | 
			
		||||
                const plane: *const Plane = @ptrCast(@alignCast(self_.ctx));
 | 
			
		||||
                return plane.egc_chunk_width(chunk_, abs_col_, self_.tab_width);
 | 
			
		||||
            }
 | 
			
		||||
        }.f,
 | 
			
		||||
        .tab_width = tab_width,
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -78,11 +78,11 @@ fn inspect_location(self: *Self, row: usize, col: usize) void {
 | 
			
		|||
 | 
			
		||||
fn get_buffer_text(self: *Self, buf: []u8, sel: Buffer.Selection) ?[]const u8 {
 | 
			
		||||
    const root = self.editor.get_current_root() orelse return null;
 | 
			
		||||
    return root.get_range(sel, buf, null, null, self.plane.metrics()) catch return null;
 | 
			
		||||
    return root.get_range(sel, buf, null, null, self.plane.metrics(self.editor.tab_width)) catch return null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn dump_highlight(self: *Self, range: syntax.Range, scope: []const u8, id: u32, _: usize, ast_node: *const syntax.Node) error{Stop}!void {
 | 
			
		||||
    const sel = self.pos_cache.range_to_selection(range, self.editor.get_current_root() orelse return, self.plane) orelse return;
 | 
			
		||||
    const sel = self.pos_cache.range_to_selection(range, self.editor.get_current_root() orelse return, self.editor.metrics) orelse return;
 | 
			
		||||
 | 
			
		||||
    var update_match: enum { no, add, set } = .no;
 | 
			
		||||
    var match = ed.Match.from_selection(sel);
 | 
			
		||||
| 
						 | 
				
			
			@ -113,7 +113,7 @@ fn dump_highlight(self: *Self, range: syntax.Range, scope: []const u8, id: u32,
 | 
			
		|||
            const ast_parent = parent.asSExpressionString();
 | 
			
		||||
            _ = self.plane.print("parent: {s}\n", .{ast_parent}) catch {};
 | 
			
		||||
            syntax.Node.freeSExpressionString(ast_parent);
 | 
			
		||||
            const sel_parent = self.pos_cache.range_to_selection(parent.getRange(), self.editor.get_current_root() orelse return, self.plane) orelse return;
 | 
			
		||||
            const sel_parent = self.pos_cache.range_to_selection(parent.getRange(), self.editor.get_current_root() orelse return, self.editor.metrics) orelse return;
 | 
			
		||||
            var match_parent = ed.Match.from_selection(sel_parent);
 | 
			
		||||
            if (self.theme) |theme| match_parent.style = .{ .bg = theme.editor_gutter_added.fg };
 | 
			
		||||
            switch (update_match) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -117,7 +117,7 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void {
 | 
			
		|||
            key.BACKSPACE => self.cmd("delete_word_left", .{}),
 | 
			
		||||
            key.DEL => self.cmd("delete_word_right", .{}),
 | 
			
		||||
            key.F05 => self.cmd("toggle_inspector_view", .{}),
 | 
			
		||||
            key.F10 => self.cmd("toggle_whitespace", .{}), // aka F34
 | 
			
		||||
            key.F10 => self.cmd("toggle_whitespace_mode", .{}), // aka F34
 | 
			
		||||
            key.F12 => self.cmd("goto_implementation", .{}),
 | 
			
		||||
            else => {},
 | 
			
		||||
        },
 | 
			
		||||
| 
						 | 
				
			
			@ -209,7 +209,7 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void {
 | 
			
		|||
            key.F10 => self.cmd("theme_next", .{}),
 | 
			
		||||
            key.F11 => self.cmd("toggle_panel", .{}),
 | 
			
		||||
            key.F12 => self.cmd("goto_definition", .{}),
 | 
			
		||||
            key.F34 => self.cmd("toggle_whitespace", .{}), // C-F10
 | 
			
		||||
            key.F34 => self.cmd("toggle_whitespace_mode", .{}), // C-F10
 | 
			
		||||
            key.F58 => self.cmd("gutter_mode_next", .{}), // A-F10
 | 
			
		||||
            key.ESC => self.cmd("cancel", .{}),
 | 
			
		||||
            key.ENTER => self.cmd("smart_insert_line", .{}),
 | 
			
		||||
| 
						 | 
				
			
			@ -425,7 +425,7 @@ const hints = tui.KeybindHints.initComptime(.{
 | 
			
		|||
    .{ "toggle_inputview", "A-i" },
 | 
			
		||||
    .{ "toggle_inspector_view", "F5, C-F5, C-S-i" },
 | 
			
		||||
    .{ "toggle_panel", "C-j, F11" },
 | 
			
		||||
    .{ "toggle_whitespace", "C-F10" },
 | 
			
		||||
    .{ "toggle_whitespace_mode", "C-F10" },
 | 
			
		||||
    .{ "to_lower", "A-l" },
 | 
			
		||||
    .{ "to_upper", "A-u" },
 | 
			
		||||
    .{ "undo", "C-z" },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -121,7 +121,7 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void {
 | 
			
		|||
            key.BACKSPACE => self.cmd("delete_word_left", .{}),
 | 
			
		||||
            key.DEL => self.cmd("delete_word_right", .{}),
 | 
			
		||||
            key.F05 => self.cmd("toggle_inspector_view", .{}),
 | 
			
		||||
            key.F10 => self.cmd("toggle_whitespace", .{}), // aka F34
 | 
			
		||||
            key.F10 => self.cmd("toggle_whitespace_mode", .{}), // aka F34
 | 
			
		||||
            else => {},
 | 
			
		||||
        },
 | 
			
		||||
        mod.CTRL | mod.SHIFT => switch (keynormal) {
 | 
			
		||||
| 
						 | 
				
			
			@ -202,7 +202,7 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void {
 | 
			
		|||
            key.F10 => self.cmd("theme_next", .{}),
 | 
			
		||||
            key.F11 => self.cmd("toggle_panel", .{}),
 | 
			
		||||
            key.F12 => self.cmd("goto_definition", .{}),
 | 
			
		||||
            key.F34 => self.cmd("toggle_whitespace", .{}), // C-F10
 | 
			
		||||
            key.F34 => self.cmd("toggle_whitespace_mode", .{}), // C-F10
 | 
			
		||||
            key.F58 => self.cmd("gutter_mode_next", .{}), // A-F10
 | 
			
		||||
            key.ESC => self.cmd("enter_mode", command.fmt(.{"helix/normal"})),
 | 
			
		||||
            key.ENTER => self.cmd("smart_insert_line", .{}),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -645,7 +645,7 @@ const hints = tui.KeybindHints.initComptime(.{
 | 
			
		|||
    .{ "toggle_inputview", "A-i" },
 | 
			
		||||
    .{ "toggle_inspector_view", "F5, C-F5, C-S-i" },
 | 
			
		||||
    .{ "toggle_panel", "C-j, F11" },
 | 
			
		||||
    .{ "toggle_whitespace", "C-F10" },
 | 
			
		||||
    .{ "toggle_whitespace_mode", "C-F10" },
 | 
			
		||||
    .{ "to_lower", "A-l" },
 | 
			
		||||
    .{ "to_upper", "A-u" },
 | 
			
		||||
    .{ "undo", "C-z" },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -645,7 +645,7 @@ const hints = tui.KeybindHints.initComptime(.{
 | 
			
		|||
    .{ "toggle_inputview", "A-i" },
 | 
			
		||||
    .{ "toggle_inspector_view", "F5, C-F5, C-S-i" },
 | 
			
		||||
    .{ "toggle_panel", "C-j, F11" },
 | 
			
		||||
    .{ "toggle_whitespace", "C-F10" },
 | 
			
		||||
    .{ "toggle_whitespace_mode", "C-F10" },
 | 
			
		||||
    .{ "to_lower", "A-l" },
 | 
			
		||||
    .{ "to_upper", "A-u" },
 | 
			
		||||
    .{ "undo", "C-z" },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -121,7 +121,7 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void {
 | 
			
		|||
            key.BACKSPACE => self.cmd("delete_word_left", .{}),
 | 
			
		||||
            key.DEL => self.cmd("delete_word_right", .{}),
 | 
			
		||||
            key.F05 => self.cmd("toggle_inspector_view", .{}),
 | 
			
		||||
            key.F10 => self.cmd("toggle_whitespace", .{}), // aka F34
 | 
			
		||||
            key.F10 => self.cmd("toggle_whitespace_mode", .{}), // aka F34
 | 
			
		||||
            else => {},
 | 
			
		||||
        },
 | 
			
		||||
        mod.CTRL | mod.SHIFT => switch (keynormal) {
 | 
			
		||||
| 
						 | 
				
			
			@ -202,7 +202,7 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void {
 | 
			
		|||
            key.F10 => self.cmd("theme_next", .{}),
 | 
			
		||||
            key.F11 => self.cmd("toggle_panel", .{}),
 | 
			
		||||
            key.F12 => self.cmd("goto_definition", .{}),
 | 
			
		||||
            key.F34 => self.cmd("toggle_whitespace", .{}), // C-F10
 | 
			
		||||
            key.F34 => self.cmd("toggle_whitespace_mode", .{}), // C-F10
 | 
			
		||||
            key.F58 => self.cmd("gutter_mode_next", .{}), // A-F10
 | 
			
		||||
            key.ESC => self.cmd("enter_mode", command.fmt(.{"vim/normal"})),
 | 
			
		||||
            key.ENTER => self.cmd("smart_insert_line", .{}),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -126,7 +126,7 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void {
 | 
			
		|||
            key.BACKSPACE => self.cmd("delete_word_left", .{}),
 | 
			
		||||
            key.DEL => self.cmd("delete_word_right", .{}),
 | 
			
		||||
            key.F05 => self.cmd("toggle_inspector_view", .{}),
 | 
			
		||||
            key.F10 => self.cmd("toggle_whitespace", .{}), // aka F34
 | 
			
		||||
            key.F10 => self.cmd("toggle_whitespace_mode", .{}), // aka F34
 | 
			
		||||
            else => {},
 | 
			
		||||
        },
 | 
			
		||||
        mod.CTRL | mod.SHIFT => switch (keynormal) {
 | 
			
		||||
| 
						 | 
				
			
			@ -223,7 +223,7 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void {
 | 
			
		|||
            key.F10 => self.cmd("theme_next", .{}),
 | 
			
		||||
            key.F11 => self.cmd("toggle_panel", .{}),
 | 
			
		||||
            key.F12 => self.cmd("goto_definition", .{}),
 | 
			
		||||
            key.F34 => self.cmd("toggle_whitespace", .{}), // C-F10
 | 
			
		||||
            key.F34 => self.cmd("toggle_whitespace_mode", .{}), // C-F10
 | 
			
		||||
            key.F58 => self.cmd("gutter_mode_next", .{}), // A-F10
 | 
			
		||||
            key.ESC => self.cmd("cancel", .{}),
 | 
			
		||||
            key.ENTER => self.cmd("smart_insert_line", .{}),
 | 
			
		||||
| 
						 | 
				
			
			@ -609,7 +609,7 @@ const hints = tui.KeybindHints.initComptime(.{
 | 
			
		|||
    .{ "toggle_inputview", "A-i" },
 | 
			
		||||
    .{ "toggle_inspector_view", "F5, C-F5, C-S-i" },
 | 
			
		||||
    .{ "toggle_panel", "C-j, F11" },
 | 
			
		||||
    .{ "toggle_whitespace", "C-F10" },
 | 
			
		||||
    .{ "toggle_whitespace_mode", "C-F10" },
 | 
			
		||||
    .{ "to_lower", "A-l" },
 | 
			
		||||
    .{ "to_upper", "A-u" },
 | 
			
		||||
    .{ "undo", "C-z" },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -126,7 +126,7 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void {
 | 
			
		|||
            key.BACKSPACE => self.cmd("delete_word_left", .{}),
 | 
			
		||||
            key.DEL => self.cmd("delete_word_right", .{}),
 | 
			
		||||
            key.F05 => self.cmd("toggle_inspector_view", .{}),
 | 
			
		||||
            key.F10 => self.cmd("toggle_whitespace", .{}), // aka F34
 | 
			
		||||
            key.F10 => self.cmd("toggle_whitespace_mode", .{}), // aka F34
 | 
			
		||||
            else => {},
 | 
			
		||||
        },
 | 
			
		||||
        mod.CTRL | mod.SHIFT => switch (keynormal) {
 | 
			
		||||
| 
						 | 
				
			
			@ -220,7 +220,7 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void {
 | 
			
		|||
            key.F10 => self.cmd("theme_next", .{}),
 | 
			
		||||
            key.F11 => self.cmd("toggle_panel", .{}),
 | 
			
		||||
            key.F12 => self.cmd("goto_definition", .{}),
 | 
			
		||||
            key.F34 => self.cmd("toggle_whitespace", .{}), // C-F10
 | 
			
		||||
            key.F34 => self.cmd("toggle_whitespace_mode", .{}), // C-F10
 | 
			
		||||
            key.F58 => self.cmd("gutter_mode_next", .{}), // A-F10
 | 
			
		||||
            key.ESC => self.seq(.{ "cancel", "enter_mode" }, command.fmt(.{"vim/normal"})),
 | 
			
		||||
            key.ENTER => self.cmd("smart_insert_line", .{}),
 | 
			
		||||
| 
						 | 
				
			
			@ -558,7 +558,7 @@ const hints = tui.KeybindHints.initComptime(.{
 | 
			
		|||
    .{ "toggle_inputview", "A-i" },
 | 
			
		||||
    .{ "toggle_inspector_view", "F5, C-F5, C-S-i" },
 | 
			
		||||
    .{ "toggle_panel", "C-j, F11" },
 | 
			
		||||
    .{ "toggle_whitespace", "C-F10" },
 | 
			
		||||
    .{ "toggle_whitespace_mode", "C-F10" },
 | 
			
		||||
    .{ "to_lower", "A-l" },
 | 
			
		||||
    .{ "to_upper", "A-u" },
 | 
			
		||||
    .{ "undo", "C-z" },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,7 +35,7 @@ fn on_click(_: *Self, _: *Button.State(Self)) void {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
pub fn layout(self: *Self, btn: *Button.State(Self)) Widget.Layout {
 | 
			
		||||
    const len = btn.plane.egc_chunk_width(self.rendered, 0);
 | 
			
		||||
    const len = btn.plane.egc_chunk_width(self.rendered, 0, 1);
 | 
			
		||||
    return .{ .static = len };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,8 +24,8 @@ pub fn create(allocator: Allocator, parent: Plane, event_handler: ?Widget.EventH
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
pub fn layout(_: *void, btn: *Button.State(void)) Widget.Layout {
 | 
			
		||||
    const name = btn.plane.egc_chunk_width(tui.get_mode(), 0);
 | 
			
		||||
    const logo = if (is_mini_mode() or is_overlay_mode()) 1 else btn.plane.egc_chunk_width(left ++ symbol ++ right, 0);
 | 
			
		||||
    const name = btn.plane.egc_chunk_width(tui.get_mode(), 0, 1);
 | 
			
		||||
    const logo = if (is_mini_mode() or is_overlay_mode()) 1 else btn.plane.egc_chunk_width(left ++ symbol ++ right, 0, 1);
 | 
			
		||||
    const padding: usize = 2;
 | 
			
		||||
    const minimode_sep: usize = if (is_mini_mode()) 1 else 0;
 | 
			
		||||
    return .{ .static = logo + name + padding + minimode_sep };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -601,15 +601,20 @@ const cmds = struct {
 | 
			
		|||
    }
 | 
			
		||||
    pub const theme_prev_meta = .{ .description = "Switch to previous color theme" };
 | 
			
		||||
 | 
			
		||||
    pub fn toggle_whitespace(self: *Self, _: Ctx) Result {
 | 
			
		||||
        self.config.show_whitespace = !self.config.show_whitespace;
 | 
			
		||||
        self.logger.print("show_whitspace {s}", .{if (self.config.show_whitespace) "enabled" else "disabled"});
 | 
			
		||||
    pub fn toggle_whitespace_mode(self: *Self, _: Ctx) Result {
 | 
			
		||||
        self.config.whitespace_mode = if (std.mem.eql(u8, self.config.whitespace_mode, "none"))
 | 
			
		||||
            "indent"
 | 
			
		||||
        else if (std.mem.eql(u8, self.config.whitespace_mode, "indent"))
 | 
			
		||||
            "visible"
 | 
			
		||||
        else
 | 
			
		||||
            "none";
 | 
			
		||||
        try self.save_config();
 | 
			
		||||
        var buf: [32]u8 = undefined;
 | 
			
		||||
        const m = try tp.message.fmtbuf(&buf, .{ "show_whitespace", self.config.show_whitespace });
 | 
			
		||||
        const m = try tp.message.fmtbuf(&buf, .{ "whitespace_mode", self.config.whitespace_mode });
 | 
			
		||||
        _ = try self.send_widgets(tp.self_pid(), m);
 | 
			
		||||
        self.logger.print("whitespace rendering {s}", .{self.config.whitespace_mode});
 | 
			
		||||
    }
 | 
			
		||||
    pub const toggle_whitespace_meta = .{ .description = "Toggle visible whitespace" };
 | 
			
		||||
    pub const toggle_whitespace_mode_meta = .{ .description = "Switch to next whitespace rendering mode" };
 | 
			
		||||
 | 
			
		||||
    pub fn toggle_input_mode(self: *Self, _: Ctx) Result {
 | 
			
		||||
        self.config.input_mode = if (std.mem.eql(u8, self.config.input_mode, "flow"))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue