diff --git a/build.zig b/build.zig index cc54c43..453ee81 100644 --- a/build.zig +++ b/build.zig @@ -587,7 +587,6 @@ pub fn build_exe( check_exe.root_module.addImport("input", input_mod); check_exe.root_module.addImport("syntax", syntax_mod); check_exe.root_module.addImport("color", color_mod); - check_exe.root_module.addImport("bin_path", bin_path_mod); check_exe.root_module.addImport("version", b.createModule(.{ .root_source_file = version_file })); check_exe.root_module.addImport("version_info", b.createModule(.{ .root_source_file = version_info_file })); check_step.dependOn(&check_exe.step); diff --git a/src/git.zig b/src/git.zig index 80413ae..b2b4626 100644 --- a/src/git.zig +++ b/src/git.zig @@ -3,101 +3,30 @@ const tp = @import("thespian"); const shell = @import("shell"); const bin_path = @import("bin_path"); -pub const Error = error{ OutOfMemory, GitNotFound, GitCallFailed }; - -const log_execute = false; - -pub fn workspace_path() Error!void { - const fn_name = @src().fn_name; - try git(.{ "rev-parse", "--show-toplevel" }, struct { - fn result(parent: tp.pid_ref, output: []const u8) void { - var it = std.mem.splitScalar(u8, output, '\n'); - while (it.next()) |branch| if (branch.len > 0) - parent.send(.{ module_name, fn_name, branch }) catch {}; - } - }.result, exit_null_on_error(fn_name)); -} - -pub fn current_branch() Error!void { - const fn_name = @src().fn_name; - try git(.{ "rev-parse", "--abbrev-ref", "HEAD" }, struct { - fn result(parent: tp.pid_ref, output: []const u8) void { - var it = std.mem.splitScalar(u8, output, '\n'); - while (it.next()) |branch| if (branch.len > 0) - parent.send(.{ module_name, fn_name, branch }) catch {}; - } - }.result, exit_null_on_error(fn_name)); -} - -fn git( - cmd: anytype, - out: OutputHandler, - exit: ExitHandler, -) Error!void { - return git_err(cmd, out, noop, exit); -} - -fn git_err( - cmd: anytype, - out: OutputHandler, - err: OutputHandler, - exit: ExitHandler, -) Error!void { - const cbor = @import("cbor"); - const git_binary = get_git() orelse return error.GitNotFound; - var buf: std.ArrayListUnmanaged(u8) = .empty; - const writer = buf.writer(allocator); - switch (@typeInfo(@TypeOf(cmd))) { - .@"struct" => |info| if (info.is_tuple) { - try cbor.writeArrayHeader(writer, info.fields.len + 1); - try cbor.writeValue(writer, git_binary); - inline for (info.fields) |f| - try cbor.writeValue(writer, @field(cmd, f.name)); - return shell.execute(allocator, .{ .buf = buf.items }, .{ - .out = to_shell_output_handler(out), - .err = to_shell_output_handler(err), - .exit = exit, - .log_execute = log_execute, - }) catch error.GitCallFailed; - }, - else => {}, - } - @compileError("git command should be a tuple: " ++ @typeName(@TypeOf(cmd))); -} - -fn exit_null_on_error(comptime tag: []const u8) shell.ExitHandler { - return struct { - fn exit(_: usize, parent: tp.pid_ref, _: []const u8, _: []const u8, exit_code: i64) void { - if (exit_code > 0) - parent.send(.{ module_name, tag, null }) catch {}; - } - }.exit; -} - -const OutputHandler = fn (parent: tp.pid_ref, output: []const u8) void; -const ExitHandler = shell.ExitHandler; - -fn to_shell_output_handler(handler: anytype) shell.OutputHandler { - return struct { - fn out(_: usize, parent: tp.pid_ref, _: []const u8, output: []const u8) void { - handler(parent, output); - } - }.out; -} - -fn noop(_: tp.pid_ref, _: []const u8) void {} - var git_path: ?struct { path: ?[:0]const u8 = null, } = null; -const allocator = std.heap.c_allocator; - fn get_git() ?[]const u8 { if (git_path) |p| return p.path; - const path = bin_path.find_binary_in_path(allocator, module_name) catch null; + const path = bin_path.find_binary_in_path(std.heap.c_allocator, "git") catch null; git_path = .{ .path = path }; return path; } -const module_name = @typeName(@This()); +pub fn get_current_branch(allocator: std.mem.Allocator) !void { + const git_binary = get_git() orelse return error.GitBinaryNotFound; + const git_current_branch_cmd = tp.message.fmt(.{ git_binary, "rev-parse", "--abbrev-ref", "HEAD" }); + const handlers = struct { + fn out(_: usize, parent: tp.pid_ref, _: []const u8, output: []const u8) void { + var it = std.mem.splitScalar(u8, output, '\n'); + while (it.next()) |branch| if (branch.len > 0) + parent.send(.{ "git", "current_branch", branch }) catch {}; + } + }; + try shell.execute(allocator, git_current_branch_cmd, .{ + .out = handlers.out, + .err = shell.log_err_handler, + .exit = shell.log_exit_err_handler, + }); +} diff --git a/src/shell.zig b/src/shell.zig index 5a8424d..c4ee5ca 100644 --- a/src/shell.zig +++ b/src/shell.zig @@ -36,7 +36,6 @@ pub const Handlers = struct { out: *const OutputHandler, err: ?*const OutputHandler = null, exit: *const ExitHandler = log_exit_handler, - log_execute: bool = true, }; pub fn execute(allocator: std.mem.Allocator, argv: tp.message, handlers: Handlers) Error!void { @@ -186,8 +185,7 @@ const Process = struct { _ = tp.set_trap(true); var buf: [1024]u8 = undefined; const json = self.argv.to_json(&buf) catch |e| return tp.exit_error(e, @errorReturnTrace()); - if (self.handlers.log_execute) - self.logger.print("shell: execute {s}", .{json}); + self.logger.print("shell: execute {s}", .{json}); self.sp = tp.subprocess.init(self.allocator, self.argv, module_name, self.stdin_behavior) catch |e| return tp.exit_error(e, @errorReturnTrace()); tp.receive(&self.receiver); } diff --git a/src/tui/mode/mini/goto.zig b/src/tui/mode/mini/goto.zig index ec18e48..d5023c7 100644 --- a/src/tui/mode/mini/goto.zig +++ b/src/tui/mode/mini/goto.zig @@ -131,9 +131,4 @@ const cmds = struct { self.goto(); } pub const mini_mode_insert_bytes_meta: Meta = .{ .arguments = &.{.string} }; - - pub fn mini_mode_paste(self: *Self, ctx: Ctx) Result { - return mini_mode_insert_bytes(self, ctx); - } - pub const mini_mode_paste_meta: Meta = .{ .arguments = &.{.string} }; }; diff --git a/src/tui/status/branch.zig b/src/tui/status/branch.zig index 6f1ffa5..86b7295 100644 --- a/src/tui/status/branch.zig +++ b/src/tui/status/branch.zig @@ -1,5 +1,6 @@ const std = @import("std"); const tp = @import("thespian"); +const cbor = @import("cbor"); const EventHandler = @import("EventHandler"); const Plane = @import("renderer").Plane; @@ -17,19 +18,14 @@ branch: ?[]const u8 = null, const Self = @This(); -pub fn create( - allocator: std.mem.Allocator, - parent: Plane, - _: ?EventHandler, - _: ?[]const u8, -) @import("widget.zig").CreateError!Widget { +pub fn create(allocator: std.mem.Allocator, parent: Plane, _: ?EventHandler, _: ?[]const u8) @import("widget.zig").CreateError!Widget { const self: *Self = try allocator.create(Self); self.* = .{ .allocator = allocator, .plane = try Plane.init(&(Widget.Box{}).opts(@typeName(Self)), parent), }; try tui.message_filters().add(MessageFilter.bind(self, receive_git)); - git.workspace_path() catch {}; + git.get_current_branch(self.allocator) catch {}; return Widget.to(self); } @@ -40,28 +36,13 @@ pub fn deinit(self: *Self, allocator: std.mem.Allocator) void { } fn receive_git(self: *Self, _: tp.pid_ref, m: tp.message) MessageFilter.Error!bool { - return if (try match(m.buf, .{ "git", more })) - self.process_git(m) - else - false; -} - -fn process_git( - self: *Self, - m: tp.message, -) MessageFilter.Error!bool { var branch: []const u8 = undefined; - if (try match(m.buf, .{ any, "workspace_path", null_ })) { - self.branch = try self.allocator.dupe(u8, "null"); - } else if (try match(m.buf, .{ any, "workspace_path", string })) { - git.current_branch() catch {}; - } else if (try match(m.buf, .{ any, "current_branch", extract(&branch) })) { + if (try cbor.match(m.buf, .{ "git", "current_branch", tp.extract(&branch) })) { if (self.branch) |p| self.allocator.free(p); self.branch = try self.allocator.dupe(u8, branch); - } else { - return false; + return true; } - return true; + return false; } pub fn layout(self: *Self) Widget.Layout { @@ -85,12 +66,3 @@ pub fn render(self: *Self, theme: *const Widget.Theme) bool { _ = self.plane.print("{s} {s}", .{ branch_symbol, branch }) catch {}; return false; } - -const match = cbor.match; -const more = cbor.more; -const null_ = cbor.null_; -const string = cbor.string; -const extract = cbor.extract; -const any = cbor.any; - -const cbor = @import("cbor");