space commands here we go again
This commit is contained in:
@@ -264,6 +264,25 @@ impl Config {
|
||||
};
|
||||
}
|
||||
|
||||
// If binding contains '+', distinguish between:
|
||||
// - modifier combos (e.g., ctrl+shift+s) => single key + modifiers
|
||||
// - multi-key sequences (e.g., space+b+r, g+g) => NOT a single key
|
||||
if binding_lc.contains('+') {
|
||||
let parts: Vec<&str> = binding_lc.split('+').collect();
|
||||
let is_modifier = |t: &str| {
|
||||
matches!(
|
||||
t,
|
||||
"ctrl" | "control" | "shift" | "alt" | "super" | "windows" | "cmd" | "hyper" | "meta"
|
||||
)
|
||||
};
|
||||
let non_modifier_count = parts.iter().filter(|p| !is_modifier(p)).count();
|
||||
if non_modifier_count > 1 {
|
||||
// This is a multi-key sequence (e.g., space+b+r, g+g), not a single keybind.
|
||||
// It must be handled by the sequence engine, not here.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Robust handling for shift+<char> (letters)
|
||||
// Many terminals send uppercase Char without SHIFT bit.
|
||||
if binding_lc.starts_with("shift+") {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// client/src/config/key_sequences.rs
|
||||
use crossterm::event::{KeyCode, KeyModifiers};
|
||||
use std::time::{Duration, Instant};
|
||||
use tracing::info;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct ParsedKey {
|
||||
@@ -25,19 +26,21 @@ impl KeySequenceTracker {
|
||||
}
|
||||
|
||||
pub fn reset(&mut self) {
|
||||
info!("KeySequenceTracker.reset() from {:?}", self.current_sequence);
|
||||
self.current_sequence.clear();
|
||||
self.last_key_time = Instant::now();
|
||||
}
|
||||
|
||||
pub fn add_key(&mut self, key: KeyCode) -> bool {
|
||||
// Check if timeout has expired
|
||||
let now = Instant::now();
|
||||
if now.duration_since(self.last_key_time) > self.timeout {
|
||||
info!("KeySequenceTracker timeout — reset before adding {:?}", key);
|
||||
self.reset();
|
||||
}
|
||||
|
||||
self.current_sequence.push(key);
|
||||
self.last_key_time = now;
|
||||
info!("KeySequenceTracker state after add: {:?}", self.current_sequence);
|
||||
true
|
||||
}
|
||||
|
||||
@@ -115,26 +118,21 @@ pub fn string_to_keycode(s: &str) -> Option<KeyCode> {
|
||||
pub fn parse_binding(binding: &str) -> Vec<ParsedKey> {
|
||||
let mut sequence = Vec::new();
|
||||
|
||||
// Handle different binding formats
|
||||
let parts: Vec<String> = if binding.contains('+') {
|
||||
// Format with explicit '+' separators like "g+left"
|
||||
binding.split('+').map(|s| s.to_string()).collect()
|
||||
} else if binding.contains(' ') {
|
||||
// Format with spaces like "g left"
|
||||
binding.split(' ').map(|s| s.to_string()).collect()
|
||||
} else if is_compound_key(binding) {
|
||||
// A single compound key like "left" or "enter"
|
||||
vec![binding.to_string()]
|
||||
// Split into multi-key sequence:
|
||||
// - If contains space → sequence split by space
|
||||
// - Else split by '+'
|
||||
let parts: Vec<&str> = if binding.contains(' ') {
|
||||
binding.split(' ').collect()
|
||||
} else {
|
||||
// Simple character sequence like "gg"
|
||||
binding.chars().map(|c| c.to_string()).collect()
|
||||
binding.split('+').collect()
|
||||
};
|
||||
|
||||
for part in &parts {
|
||||
if let Some(key) = parse_key_part(part) {
|
||||
sequence.push(key);
|
||||
for part in parts {
|
||||
if let Some(parsed) = parse_key_part(part) {
|
||||
sequence.push(parsed);
|
||||
}
|
||||
}
|
||||
|
||||
sequence
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user