Skip to main content

max / makeover-tui

0.16.1: rustfmt the two modules that arrived in 0.16.0 Bento's preflight runs cargo fmt --all --check and 0.16.0 failed it, so 0.16.0 was tagged and pushed but never reached crates.io. Line wrapping only, in text.rs and widget.rs, no logic touched. A patch rather than a moved tag: v0.16.0 was already on astra, mnw and srht when the gate failed, and repointing a published tag to different content is worse than spending a patch number. 0.16.0 stays as the tag that did not ship. Consumers pin ^0.16.0 and resolve this without moving.
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-08-12 19:19 UTC
Signed with PGP, not checked
Commit: 63ff635bbf0df76301e4ad4fa0f92e5be7cffa43
Parent: 320c747
3 files changed, +77 insertions, -17 deletions
M Cargo.toml +1 -1
@@ -1,6 +1,6 @@
1 1 [package]
2 2 name = "makeover-tui"
3 - version = "0.16.0"
3 + version = "0.16.1"
4 4 edition = "2024"
5 5 description = "The terminal renderer for makeover-layout, on ratatui. Colour stops being the constraint above 256 entries; geometry never does, because an edge occupies a whole cell on every side."
6 6 license = "MIT"
M src/text.rs +10 -2
@@ -241,7 +241,10 @@
241 241 // The case with no good answer. Cutting is the least bad one: the
242 242 // alternative is a line wider than the region and a buffer that
243 243 // swallows the overflow silently.
244 - assert_eq!(wrap("supercalifragilistic", 6), ["superc", "alifra", "gilist", "ic"]);
244 + assert_eq!(
245 + wrap("supercalifragilistic", 6),
246 + ["superc", "alifra", "gilist", "ic"]
247 + );
245 248 }
246 249
247 250 #[test]
@@ -265,7 +268,12 @@
265 268 fn a_drawing_stops_at_the_bottom_of_the_area_it_was_given() {
266 269 // Never below the rect, which is what a terminal does with everything.
267 270 let mut buf = Buffer::empty(Rect::new(0, 0, 10, 2));
268 - let used = draw("the quick brown fox jumps over", Style::new(), buf.area, &mut buf);
271 + let used = draw(
272 + "the quick brown fox jumps over",
273 + Style::new(),
274 + buf.area,
275 + &mut buf,
276 + );
269 277 assert_eq!(used, 2);
270 278 }
271 279 }
M src/widget.rs +66 -14
@@ -159,9 +159,7 @@
159 159 .add_modifier(Modifier::BOLD),
160 160 subsection: Style::new().fg(theme.content_secondary),
161 161 action: Style::new().fg(theme.action_primary),
162 - filled: Style::new()
163 - .fg(theme.selection_on)
164 - .bg(theme.action_primary),
162 + filled: Style::new().fg(theme.selection_on).bg(theme.action_primary),
165 163 sunken: Style::new().bg(theme.surface_sunken),
166 164 focus: Modifier::REVERSED,
167 165 meter_cells: 10,
@@ -267,7 +265,10 @@
267 265 let bar = format!(
268 266 "{}{}",
269 267 style.meter_full.to_string().repeat(filled as usize),
270 - style.meter_empty.to_string().repeat((cells - filled) as usize)
268 + style
269 + .meter_empty
270 + .to_string()
271 + .repeat((cells - filled) as usize)
271 272 );
272 273 let reading = match meter.label {
273 274 Some(label) => format!(" {}/{} {label}", meter.done, meter.total),
@@ -456,7 +457,9 @@
456 457 // A file field has no way back on a terminal any more than it has on an
457 458 // HTTP host. The name is drawn and picking one belongs to whoever owns
458 459 // the interaction.
459 - _ if held.text().is_empty() => empty_well(style, placeholder, well, focused, below(area, used), buf),
460 + _ if held.text().is_empty() => {
461 + empty_well(style, placeholder, well, focused, below(area, used), buf)
462 + }
460 463 _ => text::draw(held.text(), well, below(area, used), buf),
461 464 };
462 465
@@ -552,7 +555,10 @@
552 555 (0..buf.area.height)
553 556 .map(|y| {
554 557 (0..buf.area.width)
555 - .map(|x| buf.cell((x, y)).map_or(' ', |c| c.symbol().chars().next().unwrap_or(' ')))
558 + .map(|x| {
559 + buf.cell((x, y))
560 + .map_or(' ', |c| c.symbol().chars().next().unwrap_or(' '))
561 + })
556 562 .collect::<String>()
557 563 .trim_end()
558 564 .to_owned()
@@ -638,12 +644,22 @@
638 644 let style = style();
639 645 let disabled = Act::new("Save").state(State::Disabled);
640 646 let line = act(&style, &disabled, true);
641 - assert!(!line.spans[0].style.add_modifier.contains(Modifier::REVERSED));
647 + assert!(
648 + !line.spans[0]
649 + .style
650 + .add_modifier
651 + .contains(Modifier::REVERSED)
652 + );
642 653 assert_eq!(line.spans[0].style, style.muted);
643 654 // Focus is a state and does not suppress anything.
644 655 let focused_state = Act::new("Save").state(State::Focus);
645 656 let line = act(&style, &focused_state, true);
646 - assert!(line.spans[0].style.add_modifier.contains(Modifier::REVERSED));
657 + assert!(
658 + line.spans[0]
659 + .style
660 + .add_modifier
661 + .contains(Modifier::REVERSED)
662 + );
647 663 }
648 664
649 665 #[test]
@@ -652,7 +668,10 @@
652 668 // is the button that destroys something survives being landed on.
653 669 let style = style();
654 670 let line = act(&style, &Act::new("Delete").tone(Tone::Danger), true);
655 - assert_eq!(line.spans[0].style.add_modifier, style.danger.add_modifier | Modifier::REVERSED);
671 + assert_eq!(
672 + line.spans[0].style.add_modifier,
673 + style.danger.add_modifier | Modifier::REVERSED
674 + );
656 675 }
657 676
658 677 #[test]
@@ -671,7 +690,9 @@
671 690 // The delta is the toned part and the value is an ordinary fact, so the
672 691 // two share a row rather than the caption growing a second sentence.
673 692 let style = style();
674 - let figure_ = Figure::new("42", "open tasks").change("+3").tone(Tone::Success);
693 + let figure_ = Figure::new("42", "open tasks")
694 + .change("+3")
695 + .tone(Tone::Success);
675 696 let mut buf = buffer(20, 4);
676 697 figure(&style, &figure_, buf.area, &mut buf);
677 698 assert_eq!(rows(&buf)[0], "42 +3");
@@ -693,7 +714,17 @@
693 714 let style = style();
694 715 let field_ = Field::new(FieldKind::Hidden, "csrf", "Token");
695 716 let mut buf = buffer(20, 4);
696 - assert_eq!(field(&style, &field_, Held::Text("abc"), false, buf.area, &mut buf), 0);
717 + assert_eq!(
718 + field(
719 + &style,
720 + &field_,
721 + Held::Text("abc"),
722 + false,
723 + buf.area,
724 + &mut buf
725 + ),
726 + 0
727 + );
697 728 assert_eq!(field_height(&style, &field_, 20), 0);
698 729 assert_eq!(rows(&buf)[0], "");
699 730 }
@@ -705,7 +736,14 @@
705 736 let style = style();
706 737 let field_ = Field::new(FieldKind::Secret, "password", "Password");
707 738 let mut buf = buffer(20, 4);
708 - field(&style, &field_, Held::Text("hunter2"), false, buf.area, &mut buf);
739 + field(
740 + &style,
741 + &field_,
742 + Held::Text("hunter2"),
743 + false,
744 + buf.area,
745 + &mut buf,
746 + );
709 747 assert_eq!(rows(&buf)[1], "*******");
710 748 }
711 749
@@ -718,7 +756,14 @@
718 756 field_.hint = Some("work address");
719 757 field_.error = Some("not an address");
720 758 let mut buf = buffer(20, 5);
721 - field(&style, &field_, Held::Text("nope"), false, buf.area, &mut buf);
759 + field(
760 + &style,
761 + &field_,
762 + Held::Text("nope"),
763 + false,
764 + buf.area,
765 + &mut buf,
766 + );
722 767 assert_eq!(rows(&buf)[2], "not an address");
723 768 assert_eq!(field_height(&style, &field_, 20), 3);
724 769 }
@@ -742,7 +787,14 @@
742 787 let options = [Choice::plain("small"), Choice::plain("large")];
743 788 field_.options = &options;
744 789 let mut buf = buffer(20, 5);
745 - field(&style, &field_, Held::Text("large"), false, buf.area, &mut buf);
790 + field(
791 + &style,
792 + &field_,
793 + Held::Text("large"),
794 + false,
795 + buf.area,
796 + &mut buf,
797 + );
746 798 assert_eq!(rows(&buf)[1], "( ) small");
747 799 assert_eq!(rows(&buf)[2], "(*) large");
748 800 assert_eq!(field_height(&style, &field_, 20), 3);