diff --git a/canvas/Cargo.toml b/canvas/Cargo.toml index 31199b1..2f8b33b 100644 --- a/canvas/Cargo.toml +++ b/canvas/Cargo.toml @@ -91,10 +91,10 @@ required-features = ["gui", "computed"] [[example]] name = "textarea_vim" -required-features = ["gui", "cursor-style", "textarea"] +required-features = ["gui", "cursor-style", "textarea", "textmode-vim"] path = "examples/textarea_vim.rs" [[example]] name = "textarea_normal" -required-features = ["gui", "cursor-style", "textarea"] +required-features = ["gui", "cursor-style", "textarea", "textmode-normal"] path = "examples/textarea_normal.rs" diff --git a/canvas/examples/textarea_normal.rs b/canvas/examples/textarea_normal.rs index 7584a63..91e4d18 100644 --- a/canvas/examples/textarea_normal.rs +++ b/canvas/examples/textarea_normal.rs @@ -200,9 +200,16 @@ Press ? for help, Ctrl+Q to quit."; } } -/// Handle key press in NORMALMODE (always editing) -fn handle_key_press(key_event: KeyEvent, editor: &mut AutoCursorTextArea) -> anyhow::Result { - let KeyEvent { code: key, modifiers, .. } = key_event; +/// Handle key press in NORMALMODE (always editing, casual editor style) +fn handle_key_press( + key_event: KeyEvent, + editor: &mut AutoCursorTextArea, +) -> anyhow::Result { + let KeyEvent { + code: key, + modifiers, + .. + } = key_event; // Quit if (key == KeyCode::Char('q') && modifiers.contains(KeyModifiers::CONTROL)) @@ -214,52 +221,32 @@ fn handle_key_press(key_event: KeyEvent, editor: &mut AutoCursorTextArea) -> any match (key, modifiers) { // Movement - (KeyCode::Char('h'), _) | (KeyCode::Left, _) => editor.move_left(), - (KeyCode::Char('l'), _) | (KeyCode::Right, _) => editor.move_right(), - (KeyCode::Char('j'), _) | (KeyCode::Down, _) => editor.move_down(), - (KeyCode::Char('k'), _) | (KeyCode::Up, _) => editor.move_up(), + (KeyCode::Left, _) => editor.move_left(), + (KeyCode::Right, _) => editor.move_right(), + (KeyCode::Up, _) => editor.move_up(), + (KeyCode::Down, _) => editor.move_down(), - // Word movement - (KeyCode::Char('w'), _) => editor.move_word_next(), - (KeyCode::Char('b'), _) => editor.move_word_prev(), - (KeyCode::Char('e'), _) => { - if editor.get_command_buffer() == "g" { - editor.move_word_end_prev(); - editor.clear_command_buffer(); - } else { - editor.move_word_end(); - editor.clear_command_buffer(); - } + // Word movement (Ctrl+Arrows) + (KeyCode::Left, m) if m.contains(KeyModifiers::CONTROL) => editor.move_word_prev(), + (KeyCode::Right, m) if m.contains(KeyModifiers::CONTROL) => editor.move_word_next(), + (KeyCode::Right, m) if m.contains(KeyModifiers::CONTROL | KeyModifiers::SHIFT) => { + editor.move_word_end() } - // Big word movement - (KeyCode::Char('W'), _) => editor.move_big_word_next(), - (KeyCode::Char('B'), _) => editor.move_big_word_prev(), - (KeyCode::Char('E'), _) => editor.move_big_word_end(), - // Line/document movement - (KeyCode::Char('0'), _) | (KeyCode::Home, _) => editor.move_line_start(), - (KeyCode::Char('$'), _) | (KeyCode::End, _) => editor.move_line_end(), - (KeyCode::Char('g'), _) => { - if editor.get_command_buffer() == "g" { - editor.move_first_line(); - editor.clear_command_buffer(); - } else { - editor.clear_command_buffer(); - editor.add_to_command_buffer('g'); - editor.set_debug_message("g".to_string()); - } - } - (KeyCode::Char('G'), _) => editor.move_last_line(), + (KeyCode::Home, _) => editor.move_line_start(), + (KeyCode::End, _) => editor.move_line_end(), + (KeyCode::Home, m) if m.contains(KeyModifiers::CONTROL) => editor.move_first_line(), + (KeyCode::End, m) if m.contains(KeyModifiers::CONTROL) => editor.move_last_line(), // Delete - (KeyCode::Char('x'), _) => editor.delete_char_forward(), - (KeyCode::Char('X'), _) => editor.delete_char_backward(), + (KeyCode::Delete, _) => editor.delete_char_forward(), + (KeyCode::Backspace, _) => editor.delete_char_backward(), // Debug/info (KeyCode::Char('?'), _) => { editor.set_debug_message(format!( - "{}, Mode: NORMALMODE (always editing, underscore cursor)", + "{}, Mode: NORMALMODE (casual editor, underscore cursor)", editor.get_cursor_info() )); editor.clear_command_buffer(); diff --git a/canvas/src/canvas/cursor.rs b/canvas/src/canvas/cursor.rs index 4fd7e56..2db839c 100644 --- a/canvas/src/canvas/cursor.rs +++ b/canvas/src/canvas/cursor.rs @@ -18,7 +18,7 @@ impl CursorManager { // NORMALMODE: force underscore for every mode #[cfg(feature = "textmode-normal")] { - let style = SetCursorStyle::SteadyUnderScore; + let style = SetCursorStyle::SteadyBar; return execute!(io::stdout(), style); } diff --git a/canvas/src/canvas/modes/manager.rs b/canvas/src/canvas/modes/manager.rs index 4b0556b..854374c 100644 --- a/canvas/src/canvas/modes/manager.rs +++ b/canvas/src/canvas/modes/manager.rs @@ -36,13 +36,22 @@ impl ModeManager { /// Transition to new mode with automatic cursor update (when cursor-style feature enabled) pub fn transition_to_mode(current_mode: AppMode, new_mode: AppMode) -> std::io::Result { - if current_mode != new_mode { - #[cfg(feature = "cursor-style")] - { - let _ = CursorManager::update_for_mode(new_mode); - } + #[cfg(feature = "textmode-normal")] + { + // Always force Edit in normalmode + return Ok(AppMode::Edit); + } + + #[cfg(not(feature = "textmode-normal"))] + { + if current_mode != new_mode { + #[cfg(feature = "cursor-style")] + { + let _ = CursorManager::update_for_mode(new_mode); + } + } + Ok(new_mode) } - Ok(new_mode) } /// Enter highlight mode with cursor styling diff --git a/canvas/src/canvas/state.rs b/canvas/src/canvas/state.rs index 8ec1c19..a39ec55 100644 --- a/canvas/src/canvas/state.rs +++ b/canvas/src/canvas/state.rs @@ -54,7 +54,13 @@ impl EditorState { current_field: 0, cursor_pos: 0, ideal_cursor_column: 0, + // NORMALMODE: always start in Edit + #[cfg(feature = "textmode-normal")] current_mode: AppMode::Edit, + // Default (vim): start in ReadOnly + #[cfg(not(feature = "textmode-normal"))] + current_mode: AppMode::ReadOnly, + #[cfg(feature = "suggestions")] suggestions: SuggestionsUIState { is_active: false, diff --git a/canvas/src/editor/core.rs b/canvas/src/editor/core.rs index 52dbe28..35ecdac 100644 --- a/canvas/src/editor/core.rs +++ b/canvas/src/editor/core.rs @@ -53,10 +53,19 @@ impl FormEditor { { let mut editor = editor; editor.initialize_validation(); + + #[cfg(feature = "cursor-style")] + { + let _ = CursorManager::update_for_mode(editor.ui_state.current_mode); + } editor } #[cfg(not(feature = "validation"))] { + #[cfg(feature = "cursor-style")] + { + let _ = CursorManager::update_for_mode(editor.ui_state.current_mode); + } editor } } diff --git a/canvas/src/lib.rs b/canvas/src/lib.rs index affa31c..99347c4 100644 --- a/canvas/src/lib.rs +++ b/canvas/src/lib.rs @@ -16,9 +16,6 @@ pub mod validation; #[cfg(feature = "computed")] pub mod computed; -#[path = "textmode/check.rs"] -mod textmode_check; - #[cfg(feature = "cursor-style")] pub use canvas::CursorManager; diff --git a/canvas/src/textmode/check.rs b/canvas/src/textmode/check.rs deleted file mode 100644 index 6956e51..0000000 --- a/canvas/src/textmode/check.rs +++ /dev/null @@ -1,7 +0,0 @@ -// src/textmode/check.rs - -#[cfg(all(feature = "textmode-vim", feature = "textmode-normal"))] -compile_error!("Enable exactly one of: textmode-vim or textmode-normal."); - -#[cfg(not(any(feature = "textmode-vim", feature = "textmode-normal")))] -compile_error!("No textmode selected. Enable one of: textmode-vim or textmode-normal.");