Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 31 additions & 10 deletions src/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ impl KeyPath {
}

/// Adds an item to the KeyPath.
pub fn add_path_item(&mut self, item: u16) {
self.0.insert(1, item).unwrap();
pub fn append_path_item(&self, item: u16) -> KeyPath {
let mut kp = self.clone();
kp.0.push(item).unwrap();
kp
}
}

Expand Down Expand Up @@ -127,11 +129,34 @@ impl<E: Debug, const M: usize> IntoIterator for KeyEvents<E, M> {
}
}

/// Newtype for invoking new_pressed_key on the key at the given [KeyPath].
#[derive(Debug)]
pub enum NewPressedKey {
/// Invoke new_pressed_key on the key at the given [KeyPath].
Key(KeyPath),
/// For keys which do nothing when pressed.
NoOp,
}

impl NewPressedKey {
/// Constructs a NewPressedKey value.
pub fn key_path(key_path: KeyPath) -> Self {
NewPressedKey::Key(key_path)
}

/// Constructs a NoOp NewPressedKey value.
pub fn no_op() -> Self {
NewPressedKey::NoOp
}
}

/// Pressed Key which may be pending, or a resolved key state.
#[derive(Debug)]
pub enum PressedKeyResult<PKS, KS> {
/// Unresolved key state. (e.g. tap-hold or chorded keys when first pressed).
Pending(KeyPath, PKS),
/// Resolved as a new pressed key.
NewPressedKey(NewPressedKey),
/// Resolved key state.
Resolved(KS),
}
Expand All @@ -154,11 +179,10 @@ impl<PKS, KS> PressedKeyResult<PKS, KS> {
}

