feat: improve layout of filelist view
This commit is contained in:
parent
3a7e124255
commit
3cbca45b82
3 changed files with 32 additions and 16 deletions
11
src/main.zig
11
src/main.zig
|
@ -587,3 +587,14 @@ pub fn is_directory(rel_path: []const u8) !bool {
|
||||||
dir.close();
|
dir.close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn shorten_path(buf: []u8, path: []const u8, removed_prefix: *usize, max_len: usize) []const u8 {
|
||||||
|
removed_prefix.* = 0;
|
||||||
|
if (path.len <= max_len) return path;
|
||||||
|
const ellipsis = "…";
|
||||||
|
const prefix = path.len - max_len;
|
||||||
|
defer removed_prefix.* = prefix - 1;
|
||||||
|
@memcpy(buf[0..ellipsis.len], ellipsis);
|
||||||
|
@memcpy(buf[ellipsis.len .. max_len + ellipsis.len], path[prefix..]);
|
||||||
|
return buf[0 .. max_len + ellipsis.len];
|
||||||
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ const tp = @import("thespian");
|
||||||
const log = @import("log");
|
const log = @import("log");
|
||||||
const key = @import("renderer").input.key;
|
const key = @import("renderer").input.key;
|
||||||
const event_type = @import("renderer").input.event_type;
|
const event_type = @import("renderer").input.event_type;
|
||||||
|
const root = @import("root");
|
||||||
|
|
||||||
const command = @import("command.zig");
|
const command = @import("command.zig");
|
||||||
const tui = @import("tui.zig");
|
const tui = @import("tui.zig");
|
||||||
|
@ -37,9 +38,12 @@ commands: Commands = undefined,
|
||||||
items: usize = 0,
|
items: usize = 0,
|
||||||
view_pos: usize = 0,
|
view_pos: usize = 0,
|
||||||
view_rows: usize = 0,
|
view_rows: usize = 0,
|
||||||
|
view_cols: usize = 0,
|
||||||
entries: std.ArrayList(Entry) = undefined,
|
entries: std.ArrayList(Entry) = undefined,
|
||||||
selected: ?usize = null,
|
selected: ?usize = null,
|
||||||
|
|
||||||
|
const path_column_ratio = 4;
|
||||||
|
|
||||||
const Entry = struct {
|
const Entry = struct {
|
||||||
path: []const u8,
|
path: []const u8,
|
||||||
begin_line: usize,
|
begin_line: usize,
|
||||||
|
@ -79,6 +83,7 @@ pub fn handle_resize(self: *Self, pos: Widget.Box) void {
|
||||||
self.plane.resize_simple(@intCast(pos.h), @intCast(pos.w)) catch return;
|
self.plane.resize_simple(@intCast(pos.h), @intCast(pos.w)) catch return;
|
||||||
self.menu.container_widget.resize(pos);
|
self.menu.container_widget.resize(pos);
|
||||||
self.view_rows = pos.h;
|
self.view_rows = pos.h;
|
||||||
|
self.view_cols = pos.w;
|
||||||
self.update_scrollbar();
|
self.update_scrollbar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +126,9 @@ pub fn render(self: *Self, theme: *const Widget.Theme) bool {
|
||||||
|
|
||||||
fn handle_render_menu(self: *Self, button: *Button.State(*Menu.State(*Self)), theme: *const Widget.Theme, selected: bool) bool {
|
fn handle_render_menu(self: *Self, button: *Button.State(*Menu.State(*Self)), theme: *const Widget.Theme, selected: bool) bool {
|
||||||
const style_base = if (button.active) theme.editor_cursor else if (button.hover or selected) theme.editor_selection else theme.panel;
|
const style_base = if (button.active) theme.editor_cursor else if (button.hover or selected) theme.editor_selection else theme.panel;
|
||||||
// const style_keybind = if (tui.find_scope_style(theme, "entity.name")) |sty| sty.style else style_base;
|
const style_info: Widget.Theme.Style = .{ .fg = theme.editor_information.fg, .fs = theme.editor_information.fs, .bg = style_base.bg };
|
||||||
|
const style_separator: Widget.Theme.Style = .{ .fg = theme.editor_selection.bg, .bg = style_base.bg };
|
||||||
|
// const style_error: Widget.Theme.Style = .{ .fg = theme.editor_error.fg, .fs = theme.editor_error.fs, .bg = style_base.bg };
|
||||||
button.plane.set_base_style(" ", style_base);
|
button.plane.set_base_style(" ", style_base);
|
||||||
button.plane.erase();
|
button.plane.erase();
|
||||||
button.plane.home();
|
button.plane.home();
|
||||||
|
@ -140,8 +147,16 @@ fn handle_render_menu(self: *Self, button: *Button.State(*Menu.State(*Self)), th
|
||||||
const entry = &self.entries.items[idx];
|
const entry = &self.entries.items[idx];
|
||||||
const pointer = if (selected) "⏵" else " ";
|
const pointer = if (selected) "⏵" else " ";
|
||||||
_ = button.plane.print("{s} ", .{pointer}) catch {};
|
_ = button.plane.print("{s} ", .{pointer}) catch {};
|
||||||
|
var buf: [std.fs.max_path_bytes]u8 = undefined;
|
||||||
|
var removed_prefix: usize = 0;
|
||||||
|
const max_len = self.view_cols / path_column_ratio;
|
||||||
button.plane.set_style(style_base);
|
button.plane.set_style(style_base);
|
||||||
_ = button.plane.print("{s}:{d} {s}", .{ entry.path, entry.begin_line + 1, entry.lines }) catch {};
|
_ = button.plane.print("{s}:{d}", .{ root.shorten_path(&buf, entry.path, &removed_prefix, max_len - 6), entry.begin_line + 1 }) catch {};
|
||||||
|
button.plane.cursor_move_yx(0, @intCast(max_len)) catch return false;
|
||||||
|
button.plane.set_style(style_separator);
|
||||||
|
_ = button.plane.print(" ▏", .{}) catch {};
|
||||||
|
button.plane.set_style(style_info);
|
||||||
|
_ = button.plane.print("{s}", .{entry.lines}) catch {};
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ const std = @import("std");
|
||||||
const tp = @import("thespian");
|
const tp = @import("thespian");
|
||||||
const log = @import("log");
|
const log = @import("log");
|
||||||
const cbor = @import("cbor");
|
const cbor = @import("cbor");
|
||||||
|
const root = @import("root");
|
||||||
|
|
||||||
const Plane = @import("renderer").Plane;
|
const Plane = @import("renderer").Plane;
|
||||||
const planeutils = @import("renderer").planeutils;
|
const planeutils = @import("renderer").planeutils;
|
||||||
|
@ -88,7 +89,7 @@ inline fn max_menu_width() usize {
|
||||||
return @max(15, width - (width / 5));
|
return @max(15, width - (width / 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_render_menu(self: *Self, button: *Button.State(*Menu.State(*Self)), theme: *const Widget.Theme, selected: bool) bool {
|
fn on_render_menu(_: *Self, button: *Button.State(*Menu.State(*Self)), theme: *const Widget.Theme, selected: bool) bool {
|
||||||
const style_base = if (button.active) theme.editor_cursor else if (button.hover or selected) theme.editor_selection else theme.editor_widget;
|
const style_base = if (button.active) theme.editor_cursor else if (button.hover or selected) theme.editor_selection else theme.editor_widget;
|
||||||
const style_keybind = if (tui.find_scope_style(theme, "entity.name")) |sty| sty.style else style_base;
|
const style_keybind = if (tui.find_scope_style(theme, "entity.name")) |sty| sty.style else style_base;
|
||||||
button.plane.set_base_style(" ", style_base);
|
button.plane.set_base_style(" ", style_base);
|
||||||
|
@ -103,9 +104,10 @@ fn on_render_menu(self: *Self, button: *Button.State(*Menu.State(*Self)), theme:
|
||||||
_ = button.plane.print("{s}", .{ pointer }) catch {};
|
_ = button.plane.print("{s}", .{ pointer }) catch {};
|
||||||
var buf: [std.fs.max_path_bytes]u8 = undefined;
|
var buf: [std.fs.max_path_bytes]u8 = undefined;
|
||||||
var removed_prefix: usize = 0;
|
var removed_prefix: usize = 0;
|
||||||
|
const max_len = max_menu_width() - 2;
|
||||||
button.plane.set_style(style_base);
|
button.plane.set_style(style_base);
|
||||||
_ = button.plane.print("{s} ", .{
|
_ = button.plane.print("{s} ", .{
|
||||||
if (file_path.len > max_menu_width() - 2) self.shorten_path(&buf, file_path, &removed_prefix) else file_path,
|
if (file_path.len > max_len) root.shorten_path(&buf, file_path, &removed_prefix, max_len) else file_path,
|
||||||
}) catch {};
|
}) catch {};
|
||||||
var index: usize = 0;
|
var index: usize = 0;
|
||||||
var len = cbor.decodeArrayHeader(&iter) catch return false;
|
var len = cbor.decodeArrayHeader(&iter) catch return false;
|
||||||
|
@ -138,18 +140,6 @@ fn menu_action_open_file(menu: **Menu.State(*Self), button: *Button.State(*Menu.
|
||||||
tp.self_pid().send(.{ "cmd", "navigate", .{ .file = file_path } }) 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shorten_path(_: *Self, buf: []u8, path: []const u8, removed_prefix: *usize) []const u8 {
|
|
||||||
const max_len = max_menu_width() - 2;
|
|
||||||
removed_prefix.* = 0;
|
|
||||||
if (path.len <= max_len) return path;
|
|
||||||
const ellipsis = "…";
|
|
||||||
const prefix = path.len - max_len;
|
|
||||||
defer removed_prefix.* = prefix - 1;
|
|
||||||
@memcpy(buf[0..ellipsis.len], ellipsis);
|
|
||||||
@memcpy(buf[ellipsis.len .. max_len + ellipsis.len], path[prefix..]);
|
|
||||||
return buf[0 .. max_len + ellipsis.len];
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_item(self: *Self, file_name: []const u8, matches: ?[]const u8) !void {
|
fn add_item(self: *Self, file_name: []const u8, matches: ?[]const u8) !void {
|
||||||
var label = std.ArrayList(u8).init(self.a);
|
var label = std.ArrayList(u8).init(self.a);
|
||||||
defer label.deinit();
|
defer label.deinit();
|
||||||
|
|
Loading…
Add table
Reference in a new issue