From b0b842f83496d477ed176ce704096ba40c67e91e Mon Sep 17 00:00:00 2001 From: rustbasic <127506429+rustbasic@users.noreply.github.com> Date: Wed, 24 Jan 2024 18:53:27 +0900 Subject: [PATCH 1/3] Fix: panic when pressing Shift + TAB in a TextEdit panic when pressing Shift + TAB in a TextEdit #3846 rev() is panic with UTF8 Not byte_index It's char_index ( for UTF8 ) --- crates/egui/src/widgets/text_edit/text_buffer.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/egui/src/widgets/text_edit/text_buffer.rs b/crates/egui/src/widgets/text_edit/text_buffer.rs index f28878a1dd3..e70ce695af9 100644 --- a/crates/egui/src/widgets/text_edit/text_buffer.rs +++ b/crates/egui/src/widgets/text_edit/text_buffer.rs @@ -89,10 +89,12 @@ pub trait TextBuffer { fn decrease_indentation(&mut self, ccursor: &mut CCursor) { let line_start = find_line_start(self.as_str(), *ccursor); - let remove_len = if self.as_str()[line_start.index..].starts_with('\t') { + let remove_len = if self.as_str().chars().nth(line_start.index) == Some('\t') { Some(1) - } else if self.as_str()[line_start.index..] + } else if self + .as_str() .chars() + .skip(line_start.index) .take(TAB_SIZE) .all(|c| c == ' ') { From 3b8fe476163469de446cb27aac940e180295b5ad Mon Sep 17 00:00:00 2001 From: rustbasic <127506429+rustbasic@users.noreply.github.com> Date: Wed, 24 Jan 2024 19:12:21 +0900 Subject: [PATCH 2/3] Update text_cursor_state.rs --- .../src/text_selection/text_cursor_state.rs | 42 +++++++++++++++---- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/crates/egui/src/text_selection/text_cursor_state.rs b/crates/egui/src/text_selection/text_cursor_state.rs index d8adfb83376..a3d59274d17 100644 --- a/crates/egui/src/text_selection/text_cursor_state.rs +++ b/crates/egui/src/text_selection/text_cursor_state.rs @@ -300,18 +300,42 @@ pub fn find_line_start(text: &str, current_index: CCursor) -> CCursor { // number of multi byte chars. // We need to know the char index to be able to correctly set the cursor // later. - let chars_count = text.chars().count(); + let mut char_line_indexes: Vec = create_char_line_indexes(text); + let line_start_index = get_line_start_index(&mut char_line_indexes, current_index.index); - let position = text - .chars() - .rev() - .skip(chars_count - current_index.index) - .position(|x| x == '\n'); + CCursor::new(line_start_index) +} + +pub fn create_char_line_indexes(text: &str) -> Vec { + let mut line_indexes = vec![0]; - match position { - Some(pos) => CCursor::new(current_index.index - pos), - None => CCursor::new(0), + let mut count = 0; + for (_i, c) in text.chars().enumerate() { + count += 1; + if c == '\n' { + line_indexes.push(count); + } } + line_indexes.push(count); + + line_indexes +} + +pub fn get_line_start_index(line_indexes: &mut [usize], index: usize) -> usize { + let (_current_line, line_start) = get_line_and_start_index(line_indexes, index); + line_start +} + +pub fn get_line_and_start_index(line_indexes: &mut [usize], index: usize) -> (usize, usize) { + let mut current_line = 1; + for (i, line_start) in line_indexes.iter().enumerate() { + current_line = i; + if *line_start > index { + break; + } + } + + (current_line, line_indexes[current_line - 1]) } pub fn byte_index_from_char_index(s: &str, char_index: usize) -> usize { From a493bf40b0026cc9c47e372577a49eebda8d264f Mon Sep 17 00:00:00 2001 From: rustbasic <127506429+rustbasic@users.noreply.github.com> Date: Fri, 26 Jan 2024 10:40:27 +0900 Subject: [PATCH 3/3] Update text_cursor_state.rs --- crates/egui/src/text_selection/text_cursor_state.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/egui/src/text_selection/text_cursor_state.rs b/crates/egui/src/text_selection/text_cursor_state.rs index c4423a4aef6..ed51fde3153 100644 --- a/crates/egui/src/text_selection/text_cursor_state.rs +++ b/crates/egui/src/text_selection/text_cursor_state.rs @@ -312,7 +312,7 @@ pub fn create_char_line_indexes(text: &str) -> Vec { let mut line_indexes = vec![0]; let mut count = 0; - for (_i, c) in text.chars().enumerate() { + for c in text.chars() { count += 1; if c == '\n' { line_indexes.push(count);