refactor: add argv module with helper functions
This commit is contained in:
parent
a35edeaa9b
commit
fc78e8cf02
4 changed files with 73 additions and 52 deletions
10
build.zig
10
build.zig
|
|
@ -392,6 +392,13 @@ pub fn build_exe(
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const argv_mod = b.createModule(.{
|
||||||
|
.root_source_file = b.path("src/argv.zig"),
|
||||||
|
.imports = &.{
|
||||||
|
.{ .name = "cbor", .module = cbor_mod },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const lsp_config_mod = b.createModule(.{
|
const lsp_config_mod = b.createModule(.{
|
||||||
.root_source_file = b.path("src/lsp_config.zig"),
|
.root_source_file = b.path("src/lsp_config.zig"),
|
||||||
.imports = &.{
|
.imports = &.{
|
||||||
|
|
@ -660,6 +667,7 @@ pub fn build_exe(
|
||||||
.{ .name = "project_manager", .module = project_manager_mod },
|
.{ .name = "project_manager", .module = project_manager_mod },
|
||||||
.{ .name = "syntax", .module = syntax_mod },
|
.{ .name = "syntax", .module = syntax_mod },
|
||||||
.{ .name = "text_manip", .module = text_manip_mod },
|
.{ .name = "text_manip", .module = text_manip_mod },
|
||||||
|
.{ .name = "argv", .module = argv_mod },
|
||||||
.{ .name = "Buffer", .module = Buffer_mod },
|
.{ .name = "Buffer", .module = Buffer_mod },
|
||||||
.{ .name = "keybind", .module = keybind_mod },
|
.{ .name = "keybind", .module = keybind_mod },
|
||||||
.{ .name = "shell", .module = shell_mod },
|
.{ .name = "shell", .module = shell_mod },
|
||||||
|
|
@ -709,6 +717,7 @@ pub fn build_exe(
|
||||||
exe.root_module.addImport("cbor", cbor_mod);
|
exe.root_module.addImport("cbor", cbor_mod);
|
||||||
exe.root_module.addImport("config", config_mod);
|
exe.root_module.addImport("config", config_mod);
|
||||||
exe.root_module.addImport("text_manip", text_manip_mod);
|
exe.root_module.addImport("text_manip", text_manip_mod);
|
||||||
|
exe.root_module.addImport("argv", argv_mod);
|
||||||
exe.root_module.addImport("Buffer", Buffer_mod);
|
exe.root_module.addImport("Buffer", Buffer_mod);
|
||||||
exe.root_module.addImport("tui", tui_mod);
|
exe.root_module.addImport("tui", tui_mod);
|
||||||
exe.root_module.addImport("thespian", thespian_mod);
|
exe.root_module.addImport("thespian", thespian_mod);
|
||||||
|
|
@ -759,6 +768,7 @@ pub fn build_exe(
|
||||||
check_exe.root_module.addImport("cbor", cbor_mod);
|
check_exe.root_module.addImport("cbor", cbor_mod);
|
||||||
check_exe.root_module.addImport("config", config_mod);
|
check_exe.root_module.addImport("config", config_mod);
|
||||||
check_exe.root_module.addImport("text_manip", text_manip_mod);
|
check_exe.root_module.addImport("text_manip", text_manip_mod);
|
||||||
|
check_exe.root_module.addImport("argv", argv_mod);
|
||||||
check_exe.root_module.addImport("Buffer", Buffer_mod);
|
check_exe.root_module.addImport("Buffer", Buffer_mod);
|
||||||
check_exe.root_module.addImport("tui", tui_mod);
|
check_exe.root_module.addImport("tui", tui_mod);
|
||||||
check_exe.root_module.addImport("thespian", thespian_mod);
|
check_exe.root_module.addImport("thespian", thespian_mod);
|
||||||
|
|
|
||||||
33
src/argv.zig
Normal file
33
src/argv.zig
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
/// Write a `[]const []const u8` argv array as a space-separated command string.
|
||||||
|
/// Args that contain spaces are wrapped in double-quotes.
|
||||||
|
/// Writes nothing if argv is null or empty.
|
||||||
|
pub fn write(writer: *std.Io.Writer, argv: ?[]const []const u8) error{WriteFailed}!usize {
|
||||||
|
const args = argv orelse return 0;
|
||||||
|
var count: usize = 0;
|
||||||
|
for (args, 0..) |arg, i| {
|
||||||
|
if (i > 0) {
|
||||||
|
try writer.writeByte(' ');
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
const needs_quote = std.mem.indexOfScalar(u8, arg, ' ') != null;
|
||||||
|
if (needs_quote) {
|
||||||
|
try writer.writeByte('"');
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
try writer.writeAll(arg);
|
||||||
|
count += arg.len;
|
||||||
|
if (needs_quote) {
|
||||||
|
try writer.writeByte('"');
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the display length of an argv array rendered by write_argv.
|
||||||
|
pub fn len(argv: ?[]const []const u8) usize {
|
||||||
|
var discard: std.Io.Writer.Discarding = .init(&.{});
|
||||||
|
return write(&discard.writer, argv) catch return 0;
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ const file_type_config = @import("file_type_config");
|
||||||
const text_manip = @import("text_manip");
|
const text_manip = @import("text_manip");
|
||||||
const write_string = text_manip.write_string;
|
const write_string = text_manip.write_string;
|
||||||
const write_padding = text_manip.write_padding;
|
const write_padding = text_manip.write_padding;
|
||||||
|
const argv = @import("argv");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const RGB = @import("color").RGB;
|
const RGB = @import("color").RGB;
|
||||||
|
|
||||||
|
|
@ -22,9 +23,9 @@ pub fn list(allocator: std.mem.Allocator, writer: *std.io.Writer, tty_config: st
|
||||||
for (file_type_config.get_all_names()) |file_type_name| {
|
for (file_type_config.get_all_names()) |file_type_name| {
|
||||||
const file_type = try file_type_config.get(file_type_name) orelse unreachable;
|
const file_type = try file_type_config.get(file_type_name) orelse unreachable;
|
||||||
max_language_len = @max(max_language_len, file_type.name.len);
|
max_language_len = @max(max_language_len, file_type.name.len);
|
||||||
max_langserver_len = @max(max_langserver_len, args_string_length(file_type.language_server));
|
max_langserver_len = @max(max_langserver_len, argv.len(file_type.language_server));
|
||||||
max_formatter_len = @max(max_formatter_len, args_string_length(file_type.formatter));
|
max_formatter_len = @max(max_formatter_len, argv.len(file_type.formatter));
|
||||||
max_extensions_len = @max(max_extensions_len, args_string_length(file_type.extensions));
|
max_extensions_len = @max(max_extensions_len, argv.len(file_type.extensions));
|
||||||
}
|
}
|
||||||
|
|
||||||
try tty_config.setColor(writer, .yellow);
|
try tty_config.setColor(writer, .yellow);
|
||||||
|
|
@ -43,59 +44,42 @@ pub fn list(allocator: std.mem.Allocator, writer: *std.io.Writer, tty_config: st
|
||||||
try tty_config.setColor(writer, .reset);
|
try tty_config.setColor(writer, .reset);
|
||||||
try writer.writeAll(" ");
|
try writer.writeAll(" ");
|
||||||
try write_string(writer, file_type.name, max_language_len + 1);
|
try write_string(writer, file_type.name, max_language_len + 1);
|
||||||
try write_segmented(writer, file_type.extensions, ",", max_extensions_len + 1, tty_config);
|
{
|
||||||
|
const exts = file_type.extensions orelse &.{};
|
||||||
|
var ext_len: usize = 0;
|
||||||
|
for (exts, 0..) |ext, i| {
|
||||||
|
if (i > 0) {
|
||||||
|
try writer.writeByte(',');
|
||||||
|
ext_len += 1;
|
||||||
|
}
|
||||||
|
try writer.writeAll(ext);
|
||||||
|
ext_len += ext.len;
|
||||||
|
}
|
||||||
|
try tty_config.setColor(writer, .reset);
|
||||||
|
try write_padding(writer, ext_len, max_extensions_len + 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (file_type.language_server) |language_server|
|
if (file_type.language_server) |language_server|
|
||||||
try write_checkmark(writer, bin_path.can_execute(allocator, language_server[0]), tty_config);
|
try write_checkmark(writer, bin_path.can_execute(allocator, language_server[0]), tty_config);
|
||||||
|
|
||||||
try write_segmented(writer, file_type.language_server, " ", max_langserver_len + 1, tty_config);
|
const len = try argv.write(writer, file_type.language_server);
|
||||||
|
try tty_config.setColor(writer, .reset);
|
||||||
|
try write_padding(writer, len, max_langserver_len + 1);
|
||||||
|
|
||||||
if (file_type.formatter) |formatter|
|
if (file_type.formatter) |formatter|
|
||||||
try write_checkmark(writer, bin_path.can_execute(allocator, formatter[0]), tty_config);
|
try write_checkmark(writer, bin_path.can_execute(allocator, formatter[0]), tty_config);
|
||||||
|
|
||||||
try write_segmented(writer, file_type.formatter, " ", null, tty_config);
|
_ = try argv.write(writer, file_type.formatter);
|
||||||
|
try tty_config.setColor(writer, .reset);
|
||||||
try writer.writeAll("\n");
|
try writer.writeAll("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn args_string_length(args_: ?[]const []const u8) usize {
|
|
||||||
const args = args_ orelse return 0;
|
|
||||||
var len: usize = 0;
|
|
||||||
var first: bool = true;
|
|
||||||
for (args) |arg| {
|
|
||||||
if (first) first = false else len += 1;
|
|
||||||
len += arg.len;
|
|
||||||
}
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_checkmark(writer: anytype, success: bool, tty_config: std.io.tty.Config) !void {
|
fn write_checkmark(writer: anytype, success: bool, tty_config: std.io.tty.Config) !void {
|
||||||
try tty_config.setColor(writer, if (success) .green else .red);
|
try tty_config.setColor(writer, if (success) .green else .red);
|
||||||
if (success) try writer.writeAll(success_mark) else try writer.writeAll(fail_mark);
|
if (success) try writer.writeAll(success_mark) else try writer.writeAll(fail_mark);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_segmented(
|
|
||||||
writer: anytype,
|
|
||||||
args_: ?[]const []const u8,
|
|
||||||
sep: []const u8,
|
|
||||||
pad: ?usize,
|
|
||||||
tty_config: std.io.tty.Config,
|
|
||||||
) !void {
|
|
||||||
const args = args_ orelse return;
|
|
||||||
var len: usize = 0;
|
|
||||||
var first: bool = true;
|
|
||||||
for (args) |arg| {
|
|
||||||
if (first) first = false else {
|
|
||||||
len += 1;
|
|
||||||
try writer.writeAll(sep);
|
|
||||||
}
|
|
||||||
len += arg.len;
|
|
||||||
try writer.writeAll(arg);
|
|
||||||
}
|
|
||||||
try tty_config.setColor(writer, .reset);
|
|
||||||
if (pad) |pad_| try write_padding(writer, len, pad_);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn setColorRgb(writer: anytype, color: u24) !void {
|
fn setColorRgb(writer: anytype, color: u24) !void {
|
||||||
const fg_rgb_legacy = "\x1b[38;2;{d};{d};{d}m";
|
const fg_rgb_legacy = "\x1b[38;2;{d};{d};{d}m";
|
||||||
const rgb = RGB.from_u24(color);
|
const rgb = RGB.from_u24(color);
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ const cbor = @import("cbor");
|
||||||
const command = @import("command");
|
const command = @import("command");
|
||||||
const vaxis = @import("renderer").vaxis;
|
const vaxis = @import("renderer").vaxis;
|
||||||
const shell = @import("shell");
|
const shell = @import("shell");
|
||||||
|
const argv = @import("argv");
|
||||||
|
|
||||||
const Plane = @import("renderer").Plane;
|
const Plane = @import("renderer").Plane;
|
||||||
const Widget = @import("Widget.zig");
|
const Widget = @import("Widget.zig");
|
||||||
|
|
@ -274,18 +275,11 @@ fn show_exit_message(self: *Self, code: u8) void {
|
||||||
if (code != 0)
|
if (code != 0)
|
||||||
w.print(" with code {d}", .{code}) catch {};
|
w.print(" with code {d}", .{code}) catch {};
|
||||||
w.writeAll("]\x1b[0m\r\n") catch {};
|
w.writeAll("]\x1b[0m\r\n") catch {};
|
||||||
// Build display command string from argv for the re-run prompt
|
// Re-run prompt
|
||||||
const argv = self.vt.vt.cmd.argv;
|
const cmd_argv = self.vt.vt.cmd.argv;
|
||||||
if (argv.len > 0) {
|
if (cmd_argv.len > 0) {
|
||||||
w.writeAll("\x1b[0m\x1b[2mPress enter to re-run '") catch {};
|
w.writeAll("\x1b[0m\x1b[2mPress enter to re-run '") catch {};
|
||||||
for (argv, 0..) |arg, i| {
|
_ = argv.write(w, cmd_argv) catch {};
|
||||||
if (i > 0) w.writeByte(' ') catch {};
|
|
||||||
// Quote args that contain spaces
|
|
||||||
const needs_quote = std.mem.indexOfScalar(u8, arg, ' ') != null;
|
|
||||||
if (needs_quote) w.writeByte('"') catch {};
|
|
||||||
w.writeAll(arg) catch {};
|
|
||||||
if (needs_quote) w.writeByte('"') catch {};
|
|
||||||
}
|
|
||||||
w.writeAll("'\x1b[0m\r\n") catch {};
|
w.writeAll("'\x1b[0m\r\n") catch {};
|
||||||
}
|
}
|
||||||
var parser: pty.Parser = .{ .buf = .init(self.allocator) };
|
var parser: pty.Parser = .{ .buf = .init(self.allocator) };
|
||||||
|
|
@ -355,7 +349,7 @@ const Vt = struct {
|
||||||
app_cursor: ?[3]u8 = null,
|
app_cursor: ?[3]u8 = null,
|
||||||
process_exited: bool = false,
|
process_exited: bool = false,
|
||||||
|
|
||||||
fn init(allocator: std.mem.Allocator, argv: []const []const u8, env: std.process.EnvMap, rows: u16, cols: u16) !void {
|
fn init(allocator: std.mem.Allocator, cmd_argv: []const []const u8, env: std.process.EnvMap, rows: u16, cols: u16) !void {
|
||||||
const home = env.get("HOME") orelse "/tmp";
|
const home = env.get("HOME") orelse "/tmp";
|
||||||
|
|
||||||
global_vt = .{
|
global_vt = .{
|
||||||
|
|
@ -367,7 +361,7 @@ const Vt = struct {
|
||||||
const self = &global_vt.?;
|
const self = &global_vt.?;
|
||||||
self.vt = try Terminal.init(
|
self.vt = try Terminal.init(
|
||||||
allocator,
|
allocator,
|
||||||
argv,
|
cmd_argv,
|
||||||
&env,
|
&env,
|
||||||
.{
|
.{
|
||||||
.winsize = .{ .rows = rows, .cols = cols, .x_pixel = 0, .y_pixel = 0 },
|
.winsize = .{ .rows = rows, .cols = cols, .x_pixel = 0, .y_pixel = 0 },
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue