Skip to main content

smart_keymap_core/key/
history.rs

1//! History keys: behaviours that depend on previously resolved key output.
2//!
3//! v1 provides [Key::Repeat](crate::key::history::Key::Repeat), which re-emits
4//! the last remembered [crate::key::KeyOutput] as the pressed key's own output
5//! while held.
6
7use core::fmt::Debug;
8use core::marker::PhantomData;
9
10use serde::Deserialize;
11
12use crate::key;
13use crate::keymap;
14
15/// Reference for a history key.
16#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
17pub struct Ref(pub Key);
18
19/// History key kinds.
20#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
21pub enum Key {
22    /// Re-emit the last remembered key output while pressed.
23    Repeat,
24}
25
26impl Key {
27    /// Constructs a [Key::Repeat].
28    pub const fn new_repeat() -> Self {
29        Key::Repeat
30    }
31}
32
33/// Whether a resolved [key::KeyOutput] should become the remembered last output.
34///
35/// Empty / no-op outputs are ignored so that pressing Repeat with no history
36/// (or keys that resolve without output) does not clear a prior memory.
37pub fn is_rememberable(key_output: &key::KeyOutput) -> bool {
38    *key_output != key::KeyOutput::NO_OUTPUT
39}
40
41/// Context for history keys: tracks the last rememberable resolved output.
42#[derive(Debug, Clone, Copy, PartialEq)]
43pub struct Context {
44    last: Option<key::KeyOutput>,
45}
46
47impl Default for Context {
48    fn default() -> Self {
49        Self::new()
50    }
51}
52
53impl Context {
54    /// Constructs a new [Context].
55    pub const fn new() -> Self {
56        Context { last: None }
57    }
58
59    /// Clear remembered history.
60    pub fn reset(&mut self) {
61        *self = Self::new();
62    }
63
64    /// The last rememberable resolved key output, if any.
65    pub fn last(&self) -> Option<key::KeyOutput> {
66        self.last
67    }
68
69    fn handle_event(&mut self, event: key::Event<Event>) -> key::KeyEvents<Event> {
70        if let key::Event::Keymap(keymap::KeymapEvent::ResolvedKeyOutput { key_output, .. }) = event
71        {
72            if is_rememberable(&key_output) {
73                self.last = Some(key_output);
74            }
75        }
76        key::KeyEvents::no_events()
77    }
78}
79
80impl key::Context for Context {
81    type Event = Event;
82
83    fn handle_event(&mut self, event: key::Event<Self::Event>) -> key::KeyEvents<Self::Event> {
84        self.handle_event(event)
85    }
86
87    fn reset(&mut self) {
88        Context::reset(self);
89    }
90}
91
92/// Events for history keys. (None for v1.)
93#[derive(Debug, Clone, Copy, PartialEq)]
94pub struct Event;
95
96/// Pending key state type for history keys. (No pending state.)
97#[derive(Debug, Clone, Copy, PartialEq)]
98pub struct PendingKeyState;
99
100/// Pressed state: the output being repeated (if any) for the hold duration.
101#[derive(Debug, Clone, Copy, PartialEq)]
102pub struct KeyState {
103    output: Option<key::KeyOutput>,
104}
105
106impl KeyState {
107    /// Constructs a key state with the given output.
108    pub const fn new(output: Option<key::KeyOutput>) -> Self {
109        Self { output }
110    }
111
112    /// The output this pressed history key contributes, if any.
113    pub const fn output(&self) -> Option<key::KeyOutput> {
114        self.output
115    }
116}
117
118/// The [key::System] implementation for history keys.
119#[derive(Debug, Clone, Copy, PartialEq)]
120pub struct System<R>(PhantomData<R>);
121
122impl<R> System<R> {
123    /// Constructs a new [System].
124    pub const fn new() -> Self {
125        Self(PhantomData)
126    }
127}
128
129impl<R> Default for System<R> {
130    fn default() -> Self {
131        Self::new()
132    }
133}
134
135impl<R: Debug> key::System<R> for System<R> {
136    type Ref = Ref;
137    type Context = Context;
138    type Event = Event;
139    type PendingKeyState = PendingKeyState;
140    type KeyState = KeyState;
141
142    fn new_pressed_key(
143        &self,
144        _keymap_index: u16,
145        context: &Self::Context,
146        Ref(key): Ref,
147    ) -> (
148        key::PressedKeyResult<R, Self::PendingKeyState, Self::KeyState>,
149        key::KeyEvents<Self::Event>,
150    ) {
151        let output = match key {
152            Key::Repeat => context.last(),
153        };
154        (
155            key::PressedKeyResult::Resolved(KeyState::new(output)),
156            key::KeyEvents::no_events(),
157        )
158    }
159
160    fn update_pending_state(
161        &self,
162        _pending_state: &mut Self::PendingKeyState,
163        _keymap_index: u16,
164        _context: &Self::Context,
165        _key_ref: Ref,
166        _event: key::Event<Self::Event>,
167    ) -> (Option<key::NewPressedKey<R>>, key::KeyEvents<Self::Event>) {
168        panic!()
169    }
170
171    fn key_output(
172        &self,
173        _key_ref: &Self::Ref,
174        key_state: &Self::KeyState,
175    ) -> Option<key::KeyOutput> {
176        key_state.output()
177    }
178}
179
180#[cfg(test)]
181mod tests {
182    use super::*;
183    use crate::key::System as _;
184
185    #[test]
186    fn test_sizeof_ref() {
187        assert_eq!(0, core::mem::size_of::<Ref>());
188    }
189
190    #[test]
191    fn test_sizeof_event() {
192        assert_eq!(0, core::mem::size_of::<Event>());
193    }
194
195    #[test]
196    fn context_remembers_resolved_keyboard_output() {
197        let mut ctx = Context::new();
198        assert_eq!(None, ctx.last());
199
200        let key_output = key::KeyOutput::from_key_code(0x04);
201        let _ = key::Context::handle_event(
202            &mut ctx,
203            key::Event::Keymap(keymap::KeymapEvent::ResolvedKeyOutput {
204                keymap_index: 0,
205                key_output,
206            }),
207        );
208
209        assert_eq!(Some(key_output), ctx.last());
210    }
211
212    #[test]
213    fn context_ignores_empty_output() {
214        let mut ctx = Context::new();
215        let remembered = key::KeyOutput::from_key_code(0x04);
216        ctx.last = Some(remembered);
217
218        let _ = key::Context::handle_event(
219            &mut ctx,
220            key::Event::Keymap(keymap::KeymapEvent::ResolvedKeyOutput {
221                keymap_index: 0,
222                key_output: key::KeyOutput::NO_OUTPUT,
223            }),
224        );
225
226        assert_eq!(Some(remembered), ctx.last());
227    }
228
229    #[test]
230    fn repeat_pressed_key_uses_context_last() {
231        let system = System::<()>::new();
232        let mut ctx = Context::new();
233        let key_output = key::KeyOutput::from_key_code(0x05);
234        ctx.last = Some(key_output);
235
236        let (pkr, _) = system.new_pressed_key(0, &ctx, Ref(Key::Repeat));
237        let ks = pkr.unwrap_resolved();
238        assert_eq!(Some(key_output), system.key_output(&Ref(Key::Repeat), &ks));
239    }
240}