From ee040656a1784061262b82309c75c59b8687a13a Mon Sep 17 00:00:00 2001 From: Lstarsky0 <59827030+Lstarsky0@users.noreply.github.com> Date: Mon, 19 Oct 2026 12:12:16 +0800 Subject: [PATCH 1/2] fix(tui): end a clipped /feedback description at a word, with an ellipsis MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The /feedback picker paints each option's description as is and lets the card edge cut it, so below about 80 columns the rows end mid-word: "Report a proble", "Suggest an", "Rev" at 40x12, and "Review the security pol" at 60x16. Nothing marks the text as cut. The /mode picker had the same problem and truncates its hints with semantic_truncate at the width left after the prefix. Do the same here: measure the number, label and gap actually painted, and truncate the description to the rest. At 40x12 the rows now read "Report a…", "Suggest…" and "Re…", and at 60x16 "Review the security…". Where the descriptions fit, as at 80x24 and 100x32, the picker renders as before. Signed-off-by: Lstarsky0 <59827030+Lstarsky0@users.noreply.github.com> --- crates/tui/src/tui/feedback_picker.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/crates/tui/src/tui/feedback_picker.rs b/crates/tui/src/tui/feedback_picker.rs index 9724ec32c4..0879951a59 100644 --- a/crates/tui/src/tui/feedback_picker.rs +++ b/crates/tui/src/tui/feedback_picker.rs @@ -17,6 +17,7 @@ use crate::tui::views::{ centered_modal_area, render_modal_footer, render_modal_surface, }; use codewhale_palette as palette; +use unicode_width::UnicodeWidthStr; #[derive(Debug, Clone, Copy)] struct FeedbackOption { @@ -183,12 +184,18 @@ impl ModalView for FeedbackPickerView { Style::default().fg(palette::TEXT_MUTED) }; let pointer = crate::tui::glyphs::selection_marker(is_selected); + let lead = format!("{pointer} {}. ", option.number); + let description_width = usize::from(content.width).saturating_sub( + UnicodeWidthStr::width(lead.as_str()) + UnicodeWidthStr::width(option.label) + 4, + ); + let description = + crate::tui::ui_text::semantic_truncate(option.description, description_width); lines.push(Line::from(vec![ - Span::styled(format!("{pointer} {}. ", option.number), row_style), + Span::styled(lead, row_style), Span::styled(option.label, row_style), Span::raw(" "), - Span::styled(option.description, desc_style), + Span::styled(description, desc_style), ])); } From c4856f9a8d231e63180cf5b8b7359d93578998e8 Mon Sep 17 00:00:00 2001 From: Lstarsky0 <59827030+Lstarsky0@users.noreply.github.com> Date: Tue, 20 Oct 2026 01:13:07 +0800 Subject: [PATCH 2/2] fix(tui): keep the /feedback cut visible in ASCII-safe mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With CODEWHALE_ASCII_SAFE=1 the backend maps "…" to a single "." on draw, so a clipped description such as "Review the security…" showed as "Review the security.", which reads as a finished sentence. codewhale_ratatui::text::truncate_words is the same word-boundary truncation and spends "..." in ASCII-safe mode, so use it here. Outside ASCII-safe mode the rows render exactly as before; at 60x16 in ASCII mode the third row now reads "Review the security...". Signed-off-by: Lstarsky0 <59827030+Lstarsky0@users.noreply.github.com> --- crates/tui/src/tui/feedback_picker.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/crates/tui/src/tui/feedback_picker.rs b/crates/tui/src/tui/feedback_picker.rs index 0879951a59..31b2b9eb01 100644 --- a/crates/tui/src/tui/feedback_picker.rs +++ b/crates/tui/src/tui/feedback_picker.rs @@ -188,8 +188,11 @@ impl ModalView for FeedbackPickerView { let description_width = usize::from(content.width).saturating_sub( UnicodeWidthStr::width(lead.as_str()) + UnicodeWidthStr::width(option.label) + 4, ); - let description = - crate::tui::ui_text::semantic_truncate(option.description, description_width); + let description = codewhale_ratatui::text::truncate_words( + option.description, + description_width, + crate::tui::color_compat::ascii_safe_enabled(), + ); lines.push(Line::from(vec![ Span::styled(lead, row_style),