mirror of
https://github.com/wez/wezterm.git
synced 2024-11-10 15:04:32 +03:00
keyboard: define keytable related types
This commit introduces a new `key_tables` config option that allows defining named groups of key assignments, but that have no effect yet. To support this change, the InputMap type has been adjusted to allow for the idea that multiple tables can exist. refs: https://github.com/wez/wezterm/discussions/1812
This commit is contained in:
parent
366c2fd807
commit
3c4eb0846f
@ -7,7 +7,9 @@ use crate::font::{
|
||||
FreeTypeLoadFlags, FreeTypeLoadTarget, StyleRule, TextStyle,
|
||||
};
|
||||
use crate::frontend::FrontEndSelection;
|
||||
use crate::keyassignment::{KeyAssignment, MouseEventTrigger, SpawnCommand};
|
||||
use crate::keyassignment::{
|
||||
KeyAssignment, KeyTable, KeyTableEntry, KeyTables, MouseEventTrigger, SpawnCommand,
|
||||
};
|
||||
use crate::keys::{Key, LeaderKey, Mouse};
|
||||
use crate::ssh::{SshBackend, SshDomain};
|
||||
use crate::tls::{TlsDomainClient, TlsDomainServer};
|
||||
@ -32,7 +34,7 @@ use std::time::Duration;
|
||||
use termwiz::hyperlink;
|
||||
use termwiz::surface::CursorShape;
|
||||
use wezterm_bidi::ParagraphDirectionHint;
|
||||
use wezterm_input_types::{KeyCode, Modifiers, WindowDecorations};
|
||||
use wezterm_input_types::{Modifiers, WindowDecorations};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct Config {
|
||||
@ -251,6 +253,9 @@ pub struct Config {
|
||||
|
||||
#[serde(default, deserialize_with = "de_vec_table")]
|
||||
pub keys: Vec<Key>,
|
||||
#[serde(default)]
|
||||
pub key_tables: HashMap<String, Vec<Key>>,
|
||||
|
||||
#[serde(
|
||||
default = "default_bypass_mouse_reporting_modifiers",
|
||||
deserialize_with = "crate::keys::de_modifiers"
|
||||
@ -780,8 +785,8 @@ impl Config {
|
||||
Self::default().compute_extra_defaults(None)
|
||||
}
|
||||
|
||||
pub fn key_bindings(&self) -> HashMap<(KeyCode, Modifiers), KeyAssignment> {
|
||||
let mut map = HashMap::new();
|
||||
pub fn key_bindings(&self) -> KeyTables {
|
||||
let mut tables = KeyTables::default();
|
||||
|
||||
for k in &self.keys {
|
||||
let (key, mods) = k
|
||||
@ -789,10 +794,33 @@ impl Config {
|
||||
.key
|
||||
.resolve(self.key_map_preference)
|
||||
.normalize_shift(k.key.mods);
|
||||
map.insert((key, mods), k.action.clone());
|
||||
tables.default.insert(
|
||||
(key, mods),
|
||||
KeyTableEntry {
|
||||
action: k.action.clone(),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
map
|
||||
for (name, keys) in &self.key_tables {
|
||||
let mut table = KeyTable::default();
|
||||
for k in keys {
|
||||
let (key, mods) = k
|
||||
.key
|
||||
.key
|
||||
.resolve(self.key_map_preference)
|
||||
.normalize_shift(k.key.mods);
|
||||
table.insert(
|
||||
(key, mods),
|
||||
KeyTableEntry {
|
||||
action: k.action.clone(),
|
||||
},
|
||||
);
|
||||
}
|
||||
tables.by_name.insert(name.to_string(), table);
|
||||
}
|
||||
|
||||
tables
|
||||
}
|
||||
|
||||
pub fn mouse_bindings(&self) -> HashMap<(MouseEventTrigger, Modifiers), KeyAssignment> {
|
||||
|
@ -349,8 +349,21 @@ pub enum KeyAssignment {
|
||||
}
|
||||
impl_lua_conversion!(KeyAssignment);
|
||||
|
||||
pub type KeyTable = HashMap<(KeyCode, Modifiers), KeyTableEntry>;
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct KeyTables {
|
||||
pub default: KeyTable,
|
||||
pub by_name: HashMap<String, KeyTable>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct KeyTableEntry {
|
||||
pub action: KeyAssignment,
|
||||
}
|
||||
|
||||
pub struct InputMap {
|
||||
pub keys: HashMap<(KeyCode, Modifiers), KeyAssignment>,
|
||||
pub keys: KeyTables,
|
||||
pub mouse: HashMap<(MouseEventTrigger, Modifiers), KeyAssignment>,
|
||||
leader: Option<(KeyCode, Modifiers, Duration)>,
|
||||
}
|
||||
@ -432,7 +445,9 @@ impl InputMap {
|
||||
}
|
||||
|
||||
for key in items {
|
||||
keys.entry(key).or_insert($action.clone());
|
||||
keys.default.entry(key).or_insert(KeyTableEntry {
|
||||
action: $action.clone()
|
||||
});
|
||||
}
|
||||
|
||||
)*
|
||||
@ -738,7 +753,8 @@ impl InputMap {
|
||||
);
|
||||
}
|
||||
|
||||
keys.retain(|_, v| *v != KeyAssignment::DisableDefaultAssignment);
|
||||
keys.default
|
||||
.retain(|_, v| v.action != KeyAssignment::DisableDefaultAssignment);
|
||||
mouse.retain(|_, v| *v != KeyAssignment::DisableDefaultAssignment);
|
||||
|
||||
Self {
|
||||
@ -761,8 +777,9 @@ impl InputMap {
|
||||
mods - (Modifiers::LEFT_ALT | Modifiers::RIGHT_ALT)
|
||||
}
|
||||
|
||||
pub fn lookup_key(&self, key: &KeyCode, mods: Modifiers) -> Option<KeyAssignment> {
|
||||
pub fn lookup_key(&self, key: &KeyCode, mods: Modifiers) -> Option<KeyTableEntry> {
|
||||
self.keys
|
||||
.default
|
||||
.get(&key.normalize_shift(Self::remove_positional_alt(mods)))
|
||||
.cloned()
|
||||
}
|
||||
|
@ -299,10 +299,10 @@ impl LauncherState {
|
||||
let input_map = InputMap::new(&config);
|
||||
let mut key_entries: Vec<Entry> = vec![];
|
||||
// Give a consistent order to the entries
|
||||
let keys: BTreeMap<_, _> = input_map.keys.into_iter().collect();
|
||||
for ((keycode, mods), assignment) in keys {
|
||||
let keys: BTreeMap<_, _> = input_map.keys.default.into_iter().collect();
|
||||
for ((keycode, mods), entry) in keys {
|
||||
if matches!(
|
||||
&assignment,
|
||||
&entry.action,
|
||||
KeyAssignment::ActivateTabRelative(_) | KeyAssignment::ActivateTab(_)
|
||||
) {
|
||||
// Filter out some noisy, repetitive entries
|
||||
@ -311,7 +311,7 @@ impl LauncherState {
|
||||
if key_entries
|
||||
.iter()
|
||||
.find(|ent| match &ent.kind {
|
||||
EntryKind::KeyAssignment(a) => a == &assignment,
|
||||
EntryKind::KeyAssignment(a) => a == &entry.action,
|
||||
_ => false,
|
||||
})
|
||||
.is_some()
|
||||
@ -322,11 +322,11 @@ impl LauncherState {
|
||||
key_entries.push(Entry {
|
||||
label: format!(
|
||||
"{:?} ({} {})",
|
||||
assignment,
|
||||
entry.action,
|
||||
mods.to_string(),
|
||||
keycode.to_string()
|
||||
),
|
||||
kind: EntryKind::KeyAssignment(assignment),
|
||||
kind: EntryKind::KeyAssignment(entry.action),
|
||||
});
|
||||
}
|
||||
key_entries.sort_by(|a, b| a.label.cmp(&b.label));
|
||||
|
@ -86,7 +86,7 @@ impl super::TermWindow {
|
||||
}
|
||||
|
||||
if is_down {
|
||||
if let Some(assignment) = self
|
||||
if let Some(entry) = self
|
||||
.input_map
|
||||
.lookup_key(&keycode, raw_modifiers | leader_mod)
|
||||
{
|
||||
@ -95,10 +95,10 @@ impl super::TermWindow {
|
||||
"{:?} {:?} -> perform {:?}",
|
||||
keycode,
|
||||
raw_modifiers | leader_mod,
|
||||
assignment
|
||||
entry.action,
|
||||
);
|
||||
}
|
||||
self.perform_key_assignment(&pane, &assignment).ok();
|
||||
self.perform_key_assignment(&pane, &entry.action).ok();
|
||||
context.invalidate();
|
||||
|
||||
if leader_active {
|
||||
|
Loading…
Reference in New Issue
Block a user