From e45329a689e522dbc22d15f681917284da600e3f Mon Sep 17 00:00:00 2001 From: June Kim Date: Sat, 9 May 2026 10:08:43 -0700 Subject: [PATCH] fix: use UnicodeWidthChar and buffer-relative bounds for wide-char reset Address review feedback: - Use UnicodeWidthChar on the first char instead of UnicodeWidthStr on the whole symbol string, which is semantically cleaner for single-cell wide character detection. - Check against buf.area.x instead of 0, so the guard is correct even when the buffer origin is non-zero. --- yazi-widgets/src/clear.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/yazi-widgets/src/clear.rs b/yazi-widgets/src/clear.rs index fb366809..cc2920d3 100644 --- a/yazi-widgets/src/clear.rs +++ b/yazi-widgets/src/clear.rs @@ -1,7 +1,7 @@ use std::sync::atomic::{AtomicBool, Ordering}; use ratatui::{buffer::Buffer, layout::Rect, widgets::Widget}; -use unicode_width::UnicodeWidthStr; +use unicode_width::UnicodeWidthChar; use yazi_adapter::ADAPTOR; pub static COLLISION: AtomicBool = AtomicBool::new(false); @@ -14,13 +14,18 @@ impl Widget for Clear { where Self: Sized, { - // Reset any double-width characters just outside the left edge whose - // second half would overlap into the cleared area, which would otherwise - // obscure the border drawn at area.x. - if area.x > 0 { + // Reset double-width characters straddling the overlay boundary. + // + // A wide char (e.g. CJK) just outside the left edge occupies two + // columns; its second half falls on the border column, and the + // terminal renders the wide char over the border. Invalidating + // the owning cell is the correct fix — terminals cannot render + // half a wide glyph. + if area.x > buf.area.x { let left = area.x - 1; for y in area.top()..area.bottom() { - if buf[(left, y)].symbol().width() > 1 { + let ch = buf[(left, y)].symbol().chars().next(); + if ch.is_some_and(|c| c.width().unwrap_or(0) > 1) { buf[(left, y)].reset(); } }