From e11d5940ba2077fd2128571deacbbecc47c5d2df Mon Sep 17 00:00:00 2001 From: Allan Calix Date: Wed, 31 Jan 2024 16:24:15 -0800 Subject: [PATCH 1/3] Automatically inject ghostty cli to end of $PATH --- src/termio/Exec.zig | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig index 175a8d4b2..0b3c16ae5 100644 --- a/src/termio/Exec.zig +++ b/src/termio/Exec.zig @@ -1145,6 +1145,20 @@ const Subprocess = struct { // Our screen size should be our padded size const padded_size = opts.screen_size.subPadding(opts.padding); + + var exe_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; + const ghostty_bin_dir = ghostty: { + const exe: ?[]const u8 = std.fs.selfExePath(&exe_buf) catch break: ghostty null; + const exe_bin_path = exe orelse break :ghostty null; + break :ghostty std.fs.path.dirname(exe_bin_path); + }; + if (ghostty_bin_dir) |dir| { + if (env.get("PATH")) |path| { + try env.put("PATH", try internal_os.appendEnv(alloc, path, dir)); + log.info("shell appending ghostty bin to path ghostty_dir={s}", .{dir}); + } + } + return .{ .arena = arena, .env = env, From 577b12430ccb86b293f1ca3b4d1d48d92997fe0f Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 31 Jan 2024 18:50:50 -0800 Subject: [PATCH 2/3] termio/exec: always put ghostty bin dir in GHOSTTY_BIN_DIR env var --- src/termio/Exec.zig | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig index 0b3c16ae5..0a1248170 100644 --- a/src/termio/Exec.zig +++ b/src/termio/Exec.zig @@ -944,6 +944,30 @@ const Subprocess = struct { try env.put("COLORTERM", "truecolor"); } + // Add our binary to the path if we can find it. + ghostty_path: { + var exe_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; + const exe_bin_path = std.fs.selfExePath(&exe_buf) catch |err| { + log.warn("failed to get ghostty exe path err={}", .{err}); + break :ghostty_path; + }; + const exe_dir = std.fs.path.dirname(exe_bin_path) orelse break :ghostty_path; + log.debug("appending ghostty bin to path dir={s}", .{exe_dir}); + + // We always set this so that if the shell overwrites the path + // scripts still have a way to find the Ghostty binary when + // running in Ghostty. + try env.put("GHOSTTY_BIN_DIR", exe_dir); + + // Append if we have a path. We want to append so that ghostty is + // the last priority in the path. If we don't have a path set + // then we just set it to the directory of the binary. + try env.put("PATH", if (env.get("PATH")) |path| + try internal_os.appendEnv(alloc, path, exe_dir) + else + exe_dir); + } + // Set environment variables used by some programs (such as neovim) to detect // which terminal emulator and version they're running under. try env.put("TERM_PROGRAM", "ghostty"); @@ -1145,20 +1169,6 @@ const Subprocess = struct { // Our screen size should be our padded size const padded_size = opts.screen_size.subPadding(opts.padding); - - var exe_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; - const ghostty_bin_dir = ghostty: { - const exe: ?[]const u8 = std.fs.selfExePath(&exe_buf) catch break: ghostty null; - const exe_bin_path = exe orelse break :ghostty null; - break :ghostty std.fs.path.dirname(exe_bin_path); - }; - if (ghostty_bin_dir) |dir| { - if (env.get("PATH")) |path| { - try env.put("PATH", try internal_os.appendEnv(alloc, path, dir)); - log.info("shell appending ghostty bin to path ghostty_dir={s}", .{dir}); - } - } - return .{ .arena = arena, .env = env, From c2e0cff1d22092588e3ba43dcc1f3694ed3be122 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 31 Jan 2024 18:57:42 -0800 Subject: [PATCH 3/3] termio/exec: only add ghostty path if it isn't already in path --- src/os/env.zig | 13 +++++++------ src/termio/Exec.zig | 18 ++++++++++++++---- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/os/env.zig b/src/os/env.zig index 3f94b2a76..70ca75d4f 100644 --- a/src/os/env.zig +++ b/src/os/env.zig @@ -2,6 +2,12 @@ const std = @import("std"); const builtin = @import("builtin"); const Allocator = std.mem.Allocator; +/// The separator used in environment variables such as PATH. +pub const PATH_SEP = switch (builtin.os.tag) { + .windows => ";", + else => ":", +}; + /// Append a value to an environment variable such as PATH. /// The returned value is always allocated so it must be freed. pub fn appendEnv( @@ -13,14 +19,9 @@ pub fn appendEnv( if (current.len == 0) return try alloc.dupe(u8, value); // Otherwise we must prefix. - const sep = switch (builtin.os.tag) { - .windows => ";", - else => ":", - }; - return try std.fmt.allocPrint(alloc, "{s}{s}{s}", .{ current, - sep, + PATH_SEP, value, }); } diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig index 0a1248170..1580309b1 100644 --- a/src/termio/Exec.zig +++ b/src/termio/Exec.zig @@ -962,10 +962,20 @@ const Subprocess = struct { // Append if we have a path. We want to append so that ghostty is // the last priority in the path. If we don't have a path set // then we just set it to the directory of the binary. - try env.put("PATH", if (env.get("PATH")) |path| - try internal_os.appendEnv(alloc, path, exe_dir) - else - exe_dir); + if (env.get("PATH")) |path| { + // Verify that our path doesn't already contain this entry + var it = std.mem.tokenizeScalar(u8, path, internal_os.PATH_SEP[0]); + while (it.next()) |entry| { + if (std.mem.eql(u8, entry, exe_dir)) break :ghostty_path; + } + + try env.put( + "PATH", + try internal_os.appendEnv(alloc, path, exe_dir), + ); + } else { + try env.put("PATH", exe_dir); + } } // Set environment variables used by some programs (such as neovim) to detect