From ddcaf3dccd7a817b6307bff61a4604c4dff27621 Mon Sep 17 00:00:00 2001 From: Jeremy Rose <172423086+nornagon-openai@users.noreply.github.com> Date: Thu, 9 Oct 2025 15:07:04 -0700 Subject: [PATCH] tui: fix crash when alt+bksp past unicode nbsp (#5016) notably, screenshot filenames on macOS by default contain U+202F right before the "AM/PM" part of the filename. --- codex-rs/tui/src/bottom_pane/textarea.rs | 35 +++++++++++++++++------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/codex-rs/tui/src/bottom_pane/textarea.rs b/codex-rs/tui/src/bottom_pane/textarea.rs index 269fa345..66877939 100644 --- a/codex-rs/tui/src/bottom_pane/textarea.rs +++ b/codex-rs/tui/src/bottom_pane/textarea.rs @@ -799,16 +799,22 @@ impl TextArea { } pub(crate) fn beginning_of_previous_word(&self) -> usize { - if let Some(first_non_ws) = self.text[..self.cursor_pos].rfind(|c: char| !c.is_whitespace()) - { - let candidate = self.text[..first_non_ws] - .rfind(|c: char| c.is_whitespace()) - .map(|i| i + 1) - .unwrap_or(0); - self.adjust_pos_out_of_elements(candidate, true) - } else { - 0 - } + let prefix = &self.text[..self.cursor_pos]; + let Some((first_non_ws_idx, _)) = prefix + .char_indices() + .rev() + .find(|&(_, ch)| !ch.is_whitespace()) + else { + return 0; + }; + let before = &prefix[..first_non_ws_idx]; + let candidate = before + .char_indices() + .rev() + .find(|&(_, ch)| ch.is_whitespace()) + .map(|(idx, ch)| idx + ch.len_utf8()) + .unwrap_or(0); + self.adjust_pos_out_of_elements(candidate, true) } pub(crate) fn end_of_next_word(&self) -> usize { @@ -1262,6 +1268,15 @@ mod tests { assert_eq!(t.cursor(), 6); } + #[test] + fn delete_backward_word_handles_narrow_no_break_space() { + let mut t = ta_with("32\u{202F}AM"); + t.set_cursor(t.text().len()); + t.input(KeyEvent::new(KeyCode::Backspace, KeyModifiers::ALT)); + pretty_assertions::assert_eq!(t.text(), "32\u{202F}"); + pretty_assertions::assert_eq!(t.cursor(), t.text().len()); + } + #[test] fn delete_forward_word_with_without_alt_modifier() { let mut t = ta_with("hello world");