space and revert working properly well, also shift
This commit is contained in:
@@ -250,28 +250,44 @@ impl Config {
|
||||
key: KeyCode,
|
||||
modifiers: KeyModifiers,
|
||||
) -> bool {
|
||||
// Special handling for shift+character combinations
|
||||
if binding.to_lowercase().starts_with("shift+") {
|
||||
|
||||
// Normalize binding once
|
||||
let binding_lc = binding.to_lowercase();
|
||||
|
||||
// Robust handling for Shift+Tab
|
||||
// Accept either BackTab (with or without SHIFT flagged) or Tab+SHIFT
|
||||
if binding_lc == "shift+tab" || binding_lc == "backtab" {
|
||||
return match key {
|
||||
KeyCode::BackTab => true,
|
||||
KeyCode::Tab => modifiers.contains(KeyModifiers::SHIFT),
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
||||
// Robust handling for shift+<char> (letters)
|
||||
// Many terminals send uppercase Char without SHIFT bit.
|
||||
if binding_lc.starts_with("shift+") {
|
||||
let parts: Vec<&str> = binding.split('+').collect();
|
||||
if parts.len() == 2 && parts[1].len() == 1 {
|
||||
let expected_lowercase = parts[1].chars().next().unwrap().to_lowercase().next().unwrap();
|
||||
let expected_uppercase = expected_lowercase.to_uppercase().next().unwrap();
|
||||
if let KeyCode::Char(actual_char) = key {
|
||||
if actual_char == expected_uppercase && modifiers.contains(KeyModifiers::SHIFT) {
|
||||
if parts.len() == 2 && parts[1].chars().count() == 1 {
|
||||
let base = parts[1].chars().next().unwrap();
|
||||
let upper = base.to_ascii_uppercase();
|
||||
let lower = base.to_ascii_lowercase();
|
||||
if let KeyCode::Char(actual) = key {
|
||||
// Accept uppercase char regardless of SHIFT bit
|
||||
if actual == upper {
|
||||
return true;
|
||||
}
|
||||
// Also accept lowercase char with SHIFT flagged (some terms do this)
|
||||
if actual == lower && modifiers.contains(KeyModifiers::SHIFT) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle Shift+Tab -> BackTab
|
||||
if binding.to_lowercase() == "shift+tab" && key == KeyCode::BackTab && modifiers.is_empty() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Handle multi-character bindings (all standard keys without modifiers)
|
||||
if binding.len() > 1 && !binding.contains('+') {
|
||||
return match binding.to_lowercase().as_str() {
|
||||
return match binding_lc.as_str() {
|
||||
// Navigation keys
|
||||
"left" => key == KeyCode::Left,
|
||||
"right" => key == KeyCode::Right,
|
||||
@@ -371,6 +387,7 @@ impl Config {
|
||||
let mut expected_key = None;
|
||||
|
||||
for part in parts {
|
||||
let part_lc = part.to_lowercase();
|
||||
match part.to_lowercase().as_str() {
|
||||
// Modifiers
|
||||
"ctrl" | "control" => expected_modifiers |= KeyModifiers::CONTROL,
|
||||
@@ -789,12 +806,43 @@ impl Config {
|
||||
None
|
||||
}
|
||||
|
||||
// Normalize bindings for canvas consumption:
|
||||
// - "shift+<char>" -> also add "<CHAR>"
|
||||
// - "shift+tab" -> also add "backtab"
|
||||
// This keeps your config human-friendly while making the canvas happy.
|
||||
fn normalize_for_canvas(
|
||||
map: &HashMap<String, Vec<String>>,
|
||||
) -> HashMap<String, Vec<String>> {
|
||||
let mut out: HashMap<String, Vec<String>> = HashMap::new();
|
||||
for (action, bindings) in map {
|
||||
let mut new_list: Vec<String> = Vec::new();
|
||||
for b in bindings {
|
||||
new_list.push(b.clone());
|
||||
let blc = b.to_lowercase();
|
||||
if blc.starts_with("shift+") {
|
||||
let parts: Vec<&str> = b.split('+').collect();
|
||||
if parts.len() == 2 && parts[1].chars().count() == 1 {
|
||||
let ch = parts[1].chars().next().unwrap();
|
||||
new_list.push(ch.to_ascii_uppercase().to_string());
|
||||
}
|
||||
if blc == "shift+tab" {
|
||||
new_list.push("backtab".to_string());
|
||||
}
|
||||
}
|
||||
if blc == "shift+tab" {
|
||||
new_list.push("backtab".to_string());
|
||||
}
|
||||
}
|
||||
out.insert(action.clone(), new_list);
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
pub fn build_canvas_keymap(&self) -> CanvasKeyMap {
|
||||
CanvasKeyMap::from_mode_maps(
|
||||
&self.keybindings.read_only,
|
||||
&self.keybindings.edit,
|
||||
&self.keybindings.highlight,
|
||||
)
|
||||
let ro = Self::normalize_for_canvas(&self.keybindings.read_only);
|
||||
let ed = Self::normalize_for_canvas(&self.keybindings.edit);
|
||||
let hl = Self::normalize_for_canvas(&self.keybindings.highlight);
|
||||
CanvasKeyMap::from_mode_maps(&ro, &ed, &hl)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -574,6 +574,16 @@ impl EventHandler {
|
||||
);
|
||||
return Ok(EventOutcome::Ok(message));
|
||||
}
|
||||
"revert" | "save" | "force_quit" | "save_and_quit" => {
|
||||
let outcome = self.handle_core_action(
|
||||
action,
|
||||
auth_state,
|
||||
terminal,
|
||||
app_state,
|
||||
router,
|
||||
).await?;
|
||||
return Ok(outcome);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user