fish: add descriptions to fish shell completions (#9551)
Add descriptions to fish shell completions Claude Code used to understand the codebase and reason through the edge cases (several iterations) - Using first sentence from the Config to add description for each config, even if sentence spans few lines - Several options can share the same description, code doesn't duplicate description, see screenshot in the posted issue thread below Fixes [#9531](https://github.com/ghostty-org/ghostty/issues/9531)pull/8200/head
commit
a4e65f02b4
|
|
@ -55,7 +55,7 @@ pub fn build(b: *std.Build) !void {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Ghostty resources like terminfo, shell integration, themes, etc.
|
// Ghostty resources like terminfo, shell integration, themes, etc.
|
||||||
const resources = try buildpkg.GhosttyResources.init(b, &config);
|
const resources = try buildpkg.GhosttyResources.init(b, &config, &deps);
|
||||||
const i18n = if (config.i18n) try buildpkg.GhosttyI18n.init(b, &config) else null;
|
const i18n = if (config.i18n) try buildpkg.GhosttyI18n.init(b, &config) else null;
|
||||||
|
|
||||||
// Ghostty executable, the actual runnable Ghostty program.
|
// Ghostty executable, the actual runnable Ghostty program.
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,11 @@ const assert = std.debug.assert;
|
||||||
const buildpkg = @import("main.zig");
|
const buildpkg = @import("main.zig");
|
||||||
const Config = @import("Config.zig");
|
const Config = @import("Config.zig");
|
||||||
const RunStep = std.Build.Step.Run;
|
const RunStep = std.Build.Step.Run;
|
||||||
|
const SharedDeps = @import("SharedDeps.zig");
|
||||||
|
|
||||||
steps: []*std.Build.Step,
|
steps: []*std.Build.Step,
|
||||||
|
|
||||||
pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
pub fn init(b: *std.Build, cfg: *const Config, deps: *const SharedDeps) !GhosttyResources {
|
||||||
var steps: std.ArrayList(*std.Build.Step) = .empty;
|
var steps: std.ArrayList(*std.Build.Step) = .empty;
|
||||||
errdefer steps.deinit(b.allocator);
|
errdefer steps.deinit(b.allocator);
|
||||||
|
|
||||||
|
|
@ -26,6 +27,8 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
||||||
});
|
});
|
||||||
build_data_exe.linkLibC();
|
build_data_exe.linkLibC();
|
||||||
|
|
||||||
|
deps.help_strings.addImport(build_data_exe);
|
||||||
|
|
||||||
// Terminfo
|
// Terminfo
|
||||||
terminfo: {
|
terminfo: {
|
||||||
const os_tag = cfg.target.result.os.tag;
|
const os_tag = cfg.target.result.os.tag;
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ const std = @import("std");
|
||||||
|
|
||||||
const Config = @import("../config/Config.zig");
|
const Config = @import("../config/Config.zig");
|
||||||
const Action = @import("../cli.zig").ghostty.Action;
|
const Action = @import("../cli.zig").ghostty.Action;
|
||||||
|
const help_strings = @import("help_strings");
|
||||||
|
|
||||||
/// A fish completions configuration that contains all the available commands
|
/// A fish completions configuration that contains all the available commands
|
||||||
/// and options.
|
/// and options.
|
||||||
|
|
@ -81,6 +82,15 @@ fn writeCompletions(writer: *std.Io.Writer) !void {
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (@hasDecl(help_strings.Config, field.name)) {
|
||||||
|
const help = @field(help_strings.Config, field.name);
|
||||||
|
const desc = getDescription(help);
|
||||||
|
try writer.writeAll(" -d \"");
|
||||||
|
try writer.writeAll(desc);
|
||||||
|
try writer.writeAll("\"");
|
||||||
|
}
|
||||||
|
|
||||||
try writer.writeAll("\n");
|
try writer.writeAll("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -143,3 +153,54 @@ fn writeCompletions(writer: *std.Io.Writer) !void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn getDescription(comptime help: []const u8) []const u8 {
|
||||||
|
var out: [help.len * 2]u8 = undefined;
|
||||||
|
var len: usize = 0;
|
||||||
|
var prev_was_space = false;
|
||||||
|
|
||||||
|
for (help, 0..) |c, i| {
|
||||||
|
switch (c) {
|
||||||
|
'.' => {
|
||||||
|
out[len] = '.';
|
||||||
|
len += 1;
|
||||||
|
|
||||||
|
if (i + 1 >= help.len) break;
|
||||||
|
const next = help[i + 1];
|
||||||
|
if (next == ' ' or next == '\n') break;
|
||||||
|
},
|
||||||
|
'\n' => {
|
||||||
|
if (!prev_was_space and len > 0) {
|
||||||
|
out[len] = ' ';
|
||||||
|
len += 1;
|
||||||
|
prev_was_space = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'"' => {
|
||||||
|
out[len] = '\\';
|
||||||
|
out[len + 1] = '"';
|
||||||
|
len += 2;
|
||||||
|
prev_was_space = false;
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
out[len] = c;
|
||||||
|
len += 1;
|
||||||
|
prev_was_space = (c == ' ');
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out[0..len];
|
||||||
|
}
|
||||||
|
|
||||||
|
test "getDescription" {
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
const input = "First sentence with \"quotes\"\nand newlines. Second sentence.";
|
||||||
|
const expected = "First sentence with \\\"quotes\\\" and newlines.";
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
const result = getDescription(input);
|
||||||
|
try testing.expectEqualStrings(expected, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue