Find and Replace #5

Merged
candle merged 9 commits from master into release 2025-07-16 21:36:23 +00:00
Showing only changes of commit 48cfcb9997 - Show all commits

View File

@ -2,6 +2,15 @@ use super::editor::{TextEditor, TextProcessingResult};
use eframe::egui; use eframe::egui;
impl TextEditor { impl TextEditor {
fn safe_slice_to_pos(content: &str, pos: usize) -> &str {
let pos = pos.min(content.len());
let mut boundary_pos = pos;
while boundary_pos > 0 && !content.is_char_boundary(boundary_pos) {
boundary_pos -= 1;
}
&content[..boundary_pos]
}
pub fn process_text_for_rendering(&mut self, content: &str, ui: &egui::Ui) { pub fn process_text_for_rendering(&mut self, content: &str, ui: &egui::Ui) {
let line_count = content.bytes().filter(|&b| b == b'\n').count() + 1; let line_count = content.bytes().filter(|&b| b == b'\n').count() + 1;
@ -119,12 +128,12 @@ impl TextEditor {
old_cursor_pos: usize, old_cursor_pos: usize,
new_cursor_pos: usize, new_cursor_pos: usize,
) -> isize { ) -> isize {
let old_newlines = old_content[..old_cursor_pos.min(old_content.len())] let old_newlines = Self::safe_slice_to_pos(old_content, old_cursor_pos)
.bytes() .bytes()
.filter(|&b| b == b'\n') .filter(|&b| b == b'\n')
.count(); .count();
let new_newlines = new_content[..new_cursor_pos.min(new_content.len())] let new_newlines = Self::safe_slice_to_pos(new_content, new_cursor_pos)
.bytes() .bytes()
.filter(|&b| b == b'\n') .filter(|&b| b == b'\n')
.count(); .count();
@ -190,11 +199,11 @@ impl TextEditor {
let mut current_result = self.get_text_processing_result(); let mut current_result = self.get_text_processing_result();
current_result.line_count += newlines_added; current_result.line_count += newlines_added;
let addition_start_line = old_content[..added_start] let addition_start_line = Self::safe_slice_to_pos(old_content, added_start)
.bytes() .bytes()
.filter(|&b| b == b'\n') .filter(|&b| b == b'\n')
.count(); .count();
let addition_end_line = old_content[..added_end.min(old_content.len())] let addition_end_line = Self::safe_slice_to_pos(old_content, added_end)
.bytes() .bytes()
.filter(|&b| b == b'\n') .filter(|&b| b == b'\n')
.count(); .count();
@ -261,11 +270,11 @@ impl TextEditor {
let mut current_result = self.get_text_processing_result(); let mut current_result = self.get_text_processing_result();
current_result.line_count = current_result.line_count.saturating_sub(newlines_removed); current_result.line_count = current_result.line_count.saturating_sub(newlines_removed);
let removal_start_line = old_content[..removed_start] let removal_start_line = Self::safe_slice_to_pos(old_content, removed_start)
.bytes() .bytes()
.filter(|&b| b == b'\n') .filter(|&b| b == b'\n')
.count(); .count();
let removal_end_line = old_content[..removed_end] let removal_end_line = Self::safe_slice_to_pos(old_content, removed_end)
.bytes() .bytes()
.filter(|&b| b == b'\n') .filter(|&b| b == b'\n')
.count(); .count();
@ -304,18 +313,26 @@ impl TextEditor {
fn extract_current_line(&self, content: &str, cursor_pos: usize) -> String { fn extract_current_line(&self, content: &str, cursor_pos: usize) -> String {
let bytes = content.as_bytes(); let bytes = content.as_bytes();
let safe_cursor_pos = cursor_pos.min(bytes.len());
let mut line_start = cursor_pos; let mut line_start = safe_cursor_pos;
while line_start > 0 && bytes[line_start - 1] != b'\n' { while line_start > 0 && bytes[line_start - 1] != b'\n' {
line_start -= 1; line_start -= 1;
} }
let mut line_end = cursor_pos; let mut line_end = safe_cursor_pos;
while line_end < bytes.len() && bytes[line_end] != b'\n' { while line_end < bytes.len() && bytes[line_end] != b'\n' {
line_end += 1; line_end += 1;
} }
content[line_start..line_end].to_string() let line_start_boundary = line_start;
let line_end_boundary = line_end;
if content.is_char_boundary(line_start_boundary) && content.is_char_boundary(line_end_boundary) {
content[line_start_boundary..line_end_boundary].to_string()
} else {
Self::safe_slice_to_pos(content, line_end_boundary)[line_start_boundary..].to_string()
}
} }
fn update_line_if_longer( fn update_line_if_longer(