diff --git a/src/bin_path.zig b/src/bin_path.zig index 8134ca4..b66dcb1 100644 --- a/src/bin_path.zig +++ b/src/bin_path.zig @@ -53,3 +53,25 @@ fn find_binary_in_path_windows(allocator: std.mem.Allocator, binary_name_: []con } return null; } + +fn is_absolute_binary_path_executable(binary_path: []const u8) bool { + switch (builtin.os.tag) { + .windows => _ = std.fs.cwd().statFile(binary_path) catch return false, + else => std.posix.access(binary_path, std.posix.X_OK) catch return false, + } + return true; +} + +pub fn can_execute(allocator: std.mem.Allocator, binary_name: []const u8) bool { + for (binary_name) |char| if (std.fs.path.isSep(char)) + return is_absolute_binary_path_executable(binary_name); + const resolved_binary_path = find_binary_in_path(allocator, binary_name) catch return false; + defer if (resolved_binary_path) |path| allocator.free(path); + return resolved_binary_path != null; +} + +pub fn resolve_executable(allocator: std.mem.Allocator, binary_name: [:0]const u8) [:0]const u8 { + return for (binary_name) |char| { + if (std.fs.path.isSep(char)) break binary_name; + } else find_binary_in_path(allocator, binary_name) catch binary_name orelse binary_name; +} diff --git a/src/list_languages.zig b/src/list_languages.zig index 7e42190..8296e87 100644 --- a/src/list_languages.zig +++ b/src/list_languages.zig @@ -46,12 +46,12 @@ pub fn list(allocator: std.mem.Allocator, writer: *std.io.Writer, tty_config: st try write_segmented(writer, file_type.extensions, ",", max_extensions_len + 1, tty_config); if (file_type.language_server) |language_server| - try write_checkmark(writer, 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); if (file_type.formatter) |formatter| - try write_checkmark(writer, 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 writer.writeAll("\n"); @@ -96,12 +96,6 @@ fn write_segmented( if (pad) |pad_| try write_padding(writer, len, pad_); } -fn can_execute(allocator: std.mem.Allocator, binary_name: []const u8) bool { - const resolved_binary_path = bin_path.find_binary_in_path(allocator, binary_name) catch return false; - defer if (resolved_binary_path) |path| allocator.free(path); - return resolved_binary_path != null; -} - fn setColorRgb(writer: anytype, color: u24) !void { const fg_rgb_legacy = "\x1b[38;2;{d};{d};{d}m"; const rgb = RGB.from_u24(color); diff --git a/src/main.zig b/src/main.zig index cf78867..b191faf 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1137,9 +1137,7 @@ pub fn get_theme_file_name(theme_name: []const u8) ![]const u8 { } 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; + return bin_path.resolve_executable(std.heap.c_allocator, executable); } fn restart() noreturn { diff --git a/src/tui/editor.zig b/src/tui/editor.zig index 2c995d7..86246f3 100644 --- a/src/tui/editor.zig +++ b/src/tui/editor.zig @@ -6589,7 +6589,7 @@ pub const Editor = struct { fn get_formatter(self: *Self) ?[]const []const u8 { if (self.checked_formatter) return self.formatter; self.checked_formatter = true; - if (self.file_type) |file_type| if (file_type.formatter) |fmtr| if (fmtr.len > 0) if (can_execute(self.allocator, fmtr[0])) { + if (self.file_type) |file_type| if (file_type.formatter) |fmtr| if (fmtr.len > 0) if (bin_path.can_execute(self.allocator, fmtr[0])) { self.formatter = fmtr; return fmtr; } else { @@ -6599,12 +6599,6 @@ pub const Editor = struct { return null; } - fn can_execute(allocator: std.mem.Allocator, binary_name: []const u8) bool { - const resolved_binary_path = bin_path.find_binary_in_path(allocator, binary_name) catch return false; - defer if (resolved_binary_path) |path| allocator.free(path); - return resolved_binary_path != null; - } - pub fn format(self: *Self, ctx: Context) Result { if (ctx.args.buf.len > 0 and try ctx.args.match(.{ tp.string, tp.more })) { try self.filter_cmd(ctx.args);