diff --git a/canvas/src/autocomplete/actions.rs b/canvas/src/autocomplete/actions.rs deleted file mode 100644 index 1fa130d..0000000 --- a/canvas/src/autocomplete/actions.rs +++ /dev/null @@ -1,47 +0,0 @@ -// src/autocomplete/actions.rs -//! Legacy autocomplete actions - deprecated in favor of FormEditor - -use crate::canvas::actions::types::{CanvasAction, ActionResult}; -use anyhow::Result; - -/// Legacy function - use FormEditor.trigger_autocomplete() instead -/// -/// # Migration Guide -/// -/// **Old way:** -/// ```rust,ignore -/// execute_with_autocomplete(action, &mut state).await?; -/// ``` -/// -/// **New way:** -/// ```rust,ignore -/// let mut editor = FormEditor::new(your_data_provider); -/// match action { -/// CanvasAction::TriggerAutocomplete => { -/// editor.trigger_autocomplete(&mut autocomplete_provider).await?; -/// } -/// CanvasAction::InsertChar(c) => { -/// editor.insert_char(c)?; -/// } -/// // ... etc -/// } -/// ``` -#[deprecated(note = "Use FormEditor.trigger_autocomplete() and related methods instead")] -pub async fn execute_with_autocomplete( - _action: CanvasAction, - _state: &mut T, -) -> Result { - Err(anyhow::anyhow!( - "execute_with_autocomplete is deprecated. Use FormEditor API instead.\n\ - Migration: Replace CanvasState trait with DataProvider trait and use FormEditor." - )) -} - -/// Legacy function - use FormEditor methods instead -#[deprecated(note = "Use FormEditor methods instead")] -pub fn handle_autocomplete_feature_action( - _action: &CanvasAction, - _state: &T, -) -> Option { - Some("handle_autocomplete_feature_action is deprecated. Use FormEditor API instead.".to_string()) -} diff --git a/canvas/src/autocomplete/mod.rs b/canvas/src/autocomplete/mod.rs index 0ef3b62..2027914 100644 --- a/canvas/src/autocomplete/mod.rs +++ b/canvas/src/autocomplete/mod.rs @@ -1,20 +1,11 @@ // src/autocomplete/mod.rs -pub mod types; pub mod state; -pub mod actions; - #[cfg(feature = "gui")] pub mod gui; -// Re-export the main autocomplete API -pub use types::{SuggestionItem, AutocompleteState}; - -// Re-export the new action functions -pub use actions::{ - execute_with_autocomplete, - handle_autocomplete_feature_action, -}; +// Re-export the main autocomplete types +pub use state::{AutocompleteProvider, SuggestionItem}; // Re-export GUI functions if available #[cfg(feature = "gui")] diff --git a/canvas/src/autocomplete/state.rs b/canvas/src/autocomplete/state.rs index 6b4fe11..11c03fa 100644 --- a/canvas/src/autocomplete/state.rs +++ b/canvas/src/autocomplete/state.rs @@ -1,9 +1,5 @@ // src/autocomplete/state.rs -//! Simple autocomplete provider pattern - replaces complex trait +//! Autocomplete provider types -// Re-export the main types from data_provider for backward compatibility +// Re-export the main types from data_provider pub use crate::data_provider::{AutocompleteProvider, SuggestionItem}; - -// Legacy compatibility - empty trait for migration -#[deprecated(note = "Use AutocompleteProvider instead")] -pub trait AutocompleteCanvasState {} diff --git a/canvas/src/autocomplete/types.rs b/canvas/src/autocomplete/types.rs deleted file mode 100644 index dfaea81..0000000 --- a/canvas/src/autocomplete/types.rs +++ /dev/null @@ -1,21 +0,0 @@ -// src/autocomplete/types.rs -//! Legacy autocomplete types - deprecated - -// Re-export the new simplified types -pub use crate::data_provider::SuggestionItem; - -/// Legacy type - use FormEditor instead -#[deprecated(note = "Use FormEditor instead")] -#[derive(Debug, Clone)] -pub struct AutocompleteState { - _phantom: std::marker::PhantomData, -} - -#[allow(dead_code)] -impl AutocompleteState { - /// Legacy method - use FormEditor.is_autocomplete_active() instead - #[deprecated(note = "Use FormEditor.is_autocomplete_active() instead")] - pub fn is_active(&self) -> bool { - false - } -} diff --git a/canvas/src/canvas/actions/handlers/dispatcher.rs b/canvas/src/canvas/actions/handlers/dispatcher.rs deleted file mode 100644 index 6636574..0000000 --- a/canvas/src/canvas/actions/handlers/dispatcher.rs +++ /dev/null @@ -1,30 +0,0 @@ -// src/canvas/actions/handlers/dispatcher.rs - -use crate::canvas::state::EditorState; -use crate::canvas::actions::{CanvasAction, ActionResult}; -use crate::canvas::modes::AppMode; - -use super::{handle_edit_action, handle_readonly_action, handle_highlight_action}; - -/// Internal action dispatcher - routes actions to mode-specific handlers -pub(crate) fn dispatch_action_internal( - action: CanvasAction, - editor_state: &mut EditorState, - current_text: &str, -) -> ActionResult { - // Route to mode-specific handler based on current mode - match editor_state.current_mode { - AppMode::Edit => { - handle_edit_action(action, editor_state, current_text) - } - AppMode::ReadOnly => { - handle_readonly_action(action, editor_state, current_text) - } - AppMode::Highlight => { - handle_highlight_action(action, editor_state, current_text) - } - AppMode::General | AppMode::Command => { - ActionResult::success_with_message("Mode does not handle canvas actions directly") - } - } -} diff --git a/canvas/src/canvas/actions/handlers/edit.rs b/canvas/src/canvas/actions/handlers/edit.rs deleted file mode 100644 index c2706da..0000000 --- a/canvas/src/canvas/actions/handlers/edit.rs +++ /dev/null @@ -1,143 +0,0 @@ -// src/canvas/actions/handlers/edit.rs -//! Edit mode action handler with EditorState - -use crate::canvas::actions::types::{CanvasAction, ActionResult}; -use crate::canvas::actions::movement::*; -use crate::canvas::state::EditorState; - -/// Edit mode uses cursor-past-end behavior for text insertion -const FOR_EDIT_MODE: bool = true; - -/// Handle actions in edit mode with edit-specific cursor behavior -pub(crate) fn handle_edit_action( - action: CanvasAction, - editor_state: &mut EditorState, - current_text: &str, -) -> ActionResult { - match action { - // Note: Text insertion is handled at the FormEditor level - // These handlers only deal with cursor movement and navigation - - // Cursor movement actions - CanvasAction::MoveLeft => { - let new_pos = move_left(editor_state.cursor_pos); - editor_state.cursor_pos = new_pos; - editor_state.ideal_cursor_column = new_pos; - ActionResult::success() - } - - CanvasAction::MoveRight => { - let new_pos = move_right(editor_state.cursor_pos, current_text, FOR_EDIT_MODE); - editor_state.cursor_pos = new_pos; - editor_state.ideal_cursor_column = new_pos; - ActionResult::success() - } - - // Field navigation (treating single-line fields as "lines") - CanvasAction::MoveUp => { - if editor_state.current_field > 0 { - editor_state.current_field -= 1; - let new_pos = safe_cursor_position(current_text, editor_state.ideal_cursor_column, FOR_EDIT_MODE); - editor_state.cursor_pos = new_pos; - } - ActionResult::success() - } - - CanvasAction::MoveDown => { - // Note: field count validation happens at FormEditor level - editor_state.current_field += 1; - let new_pos = safe_cursor_position(current_text, editor_state.ideal_cursor_column, FOR_EDIT_MODE); - editor_state.cursor_pos = new_pos; - ActionResult::success() - } - - // Line-based movement - CanvasAction::MoveLineStart => { - let new_pos = line_start_position(); - editor_state.cursor_pos = new_pos; - editor_state.ideal_cursor_column = new_pos; - ActionResult::success() - } - - CanvasAction::MoveLineEnd => { - let new_pos = line_end_position(current_text, FOR_EDIT_MODE); - editor_state.cursor_pos = new_pos; - editor_state.ideal_cursor_column = new_pos; - ActionResult::success() - } - - // Document-level movement (first/last field) - CanvasAction::MoveFirstLine => { - editor_state.current_field = 0; - let new_pos = safe_cursor_position(current_text, 0, FOR_EDIT_MODE); - editor_state.cursor_pos = new_pos; - editor_state.ideal_cursor_column = new_pos; - ActionResult::success() - } - - CanvasAction::MoveLastLine => { - // Note: field count validation happens at FormEditor level - let new_pos = line_end_position(current_text, FOR_EDIT_MODE); - editor_state.cursor_pos = new_pos; - editor_state.ideal_cursor_column = new_pos; - ActionResult::success() - } - - // Word-based movement - CanvasAction::MoveWordNext => { - if !current_text.is_empty() { - let new_pos = find_next_word_start(current_text, editor_state.cursor_pos); - editor_state.cursor_pos = new_pos; - editor_state.ideal_cursor_column = new_pos; - } - ActionResult::success() - } - - CanvasAction::MoveWordEnd => { - if !current_text.is_empty() { - let new_pos = find_word_end(current_text, editor_state.cursor_pos); - editor_state.cursor_pos = new_pos; - editor_state.ideal_cursor_column = new_pos; - } - ActionResult::success() - } - - CanvasAction::MoveWordPrev => { - if !current_text.is_empty() { - let new_pos = find_prev_word_start(current_text, editor_state.cursor_pos); - editor_state.cursor_pos = new_pos; - editor_state.ideal_cursor_column = new_pos; - } - ActionResult::success() - } - - CanvasAction::MoveWordEndPrev => { - if !current_text.is_empty() { - let new_pos = find_prev_word_end(current_text, editor_state.cursor_pos); - editor_state.cursor_pos = new_pos; - editor_state.ideal_cursor_column = new_pos; - } - ActionResult::success() - } - - // Field navigation - handled at FormEditor level for bounds checking - CanvasAction::NextField | CanvasAction::PrevField => { - ActionResult::success_with_message("Field navigation handled by FormEditor") - } - - // Text editing actions - handled at FormEditor level - CanvasAction::InsertChar(_) | - CanvasAction::DeleteBackward | - CanvasAction::DeleteForward => { - ActionResult::success_with_message("Text editing handled by FormEditor") - } - - CanvasAction::Custom(action_str) => { - ActionResult::success_with_message(&format!("Custom edit action: {}", action_str)) - } - - _ => { - ActionResult::success_with_message("Action not implemented for edit mode") - } - } -} diff --git a/canvas/src/canvas/actions/handlers/highlight.rs b/canvas/src/canvas/actions/handlers/highlight.rs deleted file mode 100644 index 77314f5..0000000 --- a/canvas/src/canvas/actions/handlers/highlight.rs +++ /dev/null @@ -1,97 +0,0 @@ -// src/canvas/actions/handlers/highlight.rs -//! Highlight mode action handler with EditorState - -use crate::canvas::actions::types::{CanvasAction, ActionResult}; -use crate::canvas::actions::movement::*; -use crate::canvas::state::EditorState; - -const FOR_EDIT_MODE: bool = false; // Highlight mode uses read-only cursor behavior - -/// Handle actions in highlight/visual mode -pub(crate) fn handle_highlight_action( - action: CanvasAction, - editor_state: &mut EditorState, - current_text: &str, -) -> ActionResult { - match action { - // Movement actions work similar to read-only mode but with selection - CanvasAction::MoveLeft => { - let new_pos = move_left(editor_state.cursor_pos); - editor_state.cursor_pos = new_pos; - editor_state.ideal_cursor_column = new_pos; - // TODO: Update selection range - ActionResult::success() - } - - CanvasAction::MoveRight => { - let new_pos = move_right(editor_state.cursor_pos, current_text, FOR_EDIT_MODE); - editor_state.cursor_pos = new_pos; - editor_state.ideal_cursor_column = new_pos; - // TODO: Update selection range - ActionResult::success() - } - - CanvasAction::MoveWordNext => { - if !current_text.is_empty() { - let new_pos = find_next_word_start(current_text, editor_state.cursor_pos); - let final_pos = clamp_cursor_position(new_pos, current_text, FOR_EDIT_MODE); - editor_state.cursor_pos = final_pos; - editor_state.ideal_cursor_column = final_pos; - // TODO: Update selection range - } - ActionResult::success() - } - - CanvasAction::MoveWordEnd => { - if !current_text.is_empty() { - let new_pos = find_word_end(current_text, editor_state.cursor_pos); - let final_pos = clamp_cursor_position(new_pos, current_text, FOR_EDIT_MODE); - editor_state.cursor_pos = final_pos; - editor_state.ideal_cursor_column = final_pos; - // TODO: Update selection range - } - ActionResult::success() - } - - CanvasAction::MoveWordPrev => { - if !current_text.is_empty() { - let new_pos = find_prev_word_start(current_text, editor_state.cursor_pos); - editor_state.cursor_pos = new_pos; - editor_state.ideal_cursor_column = new_pos; - // TODO: Update selection range - } - ActionResult::success() - } - - CanvasAction::MoveLineStart => { - let new_pos = line_start_position(); - editor_state.cursor_pos = new_pos; - editor_state.ideal_cursor_column = new_pos; - // TODO: Update selection range - ActionResult::success() - } - - CanvasAction::MoveLineEnd => { - let new_pos = line_end_position(current_text, FOR_EDIT_MODE); - editor_state.cursor_pos = new_pos; - editor_state.ideal_cursor_column = new_pos; - // TODO: Update selection range - ActionResult::success() - } - - // Highlight mode doesn't handle editing actions - CanvasAction::InsertChar(_) | - CanvasAction::DeleteBackward | - CanvasAction::DeleteForward => { - ActionResult::success_with_message("Action not available in highlight mode") - } - - CanvasAction::Custom(action_str) => { - ActionResult::success_with_message(&format!("Custom highlight action: {}", action_str)) - } - - _ => { - ActionResult::success_with_message("Action not implemented for highlight mode") - } - } -} diff --git a/canvas/src/canvas/actions/handlers/mod.rs b/canvas/src/canvas/actions/handlers/mod.rs deleted file mode 100644 index 1810a00..0000000 --- a/canvas/src/canvas/actions/handlers/mod.rs +++ /dev/null @@ -1,11 +0,0 @@ -// src/canvas/actions/handlers/mod.rs - -pub mod edit; -pub mod readonly; -pub mod highlight; -pub mod dispatcher; - -pub use edit::*; -pub use readonly::*; -pub use highlight::*; -pub use dispatcher::*; diff --git a/canvas/src/canvas/actions/handlers/readonly.rs b/canvas/src/canvas/actions/handlers/readonly.rs deleted file mode 100644 index 551457d..0000000 --- a/canvas/src/canvas/actions/handlers/readonly.rs +++ /dev/null @@ -1,136 +0,0 @@ -// src/canvas/actions/handlers/readonly.rs -//! ReadOnly mode action handler with EditorState - -use crate::canvas::actions::types::{CanvasAction, ActionResult}; -use crate::canvas::actions::movement::*; -use crate::canvas::state::EditorState; - -const FOR_EDIT_MODE: bool = false; // Read-only mode flag - -/// Handle actions in read-only mode with read-only specific cursor behavior -pub(crate) fn handle_readonly_action( - action: CanvasAction, - editor_state: &mut EditorState, - current_text: &str, -) -> ActionResult { - match action { - CanvasAction::MoveLeft => { - let new_pos = move_left(editor_state.cursor_pos); - editor_state.cursor_pos = new_pos; - editor_state.ideal_cursor_column = new_pos; - ActionResult::success() - } - - CanvasAction::MoveRight => { - let new_pos = move_right(editor_state.cursor_pos, current_text, FOR_EDIT_MODE); - editor_state.cursor_pos = new_pos; - editor_state.ideal_cursor_column = new_pos; - ActionResult::success() - } - - CanvasAction::MoveUp => { - if editor_state.current_field > 0 { - editor_state.current_field -= 1; - let new_pos = safe_cursor_position(current_text, editor_state.ideal_cursor_column, FOR_EDIT_MODE); - editor_state.cursor_pos = new_pos; - } - ActionResult::success() - } - - CanvasAction::MoveDown => { - // Note: bounds checking happens at FormEditor level - editor_state.current_field += 1; - let new_pos = safe_cursor_position(current_text, editor_state.ideal_cursor_column, FOR_EDIT_MODE); - editor_state.cursor_pos = new_pos; - ActionResult::success() - } - - CanvasAction::MoveFirstLine => { - editor_state.current_field = 0; - let new_pos = safe_cursor_position(current_text, editor_state.ideal_cursor_column, FOR_EDIT_MODE); - editor_state.cursor_pos = new_pos; - editor_state.ideal_cursor_column = new_pos; - ActionResult::success() - } - - CanvasAction::MoveLastLine => { - // Note: field count validation happens at FormEditor level - let new_pos = safe_cursor_position(current_text, editor_state.ideal_cursor_column, FOR_EDIT_MODE); - editor_state.cursor_pos = new_pos; - editor_state.ideal_cursor_column = new_pos; - ActionResult::success() - } - - CanvasAction::MoveLineStart => { - let new_pos = line_start_position(); - editor_state.cursor_pos = new_pos; - editor_state.ideal_cursor_column = new_pos; - ActionResult::success() - } - - CanvasAction::MoveLineEnd => { - let new_pos = line_end_position(current_text, FOR_EDIT_MODE); - editor_state.cursor_pos = new_pos; - editor_state.ideal_cursor_column = new_pos; - ActionResult::success() - } - - CanvasAction::MoveWordNext => { - if !current_text.is_empty() { - let new_pos = find_next_word_start(current_text, editor_state.cursor_pos); - let final_pos = clamp_cursor_position(new_pos, current_text, FOR_EDIT_MODE); - editor_state.cursor_pos = final_pos; - editor_state.ideal_cursor_column = final_pos; - } - ActionResult::success() - } - - CanvasAction::MoveWordEnd => { - if !current_text.is_empty() { - let new_pos = find_word_end(current_text, editor_state.cursor_pos); - let final_pos = clamp_cursor_position(new_pos, current_text, FOR_EDIT_MODE); - editor_state.cursor_pos = final_pos; - editor_state.ideal_cursor_column = final_pos; - } - ActionResult::success() - } - - CanvasAction::MoveWordPrev => { - if !current_text.is_empty() { - let new_pos = find_prev_word_start(current_text, editor_state.cursor_pos); - editor_state.cursor_pos = new_pos; - editor_state.ideal_cursor_column = new_pos; - } - ActionResult::success() - } - - CanvasAction::MoveWordEndPrev => { - if !current_text.is_empty() { - let new_pos = find_prev_word_end(current_text, editor_state.cursor_pos); - editor_state.cursor_pos = new_pos; - editor_state.ideal_cursor_column = new_pos; - } - ActionResult::success() - } - - // Field navigation - handled at FormEditor level - CanvasAction::NextField | CanvasAction::PrevField => { - ActionResult::success_with_message("Field navigation handled by FormEditor") - } - - // Read-only mode doesn't handle editing actions - CanvasAction::InsertChar(_) | - CanvasAction::DeleteBackward | - CanvasAction::DeleteForward => { - ActionResult::success_with_message("Action not available in read-only mode") - } - - CanvasAction::Custom(action_str) => { - ActionResult::success_with_message(&format!("Custom readonly action: {}", action_str)) - } - - _ => { - ActionResult::success_with_message("Action not implemented for read-only mode") - } - } -} diff --git a/canvas/src/canvas/actions/mod.rs b/canvas/src/canvas/actions/mod.rs index 21a80f8..412d758 100644 --- a/canvas/src/canvas/actions/mod.rs +++ b/canvas/src/canvas/actions/mod.rs @@ -1,7 +1,6 @@ // src/canvas/actions/mod.rs pub mod types; -pub mod handlers; pub mod movement; // Re-export the main API diff --git a/canvas/src/canvas/actions/types.rs b/canvas/src/canvas/actions/types.rs index d5a2de4..fe9ae9c 100644 --- a/canvas/src/canvas/actions/types.rs +++ b/canvas/src/canvas/actions/types.rs @@ -1,7 +1,5 @@ // src/canvas/actions/types.rs -use crate::canvas::state::EditorState; - /// All available canvas actions #[derive(Debug, Clone, PartialEq)] pub enum CanvasAction { @@ -83,12 +81,6 @@ impl ActionResult { } impl CanvasAction { - /// Internal method used by FormEditor - pub(crate) fn apply_to_editor_state(self, editor_state: &mut EditorState, current_text: &str) -> ActionResult { - // Internal method used by FormEditor - crate::canvas::actions::handlers::dispatch_action_internal(self, editor_state, current_text) - } - /// Get a human-readable description of this action pub fn description(&self) -> &'static str { match self { diff --git a/canvas/src/editor.rs b/canvas/src/editor.rs index 81dc16a..275463c 100644 --- a/canvas/src/editor.rs +++ b/canvas/src/editor.rs @@ -2,7 +2,6 @@ //! Main API for the canvas library - FormEditor with library-owned state use anyhow::Result; -use async_trait::async_trait; use crate::canvas::state::EditorState; use crate::data_provider::{DataProvider, AutocompleteProvider, SuggestionItem}; use crate::canvas::modes::AppMode; diff --git a/canvas/src/lib.rs b/canvas/src/lib.rs index 31084f6..d145f29 100644 --- a/canvas/src/lib.rs +++ b/canvas/src/lib.rs @@ -32,16 +32,3 @@ pub use canvas::gui::render_canvas; #[cfg(all(feature = "gui", feature = "autocomplete"))] pub use autocomplete::gui::render_autocomplete_dropdown; - -// =================================================================== -// LEGACY COMPATIBILITY: Old trait-based API (deprecated) -// =================================================================== - -// Legacy exports for backward compatibility - mark as deprecated - -#[deprecated(note = "Use FormEditor and AutocompleteProvider instead")] -#[cfg(feature = "autocomplete")] -pub use crate::autocomplete::state::AutocompleteCanvasState; - -// Mode management (still used) -pub use canvas::modes::{ModeManager, HighlightState};