// The dmenu module's tool (novox/hq research 026/04, 026/05): show the operator a menu of choices in // the graphical session and answer the one chosen — the dmenu-compatible command as a tool. A Go // bundle the node's runtime launches over stdio (ADR 0188, ADR 0193). It runs as the operator account // and reaches the account's X session as session.go finds it; with no session, it says so. package main import ( "fmt" "os" stdio "git.novox.be/novox/mesh-sdk/go" ) var providedBy = map[string]string{ "dmenu": "the dmenu package, which this module installs", } func main() { if err := stdio.Serve("", tools()); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } } func tools() []stdio.Tool { return []stdio.Tool{ { Name: "dmenu_menu", Description: "Show the operator a menu of choices on their screen and answer the line chosen, its index, or " + "that the menu was dismissed or not answered in time (default 20 s, at most 25). The operator may also " + "type a line that is not a choice. Needs the operator's graphical session. (d)", Input: map[string]any{ "choices": map[string]any{"type": "array", "items": map[string]any{"type": "string"}, "description": "the lines to choose from, at most 1000, none with a line break"}, "prompt": map[string]any{"type": "string", "description": "a prompt shown left of the input"}, "lines": map[string]any{"type": "integer", "description": "show the choices as a vertical list of this many lines (default 0: one horizontal line; at most 40)"}, "case_insensitive": map[string]any{"type": "boolean", "description": "match what is typed regardless of case (default true)"}, "timeout_seconds": map[string]any{"type": "integer", "description": "close the menu unanswered after this long (default 20, at most 25)"}, }, Run: func(args map[string]any) (any, error) { choices, err := optList(args, "choices") if err != nil { return nil, err } prompt, err := optText(args, "prompt", "") if err != nil { return nil, err } n, err := optWhole(args, "lines", 0, 0, 40) if err != nil { return nil, err } ci, err := optFlag(args, "case_insensitive", true) if err != nil { return nil, err } timeout, err := optWhole(args, "timeout_seconds", 20, 1, MostWait) if err != nil { return nil, err } return Menu(Ask{Choices: choices, Prompt: prompt, Lines: n, CaseInsensitive: ci, Timeout: timeout}) }, }, { Name: "dmenu_session", Description: "Which X session the menu would appear in and how it was found, or why there is none; and dmenu's version. (r)", Input: map[string]any{}, Run: func(map[string]any) (any, error) { return SessionCheck() }, }, } }