Compare commits
6 commits
4c98cf33e3
...
23ac73ec1c
| Author | SHA1 | Date | |
|---|---|---|---|
| 23ac73ec1c | |||
| e8ec1a4598 | |||
| 3967995e05 | |||
| b34e0c521c | |||
| a7a7e313ce | |||
| 2f77dbb845 |
4 changed files with 125 additions and 7 deletions
|
|
@ -7,6 +7,7 @@
|
|||
["ctrl+e", "find_file"],
|
||||
["ctrl+shift+n", "create_new_file"],
|
||||
["ctrl+r", "open_recent_project"],
|
||||
["ctrl+,", "last_palette"],
|
||||
["f1", "open_help"],
|
||||
["ctrl+\\", "add_split"],
|
||||
["ctrl+k w", "close_split"],
|
||||
|
|
|
|||
|
|
@ -240,7 +240,7 @@
|
|||
["space s", "show_symbols"],
|
||||
["space d", "show_diagnostics"],
|
||||
["space a", "code_action"],
|
||||
["space '", "last_picker"],
|
||||
["space '", "last_palette"],
|
||||
["space y", "copy"],
|
||||
["space p", "system_paste_after"],
|
||||
["space /", "find_in_files"],
|
||||
|
|
@ -526,10 +526,10 @@
|
|||
["space f", "find_file"],
|
||||
["space b", "switch_buffers"],
|
||||
["space j", "jumplist_picker"],
|
||||
["space s", "symbol_picker"],
|
||||
["space s", "show_symbols"],
|
||||
["space d", "show_diagnostics"],
|
||||
["space a", "code_action"],
|
||||
["space '", "last_picker"],
|
||||
["space '", "last_palette"],
|
||||
["space y", "copy"],
|
||||
["space p", "system_paste_after"],
|
||||
["space /", "find_in_files"],
|
||||
|
|
|
|||
|
|
@ -40,12 +40,18 @@ buffer_manager: ?*BufferManager,
|
|||
split: enum { none, vertical } = .none,
|
||||
total_items: usize = 0,
|
||||
total_files_in_project: usize = 0,
|
||||
quick_activate_enabled: bool = true,
|
||||
restore_info: std.ArrayList([]const u8) = .empty,
|
||||
|
||||
const inputbox_label = "Search files by name";
|
||||
const MenuType = Menu.Options(*Self).MenuType;
|
||||
const ButtonType = MenuType.ButtonType;
|
||||
|
||||
pub fn create(allocator: std.mem.Allocator) !tui.Mode {
|
||||
return create_with_args(allocator, .{});
|
||||
}
|
||||
|
||||
pub fn create_with_args(allocator: std.mem.Allocator, ctx: command.Context) !tui.Mode {
|
||||
const mv = tui.mainview() orelse return error.NotFound;
|
||||
const self = try allocator.create(Self);
|
||||
errdefer allocator.destroy(self);
|
||||
|
|
@ -70,8 +76,15 @@ pub fn create(allocator: std.mem.Allocator) !tui.Mode {
|
|||
};
|
||||
try self.commands.init(self);
|
||||
try tui.message_filters().add(MessageFilter.bind(self, receive_project_manager));
|
||||
self.query_pending = true;
|
||||
try project_manager.request_recent_files(max_recent_files);
|
||||
|
||||
if (ctx.args.buf.len != 0) {
|
||||
try self.restore(ctx);
|
||||
self.quick_activate_enabled = false;
|
||||
} else {
|
||||
self.query_pending = true;
|
||||
try project_manager.request_recent_files(max_recent_files);
|
||||
}
|
||||
|
||||
self.do_resize();
|
||||
try mv.floating_views.add(self.modal.widget());
|
||||
try mv.floating_views.add(self.menu.container_widget);
|
||||
|
|
@ -84,6 +97,8 @@ pub fn create(allocator: std.mem.Allocator) !tui.Mode {
|
|||
}
|
||||
|
||||
pub fn deinit(self: *Self) void {
|
||||
self.save();
|
||||
self.clear_restore_info();
|
||||
self.commands.deinit();
|
||||
tui.message_filters().remove_ptr(self);
|
||||
if (tui.mainview()) |mv| {
|
||||
|
|
@ -94,6 +109,60 @@ pub fn deinit(self: *Self) void {
|
|||
self.allocator.destroy(self);
|
||||
}
|
||||
|
||||
fn clear_restore_info(self: *Self) void {
|
||||
for (self.restore_info.items) |item| self.allocator.free(item);
|
||||
self.restore_info.clearRetainingCapacity();
|
||||
}
|
||||
|
||||
fn save(self: *Self) void {
|
||||
var data: std.Io.Writer.Allocating = .init(self.allocator);
|
||||
defer data.deinit();
|
||||
const writer = &data.writer;
|
||||
|
||||
cbor.writeArrayHeader(writer, 4) catch return;
|
||||
cbor.writeValue(writer, self.inputbox.text.items) catch return;
|
||||
cbor.writeValue(writer, self.longest) catch return;
|
||||
cbor.writeValue(writer, self.menu.selected) catch return;
|
||||
cbor.writeArrayHeader(writer, self.restore_info.items.len) catch return;
|
||||
for (self.restore_info.items) |item| cbor.writeValue(writer, item) catch return;
|
||||
|
||||
tui.set_last_palette(.open_recent, .{ .args = .{ .buf = data.written() } });
|
||||
}
|
||||
|
||||
fn restore(self: *Self, ctx: command.Context) !void {
|
||||
var iter = ctx.args.buf;
|
||||
|
||||
if ((cbor.decodeArrayHeader(&iter) catch 0) != 4) return;
|
||||
|
||||
var input_: []const u8 = undefined;
|
||||
if (!(cbor.matchString(&iter, &input_) catch return)) return;
|
||||
|
||||
self.inputbox.text.shrinkRetainingCapacity(0);
|
||||
try self.inputbox.text.appendSlice(self.inputbox.allocator, input_);
|
||||
self.inputbox.cursor = tui.egc_chunk_width(self.inputbox.text.items, 0, 8);
|
||||
|
||||
if (!(cbor.matchValue(&iter, cbor.extract(&self.longest)) catch return)) return;
|
||||
|
||||
var selected: ?usize = null;
|
||||
if (!(cbor.matchValue(&iter, cbor.extract(&selected)) catch return)) return;
|
||||
|
||||
var len = cbor.decodeArrayHeader(&iter) catch 0;
|
||||
while (len > 0) : (len -= 0) {
|
||||
var item: []const u8 = undefined;
|
||||
if (!(cbor.matchString(&iter, &item) catch break)) break;
|
||||
const data = try self.allocator.dupe(u8, item);
|
||||
errdefer self.allocator.free(data);
|
||||
try self.restore_item(data);
|
||||
}
|
||||
|
||||
self.do_resize();
|
||||
|
||||
if (selected) |idx| {
|
||||
var i = idx + 1;
|
||||
while (i > 0) : (i -= 1) self.menu.select_down();
|
||||
}
|
||||
}
|
||||
|
||||
inline fn menu_width(self: *Self) usize {
|
||||
return @max(@min(self.longest + 3, max_menu_width()) + 5, inputbox_label.len + 2);
|
||||
}
|
||||
|
|
@ -129,6 +198,7 @@ fn do_resize(self: *Self) void {
|
|||
}
|
||||
|
||||
fn menu_action_open_file(menu: **MenuType, button: *ButtonType, _: Widget.Pos) void {
|
||||
menu.*.opts.ctx.save();
|
||||
var file_path: []const u8 = undefined;
|
||||
var iter = button.opts.label;
|
||||
if (!(cbor.matchString(&iter, &file_path) catch false)) return;
|
||||
|
|
@ -148,7 +218,6 @@ fn add_item(
|
|||
indicator: []const u8,
|
||||
matches: ?[]const u8,
|
||||
) !void {
|
||||
self.total_items += 1;
|
||||
var label: std.Io.Writer.Allocating = .init(self.allocator);
|
||||
defer label.deinit();
|
||||
const writer = &label.writer;
|
||||
|
|
@ -157,7 +226,18 @@ fn add_item(
|
|||
try cbor.writeValue(writer, file_color);
|
||||
try cbor.writeValue(writer, indicator);
|
||||
if (matches) |cb| _ = try writer.write(cb) else try cbor.writeValue(writer, &[_]usize{});
|
||||
try self.menu.add_item_with_handler(label.written(), menu_action_open_file);
|
||||
const data = try label.toOwnedSlice();
|
||||
errdefer self.allocator.free(data);
|
||||
try self.restore_item(data);
|
||||
}
|
||||
|
||||
fn restore_item(
|
||||
self: *Self,
|
||||
label: []const u8,
|
||||
) error{OutOfMemory}!void {
|
||||
self.total_items += 1;
|
||||
try self.menu.add_item_with_handler(label, menu_action_open_file);
|
||||
(try self.restore_info.addOne(self.allocator)).* = label;
|
||||
}
|
||||
|
||||
fn receive_project_manager(self: *Self, _: tp.pid_ref, m: tp.message) MessageFilter.Error!bool {
|
||||
|
|
@ -253,6 +333,7 @@ fn start_query(self: *Self) MessageFilter.Error!void {
|
|||
self.total_items = 0;
|
||||
if (self.query_pending) return;
|
||||
self.query_pending = true;
|
||||
self.clear_restore_info();
|
||||
try project_manager.query_recent_files(max_recent_files, self.inputbox.text.items);
|
||||
}
|
||||
|
||||
|
|
@ -370,11 +451,14 @@ const cmds = struct {
|
|||
pub const palette_menu_activate_alternate_meta: Meta = .{};
|
||||
|
||||
pub fn palette_menu_activate_quick(self: *Self, _: Ctx) Result {
|
||||
if (!self.quick_activate_enabled) return;
|
||||
if (self.menu.selected orelse 0 > 0) self.menu.activate_selected();
|
||||
self.quick_activate_enabled = false;
|
||||
}
|
||||
pub const palette_menu_activate_quick_meta: Meta = .{};
|
||||
|
||||
pub fn palette_menu_cancel(self: *Self, _: Ctx) Result {
|
||||
self.save();
|
||||
try self.cmd("exit_overlay_mode", .{});
|
||||
}
|
||||
pub const palette_menu_cancel_meta: Meta = .{};
|
||||
|
|
|
|||
|
|
@ -85,9 +85,19 @@ clipboard_current_group_number: usize = 0,
|
|||
color_scheme: enum { dark, light } = .dark,
|
||||
color_scheme_locked: bool = false,
|
||||
hint_mode: HintMode = .prefix,
|
||||
last_palette: ?LastPalette = null,
|
||||
|
||||
const HintMode = enum { none, prefix, all };
|
||||
|
||||
const LastPalette = struct {
|
||||
type_: PaletteType,
|
||||
ctx: command.Context,
|
||||
};
|
||||
|
||||
pub const PaletteType = enum {
|
||||
open_recent,
|
||||
};
|
||||
|
||||
pub const ClipboardEntry = struct {
|
||||
text: []const u8 = &.{},
|
||||
group: usize = 0,
|
||||
|
|
@ -1177,6 +1187,17 @@ const cmds = struct {
|
|||
}
|
||||
pub const open_recent_meta: Meta = .{ .description = "Open recent" };
|
||||
|
||||
pub fn last_palette(self: *Self, _: Ctx) Result {
|
||||
const palette = self.last_palette orelse {
|
||||
self.logger.print("no previously used palette", .{});
|
||||
return;
|
||||
};
|
||||
switch (palette.type_) {
|
||||
.open_recent => return self.enter_overlay_mode_with_args(@import("mode/overlay/open_recent.zig"), palette.ctx),
|
||||
}
|
||||
}
|
||||
pub const last_palette_meta: Meta = .{ .description = "Open last used palette" };
|
||||
|
||||
pub fn show_vcs_status(self: *Self, _: Ctx) Result {
|
||||
return self.enter_overlay_mode(@import("mode/overlay/vcs_status.zig"));
|
||||
}
|
||||
|
|
@ -2234,3 +2255,15 @@ fn clipboard_send_to_system_internal(self: *Self, text: []const u8) void {
|
|||
self.rdr_.copy_to_system_clipboard(text);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_last_palette(type_: PaletteType, ctx: command.Context) void {
|
||||
const self = current();
|
||||
if (self.last_palette) |old| {
|
||||
self.allocator.free(old.ctx.args.buf);
|
||||
self.last_palette = null;
|
||||
}
|
||||
self.last_palette = .{
|
||||
.type_ = type_,
|
||||
.ctx = .{ .args = ctx.args.clone(self.allocator) catch return },
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue