Merge pull request #5511 from uhs-robert/feat/arg-metadata
Some checks failed
lint / lint (lint) (push) Has been cancelled
lint / lint (mozilla) (push) Has been cancelled
lint / lint (unit) (push) Has been cancelled
e2e / test (push) Has been cancelled
Website / build (push) Has been cancelled
Website / deploy (push) Has been cancelled

Add @arg tag support for documenting excmd flags
This commit is contained in:
Oliver Blanthorn 2026-08-28 18:40:42 +00:00 committed by GitHub
commit 8a6bae175e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 181 additions and 47 deletions

View file

@ -32,6 +32,25 @@ function convertMetadata(project) {
.map(part => part.text || "")
.join("")
.replace(/\n+$/, "")
const argFlags = comment => {
const flags = {}
for (const tag of comment?.blockTags || []) {
if (tag.tag !== "@flag") continue
const text = (tag.content || [])
.map(part => part.text || "")
.join("")
const flagText = text.split(/\r?\n[ \t]*\r?\n/, 1)[0]
const m = /^(-\S+)[ \t]+([^\n]+)\n*([\s\S]*)$/.exec(flagText.trim())
if (!m) continue
const [, flag, short, rest] = m
const elaboration = rest.trim()
flags[flag] = {
short,
description: elaboration ? `${short}\n\n${elaboration}` : short,
}
}
return flags
}
const normalizeParameter = (parameter, resolving) => ({
name: parameter.name,
@ -152,15 +171,16 @@ function convertMetadata(project) {
.filter(node => node.kind === KIND.Function)
.map(node => {
const signature = node.signatures?.[0]
const comment = signature?.comment || node.comment
const flags = argFlags(comment)
return [
node.name,
{
doc:
commentText(signature?.comment) ||
commentText(node.comment),
doc: commentText(comment),
params: (signature?.parameters || []).map(parameter =>
normalizeParameter(parameter),
),
...(Object.keys(flags).length ? { flags } : {}),
},
]
}),

View file

@ -48,8 +48,7 @@ function rewriteWikiLinks(parts, owner, reflections) {
candidate =>
!candidate.kindOf(
ReflectionKind.Module | ReflectionKind.Namespace,
) &&
!candidate.sources?.some(isGeneratedSource),
) && !candidate.sources?.some(isGeneratedSource),
) ||
candidates.find(
candidate =>
@ -252,7 +251,91 @@ class TridactylRouter extends KindRouter {
}
}
function parseFlagTag(tag) {
const parts = tag.content || []
let text = ""
let trailing = []
for (let i = 0; i < parts.length; i++) {
const part = parts[i]
const match = part.kind === "text" && /\r?\n[ \t]*\r?\n/.exec(part.text)
if (!match) {
text += part.text || ""
continue
}
text += part.text.slice(0, match.index)
trailing = [
{
...part,
text: part.text.slice(match.index + match[0].length),
},
...parts.slice(i + 1),
]
break
}
const m = /^(-\S+)[ \t]+([^\n]+)\n*([\s\S]*)$/.exec(text.trim())
if (!m) return undefined
const [, flag, short, rest] = m
const elaboration = rest.trim()
return [flag, short, elaboration, trailing]
}
function renderFlagList(context, parsed) {
if (parsed.length === 0) return null
return h(
"ul",
{ class: "tsd-tag-flag tsd-parameter-list" },
parsed.map(([flag, short, elaboration]) =>
h(
"li",
null,
h("code", null, flag),
" ",
short,
elaboration &&
context.displayParts([{ kind: "text", text: elaboration }]),
),
),
)
}
class TridactylTheme extends DefaultTheme {
getRenderContext(page) {
const context = super.getRenderContext(page)
const defaultCommentSummary = context.commentSummary
context.commentSummary = props => {
const blockTags = props.comment?.blockTags || []
if (!blockTags.some(tag => tag.tag === "@flag"))
return defaultCommentSummary(props)
const summaryHeadingCount = page.pageHeadings.length
const nodes = [context.displayParts(props.comment?.summary || [])]
page.pageHeadings.length = summaryHeadingCount
let flagRun = []
const flushFlags = () => {
if (flagRun.length === 0) return
nodes.push(renderFlagList(context, flagRun))
flagRun = []
}
for (const tag of blockTags) {
if (tag.tag === "@flag") {
tag.skipRendering = true
const parsed = parseFlagTag(tag)
if (!parsed) continue
const [flag, short, elaboration, trailing] = parsed
flagRun.push([flag, short, elaboration])
if (trailing.length === 0) continue
flushFlags()
const headingCount = page.pageHeadings.length
nodes.push(context.displayParts(trailing))
page.pageHeadings.length = headingCount
}
}
flushFlags()
return h(JSX.Fragment, null, ...nodes)
}
return context
}
getReflectionClasses(reflection) {
const kind = ReflectionKind.classString(reflection.kind)
const parent =
@ -335,7 +418,10 @@ class TridactylTheme extends DefaultTheme {
h(
"ul",
null,
docLink("Commands", "modules/_src_excmds_.html"),
docLink(
"Commands",
"modules/_src_excmds_.html",
),
docLink(
"Settings",
"classes/_src_lib_config_.default_config.html",

View file

@ -5526,68 +5526,83 @@ const KILL_STACK: Element[] = []
/**
* Hint a page.
*
* @param args Arguments to the `:hint` command. Multiple flags can be combined as long as they don't conflict.
* Multiple flags can be used in the `:hint` command and combined as long as they don't conflict.
* Selectors can be specified either standalone (without a flag preceding them) or with the `-c` option. Arguments that
* take callbacks (`-F` or `-W`) should be specified last, as they consume the rest of the command line.
*
* Hinting action flags (only one can be specified):
* #### Hinting action flags (only one can be specified):
*
* - -t open in a new foreground tab
* - -b open in background
* - -y copy (yank) link's target to clipboard
* - -p copy an element's text to the clipboard
* - -h select an element (as if you click-n-dragged over it)
* - -P copy an element's title/alt text to the clipboard
* - -r read an element's text with text-to-speech
* - -i view an image
* - -I view an image in a new tab
* - -k irreversibly deletes an element from the page (until reload)
* - -K hides an element on the page; hidden elements can be restored using [[elementunhide]].
* - -s save (download) the linked resource
* - -S save the linked image
* - -a save-as the linked resource
* - -A save-as the linked image
* - -; focus an element and set it as the element or the child of the element to scroll
* - -# yank an element's anchor URL to clipboard
* - -w open in new window
* - -wp open in new private window
* - -z scroll an element to the top of the viewport
* - `-pipe selector key` e.g, `-pipe a href` returns the URL of the chosen link on a page. Only makes sense with `composite`, e.g, `composite hint -pipe .some-class>a textContent | yank`. If you don't select a hint (i.e. press `<Esc>`), will return an empty string. Most useful when used like `-c` to do things other than opening links. NB: the query selector cannot contain any spaces.
* - `-W excmd...` pass hint href as the final argument to excmd and execute, e.g, `hint -W mpvsafe` to open YouTube videos. NB: passing it to bare [[exclaim]] is dangerous - see `get exaliases.mpvsafe` for an example of how to do it safely. The usual [[composite]] caveats for `;` and `|` in URLs apply. If you need to use a query selector, use `-pipe` instead.
* - -F [callback] - run a custom callback on the selected hint, e.g. `hint -JF e => {tri.excmds.tabopen("-b",e.href); e.remove()}`.
* @flag -t open in a new foreground tab
* @flag -b open in background
* @flag -y copy (yank) link's target to clipboard
* @flag -p copy an element's text to the clipboard
* @flag -h select an element (as if you click-n-dragged over it)
* @flag -P copy an element's title/alt text to the clipboard
* @flag -r read an element's text with text-to-speech
* @flag -i view an image
* @flag -I view an image in a new tab
* @flag -k irreversibly deletes an element from the page (until reload)
* @flag -K hides an element on the page
* - Hidden elements can be restored using [[elementunhide]].
* @flag -s save (download) the linked resource
* @flag -S save the linked image
* @flag -a save-as the linked resource
* @flag -A save-as the linked image
* @flag -; focus an element and set it as the element or the child of the element to scroll
* @flag -# yank an element's anchor URL to clipboard
* @flag -w open in new window
* @flag -wp open in new private window
* @flag -z scroll an element to the top of the viewport
* @flag -pipe `selector key`, e.g, `-pipe a href` returns the URL of the chosen link on a page.
* - Only makes sense with `composite`, e.g, `composite hint -pipe .some-class>a textContent | yank`.
* - If you don't select a hint (i.e. press `<Esc>`), will return an empty string.
* - Most useful when used like `-c` to do things other than opening links.
* - NB: the query selector cannot contain any spaces.
* @flag -W `excmd...` pass hint href as the final argument to excmd and execute.
* - e.g, `hint -W mpvsafe` to open YouTube videos.
* - NB: passing it to bare [[exclaim]] is dangerous - see `get exaliases.mpvsafe` for an example of how to do it safely.
* - The usual [[composite]] caveats for `;` and `|` in URLs apply.
* - If you need to use a query selector, use `-pipe` instead.
* @flag -F [callback] - run a custom callback on the selected hint
* - e.g. `hint -JF e => {tri.excmds.tabopen("-b",e.href); e.remove()}`.
*
* Element selection flags:
* #### Element selection flags
*
* - -c [selector] hint links that match the css selector
* - `bind ;c hint -c [class*="expand"],[class*="togg"]` works particularly well on reddit and HN
* - this works with most other hint modes, with the caveat that if other hint mode takes arguments your selector must contain no spaces, i.e. `hint -c[yourOtherFlag] [selector] [your other flag's arguments, which may contain spaces]`
* - -C [selector] like `-c [selector]` but also hints all elements that would normally be hinted given the other options selected
* - -x [selector] exclude the matched elements from hinting
* - -f [text] hint links and inputs that display the given text
* - `bind <c-e> hint -f Edit`
* - Backslashes can escape spaces: `bind <c-s> hint -f Save\ as`
* - -fr [text] use RegExp to hint the links and inputs
* - -J* disable javascript hints. Don't generate hints related to javascript events. This is particularly useful when used with the `-c` option when you want to generate only hints for the specified css selectors. Also useful on sites with plenty of useless javascript elements such as google.com
* - -V create hints for invisible elements. By default, elements outside the viewport when calling :hint are not hinted, this includes them anyways.
* @flag -c hint links that match the css selector
* - `bind ;c hint -c [class*="expand"],[class*="togg"]` works particularly well on reddit and HN.
* - This works with most other hint modes, with the caveat that if other hint mode takes arguments your selector must contain no spaces, i.e. `hint -c[yourOtherFlag] [selector] [your other flag's arguments, which may contain spaces]`
* @flag -C like -c but also hints all elements that would normally be hinted given the other options selected
* @flag -x exclude the matched elements from hinting
* @flag -f hint links and inputs that display the given text
* - `bind <c-e> hint -f Edit`.
* - Backslashes can escape spaces: `bind <c-s> hint -f Save\ as`
* @flag -fr use RegExp to hint the links and inputs
* @flag -J disable javascript hints
* - Don't generate hints related to javascript events. This is particularly useful when used with the `-c` option when you want to generate only hints for the specified css selectors.
* - Also useful on sites with plenty of useless javascript elements such as google.com
* @flag -V create hints for invisible elements
* - By default, elements outside the viewport when calling :hint are not hinted; this includes them anyways.
*
* Hinting mode selection:
* #### Hinting mode selection:
*
* - -q* quick (or rapid) hints mode. Stay in hint mode until you press `<Esc>`, e.g. `:hint -qb` to open multiple hints in the background or `:hint -qW excmd` to execute excmd once for each hint. This will return an array containing all elements or the result of executed functions (e.g. `hint -qpipe a href` will return an array of links).
* - For example, use `bind ;jg hint -Jc .rc > .r > a` on google.com to generate hints only for clickable search results of a given query
* - -! execute all hints without waiting for a selection
* - For example, `hint -!bf Comments` opens in background tabs all visible links whose text matches `Comments`
*
* Deprecated options:
* #### Deprecated options:
*
* - -br deprecated, use `-qb` instead
*
* #### Usage:
*
* Excepting the custom selector mode, background hint mode and the "immediate" modifier, each of these hint modes is available by default as `;<option character>`, so e.g. `;y` to yank a link's target; `;g<option character>` starts rapid hint mode for all modes where it makes sense, and some others.
*
* To open a hint in the background, the default bind is `F`.
*
* Ex-commands available exclusively in hint mode are listed [here](/static/docs/modules/_src_content_hinting_.html)
*
* Related settings:
* #### Related settings:
*
* - "hintchars": "hjklasdfgyuiopqwertnmzxcvb"
* - "hintfiltermode": "simple" | "vimperator" | "vimperator-reflow"
@ -5612,7 +5627,7 @@ const KILL_STACK: Element[] = []
* boilerplate each time you visit it, even if the number of
* links in the main body changes).
*
* There are some extra hint "modes" that are actually just normal-mode binds. We'll list them here:
* #### There are some extra hint "modes" that are actually just normal-mode binds. We'll list them here:
*
* - `;gv` - "open link in MPV" - only available if you have [[native]] installed and `mpv` on your PATH
* - `;m` and `;M` - do a reverse image search using Google in the current tab and a new tab
@ -5620,6 +5635,8 @@ const KILL_STACK: Element[] = []
* - `;d` and `;gd` - open links in discarded background tabs (defer loading until tab is switched to)
*
* NB: by default, hinting respects whether links say they should be opened in new tabs (i.e. `target=_blank`). If you wish to override this you can use `:hint -JW open` to force the hints to open in the current tab. JavaScript hints (grey ones) will always open wherever they want, but if you want to include these anyway you can use `:hint -W open`.
*
* @param args Arguments to the `:hint` command.
*/
//#content
export async function hint(...args: string[]): Promise<any> {

11
tsdoc.json Normal file
View file

@ -0,0 +1,11 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json",
"extends": ["typedoc/tsdoc.json"],
"noStandardTags": false,
"tagDefinitions": [
{
"tagName": "@flag",
"syntaxKind": "block"
}
]
}