From 3f06f6b19c53d3f1580fbcc1291e14190c1578cd Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Tue, 21 Jan 2025 22:29:39 +0100 Subject: [PATCH] feat(buffers): add buffer switcher --- src/buffer/Manager.zig | 8 ++--- src/keybind/builtin/flow.json | 2 ++ src/tui/mode/overlay/buffer_palette.zig | 44 +++++++++++++++++++++++++ src/tui/tui.zig | 5 +++ 4 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 src/tui/mode/overlay/buffer_palette.zig diff --git a/src/buffer/Manager.zig b/src/buffer/Manager.zig index 26a1448..6b68e78 100644 --- a/src/buffer/Manager.zig +++ b/src/buffer/Manager.zig @@ -51,15 +51,15 @@ pub fn retire(_: *Self, buffer: *Buffer) void { buffer.update_last_used_time(); } -pub fn list(self: *Self, allocator: std.mem.Allocator) error{OutOfMemory}![]*const Buffer { - var buffers: std.ArrayListUnmanaged([]*const Buffer) = .{}; +pub fn list_most_recently_used(self: *Self, allocator: std.mem.Allocator) error{OutOfMemory}![]*Buffer { + var buffers: std.ArrayListUnmanaged(*Buffer) = .{}; var i = self.buffers.iterator(); while (i.next()) |kv| - (try buffers.addOne()).* = kv.value_ptr.*; + (try buffers.addOne(allocator)).* = kv.value_ptr.*; std.mem.sort(*Buffer, buffers.items, {}, struct { fn less_fn(_: void, lhs: *Buffer, rhs: *Buffer) bool { - return lhs.mtime > rhs.mtime; + return lhs.utime > rhs.utime; } }.less_fn); diff --git a/src/keybind/builtin/flow.json b/src/keybind/builtin/flow.json index 33c5ec9..6876aee 100644 --- a/src/keybind/builtin/flow.json +++ b/src/keybind/builtin/flow.json @@ -1,6 +1,7 @@ { "project": { "press": [ + ["ctrl+shift+e", "switch_buffers"], ["ctrl+0", "reset_fontsize"], ["ctrl+plus", "adjust_fontsize", 1.0], ["ctrl+minus", "adjust_fontsize", -1.0], @@ -250,6 +251,7 @@ ["ctrl+p", "palette_menu_up"], ["ctrl+n", "palette_menu_down"], ["ctrl+e", "palette_menu_down"], + ["ctrl+shift+e", "palette_menu_down"], ["ctrl+r", "palette_menu_down"], ["ctrl+t", "palette_menu_down"], ["ctrl+v", "system_paste"], diff --git a/src/tui/mode/overlay/buffer_palette.zig b/src/tui/mode/overlay/buffer_palette.zig new file mode 100644 index 0000000..a8cff8e --- /dev/null +++ b/src/tui/mode/overlay/buffer_palette.zig @@ -0,0 +1,44 @@ +const std = @import("std"); +const cbor = @import("cbor"); +const tp = @import("thespian"); +const root = @import("root"); +const command = @import("command"); + +const tui = @import("../../tui.zig"); +pub const Type = @import("palette.zig").Create(@This()); + +pub const label = "Switch buffers"; +pub const name = " buffer"; +pub const description = "buffer"; + +pub const Entry = struct { + label: []const u8, +}; + +pub fn load_entries(palette: *Type) !usize { + const buffer_manager = tui.get_buffer_manager() orelse return 0; + const buffers = try buffer_manager.list_most_recently_used(palette.allocator); + defer palette.allocator.free(buffers); + for (buffers) |buffer| + (try palette.entries.addOne()).* = .{ .label = buffer.file_path }; + return if (palette.entries.items.len == 0) label.len else 0; +} + +pub fn add_menu_entry(palette: *Type, entry: *Entry, matches: ?[]const usize) !void { + var value = std.ArrayList(u8).init(palette.allocator); + defer value.deinit(); + const writer = value.writer(); + try cbor.writeValue(writer, entry.label); + try cbor.writeValue(writer, matches orelse &[_]usize{}); + try palette.menu.add_item_with_handler(value.items, select); + palette.items += 1; +} + +fn select(menu: **Type.MenuState, button: *Type.ButtonState) void { + var file_path: []const u8 = undefined; + var iter = button.opts.label; + if (!(cbor.matchString(&iter, &file_path) catch false)) return; + tp.self_pid().send(.{ "cmd", "exit_overlay_mode" }) catch |e| menu.*.opts.ctx.logger.err("navigate", e); + tp.self_pid().send(.{ "cmd", "navigate", .{} }) catch |e| menu.*.opts.ctx.logger.err("navigate", e); + tp.self_pid().send(.{ "cmd", "navigate", .{ .file = file_path } }) catch |e| menu.*.opts.ctx.logger.err("navigate", e); +} diff --git a/src/tui/tui.zig b/src/tui/tui.zig index 2b1d28c..fc385ea 100644 --- a/src/tui/tui.zig +++ b/src/tui/tui.zig @@ -815,6 +815,11 @@ const cmds = struct { } pub const open_recent_project_meta = .{ .description = "Open recent project" }; + pub fn switch_buffers(self: *Self, _: Ctx) Result { + return self.enter_overlay_mode(@import("mode/overlay/buffer_palette.zig").Type); + } + pub const switch_buffers_meta = .{ .description = "Switch buffers" }; + pub fn change_theme(self: *Self, _: Ctx) Result { return self.enter_overlay_mode(@import("mode/overlay/theme_palette.zig").Type); }