Skip to main content

fret_runtime/keymap/
types.rs

1use crate::{CommandId, KeyChord, Platform, WhenExpr};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4pub enum PlatformFilter {
5    All,
6    Macos,
7    Windows,
8    Linux,
9    Web,
10}
11
12impl PlatformFilter {
13    pub fn matches(self, platform: Platform) -> bool {
14        match self {
15            Self::All => true,
16            Self::Macos => platform == Platform::Macos,
17            Self::Windows => platform == Platform::Windows,
18            Self::Linux => platform == Platform::Linux,
19            Self::Web => platform == Platform::Web,
20        }
21    }
22}
23
24#[derive(Debug, Clone)]
25pub struct Binding {
26    pub platform: PlatformFilter,
27    pub sequence: Vec<KeyChord>,
28    pub when: Option<WhenExpr>,
29    pub command: Option<CommandId>,
30}
31
32#[derive(Debug, Clone)]
33pub struct DefaultKeybinding {
34    pub platform: PlatformFilter,
35    pub sequence: Vec<KeyChord>,
36    pub when: Option<WhenExpr>,
37}
38
39impl DefaultKeybinding {
40    pub fn single(platform: PlatformFilter, chord: KeyChord) -> Self {
41        Self {
42            platform,
43            sequence: vec![chord],
44            when: None,
45        }
46    }
47}
48
49#[derive(Debug, Default, Clone)]
50pub struct Keymap {
51    pub(super) bindings: Vec<Binding>,
52}
53
54#[derive(Debug, Clone, PartialEq, Eq, Hash)]
55pub struct KeymapBindingSignature {
56    pub platform: PlatformFilter,
57    pub sequence: Vec<KeyChord>,
58    pub when: Option<WhenExpr>,
59}
60
61#[derive(Debug, Clone, Copy, PartialEq, Eq)]
62pub enum KeymapConflictKind {
63    /// Multiple bindings exist, but they all resolve to the same command payload.
64    Redundant,
65    /// Later bindings override earlier ones (last-wins) with a different command payload.
66    Override,
67    /// At least one binding explicitly unbinds (`command: null`), shadowing earlier bindings.
68    Unbind,
69}
70
71#[derive(Debug, Clone, PartialEq, Eq)]
72pub struct KeymapConflictEntry {
73    pub index: usize,
74    pub command: Option<CommandId>,
75}
76
77#[derive(Debug, Clone, PartialEq, Eq)]
78pub struct KeymapConflict {
79    pub signature: KeymapBindingSignature,
80    pub kind: KeymapConflictKind,
81    /// Oldest -> newest (so the effective winner is `entries.last()`).
82    pub entries: Vec<KeymapConflictEntry>,
83}
84
85#[derive(Debug, Clone, Copy, PartialEq, Eq)]
86pub enum WhenValidationMode {
87    Strict,
88    Lenient,
89}
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq)]
92pub struct KeymapLoadOptions {
93    pub when_validation: WhenValidationMode,
94}
95
96impl Default for KeymapLoadOptions {
97    fn default() -> Self {
98        Self {
99            when_validation: WhenValidationMode::Strict,
100        }
101    }
102}
103
104#[derive(Debug, Clone)]
105pub struct SequenceMatch {
106    /// `Some(Some(cmd))` if an exact binding exists and is bound, `Some(None)` if explicitly unbound,
107    /// and `None` if no exact binding exists under the provided context.
108    pub exact: Option<Option<CommandId>>,
109    /// True if any longer binding exists that starts with the provided sequence under the same context.
110    pub has_continuation: bool,
111}
112
113#[derive(Debug, Clone)]
114pub struct KeymapContinuation {
115    pub next: KeyChord,
116    pub matched: SequenceMatch,
117}