diff --git a/src/shell-integration/zsh/.zshenv b/src/shell-integration/zsh/.zshenv index 4f98b1c39..7fbfad659 100644 --- a/src/shell-integration/zsh/.zshenv +++ b/src/shell-integration/zsh/.zshenv @@ -19,12 +19,10 @@ # we quote everything that can be quoted. Some aliases will still break us # though. -# Don't use [[ -v ... ]] because it doesn't work in zsh < 5.4. -if [[ -n "${GHOSTTY_ORIG_ZDOTDIR+X}" ]]; then - # Normally ZDOTDIR shouldn't be exported but it was in the environment - # of Ghostty, so we export it. - 'builtin' 'export' ZDOTDIR="$GHOSTTY_ORIG_ZDOTDIR" - 'builtin' 'unset' 'GHOSTTY_ORIG_ZDOTDIR' +# Restore the original ZDOTDIR value. +if [[ -n "${GHOSTTY_ZSH_ZDOTDIR+X}" ]]; then + 'builtin' 'export' ZDOTDIR="$GHOSTTY_ZSH_ZDOTDIR" + 'builtin' 'unset' 'GHOSTTY_ZSH_ZDOTDIR' else 'builtin' 'unset' 'ZDOTDIR' fi diff --git a/src/termio/shell_integration.zig b/src/termio/shell_integration.zig index 2aaf23870..15cf9a9d6 100644 --- a/src/termio/shell_integration.zig +++ b/src/termio/shell_integration.zig @@ -6,6 +6,7 @@ const log = std.log.scoped(.shell_integration); /// Shell types we support pub const Shell = enum { fish, + zsh, }; /// Setup the command execution environment for automatic @@ -23,6 +24,11 @@ pub fn setup( return .fish; } + if (std.mem.eql(u8, "zsh", exe)) { + try setupZsh(resource_dir, env); + return .zsh; + } + return null; } @@ -69,3 +75,25 @@ fn setupFish( try env.put("XDG_DATA_DIRS", integ_dir); } } + +/// Setup the zsh automatic shell integration. This works by setting +/// ZDOTDIR to our resources dir so that zsh will load our config. This +/// config then loads the true user config. +fn setupZsh( + resource_dir: []const u8, + env: *EnvMap, +) !void { + // Preserve the old zdotdir value so we can recover it. + if (env.get("ZDOTDIR")) |old| { + try env.put("GHOSTTY_ZSH_ZDOTDIR", old); + } + + // Set our new ZDOTDIR + var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; + const integ_dir = try std.fmt.bufPrint( + &path_buf, + "{s}/shell-integration/zsh", + .{resource_dir}, + ); + try env.put("ZDOTDIR", integ_dir); +}