From 3d2aa9bd829665fcb96500317b4bb67767cfc5cc Mon Sep 17 00:00:00 2001 From: Jon Parise Date: Tue, 23 Dec 2025 12:59:58 -0500 Subject: [PATCH] shell-integration: always call setupFeatures Our existing logic already ensured that setupFeatures() was always called, but that was happening from two code paths: explicitly when shell integration is .none and implicitly via setup(). We can simplify this by always calling setupFeatures() once, outside of the (automatic) shell integration path. There's one small behavioral change: we previously didn't set up shell features in the automatic shell integration path if we didn't have a resources directory (as a side effect). Resources are required for shell integrations, but we don't need them to export GHOSTTY_SHELL_FEATURES, which could potentially still be useful on its on. --- src/termio/Exec.zig | 15 +++++++-------- src/termio/shell_integration.zig | 9 ++------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig index 7c7b711fd..93ad835c5 100644 --- a/src/termio/Exec.zig +++ b/src/termio/Exec.zig @@ -750,15 +750,15 @@ const Subprocess = struct { else => "sh", } }; + // Always set up shell features (GHOSTTY_SHELL_FEATURES). These are + // used by both automatic and manual shell integrations. + try shell_integration.setupFeatures( + &env, + cfg.shell_integration_features, + ); + const force: ?shell_integration.Shell = switch (cfg.shell_integration) { .none => { - // Even if shell integration is none, we still want to - // set up the feature env vars - try shell_integration.setupFeatures( - &env, - cfg.shell_integration_features, - ); - // This is a source of confusion for users despite being // opt-in since it results in some Ghostty features not // working. We always want to log it. @@ -784,7 +784,6 @@ const Subprocess = struct { default_shell_command, &env, force, - cfg.shell_integration_features, ) orelse { log.warn("shell could not be detected, no automatic shell integration will be injected", .{}); break :shell default_shell_command; diff --git a/src/termio/shell_integration.zig b/src/termio/shell_integration.zig index dba4a8f32..e9f85e44c 100644 --- a/src/termio/shell_integration.zig +++ b/src/termio/shell_integration.zig @@ -44,7 +44,6 @@ pub fn setup( command: config.Command, env: *EnvMap, force_shell: ?Shell, - features: config.ShellIntegrationFeatures, ) !?ShellIntegration { const exe = if (force_shell) |shell| switch (shell) { .bash => "bash", @@ -70,8 +69,6 @@ pub fn setup( exe, ); - try setupFeatures(env, features); - return result; } @@ -161,7 +158,6 @@ test "force shell" { .{ .shell = "sh" }, &env, shell, - .{}, ); try testing.expectEqual(shell, result.?.shell); } @@ -183,11 +179,10 @@ test "shell integration failure" { .{ .shell = "sh" }, &env, null, - .{ .cursor = true, .title = false, .path = false }, ); try testing.expect(result == null); - try testing.expectEqualStrings("cursor", env.get("GHOSTTY_SHELL_FEATURES").?); + try testing.expectEqual(0, env.count()); } /// Set up the shell integration features environment variable. @@ -756,7 +751,7 @@ const TmpResourcesDir = struct { path: []const u8, shell_path: []const u8, - fn init(allocator: std.mem.Allocator, shell: Shell) !TmpResourcesDir { + fn init(allocator: Allocator, shell: Shell) !TmpResourcesDir { var tmp_dir = std.testing.tmpDir(.{}); errdefer tmp_dir.cleanup();