Skip to main content

pc_keyboard/layouts/
colemak.rs

1//! Colemak keyboard support
2
3use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard};
4
5/// A Colemak 101-key (or 104-key including Windows keys) keyboard.
6///
7/// Has a 1-row high Enter key, with Oem5 above (ANSI layout).
8///
9/// Based on US 101/104 key, with the letters re-arranged.
10///
11/// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We
12/// show either a Unicode glyph, or a hex number if the glyph isn't a
13/// printable character. Blank spaces are passed through as
14/// [`DecodedKey::RawKey`].
15///
16/// Run the `print_keyboard` example to re-generate these images.
17///
18/// ## Unmodified
19///
20/// ```text
21/// ┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
22/// │001b│  │    │    │    │    │  │    │    │    │    │  │    │    │    │    │   │    │    │    │
23/// └────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘   └────┴────┴────┘
24///
25/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐  ┌────┬────┬────┐  ┌────┬────┬────┬────┐
26/// │ `  │ 1  │ 2  │ 3  │ 4  │ 5  │ 6  │ 7  │ 8  │ 9  │ 0  │ -  │ =  │  0008   │  │    │    │    │  │    │ /  │ *  │ -  │
27/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤  ├────┼────┼────┤  ├────┼────┼────┼────┤
28/// │0009 │ q  │ w  │ f  │ p  │ g  │ j  │ l  │ u  │ y  │ ;  │ [  │ ]  │   \    │  │007f│    │    │  │ 7  │ 8  │ 9  │    │
29/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤  └────┴────┴────┘  ├────┼────┼────┤ +  │
30/// │      │ a  │ r  │ s  │ t  │ d  │ h  │ n  │ e  │ i  │ o  │ '  │   000a     │                    │ 4  │ 5  │ 6  │    │
31/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤       ┌────┐       ├────┼────┼────┼────┤
32/// │         │ z  │ x  │ c  │ v  │ b  │ k  │ m  │ ,  │ .  │ /  │              │       │    │       │ 1  │ 2  │ 3  │    │
33/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤  ┌────┼────┼────┐  ├────┴────┼────┤000a│
34/// │     │     │     │             0020             │     │     │      │      │  │    │    │    │  │ 0       │ .  │    │
35/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘  └────┴────┴────┘  └─────────┴────┴────┘
36/// ```
37///
38/// ## Caps Lock
39///
40/// ```text
41/// ┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
42/// │001b│  │    │    │    │    │  │    │    │    │    │  │    │    │    │    │   │    │    │    │
43/// └────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘   └────┴────┴────┘
44///
45/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐  ┌────┬────┬────┐  ┌────┬────┬────┬────┐
46/// │ `  │ 1  │ 2  │ 3  │ 4  │ 5  │ 6  │ 7  │ 8  │ 9  │ 0  │ -  │ =  │  0008   │  │    │    │    │  │    │ /  │ *  │ -  │
47/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤  ├────┼────┼────┤  ├────┼────┼────┼────┤
48/// │0009 │ Q  │ W  │ F  │ P  │ G  │ J  │ L  │ U  │ Y  │ ;  │ [  │ ]  │   \    │  │007f│    │    │  │ 7  │ 8  │ 9  │    │
49/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤  └────┴────┴────┘  ├────┼────┼────┤ +  │
50/// │      │ A  │ R  │ S  │ T  │ D  │ H  │ N  │ E  │ I  │ O  │ '  │   000a     │                    │ 4  │ 5  │ 6  │    │
51/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤       ┌────┐       ├────┼────┼────┼────┤
52/// │         │ Z  │ X  │ C  │ V  │ B  │ K  │ M  │ ,  │ .  │ /  │              │       │    │       │ 1  │ 2  │ 3  │    │
53/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤  ┌────┼────┼────┐  ├────┴────┼────┤000a│
54/// │     │     │     │             0020             │     │     │      │      │  │    │    │    │  │ 0       │ .  │    │
55/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘  └────┴────┴────┘  └─────────┴────┴────┘
56/// ```
57///
58/// ## Shifted
59///
60/// ```text
61/// ┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
62/// │001b│  │    │    │    │    │  │    │    │    │    │  │    │    │    │    │   │    │    │    │
63/// └────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘   └────┴────┴────┘
64///
65/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐  ┌────┬────┬────┐  ┌────┬────┬────┬────┐
66/// │ ~  │ !  │ @  │ #  │ $  │ %  │ ^  │ &  │ *  │ (  │ )  │ _  │ +  │  0008   │  │    │    │    │  │    │ /  │ *  │ -  │
67/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤  ├────┼────┼────┤  ├────┼────┼────┼────┤
68/// │0009 │ Q  │ W  │ F  │ P  │ G  │ J  │ L  │ U  │ Y  │ :  │ {  │ }  │   |    │  │007f│    │    │  │ 7  │ 8  │ 9  │    │
69/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤  └────┴────┴────┘  ├────┼────┼────┤ +  │
70/// │      │ A  │ R  │ S  │ T  │ D  │ H  │ N  │ E  │ I  │ O  │ "  │   000a     │                    │ 4  │ 5  │ 6  │    │
71/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤       ┌────┐       ├────┼────┼────┼────┤
72/// │         │ Z  │ X  │ C  │ V  │ B  │ K  │ M  │ <  │ >  │ ?  │              │       │    │       │ 1  │ 2  │ 3  │    │
73/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤  ┌────┼────┼────┐  ├────┴────┼────┤000a│
74/// │     │     │     │             0020             │     │     │      │      │  │    │    │    │  │ 0       │ .  │    │
75/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘  └────┴────┴────┘  └─────────┴────┴────┘
76/// ```
77///
78/// ## Control
79///
80/// ```text
81/// ┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
82/// │001b│  │    │    │    │    │  │    │    │    │    │  │    │    │    │    │   │    │    │    │
83/// └────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘   └────┴────┴────┘
84///
85/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐  ┌────┬────┬────┐  ┌────┬────┬────┬────┐
86/// │ `  │ 1  │ 2  │ 3  │ 4  │ 5  │ 6  │ 7  │ 8  │ 9  │ 0  │ -  │ =  │  0008   │  │    │    │    │  │    │ /  │ *  │ -  │
87/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤  ├────┼────┼────┤  ├────┼────┼────┼────┤
88/// │0009 │0011│0017│0006│0010│0007│000a│000c│0015│0019│ ;  │ [  │ ]  │   \    │  │007f│    │    │  │ 7  │ 8  │ 9  │    │
89/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤  └────┴────┴────┘  ├────┼────┼────┤ +  │
90/// │      │0001│0012│0013│0014│0004│0008│000e│0005│0009│000f│ '  │   000a     │                    │ 4  │ 5  │ 6  │    │
91/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤       ┌────┐       ├────┼────┼────┼────┤
92/// │         │001a│0018│0003│0016│0002│000b│000d│ ,  │ .  │ /  │              │       │    │       │ 1  │ 2  │ 3  │    │
93/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤  ┌────┼────┼────┐  ├────┴────┼────┤000a│
94/// │     │     │     │             0020             │     │     │      │      │  │    │    │    │  │ 0       │ .  │    │
95/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘  └────┴────┴────┘  └─────────┴────┴────┘
96/// ```
97///
98/// ## AltGr
99///
100/// ```text
101/// ┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
102/// │001b│  │    │    │    │    │  │    │    │    │    │  │    │    │    │    │   │    │    │    │
103/// └────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘   └────┴────┴────┘
104///
105/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐  ┌────┬────┬────┐  ┌────┬────┬────┬────┐
106/// │ `  │ 1  │ 2  │ 3  │ 4  │ 5  │ 6  │ 7  │ 8  │ 9  │ 0  │ -  │ =  │  0008   │  │    │    │    │  │    │ /  │ *  │ -  │
107/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤  ├────┼────┼────┤  ├────┼────┼────┼────┤
108/// │0009 │ q  │ w  │ f  │ p  │ g  │ j  │ l  │ u  │ y  │ ;  │ [  │ ]  │   \    │  │007f│    │    │  │ 7  │ 8  │ 9  │    │
109/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤  └────┴────┴────┘  ├────┼────┼────┤ +  │
110/// │      │ a  │ r  │ s  │ t  │ d  │ h  │ n  │ e  │ i  │ o  │ '  │   000a     │                    │ 4  │ 5  │ 6  │    │
111/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤       ┌────┐       ├────┼────┼────┼────┤
112/// │         │ z  │ x  │ c  │ v  │ b  │ k  │ m  │ ,  │ .  │ /  │              │       │    │       │ 1  │ 2  │ 3  │    │
113/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤  ┌────┼────┼────┐  ├────┴────┼────┤000a│
114/// │     │     │     │             0020             │     │     │      │      │  │    │    │    │  │ 0       │ .  │    │
115/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘  └────┴────┴────┘  └─────────┴────┴────┘
116/// ```
117///
118/// ## Shift AltGr
119///
120/// ```text
121/// ┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
122/// │001b│  │    │    │    │    │  │    │    │    │    │  │    │    │    │    │   │    │    │    │
123/// └────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘   └────┴────┴────┘
124///
125/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐  ┌────┬────┬────┐  ┌────┬────┬────┬────┐
126/// │ ~  │ !  │ @  │ #  │ $  │ %  │ ^  │ &  │ *  │ (  │ )  │ _  │ +  │  0008   │  │    │    │    │  │    │ /  │ *  │ -  │
127/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤  ├────┼────┼────┤  ├────┼────┼────┼────┤
128/// │0009 │ Q  │ W  │ F  │ P  │ G  │ J  │ L  │ U  │ Y  │ :  │ {  │ }  │   |    │  │007f│    │    │  │ 7  │ 8  │ 9  │    │
129/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤  └────┴────┴────┘  ├────┼────┼────┤ +  │
130/// │      │ A  │ R  │ S  │ T  │ D  │ H  │ N  │ E  │ I  │ O  │ "  │   000a     │                    │ 4  │ 5  │ 6  │    │
131/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤       ┌────┐       ├────┼────┼────┼────┤
132/// │         │ Z  │ X  │ C  │ V  │ B  │ K  │ M  │ <  │ >  │ ?  │              │       │    │       │ 1  │ 2  │ 3  │    │
133/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤  ┌────┼────┼────┐  ├────┴────┼────┤000a│
134/// │     │     │     │             0020             │     │     │      │      │  │    │    │    │  │ 0       │ .  │    │
135/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘  └────┴────┴────┘  └─────────┴────┴────┘
136/// ```
137pub struct Colemak;
138
139impl KeyboardLayout for Colemak {
140    #[rustfmt::skip]
141    fn map_keycode(
142        &self,
143        keycode: KeyCode,
144        modifiers: &Modifiers,
145        handle_ctrl: HandleControl,
146    ) -> DecodedKey {
147        match keycode {
148            // ========= Row 3 (QWERTY) =========
149            KeyCode::E    => modifiers.handle_ascii_2('F', handle_ctrl),
150            KeyCode::R    => modifiers.handle_ascii_2('P', handle_ctrl),
151            KeyCode::T    => modifiers.handle_ascii_2('G', handle_ctrl),
152            KeyCode::Y    => modifiers.handle_ascii_2('J', handle_ctrl),
153            KeyCode::U    => modifiers.handle_ascii_2('L', handle_ctrl),
154            KeyCode::I    => modifiers.handle_ascii_2('U', handle_ctrl),
155            KeyCode::O    => modifiers.handle_ascii_2('Y', handle_ctrl),
156            KeyCode::P    => modifiers.handle_symbol2(';', ':'),
157            // ========= Row 4 (ASDFG) =========
158            KeyCode::S    => modifiers.handle_ascii_2('R', handle_ctrl),
159            KeyCode::D    => modifiers.handle_ascii_2('S', handle_ctrl),
160            KeyCode::F    => modifiers.handle_ascii_2('T', handle_ctrl),
161            KeyCode::G    => modifiers.handle_ascii_2('D', handle_ctrl),
162            KeyCode::J    => modifiers.handle_ascii_2('N', handle_ctrl),
163            KeyCode::K    => modifiers.handle_ascii_2('E', handle_ctrl),
164            KeyCode::L    => modifiers.handle_ascii_2('I', handle_ctrl),
165            KeyCode::Oem1 => modifiers.handle_ascii_2('O', handle_ctrl),
166            // ========= Row 5 (ZXCVB) =========
167            KeyCode::N    => modifiers.handle_ascii_2('K', handle_ctrl),
168            // ========= Fallback ========= 
169            e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl),
170        }
171    }
172
173    fn get_physical(&self) -> PhysicalKeyboard {
174        PhysicalKeyboard::Ansi
175    }
176}