summaryrefslogtreecommitdiff
path: root/cmd/krino/review.go
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-09-14 13:26:51 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-09-14 13:26:51 +0200
commit07c24054cab965800983ef40f53a05c2db131ede (patch)
tree741db561d614b35f8f94fee04fb5ce663a629a0b /cmd/krino/review.go
parent70dccf8d573028aaed64185acb8e134e5339afa3 (diff)
downloadkrino-07c24054cab965800983ef40f53a05c2db131ede.tar.gz
krino-07c24054cab965800983ef40f53a05c2db131ede.zip
krino: 0.0.3 — the plan as one block per file, wrapped, and -Pv0.0.3
Each file shows its steps, then the rule and the reason it matched, one field per line; on a terminal every line wraps to its width with continuation lines under their own column, and piped output is never wrapped. Choosing per file shows the same block. -P / --no-pager prints the plan without the pager. A duplicate's original is shown with ~.
Diffstat (limited to 'cmd/krino/review.go')
-rw-r--r--cmd/krino/review.go39
1 files changed, 23 insertions, 16 deletions
diff --git a/cmd/krino/review.go b/cmd/krino/review.go
index a6c1b5a..66e17b9 100644
--- a/cmd/krino/review.go
+++ b/cmd/krino/review.go
@@ -58,7 +58,10 @@ func (k keyReader) Read(p []byte) (int, error) {
// reviewPerFile's destination rendering (review finding 1, fix round
// 2026-09-12); nothing here uses it directly.
func reviewChains(in io.Reader, out io.Writer, chains []plan.Chain, root string, p palette) (map[string]bool, rune, error) {
- fmt.Fprint(out, "\n"+p.keys("[a] apply all [c] choose per file [s] skip this directory [q] quit")+"\n")
+ fmt.Fprintln(out)
+ for _, l := range wrapped("", "[a] apply all [c] choose per file [s] skip this directory [q] quit", 0, widthPolicy(out), p.keys) {
+ fmt.Fprintln(out, l)
+ }
for {
key, err := readKey(in)
if err != nil {
@@ -87,18 +90,16 @@ func reviewChains(in io.Reader, out io.Writer, chains []plan.Chain, root string,
}
// reviewPerFile is spec §8.3: one prompt per file, in the order chains
-// already carries them (the same order the numbered table above it was
-// shown in, per D15 in render.go). [y]/[n] decide just that file; [a]
-// approves it and every remaining file without asking again; [d] stops
-// asking and applies whatever was already chosen, declining the rest; [q]
-// aborts the review entirely, discarding even files already marked yes -
-// reported back to reviewChains via quit=true. root is passed to
-// actionCell exactly as the directory-level table (render.go's planRows)
-// already does, so a destination inside root renders root-relative and one
-// outside it renders ~-abbreviated - review finding 1 (fix round
-// 2026-09-12): passing "" here always fails filepath.Rel("", dir) and
-// silently fell back to the abbreviated form even for a destination inside
-// root, which is not what spec §8.3's own worked example shows.
+// already carries them (the same order the plan above it numbered them).
+// Each file shows the same block body the plan shows (stepLines): every
+// step, its rule and its reason, wrapped to the terminal. [y]/[n] decide
+// just that file; [a] approves it and every remaining file without asking
+// again; [d] stops asking and applies whatever was already chosen,
+// declining the rest; [q] aborts the review entirely, discarding even files
+// already marked yes - reported back to reviewChains via quit=true. root is
+// passed down so a destination inside root renders root-relative and one
+// outside it renders ~-abbreviated, exactly as in the plan (review finding
+// 1, fix round 2026-09-12).
func reviewPerFile(in io.Reader, out io.Writer, chains []plan.Chain, root string, p palette) (approved map[string]bool, quit bool, err error) {
approved = map[string]bool{}
yesRest := false
@@ -109,10 +110,12 @@ func reviewPerFile(in io.Reader, out io.Writer, chains []plan.Chain, root string
}
fmt.Fprintf(out, "\n[%d/%d] %s\n", i+1, len(chains), c.File.Rel)
- for _, s := range c.Steps {
- fmt.Fprintf(out, " %s\n", styleAction(p, s, actionCell(s, root)))
+ for _, l := range stepLines(c, 7, root, p, widthPolicy(out)) {
+ fmt.Fprintln(out, l)
+ }
+ for _, l := range wrapped(" ", perFileKeys, 2, widthPolicy(out), p.keys) {
+ fmt.Fprintln(out, l)
}
- fmt.Fprint(out, " "+p.keys("[y] yes [n] no [a] yes to this and all remaining [d] done, apply chosen so far [q] quit, apply nothing")+"\n")
for {
key, kerr := readKey(in)
@@ -141,6 +144,10 @@ func reviewPerFile(in io.Reader, out io.Writer, chains []plan.Chain, root string
return approved, false, nil
}
+// perFileKeys is the per-file prompt of spec §8.3, shared by review and
+// undo, and wrapped to the terminal like every other long line.
+const perFileKeys = "[y] yes [n] no [a] yes to this and all remaining [d] done, apply chosen so far [q] quit, apply nothing"
+
// readKey reads the single byte reviewChains treats as one keypress. Over
// the real terminal that byte already came from tui.ReadKey (via
// keyReader); in a test, it is just the next byte of a strings.Reader.