/// Adds an item to the KeyPath if the pressed key result is pending.
pub fn add_path_item(self, item: u16) -> Self {
pub fn append_path_item(self, item: u16) -> Self {
match self {
PressedKeyResult::Pending(mut key_path, pks) => {
key_path.add_path_item(item);
PressedKeyResult::Pending(key_path, pks)
PressedKeyResult::Pending(key_path, pks) => {
PressedKeyResult::Pending(key_path.append_path_item(item), pks)
}
pkr => pkr,
}
Expand Down Expand Up @@ -210,10 +234,7 @@ pub trait Key: Debug {
context: &Self::Context,
key_path: KeyPath,
event: Event<Self::Event>,
) -> (
Option<PressedKeyResult<Self::PendingKeyState, Self::KeyState>>,
KeyEvents<Self::Event>,
);
) -> (Option<NewPressedKey>, KeyEvents<Self::Event>);

/// Return a reference to the key for the given path.
fn lookup(
Expand Down
9 changes: 3 additions & 6 deletions src/key/callback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ impl key::Key for Key {
key::KeyEvents<Self::Event>,
) {
let &Key { keymap_callback } = self;
let pks = key::PressedKeyResult::Resolved(key::NoOpKeyState::new().into());
let pkr = key::PressedKeyResult::NewPressedKey(key::NewPressedKey::NoOp);
let km_ev = crate::keymap::KeymapEvent::Callback(keymap_callback);
let pke = key::KeyEvents::event(key::Event::Keymap(km_ev));
(pks, pke)
(pkr, pke)
}

fn handle_event(
Expand All @@ -47,10 +47,7 @@ impl key::Key for Key {
_context: &Self::Context,
_key_path: key::KeyPath,
_event: key::Event<Self::Event>,
) -> (
Option<key::PressedKeyResult<Self::PendingKeyState, Self::KeyState>>,
key::KeyEvents<Self::Event>,
) {
) -> (Option<key::NewPressedKey>, key::KeyEvents<Self::Event>) {
panic!()
}

Expand Down
9 changes: 3 additions & 6 deletions src/key/caps_word.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ impl key::Key for Key {
let caps_word_context = context.into();
let keymap_index: u16 = key_path.keymap_index();
let pke = self.new_pressed_key(caps_word_context, keymap_index);
let pks = key::PressedKeyResult::Resolved(key::NoOpKeyState::new().into());
(pks, pke.into_events())
let pkr = key::PressedKeyResult::NewPressedKey(key::NewPressedKey::NoOp);
(pkr, pke.into_events())
}

fn handle_event(
Expand All @@ -158,10 +158,7 @@ impl key::Key for Key {
_context: &Self::Context,
_key_path: key::KeyPath,
_event: key::Event<Self::Event>,
) -> (
Option<key::PressedKeyResult<Self::PendingKeyState, Self::KeyState>>,
key::KeyEvents<Self::Event>,
) {
) -> (Option<key::NewPressedKey>, key::KeyEvents<Self::Event>) {
panic!()
}

Expand Down
75 changes: 33 additions & 42 deletions src/key/chorded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,6 @@ where
K::Event: TryInto<Event>,
K::Event: From<Event>,
K::PendingKeyState: From<PendingKeyState>,
K::KeyState: From<key::NoOpKeyState<K::Context, K::Event>>,
{
/// Constructs new pressed key.
pub fn new_pressed_key(
Expand All @@ -320,12 +319,12 @@ where
chorded_ctx.config.chords.get(resolved_chord_id as usize)
{
if resolved_chord_indices.as_slice()[0] == keymap_index {
if let Some((_, k)) = self
if let Some((_, _k)) = self
.chords
.iter()
.find(|(ch_id, _)| *ch_id == resolved_chord_id)
{
Some((1 + resolved_chord_id, k))
Some(1 + resolved_chord_id)
} else {
panic!("check_resolution has invalid chord id")
}
Expand All @@ -336,15 +335,20 @@ where
panic!("check_resolution has invalid chord id")
}
}
ChordResolution::Passthrough => Some((0, &self.passthrough)),
ChordResolution::Passthrough => Some(0),
};

if let Some((i, k)) = maybe_pathel_key {
let (pkr, pke) = k.new_pressed_key(context, key_path);
if let Some(i) = maybe_pathel_key {
// PRESSED KEY PATH: add Chord (0 = passthrough, 1 = 1+chord_id)
(pkr.add_path_item(i as u16), pke)
let new_key_path = key_path.append_path_item(i as u16);
let pkr = key::PressedKeyResult::NewPressedKey(key::NewPressedKey::key_path(
new_key_path,
));
let pke = key::KeyEvents::no_events();

(pkr, pke)
} else {
let pkr = key::PressedKeyResult::Resolved(key::NoOpKeyState::new().into());
let pkr = key::PressedKeyResult::NewPressedKey(key::NewPressedKey::NoOp);
let pke = key::KeyEvents::no_events();
(pkr, pke)
}
Expand Down Expand Up @@ -407,10 +411,7 @@ impl<
context: &Self::Context,
key_path: key::KeyPath,
event: key::Event<Self::Event>,
) -> (
Option<key::PressedKeyResult<Self::PendingKeyState, Self::KeyState>>,
key::KeyEvents<Self::Event>,
) {
) -> (Option<key::NewPressedKey>, key::KeyEvents<Self::Event>) {
let keymap_index = key_path.keymap_index();
let ch_pks_res: Result<&mut PendingKeyState, _> = pending_state.try_into();
if let Ok(ch_pks) = ch_pks_res {
Expand All @@ -428,12 +429,12 @@ impl<
chorded_ctx.config.chords.get(resolved_chord_id as usize)
{
if resolved_chord_indices.as_slice()[0] == keymap_index {
if let Some((_, k)) = self
if let Some((_, _k)) = self
.chords
.iter()
.find(|(ch_id, _)| *ch_id == resolved_chord_id)
{
Some((1 + resolved_chord_id, k))
Some(1 + resolved_chord_id)
} else {
panic!("event's chord resolution has invalid chord id")
}
Expand All @@ -444,7 +445,7 @@ impl<
panic!("event's chord resolution has invalid chord id")
}
}
ChordResolution::Passthrough => Some((0, &self.passthrough)),
ChordResolution::Passthrough => Some(0),
};

let ch_r_ev = Event::ChordResolved(ch_state);
Expand All @@ -453,18 +454,16 @@ impl<
ch_r_ev.into(),
));

if let Some((i, nk)) = maybe_pathel_and_key {
let (pkr, mut pke) = nk.new_pressed_key(context, key_path);
if let Some(i) = maybe_pathel_and_key {
// PRESSED KEY PATH: add Chord (0 = passthrough, 1 = 1+chord_id)
let pkr = pkr.add_path_item(i as u16);
let new_key_path = key_path.append_path_item(i as u16);

pke.add_event(sch_ev);
let pke = key::KeyEvents::scheduled_event(sch_ev);

(Some(pkr), pke)
(Some(key::NewPressedKey::key_path(new_key_path)), pke)
} else {
let pkr = key::PressedKeyResult::Resolved(key::NoOpKeyState::new().into());
let pke = key::KeyEvents::scheduled_event(sch_ev);
(Some(pkr), pke)
(Some(key::NewPressedKey::no_op()), pke)
}
} else {
(None, key::KeyEvents::no_events())
Expand Down Expand Up @@ -520,7 +519,6 @@ where
K::Event: TryInto<Event>,
K::Event: From<Event>,
K::PendingKeyState: From<PendingKeyState>,
K::KeyState: From<key::NoOpKeyState<K::Context, K::Event>>,
{
/// Constructs new pressed key.
pub fn new_pressed_key(
Expand All @@ -539,14 +537,17 @@ where
if let PendingChordState::Resolved(resolution) = chord_resolution {
match resolution {
ChordResolution::Chord(_resolved_chord_id) => {
let pkr = key::PressedKeyResult::Resolved(key::NoOpKeyState::new().into());
let pkr = key::PressedKeyResult::NewPressedKey(key::NewPressedKey::NoOp);
let pke = key::KeyEvents::no_events();

(pkr, pke)
}
ChordResolution::Passthrough => {
let (pkr, pke) = self.passthrough.new_pressed_key(context, key_path);
let pkr = pkr.add_path_item(0); // 0 = passthrough key
let new_key_path = key_path.append_path_item(0); // 0 = passthrough key
let pkr = key::PressedKeyResult::NewPressedKey(key::NewPressedKey::key_path(
new_key_path,
));
let pke = key::KeyEvents::no_events();
(pkr, pke)
}
}
Expand Down Expand Up @@ -601,42 +602,32 @@ impl<
fn handle_event(
&self,
pending_state: &mut Self::PendingKeyState,
context: &Self::Context,
_context: &Self::Context,
key_path: key::KeyPath,
event: key::Event<Self::Event>,
) -> (
Option<key::PressedKeyResult<Self::PendingKeyState, Self::KeyState>>,
key::KeyEvents<Self::Event>,
) {
) -> (Option<key::NewPressedKey>, key::KeyEvents<Self::Event>) {
let keymap_index = key_path.keymap_index();
let ch_pks_res: Result<&mut PendingKeyState, _> = pending_state.try_into();
if let Ok(ch_pks) = ch_pks_res {
if let Ok(ch_ev) = event.try_into_key_event(|e| e.try_into()) {
let ch_state = ch_pks.handle_event(keymap_index, ch_ev);
if let Some(ChordResolution::Passthrough) = ch_state {
let nk = &self.passthrough;
let (pkr, mut pke) = nk.new_pressed_key(context, key_path);
let pkr = pkr.add_path_item(0); // 0 = passthrough key
let new_key_path = key_path.append_path_item(0); // 0 = passthrough key

let ch_r_ev = Event::ChordResolved(ChordResolution::Passthrough);
let sch_ev = key::ScheduledEvent::immediate(key::Event::key_event(
keymap_index,
ch_r_ev.into(),
));
pke.add_event(sch_ev);
let pke = key::KeyEvents::scheduled_event(sch_ev);

(Some(pkr), pke)
(Some(key::NewPressedKey::key_path(new_key_path)), pke)
} else if let Some(ChordResolution::Chord(resolved_chord_id)) = ch_state {
let ch_r_ev = Event::ChordResolved(ChordResolution::Chord(resolved_chord_id));
let pke =
key::KeyEvents::event(key::Event::key_event(keymap_index, ch_r_ev.into()));

(
Some(key::PressedKeyResult::Resolved(
key::NoOpKeyState::new().into(),
)),
pke,
)
(Some(key::NewPressedKey::no_op()), pke)
} else {
(None, key::KeyEvents::no_events())
}
Expand Down
5 changes: 1 addition & 4 deletions src/key/composite/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,7 @@ impl key::Key for BaseKey {
_context: &Self::Context,
_key_path: key::KeyPath,
_event: key::Event<Self::Event>,
) -> (
Option<key::PressedKeyResult<Self::PendingKeyState, Self::KeyState>>,
key::KeyEvents<Self::Event>,
) {
) -> (Option<key::NewPressedKey>, key::KeyEvents<Self::Event>) {
panic!()
}

Expand Down
10 changes: 2 additions & 8 deletions src/key/composite/chorded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,7 @@ impl<K: ChordedNestable> key::Key for ChordedKey<K> {
context: &Self::Context,
key_path: key::KeyPath,
event: key::Event<Self::Event>,
) -> (
Option<key::PressedKeyResult<Self::PendingKeyState, Self::KeyState>>,
key::KeyEvents<Self::Event>,
) {
) -> (Option<key::NewPressedKey>, key::KeyEvents<Self::Event>) {
match self {
ChordedKey::Chorded(key) => key.handle_event(pending_state, context, key_path, event),
ChordedKey::Auxiliary(key) => key.handle_event(pending_state, context, key_path, event),
Expand Down Expand Up @@ -115,10 +112,7 @@ impl<K: ChordedNestable> key::Key for Chorded<K> {
context: &Self::Context,
key_path: key::KeyPath,
event: key::Event<Self::Event>,
) -> (
Option<key::PressedKeyResult<Self::PendingKeyState, Self::KeyState>>,
key::KeyEvents<Self::Event>,
) {
) -> (Option<key::NewPressedKey>, key::KeyEvents<Self::Event>) {
let Chorded(key) = self;
key.handle_event(pending_state, context, key_path, event)
}
Expand Down
10 changes: 2 additions & 8 deletions src/key/composite/layered.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,7 @@ impl<K: LayeredNestable> key::Key for LayeredKey<K> {
context: &Self::Context,
key_path: key::KeyPath,
event: key::Event<Self::Event>,
) -> (
Option<key::PressedKeyResult<Self::PendingKeyState, Self::KeyState>>,
key::KeyEvents<Self::Event>,
) {
) -> (Option<key::NewPressedKey>, key::KeyEvents<Self::Event>) {
match self {
LayeredKey::Layered(key) => key.handle_event(pending_state, context, key_path, event),
LayeredKey::Pass(key) => key.handle_event(pending_state, context, key_path, event),
Expand Down Expand Up @@ -109,10 +106,7 @@ impl<K: LayeredNestable> key::Key for Layered<K> {
context: &Self::Context,
key_path: key::KeyPath,
event: key::Event<Self::Event>,
) -> (
Option<key::PressedKeyResult<Self::PendingKeyState, Self::KeyState>>,
key::KeyEvents<Self::Event>,
) {
) -> (Option<key::NewPressedKey>, key::KeyEvents<Self::Event>) {
let Layered(key) = self;
key.handle_event(pending_state, context, key_path, event)
}
Expand Down
10 changes: 2 additions & 8 deletions src/key/composite/tap_hold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,7 @@ impl<K: TapHoldNestable> key::Key for TapHoldKey<K> {
context: &Self::Context,
key_path: key::KeyPath,
event: key::Event<Self::Event>,
) -> (
Option<key::PressedKeyResult<Self::PendingKeyState, Self::KeyState>>,
key::KeyEvents<Self::Event>,
) {
) -> (Option<key::NewPressedKey>, key::KeyEvents<Self::Event>) {
match self {
TapHoldKey::TapDance(key) => key.handle_event(pending_state, context, key_path, event),
TapHoldKey::TapHold(key) => key.handle_event(pending_state, context, key_path, event),
Expand Down Expand Up @@ -118,10 +115,7 @@ impl<K: TapHoldNestable> key::Key for TapHold<K> {
context: &Self::Context,
key_path: key::KeyPath,
event: key::Event<Self::Event>,
) -> (
Option<key::PressedKeyResult<Self::PendingKeyState, Self::KeyState>>,
key::KeyEvents<Self::Event>,
) {
) -> (Option<key::NewPressedKey>, key::KeyEvents<Self::Event>) {
let TapHold(key) = self;
key.handle_event(pending_state, context, key_path, event)
}
Expand Down
Loading