summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-25 09:59:05 +0300
committerPaul Buetow <paul@buetow.org>2026-05-25 09:59:57 +0300
commitf541136ae6cb3a3efa1bed3acafa3fee19b3a37e (patch)
treea392e9983fbfd6e9707b96227a97932248750fb1
parent54049982228d8e8f25c44296835c4310e8adfd23 (diff)
refactor(repl): register 'categories' as HelpTopic with custom Render
Add a Render func() string field to HelpTopic that overrides the default formatTopic rendering. Use it to register 'categories' as a normal HelpTopic entry instead of a hardcoded if-branch in GetHelp. - Remove hardcoded if topic == "categories" from GetHelp - Remove hardcoded 'categories' from GetCompletionTopics - Remove dead getCategoriesHelp function from help.go - 'categories' now discovered through normal helpByTopic lookup
-rw-r--r--internal/repl/help.go32
-rw-r--r--internal/repl/help_topics.go36
2 files changed, 40 insertions, 28 deletions
diff --git a/internal/repl/help.go b/internal/repl/help.go
index 02688e1..4c0691b 100644
--- a/internal/repl/help.go
+++ b/internal/repl/help.go
@@ -11,14 +11,10 @@ import (
// GetHelp returns the formatted help text for a topic.
// If topic is empty, it returns the general help overview.
-// If topic is "categories", it lists all categories.
func GetHelp(topic string) string {
if topic == "" {
return getGeneralHelp()
}
- if topic == "categories" {
- return getCategoriesHelp()
- }
// Look up by operator name or alias
topic = strings.ToLower(topic)
@@ -29,6 +25,9 @@ func GetHelp(topic string) string {
if !ok {
return fmt.Sprintf("No help for %q.\n\nType 'help' for an overview, or 'help categories' to list all topics.", topic)
}
+ if t.Render != nil {
+ return t.Render()
+ }
return formatTopic(t)
}
@@ -43,14 +42,11 @@ func GetAllTopics() []string {
}
// GetCompletionTopics returns all help topics suitable for tab completion.
-// Includes operator names, aliases, and special topics like "categories".
+// Includes operator names and aliases from all registered HelpTopic entries.
func GetCompletionTopics() []string {
seen := make(map[string]bool)
var topics []string
- // Add "categories" as a special topic
- topics = append(topics, "categories")
-
// Add all operator names (skip "help" itself — no need to complete help help)
for op, t := range helpByTopic {
if op == "help" {
@@ -131,26 +127,6 @@ func getGeneralHelp() string {
return sb.String()
}
-// getCategoriesHelp lists all categories and their topics.
-func getCategoriesHelp() string {
- var sb strings.Builder
- sb.WriteString("Available help topics by category:\n\n")
- for _, cat := range categoryOrder {
- sb.WriteString(fmt.Sprintf(" %s:\n", cat))
- for _, op := range helpByCat[cat] {
- t := helpByTopic[op]
- aliasStr := ""
- if len(t.Aliases) > 0 {
- aliasStr = " (" + strings.Join(t.Aliases, ", ") + ")"
- }
- sb.WriteString(fmt.Sprintf(" %-16s %s%s\n", op, t.Description, aliasStr))
- }
- sb.WriteString("\n")
- }
- sb.WriteString("Use 'help <topic>' for details on any topic.\n")
- return sb.String()
-}
-
// formatTopic returns the detailed help for a single HelpTopic.
func formatTopic(t *HelpTopic) string {
var sb strings.Builder
diff --git a/internal/repl/help_topics.go b/internal/repl/help_topics.go
index 102f2c1..34bb708 100644
--- a/internal/repl/help_topics.go
+++ b/internal/repl/help_topics.go
@@ -3,6 +3,11 @@
package repl
+import (
+ "fmt"
+ "strings"
+)
+
type HelpTopic struct {
Category string // e.g. "Arithmetic", "Stack", "Comparison", "Variables", "Hyper", "REPL"
Operator string // the operator or command name (e.g. "+", "help", "rat")
@@ -10,6 +15,9 @@ type HelpTopic struct {
Description string
Usage string // short usage hint
Examples []string
+ // Render, when non-nil, overrides the default formatTopic rendering.
+ // Used for special topics like "categories" that need custom output.
+ Render func() string
}
// helpTopics is the single source of truth for all inline help entries.
@@ -456,6 +464,34 @@ var helpTopics = []HelpTopic{
"1 2.71828 [ln] ln(1) + ln(2.71828) = 0 + 1 = 1",
},
},
+
+ // ── Special topics (custom render) ──
+
+ {
+ Category: "REPL",
+ Operator: "categories",
+ Description: "List all available help topics by category",
+ Usage: "help categories",
+ Examples: []string{"help categories List all topics grouped by category"},
+ Render: func() string {
+ var sb strings.Builder
+ sb.WriteString("Available help topics by category:\n\n")
+ for _, cat := range categoryOrder {
+ sb.WriteString(fmt.Sprintf(" %s:\n", cat))
+ for _, op := range helpByCat[cat] {
+ t := helpByTopic[op]
+ aliasStr := ""
+ if len(t.Aliases) > 0 {
+ aliasStr = " (" + strings.Join(t.Aliases, ", ") + ")"
+ }
+ sb.WriteString(fmt.Sprintf(" %-16s %s%s\n", op, t.Description, aliasStr))
+ }
+ sb.WriteString("\n")
+ }
+ sb.WriteString("Use 'help <topic>' for details on any topic.\n")
+ return sb.String()
+ },
+ },
}
// buildHelpIndex builds lookup maps from helpTopics at package init.