diff options
Diffstat (limited to 'src/cli.zig')
-rw-r--r-- | src/cli.zig | 260 |
1 files changed, 1 insertions, 259 deletions
diff --git a/src/cli.zig b/src/cli.zig index 371e443af..51d22db45 100644 --- a/src/cli.zig +++ b/src/cli.zig @@ -36,6 +36,7 @@ const CreateCommand = @import("./cli/create_command.zig").CreateCommand; const CreateListExamplesCommand = @import("./cli/create_command.zig").CreateListExamplesCommand; const RunCommand = @import("./cli/run_command.zig").RunCommand; const UpgradeCommand = @import("./cli/upgrade_command.zig").UpgradeCommand; +const InstallCompletionsCommand = @import("./cli/install_completions_command.zig").InstallCompletionsCommand; const ShellCompletions = @import("./cli/shell_completions.zig"); var start_time: i128 = undefined; @@ -612,265 +613,6 @@ pub const Command = struct { } } - pub const InstallCompletionsCommand = struct { - pub fn testPath(completions_dir: string) !std.fs.Dir {} - pub fn exec(allocator: *std.mem.Allocator) !void { - var shell = ShellCompletions.Shell.unknown; - if (std.os.getenv("SHELL")) |shell_name| { - shell = ShellCompletions.Shell.fromEnv(@TypeOf(shell_name), shell_name); - } - - switch (shell) { - .bash => { - Output.prettyErrorln("<r><red>error:<r> Bash completions aren't implemented yet, just zsh & fish. A PR is welcome!", .{}); - std.os.exit(1); - }, - .unknown => { - Output.prettyErrorln("<r><red>error:<r> Unknown or unsupported shell. Please set $SHELL to one of zsh, fish, or bash. To manually output completions, run this:\n bun getcompletes", .{}); - std.os.exit(1); - }, - else => {}, - } - - var stdout = std.io.getStdOut(); - - if (std.os.getenvZ("IS_BUN_AUTO_UPDATE") == null) { - if (!stdout.isTty()) { - try stdout.writeAll(shell.completions()); - std.os.exit(0); - } - } - - var completions_dir: string = ""; - var output_dir: std.fs.Dir = found: { - var cwd_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; - var cwd = std.os.getcwd(&cwd_buf) catch { - Output.prettyErrorln("<r><red>error<r>: Could not get current working directory", .{}); - Output.flush(); - std.os.exit(1); - }; - - for (std.os.argv) |arg, i| { - if (strings.eqlComptime(std.mem.span(arg), "completions")) { - if (std.os.argv.len > i + 1) { - const input = std.mem.span(std.os.argv[i + 1]); - - if (!std.fs.path.isAbsolute(input)) { - completions_dir = resolve_path.joinAbs( - cwd, - .auto, - input, - ); - } else { - completions_dir = input; - } - - if (!std.fs.path.isAbsolute(completions_dir)) { - Output.prettyErrorln("<r><red>error:<r> Please pass an absolute path. {s} is invalid", .{completions_dir}); - Output.flush(); - std.os.exit(1); - } - - break :found std.fs.openDirAbsolute(completions_dir, .{ - .iterate = true, - }) catch |err| { - Output.prettyErrorln("<r><red>error:<r> accessing {s} errored {s}", .{ completions_dir, @errorName(err) }); - Output.flush(); - std.os.exit(1); - }; - } - - break; - } - } - - switch (shell) { - .fish => { - if (std.os.getenvZ("XDG_CONFIG_HOME")) |config_dir| { - outer: { - var paths = [_]string{ std.mem.span(config_dir), "./fish/completions" }; - completions_dir = resolve_path.joinAbsString(cwd, &paths, .auto); - break :found std.fs.openDirAbsolute(completions_dir, .{ .iterate = true }) catch |err| { - break :outer; - }; - } - } - - if (std.os.getenvZ("XDG_DATA_HOME")) |data_dir| { - outer: { - var paths = [_]string{ std.mem.span(data_dir), "./fish/completions" }; - completions_dir = resolve_path.joinAbsString(cwd, &paths, .auto); - - break :found std.fs.openDirAbsolute(completions_dir, .{ .iterate = true }) catch |err| { - break :outer; - }; - } - } - - if (std.os.getenvZ("HOME")) |home_dir| { - outer: { - var paths = [_]string{ std.mem.span(home_dir), "./.config/fish/completions" }; - completions_dir = resolve_path.joinAbsString(cwd, &paths, .auto); - break :found std.fs.openDirAbsolute(completions_dir, .{ .iterate = true }) catch |err| { - break :outer; - }; - } - } - - outer: { - if (Environment.isMac) { - if (!Environment.isAarch64) { - // homebrew fish - completions_dir = "/usr/local/share/fish/completions"; - break :found std.fs.openDirAbsoluteZ("/usr/local/share/fish/completions", .{ .iterate = true }) catch |err| { - break :outer; - }; - } else { - // homebrew fish - completions_dir = "/opt/homebrew/share/fish/completions"; - break :found std.fs.openDirAbsoluteZ("/opt/homebrew/share/fish/completions", .{ .iterate = true }) catch |err| { - break :outer; - }; - } - } - } - - outer: { - completions_dir = "/etc/fish/completions"; - break :found std.fs.openDirAbsoluteZ("/etc/fish/completions", .{ .iterate = true }) catch break :outer; - } - }, - .zsh => { - if (std.os.getenvZ("fpath")) |fpath| { - var splitter = std.mem.split(u8, std.mem.span(fpath), " "); - - while (splitter.next()) |dir| { - completions_dir = dir; - break :found std.fs.openDirAbsolute(dir, .{ .iterate = true }) catch continue; - } - } - - if (std.os.getenvZ("XDG_DATA_HOME")) |data_dir| { - outer: { - var paths = [_]string{ std.mem.span(data_dir), "./zsh-completions" }; - completions_dir = resolve_path.joinAbsString(cwd, &paths, .auto); - - break :found std.fs.openDirAbsolute(completions_dir, .{ .iterate = true }) catch |err| { - break :outer; - }; - } - } - - outer: { - completions_dir = "/usr/local/share/zsh-completions"; - break :found std.fs.openDirAbsolute("/usr/local/share/zsh-completions", .{ .iterate = true }) catch |err| { - break :outer; - }; - } - - if (std.os.getenvZ("HOME")) |home_dir| { - { - outer: { - var paths = [_]string{ std.mem.span(home_dir), "./.oh-my-zsh/completions" }; - completions_dir = resolve_path.joinAbsString(cwd, &paths, .auto); - break :found std.fs.openDirAbsolute(completions_dir, .{ .iterate = true }) catch |err| { - break :outer; - }; - } - } - } - - { - outer: { - completions_dir = "/usr/local/share/zsh/site-functions"; - break :found std.fs.openDirAbsolute("/usr/local/share/zsh/site-functions", .{ .iterate = true }) catch |err| { - break :outer; - }; - } - } - - outer: { - if (Environment.isMac) { - if (!Environment.isAarch64) { - // homebrew zsh - completions_dir = "/usr/local/share/zsh/completions"; - break :found std.fs.openDirAbsoluteZ("/usr/local/share/zsh/completions", .{ .iterate = true }) catch |err| { - break :outer; - }; - } else { - // homebrew zsh - completions_dir = "/opt/homebrew/share/zsh/completions"; - break :found std.fs.openDirAbsoluteZ("/opt/homebrew/share/zsh/completions", .{ .iterate = true }) catch |err| { - break :outer; - }; - } - } - } - }, - .bash => {}, - else => unreachable, - } - - Output.prettyErrorln( - "<r><red>error:<r> Could not find a directory to install completions in.\n", - .{}, - ); - - if (shell == .zsh) { - Output.prettyErrorln( - "\nzsh tip: One of the directories in $fpath might work. If you use oh-my-zsh, try mkdir $HOME/.oh-my-zsh/completions; and bun completions again\n.", - .{}, - ); - } - - Output.errorLn( - "Please either pipe it:\n bun completions > /to/a/file\n\n Or pass a directory:\n\n bun completions /my/completions/dir\n", - .{}, - ); - Output.flush(); - std.os.exit(1); - }; - - const filename = switch (shell) { - .fish => "bun.fish", - .zsh => "_bun", - .bash => "_bun.bash", - else => unreachable, - }; - - std.debug.assert(completions_dir.len > 0); - - var output_file = output_dir.createFileZ(filename, .{ - .truncate = true, - }) catch |err| { - Output.prettyErrorln("<r><red>error:<r> Could not open {s} for writing: {s}", .{ - filename, - @errorName(err), - }); - Output.flush(); - std.os.exit(1); - }; - - output_file.writeAll(shell.completions()) catch |err| { - Output.prettyErrorln("<r><red>error:<r> Could not write to {s}: {s}", .{ - filename, - @errorName(err), - }); - Output.flush(); - std.os.exit(1); - }; - - output_file.close(); - output_dir.close(); - - Output.prettyErrorln("<r><d>Installed completions to {s}/{s}<r>", .{ - completions_dir, - filename, - }); - Output.flush(); - } - }; - const default_completions_list = [_]string{ // "build", "run", |