ratatui-termwiz-v0.1.1

comet-ml/opikratatui-termwiz-v0.1.1Jun 5, 2026by github-actions[bot]

AI Summary

A release of the ratatui Rust library focusing on advanced TUI features including shadow support, improved cell diffing options, and performance improvements for no_std environments.

Key Highlights

  • Support shadows in blocks with custom presets and effects
  • Add `CellDiffOption::AlwaysUpdate` to force cell updates
  • Support layout-cache in no_std environments for embedded systems
  • Add missing `Modifier::HIDDEN` style
  • Add 3D volatility surface visualization example

New Features

  • Shadow support for blocks
  • Cell diff options for hyperlinks and Kitty images
  • Layout cache for no_std
  • Hidden modifier support
  • 3D visualization example

Full Release Notes

> _"Rats, we're rats; we're the rats." – [Rat Movie](https://www.youtube.com/watch?v=OXQwx1EolD8)_

We are excited to announce the new version of `ratatui` - a Rust library that's all about cooking up TUIs 👨‍🍳🐀

✨ **Release highlights**: <https://ratatui.rs/highlights/v0301/>

⚠️ List of breaking changes can be found [here](https://github.com/ratatui/ratatui/blob/main/BREAKING-CHANGES.md).

### Features

- [74d6a84](https://github.com/ratatui/ratatui/commit/74d6a846e1fab811fcdbcc09b09648cdca05c174) *(block)* Support shadows by orhun in [#2481](https://github.com/ratatui/ratatui/pull/2481)

  > Introduce `Block::shadow(...)` with a new `Shadow` type that supports:
  >
  > - presets: `overlay`,` block`, `light_shade`, `medium_shade`,
  > `dark_shade`
  > - custom symbols via `Shadow::symbol(...)`
  > - custom effects via `Shadow::custom(...)`
  >
  > ```rust
  > use ratatui::layout::Offset;
  > use ratatui::style::Stylize;
  > use ratatui::widgets::{Block, Shadow};
  >
  > let popup = Block::bordered().title("Popup").shadow(
  >     Shadow::dark_shade()
  >         .black()
  >         .on_white()
  >         .offset(Offset::new(2, 1)),
  > );
  > ```
  >
  > Results in:
  >
  > ```
  > ┌Popup─────┐
  > │content   │▒
  > └──────────┘▒
  >   ▒▒▒▒▒▒▒▒▒▒▒
  > ```
  >
  > ![shadow](https://github.com/user-attachments/assets/103ddc17-6536-424c-a7a8-8895540dd145)
  >
  > fixes #1892
  >
  > ---------

- [4d30420](https://github.com/ratatui/ratatui/commit/4d304206f45c96813dd9773a268b61d7d33d1f44) *(buffer)* Add `CellDiffOption::AlwaysUpdate` to force cell updates by sxyazi in [#2480](https://github.com/ratatui/ratatui/pull/2480)

  > When this option is used, the cells are updated even when content is identical.
  >
  > Follow-up for https://github.com/ratatui/ratatui/pull/1605
  >
  > Trying to resolve https://github.com/ratatui/ratatui/issues/1116

- [39c32c6](https://github.com/ratatui/ratatui/commit/39c32c6fa981c4b326bf2533100ac86b7be05eba) *(buffer)* Add cell diff options by benjajaja in [#1605](https://github.com/ratatui/ratatui/pull/1605)
  >
  > Problem:Escape sequences always cause a cell to count as "multiwidth",
  > even when it doesn't render wider than one cell, or not as wide as the
  > escape sequence would be computed as.
  >
  > Solution:Convert `skip:bool` to enum. Add enum option `ForceWidth` to
  > force a cell width for diffing.
  >
  > When using the option, this also fixes some bug where diffing is not
  > idempotent and causes a diff operation for `(symbol.len() - 1)` times.
  >
  > There are three new specific test cases:
  >
  > 1. Rendering hyperlinks by squeezing the escape sequence into the first
  >    cell and forcing the width to the unicode width of the text part.
  >    This is much easier to implement for a Link widget, as it would only
  >    need to get the unicode-width once and not iterate over graphemes
  >    like Spans must do.
  > 2. Rendering hyperlinks by squeezing the opening sequence into the first
  >    cell with the first grapheme and forcing the width to that of the
  >    first grapheme. Then rendering each grapheme as usual. Then squeezing
  >    the closing sequence into the last cell with the last grapheme and
  >    forcing the width to that of the last grapheme.
  >    This is harder to implement for a Link widget, as it would have to
  >    iterate over graphemes with their width like Spans do.
  > 3. Kitty image sequence with utf-8 placeholders, similar to 2 but with
  >    known constant grapheme widths.
  >
  > ### Link widget that leverages this
  >
  > https://github.com/benjajaja/tui-link
  >
  > ![](https://github.com/user-attachments/assets/40ac5f9e-9025-4bd9-8e88-b5c5a235b8ec)
  >
  > It would be cooler if we could just add something like `.link(url)` to
  > `Span`s, because it would much simpler to insert some link and leverage
  > all the Line/Text/Paragraph wrapping and whatnot. With a custom widget
  > you need to take care of the `Area` where you'd want to render it, so
  > it's not that clean. But we could iterate on this later, if even
  > possible.

- [6faaddb](https://github.com/ratatui/ratatui/commit/6faaddb47e9707647b97c1cdb8275f14b58397d2) *(core)* Implement from slice for line and text by NoOPeEKS in [#2371](https://github.com/ratatui/ratatui/pull/2371)

  > This PR adds the following implementations of the From trait for Line
  > and Text structs:
  >
  > - Implements From<&[T]> where T is Into\<Span> for Line, allowing using
  > of slices to construct Lines.
  > - Implements From<&[T]> where T is Into\<Line> for Text, allowing using
  > of slices of various types to construct Texts.
  >
  > closes #2279

- [5fc6ab8](https://github.com/ratatui/ratatui/commit/5fc6ab881aba8f0bad30f05730673a15ed64858f) *(core)* Support layout-cache in no_std environments by junkdog in [#2399](https://github.com/ratatui/ratatui/pull/2399)

  > this enables "layout-cache" for no_std builds; it's meant for embedded
  > environments, where the layout engine otherwise consumes all CPU,
  > capping the framerate at around ~10fps. the same app can refresh 300-500
  > times per second with layout cache enabled.
  >
  > i had to add `layout-cache = ["dep:critical-section"]` to all builds -
  > it's pretty tiny and shouldn't leave a trace in std-builds. the
  > alternative is to add an extra layer of features for layout-cache with
  > std and no_std, but it pollutes the feature space.
  >
  > ---------

- [ee4b7a9](https://github.com/ratatui/ratatui/commit/ee4b7a900cf293fc1ed3b406a4edeaa220d0b93f) *(crossterm)* Add the missing hidden modifier by sxyazi in [#2413](https://github.com/ratatui/ratatui/pull/2413)

  > Fixes https://github.com/sxyazi/yazi/issues/3724, see
  > https://github.com/sxyazi/yazi/issues/3724#issuecomment-3970129744 for a
  > reproducer.
  >
  > This PR adds the missing `Modifier::HIDDEN` style and introduces a
  > `queue_modifier_diff` to test `ModifierDiff::queue()`.
  >
  > It also fixes a bug where `CrosstermAttribute::Bold` and
  > `CrosstermAttribute::Dim` would be emitted twice when resetting
  > intensity. For example:
  >
  > ```rust
  > #[case(Modifier::DIM, Modifier::BOLD, &[CrosstermAttribute::NormalIntensity, CrosstermAttribute::Bold])]
  > ```
  >
  > would become:
  >
  > ```rust
  > #[case(Modifier::DIM, Modifier::BOLD, &[CrosstermAttribute::NormalIntensity, CrosstermAttribute::Bold, CrosstermAttribute::Bold])]
  > ```
  >
  > ---------

- [9d9239a](https://github.com/ratatui/ratatui/commit/9d9239a702d8cd29ca321745901ddb56bff20f70) *(examples)* Add volatility-surface 3D visualization by floor-licker in [#2322](https://github.com/ratatui/ratatui/pull/2322)

  > A design demonstration of a 3D volatility surface rendering using
  > Braille canvas with interactive rotation and zoom controls. I built this
  > for myself for an app I'm currently building but just wanted to share it
  > with the community as well to inspire more 3D perspective terminal
  > widgets in the future.
  >
  > ## Final Demo
  >
  > ![volatility-surface](https://github.com/user-attachments/assets/9613ef26-c766-4f6b-80eb-5bfaa2a7963d)
  >
  > ## Description
  >
  > Adds a new example demonstrating 3D visualization techniques in the
  > terminal. There aren't many examples showing how to represent 3D objects
  > in 2D terminal space so my goal is just to demonstrate more advanced
  > Canvas and Braille rendering techniques for 3D graphics. The example
  > visualizes an implied volatility surface which is a common financial
  > visualization using interactive rotation and zoom controls. You can run
  > the interactive demo for yourself with `cargo run -p volatility-surface`
  >
  > https://github.com/user-attachments/assets/aa32a864-54a8-4c67-a3c9-432dd29373fd
  >
  > <img width="659" height="432" alt="image"
  >
  > src="https://github.com/user-attachments/assets/68698cb0-c5d5-4b41-a3c3-65ec8fff12f5"
  > />
  >
  > ## Technical Highlights
  >
  > - Demonstrates how to implement perspective projection in a terminal
  > - Shows advanced use of `Canvas` widget with `Marker::Braille`
  > - Example of smooth animation patterns and state management
  > - Self-contained with synthetic data generation (no external APIs)
  >
  > ---------

- [ae975c7](https://github.com/ratatui/ratatui/commit/ae975c720006114c64e42656c111c5a9966e2af1) *(examples)* Allow overlap spacing in explorer by joshka in [#2316](https://github.com/ratatui/ratatui/pull/2316)

  > Store spacing as i16 so negative values map to Spacing::Overlap, and
  > show overlap in the axis label.

- [1e0ab0c](https://github.com/ratatui/ratatui/commit/1e0ab0c54935c27a9729e7a1c4a918d3e5a10c21) *(ratatui-crossterm)* Add IntoCrossterm<ContentStyle> for Style by 0xferrous in [#2323](https://github.com/ratatui/ratatui/pull/2323)

- [101a63e](https://github.com/ratatui/ratatui/commit/101a63e112188cbccef968053dee8bbd332cb8c3) *(render)* Add function for applying buffer by musjj in [#2566](https://github.com/ratatui/ratatui/pull/2566)

  > Add a public API for applying and flushing the terminal buffer.
  >
  > A minimal usage will look something like this:
  >
  > ```rust
  > use ratatui::Terminal;
  > use ratatui::backend::CrosstermBackend;
  > use ratatui::buffer::Buffer;
  > use ratatui::widgets::Widget;
  >
  > let backend = CrosstermBackend::new(io::stdout());
  > let mut terminal = Terminal::new(backend)?;
  >
  > terminal.autoresize()?;
  >
  > let mut custom_buffer = Buffer::default();
  > custom_buffer.resize(terminal.get_frame().area());
  > custom_buffer.reset();
  >
  > "Hello World!".render(custom_buffer.area, &mut custom_buffer);
  >
  > terminal.current_buffer_mut().merge(&custom_buffer);
  > terminal.apply_buffer()?;
  > ```
  >
  > My primary motivation for this PR is to improve the ECS ergonomics in
  > [`bevy_ratatui`](https://github.com/ratatui/bevy_ratatui). But this
  > should be useful for anyone who wants to commit incremental writes to
  > the buffer without having to do everything in one monolithic
  > [`Terminal::draw`](https://docs.rs/ratatui/latest/ratatui/struct.Terminal.html#method.draw)
  > closure.
  >
  > ---------

- [09a3027](https://github.com/ratatui/ratatui/commit/09a3027bfce906b86bf20bdcf36fc5e365892b7c) *(symbol)* Add custom marker by BenFradet in [#2356](https://github.com/ratatui/ratatui/pull/2356)

- [f9d066f](https://github.com/ratatui/ratatui/commit/f9d066f4d74684bb13fbbac6c02fb1178d9c0b15) *(table)* Let Cells span multiple columns by karkhaz in [#2150](https://github.com/ratatui/ratatui/pull/2150)

  > Add a 'column_span' field to table cells. The default value
  > is 1; larger values will cause cells to span over multiple columns,
  > being rendered over all columns plus the spaces between them.
  >
  > Fixes #1568.

- [a5b08d6](https://github.com/ratatui/ratatui/commit/a5b08d622a1411b9224c7ebbf59d57c6aeed24a9) *(widgets)* Add Fill widget by Metbcy in [#2520](https://github.com/ratatui/ratatui/pull/2520)

  > Adds a new `Fill` widget that paints every cell within its area with a
  > single repeated symbol and style. Integrates with `Stylize` so the whole
  > chain works as expected:
  >
  > ```rust
  > use ratatui::widgets::{Fill, Widget};
  > use ratatui::style::Stylize;
  >
  > Fill::new("X").blue().bold().render(area, buf);
  > ```
  >
  > Implements `Widget` (for both `Fill` and `&Fill`) and `Styled`, accepts
  > anything that converts into a `Cow<'a, str>`, and degrades gracefully on
  > empty / multi-grapheme symbols.
  >
  >
  > ---------

- [9094fd2](https://github.com/ratatui/ratatui/commit/9094fd2fa2cd22d4916a73398b391e6ebf8a5ecc) *(widgets)* Add line shape with filled area for Canvas and Chart by bananaofhappiness in [#2426](https://github.com/ratatui/ratatui/pull/2426)

  > This commit adds filled area-chart rendering for both `Canvas` and `Chart`.
  >
  > You can now render a line and fill the area between that line and a baseline Y value, which helps highlight magnitude/volume trends.
  >
  > - In `Canvas`, use `FilledLine`.
  > - In `Chart`, use `GraphType::Area` and set the baseline via `Dataset::fill_to_y(f64)`.
  >
  > The `f64` baseline is now configured on `Dataset` (not in `GraphType`), so `GraphType` stays a simple enum variant.
  >
  > Under the hood, line rasterization in canvas was refactored to share a reusable Bresenham point iterator, and `FilledLine` builds on that to paint vertical spans from each line point to `fill_to_y`.
  >
  > Some screenshots with and without this new type:
  > <img width="1460" height="879" alt="изображение"
  > src="https://github.com/user-attachments/assets/c7b534b1-2afb-49c7-9c56-178e6ba9e844"
  > />
  > <img width="1460" height="881" alt="изображение"
  > src="https://github.com/user-attachments/assets/53592e2c-ee89-4481-9099-be06480d305a"
  > />
  >
  > ```rust
  > // In Canvas
  > use ratatui::widgets::canvas::FilledLine;
  >
  > Canvas::default()
  >     .paint(|ctx| {
  >         ctx.draw(&FilledLine::new(0.0, 0.0, 10.0, 5.0, 0.0, Color::Red));
  >     });
  >
  > // In Chart
  > let dataset = Dataset::default()
  >     .data(&data)
  >     .graph_type(GraphType::Area)
  >     .fill_to_y(0.0); // fill to y = 0
  >
  > Chart::new(vec![dataset]);
  > ```
  >
  > ---

- [0a87882](https://github.com/ratatui/ratatui/commit/0a87882e95b493ede74ca72df9164eaa87a0b1f0) *(uncategorized)* Add `impl From<u16>` for `Padding` and `Margin` by JayanAXHF in [#2438](https://github.com/ratatui/ratatui/pull/2438)

- [556cc7b](https://github.com/ratatui/ratatui/commit/556cc7b543e102d7a0c1e7dc86a00777d790bb89) *(uncategorized)* Add comment for inner area to popup example by Its-Just-Nans in [#2309](https://github.com/ratatui/ratatui/pull/2309)

- [01a15f9](https://github.com/ratatui/ratatui/commit/01a15f980940e465c0455229c6910e16d69f6745) *(uncategorized)* Add AsRef impls for widget types by joshka in [#2297](https://github.com/ratatui/ratatui/pull/2297)

### Bug Fixes

- [d12bb83](https://github.com/ratatui/ratatui/commit/d12bb83840056392ad93d5d3b2d4220f1d5fb12e) *(barchart)* Handle empty horizontal charts by fallintoplace in [#2553](https://github.com/ratatui/ratatui/pull/2553)
  >
  > Fixes #2552
  >
  > This makes the `BarChart` constructors ignore empty groups, matching the
  > existing `.data(...)` builder behavior. Without this,
  >
  > `BarChart::horizontal(Vec::<Bar>::new())` stores one empty group,
  > proceeds into horizontal rendering, skips the bar loop, and then
  > underflows when computing the group label row from `bar_y -
  > self.bar_gap`.
  >
  > The fix normalizes constructor input through a shared `non_empty_groups`
  > helper for `new`, `horizontal`, and `grouped`. Empty horizontal charts
  > now render nothing instead of panicking, and constructor behavior is
  > consistent with `.data(...)`.
  >
  > ---------

- [6396b1c](https://github.com/ratatui/ratatui/commit/6396b1ce66721bda028ab3a54a6361cb98db7e6d) *(block)* Saturate block edge arithmetic by joshka in [#2488](https://github.com/ratatui/ratatui/pull/2488)

  > ### Motivation
  >
  > - Block border and title layout used unchecked `u16` arithmetic in
  > several places.
  > - In debug builds that can panic on tiny or edge-case geometry; in
  > release builds the same arithmetic wraps.
  > - The original report came from merge-border rendering on tiny areas,
  > but the same pattern appeared in title layout and spacing helpers as
  > well.
  >
  > ### Description
  >
  > - Use saturating arithmetic in `Block::inner`, `render_sides`,
  > `render_corners`, `titles_area`, and `vertical_space`.
  > - Clamp rendered title widths to `u16` for layout arithmetic.
  > - Replace unchecked title-width accumulation and cursor-advance math
  > with bounded arithmetic.
  > - Add debug-only regression tests covering empty areas, maximal padding,
  > title-area edge cases, and very large title widths.
  >
  > ### Testing
  >
  > - Ran `cargo test -p ratatui-widgets block::tests`.
  >
  > ------
  > [Codex
  > Task](https://chatgpt.com/codex/cloud/tasks/task_e_69dbd35ed38c833094a9fa56b239f0d0)

- [9143b83](https://github.com/ratatui/ratatui/commit/9143b8360f0d0be268578c9f8a10f36e1e55d8a2) *(buffer)* Diff for trailing cells when only style changes by gcavelier in [#2308](https://github.com/ratatui/ratatui/pull/2308)

  > this PR closes #2307 by preventing unnecessary diff updates for trailing
  > cells when only style changes.
  >
  > This PR was generated by Claude, and validated by me.
  >
  > ## Summary
  >
  > This PR fixes a visual artifact bug where block borders would appear
  > offset when rendered over a widget that had a foreground color style
  > applied to the entire area.
  >
  > ## The Fix
  >
  > ```diff
  > - if !next_trailing.skip && prev_trailing != next_trailing {
  > + // Only emit update if the SYMBOL changed, not just the style.
  > + // The style of hidden trailing cells is not visible, so style
  > + // differences alone should not trigger updates that can cause
  > + // cursor positioning issues on some terminals.
  > + if !next_trailing.skip && prev_trailing.symbol() != next_trailing.symbol() {
  > ```
  >
  > This aligns the code with the documented intent: only emit updates when
  > the **symbol** (visible content) changes, not when only the style
  > changes.
  >
  > ## Changes
  >
  > | File | Change |
  > |------|--------|
  > | `ratatui-core/src/buffer/buffer.rs:526-530` | Compare only symbol, not
  > full cell |
  > | `ratatui-core/src/buffer/buffer.rs:1376-1425` | Add regression test |
  >
  > ## Test Added
  >
  > ```rust
  > #[test]
  > fn diff_ignores_style_only_changes_in_trailing_cells() {
  >     // Verifies that trailing cells with same symbol but different style
  >     // do NOT generate diff updates
  > }
  > ```
  >
  > ## Why This Is Safe
  >
  > 1. **Trailing cells are hidden** - they are visually covered by the wide
  > character
  > 2. **Style is invisible** - the fg/bg color of a hidden cell has no
  > visual effect
  > 3. **Symbol changes still trigger updates** - if the symbol changes
  > (e.g., from `" "` to `"x"`), the update is still emitted
  > 4. **Aligns with documented intent** - the original comment says
  > "non-blank content", not "different style"
  >
  > ## Related
  >
  > - The existing test `diff_clears_trailing_cell_for_wide_grapheme`
  > verifies that symbol changes DO trigger updates
  > - This fix complements that behavior by ensuring style-only changes do
  > NOT trigger updates

- [e6b71f2](https://github.com/ratatui/ratatui/commit/e6b71f2ce7d829c3bf55a0b4fa8085e8ef3d0a88) *(build)* Correct rust-toolchain->rust-version on cargo-deny-action by sermuns in [#2471](https://github.com/ratatui/ratatui/pull/2471)
  >
  > closes #2470

- [65c5202](https://github.com/ratatui/ratatui/commit/65c520245aa20e99e64d9ffcb2062a4502a699ea) *(changelog)* Fix typo by joshka in [#2300](https://github.com/ratatui/ratatui/pull/2300)

- [43bbaae](https://github.com/ratatui/ratatui/commit/43bbaae9e9210e547867a129d862e416ddf746ea) *(clippy)* Fix beta clippy errors by Logan-Ruf in [#2433](https://github.com/ratatui/ratatui/pull/2433)

  > Noticed these errors on my other PR and figured I could just fix them
  > real quick.
  >
  > closes #2432

- [957fbb0](https://github.com/ratatui/ratatui/commit/957fbb02934955889b4b059666447a090d662297) *(core)* Use correct width for halfwidth dakuten/handakuten by orhun in [#2499](https://github.com/ratatui/ratatui/pull/2499)

  > unicode-width reports U+FF9E/U+FF9F as zero-width, but terminals render
  > them as 1 cell.
  > Adjusts `CellWidth` trait accordingly for fixing this behavior.
  >
  > fixes #2188

- [d7646c7](https://github.com/ratatui/ratatui/commit/d7646c7156fedfdf970149cd25101caaf19724b9) *(core)* Avoid overflow in BufferDiff forced-width advance by joshka in [#2487](https://github.com/ratatui/ratatui/pull/2487)

  > ### Motivation
  > - Prevent arithmetic overflow when advancing `self.pos` for
  > `CellDiffOption::ForcedWidth(NonZeroU16)` in
  > `ratatui-core/src/buffer/diff.rs`, which could panic in debug or wrap in
  > release and cause an iterator hang/DoS.
  >
  > ### Description
  > - Replace the unchecked `self.pos += width.get().saturating_sub(1)` with
  > a saturating addition via `self.pos =
  > self.pos.saturating_add(width.get().saturating_sub(1) as usize)` to
  > avoid overflow while preserving existing iterator semantics.
  >
  > ### Testing
  > - Ran `cargo test -p ratatui-core buffer::diff --lib` and the buffer
  > diff tests completed successfully (`10 passed, 0 failed`).
  >
  > ------
  > [Codex
  > Task](https://chatgpt.com/codex/cloud/tasks/task_e_69dbd3420b74833089a87f6021475610)

- [77f8006](https://github.com/ratatui/ratatui/commit/77f80064060cdc1e870b20005fd2be4c17f6edd5) *(core)* Avoid cursor position queries during resize by orhun in [#2485](https://github.com/ratatui/ratatui/pull/2485)
  >
  > `Terminal::resize()` now clears without calling `get_cursor_position()`,
  > so that CPR (Cursor position report) calls does not interfere with
  > stdin.
  >
  > Fixes #2483
  >
  > ---------

- [18aa467](https://github.com/ratatui/ratatui/commit/18aa467ef2e11583215d35b31df9832edec6964d) *(examples)* Make line-gauge example compatible with macos sequoia's terminal.app by lazo4 in [#2474](https://github.com/ratatui/ratatui/pull/2474)

  >
  >
  > Part of the fix for #1972
  >
  > ### Summary
  > This fix makes the `line-gauge` example compatible with the macos
  > sequoia Terminal.app which doesn't support truecolor. It reuses the
  > `is_true_color_supported` introduced in #2211 by ffex and uses a color
  > theme instead of hardcoding the colors.
  >
  > ### Result on macos sequoia
  > Before:
  > <img width="566" height="138" alt="Capture d’écran 2026-04-06 à 11 47
  > 07"
  > src="https://github.com/user-attachments/assets/1ea37832-8a07-40b0-b0ab-aa77476ef9eb"
  > />
  > After:
  > <img width="561" height="120" alt="Capture d’écran 2026-04-06 à 11 46
  > 45"
  > src="https://github.com/user-attachments/assets/4bd50bc1-68f9-4601-b361-f610abf8629d"
  > />
  >
  > ### Notes
  > This is my first open source contribution, thanks to @ffex for letting
  > me help on this issue

- [ce2c228](https://github.com/ratatui/ratatui/commit/ce2c22827a1fa9df9b97e22983cee3379327a832) *(examples)* Change flex example colors for MacOS default terminal by ffex in [#2211](https://github.com/ratatui/ratatui/pull/2211)

  > Part of the fix for #1972
  >
  > ### Summary
  >
  > This fix introduces a function to check if we are in a terminal without
  > truecolor(24-bit) and changes the default colors to appear fine of the
  > flex example.
  >
  > ### Notes
  >
  > The function "is_true_color_supported” is an old problem and there is no
  > common way to determine if a terminal supports or not the truecolor.
  >
  > This is the main reason why the function detects specifically the
  > Terminal.app version before the Tahoe. If there are other known
  > terminals with this problem, we can add it to this function.
  >
  > ---------

- [ef72dba](https://github.com/ratatui/ratatui/commit/ef72dbae54100b2c1084735cb5d7db474f2d81f2) *(examples)* Fix import for widget examples by orhun in [#2422](https://github.com/ratatui/ratatui/pull/2422)
  >
  > closes #2299

- [88441cf](https://github.com/ratatui/ratatui/commit/88441cff52cc40e380be964429956bb0b1c471da) *(terminal)* Fix inline viewport resizing issues by clearing the screen by wyvernbw in [#2355](https://github.com/ratatui/ratatui/pull/2355)

  > adds a check to the autoresize function to clear the entire screen and
  > move the inline viewport to the top when the window shrinks horizontally
  > in order to avoid line wrapping issues.
  >
  > Other libraries like ink purge the history as well, but the
  > `backend::ClearType` type does not support that. Without this if the
  > user scrolls up they will see previous broken renders. This should work
  > well with all terminal emulators and multiplexers.
  >
  > fixes #2086

- [91b6fb7](https://github.com/ratatui/ratatui/commit/91b6fb72d35404dd6db932ce70db4a50e70eab31) *(tests)* Use the correct type for the cell diff test by orhun in [#2472](https://github.com/ratatui/ratatui/pull/2472)

  > fixes the CI!

- [4493742](https://github.com/ratatui/ratatui/commit/449374226bc736d169ca8923012796d48f012b66) *(widgets)* Handle single y-axis label by fallintoplace in [#2550](https://github.com/ratatui/ratatui/pull/2550)
  >
  > Fixes #2549.
  >
  > This prevents `Chart` from panicking when the Y axis is configured with
  > exactly one label. The X-axis rendering path already skips label
  > placement when fewer than two labels are provided; this applies the same
  > guard to Y-axis labels before the spacing calculation divides by
  > `labels_len - 1`.
  >
  > This also updates the `Axis::labels` docs so they describe the new
  >
  > behavior:fewer than two labels are not rendered instead of causing a
  > panic.

- [0bdebd6](https://github.com/ratatui/ratatui/commit/0bdebd679f36d787c103ea0372b72b3318b73947) *(widgets)* Prevent chart scaling overflow by fallintoplace in [#2546](https://github.com/ratatui/ratatui/pull/2546)

  > ## Summary
  >
  > Fixes #2545.
  >
  > This changes BarChart and Sparkline scaling to use a `u128` intermediate
  > before division, then caps the scaled ticks at the drawable area. That
  > prevents debug-build panics and release-build wrapping when public `u64`
  > chart values are large.
  >
  > ## Validation
  >
  > - `cargo test -p ratatui-widgets barchart::tests`
  > - `cargo test -p ratatui-widgets sparkline::tests`
  > - `cargo check -p ratatui-widgets --all-features`
  > - `cargo clippy -p ratatui-widgets --all-targets --all-features -- -D
  > warnings`
  > - `cargo test -p ratatui-widgets`

- [e27a22a](https://github.com/ratatui/ratatui/commit/e27a22a99a91fc991c8beabe25dde6c49c70d867) *(widgets)* Inherit the text alignment for Paragraph by 7Bpencil in [#2369](https://github.com/ratatui/ratatui/pull/2369)

  > Paragraph didn't take into account alignment of the text it was created
  > from:
  >
  > ```rs
  > let lines = vec![
  >     Line::from("one"),
  >     Line::from("double"),
  >     Line::from("quadruple"),
  > ];
  > let text = Text::from(lines).centered();
  >
  > // used to be rendered left-aligned, now centered
  > let paragraph = Paragraph::new(text).block(block);
  > ```
  >
  > Now the Paragraph inherits the text alignment.

- [b5c0831](https://github.com/ratatui/ratatui/commit/b5c083151818e2c46aac837004c476dd978df55b) *(widgets)* Avoid panic if Clear area is outside of buffer by 7Bpencil in [#2368](https://github.com/ratatui/ratatui/pull/2368)

  > If Clear area is at least partially outside of buffer, panic "index
  > outside of buffer" happens on Widget::render
  >
  > <details>
  >
  > <summary>Demo source code</summary>
  >
  > ```rs
  > use crossterm::event::{self, Event, KeyModifiers};
  > use ratatui::{
  >     layout::Rect,
  >     text::Line,
  >     widgets::{Block, Borders, Clear, Paragraph},
  >     DefaultTerminal, Frame,
  > };
  > use std::iter;
  >
  > fn main() {
  >     ratatui::run(app);
  > }
  >
  > fn app(terminal: &mut DefaultTerminal) {
  >     loop {
  >         if let Event::Key(key_event) = event::read().expect("failed to read event") {
  >             if key_event.kind.is_press()
  >                 && key_event.modifiers.contains(KeyModifiers::CONTROL)
  >                 && key_event.code.is_char('c')
  >             {
  >                 break;
  >             }
  >         }
  >         terminal.draw(render).expect("failed to draw frame");
  >     }
  > }
  >
  > fn render(frame: &mut Frame) {
  >     {
  >         let width = frame.area().width;
  >         let area = Rect::new(0, 0, width, 10);
  >         let line = Line::from("W".repeat(area.width as usize));
  >         let lines: Vec<Line> = iter::repeat_n(line, area.height as usize).collect();
  >         frame.render_widget(Paragraph::new(lines), area);
  >     }
  >     {
  >         let area = Rect::new(50, 2, 20, 5);
  >         let block = Block::default()
  >             .title_top(Line::from("Popup-with-Clear").centered())
  >             .borders(Borders::ALL);
  >         let lines = vec![
  >             Line::from("one"),
  >             Line::from("double"),
  >             Line::from("quadruple"),
  >         ];
  >         frame.render_widget(Clear, area);
  >         frame.render_widget(Paragraph::new(lines).block(block).centered(), area);
  >     }
  >     {
  >         let area = Rect::new(80, 2, 20, 5);
  >         let block = Block::default()
  >             .title_top(Line::from("Popup").centered())
  >             .borders(Borders::ALL);
  >         let lines = vec![
  >             Line::from("one"),
  >             Line::from("double"),
  >             Line::from("quadruple"),
  >         ];
  >         frame.render_widget(Paragraph::new(lines).block(block).centered(), area);
  >     }
  > }
  > ```
  >
  > </details>
  >
  > Before the fix:
  >
  > https://github.com/user-attachments/assets/cebae1df-87b2-48ae-9456-7ad8cb72035c
  >
  > After the fix:
  >
  > https://github.com/user-attachments/assets/9e0170f3-9c71-4a28-96b3-3f4b7db8ed37

- [1ce29d6](https://github.com/ratatui/ratatui/commit/1ce29d66f1fda58b76d711903c89654191bb4937) *(uncategorized)* Decouple std from serde and palette features by december1981 in [#2460](https://github.com/ratatui/ratatui/pull/2460)

  > The std feature now passes through to the deps rather than
  > requiring std to use serde / palette.

- [2a0b4b2](https://github.com/ratatui/ratatui/commit/2a0b4b28de8174eb2e0ca2687fea2af693ef43ef) *(uncategorized)* Ensure consistent thumb size when scrolling by kdheepak in [#2352](https://github.com/ratatui/ratatui/pull/2352)

  > This PR removes the use of `f64` for calculating scrollbar thumb size
  > and uses integer rounding (rounding up instead of the default rounding
  > down) instead. Using integer rounding seems to fix the problem of thumb
  > size not being consistent.
  >
  > Fixes #2351

- [4986b28](https://github.com/ratatui/ratatui/commit/4986b28a39bd62d0b2e98624799d402e0191cfeb) *(uncategorized)* Allow ratatui-widgets to be used without default features by jakobhellermann in [#2350](https://github.com/ratatui/ratatui/pull/2350)

  > Previously, ratatui-widgets was always included with default features.
  >
  > Additionally, the `std` feature would always enable the `time` crate.
  >
  > Fixing this gets rid of a few crates: `deranged`, `num-conv`,
  > `time-core`, `time`.

- [720303e](https://github.com/ratatui/ratatui/commit/720303e806b884f37f986913c111e79a4e243ae9) *(uncategorized)* Align clear() semantics with contract by joshka in [#2320](https://github.com/ratatui/ratatui/pull/2320)

- [d2b0ce1](https://github.com/ratatui/ratatui/commit/d2b0ce17a4764e1af5ebed515d85b5a84f5cff18) *(uncategorized)* Fix the dependency on time by asomers in [#2306](https://github.com/ratatui/ratatui/pull/2306)

  > ratatui-widgets uses time's Month::length(), which requires time-0.3.37
  > or later.

### Refactor

- [d754c5e](https://github.com/ratatui/ratatui/commit/d754c5e58b0ff98d07338cd1e200b2c7e5991b7f) *(app)* Simplify render function in the scrollbar example by marianomarciello in [#2388](https://github.com/ratatui/ratatui/pull/2388)

  > Divide the render function into two functions for vertical and
  > horizontal scroll.

- [629e4b2](https://github.com/ratatui/ratatui/commit/629e4b2af2f35e89a1eec30a30983b4fa8ec74c1) *(core)* Reintroduce `Cell::skip` as a deprecated field by junkdog in [#2437](https://github.com/ratatui/ratatui/pull/2437)

  > as discussed in
  > https://github.com/ratatui/ratatui/pull/1605#discussion_r2933338973 -
  > this brings back `Cell::skip` as a deprecated field in order to avoid
  > breaking the API in a patch release. in terms of noise; the diff() is
  > left pretty intact, but had to `#[allow(deprecated)]` in a couple of
  > places.
  >
  > ## `Cell::skip` vs `CellDiffOption`
  >
  > `CellDiffOption::ForcedWidth` takes precedence over `Cell::skip`, and
  >
  > `CellDiffOption::skip` is already skip - so `Cell::skip` can only
  > override when `CellDiffOption::None` is set. i believe this is the
  > correct behavior, but probably good to have another pair of eyes on it.
  > @benjajaja maybe has some input too.
  >
  > ## PartialEq and Hash for `Cell::skip`
  >
  > `Cell::skip` is part of `PartialEq` and `Hash` as normal fields. another
  > option would be to treat `CellDiffOption::None` as
  >
  > `CellDiffOption::Skip` when `Cell::skip` is set, and only consider the
  > effective `CellDiffOption` for the trait impls.
  >
  > ---------

- [ca5c109](https://github.com/ratatui/ratatui/commit/ca5c10923c57f5e3cc78a36d39f9a254c1ab09ee) *(core)* Introduce `CellWidth` trait for cell width computation by junkdog in [#2400](https://github.com/ratatui/ratatui/pull/2400)

  > this PR introduces a `CellWidth` trait for calculating the cell
  > width/span, implemented for `&str` and `Cell`.
  >
  > The impl for `Cell` respects the new `CellDiffOption::ForcedWidth`. All
  > width calculations are prefixed with a check if the symbol is ascii
  > before calling `symbol.width()`; this micro-optimization probably won't
  > do much on computers, but it helps on embedded.
  >
  > As discussed recently in #1605, this also changes the
  > `CellDiffOption::ForcedWidth(type) from NonZeroUsize to NonZeroU16.
  >
  > ---------

- [9ac167d](https://github.com/ratatui/ratatui/commit/9ac167d5ec6d6ce04fef8e824966847657ff8976) *(style)* Add descriptive panic for Color::Reset anstyle conversion by singhh-piyush in [#2423](https://github.com/ratatui/ratatui/pull/2423)
  >
  > `Color::Reset` has no equivalent in `anstyle::Color`. Previously,
  > converting `Color::Reset.into()` fell through to the catch-all arm in
  > `From<Color> for anstyle::Color`, which called
  >
  > `AnsiColor::try_from(color).unwrap()` and panicked with the message:
  > `called Result::unwrap() on an Err value: Ansi`.
  >
  > This replaces the opaque `unwrap()` with an explicit, immediately
  > understandable panic: `"Color::Reset has no equivalent in anstyle"`.
  >
  > Fixes #2341

- [f093b02](https://github.com/ratatui/ratatui/commit/f093b0292db270be3eccc50470f596f0124aeaa2) *(uncategorized)* Satisfy beta Clippy buffer debug lint by joshka in [#2562](https://github.com/ratatui/ratatui/pull/2562)

  > Remove a redundant borrow in `Buffer`'s `Debug` implementation

### Documentation

- [f8b42ad](https://github.com/ratatui/ratatui/commit/f8b42adb5f12075cfb8c1b7028ec71ac12e7f97a) *(breaking-changes)* Update header for 0.30.0 by orhun in [#2295](https://github.com/ratatui/ratatui/pull/2295)

- [e82b3b7](https://github.com/ratatui/ratatui/commit/e82b3b77fefca6b72876db2dcac11d2cec13efc3) *(buffer)* Run the doctests for Buffer by orhun in [#2319](https://github.com/ratatui/ratatui/pull/2319)

  > addresses
  > https://github.com/ratatui/ratatui/pull/2314#pullrequestreview-3621576941
  >
  > the doctest was not running at all... (due to `fn foo`)

- [d8c86c3](https://github.com/ratatui/ratatui/commit/d8c86c3d7c2af49b6121d24cd39d09b63af469dc) *(canvas)* Add usage example for Line widget by ramadhan-dev-bright in [#2473](https://github.com/ratatui/ratatui/pull/2473)

  > Added a doc-tested example for the Line struct in canvas to improve
  > documentation and help new users understand how to render lines with
  > color.

- [83c1579](https://github.com/ratatui/ratatui/commit/83c157965759bf660eb81f47bdedf96b886b9fd3) *(changelog)* Fix doubled words in two entries by adv0r in [#2578](https://github.com/ratatui/ratatui/pull/2578)
  >
  > Typo:`in in` → `in` and `and and` → `and` in `CHANGELOG.md`

- [fff27e8](https://github.com/ratatui/ratatui/commit/fff27e8d50e72558a791e9ce146bcfff117ac424) *(contributing)* Add packages needed to run xtasks by alabhyajindal in [#2409](https://github.com/ratatui/ratatui/pull/2409)
  >
  > Fixes #2408
  >
  > ---------

- [be718d0](https://github.com/ratatui/ratatui/commit/be718d049a668602443e7f7dfb31ec366f40624a) *(ratatui-core)* Fix terminal rendering grammar by Zacxxx in [#2555](https://github.com/ratatui/ratatui/pull/2555)

- [095b47d](https://github.com/ratatui/ratatui/commit/095b47ddc7ce107674c5beae77841cebae7c0571) *(ratatui-crossterm)* Fix doubled article in module docs by adv0r in [#2564](https://github.com/ratatui/ratatui/pull/2564)

  > > **Dear maintainer** — AI-authored PR by **Composer** under
  > [@adv0r](https://github.com/adv0r). Methodology +
  > [opt-out](https://github.com/adv0r/tokens-for-good/blob/main/MAINTAINER_REMOVAL.md)
  > at [tokens-for-good](https://github.com/adv0r/tokens-for-good).
  > > A one-line "no thanks" → auto-apology + auto-close + permanent
  > blacklist. Silent close treated the same. Your time matters more than
  > this contribution.
  >
  > Typo:`See the the [Examples]` → `See the [Examples]` in
  > `ratatui-crossterm/src/lib.rs`.

- [160b177](https://github.com/ratatui/ratatui/commit/160b17790c3740ce2a06910e648c3eb4d7359fac) *(ratatui-termwiz)* Fix doubled article in module docs by adv0r in [#2565](https://github.com/ratatui/ratatui/pull/2565)

  > > **Dear maintainer** — AI-authored PR by **Composer** under
  > [@adv0r](https://github.com/adv0r). Methodology +
  > [opt-out](https://github.com/adv0r/tokens-for-good/blob/main/MAINTAINER_REMOVAL.md)
  > at [tokens-for-good](https://github.com/adv0r/tokens-for-good).
  > > A one-line "no thanks" → auto-apology + auto-close + permanent
  > blacklist. Silent close treated the same. Your time matters more than
  > this contribution.
  >
  > Typo:`See the the [Examples]` → `See the [Examples]` in
  > `ratatui-termwiz/src/lib.rs`.

- [8ce5513](https://github.com/ratatui/ratatui/commit/8ce5513902cc5ba23adadca2bf97c08874585ca5) *(sparkline)* Fix typo in doc comment by adv0r in [#2554](https://github.com/ratatui/ratatui/pull/2554)

- [e6529fd](https://github.com/ratatui/ratatui/commit/e6529fd6f5825752c5f8b2b6ef889b1367537e55) *(terminal)* Improve terminal and setup docs for app authors by joshka in [#2461](https://github.com/ratatui/ratatui/pull/2461)

  > ## Summary
  >
  > This updates the terminal and setup docs to better match the rendering
  > behavior Ratatui actually implements, while also making the docs.rs path
  > clearer for application authors.
  >
  > The main docs changes are split into two commits:
  >
  > 1. `docs: align terminal docs with behavior`
  > - align `Terminal`, viewport, frame, and flush docs with the real render
  > pipeline
  >    - clarify the boundary between `Terminal::flush` and `Backend::flush`
  >    - improve examples for fullscreen, inline, and fixed viewport usage
  > 2. `docs: improve terminal docs for app authors`
  > - improve setup-path guidance across `ratatui`, `ratatui-core`, and
  > backend crates
  >    - clarify viewport choice, escape hatches, and common edge cases
  > - reduce duplication so crate-level docs explain choices while method
  > docs hold detailed contracts
  >
  > A small follow-up also fixes the crate-doc heading hierarchy in
  > `ratatui-core` and
  > `ratatui-crossterm` so the generated READMEs no longer need
  > `markdownlint-disable-next-line heading-increment` suppressions.
  >
  > ## Verification
  >
  > - `cargo test -p ratatui --doc`
  > - `cargo test -p ratatui-core --doc`
  > - `cargo test -p ratatui-crossterm --doc`
  > - `cargo test -p ratatui-termion --doc`
  > - `cargo test -p ratatui-termwiz --doc`
  > - `cargo test --workspace --all-targets --no-run`
  > - `cargo doc -p ratatui --no-deps`
  > - `cargo doc -p ratatui-core --no-deps`
  > - `cargo xtask format --check`
  > - `cargo xtask readme --check`
  >
  > Note:`cargo doc -p ratatui-core --no-deps` still reports pre-existing
  > warnings outside this pass in `layout` and `text` docs. The terminal-doc
  > warnings introduced during this work were fixed.
  >
  > ---------

- [744dc36](https://github.com/ratatui/ratatui/commit/744dc360813024bcaf8e768712f4b3821ac5dde8) *(uncategorized)* Remove duplicate word in color and backend module by lphuc2250gma in [#2535](https://github.com/ratatui/ratatui/pull/2535)

  > Two one-line typo fixes for duplicated "the" in doc-comments:
  > - `ratatui-core/src/style/color.rs` — "/// the the older serialization
  > implementation of Color are also able to be deserialized." → "...the
  > older serialization..."
  > - `ratatui-core/src/backend.rs` — "//! See the the [Examples] directory
  > for more examples." → "//! See the [Examples] directory for more
  > examples."
  >
  > No code/behavior change.

- [3df8c20](https://github.com/ratatui/ratatui/commit/3df8c20dfb30e7afb8fd84614f44c62e5f6abb66) *(uncategorized)* Ask issue authors about PR willingness by joshka in [#2317](https://github.com/ratatui/ratatui/pull/2317)

  > Add a contribution question to the bug report and feature request
  > templates so maintainers know whether the reporter wants to work on a
  > fix/PR or needs guidance.

- [53d925a](https://github.com/ratatui/ratatui/commit/53d925a8abac3690680633c4ad3eefe3c1b3258c) *(uncategorized)* Add Documentation on the Map Projection / CRS by C-Loftus in [#2324](https://github.com/ratatui/ratatui/pull/2324)

- [64d964b](https://github.com/ratatui/ratatui/commit/64d964b259616f6dcd7f83147946eeddcc19b64b) *(uncategorized)* Update Terminal docs by joshka in [#2312](https://github.com/ratatui/ratatui/pull/2312)

  > ## Summary
  >
  > - Improve `Terminal` Rustdocs to better explain typical app setup, the
  > rendering pipeline, and how
  > diff-based rendering works (including full redraw behavior on viewport
  > size changes).
  > - Clarify viewport concepts and behavior in `Viewport`/`Terminal` docs,
  > with a more complete inline
  >   section (anchoring, scrolling, resize behavior).
  > - Reorder `Terminal::draw` / `Terminal::try_draw` closer to constructors
  > so the primary rendering
  >   entry points are easier to find.
  >
  > ## Notes
  >
  > - Docs-only change; no public API or runtime behavior changes.
  > - No new tests in this PR.
  >
  > ## Test Plan
  >
  > - `cargo +nightly fmt`
  > - `cargo +nightly docs-rs -p ratatui-core`
  > - `cargo test -p ratatui-core --doc --features std`

- [8d73d47](https://github.com/ratatui/ratatui/commit/8d73d4738eaa3fcb85910e189ca2d9a728485750) *(uncategorized)* Fix comment to reflect correct symbol in assertion by homebrewmellow in [#2314](https://github.com/ratatui/ratatui/pull/2314)

- [fbd5621](https://github.com/ratatui/ratatui/commit/fbd562117bd331c2094575c2f657f0f435e58711) *(uncategorized)* Fix misspellings by cgzones in [#2310](https://github.com/ratatui/ratatui/pull/2310)

### Performance

- [dcea52b](https://github.com/ratatui/ratatui/commit/dcea52bdf933dd562e165d73566f87fab30a97db) *(core)* Eliminate per-frame Vec allocation in Terminal::flush by junkdog in [#2416](https://github.com/ratatui/ratatui/pull/2416)

  > ## what and how
  >
  > this PR removes the `Vec<(u16, u16, &Cell)>` allocation in
  > `Terminal::flush` when calling `Buffer::diff`. a new method,
  > `Buffer::diff_iter` is instead used by `Terminal::flush`.
  >
  > the existing diff implementation has moved to the `BufferDiff` iterator.
  >
  > ## why (who cares?)
  >
  > it's the mice. on embedded devices, allocating a short-lived, contiguous
  > block of up to 40-50kb is problematic due to heap fragmentation in
  > combination with tiny heaps. the requirements for a full refresh over
  > 1200 terminal cells is 37.5kb+vec growth padding, but since we're
  > dealing with a contiguous block of memory, the actual memory
  > requirements are considerably higher, depending on user-land allocation
  > patterns.
  >
  > ---------

### Testing

- [b696ea3](https://github.com/ratatui/ratatui/commit/b696ea37b239689acef890c7755ca8c297655f4b) *(core)* Split `Terminal` into submodules and expand test coverage by joshka in [#2315](https://github.com/ratatui/ratatui/pull/2315)

  > - Split the `Terminal` implementation into focused submodules to improve
  > readability and maintainability.
  > - Add characterization tests covering `Terminal` initialization, buffer
  > lifecycle, resizing and autoresize behavior, and rendering paths.
  > - Add inline viewport tests for `compute_inline_size` and
  > `insert_before` in both fallback and scrolling-regions modes, including
  > an end-to-end `draw -> insert_before -> draw scenario` scenario.
  > - Extend `TestBackend` cursor plumbing to support the new terminal tests
  > and assert cursor/ behavior.

### Miscellaneous Tasks

- [746e9c9](https://github.com/ratatui/ratatui/commit/746e9c9ca2370a2ff033fb082f765f4c32a629b4) *(build)* Add symlinks from each crate dir to root LICENSE by martinvonz in [#2370](https://github.com/ratatui/ratatui/pull/2370)

  > AFAICT, each crate directory must have its own LICENSE file for it to
  > become part of the published crate. This patch therefore adds LICENSE
  > symlinks from each crate directory to the root LICENSE file. This
  > matches what e.g. clap does (https://github.com/clap-rs/clap).
  >
  > Since ratatui-macros/LICENSE already exists and with different copyright
  > holders than in the root LICENSE file, I left it unchanged.

- [7b66bd4](https://github.com/ratatui/ratatui/commit/7b66bd4a94c3d9f9015f62b4a8ec5c95a2c25f0b) *(ci)* Use latest released cargo-machete action by sermuns in [#2469](https://github.com/ratatui/ratatui/pull/2469)

- [b6dfafd](https://github.com/ratatui/ratatui/commit/b6dfafd062893963d352c5a3e623475f3bc778e4) *(markdown)* Fix linting issues reported by xtask lint by Logan-Ruf in [#2435](https://github.com/ratatui/ratatui/pull/2435)

- [fba4448](https://github.com/ratatui/ratatui/commit/fba44486e04b3abf2c3899955ea8cf5daedee7bd) *(ratatui)* Unleash the rats v0.30.1

- [0b03fe4](https://github.com/ratatui/ratatui/commit/0b03fe47f1a941fccf9dd694f2531157e312f330) *(toml)* Migrate from taplo to tombi by joshka in [#2501](https://github.com/ratatui/ratatui/pull/2501)

  > ## Summary
  >
  > This migrates the repo's TOML tooling from
  > [Taplo](https://github.com/tamasfe/taplo) to
  > [Tombi](https://github.com/tombi-toml/tombi).
  >
  > The main motivation is maintenance and installability:
  >
  > - Ratatui previously used [Taplo](https://github.com/tamasfe/taplo) for
  > TOML formatting.
  > - Taplo's maintenance future has been uncertain; see
  > <https://github.com/tamasfe/taplo/issues/715>.
  > - Taplo's current release artifacts are not friendly to
  > `cargo-binstall`, which means some setups fall back to building from
  > source.
  > - That source-build path is awkward for CI and was also a blocker while
  > exploring a future Docker/devcontainer setup because of image size and
  > install cost.
  >
  > [Tombi](https://github.com/tombi-toml/tombi) is actively maintained,
  > publishes prebuilt binaries, and has a VS Code extension that lets us
  > keep editor behavior aligned with CI.
  >
  > ## What Changed
  >
  > ### Tooling and CI
  >
  > - Replace `taplo` with `tombi` in `cargo xtask format`.
  > - Use
  > [`tombi-toml/setup-tombi`](https://github.com/tombi-toml/setup-tombi) in
  > the formatting CI job.
  > - Replace `.taplo.toml` with `tombi.toml`.
  >
  > ### Formatting policy
  >
  > - Keep the existing 100-column TOML line width.
  > - Disable schema-driven top-level table ordering for `Cargo.toml`.
  > - Disable the corresponding `tables-out-of-order` lint for `Cargo.toml`.
  >
  > Why disable Cargo schema ordering:
  >
  > - Tombi can order keys and tables according to schema metadata; see
  > <https://tombi-toml.github.io/tombi/docs/comment-directive/tombi-value-directive/#format-rules-table-keys-order>.
  > - The schema order moved sections like `[features]` below dependency
  > sections.
  > - That made feature-gated behavior harder to scan.
  > - It also created noisy migration churn that was not central to the tool
  > switch itself.
  >
  > Why disable the Cargo lint warning:
  >
  > - The VS Code warning came from Tombi's `tables-out-of-order` lint
  > rather than from formatting.
  > - Since we are intentionally preserving the existing Cargo manifest
  > section order, we also disable that lint for `Cargo.toml` to keep
  > diagnostics aligned with the formatter configuration.
  > - Related docs:
  > <https://tombi-toml.github.io/tombi/docs/configuration/>.
  >
  > ### Installation note
  >
  > - Tombi is better positioned for binary installs than Taplo today, but
  > it is still not fully in the generic `cargo-binstall` /
  > `taiki-e/install-action` path.
  > - Relevant upstream context:
  > - binary naming / generic installer compatibility:
  > <https://github.com/tombi-toml/tombi/issues/1164>
  > - crates.io publishing for `cargo-binstall` fallback:
  > <https://github.com/tombi-toml/tombi/issues/1686>
  > - earlier crates.io publishing discussion:
  > <https://github.com/tombi-toml/tombi/issues/632>
  > - In practice, this still leaves some rough edges around the generic
  > Rust installer path, but Tombi already has usable prebuilt binaries and
  > an official installer action, which is a better place for Ratatui than
  > Taplo's current install story.
  > - CI now uses
  > [`tombi-toml/setup-tombi`](https://github.com/tombi-toml/setup-tombi)
  > with a pinned version, which avoids the GitHub token path by not asking
  > the action to resolve `latest` at runtime.
  >
  > ### Docs and editor setup
  >
  > - Update contributor docs to point to Tombi's repo, docs, and
  > installation guide.
  > - Note that the repo previously used Taplo and link the upstream
  > maintenance discussion at <https://github.com/tamasfe/taplo/issues/715>.
  > - Add VS Code extension recommendations for
  > [`rust-lang.rust-analyzer`](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer)
  > and
  > [`tombi-toml.tombi`](https://marketplace.visualstudio.com/items?itemName=tombi-toml.tombi).
  > - Add committed VS Code workspace settings for shared repo defaults,
  > mainly so the workspace can define formatter behavior that matches CI,
  > including TOML formatter selection and nightly rustfmt args.
  > - Add a dedicated formatting section to `CONTRIBUTING.md` covering Rust
  > formatting, TOML formatting, nightly `rustfmt`, and the VS Code
  > workspace override workaround.
  >
  > ## Why Commit VS Code Settings
  >
  > This PR adds committed VS Code workspace settings for shared repo
  > defaults only.
  >
  > The goal is to:
  >
  > - recommend the expected extensions
  > - make local editor formatting behave more like CI
  > - avoid formatter drift between editor usage and the repo's checked-in
  > tooling
  >
  > This is not intended to standardize everyone's full editor setup.
  >
  > ## Nightly rustfmt
  >
  > The repo already uses unstable rustfmt options in
  > [`rustfmt.toml`](./rustfmt.toml), so formatting Rust code with `cargo
  > xtask format` works best with nightly Rust. This is already how CI
  > behaves.
  >
  > The docs now call this out more clearly:
  >
  > - install nightly if you want local formatting to match CI
  > - the reason is to pick up the unstable formatting options configured in
  > `rustfmt.toml`
  >
  > For contributors who cannot or do not want to install nightly, the docs
  > also point to a workaround: use a personal VS Code workspace file with
  > override settings instead of changing the tracked workspace config.
  >
  > ## Notes From Implementation
  >
  > - Tombi `v0.9.19` added config support to disable schema-defined
  > ordering per schema, which let us preserve existing `Cargo.toml` section
  > order cleanly.
  > - The `tables-out-of-order` warning seen in VS Code came from Tombi
  > lint, not formatting, so that needed a separate config change.
  > - After disabling Cargo section ordering, the remaining TOML churn was
  > much smaller and mostly mechanical.
  >
  > ## Files of Interest
  >
  > - `.github/workflows/ci.yml`
  > - `xtask/src/commands/format.rs`
  > - `tombi.toml`
  > - `.vscode/settings.json`
  > - `.vscode/extensions.json`
  > - `CONTRIBUTING.md`
  >
  > ## Verification
  >
  > - `cargo xtask format --check`
  > - `cargo metadata --format-version 1`
  > - `markdownlint-cli2 CONTRIBUTING.md`

- [ed46fef](https://github.com/ratatui/ratatui/commit/ed46fefb3f26f3786381843fe7f7cce47254781d) *(uncategorized)* Update versions

- [f30bab9](https://github.com/ratatui/ratatui/commit/f30bab9ef0c089e3200237029cdf750cb09e5fcf) *(uncategorized)* Ignore licker as typo

- [c7746e9](https://github.com/ratatui/ratatui/commit/c7746e90d0c10ea450356edac9715dd3f1b02a4a) *(uncategorized)* Bump MSRV to 1.88.0 by orhun in [#2396](https://github.com/ratatui/ratatui/pull/2396)

- [b0a7703](https://github.com/ratatui/ratatui/commit/b0a7703c0002c53bbaa432f04a342f63f75e2219) *(uncategorized)* Escape usernames in changelog with backticks by kdheepak in [#2377](https://github.com/ratatui/ratatui/pull/2377)

  > This PR escapes all github usernames in the CHANGELOG.md file by adding
  > a backtick before and after the username.
  >
  > e.g.:**Before**
  >
  > ```
  > 1dc18bf (calendar) Add width and height functions by joshka in #2198
  > ```
  >
  > **After**
  >
  > ```
  > 1dc18bf (calendar) Add width and height functions by `@joshka` in #2198
  > ```
  >
  > This change should prevent unnecessary tags in PRs and forks, at least
  > until the next release is made with git cliff changes from release-plz

- [0031fc6](https://github.com/ratatui/ratatui/commit/0031fc6b1ac93045aef041d26cf6dea1978d80fe) *(uncategorized)* Remove `@` sign from github release and PR by kdheepak in [#2353](https://github.com/ratatui/ratatui/pull/2353)

  > Previous PR (https://github.com/ratatui/ratatui/pull/2336) didn't solve
  > the problem, and everyone still seems to be getting notifications (e.g.
  > https://github.com/ratatui/ratatui/pull/2348).
  >
  > This PR removes the `@` for GitHub usernames in the autogenerated PR
  > body by `release-plz`.
  >
  > ```tera
  > {{ changelog | replace(from=" by ", to=" by ") }}
  > ```
  >
  > The motivation behind this is that GitHub mentions in PR descriptions
  > trigger notifications for every contributor for every release because
  > their username is part of the changelog.
  >
  > With this change, in GitHub PR descriptions the changelog will change
  > like so:
  >
  > **Before**
  >
  > ```
  > 1dc18bf (calendar) Add width and height functions by joshka in #2198
  > ```
  >
  > **After**
  >
  > ```
  > 1dc18bf (calendar) Add width and height functions by joshka in #2198
  > ```

- [ab5ad3f](https://github.com/ratatui/ratatui/commit/ab5ad3fc7ceb31b11ca9100a8d52dcb181e46b00) *(uncategorized)* Escape username using backticks in changelog by kdheepak in [#2336](https://github.com/ratatui/ratatui/pull/2336)

  > The motivation behind this is that GitHub mentions in PR descriptions trigger notifications for every contributor for every release because their username is part of the changelog.

### New Contributors

* @musjj made their first contribution in [#2566](https://github.com/ratatui/ratatui/pull/2566)
* @adv0r made their first contribution in [#2578](https://github.com/ratatui/ratatui/pull/2578)
* @fallintoplace made their first contribution in [#2550](https://github.com/ratatui/ratatui/pull/2550)
* @Zacxxx made their first contribution in [#2555](https://github.com/ratatui/ratatui/pull/2555)
* @lphuc2250gma made their first contribution in [#2535](https://github.com/ratatui/ratatui/pull/2535)
* @lazo4 made their first contribution in [#2474](https://github.com/ratatui/ratatui/pull/2474)
* @Metbcy made their first contribution in [#2520](https://github.com/ratatui/ratatui/pull/2520)
* @bananaofhappiness made their first contribution in [#2426](https://github.com/ratatui/ratatui/pull/2426)
* @sermuns made their first contribution in [#2469](https://github.com/ratatui/ratatui/pull/2469)
* @ramadhan-dev-bright made their first contribution in [#2473](https://github.com/ratatui/ratatui/pull/2473)
* @junkdog made their first contribution in [#2437](https://github.com/ratatui/ratatui/pull/2437)
* @december1981 made their first contribution in [#2460](https://github.com/ratatui/ratatui/pull/2460)
* @7Bpencil made their first contribution in [#2369](https://github.com/ratatui/ratatui/pull/2369)
* @JayanAXHF made their first contribution in [#2438](https://github.com/ratatui/ratatui/pull/2438)
* @Logan-Ruf made their first contribution in [#2435](https://github.com/ratatui/ratatui/pull/2435)
* @singhh-piyush made their first contribution in [#2423](https://github.com/ratatui/ratatui/pull/2423)
* @gcavelier made their first contribution in [#2308](https://github.com/ratatui/ratatui/pull/2308)
* @ffex made their first contribution in [#2211](https://github.com/ratatui/ratatui/pull/2211)
* @BenFradet made their first contribution in [#2356](https://github.com/ratatui/ratatui/pull/2356)
* @wyvernbw made their first contribution in [#2355](https://github.com/ratatui/ratatui/pull/2355)
* @NoOPeEKS made their first contribution in [#2371](https://github.com/ratatui/ratatui/pull/2371)
* @alabhyajindal made their first contribution in [#2409](https://github.com/ratatui/ratatui/pull/2409)
* @martinvonz made their first contribution in [#2370](https://github.com/ratatui/ratatui/pull/2370)
* @jakobhellermann made their first contribution in [#2350](https://github.com/ratatui/ratatui/pull/2350)
* @floor-licker made their first contribution in [#2322](https://github.com/ratatui/ratatui/pull/2322)
* @C-Loftus made their first contribution in [#2324](https://github.com/ratatui/ratatui/pull/2324)
* @0xferrous made their first contribution in [#2323](https://github.com/ratatui/ratatui/pull/2323)
* @homebrewmellow made their first contribution in [#2314](https://github.com/ratatui/ratatui/pull/2314)
* @karkhaz made their first contribution in [#2150](https://github.com/ratatui/ratatui/pull/2150)