working autocomplete now, with backwards deprecation

This commit is contained in:
Priec
2025-07-31 22:44:21 +02:00
parent c594c35b37
commit 8f99aa79ec
5 changed files with 59 additions and 45 deletions

1
Cargo.lock generated
View File

@@ -475,6 +475,7 @@ name = "canvas"
version = "0.4.2" version = "0.4.2"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait",
"common", "common",
"crossterm", "crossterm",
"ratatui", "ratatui",

View File

@@ -22,6 +22,7 @@ thiserror = { workspace = true }
tracing = "0.1.41" tracing = "0.1.41"
tracing-subscriber = "0.3.19" tracing-subscriber = "0.3.19"
async-trait = { workspace = true, optional = true }
[dev-dependencies] [dev-dependencies]
tokio-test = "0.4.4" tokio-test = "0.4.4"
@@ -29,7 +30,7 @@ tokio-test = "0.4.4"
[features] [features]
default = [] default = []
gui = ["ratatui"] gui = ["ratatui"]
autocomplete = ["tokio"] autocomplete = ["tokio", "async-trait"]
[[example]] [[example]]
name = "autocomplete" name = "autocomplete"

View File

@@ -33,6 +33,9 @@ use canvas::{
CanvasAction, CanvasAction,
}; };
// Add the async_trait import
use async_trait::async_trait;
// Simple theme implementation // Simple theme implementation
#[derive(Clone)] #[derive(Clone)]
struct DemoTheme; struct DemoTheme;
@@ -146,6 +149,8 @@ impl CanvasState for AutocompleteFormState {
} }
} }
// Add the #[async_trait] attribute to the implementation
#[async_trait]
impl AutocompleteCanvasState for AutocompleteFormState { impl AutocompleteCanvasState for AutocompleteFormState {
type SuggestionData = EmailSuggestion; type SuggestionData = EmailSuggestion;

View File

@@ -13,7 +13,7 @@ use anyhow::Result;
/// ```rust /// ```rust
/// execute_with_autocomplete(action, &mut state).await?; /// execute_with_autocomplete(action, &mut state).await?;
/// ``` /// ```
pub async fn execute_with_autocomplete<S: CanvasState + AutocompleteCanvasState>( pub async fn execute_with_autocomplete<S: CanvasState + AutocompleteCanvasState + Send>(
action: CanvasAction, action: CanvasAction,
state: &mut S, state: &mut S,
) -> Result<ActionResult> { ) -> Result<ActionResult> {
@@ -112,7 +112,7 @@ pub async fn execute_with_autocomplete<S: CanvasState + AutocompleteCanvasState>
/// None /// None
/// } /// }
/// ``` /// ```
pub fn handle_autocomplete_feature_action<S: CanvasState + AutocompleteCanvasState>( pub fn handle_autocomplete_feature_action<S: CanvasState + AutocompleteCanvasState + Send>(
action: &CanvasAction, action: &CanvasAction,
state: &S, state: &S,
) -> Option<String> { ) -> Option<String> {
@@ -160,7 +160,7 @@ pub fn handle_autocomplete_feature_action<S: CanvasState + AutocompleteCanvasSta
/// Legacy compatibility function - kept for backward compatibility /// Legacy compatibility function - kept for backward compatibility
/// This is the old function signature, now it just wraps the new system /// This is the old function signature, now it just wraps the new system
#[deprecated(note = "Use execute_with_autocomplete instead")] #[deprecated(note = "Use execute_with_autocomplete instead")]
pub async fn execute_canvas_action_with_autocomplete<S: CanvasState + AutocompleteCanvasState>( pub async fn execute_canvas_action_with_autocomplete<S: CanvasState + AutocompleteCanvasState + Send>(
action: CanvasAction, action: CanvasAction,
state: &mut S, state: &mut S,
_ideal_cursor_column: &mut usize, // Ignored - new system manages this internally _ideal_cursor_column: &mut usize, // Ignored - new system manages this internally

View File

@@ -1,6 +1,7 @@
// src/autocomplete/state.rs // src/autocomplete/state.rs
use crate::canvas::state::CanvasState; use crate::canvas::state::CanvasState;
use async_trait::async_trait;
/// OPTIONAL extension trait for states that want rich autocomplete functionality. /// OPTIONAL extension trait for states that want rich autocomplete functionality.
/// Only implement this if you need the new autocomplete features. /// Only implement this if you need the new autocomplete features.
@@ -12,6 +13,7 @@ use crate::canvas::state::CanvasState;
/// 4. You implement async fetching logic in that method /// 4. You implement async fetching logic in that method
/// 5. You call set_autocomplete_suggestions() with results /// 5. You call set_autocomplete_suggestions() with results
/// 6. Library manages UI state and navigation /// 6. Library manages UI state and navigation
#[async_trait]
pub trait AutocompleteCanvasState: CanvasState { pub trait AutocompleteCanvasState: CanvasState {
/// Associated type for suggestion data (e.g., Hit, String, CustomType) /// Associated type for suggestion data (e.g., Hit, String, CustomType)
type SuggestionData: Clone + Send + 'static; type SuggestionData: Clone + Send + 'static;
@@ -103,6 +105,10 @@ pub trait AutocompleteCanvasState: CanvasState {
/// ///
/// # Example Implementation: /// # Example Implementation:
/// ```rust /// ```rust
/// #[async_trait]
/// impl AutocompleteCanvasState for MyState {
/// type SuggestionData = MyData;
///
/// async fn trigger_autocomplete_suggestions(&mut self) { /// async fn trigger_autocomplete_suggestions(&mut self) {
/// self.activate_autocomplete(); // Show loading state /// self.activate_autocomplete(); // Show loading state
/// ///
@@ -111,6 +117,7 @@ pub trait AutocompleteCanvasState: CanvasState {
/// ///
/// self.set_autocomplete_suggestions(suggestions); /// self.set_autocomplete_suggestions(suggestions);
/// } /// }
/// }
/// ``` /// ```
async fn trigger_autocomplete_suggestions(&mut self) { async fn trigger_autocomplete_suggestions(&mut self) {
// Activate autocomplete UI // Activate autocomplete UI