| 34 | } |
| 35 | |
| 36 | func helpExample(cmd string, args ...string) string { |
| 37 | var sb strings.Builder |
| 38 | sb.WriteString(" ") |
| 39 | sb.WriteString(ansi.WithANSI(cmd, ansi.HighlightGreen)) |
| 40 | for _, arg := range args { |
| 41 | var out strings.Builder |
| 42 | pos := 0 |
| 43 | for { |
| 44 | start := strings.IndexByte(arg[pos:], '$') |
| 45 | if start == -1 { |
| 46 | if pos < len(arg) { |
| 47 | // If no variable at all (pos == 0), cyan highlight for whole-arg |
| 48 | // Otherwise, for mixed strings containing variables, leave non-variable text unhighlighted |
| 49 | if pos == 0 { |
| 50 | out.WriteString(ansi.WithANSI(arg[pos:], ansi.HighlightCyan)) |
| 51 | } else { |
| 52 | out.WriteString(arg[pos:]) |
| 53 | } |
| 54 | } |
| 55 | break |
| 56 | } |
| 57 | start += pos |
| 58 | if start > pos { |
| 59 | // Non-variable text should not be highlighted |
| 60 | out.WriteString(arg[pos:start]) |
| 61 | } |
| 62 | // Parse variable name and optional function call |
| 63 | end := start + 1 |
| 64 | for end < len(arg) && (arg[end] == '_' || (arg[end] >= 'a' && arg[end] <= 'z') || (arg[end] >= 'A' && arg[end] <= 'Z') || (arg[end] >= '0' && arg[end] <= '9')) { |
| 65 | end++ |
| 66 | } |
| 67 | // Check for function call |
| 68 | if end < len(arg) && arg[end] == '(' { |
| 69 | parenCount := 1 |
| 70 | end++ |
| 71 | for end < len(arg) && parenCount > 0 { |
| 72 | switch arg[end] { |
| 73 | case '(': |
| 74 | parenCount++ |
| 75 | case ')': |
| 76 | parenCount-- |
| 77 | } |
| 78 | end++ |
| 79 | } |
| 80 | } |
| 81 | varExpr := arg[start:end] |
| 82 | out.WriteString(helpVar(varExpr)) |
| 83 | pos = end |
| 84 | } |
| 85 | fmt.Fprintf(&sb, ` "%s"`, out.String()) |
| 86 | } |
| 87 | return sb.String() |
| 88 | } |
| 89 | |
| 90 | func helpListItem(key string, value string) string { |
| 91 | var sb strings.Builder |