diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/builtins.zig | 69 | ||||
| -rw-r--r-- | src/config.zig | 86 | ||||
| -rw-r--r-- | src/ninep/ctl.zig | 29 |
3 files changed, 133 insertions, 51 deletions
diff --git a/src/builtins.zig b/src/builtins.zig index 5818ff51..13f04859 100644 --- a/src/builtins.zig +++ b/src/builtins.zig @@ -431,6 +431,7 @@ comptime { // ---- the two acme verbs ---- +/// Look at its argument: open the file or address it names, else find the word, as a right click does. pub const Look = struct { pub const takes_arg = true; pub const requires_arg = true; @@ -442,6 +443,7 @@ pub const Look = struct { } }; +/// Execute its argument as a middle click on it would, a builtin or a shell command. pub const Exec = struct { pub const takes_arg = true; pub const requires_arg = true; @@ -517,8 +519,9 @@ fn warnModifiedIn(c: Ctx, asking: Pane.Discarding, which: Asked) bool { return modified; } -/// acme's Exit (editors/acme/exec.c:892): quit, once warnModified has -/// nothing to say. +/// Quit the editor, refusing once while a pane holds unsaved text: an Exit +/// with nothing edited since discards it (acme's Exit, editors/acme/exec.c:892, +/// asking warnModified first). pub const Exit = struct { pub const scope: Scope = .session; pub fn run(c: Ctx) void { @@ -580,6 +583,7 @@ pub const Kill = struct { } }; +/// Write the session's panes and layout to a dump file, for Restore. pub const Dump = struct { pub const scope: Scope = .session; pub fn run(c: Ctx) void { @@ -587,6 +591,7 @@ pub const Dump = struct { } }; +/// Replace every pane with those of a dump file, the last one Dump wrote when bare. pub const Restore = struct { pub const scope: Scope = .session; pub const takes_arg = true; @@ -622,6 +627,7 @@ pub const Restore = struct { } }; +/// Attach this terminal to a detached pardes session by name. pub const Attach = struct { pub const scope: Scope = .session; pub const takes_arg = true; @@ -637,6 +643,7 @@ pub const Attach = struct { } }; +/// Detach this pardes from its terminal, leaving the session running. pub const Detach = struct { pub const scope: Scope = .session; pub const enabled = pardes.can_attach; @@ -648,6 +655,7 @@ pub const Detach = struct { } }; +/// Mount another pardes's 9P tree under /n/<name>, given its dial address. pub const Mount = struct { pub const scope: Scope = .session; pub const takes_arg = true; @@ -663,6 +671,7 @@ pub const Mount = struct { } }; +/// Unmount the 9P tree mounted under /n/<name>. pub const Unmount = struct { pub const scope: Scope = .session; pub const takes_arg = true; @@ -679,6 +688,7 @@ pub const Unmount = struct { // ---- the message row ---- +/// Show its argument on this pane's message row. pub const Msg = struct { pub const takes_arg = true; pub const requires_arg = true; @@ -691,6 +701,7 @@ pub const Msg = struct { } }; +/// Switch to the next bundled theme. pub const NextColor = struct { pub const scope: Scope = .session; pub fn run(c: Ctx) void { @@ -698,6 +709,7 @@ pub const NextColor = struct { } }; +/// List the themes in a pane, each a word to click. pub const ThemeSel = struct { pub const scope: Scope = .session; pub const output: OutputTraits = .{ .name = config.themes_buffer, .steps = true, .commands = true }; @@ -706,6 +718,7 @@ pub const ThemeSel = struct { } }; +/// Load a theme from a file. pub const ThemeFile = struct { pub const scope: Scope = .session; pub const takes_arg = true; @@ -719,6 +732,7 @@ pub const ThemeFile = struct { } }; +/// Write the bundled themes into the config directory's themes, to edit. pub const DumpThemes = struct { pub const scope: Scope = .session; pub const enabled = pardes.hosted; @@ -733,6 +747,7 @@ pub const DumpThemes = struct { } }; +/// List the fonts in a pane, each a word to click. pub const FontSel = struct { pub const scope: Scope = .session; pub const output: OutputTraits = .{ .name = config.fonts_buffer, .steps = true, .commands = true }; @@ -745,6 +760,7 @@ pub const FontSel = struct { } }; +/// Show the declarations enclosing the top row at the pane's head, on or off. pub const TreeContext = struct { pub const enabled = pardes.syntax.enabled; pub const takes_arg = true; @@ -769,6 +785,7 @@ pub const TreeContext = struct { } }; +/// Fit the PDF page to the pane by width or by height, flipping between them. pub const PdfFit = struct { pub const enabled = pardes.pdf_enabled; pub fn run(c: Ctx) void { @@ -779,6 +796,7 @@ pub const PdfFit = struct { } }; +/// Tint the PDF page to the theme, or show it as printed, flipping between them. pub const PdfTint = struct { pub const enabled = pardes.pdf_enabled; pub fn run(c: Ctx) void { @@ -789,6 +807,7 @@ pub const PdfTint = struct { } }; +/// List the PDF's sections in a pane, each a place to go. pub const PdfSections = struct { pub const output: OutputTraits = .{ .name = config.pdf_sections_buffer, .steps = true, .locations = true }; pub const enabled = pardes.pdf_enabled; @@ -823,6 +842,7 @@ pub const Ascii = struct { // ---- the system clipboard ---- +/// Copy the selection to the system clipboard. pub const ClipYank = struct { pub fn run(c: Ctx) void { edit.clipYank(c.p, c.pane, false); @@ -837,18 +857,21 @@ pub const ClipYankMain = struct { } }; +/// Paste the system clipboard after the selection. pub const ClipPaste = struct { pub fn run(c: Ctx) void { edit.clipRequest(c.p, c.id, .after); } }; +/// Paste the system clipboard before the selection. pub const ClipPasteBefore = struct { pub fn run(c: Ctx) void { edit.clipRequest(c.p, c.id, .before); } }; +/// Replace the selection with the system clipboard. pub const ClipReplace = struct { pub fn run(c: Ctx) void { edit.clipRequest(c.p, c.id, .replace); @@ -857,6 +880,7 @@ pub const ClipReplace = struct { // ---- panes and columns ---- +/// Write the pane's text to its file, or to the file its argument names. pub const Save = struct { pub const takes_arg = true; pub fn run(c: Ctx) void { @@ -867,6 +891,7 @@ pub const Save = struct { } }; +/// Open an empty scratch pane, <dir>/+New, in this pane's directory. pub const New = struct { pub const output: OutputTraits = .{ .name = config.scratch_buffer, .doc = true, .saves = true }; pub fn run(c: Ctx) void { @@ -923,6 +948,7 @@ pub const Del = struct { } }; +/// Recolour a terminal's program colours to the theme, or show them as sent, flipping between them. pub const Filter = struct { pub fn run(c: Ctx) void { if (!c.pane.isTerminal()) return; @@ -987,6 +1013,7 @@ pub const Undo = struct { } }; +/// Redo the last undone edit. pub const Redo = struct { pub fn run(c: Ctx) void { if (c.pane.file) |f| if (f.history.redo_len == 0) return c.p.setMessage(c.id, "Redo: nothing to redo"); @@ -1001,6 +1028,7 @@ pub const Collapse = struct { } }; +/// Close this column and its panes, refusing once over unsaved text. pub const Delcol = struct { pub fn run(c: Ctx) void { // The column of the tag it came from, else the pane's: a pane ctl's @@ -1013,12 +1041,14 @@ pub const Delcol = struct { } }; +/// Close the pane, giving its rows to the pane above it. pub const DelAbove = struct { pub fn run(c: Ctx) void { Del.run(.{ .p = c.p, .pane = c.pane, .id = c.id, .txt = c.txt, .arg = "k" }); } }; +/// Close the pane, giving its rows to the pane below it. pub const DelBelow = struct { pub fn run(c: Ctx) void { Del.run(.{ .p = c.p, .pane = c.pane, .id = c.id, .txt = c.txt, .arg = "j" }); @@ -1056,7 +1086,8 @@ pub const Tty9p = struct { } }; -/// Binds this terminal as a language's REPL, by the language's name as the +/// Binds this terminal as a language's REPL, so an exec on that language's +/// files is typed into it instead of run. The language is named as the /// syntax table has it: an exec made on the body of a file in that /// language -- a middle click, the execute key, a single word like `ls` /// as much as a selection -- and one made on this terminal's own body, is @@ -1142,6 +1173,7 @@ pub const Joincol = struct { } }; +/// Open the tutor, a document to work through. pub const Tutor = struct { pub const scope: Scope = .session; pub fn run(c: Ctx) void { @@ -1151,6 +1183,7 @@ pub const Tutor = struct { } }; +/// Open the help: every key and every builtin. pub const Help = struct { pub const scope: Scope = .session; pub const output: OutputTraits = .{ .name = config.help_buffer }; @@ -1159,6 +1192,7 @@ pub const Help = struct { } }; +/// Open the settings in effect, each a word to click. pub const Config = struct { pub const scope: Scope = .session; pub const output: OutputTraits = .{ .name = config.config_buffer }; @@ -1167,6 +1201,7 @@ pub const Config = struct { } }; +/// Set how location rows are drawn, or show how they are when bare. pub const LocationsConfig = struct { pub const scope: Scope = .session; pub const takes_arg = true; @@ -1197,6 +1232,7 @@ pub const LocationsConfig = struct { } }; +/// Open the messages shown so far. pub const Messages = struct { pub const scope: Scope = .session; pub const output: OutputTraits = .{ .name = config.messages_buffer }; @@ -1215,6 +1251,7 @@ pub const Changelog = struct { } }; +/// Open the source of a panel transition or post shader, by name. pub const EffectCode = struct { pub const scope: Scope = .session; pub const takes_arg = true; @@ -1242,6 +1279,7 @@ pub const Pet = struct { } }; +/// Open a minimap of the file in braille dots. pub const Mini = struct { pub const takes_arg = true; pub const output: OutputTraits = .{ .name = "Mini", .doc = true }; @@ -1254,6 +1292,7 @@ pub const Mini = struct { // ---- search ---- +/// List every place a pattern matches in the pane, in a +Search. pub const Find = struct { pub const takes_arg = true; pub const requires_arg = true; @@ -1290,6 +1329,7 @@ pub const Grep = struct { // nothing above it reaches its column's tag, then the workspace's, and Down // comes back the same way. Left and Right walk the column tags. +/// Move the keyboard to the pane, or column tag, to the left. pub const Left = struct { pub fn run(c: Ctx) void { if (c.p.header_focus) { @@ -1300,6 +1340,7 @@ pub const Left = struct { } }; +/// Move the keyboard to the pane below, off a tag onto the pane under it. pub const Down = struct { pub fn run(c: Ctx) void { if (c.p.header_focus) { @@ -1318,6 +1359,7 @@ pub const Down = struct { } }; +/// Move the keyboard to the pane above, and from a column's top pane to its tag. pub const Up = struct { pub fn run(c: Ctx) void { if (c.p.header_focus) { @@ -1331,6 +1373,7 @@ pub const Up = struct { } }; +/// Move the keyboard to the pane, or column tag, to the right. pub const Right = struct { pub fn run(c: Ctx) void { if (c.p.header_focus) { @@ -1359,6 +1402,7 @@ pub const Forward = struct { } }; +/// Go back to the last place jumped from in another pane. pub const Last = struct { pub fn run(c: Ctx) void { var i = c.p.njumps; @@ -1374,6 +1418,7 @@ pub const Last = struct { } }; +/// List the places jumped from, each a place to go. pub const Jumplist = struct { pub const scope: Scope = .session; pub const output: OutputTraits = .{ .name = config.jumps_buffer, .steps = true, .locations = true }; @@ -1384,66 +1429,77 @@ pub const Jumplist = struct { // ---- the language group ---- +/// Ask the language server about the symbol under the cursor. pub const Hover = struct { pub fn run(c: Ctx) void { c.p.lspRequest(c.id, .hover, ""); } }; +/// List the language server's code actions for the cursor. pub const CodeAction = struct { pub fn run(c: Ctx) void { c.p.lspRequest(c.id, .code_action, ""); } }; +/// Select every reference to the symbol under the cursor. pub const SelectRefs = struct { pub fn run(c: Ctx) void { c.p.lspRequest(c.id, .select_refs, ""); } }; +/// List the file's symbols from the language server. pub const Symbols = struct { pub fn run(c: Ctx) void { c.p.lspRequest(c.id, .document_symbols, ""); } }; +/// List the file's diagnostics from the language server. pub const Diagnostics = struct { pub fn run(c: Ctx) void { c.p.lspRequest(c.id, .diagnostics, ""); } }; +/// List the workspace's diagnostics from the language server. pub const WsDiagnostics = struct { pub fn run(c: Ctx) void { c.p.lspRequest(c.id, .workspace_diagnostics, ""); } }; +/// List the callers of the function under the cursor. pub const Callers = struct { pub fn run(c: Ctx) void { c.p.lspRequest(c.id, .incoming_calls, ""); } }; +/// List the functions the function under the cursor calls. pub const Callees = struct { pub fn run(c: Ctx) void { c.p.lspRequest(c.id, .outgoing_calls, ""); } }; +/// List the supertypes of the type under the cursor. pub const Supertypes = struct { pub fn run(c: Ctx) void { c.p.lspRequest(c.id, .supertypes, ""); } }; +/// List the subtypes of the type under the cursor. pub const Subtypes = struct { pub fn run(c: Ctx) void { c.p.lspRequest(c.id, .subtypes, ""); } }; +/// Rename the symbol under the cursor everywhere, to its argument. pub const Rename = struct { pub const takes_arg = true; pub const requires_arg = true; @@ -1454,6 +1510,7 @@ pub const Rename = struct { } }; +/// Search the workspace's symbols for its argument. pub const WsSymbols = struct { pub const takes_arg = true; pub const requires_arg = true; @@ -1464,18 +1521,21 @@ pub const WsSymbols = struct { } }; +/// Show which language servers serve this file and their state. pub const Lspinfo = struct { pub fn run(c: Ctx) void { c.p.lspRequest(c.id, .status, ""); } }; +/// Explain how the last language server request was answered, step by step. pub const Lspwhy = struct { pub fn run(c: Ctx) void { c.p.lspRequest(c.id, .explain, ""); } }; +/// Read the board memory at an address, into a pane. pub const Peek = struct { pub const scope: Scope = .session; pub const takes_arg = true; @@ -1490,6 +1550,7 @@ pub const Peek = struct { } }; +/// Write a value to the board memory at an address. pub const Poke = struct { pub const scope: Scope = .session; pub const takes_arg = true; @@ -1503,6 +1564,7 @@ pub const Poke = struct { } }; +/// Dump a range of the board memory in hex, into a pane. pub const Hexdump = struct { pub const scope: Scope = .session; pub const takes_arg = true; @@ -1517,6 +1579,7 @@ pub const Hexdump = struct { } }; +/// Read or set the board GPIO pins, into a pane. pub const Gpio = struct { pub const scope: Scope = .session; pub const takes_arg = true; diff --git a/src/config.zig b/src/config.zig index b7662f1a..2fa6f89d 100644 --- a/src/config.zig +++ b/src/config.zig @@ -917,6 +917,8 @@ pub const Runtime = struct { pub const Setting = struct { word: []const u8, action: Action, + /// What it does, one sentence: /commands lists it after the word. + doc: []const u8, availability: ?Capability = null, pub fn enabled(setting: Setting, capabilities: Capabilities) bool { @@ -929,48 +931,48 @@ pub const Runtime = struct { // The builtin registry and Config report share this command table. pub const settings = [_]Setting{ - .{ .word = "Colors", .action = .{ .toggle = .colors } }, - .{ .word = "Wrap", .action = .{ .toggle = .wrap } }, - .{ .word = "TreeContextTagStyle", .action = .{ .toggle = .tree_context_tag_style } }, - .{ .word = "Tagbottom", .action = .{ .toggle = .tag_bottom } }, - .{ .word = "Debug", .action = .{ .toggle = .debug } }, - .{ .word = "FocusTint", .action = .{ .toggle = .focus_tint } }, - .{ .word = "SyntaxBold", .action = .{ .toggle = .syntax_bold } }, - .{ .word = "Verbose", .action = .{ .toggle = .verbose } }, - .{ .word = "MessageAnimation", .action = .{ .toggle = .message_animation } }, - .{ .word = "Ligatures", .action = .{ .toggle = .ligatures }, .availability = .ligatures }, - .{ .word = "CursorBlink", .action = .{ .toggle = .cursor_blink }, .availability = .lift }, - .{ .word = "Lift", .action = .lift, .availability = .lift }, - .{ .word = "Motion", .action = .motion }, - .{ .word = "InactiveDim", .action = .inactive_dim }, - .{ .word = "GripWidth", .action = .grip_width, .availability = .lift }, - .{ .word = "MessageLinger", .action = .{ .message_ms = .linger } }, - .{ .word = "MessageFall", .action = .{ .message_ms = .fall } }, - .{ .word = "MessageDissolve", .action = .{ .message_ms = .dissolve } }, - .{ .word = "DumpDir", .action = .dump_dir }, - .{ .word = "Theme", .action = .theme }, - .{ .word = "Shell", .action = .shell }, - .{ .word = "Font", .action = .font, .availability = .font_picker }, - .{ .word = "TaglineSize", .action = .tagline_size, .availability = .font_picker }, - .{ .word = "WindowOpacity", .action = .window_opacity, .availability = .window_opacity }, - .{ .word = "WindowBlur", .action = .window_blur, .availability = .window_blur }, - .{ .word = "PanelSlide", .action = .{ .transition = .slide }, .availability = .panel_transitions }, - .{ .word = "PanelZoom", .action = .{ .transition = .zoom }, .availability = .panel_transitions }, - .{ .word = "PanelDissolve", .action = .{ .transition = .dissolve }, .availability = .panel_transitions }, - .{ .word = "PanelAscii", .action = .{ .transition = .ascii }, .availability = .panel_transitions }, - .{ .word = "PanelVertical", .action = .{ .transition = .vertical }, .availability = .panel_transitions }, - .{ .word = "PanelEdges", .action = .{ .transition = .edges }, .availability = .panel_transitions }, - .{ .word = "PanelFall", .action = .{ .transition = .fall }, .availability = .panel_transitions }, - .{ .word = "PanelWave", .action = .{ .transition = .wave }, .availability = .panel_transitions }, - .{ .word = "PanelCurtain", .action = .{ .transition = .curtain }, .availability = .panel_transitions }, - .{ .word = "PanelScramble", .action = .{ .transition = .scramble }, .availability = .panel_transitions }, - .{ .word = "PanelType", .action = .{ .transition = .typewriter }, .availability = .panel_transitions }, - .{ .word = "Crt", .action = .{ .scene = .crt }, .availability = .scene_shaders }, - .{ .word = "Shader", .action = .shader, .availability = .scene_shaders }, - .{ .word = "ShaderAnimation", .action = .shader_animation, .availability = .scene_shaders }, - .{ .word = "Placement", .action = .{ .choice = .placement } }, - .{ .word = "BootShell", .action = .{ .choice = .boot_shell } }, - .{ .word = "LookWord", .action = .{ .choice = .look_word } }, + .{ .word = "Colors", .action = .{ .toggle = .colors }, .doc = "Syntax colours in text panes, on or off." }, + .{ .word = "Wrap", .action = .{ .toggle = .wrap }, .doc = "Long lines wrap onto the next row, on or off." }, + .{ .word = "TreeContextTagStyle", .action = .{ .toggle = .tree_context_tag_style }, .doc = "A pane's TreeContext rows draw in the tag's style, on or off." }, + .{ .word = "Tagbottom", .action = .{ .toggle = .tag_bottom }, .doc = "Each pane's tag goes at its foot rather than its head, on or off." }, + .{ .word = "Debug", .action = .{ .toggle = .debug }, .doc = "A small box of frame statistics at the top right, on or off." }, + .{ .word = "FocusTint", .action = .{ .toggle = .focus_tint }, .doc = "The focused pane's and column's tags are tinted, on or off." }, + .{ .word = "SyntaxBold", .action = .{ .toggle = .syntax_bold }, .doc = "Keywords and the like are drawn bold, on or off." }, + .{ .word = "Verbose", .action = .{ .toggle = .verbose }, .doc = "A builtin says its own name on the message row as it runs, on or off." }, + .{ .word = "MessageAnimation", .action = .{ .toggle = .message_animation }, .doc = "A message falls into its row and dissolves out of it, on or off." }, + .{ .word = "Ligatures", .action = .{ .toggle = .ligatures }, .availability = .ligatures, .doc = "A font's programming ligatures draw across their cells, on or off." }, + .{ .word = "CursorBlink", .action = .{ .toggle = .cursor_blink }, .availability = .lift, .doc = "The cursor blinks, solid while typing, on or off." }, + .{ .word = "Lift", .action = .lift, .availability = .lift, .doc = "How the focused pane stands off the page: off, shadow, rim or auto." }, + .{ .word = "Motion", .action = .motion, .doc = "How animations move: off, crisp, smooth, bouncy or playful." }, + .{ .word = "InactiveDim", .action = .inactive_dim, .doc = "Fade the unfocused panes' text by a percentage, 0 through 100, 0 off." }, + .{ .word = "GripWidth", .action = .grip_width, .availability = .lift, .doc = "The grip and scrollbar width, as a percent of the theme's rail." }, + .{ .word = "MessageLinger", .action = .{ .message_ms = .linger }, .doc = "How long, in milliseconds, a message stays after what dismisses it." }, + .{ .word = "MessageFall", .action = .{ .message_ms = .fall }, .doc = "How long, in milliseconds, a message takes to fall into its row." }, + .{ .word = "MessageDissolve", .action = .{ .message_ms = .dissolve }, .doc = "How long, in milliseconds, a message takes to dissolve." }, + .{ .word = "DumpDir", .action = .dump_dir, .doc = "The directory Dump writes to and a relative Restore reads from; bare, the default." }, + .{ .word = "Theme", .action = .theme, .doc = "Switch to the named theme." }, + .{ .word = "Shell", .action = .shell, .doc = "The shell new terminals run; bare, the login shell." }, + .{ .word = "Font", .action = .font, .availability = .font_picker, .doc = "The body font, by name or path, and its size." }, + .{ .word = "TaglineSize", .action = .tagline_size, .availability = .font_picker, .doc = "Scale the tag font, a percentage." }, + .{ .word = "WindowOpacity", .action = .window_opacity, .availability = .window_opacity, .doc = "The window's opacity, a percentage." }, + .{ .word = "WindowBlur", .action = .window_blur, .availability = .window_blur, .doc = "The blur behind a translucent window, a radius." }, + .{ .word = "PanelSlide", .action = .{ .transition = .slide }, .availability = .panel_transitions, .doc = "Panes slide in and out as they open and close, on or off." }, + .{ .word = "PanelZoom", .action = .{ .transition = .zoom }, .availability = .panel_transitions, .doc = "Panes zoom in and out as they open and close, on or off." }, + .{ .word = "PanelDissolve", .action = .{ .transition = .dissolve }, .availability = .panel_transitions, .doc = "Panes dissolve in and out as they open and close, on or off." }, + .{ .word = "PanelAscii", .action = .{ .transition = .ascii }, .availability = .panel_transitions, .doc = "Panes open and close through a scatter of ASCII, on or off." }, + .{ .word = "PanelVertical", .action = .{ .transition = .vertical }, .availability = .panel_transitions, .doc = "Panes open and close with a vertical wipe, on or off." }, + .{ .word = "PanelEdges", .action = .{ .transition = .edges }, .availability = .panel_transitions, .doc = "Panes open and close from their edges, on or off." }, + .{ .word = "PanelFall", .action = .{ .transition = .fall }, .availability = .panel_transitions, .doc = "Panes fall into place as they open, on or off." }, + .{ .word = "PanelWave", .action = .{ .transition = .wave }, .availability = .panel_transitions, .doc = "Panes open and close in a wave, on or off." }, + .{ .word = "PanelCurtain", .action = .{ .transition = .curtain }, .availability = .panel_transitions, .doc = "Panes open and close like a curtain, on or off." }, + .{ .word = "PanelScramble", .action = .{ .transition = .scramble }, .availability = .panel_transitions, .doc = "Panes open and close through scrambled text, on or off." }, + .{ .word = "PanelType", .action = .{ .transition = .typewriter }, .availability = .panel_transitions, .doc = "Panes type themselves in as they open, on or off." }, + .{ .word = "Crt", .action = .{ .scene = .crt }, .availability = .scene_shaders, .doc = "The bundled CRT post pass over the window, on or off." }, + .{ .word = "Shader", .action = .shader, .availability = .scene_shaders, .doc = "A Shadertoy file into the post chain, or out of it; off empties the chain." }, + .{ .word = "ShaderAnimation", .action = .shader_animation, .availability = .scene_shaders, .doc = "When the post chain animates on its own: off, on (while focused) or always." }, + .{ .word = "Placement", .action = .{ .choice = .placement }, .doc = "Where a new pane goes: acme, as makenewwindow does, or pardes, the older rules." }, + .{ .word = "BootShell", .action = .{ .choice = .boot_shell }, .doc = "A document dropped where a lone untouched shell stands: keep the shell, or replace it." }, + .{ .word = "LookWord", .action = .{ .choice = .look_word }, .doc = "A plain word looked at: search selects its next place in the pane, list lists every place in a +Search." }, }; pub fn find(name: []const u8) ?Setting { diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig index bed53473..de63c6aa 100644 --- a/src/ninep/ctl.zig +++ b/src/ninep/ctl.zig @@ -636,9 +636,9 @@ fn writeCommands(w: *std.Io.Writer) !void { var first = true; while (parts.next()) |v| : (first = false) try w.print("{s}{s}", .{ if (first) "" else ",", v }); }; - // Then ` -- ` and what it does, when its source says. + // Then ` -- ` and what it does: a setting's doc, else its source's. var summary_buf: [2048]u8 = undefined; - const summary = summaryOf(@tagName(b), &summary_buf); + const summary = if (config.Runtime.find(@tagName(b))) |setting| setting.doc else summaryOf(@tagName(b), &summary_buf); if (summary.len > 0) { // The sentence whole unless it is long, then cut between words. const kept = @import("../Messages.zig").clip(summary, 240); @@ -1760,14 +1760,20 @@ test "a looked word is found in its own pane, next place after the dot, wrapping try testing.expect(listed); } -test "each word's /commands description is its own doc comment's first sentence, no citation" { +test "every word's /commands description is its own doc comment's first sentence, no citation" { const p = try withFile(testing.allocator, "x\n"); defer p.deinit(); const listed = rd(p, @intFromEnum(tree.TopFile.commands), 0, 1 << 16).bytes; for ([_][]const u8{ - "\nRepl arg pane -- Binds this terminal as a language's REPL", + "\nRepl arg pane -- Binds this terminal as a language's REPL, so an exec on that language's files is typed into it instead of run.\n", "\nJoincol root -- Fold the active pane's column into the one on its right, keeping its panes.\n", - "\nExit root -- acme's Exit: quit, once warnModified has nothing to say.\n", + "\nExit root -- Quit the editor, refusing once while a pane holds unsaved text: an Exit with nothing edited since discards it.\n", + "\nColors arg root on,off -- Syntax colours in text panes, on or off.\n", + // fs.md's examples, as they read. + "\nNewcol root -- An empty column right of the keyboard's, its tag taking the keyboard.\n", + "\nSave arg pane -- Write the pane's text to its file, or to the file its argument names.\n", + "\nVerbose arg root on,off -- A builtin says its own name on the message row as it runs, on or off.\n", + "\nPlacement arg root acme,pardes -- Where a new pane goes: acme, as makenewwindow does, or pardes, the older rules.\n", "\nKill arg root -- acme's Kill: stop the commands pardes started", }) |row| try testing.expect(std.mem.indexOf(u8, listed, row) != null); try testing.expect(std.mem.indexOf(u8, listed, ".c:") == null); @@ -1775,9 +1781,19 @@ test "each word's /commands description is its own doc comment's first sentence, // above its word's declaration in builtins.zig. const source = @embedFile("../builtins.zig"); var it = std.mem.tokenizeScalar(u8, listed, '\n'); + var undescribed: usize = 0; while (it.next()) |line| { - const dashes = std.mem.indexOf(u8, line, " -- ") orelse continue; + // Every builtin has one: a word nobody can look up is no use. + const dashes = std.mem.indexOf(u8, line, " -- ") orelse { + std.debug.print("no doc comment: {s}\n", .{line}); + undescribed += 1; + continue; + }; const word = line[0 .. std.mem.indexOfScalar(u8, line, ' ').?]; + if (config.Runtime.find(word)) |setting| { + try testing.expect(std.mem.endsWith(u8, line, setting.doc)); + continue; + } var needle: [64]u8 = undefined; const at = std.mem.indexOf(u8, source, try std.fmt.bufPrint(&needle, "\npub const {s} = struct", .{word})).?; const said = std.mem.trimEnd(u8, line[dashes + 4 ..], "…"); @@ -1786,6 +1802,7 @@ test "each word's /commands description is its own doc comment's first sentence, const block_start = std.mem.lastIndexOf(u8, source[0..at], "\n\n") orelse 0; try testing.expect(std.mem.indexOf(u8, source[block_start..at], head) != null); } + try testing.expectEqual(0, undescribed); } test "Newcol at the column cap fails the write and says the cap" { |
