Compare commits
6 commits
b2b34e4710
...
a1f296ddde
| Author | SHA1 | Date | |
|---|---|---|---|
| a1f296ddde | |||
| fbccf13850 | |||
| 5bb742fe58 | |||
| 93be688e6c | |||
| 51f74e37b8 | |||
| 8ccdc9654a |
7 changed files with 367 additions and 2242 deletions
43
src/main.zig
43
src/main.zig
|
|
@ -385,12 +385,13 @@ pub fn main() anyerror!void {
|
|||
|
||||
ctx.run();
|
||||
|
||||
if (want_restart) restart();
|
||||
if (want_restart) if (want_restart_with_sudo) restart_with_sudo() else restart();
|
||||
exit(final_exit_status);
|
||||
}
|
||||
|
||||
var final_exit_status: u8 = 0;
|
||||
var want_restart: bool = false;
|
||||
var want_restart_with_sudo: bool = false;
|
||||
|
||||
pub fn print_exit_status(_: void, msg: []const u8) void {
|
||||
if (std.mem.eql(u8, msg, "normal")) {
|
||||
|
|
@ -406,6 +407,10 @@ pub fn print_exit_status(_: void, msg: []const u8) void {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_restart_with_sudo() void {
|
||||
want_restart_with_sudo = true;
|
||||
}
|
||||
|
||||
fn count_args() usize {
|
||||
var args = std.process.args();
|
||||
_ = args.next();
|
||||
|
|
@ -1107,25 +1112,41 @@ pub fn get_theme_file_name(theme_name: []const u8) ![]const u8 {
|
|||
return try std.fmt.bufPrint(&local.file_buffer, "{s}{c}{s}.json", .{ dir, sep, theme_name });
|
||||
}
|
||||
|
||||
fn resolve_executable(executable: [:0]const u8) [:0]const u8 {
|
||||
return for (executable) |char| {
|
||||
if (std.fs.path.isSep(char)) break executable;
|
||||
} else bin_path.find_binary_in_path(std.heap.c_allocator, executable) catch executable orelse executable;
|
||||
}
|
||||
|
||||
fn restart() noreturn {
|
||||
var executable: [:0]const u8 = std.mem.span(std.os.argv[0]);
|
||||
var is_basename = true;
|
||||
for (executable) |char| if (std.fs.path.isSep(char)) {
|
||||
is_basename = false;
|
||||
};
|
||||
if (is_basename) {
|
||||
const a = std.heap.c_allocator;
|
||||
executable = bin_path.find_binary_in_path(a, executable) catch executable orelse executable;
|
||||
}
|
||||
const executable = resolve_executable(std.mem.span(std.os.argv[0]));
|
||||
const argv = [_]?[*:0]const u8{
|
||||
executable,
|
||||
"--restore-session",
|
||||
null,
|
||||
};
|
||||
const ret = std.c.execve(executable, @ptrCast(&argv), @ptrCast(std.os.environ));
|
||||
restart_failed(ret);
|
||||
}
|
||||
|
||||
fn restart_with_sudo() noreturn {
|
||||
const sudo_executable = resolve_executable("sudo");
|
||||
const flow_executable = resolve_executable(std.mem.span(std.os.argv[0]));
|
||||
const argv = [_]?[*:0]const u8{
|
||||
sudo_executable,
|
||||
"--preserve-env",
|
||||
flow_executable,
|
||||
"--restore-session",
|
||||
null,
|
||||
};
|
||||
const ret = std.c.execve(sudo_executable, @ptrCast(&argv), @ptrCast(std.os.environ));
|
||||
restart_failed(ret);
|
||||
}
|
||||
|
||||
fn restart_failed(ret: c_int) noreturn {
|
||||
var stderr_buffer: [1024]u8 = undefined;
|
||||
var stderr_writer = std.fs.File.stderr().writer(&stderr_buffer);
|
||||
stderr_writer.interface.print("\nrestart failed: {d}", .{ret}) catch {};
|
||||
stderr_writer.interface.print("\nrestart failed: {s}", .{@tagName(std.posix.errno(ret))}) catch {};
|
||||
stderr_writer.interface.flush() catch {};
|
||||
exit(234);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ pub const root = struct {
|
|||
|
||||
pub const exit = if (@hasDecl(hard_root, "exit")) hard_root.exit else dummy.exit;
|
||||
pub const print_exit_status = if (@hasDecl(hard_root, "print_exit_status")) hard_root.print_exit_status else dummy.print_exit_status;
|
||||
pub const set_restart_with_sudo = if (@hasDecl(hard_root, "set_restart_with_sudo")) hard_root.set_restart_with_sudo else dummy.set_restart_with_sudo;
|
||||
|
||||
pub const is_directory = if (@hasDecl(hard_root, "is_directory")) hard_root.is_directory else dummy.is_directory;
|
||||
pub const is_file = if (@hasDecl(hard_root, "is_file")) hard_root.is_file else dummy.is_file;
|
||||
|
|
@ -118,6 +119,9 @@ const dummy = struct {
|
|||
pub fn print_exit_status(_: void, _: []const u8) void {
|
||||
@panic("dummy print_exit_status call");
|
||||
}
|
||||
pub fn set_restart_with_sudo() void {
|
||||
@panic("dummy set_restart_with_sudo call");
|
||||
}
|
||||
|
||||
pub fn is_directory(_: []const u8) bool {
|
||||
@panic("dummy is_directory call");
|
||||
|
|
|
|||
|
|
@ -17,9 +17,12 @@ const keybind = @import("keybind");
|
|||
|
||||
const fonts = @import("fonts.zig");
|
||||
|
||||
pub const subtext_root = "I am groot!";
|
||||
|
||||
const style = struct {
|
||||
title: []const u8 = root.application_title,
|
||||
subtext: []const u8 = root.application_subtext,
|
||||
subtext_root: []const u8 = subtext_root,
|
||||
|
||||
centered: bool = false,
|
||||
|
||||
|
|
@ -76,6 +79,7 @@ menu_count: usize = 0,
|
|||
menu_len: usize = 0,
|
||||
max_desc_len: usize = 0,
|
||||
input_namespace: []const u8,
|
||||
root_mode: bool = false,
|
||||
|
||||
home_style: style,
|
||||
home_style_bufs: [][]const u8,
|
||||
|
|
@ -111,6 +115,9 @@ pub fn create(allocator: std.mem.Allocator, parent: Widget) !Widget {
|
|||
.home_style = home_style,
|
||||
.home_style_bufs = home_style_bufs,
|
||||
};
|
||||
if (builtin.os.tag != .windows and std.posix.geteuid() == 0) {
|
||||
self.root_mode = true;
|
||||
}
|
||||
self.commands.init_unregistered(self);
|
||||
var it = std.mem.splitAny(u8, self.home_style.menu_commands, "\n ");
|
||||
while (it.next()) |command_name| {
|
||||
|
|
@ -296,34 +303,46 @@ pub fn render(self: *Self, theme: *const Widget.Theme) bool {
|
|||
self.plane.set_base_style(theme.editor);
|
||||
|
||||
const style_title = if (tui.find_scope_style(theme, "function")) |sty| sty.style else theme.editor;
|
||||
const style_subtext = if (tui.find_scope_style(theme, "comment")) |sty| sty.style else theme.editor;
|
||||
const style_subtext = if (self.root_mode)
|
||||
theme.editor_error
|
||||
else if (tui.find_scope_style(theme, "comment")) |sty|
|
||||
sty.style
|
||||
else
|
||||
theme.editor;
|
||||
|
||||
const title = self.home_style.title;
|
||||
|
||||
const subtext = if (self.root_mode)
|
||||
self.home_style.subtext_root
|
||||
else
|
||||
self.home_style.subtext;
|
||||
|
||||
if (self.plane.dim_x() > 120 and self.plane.dim_y() > 22) {
|
||||
self.plane.cursor_move_yx(2, self.centerI(4, self.home_style.title.len * 8)) catch return false;
|
||||
fonts.print_string_large(&self.plane, self.home_style.title, style_title) catch return false;
|
||||
self.plane.cursor_move_yx(2, self.centerI(4, title.len * 8)) catch return false;
|
||||
fonts.print_string_large(&self.plane, title, style_title) catch return false;
|
||||
|
||||
self.plane.cursor_move_yx(10, self.centerI(8, self.home_style.subtext.len * 4)) catch return false;
|
||||
fonts.print_string_medium(&self.plane, self.home_style.subtext, style_subtext) catch return false;
|
||||
self.plane.cursor_move_yx(10, self.centerI(8, subtext.len * 4)) catch return false;
|
||||
fonts.print_string_medium(&self.plane, subtext, style_subtext) catch return false;
|
||||
|
||||
self.position_menu(self.v_center(15, self.menu_len, 15), self.center(10, self.menu_w));
|
||||
} else if (self.plane.dim_x() > 55 and self.plane.dim_y() > 16) {
|
||||
self.plane.cursor_move_yx(2, self.centerI(4, self.home_style.title.len * 4)) catch return false;
|
||||
fonts.print_string_medium(&self.plane, self.home_style.title, style_title) catch return false;
|
||||
self.plane.cursor_move_yx(2, self.centerI(4, title.len * 4)) catch return false;
|
||||
fonts.print_string_medium(&self.plane, title, style_title) catch return false;
|
||||
|
||||
self.plane.set_style_bg_transparent(style_subtext);
|
||||
self.plane.cursor_move_yx(7, self.centerI(6, self.home_style.subtext.len)) catch return false;
|
||||
_ = self.plane.print("{s}", .{self.home_style.subtext}) catch {};
|
||||
self.plane.cursor_move_yx(7, self.centerI(6, subtext.len)) catch return false;
|
||||
_ = self.plane.print("{s}", .{subtext}) catch {};
|
||||
self.plane.set_style(theme.editor);
|
||||
|
||||
self.position_menu(self.v_center(9, self.menu_len, 9), self.center(8, self.menu_w));
|
||||
} else {
|
||||
self.plane.set_style_bg_transparent(style_title);
|
||||
self.plane.cursor_move_yx(1, self.centerI(4, self.home_style.title.len)) catch return false;
|
||||
_ = self.plane.print("{s}", .{self.home_style.title}) catch return false;
|
||||
self.plane.cursor_move_yx(1, self.centerI(4, title.len)) catch return false;
|
||||
_ = self.plane.print("{s}", .{title}) catch return false;
|
||||
|
||||
self.plane.set_style_bg_transparent(style_subtext);
|
||||
self.plane.cursor_move_yx(3, self.centerI(6, self.home_style.subtext.len)) catch return false;
|
||||
_ = self.plane.print("{s}", .{self.home_style.subtext}) catch {};
|
||||
self.plane.cursor_move_yx(3, self.centerI(6, subtext.len)) catch return false;
|
||||
_ = self.plane.print("{s}", .{subtext}) catch {};
|
||||
self.plane.set_style(theme.editor);
|
||||
|
||||
const x = @min(self.plane.dim_x() -| 32, 8);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const Plane = @import("renderer").Plane;
|
||||
|
|
@ -15,6 +16,8 @@ const CreateError = @import("widget.zig").CreateError;
|
|||
const Style = enum {
|
||||
plain,
|
||||
fancy,
|
||||
plain_root,
|
||||
fancy_root,
|
||||
};
|
||||
const default_style = .fancy;
|
||||
|
||||
|
|
@ -23,7 +26,11 @@ const ButtonType = Button.Options(Style).ButtonType;
|
|||
pub fn create(allocator: Allocator, parent: Plane, event_handler: ?EventHandler, arg: ?[]const u8) CreateError!Widget {
|
||||
const style_ = if (arg) |str_style| std.meta.stringToEnum(Style, str_style) orelse default_style else default_style;
|
||||
return Button.create_widget(Style, allocator, parent, .{
|
||||
.ctx = style_,
|
||||
.ctx = if (builtin.os.tag != .windows and std.posix.geteuid() == 0) switch (style_) {
|
||||
.fancy => .fancy_root,
|
||||
.plain => .plain_root,
|
||||
else => style_,
|
||||
} else style_,
|
||||
.label = tui.get_mode(),
|
||||
.on_click = on_click,
|
||||
.on_click2 = toggle_panel,
|
||||
|
|
@ -53,8 +60,8 @@ fn is_overlay_mode() bool {
|
|||
pub fn render(ctx: *Style, self: *ButtonType, theme: *const Widget.Theme) bool {
|
||||
const style_base = theme.statusbar;
|
||||
const style_label = switch (ctx.*) {
|
||||
.fancy => if (self.active) theme.editor_cursor else if (self.hover) theme.editor_selection else theme.statusbar_hover,
|
||||
.plain => if (self.active) theme.editor_cursor else if (self.hover or is_mini_mode()) theme.statusbar_hover else style_base,
|
||||
.fancy, .fancy_root => if (self.active) theme.editor_cursor else if (self.hover) theme.editor_selection else theme.statusbar_hover,
|
||||
.plain, .plain_root => if (self.active) theme.editor_cursor else if (self.hover or is_mini_mode()) theme.statusbar_hover else style_base,
|
||||
};
|
||||
self.plane.set_base_style(theme.editor);
|
||||
self.plane.erase();
|
||||
|
|
@ -68,7 +75,7 @@ pub fn render(ctx: *Style, self: *ButtonType, theme: *const Widget.Theme) bool {
|
|||
self.plane.on_styles(styles.bold);
|
||||
var buf: [31:0]u8 = undefined;
|
||||
if (!is_mini_mode() and !is_overlay_mode()) {
|
||||
render_logo(self, theme, style_label);
|
||||
render_logo(ctx, self, theme, style_label);
|
||||
} else {
|
||||
_ = self.plane.putstr(" ") catch {};
|
||||
}
|
||||
|
|
@ -89,16 +96,26 @@ fn render_separator(self: *ButtonType, theme: *const Widget.Theme) void {
|
|||
|
||||
const left = " ";
|
||||
const symbol = "";
|
||||
const symbol_root = "";
|
||||
const right = " ";
|
||||
|
||||
fn render_logo(self: *ButtonType, theme: *const Widget.Theme, style_label: Widget.Theme.Style) void {
|
||||
fn render_logo(ctx: *Style, self: *ButtonType, theme: *const Widget.Theme, style_label: Widget.Theme.Style) void {
|
||||
const style_root = theme.editor_error;
|
||||
const style_braces: Widget.Theme.Style = if (tui.find_scope_style(theme, "punctuation")) |sty| .{ .fg = sty.style.fg, .bg = style_label.bg, .fs = style_label.fs } else style_label;
|
||||
if (left.len > 0) {
|
||||
self.plane.set_style(style_braces);
|
||||
_ = self.plane.putstr(" " ++ left) catch {};
|
||||
}
|
||||
switch (ctx.*) {
|
||||
.fancy_root, .plain_root => {
|
||||
self.plane.set_style(style_root);
|
||||
_ = self.plane.putstr(symbol_root) catch {};
|
||||
},
|
||||
else => {
|
||||
self.plane.set_style(style_label);
|
||||
_ = self.plane.putstr(symbol) catch {};
|
||||
},
|
||||
}
|
||||
if (right.len > 0) {
|
||||
self.plane.set_style(style_braces);
|
||||
_ = self.plane.putstr(right) catch {};
|
||||
|
|
|
|||
|
|
@ -915,7 +915,13 @@ const cmds = struct {
|
|||
pub fn restart(_: *Self, _: Ctx) Result {
|
||||
try tp.self_pid().send("restart");
|
||||
}
|
||||
pub const restart_meta: Meta = .{ .description = "Restart (without saving)" };
|
||||
pub const restart_meta: Meta = .{ .description = "Restart session" };
|
||||
|
||||
pub fn restart_with_sudo(_: *Self, _: Ctx) Result {
|
||||
root.set_restart_with_sudo();
|
||||
try tp.self_pid().send("restart");
|
||||
}
|
||||
pub const restart_with_sudo_meta: Meta = .{ .description = "Restart with sudo" };
|
||||
|
||||
pub fn force_terminate(self: *Self, _: Ctx) Result {
|
||||
self.deinit();
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue