fixed working canvas in client, need more fixes now

This commit is contained in:
Priec
2025-07-31 14:44:47 +02:00
parent ebe4adaa5d
commit 5d084bf822
4 changed files with 280 additions and 96 deletions

View File

@@ -54,10 +54,10 @@ move_word_next = ["w"]
next_field = ["Tab"]
move_word_prev = ["b"]
move_word_end = ["e"]
move_last_line = ["G"]
move_last_line = ["shift+g"]
move_word_end_prev = ["ge"]
move_line_start = ["0"]
move_first_line = ["gg"]
move_first_line = ["g+g"]
prev_field = ["Shift+Tab"]
[keybindings.highlight]

View File

@@ -12,7 +12,7 @@ use canvas::canvas::CanvasState;
use canvas::{canvas::CanvasAction, dispatcher::ActionDispatcher, canvas::ActionResult};
use anyhow::Result;
use common::proto::komp_ac::search::search_response::Hit;
use crossterm::event::{KeyCode, KeyEvent};
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use tokio::sync::mpsc;
use tracing::info;
@@ -143,23 +143,46 @@ async fn execute_canvas_action(
}
}
/// NEW: Unified canvas action handler for any CanvasState (LoginState, RegisterState, etc.)
/// This replaces the old auth_e::execute_edit_action calls with the new canvas library
/// NEW: Unified canvas action handler for any CanvasState with character fallback
/// Complete canvas action handler with fallbacks for common keys
/// Debug version to see what's happening
/// FIXED: Unified canvas action handler with proper priority order for edit mode
async fn handle_canvas_state_edit<S: CanvasState>(
key: KeyEvent,
config: &Config,
state: &mut S,
ideal_cursor_column: &mut usize,
) -> Result<String> {
println!("DEBUG: Key pressed: {:?}", key); // DEBUG
// Try direct key mapping first (same pattern as FormState)
// println!("DEBUG: Key pressed: {:?}", key); // DEBUG
// PRIORITY 1: Character insertion in edit mode comes FIRST
if let KeyCode::Char(c) = key.code {
// Only insert if no modifiers or just shift (for uppercase)
if key.modifiers.is_empty() || key.modifiers == KeyModifiers::SHIFT {
// println!("DEBUG: Using character insertion priority for: {}", c); // DEBUG
let canvas_action = CanvasAction::InsertChar(c);
match ActionDispatcher::dispatch(canvas_action, state, ideal_cursor_column).await {
Ok(ActionResult::Success(msg)) => {
return Ok(msg.unwrap_or_default());
}
Ok(ActionResult::HandledByFeature(msg)) => {
return Ok(msg);
}
Ok(ActionResult::Error(msg)) => {
return Ok(format!("Error: {}", msg));
}
Ok(ActionResult::RequiresContext(msg)) => {
return Ok(format!("Context needed: {}", msg));
}
Err(e) => {
// println!("DEBUG: Character insertion failed: {:?}, trying config", e);
// Fall through to try config mappings
}
}
}
}
// PRIORITY 2: Check canvas config for special keys/combinations
let canvas_config = canvas::config::CanvasConfig::load();
if let Some(action_name) = canvas_config.get_edit_action(key.code, key.modifiers) {
println!("DEBUG: Canvas config mapped to: {}", action_name); // DEBUG
// println!("DEBUG: Canvas config mapped to: {}", action_name); // DEBUG
let canvas_action = CanvasAction::from_string(action_name);
match ActionDispatcher::dispatch(canvas_action, state, ideal_cursor_column).await {
@@ -176,62 +199,43 @@ async fn handle_canvas_state_edit<S: CanvasState>(
return Ok(format!("Context needed: {}", msg));
}
Err(_) => {
println!("DEBUG: Canvas action failed, trying client config"); // DEBUG
// println!("DEBUG: Canvas action failed, trying client config"); // DEBUG
}
}
} else {
println!("DEBUG: No canvas config mapping found"); // DEBUG
// println!("DEBUG: No canvas config mapping found"); // DEBUG
}
// Try config-mapped action (same pattern as FormState)
if let Some(action_str) = config.get_edit_action_for_key(key.code, key.modifiers) {
println!("DEBUG: Client config mapped to: {}", action_str); // DEBUG
let canvas_action = CanvasAction::from_string(&action_str);
match ActionDispatcher::dispatch(canvas_action, state, ideal_cursor_column).await {
Ok(ActionResult::Success(msg)) => {
return Ok(msg.unwrap_or_default());
}
Ok(ActionResult::HandledByFeature(msg)) => {
return Ok(msg);
}
Ok(ActionResult::Error(msg)) => {
return Ok(format!("Error: {}", msg));
}
Ok(ActionResult::RequiresContext(msg)) => {
return Ok(format!("Context needed: {}", msg));
}
Err(e) => {
return Ok(format!("Action failed: {}", e));
// PRIORITY 3: Check client config ONLY for non-character keys or modified keys
if !matches!(key.code, KeyCode::Char(_)) || !key.modifiers.is_empty() {
if let Some(action_str) = config.get_edit_action_for_key(key.code, key.modifiers) {
// println!("DEBUG: Client config mapped to: {} (for non-char key)", action_str); // DEBUG
let canvas_action = CanvasAction::from_string(&action_str);
match ActionDispatcher::dispatch(canvas_action, state, ideal_cursor_column).await {
Ok(ActionResult::Success(msg)) => {
return Ok(msg.unwrap_or_default());
}
Ok(ActionResult::HandledByFeature(msg)) => {
return Ok(msg);
}
Ok(ActionResult::Error(msg)) => {
return Ok(format!("Error: {}", msg));
}
Ok(ActionResult::RequiresContext(msg)) => {
return Ok(format!("Context needed: {}", msg));
}
Err(e) => {
return Ok(format!("Action failed: {}", e));
}
}
} else {
// println!("DEBUG: No client config mapping found for non-char key"); // DEBUG
}
} else {
println!("DEBUG: No client config mapping found"); // DEBUG
// println!("DEBUG: Skipping client config for character key in edit mode"); // DEBUG
}
// Character insertion fallback
if let KeyCode::Char(c) = key.code {
println!("DEBUG: Using character fallback for: {}", c); // DEBUG
let canvas_action = CanvasAction::InsertChar(c);
match ActionDispatcher::dispatch(canvas_action, state, ideal_cursor_column).await {
Ok(ActionResult::Success(msg)) => {
return Ok(msg.unwrap_or_default());
}
Ok(ActionResult::HandledByFeature(msg)) => {
return Ok(msg);
}
Ok(ActionResult::Error(msg)) => {
return Ok(format!("Error: {}", msg));
}
Ok(ActionResult::RequiresContext(msg)) => {
return Ok(format!("Context needed: {}", msg));
}
Err(e) => {
return Ok(format!("Character insertion failed: {}", e));
}
}
}
println!("DEBUG: No action taken for key: {:?}", key); // DEBUG
// println!("DEBUG: No action taken for key: {:?}", key); // DEBUG
Ok(String::new())
}