Skip to content

Commit ddcaf3d

Browse files
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.
1 parent 56296ca commit ddcaf3d

File tree

1 file changed

+25
-10
lines changed

1 file changed

+25
-10
lines changed

codex-rs/tui/src/bottom_pane/textarea.rs

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -799,16 +799,22 @@ impl TextArea {
799799
}
800800

801801
pub(crate) fn beginning_of_previous_word(&self) -> usize {
802-
if let Some(first_non_ws) = self.text[..self.cursor_pos].rfind(|c: char| !c.is_whitespace())
803-
{
804-
let candidate = self.text[..first_non_ws]
805-
.rfind(|c: char| c.is_whitespace())
806-
.map(|i| i + 1)
807-
.unwrap_or(0);
808-
self.adjust_pos_out_of_elements(candidate, true)
809-
} else {
810-
0
811-
}
802+
let prefix = &self.text[..self.cursor_pos];
803+
let Some((first_non_ws_idx, _)) = prefix
804+
.char_indices()
805+
.rev()
806+
.find(|&(_, ch)| !ch.is_whitespace())
807+
else {
808+
return 0;
809+
};
810+
let before = &prefix[..first_non_ws_idx];
811+
let candidate = before
812+
.char_indices()
813+
.rev()
814+
.find(|&(_, ch)| ch.is_whitespace())
815+
.map(|(idx, ch)| idx + ch.len_utf8())
816+
.unwrap_or(0);
817+
self.adjust_pos_out_of_elements(candidate, true)
812818
}
813819

814820
pub(crate) fn end_of_next_word(&self) -> usize {
@@ -1262,6 +1268,15 @@ mod tests {
12621268
assert_eq!(t.cursor(), 6);
12631269
}
12641270

1271+
#[test]
1272+
fn delete_backward_word_handles_narrow_no_break_space() {
1273+
let mut t = ta_with("32\u{202F}AM");
1274+
t.set_cursor(t.text().len());
1275+
t.input(KeyEvent::new(KeyCode::Backspace, KeyModifiers::ALT));
1276+
pretty_assertions::assert_eq!(t.text(), "32\u{202F}");
1277+
pretty_assertions::assert_eq!(t.cursor(), t.text().len());
1278+
}
1279+
12651280
#[test]
12661281
fn delete_forward_word_with_without_alt_modifier() {
12671282
let mut t = ta_with("hello world");

0 commit comments

Comments
 (0)