1
1
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:
Wez Furlong 2022-04-03 13:45:21 -07:00
parent 366c2fd807
commit 3c4eb0846f
4 changed files with 64 additions and 19 deletions

View File

@ -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> {

View File

@ -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()
}

View File

@ -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));

View File

@ -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 {