From f3440d4f83fa5105d479fc963c39738976a00ed8 Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Tue, 18 Nov 2025 23:25:40 +0100 Subject: [PATCH 1/5] refactor: make editor.update_scroll_dest_abs public --- src/tui/editor.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tui/editor.zig b/src/tui/editor.zig index beda0ee..6850858 100644 --- a/src/tui/editor.zig +++ b/src/tui/editor.zig @@ -2626,7 +2626,7 @@ pub const Editor = struct { self.view.row = row; } - fn update_scroll_dest_abs(self: *Self, dest: usize) void { + pub fn update_scroll_dest_abs(self: *Self, dest: usize) void { const root = self.buf_root() catch return; const max_view = if (root.lines() <= scroll_cursor_min_border_distance) 0 else root.lines() - scroll_cursor_min_border_distance; self.scroll_dest = @min(dest, max_view); From f49d6a7423e5cb52afb09d2fbfc14f1e87610b95 Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Tue, 18 Nov 2025 23:26:24 +0100 Subject: [PATCH 2/5] refactor: use a match instead of the primary cursor in focus_on_range --- src/tui/editor.zig | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/src/tui/editor.zig b/src/tui/editor.zig index 6850858..3788550 100644 --- a/src/tui/editor.zig +++ b/src/tui/editor.zig @@ -5713,32 +5713,27 @@ pub const Editor = struct { pub fn focus_on_range(self: *Self, ctx: Context) Result { var sel: Selection = .{}; - var pos_type: PosType = .column; if (!try ctx.args.match(.{ tp.extract(&sel.begin.row), tp.extract(&sel.begin.col), tp.extract(&sel.end.row), tp.extract(&sel.end.col), - tp.extract(&pos_type), })) return error.InvalidFocusOnRangeArgument; - self.cancel_all_selections(); - const root = self.buf_root() catch return; - if (pos_type == .byte) - sel = sel.from_pos(root, self.metrics) catch return; - const primary = self.get_primary(); - try primary.cursor.move_to( - root, - sel.begin.row, - sel.begin.col, - self.metrics, - ); - primary.selection = sel; - if (self.view.is_visible(&primary.cursor)) - self.clamp() + self.cancel_all_matches(); + self.add_match_internal(sel.begin.row + 1, sel.begin.col, sel.end.row + 1, sel.end.col); + const cursor = sel.begin; + const range_height = sel.end.row - sel.begin.row + 1; + const view_height = self.view.rows / 2; + const offset = if (range_height > view_height - @min(view_height, scroll_cursor_min_border_distance * 2)) + scroll_cursor_min_border_distance else - try self.scroll_view_center(.{}); - self.need_render(); + (view_height / 2) - (range_height / 2); + const row = if (cursor.row > offset) + cursor.row - offset + else + 0; + self.update_scroll_dest_abs(row); } pub const focus_on_range_meta: Meta = .{ .arguments = &.{ .integer, .integer, .integer, .integer } }; From 8c0eac80cf4d1dd6e37037aaf810f80cb8184de0 Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Tue, 18 Nov 2025 23:27:34 +0100 Subject: [PATCH 3/5] refactor: use a match instead of the primary cursor in symbol_palette --- src/tui/mode/overlay/symbol_palette.zig | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/tui/mode/overlay/symbol_palette.zig b/src/tui/mode/overlay/symbol_palette.zig index 1acd873..9f5e445 100644 --- a/src/tui/mode/overlay/symbol_palette.zig +++ b/src/tui/mode/overlay/symbol_palette.zig @@ -46,6 +46,7 @@ pub const Entry = struct { pub const ValueType = struct { start: ed.CurSel = .{}, + view: ed.View = .{}, column_size: [3]u8 = undefined, }; pub const defaultValue: ValueType = .{}; @@ -99,6 +100,7 @@ pub fn load_entries(palette: *Type) !usize { var max_label_len: usize = 0; palette.value.start = editor.get_primary().*; + palette.value.view = editor.view; var iter: []const u8 = mv.symbols.items; init_col_sizes(palette); while (iter.len > 0) { @@ -203,6 +205,8 @@ fn find_closest(palette: *Type) ?usize { } fn select(menu: **Type.MenuType, button: *Type.ButtonType, _: Type.Pos) void { + const editor = tui.get_active_editor() orelse return; + editor.clear_matches(); _, _, _, const sel = get_values(button.opts.label); tp.self_pid().send(.{ "cmd", "exit_overlay_mode" }) catch |e| menu.*.opts.ctx.logger.err(module_name, e); tp.self_pid().send(.{ "cmd", "goto_line_and_column", .{ sel.begin.row + 1, sel.begin.col + 1 } }) catch |e| menu.*.opts.ctx.logger.err(module_name, e); @@ -211,13 +215,13 @@ fn select(menu: **Type.MenuType, button: *Type.ButtonType, _: Type.Pos) void { pub fn updated(palette: *Type, button_: ?*Type.ButtonType) !void { const button = button_ orelse return cancel(palette); _, _, _, const sel = get_values(button.opts.label); - tp.self_pid().send(.{ "cmd", "focus_on_range", .{ sel.begin.row, sel.begin.col, sel.end.row, sel.end.col, ed.PosType.byte } }) catch {}; + tp.self_pid().send(.{ "cmd", "focus_on_range", .{ sel.begin.row, sel.begin.col, sel.end.row, sel.end.col } }) catch {}; } pub fn cancel(palette: *Type) !void { - tp.self_pid().send(.{ "cmd", "goto_line_and_column", .{ palette.value.start.cursor.row + 1, palette.value.start.cursor.col + 1 } }) catch return; const editor = tui.get_active_editor() orelse return; - editor.get_primary().selection = palette.value.start.selection; + editor.clear_matches(); + editor.update_scroll_dest_abs(palette.value.view.row); } const SymbolKind = enum(u8) { From db8bd0840f765d6bd4eff1f3e14441d4b93fbd2c Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Tue, 18 Nov 2025 23:27:59 +0100 Subject: [PATCH 4/5] fix: find the closest matching symbol not the largest enclosing symbol --- src/tui/mode/overlay/symbol_palette.zig | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/tui/mode/overlay/symbol_palette.zig b/src/tui/mode/overlay/symbol_palette.zig index 9f5e445..34c4b4f 100644 --- a/src/tui/mode/overlay/symbol_palette.zig +++ b/src/tui/mode/overlay/symbol_palette.zig @@ -196,8 +196,6 @@ fn find_closest(palette: *Type) ?usize { var previous: usize = 0; for (palette.entries.items, 0..) |entry, idx| { _, _, _, const sel = get_values(entry.cbor); - if (cursor.within(sel)) - return idx + 1; if (cursor.row < sel.begin.row) return previous + 1; previous = idx; } From fc6f2e2cde0471ad1ecaff33a1d6276141a0b962 Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Tue, 18 Nov 2025 23:36:35 +0100 Subject: [PATCH 5/5] fix: center in the middle not top quarter --- src/tui/editor.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tui/editor.zig b/src/tui/editor.zig index 3788550..73b2124 100644 --- a/src/tui/editor.zig +++ b/src/tui/editor.zig @@ -5724,7 +5724,7 @@ pub const Editor = struct { self.add_match_internal(sel.begin.row + 1, sel.begin.col, sel.end.row + 1, sel.end.col); const cursor = sel.begin; const range_height = sel.end.row - sel.begin.row + 1; - const view_height = self.view.rows / 2; + const view_height = self.view.rows; const offset = if (range_height > view_height - @min(view_height, scroll_cursor_min_border_distance * 2)) scroll_cursor_min_border_distance else