Find and Replace #5
@ -149,7 +149,7 @@ fn get_shortcuts() -> Vec<ShortcutDefinition> {
|
||||
]
|
||||
}
|
||||
|
||||
fn execute_action(action: ShortcutAction, editor: &mut TextEditor, ctx: &egui::Context) -> bool {
|
||||
fn execute_action(action: ShortcutAction, editor: &mut TextEditor) -> bool {
|
||||
match action {
|
||||
ShortcutAction::NewFile => {
|
||||
io::new_file(editor);
|
||||
@ -291,16 +291,16 @@ pub fn handle(editor: &mut TextEditor, ctx: &egui::Context) {
|
||||
if i.consume_key(modifiers, key) {
|
||||
match action {
|
||||
ShortcutAction::ZoomIn | ShortcutAction::ZoomOut => {
|
||||
font_zoom_occurred = execute_action(action, editor, ctx);
|
||||
font_zoom_occurred = execute_action(action, editor);
|
||||
}
|
||||
ShortcutAction::GlobalZoomIn
|
||||
| ShortcutAction::GlobalZoomOut
|
||||
| ShortcutAction::ResetZoom => {
|
||||
execute_action(action, editor, ctx);
|
||||
execute_action(action, editor);
|
||||
global_zoom_occurred = true;
|
||||
}
|
||||
_ => {
|
||||
execute_action(action, editor, ctx);
|
||||
execute_action(action, editor);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -39,12 +39,12 @@ impl TextEditor {
|
||||
}
|
||||
&search_content[start..]
|
||||
};
|
||||
|
||||
|
||||
if let Some(pos) = search_slice.find(&query) {
|
||||
let absolute_pos = start + pos;
|
||||
self.find_matches
|
||||
.push((absolute_pos, absolute_pos + query.len()));
|
||||
|
||||
|
||||
// Advance to next valid character boundary instead of just +1
|
||||
start = absolute_pos + 1;
|
||||
while start < search_content.len() && !search_content.is_char_boundary(start) {
|
||||
@ -154,9 +154,10 @@ impl TextEditor {
|
||||
self.update_find_matches();
|
||||
|
||||
if let Some(active_tab) = self.get_active_tab() {
|
||||
let replacement_end_char = Self::safe_slice_to_pos(&active_tab.content, replacement_end)
|
||||
.chars()
|
||||
.count();
|
||||
let replacement_end_char =
|
||||
Self::safe_slice_to_pos(&active_tab.content, replacement_end)
|
||||
.chars()
|
||||
.count();
|
||||
|
||||
let text_edit_id = egui::Id::new("main_text_editor");
|
||||
if let Some(mut state) = egui::TextEdit::load_state(ctx, text_edit_id) {
|
||||
|
||||
@ -35,13 +35,17 @@ impl TextEditor {
|
||||
let (files_to_list, title, confirmation_text, button_text, action) =
|
||||
if let Some(action) = &self.pending_unsaved_action {
|
||||
match action {
|
||||
UnsavedAction::Quit => (
|
||||
self.get_unsaved_files(),
|
||||
"Unsaved Changes".to_string(),
|
||||
"You have unsaved changes.".to_string(),
|
||||
"Quit Without Saving".to_string(),
|
||||
action.to_owned(),
|
||||
),
|
||||
UnsavedAction::Quit => {
|
||||
let files = self.get_unsaved_files();
|
||||
let file_plural = if files.len() > 1 { "s" } else { "" };
|
||||
(
|
||||
files,
|
||||
"Unsaved Changes".to_string(),
|
||||
format!("File{file_plural} with unsaved changes:"),
|
||||
"Quit Without Saving".to_string(),
|
||||
action.to_owned(),
|
||||
)
|
||||
}
|
||||
UnsavedAction::CloseTab(tab_index) => {
|
||||
let file_name = self
|
||||
.tabs
|
||||
@ -50,7 +54,7 @@ impl TextEditor {
|
||||
(
|
||||
vec![file_name],
|
||||
"Unsaved Changes".to_string(),
|
||||
"The file has unsaved changes.".to_string(),
|
||||
"This file has unsaved changes:".to_string(),
|
||||
"Close Without Saving".to_string(),
|
||||
action.to_owned(),
|
||||
)
|
||||
|
||||
@ -325,8 +325,10 @@ impl TextEditor {
|
||||
|
||||
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) {
|
||||
|
||||
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()
|
||||
|
||||
10
src/io.rs
10
src/io.rs
@ -24,7 +24,10 @@ pub(crate) fn open_file(app: &mut TextEditor) {
|
||||
|
||||
if should_replace_current_tab {
|
||||
if let Some(active_tab) = app.get_active_tab_mut() {
|
||||
let title = path.file_name().and_then(|n| n.to_str()).unwrap_or("Untitled");
|
||||
let title = path
|
||||
.file_name()
|
||||
.and_then(|n| n.to_str())
|
||||
.unwrap_or("Untitled");
|
||||
active_tab.content = content;
|
||||
active_tab.file_path = Some(path.to_path_buf());
|
||||
active_tab.title = title.to_string();
|
||||
@ -71,7 +74,10 @@ pub(crate) fn save_to_path(app: &mut TextEditor, path: PathBuf) {
|
||||
if let Some(active_tab) = app.get_active_tab_mut() {
|
||||
match fs::write(&path, &active_tab.content) {
|
||||
Ok(()) => {
|
||||
let title = path.file_name().and_then(|n| n.to_str()).unwrap_or("Untitled");
|
||||
let title = path
|
||||
.file_name()
|
||||
.and_then(|n| n.to_str())
|
||||
.unwrap_or("Untitled");
|
||||
active_tab.file_path = Some(path.to_path_buf());
|
||||
active_tab.title = title.to_string();
|
||||
active_tab.mark_as_saved();
|
||||
|
||||
@ -62,7 +62,9 @@ fn draw_single_highlight(
|
||||
}
|
||||
|
||||
let line_start_byte_pos = text_up_to_start.rfind('\n').map(|pos| pos + 1).unwrap_or(0);
|
||||
let line_start_char_pos = safe_slice_to_pos(content, line_start_byte_pos).chars().count();
|
||||
let line_start_char_pos = safe_slice_to_pos(content, line_start_byte_pos)
|
||||
.chars()
|
||||
.count();
|
||||
let start_char_pos = safe_slice_to_pos(content, start_pos).chars().count();
|
||||
let start_col = start_char_pos - line_start_char_pos;
|
||||
|
||||
|
||||
@ -143,7 +143,8 @@ pub(crate) fn preferences_window(app: &mut TextEditor, ctx: &egui::Context) {
|
||||
.font(preview_font.to_owned()),
|
||||
);
|
||||
ui.label(
|
||||
egui::RichText::new("1234567890 !@#$%^&*()").font(preview_font.to_owned()),
|
||||
egui::RichText::new("1234567890 !@#$%^&*()")
|
||||
.font(preview_font.to_owned()),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user