config: formatted action should be parsable into the original (#13609)

This fixes the issue where an action with string as it's parameter is
not working correctly in CommandPalette, found in #9671. For example:

```
command-palette-entry = title:"Set Ghostty Title",description:test sending text.,action:set_tab_title:👻
keybind=cmd+r=set_tab_title:👻
```

Keybind works perfectly, but the title is escaped when triggering in
CommandPalette.

> Introduced in
[#8873](https://github.com/ghostty-org/ghostty/pull/8873/changes#diff-9e7936787320bcf70e332c868125039d8c0a7f96c4a88f2af0af21d952c6830dR1216),
I tested the fixed issue as well, the following config still parses
correctly, mentioned in
https://github.com/ghostty-org/ghostty/issues/8849#issuecomment-3322018212.

```
command-palette-entry = title:Focus Split: Next,description:"Focus the next split, if any.",action:goto_split:next
```

Also `ghostty +show-config` now will also output the readable strings as
well.
<img width="1078" height="428" alt="image"
src="https://github.com/user-attachments/assets/f9dc1447-7b4e-44f4-8362-b54f4d805c7a"
/>
This commit is contained in:
Mitchell Hashimoto
2026-08-04 11:19:37 -07:00
committed by GitHub

View File

@@ -1524,7 +1524,7 @@ pub const Action = union(enum) {
const value_info = @typeInfo(Value);
switch (Value) {
void => {},
[]const u8 => try std.zig.stringEscape(value, writer),
[]const u8 => try writer.print("{s}", .{value}),
else => switch (value_info) {
.@"enum" => try writer.print("{t}", .{value}),
.float => try writer.print("{d}", .{value}),
@@ -4611,12 +4611,14 @@ test "action: format" {
const testing = std.testing;
const alloc = testing.allocator;
const a: Action = .{ .text = "👻" };
const a: Action = .{ .text = "👻Ghostty'\"" };
var buf: std.Io.Writer.Allocating = .init(alloc);
defer buf.deinit();
try a.format(&buf.writer);
try testing.expectEqualStrings("text:\\xf0\\x9f\\x91\\xbb", buf.written());
const b = try Binding.Action.parse(buf.written());
try testing.expect(a.equal(b));
}
test "action: format set title" {