package cmd import ( "fmt" "strings" "github.com/zemenawi/zutils/pkg/colors" ) type CommandHelp struct { Name string Help string Examples []string } var readHelp = CommandHelp{ Name: "read", Help: "Read and display file with smart detection.\n" + "Automatically detects file type:\n" + " - Markdown (.md) - Renders with colored headings, lists, code blocks\n" + " - Code files - Syntax highlighting with line numbers\n" + " - Other files - Plain text display", Examples: []string{ "z read README.md # Read markdown file", "z read main.go # Read code with syntax highlighting", "z read package.json # Read JSON file", }, } var sysHelp = CommandHelp{ Name: "sys", Help: "Show system overview including CPU, memory, disk usage, and top processes.\n" + "Useful for quick system diagnostics.", Examples: []string{ "z sys # Show full system overview", }, } var findHelp = CommandHelp{ Name: "find", Help: "Find files matching criteria.\n" + "Supports glob patterns, size filters, modification time, and depth limits.", Examples: []string{ "z find . -name '*.go' # Find all Go files", "z find . -mtime 7 # Files modified in last 7 days", "z find . -size +1m # Files larger than 1MB", "z find . -type d # Directories only", }, } var searchHelp = CommandHelp{ Name: "search", Help: "Search for a pattern in files.\n" + "A user-friendly alternative to grep with colored output.", Examples: []string{ "z search func cmd/ # Search for 'func' in cmd directory", "z search -i 'error' . # Case-insensitive search", "z search -w 'import' *.go # Whole word match", "z search -C 2 'TODO' . # Show 2 lines of context", }, } var usageHelp = CommandHelp{ Name: "usage", Help: "Show resource usage (CPU, memory) for processes matching a name.\n" + "Useful for monitoring specific applications or services.", Examples: []string{ "z usage cron # Show cron process usage", "z usage mongod # Show MongoDB usage", "z usage chrome # Show all Chrome processes", "z usage postgres # Show PostgreSQL usage", }, } var junksHelp = CommandHelp{ Name: "junks", Help: "Find and clean junk files (caches, temporary files).\n" + "Shows storage taken by build outputs, caches, and temporary files.\n" + "Safe to clean: build outputs, caches, temporary files.\n" + "Not cleanable: runtime version files (require manual cleanup).", Examples: []string{ "z junks # List junk files and space usage", "z junks clean # Preview what will be cleaned", "z junks clean --force # Actually clean junk files", }, } var portsHelp = CommandHelp{ Name: "ports", Help: "Show all listening ports and the processes using them.\n" + "Useful for debugging network services and finding port conflicts.", Examples: []string{ "z ports # Show listening ports", "z ports -a # Show all ports (including established)", "z ports 8080 # Filter by specific port", }, } var usagesHelp = CommandHelp{ Name: "usages", Help: "Show all running processes sorted by resource usage.\n" + "By default sorts by CPU usage. Use -m to sort by memory.", Examples: []string{ "z usages # Top processes by CPU", "z usages -m # Top processes by memory", "z usages -n=50 # Show top 50 processes", "z usages chrome # Filter processes by name", }, } var networkHelp = CommandHelp{ Name: "network", Help: "Show network information including:\n" + " - Local IP addresses\n" + " - Public IP\n" + " - DNS servers\n" + " - Active network connections", Examples: []string{ "z network # Show network overview", }, } func PrintErrorAndHelp(name string, err error) { help := getHelpForCommand(name) fmt.Printf("\n %s✖ Error: %s%s\n\n", colors.Red, err, colors.Reset) if help != nil { fmt.Printf(" %sUsage:%s z %s %s\n\n", colors.Bold, colors.Reset, help.Name, getUsageHint(help.Name)) if help.Help != "" { fmt.Printf(" %sDescription:%s\n", colors.Bold, colors.Reset) lines := splitIntoLines(help.Help, 60) for _, line := range lines { fmt.Printf(" %s%s%s\n", colors.Reset, line, colors.Reset) } fmt.Printf("\n") } if len(help.Examples) > 0 { fmt.Printf(" %sExamples:%s\n", colors.Bold, colors.Reset) for _, ex := range help.Examples { fmt.Printf(" %s%s%s\n", colors.Green, ex, colors.Reset) } fmt.Printf("\n") } } } func getHelpForCommand(name string) *CommandHelp { switch name { case "read": return &readHelp case "sys": return &sysHelp case "find": return &findHelp case "search": return &searchHelp case "usage": return &usageHelp case "junks": return &junksHelp case "ports": return &portsHelp case "usages": return &usagesHelp case "network": return &networkHelp } return nil } func getUsageHint(name string) string { switch name { case "read": return "" case "sys": return "" case "find": return "[path] [options]" case "search": return " [path]" case "usage": return "" case "junks": return "[clean]" case "ports": return "[-a] [port]" case "usages": return "[-m] [-n=N]" case "network": return "" case "info": return "" } return "" } func splitIntoLines(text string, maxLen int) []string { var lines []string paragraphs := splitIntoParagraphs(text) for _, para := range paragraphs { if para == "" { lines = append(lines, "") continue } words := strings.Fields(para) currentLine := "" for _, word := range words { if currentLine == "" { currentLine = word } else if len(currentLine)+len(word)+1 <= maxLen { currentLine += " " + word } else { lines = append(lines, currentLine) currentLine = word } } if currentLine != "" { lines = append(lines, currentLine) } } return lines } func splitIntoParagraphs(text string) []string { var paragraphs []string lines := strings.Split(text, "\n") current := "" for _, line := range lines { trimmed := strings.TrimSpace(line) if trimmed == "" { if current != "" { paragraphs = append(paragraphs, current) current = "" } } else { if current != "" { current += " " } current += trimmed } } if current != "" { paragraphs = append(paragraphs, current) } return paragraphs }