diff --git a/src/config.zig b/src/config.zig index f232d3c..bc4ad69 100644 --- a/src/config.zig +++ b/src/config.zig @@ -43,6 +43,11 @@ widget_style: WidgetStyle = .compact, palette_style: WidgetStyle = .bars_top_bottom, panel_style: WidgetStyle = .compact, home_style: WidgetStyle = .bars_top_bottom, +pane_left_style: WidgetStyle = .bar_right, +pane_right_style: WidgetStyle = .bar_left, + +centered_view: bool = true, +centered_view_width: usize = 124, lsp_output: enum { quiet, verbose } = .quiet, @@ -78,11 +83,15 @@ pub const WidgetType = enum { palette, panel, home, + pane_left, + pane_right, }; pub const WidgetStyle = enum { bars_top_bottom, bars_left_right, + bar_left, + bar_right, thick_boxed, extra_thick_boxed, dotted_boxed, diff --git a/src/keybind/builtin/flow.json b/src/keybind/builtin/flow.json index c608c42..64dffca 100644 --- a/src/keybind/builtin/flow.json +++ b/src/keybind/builtin/flow.json @@ -8,6 +8,7 @@ ["f1", "open_help"], ["ctrl+\\", "add_split"], ["ctrl+k w", "close_split"], + ["ctrl+k x", "toggle_centered_view"], ["ctrl+1", "focus_split", 0], ["ctrl+2", "focus_split", 1], ["ctrl+3", "focus_split", 2], @@ -56,6 +57,7 @@ ["ctrl+0", "reset_fontsize"], ["ctrl+plus", "adjust_fontsize", 1.0], ["ctrl+minus", "adjust_fontsize", -1.0], + ["alt+f5", "open_config"], ["f5", ["create_scratch_buffer", "*test*"], ["shell_execute_insert", "zig", "build", "test"]], ["f7", ["create_scratch_buffer", "*build*"], ["shell_execute_insert", "zig", "build"]], ["ctrl+f6", "open_version_info"], @@ -113,7 +115,7 @@ ["ctrl+kp_right", "move_word_right"], ["ctrl+backspace", "delete_word_left"], ["ctrl+delete", "delete_word_right"], - ["ctrl+f5", "toggle_inspector_view"], + ["alt+shift+f5", "toggle_inspector_view"], ["ctrl+f10", "toggle_whitespace_mode"], ["ctrl+f12", "goto_implementation"], ["ctrl+shift+s", "save_as"], @@ -216,8 +218,6 @@ ["f2", "rename_symbol"], ["f3", "goto_next_match"], ["f15", "goto_prev_match"], - ["ctrl+f5", "dump_current_line_tree"], - ["ctrl+f7", "dump_current_line"], ["f9", "theme_prev"], ["f10", "theme_next"], ["f11", "toggle_panel"], @@ -360,7 +360,6 @@ ["f", "change_fontface"], ["ctrl+f ctrl+f ctrl+f ctrl+f ctrl+f", "home_sheeran"], ["ctrl+shift+r", "restart"], - ["f6", "open_config"], ["v", "open_version_info"], ["ctrl+q", "quit"], ["q", "quit"], diff --git a/src/keybind/builtin/helix.json b/src/keybind/builtin/helix.json index 0869eae..f016a75 100644 --- a/src/keybind/builtin/helix.json +++ b/src/keybind/builtin/helix.json @@ -26,6 +26,13 @@ ["ctrl+x", "decrement"], ["ctrl+^", "open_previous_file"], + ["ctrl+w v", "add_split"], + ["ctrl+w h", "goto_left_split"], + ["ctrl+w l", "goto_right_split"], + ["ctrl+w H", "swap_left_split"], + ["ctrl+w L", "swap_right_split"], + ["ctrl+w q", "close_split"], + ["ctrl+w o", "close_other_splits"], ["alt+.", "repeat_last_motion"], ["alt+d", "delete_backward"], diff --git a/src/tui/WidgetStyle.zig b/src/tui/WidgetStyle.zig index 4f91d71..fd5e713 100644 --- a/src/tui/WidgetStyle.zig +++ b/src/tui/WidgetStyle.zig @@ -29,6 +29,8 @@ pub const Margin = struct { const @"top/bottom/2": Margin = .{ .top = 2, .bottom = 2, .left = 0, .right = 0 }; const @"left/right/1": Margin = .{ .top = 0, .bottom = 0, .left = 1, .right = 1 }; const @"left/right/2": Margin = .{ .top = 0, .bottom = 0, .left = 2, .right = 2 }; + const @"left/1": Margin = .{ .top = 0, .bottom = 0, .left = 1, .right = 0 }; + const @"right/1": Margin = .{ .top = 0, .bottom = 0, .left = 0, .right = 1 }; }; pub const Border = struct { @@ -112,6 +114,16 @@ const bars_left_right: @This() = .{ .border = Border.@"thick box (octant)", }; +const bar_left: @This() = .{ + .padding = Margin.@"left/1", + .border = Border.@"thick box (octant)", +}; + +const bar_right: @This() = .{ + .padding = Margin.@"right/1", + .border = Border.@"thick box (octant)", +}; + pub fn from_tag(tag: WidgetStyle) *const @This() { return switch (tag) { .compact => &compact, @@ -126,6 +138,8 @@ pub fn from_tag(tag: WidgetStyle) *const @This() { .extra_thick_boxed => &extra_thick_boxed, .bars_top_bottom => &bars_top_bottom, .bars_left_right => &bars_left_right, + .bar_left => &bar_left, + .bar_right => &bar_right, }; } @@ -137,5 +151,7 @@ pub fn theme_style_from_type(style_type: WidgetType, theme: *const Theme) Theme. .palette => .{ .fg = theme.editor_widget_border.fg, .bg = theme.editor_widget.bg }, .panel => .{ .fg = theme.editor_widget_border.fg, .bg = theme.editor.bg }, .home => .{ .fg = theme.editor_widget_border.fg, .bg = theme.editor.bg }, + .pane_left => .{ .fg = theme.editor_widget.bg, .bg = theme.panel.bg }, + .pane_right => .{ .fg = theme.editor_widget.bg, .bg = theme.panel.bg }, }; } diff --git a/src/tui/mainview.zig b/src/tui/mainview.zig index 3dd05ac..111b53c 100644 --- a/src/tui/mainview.zig +++ b/src/tui/mainview.zig @@ -47,6 +47,8 @@ active_editor: ?*ed.Editor = null, views: *WidgetList, views_widget: Widget, active_view: usize = 0, +panes: *WidgetList, +panes_widget: Widget, panels: ?*WidgetList = null, last_match_text: ?[]const u8 = null, location_history_: location_history, @@ -77,6 +79,8 @@ pub fn create(allocator: std.mem.Allocator) CreateError!Widget { .location_history_ = try location_history.create(), .views = undefined, .views_widget = undefined, + .panes = undefined, + .panes_widget = undefined, .buffer_manager = Buffer.Manager.init(allocator), }; try self.commands.init(self); @@ -93,7 +97,12 @@ pub fn create(allocator: std.mem.Allocator) CreateError!Widget { self.views_widget = views.widget(); try views.add(try Widget.empty(allocator, self.views_widget.plane.*, .dynamic)); - try widgets.add(self.views_widget); + const panes = try WidgetList.createH(allocator, self.plane, @typeName(Self), .dynamic); + self.panes = panes; + self.panes_widget = panes.widget(); + try self.update_panes_layout(); + + try widgets.add(self.panes_widget); if (tui.config().bottom_bar.len > 0) { self.bottom_bar = (try widgets.addP(try @import("status/bar.zig").create(allocator, self.plane, tui.config().bottom_bar, .grip, EventHandler.bind(self, handle_bottom_bar_event)))).*; @@ -180,6 +189,34 @@ pub fn update(self: *Self) void { self.floating_views.update(); } +pub fn update_panes_layout(self: *Self) !void { + while (self.panes.pop()) |widget| if (widget.dynamic_cast(WidgetList) == null) + widget.deinit(self.allocator); + const centered_view_width = tui.config().centered_view_width; + const screen_width = tui.screen().w; + const need_padding = screen_width > centered_view_width; + if (need_padding and tui.config().centered_view and self.views.widgets.items.len == 1) { + const padding = (screen_width - centered_view_width) / 2; + try self.panes.add(try self.create_padding_pane(padding, .pane_left)); + try self.panes.add(self.views_widget); + try self.panes.add(try self.create_padding_pane(padding, .pane_right)); + } else { + try self.panes.add(self.views_widget); + } +} + +fn create_padding_pane(self: *Self, padding: usize, widget_type: Widget.Type) !Widget { + const pane = try WidgetList.createHStyled( + self.allocator, + self.panes_widget.plane.*, + @typeName(Self), + .{ .static = padding }, + widget_type, + ); + try pane.add(try Widget.empty(self.allocator, self.views_widget.plane.*, .dynamic)); + return pane.widget(); +} + pub fn render(self: *Self, theme: *const Widget.Theme) bool { const widgets_more = self.widgets.render(theme); const views_more = self.floating_views.render(theme); @@ -187,6 +224,7 @@ pub fn render(self: *Self, theme: *const Widget.Theme) bool { } pub fn handle_resize(self: *Self, pos: Box) void { + self.update_panes_layout() catch {}; self.plane = tui.plane(); if (self.panel_height) |h| if (h >= self.box().h) { self.panel_height = null; @@ -786,7 +824,7 @@ const cmds = struct { pub const add_split_meta: Meta = .{ .description = "Add split view" }; pub fn close_split(self: *Self, _: Ctx) Result { - if (self.views.widgets.items.len == 1) + if (self.views.widgets.items.len == 1 and self.views.widgets.items[0].widget.dynamic_cast(home) != null) return command.executeName("quit", .{}); return self.remove_active_view(); } diff --git a/src/tui/tui.zig b/src/tui/tui.zig index 75058ce..09a8462 100644 --- a/src/tui/tui.zig +++ b/src/tui/tui.zig @@ -1020,6 +1020,14 @@ const cmds = struct { } pub const toggle_highlight_columns_meta: Meta = .{ .description = "Toggle highlight columns" }; + pub fn toggle_centered_view(self: *Self, _: Ctx) Result { + defer self.logger.print("centered view {s}", .{if (self.config_.centered_view) "enabled" else "disabled"}); + self.config_.centered_view = !self.config_.centered_view; + try save_config(); + resize(); + } + pub const toggle_centered_view_meta: Meta = .{ .description = "Toggle centered view" }; + pub fn force_color_scheme(self: *Self, ctx: Ctx) Result { self.force_color_scheme(if (try ctx.args.match(.{"dark"})) .dark @@ -1983,6 +1991,8 @@ pub fn get_widget_style(widget_type: WidgetType) *const WidgetStyle { .palette => WidgetStyle.from_tag(config_.palette_style), .panel => WidgetStyle.from_tag(config_.panel_style), .home => WidgetStyle.from_tag(config_.home_style), + .pane_left => WidgetStyle.from_tag(config_.pane_left_style), + .pane_right => WidgetStyle.from_tag(config_.pane_right_style), }; } @@ -2006,6 +2016,8 @@ fn widget_type_config_variable(widget_type: WidgetType) *ConfigWidgetStyle { .palette => &config_.palette_style, .panel => &config_.panel_style, .home => &config_.home_style, + .pane_left => &config_.pane_left_style, + .pane_right => &config_.pane_right_style, }; }