Something went wrong. Try again.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113//! This module is a help generator for keybind actions documentation.//! It can generate documentation in different formats (plaintext for CLI,//! markdown for website) while maintaining consistent content.
const std = @import("std");const KeybindAction = @import("Binding.zig").Action;const help_strings = @import("help_strings");
/// Format options for generating keybind actions documentationpub const Format = enum { /// Plain text output with indentation plaintext, /// Markdown formatted output markdown,
fn formatFieldName(self: Format, writer: *std.Io.Writer, field_name: []const u8) !void { switch (self) { .plaintext => { try writer.writeAll(field_name); try writer.writeAll(":\n"); }, .markdown => { try writer.writeAll("## `"); try writer.writeAll(field_name); try writer.writeAll("`\n"); }, } }
fn formatDocLine(self: Format, writer: *std.Io.Writer, line: []const u8) !void { switch (self) { .plaintext => { try writer.writeAll(" "); try writer.writeAll(line); try writer.writeAll("\n"); }, .markdown => { try writer.writeAll(line); try writer.writeAll("\n"); }, } }
fn header(self: Format) ?[]const u8 { return switch (self) { .plaintext => null, .markdown => \\--- \\title: Keybinding Action Reference \\description: Reference of all Ghostty keybinding actions. \\editOnGithubLink: https://github.com/ghostty-org/ghostty/edit/main/src/input/Binding.zig \\--- \\ \\This is a reference of all Ghostty keybinding actions. \\ \\ , }; }};
/// Generate keybind actions documentation with the specified formatpub fn generate( writer: *std.Io.Writer, format: Format, show_docs: bool, page_allocator: std.mem.Allocator,) !void { if (format.header()) |header| { try writer.writeAll(header); }
var stream: std.Io.Writer.Allocating = .init(page_allocator); defer stream.deinit();
const fields = @typeInfo(KeybindAction).@"union".fields; inline for (fields) |field| { if (field.name[0] == '_') continue;
// Write previously stored doc comment below all related actions if (show_docs and @hasDecl(help_strings.KeybindAction, field.name)) { try writer.writeAll(stream.written()); try writer.writeAll("\n"); stream.clearRetainingCapacity(); }
if (show_docs) { try format.formatFieldName(writer, field.name); } else { try writer.writeAll(field.name); try writer.writeAll("\n"); }
if (show_docs and @hasDecl(help_strings.KeybindAction, field.name)) { var iter = std.mem.splitScalar( u8, @field(help_strings.KeybindAction, field.name), '\n', ); while (iter.next()) |s| { // If it is the last line and empty, then skip it. if (iter.peek() == null and s.len == 0) continue; try format.formatDocLine(&stream.writer, s); } } }
// Write any remaining buffered documentation if (stream.written().len > 0) { try writer.writeAll(stream.written()); }}