mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-06-11 22:28:20 +00:00
shell-integration: respect cursor-style-blink
The `cursor` shell feature always used a blinking bar (beam), often to the surprise of users who set `cursor-style-blink = false`. This change extends our GHOSTTY_SHELL_FEATURES format to include either `cursor:blink` (default) or `cursor:steady` based on cursor-style-blink when the `cursor` feature is enabled, and all shell integrations have been updated to use that additional information to choose the DECSCUSR cursor value (5=blinking bar, 6=steady bar). I also considered passing a DECSCUSR value in GHOSTTY_SHELL_FEATURES (e.g. `cursor:5`). This mostly worked well, but zsh also needs the blink state on its own for its block cursor. We also don't support any other shell feature cursor configurability (e.g. the shape), so this was an over generalization. This does change the behavior for users who like the blinking bar in the shell but have `cursor-blink-style = false` for other reasons. We could provide additional `cursor` shell feature configurability, but I think that's best left to a separate change.
This commit is contained in:
@@ -188,11 +188,13 @@ test detectShell {
|
||||
pub fn setupFeatures(
|
||||
env: *EnvMap,
|
||||
features: config.ShellIntegrationFeatures,
|
||||
cursor_blink: bool,
|
||||
) !void {
|
||||
const fields = @typeInfo(@TypeOf(features)).@"struct".fields;
|
||||
const capacity: usize = capacity: {
|
||||
comptime var n: usize = fields.len - 1; // commas
|
||||
inline for (fields) |field| n += field.name.len;
|
||||
n += ":steady".len; // cursor value
|
||||
break :capacity n;
|
||||
};
|
||||
|
||||
@@ -221,6 +223,10 @@ pub fn setupFeatures(
|
||||
if (@field(features, name)) {
|
||||
if (writer.end > 0) try writer.writeByte(',');
|
||||
try writer.writeAll(name);
|
||||
|
||||
if (std.mem.eql(u8, name, "cursor")) {
|
||||
try writer.writeAll(if (cursor_blink) ":blink" else ":steady");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,8 +247,8 @@ test "setup features" {
|
||||
var env = EnvMap.init(alloc);
|
||||
defer env.deinit();
|
||||
|
||||
try setupFeatures(&env, .{ .cursor = true, .sudo = true, .title = true, .@"ssh-env" = true, .@"ssh-terminfo" = true, .path = true });
|
||||
try testing.expectEqualStrings("cursor,path,ssh-env,ssh-terminfo,sudo,title", env.get("GHOSTTY_SHELL_FEATURES").?);
|
||||
try setupFeatures(&env, .{ .cursor = true, .sudo = true, .title = true, .@"ssh-env" = true, .@"ssh-terminfo" = true, .path = true }, true);
|
||||
try testing.expectEqualStrings("cursor:blink,path,ssh-env,ssh-terminfo,sudo,title", env.get("GHOSTTY_SHELL_FEATURES").?);
|
||||
}
|
||||
|
||||
// Test: all features disabled
|
||||
@@ -250,7 +256,7 @@ test "setup features" {
|
||||
var env = EnvMap.init(alloc);
|
||||
defer env.deinit();
|
||||
|
||||
try setupFeatures(&env, std.mem.zeroes(config.ShellIntegrationFeatures));
|
||||
try setupFeatures(&env, std.mem.zeroes(config.ShellIntegrationFeatures), true);
|
||||
try testing.expect(env.get("GHOSTTY_SHELL_FEATURES") == null);
|
||||
}
|
||||
|
||||
@@ -259,9 +265,25 @@ test "setup features" {
|
||||
var env = EnvMap.init(alloc);
|
||||
defer env.deinit();
|
||||
|
||||
try setupFeatures(&env, .{ .cursor = false, .sudo = true, .title = false, .@"ssh-env" = true, .@"ssh-terminfo" = false, .path = false });
|
||||
try setupFeatures(&env, .{ .cursor = false, .sudo = true, .title = false, .@"ssh-env" = true, .@"ssh-terminfo" = false, .path = false }, true);
|
||||
try testing.expectEqualStrings("ssh-env,sudo", env.get("GHOSTTY_SHELL_FEATURES").?);
|
||||
}
|
||||
|
||||
// Test: blinking cursor
|
||||
{
|
||||
var env = EnvMap.init(alloc);
|
||||
defer env.deinit();
|
||||
try setupFeatures(&env, .{ .cursor = true, .sudo = false, .title = false, .@"ssh-env" = false, .@"ssh-terminfo" = false, .path = false }, true);
|
||||
try testing.expectEqualStrings("cursor:blink", env.get("GHOSTTY_SHELL_FEATURES").?);
|
||||
}
|
||||
|
||||
// Test: steady cursor
|
||||
{
|
||||
var env = EnvMap.init(alloc);
|
||||
defer env.deinit();
|
||||
try setupFeatures(&env, .{ .cursor = true, .sudo = false, .title = false, .@"ssh-env" = false, .@"ssh-terminfo" = false, .path = false }, false);
|
||||
try testing.expectEqualStrings("cursor:steady", env.get("GHOSTTY_SHELL_FEATURES").?);
|
||||
}
|
||||
}
|
||||
|
||||
/// Setup the bash automatic shell integration. This works by
|
||||
|
||||
Reference in New Issue
Block a user