use crate::app::state::TextEditor; use crate::io; use eframe::egui; #[derive(Debug, Clone, Copy)] enum ShortcutAction { NewFile, OpenFile, SaveFile, SaveAsFile, NewTab, CloseTab, ToggleLineNumbers, ToggleLineSide, ToggleWordWrap, ToggleAutoHideToolbar, ToggleFind, FocusFind, NextTab, PrevTab, PageUp, PageDown, ZoomIn, ZoomOut, GlobalZoomIn, GlobalZoomOut, ResetZoom, Escape, Preferences, ToggleVimMode, } type ShortcutDefinition = (egui::Modifiers, egui::Key, ShortcutAction); fn get_shortcuts() -> Vec { vec![ (egui::Modifiers::CTRL, egui::Key::N, ShortcutAction::NewFile), ( egui::Modifiers::CTRL, egui::Key::O, ShortcutAction::OpenFile, ), ( egui::Modifiers::CTRL | egui::Modifiers::SHIFT, egui::Key::S, ShortcutAction::SaveAsFile, ), ( egui::Modifiers::CTRL, egui::Key::S, ShortcutAction::SaveFile, ), (egui::Modifiers::CTRL, egui::Key::T, ShortcutAction::NewTab), ( egui::Modifiers::CTRL, egui::Key::W, ShortcutAction::CloseTab, ), ( egui::Modifiers::CTRL | egui::Modifiers::SHIFT, egui::Key::F, ShortcutAction::FocusFind, ), ( egui::Modifiers::CTRL, egui::Key::F, ShortcutAction::ToggleFind, ), ( egui::Modifiers::CTRL | egui::Modifiers::SHIFT, egui::Key::L, ShortcutAction::ToggleLineSide, ), ( egui::Modifiers::CTRL, egui::Key::L, ShortcutAction::ToggleLineNumbers, ), ( egui::Modifiers::CTRL, egui::Key::K, ShortcutAction::ToggleWordWrap, ), ( egui::Modifiers::CTRL, egui::Key::H, ShortcutAction::ToggleAutoHideToolbar, ), ( egui::Modifiers::CTRL | egui::Modifiers::SHIFT, egui::Key::Tab, ShortcutAction::PrevTab, ), ( egui::Modifiers::CTRL, egui::Key::Tab, ShortcutAction::NextTab, ), ( egui::Modifiers::NONE, egui::Key::PageUp, ShortcutAction::PageUp, ), ( egui::Modifiers::NONE, egui::Key::PageDown, ShortcutAction::PageDown, ), ( egui::Modifiers::CTRL, egui::Key::Equals, ShortcutAction::ZoomIn, ), ( egui::Modifiers::CTRL | egui::Modifiers::SHIFT, egui::Key::Minus, ShortcutAction::GlobalZoomOut, ), ( egui::Modifiers::CTRL, egui::Key::Minus, ShortcutAction::ZoomOut, ), ( egui::Modifiers::CTRL, egui::Key::Plus, ShortcutAction::GlobalZoomIn, ), ( egui::Modifiers::CTRL, egui::Key::Num0, ShortcutAction::ResetZoom, ), ( egui::Modifiers::CTRL, egui::Key::P, ShortcutAction::Preferences, ), ( egui::Modifiers::CTRL | egui::Modifiers::SHIFT, egui::Key::Period, ShortcutAction::ToggleVimMode, ), ( egui::Modifiers::NONE, egui::Key::Escape, ShortcutAction::Escape, ), ] } fn execute_action(action: ShortcutAction, editor: &mut TextEditor, _ctx: &egui::Context) -> bool { match action { ShortcutAction::NewFile => { io::new_file(editor); false } ShortcutAction::OpenFile => { io::open_file(editor); false } ShortcutAction::SaveFile => { io::save_file(editor); false } ShortcutAction::SaveAsFile => { io::save_as_file(editor); false } ShortcutAction::NewTab => { editor.add_new_tab(); false } ShortcutAction::CloseTab => { if editor.tabs.len() > 1 { if let Some(current_tab) = editor.get_active_tab() { if current_tab.is_modified { editor.pending_unsaved_action = Some( super::state::UnsavedAction::CloseTab(editor.active_tab_index), ); } else { editor.close_tab(editor.active_tab_index); } } } false } ShortcutAction::ToggleLineNumbers => { editor.show_line_numbers = !editor.show_line_numbers; editor.save_config(); false } ShortcutAction::ToggleLineSide => { editor.line_side = !editor.line_side; editor.save_config(); false } ShortcutAction::ToggleWordWrap => { editor.word_wrap = !editor.word_wrap; editor.save_config(); false } ShortcutAction::ToggleAutoHideToolbar => { editor.auto_hide_toolbar = !editor.auto_hide_toolbar; editor.save_config(); false } ShortcutAction::NextTab => { let next_tab_index = editor.active_tab_index + 1; if next_tab_index < editor.tabs.len() { editor.switch_to_tab(next_tab_index); } else { editor.switch_to_tab(0); } false } ShortcutAction::PrevTab => { if editor.active_tab_index == 0 { editor.switch_to_tab(editor.tabs.len() - 1); } else { editor.switch_to_tab(editor.active_tab_index - 1); } false } ShortcutAction::PageUp => false, ShortcutAction::PageDown => false, ShortcutAction::ZoomIn => { editor.font_size += 1.0; true } ShortcutAction::ZoomOut => { editor.font_size -= 1.0; true } ShortcutAction::GlobalZoomIn => { editor.zoom_factor += 0.1; false } ShortcutAction::GlobalZoomOut => { editor.zoom_factor -= 0.1; if editor.zoom_factor < 0.1 { editor.zoom_factor = 0.1; } false } ShortcutAction::ResetZoom => { editor.zoom_factor = 1.0; false } ShortcutAction::ToggleVimMode => { // editor.vim_mode = !editor.vim_mode; false } ShortcutAction::Escape => { editor.show_about = false; editor.show_shortcuts = false; if editor.show_find { editor.should_select_current_match = true; } editor.show_find = false; editor.show_preferences = false; editor.pending_unsaved_action = None; false } ShortcutAction::ToggleFind => { editor.show_find = !editor.show_find; if editor.show_find && !editor.find_query.is_empty() { editor.update_find_matches(); } false } ShortcutAction::FocusFind => { if editor.show_find { editor.focus_find = true; } false } ShortcutAction::Preferences => { editor.show_preferences = !editor.show_preferences; false } } } pub fn handle(editor: &mut TextEditor, ctx: &egui::Context) { let mut font_zoom_occurred = false; let mut global_zoom_occurred = false; ctx.input_mut(|i| { for (modifiers, key, action) in get_shortcuts() { if i.consume_key(modifiers, key) { match action { ShortcutAction::ZoomIn | ShortcutAction::ZoomOut => { font_zoom_occurred = execute_action(action, editor, ctx); } ShortcutAction::GlobalZoomIn | ShortcutAction::GlobalZoomOut | ShortcutAction::ResetZoom => { execute_action(action, editor, ctx); global_zoom_occurred = true; } _ => { execute_action(action, editor, ctx); } } break; } } }); if font_zoom_occurred { editor.apply_font_settings(ctx); } if global_zoom_occurred { ctx.set_zoom_factor(editor.zoom_factor); } if editor.should_select_current_match { editor.select_current_match(ctx); editor.should_select_current_match = false; } }