Files
rikuri/cli_display.go
2026-04-20 21:38:22 +02:00

122 lines
2.7 KiB
Go

package cli
import (
"bufio"
"fmt"
"os"
"runtime"
"strings"
"sync"
)
type Printer struct {
mutex sync.Mutex
Program string
Debugging bool
Color bool
}
func (printer *Printer) Debug(v ...any) {
if printer.Debugging {
printer.mutex.Lock()
fmt.Fprint(os.Stdout, "dbg ")
_, file, line, ok := runtime.Caller(2)
if ok {
lastSegment := strings.LastIndex(file, "/") + 1
fmt.Fprint(os.Stdout, "@ ", file[lastSegment:], ":", line, " ")
}
fmt.Fprintln(os.Stdout, v...)
printer.mutex.Unlock()
}
}
func fprintIndented(f *os.File, maxWidth int, indent int, value any) {
wrapped := wrap.Indents(indent, wrap.Wrap(fmt.Sprint(value), maxWidth-indent))
for _, line := range wrapped {
fmt.Fprintln(f, line)
}
}
func (printer *Printer) printErrorMessage(msg string, details ...error) {
termInfo := GetStderrInfo()
if termInfo.SupportsColor && printer.Color {
errorStyle(os.Stderr)
}
fmt.Fprintln(os.Stderr, "Error:", msg)
for _, detail := range details {
fprintIndented(os.Stderr, termInfo.Width, 3, detail)
}
if termInfo.SupportsColor && printer.Color {
resetStyle(os.Stderr)
}
}
func (printer *Printer) Error(msg string, details ...error) {
printer.mutex.Lock()
printer.printErrorMessage(msg, details...)
printer.mutex.Unlock()
}
func (printer *Printer) Fatal(msg string, reason ExitReason, details ...error) {
printer.mutex.Lock()
printer.printErrorMessage(msg, details...)
if reason == BadUsage {
fmt.Fprintf(os.Stdout, "run '%s --help' for usage\n", printer.Program)
}
os.Exit(int(reason))
}
var defaultPrinter Printer
func DefaultPrinter() *Printer {
return &defaultPrinter
}
func Debug(v ...any) {
defaultPrinter.Debug(v...)
}
func Error(msg string, details ...error) {
defaultPrinter.Error(msg, details...)
}
func Fatal(msg string, reason ExitReason, details ...error) {
defaultPrinter.Fatal(msg, reason, details...)
}
func InvalidArgs(errs ...error) {
Fatal("invalid command-line arguments", BadUsage, errs...)
}
func Show(msg string) {
termInfo := GetStdoutInfo()
wrapped := wrap.Wrap(msg, termInfo.Width)
for _, line := range wrapped {
fmt.Println(line)
}
}
func ShowUsage(explanation string, examples ...string) {
fmt.Print(explanation, "\n\nUsage:\n")
for _, line := range wrap.Indents(3, examples) {
fmt.Println(line)
}
}
func DescribeOption(name string, description string) {
name = " " + name + " "
termInfo := GetStdoutInfo()
wrapped := wrap.Indentfs(name, len(name), wrap.Wrap(description, termInfo.Width-len(name)))
for _, line := range wrapped {
fmt.Println(line)
}
}
func AskString(prompt string) string {
fmt.Print(prompt)
reader := bufio.NewReader(os.Stdin)
text, _ := reader.ReadString('\n')
return text
}