From adc3410395771609d2db5ee5ae2b9da71115c5ca Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Mon, 14 Sep 2026 11:05:13 +0200 Subject: krino: coloured output, and --no-color One palette type styles the plan table, warnings, headers, outcome counts, prompt keys, undo's refused steps and krino log's (undone), from the 16-colour ANSI palette plus bold and faint only. Widths are measured on the plain text, so columns line up; with colour off the output is unchanged. --no-color works before or after any subcommand, as NO_COLOR does. The two search-and-replace colourings are gone. --- cmd/krino/sort.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'cmd/krino/sort.go') diff --git a/cmd/krino/sort.go b/cmd/krino/sort.go index 68f9eda..dd056e0 100644 --- a/cmd/krino/sort.go +++ b/cmd/krino/sort.go @@ -63,6 +63,7 @@ func cmdSort(g *globals, names []string, stdout, stderr io.Writer) int { printDiags(stderr, errs) return 2 } + p := palette{on: colourOn(g, stdout)} // Spec §8.4: with neither -y nor -n, krino asks; asking a non-terminal // stdin would just hang (or read garbage), so it refuses instead. @@ -162,7 +163,7 @@ func cmdSort(g *globals, names []string, stdout, stderr io.Writer) int { fmt.Fprintln(stdout) } printed = true - fmt.Fprintf(stdout, "krino: %s %s\n", d.Name, xdg.Abbrev(d.Root)) + fmt.Fprintln(stdout, p.bold(fmt.Sprintf("krino: %s %s", d.Name, xdg.Abbrev(d.Root)))) } // C3: directory-level warnings go to stderr after the header // line above, not before it, so on a terminal they read as @@ -186,9 +187,8 @@ func cmdSort(g *globals, names []string, stdout, stderr io.Writer) int { // exists for. printPlan is reused as-is (render.go), never // re-rendered here. var buf bytes.Buffer - printPlan(&buf, dp, g.verbose) - text := colourDeletePermanently(buf.String(), tui.Colour(stdout)) - if err := tui.Page(stdout, text); err != nil { + printPlan(&buf, dp, g.verbose, p) + if err := tui.Page(stdout, buf.String()); err != nil { fmt.Fprintf(stderr, "krino: %s: %v\n", d.Name, err) exit = 1 return false @@ -212,7 +212,7 @@ func cmdSort(g *globals, names []string, stdout, stderr io.Writer) int { approved, action = approveAll(actionable), 'a' } else { var rerr error - approved, action, rerr = reviewDir(stdout, actionable, d.Root) + approved, action, rerr = reviewDir(stdout, actionable, d.Root, p) if rerr != nil { fmt.Fprintf(stderr, "krino: %s: %v\n", d.Name, rerr) exit = 1 @@ -252,7 +252,7 @@ func cmdSort(g *globals, names []string, stdout, stderr io.Writer) int { exit = 1 return false } - fmt.Fprintf(stdout, "%d applied · %d failed · %d declined\n", res.Applied, res.Failed, res.Declined) + fmt.Fprintln(stdout, outcome(p, res.Applied, res.Failed, res.Declined)) // Ruling 1: only an actual step failure makes the run exit 1 // here - a directory the user declined or skipped must not. if res.Failed > 0 { @@ -432,15 +432,15 @@ func warnedCount(lines []warnLine) int { } // printWarnings lists one line per warning, Rel padded to the widest shown -// (capped at 40). -func printWarnings(w io.Writer, lines []warnLine) { +// (capped at 40), each line styled with p's warning colour. +func printWarnings(w io.Writer, lines []warnLine, p palette) { rels := make([]string, len(lines)) for i, l := range lines { rels[i] = l.rel } width := relWidth(rels) for _, l := range lines { - fmt.Fprintf(w, " %s %s\n", padCell(l.rel, width), l.text) + fmt.Fprintf(w, " %s\n", p.warn(padCell(l.rel, width)+" "+l.text)) } } -- cgit v1.3