diff --git a/src/config.zig b/src/config.zig index 7436e84..f2a65e6 100644 --- a/src/config.zig +++ b/src/config.zig @@ -17,6 +17,7 @@ whitespace_mode: []const u8 = "none", inline_diagnostics: bool = true, animation_min_lag: usize = 0, //milliseconds animation_max_lag: usize = 50, //milliseconds +hover_time_ms: usize = 500, //milliseconds enable_format_on_save: bool = false, restore_last_cursor_position: bool = true, follow_cursor_on_buffer_switch: bool = false, //scroll cursor into view on buffer switch diff --git a/src/git.zig b/src/git.zig index 714ba86..1bf696d 100644 --- a/src/git.zig +++ b/src/git.zig @@ -168,7 +168,8 @@ pub fn status(context_: usize) Error!void { }.result, struct { fn result(_: usize, _: tp.pid_ref, output: []const u8) void { var it = std.mem.splitScalar(u8, output, '\n'); - while (it.next()) |line| std.log.err("{s}: {s}", .{ module_name, line }); + while (it.next()) |line| if (line.len > 0) + std.log.err("{s}: {s}", .{ module_name, line }); } }.result, exit_null(tag)); } @@ -183,7 +184,8 @@ fn git_line_output(context_: usize, comptime tag: []const u8, cmd: anytype) Erro }.result, struct { fn result(_: usize, _: tp.pid_ref, output: []const u8) void { var it = std.mem.splitScalar(u8, output, '\n'); - while (it.next()) |line| std.log.err("{s}: {s}", .{ module_name, line }); + while (it.next()) |line| if (line.len > 0) + std.log.err("{s}: {s}", .{ module_name, line }); } }.result, exit_null(tag)); } diff --git a/src/keybind/builtin/emacs.json b/src/keybind/builtin/emacs.json index b2a9c71..661a77d 100644 --- a/src/keybind/builtin/emacs.json +++ b/src/keybind/builtin/emacs.json @@ -1,5 +1,5 @@ { - "project": { + "normal": { "press": [ ["f4", "toggle_input_mode"], ["ctrl+0", "reset_fontsize"], @@ -7,17 +7,11 @@ ["ctrl+-", "adjust_fontsize", -1.0], ["ctrl+r", "find_file"], ["ctrl+h ctrl+a", "open_help"], - ["ctrl+x ctrl+f", "open_file"], - ["ctrl+x b", "open_recent"], ["ctrl+c ctrl+o", "open_recent_project"], ["ctrl+c g", "find_in_files"], ["alt+x", "open_command_palette"], - ["ctrl+x ctrl+c", "quit"] - ] - }, - "normal": { - "inherit": "project", - "press": [ + ["ctrl+x ctrl+c", "quit"], + ["ctrl+g", "cancel"], ["ctrl+_", "undo"], ["\u001f", "undo"], @@ -115,9 +109,21 @@ }, "home": { "on_match_failure": "ignore", - "inherit": "project", "press": [ - ["f", "change_fontface"] + ["f", "change_fontface"], + ["f4", "toggle_input_mode"], + ["ctrl+0", "reset_fontsize"], + ["ctrl+=", "adjust_fontsize", 1.0], + ["ctrl+-", "adjust_fontsize", -1.0], + ["ctrl+r", "find_file"], + ["ctrl+h ctrl+a", "open_help"], + ["ctrl+x ctrl+f", "open_file"], + ["ctrl+x ctrl+r", "open_recent"], + ["ctrl+x b", "switch_buffers"], + ["ctrl+c ctrl+o", "open_recent_project"], + ["ctrl+c g", "find_in_files"], + ["alt+x", "open_command_palette"], + ["ctrl+x ctrl+c", "quit"] ] } } diff --git a/src/tui/editor.zig b/src/tui/editor.zig index e432ab8..f6943c7 100644 --- a/src/tui/editor.zig +++ b/src/tui/editor.zig @@ -6043,6 +6043,7 @@ pub const EditorWidget = struct { hover_timer: ?tp.Cancellable = null, hover_x: c_int = -1, hover_y: c_int = -1, + hover_mouse_event: bool = false, const Self = @This(); const Commands = command.Collection(Editor); @@ -6109,8 +6110,10 @@ pub const EditorWidget = struct { const hover_y, const hover_x = self.editor.plane.abs_yx_to_rel(y, x); if (hover_y != self.hover_y or hover_x != self.hover_x) { self.hover_y, self.hover_x = .{ hover_y, hover_x }; - if (self.editor.jump_mode) + if (self.editor.jump_mode) { self.update_hover_timer(.init); + self.hover_mouse_event = true; + } } } else if (try m.match(.{ "B", tp.extract(&event), tp.extract(&btn), tp.any, tp.extract(&x), tp.extract(&y), tp.extract(&xpx), tp.extract(&ypx) })) { try self.mouse_click_event(event, @enumFromInt(btn), y, x, ypx, xpx); @@ -6138,7 +6141,7 @@ pub const EditorWidget = struct { } } else if (try m.match(.{"HOVER"})) { self.update_hover_timer(.fired); - if (self.hover_y >= 0 and self.hover_x >= 0) + if (self.hover_y >= 0 and self.hover_x >= 0 and self.hover_mouse_event) try self.editor.hover_at_abs(@intCast(self.hover_y), @intCast(self.hover_x)); } else if (try m.match(.{ "whitespace_mode", tp.extract(&bytes) })) { self.editor.render_whitespace = Editor.from_whitespace_mode(bytes); @@ -6155,7 +6158,8 @@ pub const EditorWidget = struct { self.hover_timer = null; } if (event == .init) { - const delay_us: u64 = std.time.us_per_ms * 100; + self.hover_mouse_event = false; + const delay_us: u64 = std.time.us_per_ms * tui.config().hover_time_ms; self.hover_timer = tp.self_pid().delay_send_cancellable(self.editor.allocator, "editor.hover_timer", delay_us, .{"HOVER"}) catch null; } } diff --git a/src/tui/mainview.zig b/src/tui/mainview.zig index f32b90a..b0c2c03 100644 --- a/src/tui/mainview.zig +++ b/src/tui/mainview.zig @@ -337,8 +337,7 @@ const cmds = struct { tui.rdr().set_terminal_working_directory(project); if (self.top_bar) |bar| _ = try bar.msg(.{ "PRJ", "open" }); if (self.bottom_bar) |bar| _ = try bar.msg(.{ "PRJ", "open" }); - if (try project_manager.request_most_recent_file(self.allocator)) |file_path| - self.show_file_async_and_free(file_path); + tp.self_pid().send(.{ "cmd", "open_recent" }) catch return; } pub const change_project_meta: Meta = .{ .arguments = &.{.string} }; @@ -1224,11 +1223,6 @@ fn toggle_inputview_async(_: *Self) void { tp.self_pid().send(.{ "cmd", "toggle_inputview" }) catch return; } -fn show_file_async_and_free(self: *Self, file_path: []const u8) void { - defer self.allocator.free(file_path); - self.show_file_async(file_path); -} - fn show_file_async(_: *Self, file_path: []const u8) void { tp.self_pid().send(.{ "cmd", "navigate", .{ .file = file_path } }) catch return; } diff --git a/src/tui/mode/mini/open_file.zig b/src/tui/mode/mini/open_file.zig index de60c07..3eeb4b6 100644 --- a/src/tui/mode/mini/open_file.zig +++ b/src/tui/mode/mini/open_file.zig @@ -2,6 +2,7 @@ const std = @import("std"); const tp = @import("thespian"); const root = @import("root"); const command = @import("command"); +const project_manager = @import("project_manager"); const tui = @import("../../tui.zig"); @@ -10,6 +11,11 @@ pub const Type = @import("file_browser.zig").Create(@This()); pub const create = Type.create; pub fn load_entries(self: *Type) error{ Exit, OutOfMemory }!void { + var project_name_buf: [512]u8 = undefined; + const project_path = tp.env.get().str("project"); + const project_name = project_manager.abbreviate_home(&project_name_buf, project_path); + try self.file_path.appendSlice(project_name); + try self.file_path.append(std.fs.path.sep); const editor = tui.get_active_editor() orelse return; if (editor.file_path) |old_path| if (std.mem.lastIndexOf(u8, old_path, "/")) |pos| @@ -28,8 +34,15 @@ pub fn name(_: *Type) []const u8 { } pub fn select(self: *Type) void { - if (root.is_directory(self.file_path.items)) return; - if (self.file_path.items.len > 0) - tp.self_pid().send(.{ "cmd", "navigate", .{ .file = self.file_path.items } }) catch {}; + var buf = std.ArrayList(u8).init(self.allocator); + defer buf.deinit(); + const file_path = project_manager.expand_home(&buf, self.file_path.items); + if (root.is_directory(file_path)) { + tp.self_pid().send(.{ "cmd", "exit_overlay_mode" }) catch return; + tp.self_pid().send(.{ "cmd", "change_project", .{file_path} }) catch {}; + return; + } + if (file_path.len > 0) + tp.self_pid().send(.{ "cmd", "navigate", .{ .file = file_path } }) catch {}; command.executeName("exit_mini_mode", .{}) catch {}; } diff --git a/src/tui/status/branch.zig b/src/tui/status/branch.zig index 3ad6457..940699d 100644 --- a/src/tui/status/branch.zig +++ b/src/tui/status/branch.zig @@ -66,8 +66,8 @@ fn on_click(self: *Self, _: *Button.State(Self)) void { command.executeName("show_git_status", .{}) catch {}; } -fn refresh_git_status(_: *Self) void { - git.status(0) catch {}; +fn refresh_git_status(self: *Self) void { + if (self.workspace_path) |_| git.status(0) catch {}; } pub fn receive(self: *Self, _: *Button.State(Self), _: tp.pid_ref, m: tp.message) error{Exit}!bool {