webgen: update config to support callouts, emit keybind actions (#3023)

This commit is contained in:
Mitchell Hashimoto
2024-12-19 19:27:55 -08:00
committed by GitHub
6 changed files with 134 additions and 33 deletions

View File

@ -1596,32 +1596,63 @@ fn buildWebData(
b: *std.Build, b: *std.Build,
config: BuildConfig, config: BuildConfig,
) !void { ) !void {
const webgen_config = b.addExecutable(.{
.name = "webgen_config",
.root_source_file = b.path("src/main.zig"),
.target = b.host,
});
try addHelp(b, webgen_config, config);
{ {
const buildconfig = config: { const webgen_config = b.addExecutable(.{
var copy = config; .name = "webgen_config",
copy.exe_entrypoint = .webgen_config; .root_source_file = b.path("src/main.zig"),
break :config copy; .target = b.host,
}; });
try addHelp(b, webgen_config, config);
const options = b.addOptions(); {
try buildconfig.addOptions(options); const buildconfig = config: {
webgen_config.root_module.addOptions("build_options", options); var copy = config;
copy.exe_entrypoint = .webgen_config;
break :config copy;
};
const options = b.addOptions();
try buildconfig.addOptions(options);
webgen_config.root_module.addOptions("build_options", options);
}
const webgen_config_step = b.addRunArtifact(webgen_config);
const webgen_config_out = webgen_config_step.captureStdOut();
b.getInstallStep().dependOn(&b.addInstallFile(
webgen_config_out,
"share/ghostty/webdata/config.mdx",
).step);
} }
const webgen_config_step = b.addRunArtifact(webgen_config); {
const webgen_config_out = webgen_config_step.captureStdOut(); const webgen_actions = b.addExecutable(.{
.name = "webgen_actions",
.root_source_file = b.path("src/main.zig"),
.target = b.host,
});
try addHelp(b, webgen_actions, config);
b.getInstallStep().dependOn(&b.addInstallFile( {
webgen_config_out, const buildconfig = config: {
"share/ghostty/webdata/config.mdx", var copy = config;
).step); copy.exe_entrypoint = .webgen_actions;
break :config copy;
};
const options = b.addOptions();
try buildconfig.addOptions(options);
webgen_actions.root_module.addOptions("build_options", options);
}
const webgen_actions_step = b.addRunArtifact(webgen_actions);
const webgen_actions_out = webgen_actions_step.captureStdOut();
b.getInstallStep().dependOn(&b.addInstallFile(
webgen_actions_out,
"share/ghostty/webdata/actions.mdx",
).step);
}
} }
fn benchSteps( fn benchSteps(

View File

@ -0,0 +1,46 @@
const std = @import("std");
const help_strings = @import("help_strings");
const KeybindAction = @import("../../input/Binding.zig").Action;
pub fn main() !void {
const output = std.io.getStdOut().writer();
try genKeybindActions(output);
}
pub fn genKeybindActions(writer: anytype) !void {
// Write the header
try writer.writeAll(
\\---
\\title: Keybinding Action Reference
\\description: Reference of all Ghostty keybinding actions.
\\---
\\
\\This is a reference of all Ghostty keybinding actions.
\\
\\
);
@setEvalBranchQuota(5_000);
const fields = @typeInfo(KeybindAction).Union.fields;
inline for (fields) |field| {
if (field.name[0] == '_') continue;
// Write the field name.
try writer.writeAll("## `");
try writer.writeAll(field.name);
try writer.writeAll("`\n");
if (@hasDecl(help_strings.KeybindAction, field.name)) {
var iter = std.mem.splitScalar(
u8,
@field(help_strings.KeybindAction, field.name),
'\n',
);
while (iter.next()) |s| {
try writer.writeAll(s);
try writer.writeAll("\n");
}
try writer.writeAll("\n\n");
}
}
}

View File

@ -27,7 +27,7 @@ pub fn genConfig(writer: anytype) !void {
\\ \\
); );
@setEvalBranchQuota(3000); @setEvalBranchQuota(50_000);
const fields = @typeInfo(Config).Struct.fields; const fields = @typeInfo(Config).Struct.fields;
inline for (fields, 0..) |field, i| { inline for (fields, 0..) |field, i| {
if (field.name[0] == '_') continue; if (field.name[0] == '_') continue;
@ -70,15 +70,17 @@ pub fn genConfig(writer: anytype) !void {
/// code blocks in our comments but the website parser only /// code blocks in our comments but the website parser only
/// supports triple backticks. /// supports triple backticks.
code, code,
/// Callouts. We detect these based on paragraphs starting
/// with "Note:", "Warning:", etc. (case-insensitive).
callout_note,
callout_warning,
} = null; } = null;
while (iter.next()) |s| { while (iter.next()) |s| {
// Empty line resets our block // Empty line resets our block
if (std.mem.eql(u8, s, "")) { if (std.mem.eql(u8, s, "")) {
if (block) |v| switch (v) { try endBlock(writer, block);
.text => {},
.code => try writer.writeAll("```\n"),
};
block = null; block = null;
try writer.writeAll("\n"); try writer.writeAll("\n");
@ -86,10 +88,17 @@ pub fn genConfig(writer: anytype) !void {
} }
// If we don't have a block figure out our type. // If we don't have a block figure out our type.
const first: bool = block == null;
if (block == null) { if (block == null) {
if (std.mem.startsWith(u8, s, " ")) { if (std.mem.startsWith(u8, s, " ")) {
block = .code; block = .code;
try writer.writeAll("```\n"); try writer.writeAll("```\n");
} else if (std.ascii.startsWithIgnoreCase(s, "note:")) {
block = .callout_note;
try writer.writeAll("<Note>\n");
} else if (std.ascii.startsWithIgnoreCase(s, "warning:")) {
block = .callout_warning;
try writer.writeAll("<Warning>\n");
} else { } else {
block = .text; block = .text;
} }
@ -97,6 +106,9 @@ pub fn genConfig(writer: anytype) !void {
try writer.writeAll(switch (block.?) { try writer.writeAll(switch (block.?) {
.text => s, .text => s,
.callout_note => if (first) s["note:".len..] else s,
.callout_warning => if (first) s["warning:".len..] else s,
.code => if (std.mem.startsWith(u8, s, " ")) .code => if (std.mem.startsWith(u8, s, " "))
s[4..] s[4..]
else else
@ -104,6 +116,16 @@ pub fn genConfig(writer: anytype) !void {
}); });
try writer.writeAll("\n"); try writer.writeAll("\n");
} }
try endBlock(writer, block);
try writer.writeAll("\n"); try writer.writeAll("\n");
} }
} }
fn endBlock(writer: anytype, block: anytype) !void {
if (block) |v| switch (v) {
.text => {},
.code => try writer.writeAll("```\n"),
.callout_note => try writer.writeAll("</Note>\n"),
.callout_warning => try writer.writeAll("</Warning>\n"),
};
}

View File

@ -173,6 +173,7 @@ pub const ExeEntrypoint = enum {
mdgen_ghostty_1, mdgen_ghostty_1,
mdgen_ghostty_5, mdgen_ghostty_5,
webgen_config, webgen_config,
webgen_actions,
bench_parser, bench_parser,
bench_stream, bench_stream,
bench_codepoint_width, bench_codepoint_width,

View File

@ -138,7 +138,7 @@ const c = @cImport({
/// requested style, then the font will be used as-is since the style is /// requested style, then the font will be used as-is since the style is
/// not synthetic. /// not synthetic.
/// ///
/// Warning! An easy mistake is to disable `bold` or `italic` but not /// Warning: An easy mistake is to disable `bold` or `italic` but not
/// `bold-italic`. Disabling only `bold` or `italic` will NOT disable either /// `bold-italic`. Disabling only `bold` or `italic` will NOT disable either
/// in the `bold-italic` style. If you want to disable `bold-italic`, you must /// in the `bold-italic` style. If you want to disable `bold-italic`, you must
/// explicitly disable it. You cannot partially disable `bold-italic`. /// explicitly disable it. You cannot partially disable `bold-italic`.
@ -780,7 +780,7 @@ class: ?[:0]const u8 = null,
/// or the alias. When debugging keybinds, the non-aliased modifier will always /// or the alias. When debugging keybinds, the non-aliased modifier will always
/// be used in output. /// be used in output.
/// ///
/// Note that the fn or "globe" key on keyboards are not supported as a /// Note: The fn or "globe" key on keyboards are not supported as a
/// modifier. This is a limitation of the operating systems and GUI toolkits /// modifier. This is a limitation of the operating systems and GUI toolkits
/// that Ghostty uses. /// that Ghostty uses.
/// ///
@ -791,7 +791,7 @@ class: ?[:0]const u8 = null,
/// is sometimes called a leader key, a key chord, a key table, etc. There /// is sometimes called a leader key, a key chord, a key table, etc. There
/// is no hardcoded limit on the number of parts in a sequence. /// is no hardcoded limit on the number of parts in a sequence.
/// ///
/// Warning: if you define a sequence as a CLI argument to `ghostty`, /// Warning: If you define a sequence as a CLI argument to `ghostty`,
/// you probably have to quote the keybind since `>` is a special character /// you probably have to quote the keybind since `>` is a special character
/// in most shells. Example: ghostty --keybind='ctrl+a>n=new_window' /// in most shells. Example: ghostty --keybind='ctrl+a>n=new_window'
/// ///
@ -880,7 +880,7 @@ class: ?[:0]const u8 = null,
/// Since they are not associated with a specific terminal surface, /// Since they are not associated with a specific terminal surface,
/// they're never encoded. /// they're never encoded.
/// ///
/// Keybind trigger are not unique per prefix combination. For example, /// Keybind triggers are not unique per prefix combination. For example,
/// `ctrl+a` and `global:ctrl+a` are not two separate keybinds. The keybind /// `ctrl+a` and `global:ctrl+a` are not two separate keybinds. The keybind
/// set later will overwrite the keybind set earlier. In this case, the /// set later will overwrite the keybind set earlier. In this case, the
/// `global:` keybind will be used. /// `global:` keybind will be used.
@ -889,7 +889,7 @@ class: ?[:0]const u8 = null,
/// `global:unconsumed:ctrl+a=reload_config` will make the keybind global /// `global:unconsumed:ctrl+a=reload_config` will make the keybind global
/// and not consume the input to reload the config. /// and not consume the input to reload the config.
/// ///
/// A note on `global:`: this feature is only supported on macOS. On macOS, /// Note: `global:` is only supported on macOS. On macOS,
/// this feature requires accessibility permissions to be granted to Ghostty. /// this feature requires accessibility permissions to be granted to Ghostty.
/// When a `global:` keybind is specified and Ghostty is launched or reloaded, /// When a `global:` keybind is specified and Ghostty is launched or reloaded,
/// Ghostty will attempt to request these permissions. If the permissions are /// Ghostty will attempt to request these permissions. If the permissions are
@ -1471,7 +1471,7 @@ keybind: Keybinds = .{},
/// Custom shaders to run after the default shaders. This is a file path /// Custom shaders to run after the default shaders. This is a file path
/// to a GLSL-syntax shader for all platforms. /// to a GLSL-syntax shader for all platforms.
/// ///
/// WARNING: Invalid shaders can cause Ghostty to become unusable such as by /// Warning: Invalid shaders can cause Ghostty to become unusable such as by
/// causing the window to be completely black. If this happens, you can /// causing the window to be completely black. If this happens, you can
/// unset this configuration to disable the shader. /// unset this configuration to disable the shader.
/// ///
@ -1722,7 +1722,7 @@ keybind: Keybinds = .{},
/// If this is true, then any cgroup initialization failure will cause /// If this is true, then any cgroup initialization failure will cause
/// Ghostty to exit or new surfaces to not be created. /// Ghostty to exit or new surfaces to not be created.
/// ///
/// Note: this currently only affects cgroup initialization. Subprocesses /// Note: This currently only affects cgroup initialization. Subprocesses
/// must always be able to move themselves into an isolated cgroup. /// must always be able to move themselves into an isolated cgroup.
@"linux-cgroup-hard-fail": bool = false, @"linux-cgroup-hard-fail": bool = false,

View File

@ -8,6 +8,7 @@ const entrypoint = switch (build_config.exe_entrypoint) {
.mdgen_ghostty_1 => @import("build/mdgen/main_ghostty_1.zig"), .mdgen_ghostty_1 => @import("build/mdgen/main_ghostty_1.zig"),
.mdgen_ghostty_5 => @import("build/mdgen/main_ghostty_5.zig"), .mdgen_ghostty_5 => @import("build/mdgen/main_ghostty_5.zig"),
.webgen_config => @import("build/webgen/main_config.zig"), .webgen_config => @import("build/webgen/main_config.zig"),
.webgen_actions => @import("build/webgen/main_actions.zig"),
.bench_parser => @import("bench/parser.zig"), .bench_parser => @import("bench/parser.zig"),
.bench_stream => @import("bench/stream.zig"), .bench_stream => @import("bench/stream.zig"),
.bench_codepoint_width => @import("bench/codepoint-width.zig"), .bench_codepoint_width => @import("bench/codepoint-width.zig"),