diff --git a/build.zig b/build.zig index 08cff1561..d642f254a 100644 --- a/build.zig +++ b/build.zig @@ -1596,32 +1596,63 @@ fn buildWebData( b: *std.Build, config: BuildConfig, ) !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: { - var copy = config; - copy.exe_entrypoint = .webgen_config; - break :config copy; - }; + 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 options = b.addOptions(); - try buildconfig.addOptions(options); - webgen_config.root_module.addOptions("build_options", options); + { + const buildconfig = config: { + 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, - "share/ghostty/webdata/config.mdx", - ).step); + { + const buildconfig = config: { + var copy = config; + 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( diff --git a/src/build/webgen/main_actions.zig b/src/build/webgen/main_actions.zig new file mode 100644 index 000000000..587851003 --- /dev/null +++ b/src/build/webgen/main_actions.zig @@ -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"); + } + } +} diff --git a/src/build/webgen/main_config.zig b/src/build/webgen/main_config.zig index 59eddbca4..842d17bf9 100644 --- a/src/build/webgen/main_config.zig +++ b/src/build/webgen/main_config.zig @@ -27,7 +27,7 @@ pub fn genConfig(writer: anytype) !void { \\ ); - @setEvalBranchQuota(3000); + @setEvalBranchQuota(50_000); const fields = @typeInfo(Config).Struct.fields; inline for (fields, 0..) |field, i| { 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 /// supports triple backticks. code, + + /// Callouts. We detect these based on paragraphs starting + /// with "Note:", "Warning:", etc. (case-insensitive). + callout_note, + callout_warning, } = null; while (iter.next()) |s| { // Empty line resets our block if (std.mem.eql(u8, s, "")) { - if (block) |v| switch (v) { - .text => {}, - .code => try writer.writeAll("```\n"), - }; + try endBlock(writer, block); block = null; 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. + const first: bool = block == null; if (block == null) { if (std.mem.startsWith(u8, s, " ")) { block = .code; try writer.writeAll("```\n"); + } else if (std.ascii.startsWithIgnoreCase(s, "note:")) { + block = .callout_note; + try writer.writeAll("\n"); + } else if (std.ascii.startsWithIgnoreCase(s, "warning:")) { + block = .callout_warning; + try writer.writeAll("\n"); } else { block = .text; } @@ -97,6 +106,9 @@ pub fn genConfig(writer: anytype) !void { try writer.writeAll(switch (block.?) { .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, " ")) s[4..] else @@ -104,6 +116,16 @@ pub fn genConfig(writer: anytype) !void { }); try writer.writeAll("\n"); } + try endBlock(writer, block); 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("\n"), + .callout_warning => try writer.writeAll("\n"), + }; +} diff --git a/src/build_config.zig b/src/build_config.zig index 3bd342897..41e2767bf 100644 --- a/src/build_config.zig +++ b/src/build_config.zig @@ -173,6 +173,7 @@ pub const ExeEntrypoint = enum { mdgen_ghostty_1, mdgen_ghostty_5, webgen_config, + webgen_actions, bench_parser, bench_stream, bench_codepoint_width, diff --git a/src/config/Config.zig b/src/config/Config.zig index ca725f409..99c0663cf 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -138,7 +138,7 @@ const c = @cImport({ /// requested style, then the font will be used as-is since the style is /// 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 /// in the `bold-italic` style. If you want to disable `bold-italic`, you must /// 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 /// 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 /// 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 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 /// 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, /// 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 /// set later will overwrite the keybind set earlier. In this case, the /// `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 /// 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. /// When a `global:` keybind is specified and Ghostty is launched or reloaded, /// 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 /// 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 /// unset this configuration to disable the shader. /// @@ -1722,7 +1722,7 @@ keybind: Keybinds = .{}, /// If this is true, then any cgroup initialization failure will cause /// 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. @"linux-cgroup-hard-fail": bool = false, diff --git a/src/main.zig b/src/main.zig index 24c5b7a3f..ecf38fbb3 100644 --- a/src/main.zig +++ b/src/main.zig @@ -8,6 +8,7 @@ const entrypoint = switch (build_config.exe_entrypoint) { .mdgen_ghostty_1 => @import("build/mdgen/main_ghostty_1.zig"), .mdgen_ghostty_5 => @import("build/mdgen/main_ghostty_5.zig"), .webgen_config => @import("build/webgen/main_config.zig"), + .webgen_actions => @import("build/webgen/main_actions.zig"), .bench_parser => @import("bench/parser.zig"), .bench_stream => @import("bench/stream.zig"), .bench_codepoint_width => @import("bench/codepoint-width.zig"),