space and revert working properly well, also shift

This commit is contained in:
Priec
2025-09-08 20:05:39 +02:00
parent ad15becd7a
commit 1c17d07497
3 changed files with 78 additions and 20 deletions

View File

@@ -5,6 +5,7 @@ enter_command_mode = [":", "ctrl+;"]
next_buffer = ["space+b+n"] next_buffer = ["space+b+n"]
previous_buffer = ["space+b+p"] previous_buffer = ["space+b+p"]
close_buffer = ["space+b+d"] close_buffer = ["space+b+d"]
revert = ["space+b+r"]
[keybindings.general] [keybindings.general]
up = ["k", "Up"] up = ["k", "Up"]
@@ -27,7 +28,6 @@ move_up = ["Up"]
move_down = ["Down"] move_down = ["Down"]
toggle_sidebar = ["ctrl+t"] toggle_sidebar = ["ctrl+t"]
toggle_buffer_list = ["ctrl+b"] toggle_buffer_list = ["ctrl+b"]
revert = ["space+b+r"]
# MODE SPECIFIC # MODE SPECIFIC
# READ ONLY MODE # READ ONLY MODE
@@ -60,7 +60,7 @@ prev_field = ["Shift+Tab"]
[keybindings.highlight] [keybindings.highlight]
exit_highlight_mode = ["esc"] exit_highlight_mode = ["esc"]
enter_highlight_mode_linewise = ["ctrl+v"] enter_highlight_mode_linewise = ["shift+v"]
### AUTOGENERATED CANVAS CONFIG ### AUTOGENERATED CANVAS CONFIG
# Required # Required

View File

@@ -250,28 +250,44 @@ impl Config {
key: KeyCode, key: KeyCode,
modifiers: KeyModifiers, modifiers: KeyModifiers,
) -> bool { ) -> bool {
// Special handling for shift+character combinations
if binding.to_lowercase().starts_with("shift+") { // Normalize binding once
let parts: Vec<&str> = binding.split('+').collect(); let binding_lc = binding.to_lowercase();
if parts.len() == 2 && parts[1].len() == 1 {
let expected_lowercase = parts[1].chars().next().unwrap().to_lowercase().next().unwrap(); // Robust handling for Shift+Tab
let expected_uppercase = expected_lowercase.to_uppercase().next().unwrap(); // Accept either BackTab (with or without SHIFT flagged) or Tab+SHIFT
if let KeyCode::Char(actual_char) = key { if binding_lc == "shift+tab" || binding_lc == "backtab" {
if actual_char == expected_uppercase && modifiers.contains(KeyModifiers::SHIFT) { return match key {
return true; KeyCode::BackTab => true,
} KeyCode::Tab => modifiers.contains(KeyModifiers::SHIFT),
} _ => false,
} };
} }
// Handle Shift+Tab -> BackTab // Robust handling for shift+<char> (letters)
if binding.to_lowercase() == "shift+tab" && key == KeyCode::BackTab && modifiers.is_empty() { // 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].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; return true;
} }
// Also accept lowercase char with SHIFT flagged (some terms do this)
if actual == lower && modifiers.contains(KeyModifiers::SHIFT) {
return true;
}
}
}
}
// Handle multi-character bindings (all standard keys without modifiers) // Handle multi-character bindings (all standard keys without modifiers)
if binding.len() > 1 && !binding.contains('+') { if binding.len() > 1 && !binding.contains('+') {
return match binding.to_lowercase().as_str() { return match binding_lc.as_str() {
// Navigation keys // Navigation keys
"left" => key == KeyCode::Left, "left" => key == KeyCode::Left,
"right" => key == KeyCode::Right, "right" => key == KeyCode::Right,
@@ -371,6 +387,7 @@ impl Config {
let mut expected_key = None; let mut expected_key = None;
for part in parts { for part in parts {
let part_lc = part.to_lowercase();
match part.to_lowercase().as_str() { match part.to_lowercase().as_str() {
// Modifiers // Modifiers
"ctrl" | "control" => expected_modifiers |= KeyModifiers::CONTROL, "ctrl" | "control" => expected_modifiers |= KeyModifiers::CONTROL,
@@ -789,12 +806,43 @@ impl Config {
None 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 { pub fn build_canvas_keymap(&self) -> CanvasKeyMap {
CanvasKeyMap::from_mode_maps( let ro = Self::normalize_for_canvas(&self.keybindings.read_only);
&self.keybindings.read_only, let ed = Self::normalize_for_canvas(&self.keybindings.edit);
&self.keybindings.edit, let hl = Self::normalize_for_canvas(&self.keybindings.highlight);
&self.keybindings.highlight, CanvasKeyMap::from_mode_maps(&ro, &ed, &hl)
)
} }
} }

View File

@@ -574,6 +574,16 @@ impl EventHandler {
); );
return Ok(EventOutcome::Ok(message)); 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);
}
_ => {} _ => {}
} }
} }