Skip to repository content1503 lines · 39.2 KB · rust
tenant.openagents/omega
No repository description is available.
OpenAgents Git authority 2026-07-28T02:36:49.541Z Public web read
NIP-34 coordinate
30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omegaMaintainersHidden in public view
References2 branches · 1 tag
Read-only clone
git clone https://openagents.com/git/tenant.openagents/omega.gitBrowse files
keyboard.rs
1use collections::HashMap;
2use std::ffi::{CStr, c_void};
3
4use objc::{msg_send, runtime::Object, sel, sel_impl};
5
6use gpui::{KeybindingKeystroke, Keystroke, PlatformKeyboardLayout, PlatformKeyboardMapper};
7
8use crate::{
9 TISCopyCurrentKeyboardLayoutInputSource, TISGetInputSourceProperty, kTISPropertyInputSourceID,
10 kTISPropertyLocalizedName,
11};
12
13pub(crate) struct MacKeyboardLayout {
14 id: String,
15 name: String,
16}
17
18pub(crate) struct MacKeyboardMapper {
19 key_equivalents: Option<HashMap<char, char>>,
20}
21
22impl PlatformKeyboardLayout for MacKeyboardLayout {
23 fn id(&self) -> &str {
24 &self.id
25 }
26
27 fn name(&self) -> &str {
28 &self.name
29 }
30}
31
32impl PlatformKeyboardMapper for MacKeyboardMapper {
33 fn map_key_equivalent(
34 &self,
35 mut keystroke: Keystroke,
36 use_key_equivalents: bool,
37 ) -> KeybindingKeystroke {
38 if use_key_equivalents && let Some(key_equivalents) = &self.key_equivalents {
39 if keystroke.key.chars().count() == 1
40 && let Some(key) = key_equivalents.get(&keystroke.key.chars().next().unwrap())
41 {
42 keystroke.key = key.to_string();
43 }
44 }
45 KeybindingKeystroke::from_keystroke(keystroke)
46 }
47
48 fn get_key_equivalents(&self) -> Option<&HashMap<char, char>> {
49 self.key_equivalents.as_ref()
50 }
51}
52
53impl MacKeyboardLayout {
54 pub(crate) fn new() -> Self {
55 unsafe {
56 let current_keyboard = TISCopyCurrentKeyboardLayoutInputSource();
57
58 let id: *mut Object = TISGetInputSourceProperty(
59 current_keyboard,
60 kTISPropertyInputSourceID as *const c_void,
61 );
62 let id: *const std::os::raw::c_char = msg_send![id, UTF8String];
63 let id = CStr::from_ptr(id).to_str().unwrap().to_string();
64
65 let name: *mut Object = TISGetInputSourceProperty(
66 current_keyboard,
67 kTISPropertyLocalizedName as *const c_void,
68 );
69 let name: *const std::os::raw::c_char = msg_send![name, UTF8String];
70 let name = CStr::from_ptr(name).to_str().unwrap().to_string();
71
72 let _: () = msg_send![current_keyboard, release];
73
74 Self { id, name }
75 }
76 }
77}
78
79impl MacKeyboardMapper {
80 pub(crate) fn new(layout_id: &str) -> Self {
81 let key_equivalents = get_key_equivalents(layout_id);
82
83 Self { key_equivalents }
84 }
85}
86
87// On some keyboards (e.g. German QWERTZ) it is not possible to type the full ASCII range
88// without using option. This means that some of our built in keyboard shortcuts do not work
89// for those users.
90//
91// The way macOS solves this problem is to move shortcuts around so that they are all reachable,
92// even if the mnemonic changes. https://developer.apple.com/documentation/swiftui/keyboardshortcut/localization-swift.struct
93//
94// For example, cmd-> is the "switch window" shortcut because the > key is right above tab.
95// To ensure this doesn't cause problems for shortcuts defined for a QWERTY layout, apple moves
96// any shortcuts defined as cmd-> to cmd-:. Coincidentally this s also the same keyboard position
97// as cmd-> on a QWERTY layout.
98//
99// Another example is cmd-[ and cmd-], as they cannot be typed without option, those keys are remapped to cmd-ö
100// and cmd-ä. These shortcuts are not in the same position as a QWERTY keyboard, because on a QWERTZ keyboard
101// the + key is in the way; and shortcuts bound to cmd-+ are still typed as cmd-+ on either keyboard (though the
102// specific key moves)
103//
104// As far as I can tell, there's no way to query the mappings Apple uses except by rendering a menu with every
105// possible key combination, and inspecting the UI to see what it rendered. So that's what we did...
106//
107// These mappings were generated by running https://github.com/ConradIrwin/keyboard-inspector, tidying up the
108// output to remove languages with no mappings and other oddities, and converting it to a less verbose representation with:
109// jq -s 'map(to_entries | map({key: .key, value: [(.value | to_entries | map(.key) | concat()), (.value | to_entries | map(.value) | concat())]}) | from_entries) | add'
110// From there I used multi-cursor to produce this match statement.
111fn get_key_equivalents(layout_id: &str) -> Option<HashMap<char, char>> {
112 let mappings: &[(char, char)] = match layout_id {
113 "com.apple.keylayout.ABC-AZERTY" => &[
114 ('!', '1'),
115 ('"', '%'),
116 ('#', '3'),
117 ('$', '4'),
118 ('%', '5'),
119 ('&', '7'),
120 ('(', '9'),
121 (')', '0'),
122 ('*', '8'),
123 ('.', ';'),
124 ('/', ':'),
125 ('0', 'à'),
126 ('1', '&'),
127 ('2', 'é'),
128 ('3', '"'),
129 ('4', '\''),
130 ('5', '('),
131 ('6', '§'),
132 ('7', 'è'),
133 ('8', '!'),
134 ('9', 'ç'),
135 (':', '°'),
136 (';', ')'),
137 ('<', '.'),
138 ('>', '/'),
139 ('@', '2'),
140 ('[', '^'),
141 ('\'', 'ù'),
142 ('\\', '`'),
143 (']', '$'),
144 ('^', '6'),
145 ('`', '<'),
146 ('{', '¨'),
147 ('|', '£'),
148 ('}', '*'),
149 ('~', '>'),
150 ],
151 "com.apple.keylayout.ABC-QWERTZ" => &[
152 ('"', '`'),
153 ('#', '§'),
154 ('&', '/'),
155 ('(', ')'),
156 (')', '='),
157 ('*', '('),
158 ('/', 'ß'),
159 (':', 'Ü'),
160 (';', 'ü'),
161 ('<', ';'),
162 ('=', '*'),
163 ('>', ':'),
164 ('@', '"'),
165 ('[', 'ö'),
166 ('\'', '´'),
167 ('\\', '#'),
168 (']', 'ä'),
169 ('^', '&'),
170 ('`', '<'),
171 ('{', 'Ö'),
172 ('|', '\''),
173 ('}', 'Ä'),
174 ('~', '>'),
175 ],
176 "com.apple.keylayout.Albanian" => &[
177 ('"', '\''),
178 (':', 'Ç'),
179 (';', 'ç'),
180 ('<', ';'),
181 ('>', ':'),
182 ('@', '"'),
183 ('\'', '@'),
184 ('\\', 'ë'),
185 ('`', '<'),
186 ('|', 'Ë'),
187 ('~', '>'),
188 ],
189 "com.apple.keylayout.Austrian" => &[
190 ('"', '`'),
191 ('#', '§'),
192 ('&', '/'),
193 ('(', ')'),
194 (')', '='),
195 ('*', '('),
196 ('/', 'ß'),
197 (':', 'Ü'),
198 (';', 'ü'),
199 ('<', ';'),
200 ('=', '*'),
201 ('>', ':'),
202 ('@', '"'),
203 ('[', 'ö'),
204 ('\'', '´'),
205 ('\\', '#'),
206 (']', 'ä'),
207 ('^', '&'),
208 ('`', '<'),
209 ('{', 'Ö'),
210 ('|', '\''),
211 ('}', 'Ä'),
212 ('~', '>'),
213 ],
214 "com.apple.keylayout.Azeri" => &[
215 ('"', 'Ə'),
216 (',', 'ç'),
217 ('.', 'ş'),
218 ('/', '.'),
219 (':', 'I'),
220 (';', 'ı'),
221 ('<', 'Ç'),
222 ('>', 'Ş'),
223 ('?', ','),
224 ('W', 'Ü'),
225 ('[', 'ö'),
226 ('\'', 'ə'),
227 (']', 'ğ'),
228 ('w', 'ü'),
229 ('{', 'Ö'),
230 ('|', '/'),
231 ('}', 'Ğ'),
232 ],
233 "com.apple.keylayout.Belgian" => &[
234 ('!', '1'),
235 ('"', '%'),
236 ('#', '3'),
237 ('$', '4'),
238 ('%', '5'),
239 ('&', '7'),
240 ('(', '9'),
241 (')', '0'),
242 ('*', '8'),
243 ('.', ';'),
244 ('/', ':'),
245 ('0', 'à'),
246 ('1', '&'),
247 ('2', 'é'),
248 ('3', '"'),
249 ('4', '\''),
250 ('5', '('),
251 ('6', '§'),
252 ('7', 'è'),
253 ('8', '!'),
254 ('9', 'ç'),
255 (':', '°'),
256 (';', ')'),
257 ('<', '.'),
258 ('>', '/'),
259 ('@', '2'),
260 ('[', '^'),
261 ('\'', 'ù'),
262 ('\\', '`'),
263 (']', '$'),
264 ('^', '6'),
265 ('`', '<'),
266 ('{', '¨'),
267 ('|', '£'),
268 ('}', '*'),
269 ('~', '>'),
270 ],
271 "com.apple.keylayout.Brazilian-ABNT2" => &[
272 ('"', '`'),
273 ('/', 'ç'),
274 ('?', 'Ç'),
275 ('\'', '´'),
276 ('\\', '~'),
277 ('^', '¨'),
278 ('`', '\''),
279 ('|', '^'),
280 ('~', '"'),
281 ],
282 "com.apple.keylayout.Brazilian-Pro" => &[('^', 'ˆ'), ('~', '˜')],
283 "com.apple.keylayout.British" => &[('#', '£')],
284 "com.apple.keylayout.Canadian-CSA" => &[
285 ('"', 'È'),
286 ('/', 'é'),
287 ('<', '\''),
288 ('>', '"'),
289 ('?', 'É'),
290 ('[', '^'),
291 ('\'', 'è'),
292 ('\\', 'à'),
293 (']', 'ç'),
294 ('`', 'ù'),
295 ('{', '¨'),
296 ('|', 'À'),
297 ('}', 'Ç'),
298 ('~', 'Ù'),
299 ],
300 "com.apple.keylayout.Croatian" => &[
301 ('"', 'Ć'),
302 ('&', '\''),
303 ('(', ')'),
304 (')', '='),
305 ('*', '('),
306 (':', 'Č'),
307 (';', 'č'),
308 ('<', ';'),
309 ('=', '*'),
310 ('>', ':'),
311 ('@', '"'),
312 ('[', 'š'),
313 ('\'', 'ć'),
314 ('\\', 'ž'),
315 (']', 'đ'),
316 ('^', '&'),
317 ('`', '<'),
318 ('{', 'Š'),
319 ('|', 'Ž'),
320 ('}', 'Đ'),
321 ('~', '>'),
322 ],
323 "com.apple.keylayout.Croatian-PC" => &[
324 ('"', 'Ć'),
325 ('&', '/'),
326 ('(', ')'),
327 (')', '='),
328 ('*', '('),
329 ('/', '\''),
330 (':', 'Č'),
331 (';', 'č'),
332 ('<', ';'),
333 ('=', '*'),
334 ('>', ':'),
335 ('@', '"'),
336 ('[', 'š'),
337 ('\'', 'ć'),
338 ('\\', 'ž'),
339 (']', 'đ'),
340 ('^', '&'),
341 ('`', '<'),
342 ('{', 'Š'),
343 ('|', 'Ž'),
344 ('}', 'Đ'),
345 ('~', '>'),
346 ],
347 "com.apple.keylayout.Czech" => &[
348 ('!', '1'),
349 ('"', '!'),
350 ('#', '3'),
351 ('$', '4'),
352 ('%', '5'),
353 ('&', '7'),
354 ('(', '9'),
355 (')', '0'),
356 ('*', '8'),
357 ('+', '%'),
358 ('/', '\''),
359 ('0', 'é'),
360 ('1', '+'),
361 ('2', 'ě'),
362 ('3', 'š'),
363 ('4', 'č'),
364 ('5', 'ř'),
365 ('6', 'ž'),
366 ('7', 'ý'),
367 ('8', 'á'),
368 ('9', 'í'),
369 (':', '"'),
370 (';', 'ů'),
371 ('<', '?'),
372 ('>', ':'),
373 ('?', 'ˇ'),
374 ('@', '2'),
375 ('[', 'ú'),
376 ('\'', '§'),
377 (']', ')'),
378 ('^', '6'),
379 ('`', '¨'),
380 ('{', 'Ú'),
381 ('}', '('),
382 ('~', '`'),
383 ],
384 "com.apple.keylayout.Czech-QWERTY" => &[
385 ('!', '1'),
386 ('"', '!'),
387 ('#', '3'),
388 ('$', '4'),
389 ('%', '5'),
390 ('&', '7'),
391 ('(', '9'),
392 (')', '0'),
393 ('*', '8'),
394 ('+', '%'),
395 ('/', '\''),
396 ('0', 'é'),
397 ('1', '+'),
398 ('2', 'ě'),
399 ('3', 'š'),
400 ('4', 'č'),
401 ('5', 'ř'),
402 ('6', 'ž'),
403 ('7', 'ý'),
404 ('8', 'á'),
405 ('9', 'í'),
406 (':', '"'),
407 (';', 'ů'),
408 ('<', '?'),
409 ('>', ':'),
410 ('?', 'ˇ'),
411 ('@', '2'),
412 ('[', 'ú'),
413 ('\'', '§'),
414 (']', ')'),
415 ('^', '6'),
416 ('`', '¨'),
417 ('{', 'Ú'),
418 ('}', '('),
419 ('~', '`'),
420 ],
421 "com.apple.keylayout.Danish" => &[
422 ('"', '^'),
423 ('$', '€'),
424 ('&', '/'),
425 ('(', ')'),
426 (')', '='),
427 ('*', '('),
428 ('/', '´'),
429 (':', 'Å'),
430 (';', 'å'),
431 ('<', ';'),
432 ('=', '`'),
433 ('>', ':'),
434 ('@', '"'),
435 ('[', 'æ'),
436 ('\'', '¨'),
437 ('\\', '\''),
438 (']', 'ø'),
439 ('^', '&'),
440 ('`', '<'),
441 ('{', 'Æ'),
442 ('|', '*'),
443 ('}', 'Ø'),
444 ('~', '>'),
445 ],
446 "com.apple.keylayout.Faroese" => &[
447 ('"', 'Ø'),
448 ('$', '€'),
449 ('&', '/'),
450 ('(', ')'),
451 (')', '='),
452 ('*', '('),
453 ('/', '´'),
454 (':', 'Æ'),
455 (';', 'æ'),
456 ('<', ';'),
457 ('=', '`'),
458 ('>', ':'),
459 ('@', '"'),
460 ('[', 'å'),
461 ('\'', 'ø'),
462 ('\\', '\''),
463 (']', 'ð'),
464 ('^', '&'),
465 ('`', '<'),
466 ('{', 'Å'),
467 ('|', '*'),
468 ('}', 'Ð'),
469 ('~', '>'),
470 ],
471 "com.apple.keylayout.Finnish" => &[
472 ('"', '^'),
473 ('$', '€'),
474 ('&', '/'),
475 ('(', ')'),
476 (')', '='),
477 ('*', '('),
478 ('/', '´'),
479 (':', 'Å'),
480 (';', 'å'),
481 ('<', ';'),
482 ('=', '`'),
483 ('>', ':'),
484 ('@', '"'),
485 ('[', 'ö'),
486 ('\'', '¨'),
487 ('\\', '\''),
488 (']', 'ä'),
489 ('^', '&'),
490 ('`', '<'),
491 ('{', 'Ö'),
492 ('|', '*'),
493 ('}', 'Ä'),
494 ('~', '>'),
495 ],
496 "com.apple.keylayout.FinnishExtended" => &[
497 ('"', 'ˆ'),
498 ('$', '€'),
499 ('&', '/'),
500 ('(', ')'),
501 (')', '='),
502 ('*', '('),
503 ('/', '´'),
504 (':', 'Å'),
505 (';', 'å'),
506 ('<', ';'),
507 ('=', '`'),
508 ('>', ':'),
509 ('@', '"'),
510 ('[', 'ö'),
511 ('\'', '¨'),
512 ('\\', '\''),
513 (']', 'ä'),
514 ('^', '&'),
515 ('`', '<'),
516 ('{', 'Ö'),
517 ('|', '*'),
518 ('}', 'Ä'),
519 ('~', '>'),
520 ],
521 "com.apple.keylayout.FinnishSami-PC" => &[
522 ('"', 'ˆ'),
523 ('&', '/'),
524 ('(', ')'),
525 (')', '='),
526 ('*', '('),
527 ('/', '´'),
528 (':', 'Å'),
529 (';', 'å'),
530 ('<', ';'),
531 ('=', '`'),
532 ('>', ':'),
533 ('@', '"'),
534 ('[', 'ö'),
535 ('\'', '¨'),
536 ('\\', '@'),
537 (']', 'ä'),
538 ('^', '&'),
539 ('`', '<'),
540 ('{', 'Ö'),
541 ('|', '*'),
542 ('}', 'Ä'),
543 ('~', '>'),
544 ],
545 "com.apple.keylayout.French" => &[
546 ('!', '1'),
547 ('"', '%'),
548 ('#', '3'),
549 ('$', '4'),
550 ('%', '5'),
551 ('&', '7'),
552 ('(', '9'),
553 (')', '0'),
554 ('*', '8'),
555 ('.', ';'),
556 ('/', ':'),
557 ('0', 'à'),
558 ('1', '&'),
559 ('2', 'é'),
560 ('3', '"'),
561 ('4', '\''),
562 ('5', '('),
563 ('6', '§'),
564 ('7', 'è'),
565 ('8', '!'),
566 ('9', 'ç'),
567 (':', '°'),
568 (';', ')'),
569 ('<', '.'),
570 ('>', '/'),
571 ('@', '2'),
572 ('[', '^'),
573 ('\'', 'ù'),
574 ('\\', '`'),
575 (']', '$'),
576 ('^', '6'),
577 ('`', '<'),
578 ('{', '¨'),
579 ('|', '£'),
580 ('}', '*'),
581 ('~', '>'),
582 ],
583 "com.apple.keylayout.French-PC" => &[
584 ('!', '1'),
585 ('"', '%'),
586 ('#', '3'),
587 ('$', '4'),
588 ('%', '5'),
589 ('&', '7'),
590 ('(', '9'),
591 (')', '0'),
592 ('*', '8'),
593 ('-', ')'),
594 ('.', ';'),
595 ('/', ':'),
596 ('0', 'à'),
597 ('1', '&'),
598 ('2', 'é'),
599 ('3', '"'),
600 ('4', '\''),
601 ('5', '('),
602 ('6', '-'),
603 ('7', 'è'),
604 ('8', '_'),
605 ('9', 'ç'),
606 (':', '§'),
607 (';', '!'),
608 ('<', '.'),
609 ('>', '/'),
610 ('@', '2'),
611 ('[', '^'),
612 ('\'', 'ù'),
613 ('\\', '*'),
614 (']', '$'),
615 ('^', '6'),
616 ('_', '°'),
617 ('`', '<'),
618 ('{', '¨'),
619 ('|', 'μ'),
620 ('}', '£'),
621 ('~', '>'),
622 ],
623 "com.apple.keylayout.French-numerical" => &[
624 ('!', '1'),
625 ('"', '%'),
626 ('#', '3'),
627 ('$', '4'),
628 ('%', '5'),
629 ('&', '7'),
630 ('(', '9'),
631 (')', '0'),
632 ('*', '8'),
633 ('.', ';'),
634 ('/', ':'),
635 ('0', 'à'),
636 ('1', '&'),
637 ('2', 'é'),
638 ('3', '"'),
639 ('4', '\''),
640 ('5', '('),
641 ('6', '§'),
642 ('7', 'è'),
643 ('8', '!'),
644 ('9', 'ç'),
645 (':', '°'),
646 (';', ')'),
647 ('<', '.'),
648 ('>', '/'),
649 ('@', '2'),
650 ('[', '^'),
651 ('\'', 'ù'),
652 ('\\', '`'),
653 (']', '$'),
654 ('^', '6'),
655 ('`', '<'),
656 ('{', '¨'),
657 ('|', '£'),
658 ('}', '*'),
659 ('~', '>'),
660 ],
661 "com.apple.keylayout.German" => &[
662 ('"', '`'),
663 ('#', '§'),
664 ('&', '/'),
665 ('(', ')'),
666 (')', '='),
667 ('*', '('),
668 ('/', 'ß'),
669 (':', 'Ü'),
670 (';', 'ü'),
671 ('<', ';'),
672 ('=', '*'),
673 ('>', ':'),
674 ('@', '"'),
675 ('[', 'ö'),
676 ('\'', '´'),
677 ('\\', '#'),
678 (']', 'ä'),
679 ('^', '&'),
680 ('`', '<'),
681 ('{', 'Ö'),
682 ('|', '\''),
683 ('}', 'Ä'),
684 ('~', '>'),
685 ],
686 "com.apple.keylayout.German-DIN-2137" => &[
687 ('"', '`'),
688 ('#', '§'),
689 ('&', '/'),
690 ('(', ')'),
691 (')', '='),
692 ('*', '('),
693 ('/', 'ß'),
694 (':', 'Ü'),
695 (';', 'ü'),
696 ('<', ';'),
697 ('=', '*'),
698 ('>', ':'),
699 ('@', '"'),
700 ('[', 'ö'),
701 ('\'', '´'),
702 ('\\', '#'),
703 (']', 'ä'),
704 ('^', '&'),
705 ('`', '<'),
706 ('{', 'Ö'),
707 ('|', '\''),
708 ('}', 'Ä'),
709 ('~', '>'),
710 ],
711 "com.apple.keylayout.Hawaiian" => &[('\'', 'ʻ')],
712 "com.apple.keylayout.Hungarian" => &[
713 ('!', '\''),
714 ('"', 'Á'),
715 ('#', '+'),
716 ('$', '!'),
717 ('&', '='),
718 ('(', ')'),
719 (')', 'Ö'),
720 ('*', '('),
721 ('+', 'Ó'),
722 ('/', 'ü'),
723 ('0', 'ö'),
724 (':', 'É'),
725 (';', 'é'),
726 ('<', 'Ü'),
727 ('=', 'ó'),
728 ('>', ':'),
729 ('@', '"'),
730 ('[', 'ő'),
731 ('\'', 'á'),
732 ('\\', 'ű'),
733 (']', 'ú'),
734 ('^', '/'),
735 ('`', 'í'),
736 ('{', 'Ő'),
737 ('|', 'Ű'),
738 ('}', 'Ú'),
739 ('~', 'Í'),
740 ],
741 "com.apple.keylayout.Hungarian-QWERTY" => &[
742 ('!', '\''),
743 ('"', 'Á'),
744 ('#', '+'),
745 ('$', '!'),
746 ('&', '='),
747 ('(', ')'),
748 (')', 'Ö'),
749 ('*', '('),
750 ('+', 'Ó'),
751 ('/', 'ü'),
752 ('0', 'ö'),
753 (':', 'É'),
754 (';', 'é'),
755 ('<', 'Ü'),
756 ('=', 'ó'),
757 ('>', ':'),
758 ('@', '"'),
759 ('[', 'ő'),
760 ('\'', 'á'),
761 ('\\', 'ű'),
762 (']', 'ú'),
763 ('^', '/'),
764 ('`', 'í'),
765 ('{', 'Ő'),
766 ('|', 'Ű'),
767 ('}', 'Ú'),
768 ('~', 'Í'),
769 ],
770 "com.apple.keylayout.Icelandic" => &[
771 ('"', 'Ö'),
772 ('&', '/'),
773 ('(', ')'),
774 (')', '='),
775 ('*', '('),
776 ('/', '\''),
777 (':', 'Ð'),
778 (';', 'ð'),
779 ('<', ';'),
780 ('=', '*'),
781 ('>', ':'),
782 ('@', '"'),
783 ('[', 'æ'),
784 ('\'', 'ö'),
785 ('\\', 'þ'),
786 (']', '´'),
787 ('^', '&'),
788 ('`', '<'),
789 ('{', 'Æ'),
790 ('|', 'Þ'),
791 ('}', '´'),
792 ('~', '>'),
793 ],
794 "com.apple.keylayout.Irish" => &[('#', '£')],
795 "com.apple.keylayout.IrishExtended" => &[('#', '£')],
796 "com.apple.keylayout.Italian" => &[
797 ('!', '1'),
798 ('"', '%'),
799 ('#', '3'),
800 ('$', '4'),
801 ('%', '5'),
802 ('&', '7'),
803 ('(', '9'),
804 (')', '0'),
805 ('*', '8'),
806 (',', ';'),
807 ('.', ':'),
808 ('/', ','),
809 ('0', 'é'),
810 ('1', '&'),
811 ('2', '"'),
812 ('3', '\''),
813 ('4', '('),
814 ('5', 'ç'),
815 ('6', 'è'),
816 ('7', ')'),
817 ('8', '£'),
818 ('9', 'à'),
819 (':', '!'),
820 (';', 'ò'),
821 ('<', '.'),
822 ('>', '/'),
823 ('@', '2'),
824 ('[', 'ì'),
825 ('\'', 'ù'),
826 ('\\', '§'),
827 (']', '$'),
828 ('^', '6'),
829 ('`', '<'),
830 ('{', '^'),
831 ('|', '°'),
832 ('}', '*'),
833 ('~', '>'),
834 ],
835 "com.apple.keylayout.Italian-Pro" => &[
836 ('"', '^'),
837 ('#', '£'),
838 ('&', '/'),
839 ('(', ')'),
840 (')', '='),
841 ('*', '('),
842 ('/', '\''),
843 (':', 'é'),
844 (';', 'è'),
845 ('<', ';'),
846 ('=', '*'),
847 ('>', ':'),
848 ('@', '"'),
849 ('[', 'ò'),
850 ('\'', 'ì'),
851 ('\\', 'ù'),
852 (']', 'à'),
853 ('^', '&'),
854 ('`', '<'),
855 ('{', 'ç'),
856 ('|', '§'),
857 ('}', '°'),
858 ('~', '>'),
859 ],
860 "com.apple.keylayout.LatinAmerican" => &[
861 ('"', '¨'),
862 ('&', '/'),
863 ('(', ')'),
864 (')', '='),
865 ('*', '('),
866 ('/', '\''),
867 (':', 'Ñ'),
868 (';', 'ñ'),
869 ('<', ';'),
870 ('=', '*'),
871 ('>', ':'),
872 ('@', '"'),
873 ('[', '{'),
874 ('\'', '´'),
875 ('\\', '¿'),
876 (']', '}'),
877 ('^', '&'),
878 ('`', '<'),
879 ('{', '['),
880 ('|', '¡'),
881 ('}', ']'),
882 ('~', '>'),
883 ],
884 "com.apple.keylayout.Lithuanian" => &[
885 ('!', 'Ą'),
886 ('#', 'Ę'),
887 ('$', 'Ė'),
888 ('%', 'Į'),
889 ('&', 'Ų'),
890 ('*', 'Ū'),
891 ('+', 'Ž'),
892 ('1', 'ą'),
893 ('2', 'č'),
894 ('3', 'ę'),
895 ('4', 'ė'),
896 ('5', 'į'),
897 ('6', 'š'),
898 ('7', 'ų'),
899 ('8', 'ū'),
900 ('=', 'ž'),
901 ('@', 'Č'),
902 ('^', 'Š'),
903 ],
904 "com.apple.keylayout.Maltese" => &[
905 ('#', '£'),
906 ('[', 'ġ'),
907 (']', 'ħ'),
908 ('`', 'ż'),
909 ('{', 'Ġ'),
910 ('}', 'Ħ'),
911 ('~', 'Ż'),
912 ],
913 "com.apple.keylayout.NorthernSami" => &[
914 ('"', 'Ŋ'),
915 ('&', '/'),
916 ('(', ')'),
917 (')', '='),
918 ('*', '('),
919 ('/', '´'),
920 (':', 'Å'),
921 (';', 'å'),
922 ('<', ';'),
923 ('=', '`'),
924 ('>', ':'),
925 ('@', '"'),
926 ('Q', 'Á'),
927 ('W', 'Š'),
928 ('X', 'Č'),
929 ('[', 'ø'),
930 ('\'', 'ŋ'),
931 ('\\', 'đ'),
932 (']', 'æ'),
933 ('^', '&'),
934 ('`', 'ž'),
935 ('q', 'á'),
936 ('w', 'š'),
937 ('x', 'č'),
938 ('{', 'Ø'),
939 ('|', 'Đ'),
940 ('}', 'Æ'),
941 ('~', 'Ž'),
942 ],
943 "com.apple.keylayout.Norwegian" => &[
944 ('"', '^'),
945 ('&', '/'),
946 ('(', ')'),
947 (')', '='),
948 ('*', '('),
949 ('/', '´'),
950 (':', 'Å'),
951 (';', 'å'),
952 ('<', ';'),
953 ('=', '`'),
954 ('>', ':'),
955 ('@', '"'),
956 ('[', 'ø'),
957 ('\'', '¨'),
958 ('\\', '@'),
959 (']', 'æ'),
960 ('^', '&'),
961 ('`', '<'),
962 ('{', 'Ø'),
963 ('|', '*'),
964 ('}', 'Æ'),
965 ('~', '>'),
966 ],
967 "com.apple.keylayout.NorwegianExtended" => &[
968 ('"', 'ˆ'),
969 ('&', '/'),
970 ('(', ')'),
971 (')', '='),
972 ('*', '('),
973 ('/', '´'),
974 (':', 'Å'),
975 (';', 'å'),
976 ('<', ';'),
977 ('=', '`'),
978 ('>', ':'),
979 ('@', '"'),
980 ('[', 'ø'),
981 ('\\', '@'),
982 (']', 'æ'),
983 ('`', '<'),
984 ('}', 'Æ'),
985 ('~', '>'),
986 ],
987 "com.apple.keylayout.NorwegianSami-PC" => &[
988 ('"', 'ˆ'),
989 ('&', '/'),
990 ('(', ')'),
991 (')', '='),
992 ('*', '('),
993 ('/', '´'),
994 (':', 'Å'),
995 (';', 'å'),
996 ('<', ';'),
997 ('=', '`'),
998 ('>', ':'),
999 ('@', '"'),
1000 ('[', 'ø'),
1001 ('\'', '¨'),
1002 ('\\', '@'),
1003 (']', 'æ'),
1004 ('^', '&'),
1005 ('`', '<'),
1006 ('{', 'Ø'),
1007 ('|', '*'),
1008 ('}', 'Æ'),
1009 ('~', '>'),
1010 ],
1011 "com.apple.keylayout.Polish" => &[
1012 ('!', '§'),
1013 ('"', 'ę'),
1014 ('#', '!'),
1015 ('$', '?'),
1016 ('%', '+'),
1017 ('&', ':'),
1018 ('(', '/'),
1019 (')', '"'),
1020 ('*', '_'),
1021 ('+', ']'),
1022 (',', '.'),
1023 ('.', ','),
1024 ('/', 'ż'),
1025 (':', 'Ł'),
1026 (';', 'ł'),
1027 ('<', 'ś'),
1028 ('=', '['),
1029 ('>', 'ń'),
1030 ('?', 'Ż'),
1031 ('@', '%'),
1032 ('[', 'ó'),
1033 ('\'', 'ą'),
1034 ('\\', ';'),
1035 (']', '('),
1036 ('^', '='),
1037 ('_', 'ć'),
1038 ('`', '<'),
1039 ('{', 'ź'),
1040 ('|', '$'),
1041 ('}', ')'),
1042 ('~', '>'),
1043 ],
1044 "com.apple.keylayout.Portuguese" => &[
1045 ('"', '`'),
1046 ('&', '/'),
1047 ('(', ')'),
1048 (')', '='),
1049 ('*', '('),
1050 ('/', '\''),
1051 (':', 'ª'),
1052 (';', 'º'),
1053 ('<', ';'),
1054 ('=', '*'),
1055 ('>', ':'),
1056 ('@', '"'),
1057 ('[', 'ç'),
1058 ('\'', '´'),
1059 (']', '~'),
1060 ('^', '&'),
1061 ('`', '<'),
1062 ('{', 'Ç'),
1063 ('}', '^'),
1064 ('~', '>'),
1065 ],
1066 "com.apple.keylayout.Sami-PC" => &[
1067 ('"', 'Ŋ'),
1068 ('&', '/'),
1069 ('(', ')'),
1070 (')', '='),
1071 ('*', '('),
1072 ('/', '´'),
1073 (':', 'Å'),
1074 (';', 'å'),
1075 ('<', ';'),
1076 ('=', '`'),
1077 ('>', ':'),
1078 ('@', '"'),
1079 ('Q', 'Á'),
1080 ('W', 'Š'),
1081 ('X', 'Č'),
1082 ('[', 'ø'),
1083 ('\'', 'ŋ'),
1084 ('\\', 'đ'),
1085 (']', 'æ'),
1086 ('^', '&'),
1087 ('`', 'ž'),
1088 ('q', 'á'),
1089 ('w', 'š'),
1090 ('x', 'č'),
1091 ('{', 'Ø'),
1092 ('|', 'Đ'),
1093 ('}', 'Æ'),
1094 ('~', 'Ž'),
1095 ],
1096 "com.apple.keylayout.Serbian-Latin" => &[
1097 ('"', 'Ć'),
1098 ('&', '\''),
1099 ('(', ')'),
1100 (')', '='),
1101 ('*', '('),
1102 (':', 'Č'),
1103 (';', 'č'),
1104 ('<', ';'),
1105 ('=', '*'),
1106 ('>', ':'),
1107 ('@', '"'),
1108 ('[', 'š'),
1109 ('\'', 'ć'),
1110 ('\\', 'ž'),
1111 (']', 'đ'),
1112 ('^', '&'),
1113 ('`', '<'),
1114 ('{', 'Š'),
1115 ('|', 'Ž'),
1116 ('}', 'Đ'),
1117 ('~', '>'),
1118 ],
1119 "com.apple.keylayout.Slovak" => &[
1120 ('!', '1'),
1121 ('"', '!'),
1122 ('#', '3'),
1123 ('$', '4'),
1124 ('%', '5'),
1125 ('&', '7'),
1126 ('(', '9'),
1127 (')', '0'),
1128 ('*', '8'),
1129 ('+', '%'),
1130 ('/', '\''),
1131 ('0', 'é'),
1132 ('1', '+'),
1133 ('2', 'ľ'),
1134 ('3', 'š'),
1135 ('4', 'č'),
1136 ('5', 'ť'),
1137 ('6', 'ž'),
1138 ('7', 'ý'),
1139 ('8', 'á'),
1140 ('9', 'í'),
1141 (':', '"'),
1142 (';', 'ô'),
1143 ('<', '?'),
1144 ('>', ':'),
1145 ('?', 'ˇ'),
1146 ('@', '2'),
1147 ('[', 'ú'),
1148 ('\'', '§'),
1149 (']', 'ä'),
1150 ('^', '6'),
1151 ('`', 'ň'),
1152 ('{', 'Ú'),
1153 ('}', 'Ä'),
1154 ('~', 'Ň'),
1155 ],
1156 "com.apple.keylayout.Slovak-QWERTY" => &[
1157 ('!', '1'),
1158 ('"', '!'),
1159 ('#', '3'),
1160 ('$', '4'),
1161 ('%', '5'),
1162 ('&', '7'),
1163 ('(', '9'),
1164 (')', '0'),
1165 ('*', '8'),
1166 ('+', '%'),
1167 ('/', '\''),
1168 ('0', 'é'),
1169 ('1', '+'),
1170 ('2', 'ľ'),
1171 ('3', 'š'),
1172 ('4', 'č'),
1173 ('5', 'ť'),
1174 ('6', 'ž'),
1175 ('7', 'ý'),
1176 ('8', 'á'),
1177 ('9', 'í'),
1178 (':', '"'),
1179 (';', 'ô'),
1180 ('<', '?'),
1181 ('>', ':'),
1182 ('?', 'ˇ'),
1183 ('@', '2'),
1184 ('[', 'ú'),
1185 ('\'', '§'),
1186 (']', 'ä'),
1187 ('^', '6'),
1188 ('`', 'ň'),
1189 ('{', 'Ú'),
1190 ('}', 'Ä'),
1191 ('~', 'Ň'),
1192 ],
1193 "com.apple.keylayout.Slovenian" => &[
1194 ('"', 'Ć'),
1195 ('&', '\''),
1196 ('(', ')'),
1197 (')', '='),
1198 ('*', '('),
1199 (':', 'Č'),
1200 (';', 'č'),
1201 ('<', ';'),
1202 ('=', '*'),
1203 ('>', ':'),
1204 ('@', '"'),
1205 ('[', 'š'),
1206 ('\'', 'ć'),
1207 ('\\', 'ž'),
1208 (']', 'đ'),
1209 ('^', '&'),
1210 ('`', '<'),
1211 ('{', 'Š'),
1212 ('|', 'Ž'),
1213 ('}', 'Đ'),
1214 ('~', '>'),
1215 ],
1216 "com.apple.keylayout.Spanish" => &[
1217 ('!', '¡'),
1218 ('"', '¨'),
1219 ('.', 'ç'),
1220 ('/', '.'),
1221 (':', 'º'),
1222 (';', '´'),
1223 ('<', '¿'),
1224 ('>', 'Ç'),
1225 ('@', '!'),
1226 ('[', 'ñ'),
1227 ('\'', '`'),
1228 ('\\', '\''),
1229 (']', ';'),
1230 ('^', '/'),
1231 ('`', '<'),
1232 ('{', 'Ñ'),
1233 ('|', '"'),
1234 ('}', ':'),
1235 ('~', '>'),
1236 ],
1237 "com.apple.keylayout.Spanish-ISO" => &[
1238 ('"', '¨'),
1239 ('#', '·'),
1240 ('&', '/'),
1241 ('(', ')'),
1242 (')', '='),
1243 ('*', '('),
1244 ('.', 'ç'),
1245 ('/', '.'),
1246 (':', 'º'),
1247 (';', '´'),
1248 ('<', '¿'),
1249 ('>', 'Ç'),
1250 ('@', '"'),
1251 ('[', 'ñ'),
1252 ('\'', '`'),
1253 ('\\', '\''),
1254 (']', ';'),
1255 ('^', '&'),
1256 ('`', '<'),
1257 ('{', 'Ñ'),
1258 ('|', '"'),
1259 ('}', '`'),
1260 ('~', '>'),
1261 ],
1262 "com.apple.keylayout.Swedish" => &[
1263 ('"', '^'),
1264 ('$', '€'),
1265 ('&', '/'),
1266 ('(', ')'),
1267 (')', '='),
1268 ('*', '('),
1269 ('/', '´'),
1270 (':', 'Å'),
1271 (';', 'å'),
1272 ('<', ';'),
1273 ('=', '`'),
1274 ('>', ':'),
1275 ('@', '"'),
1276 ('[', 'ö'),
1277 ('\'', '¨'),
1278 ('\\', '\''),
1279 (']', 'ä'),
1280 ('^', '&'),
1281 ('`', '<'),
1282 ('{', 'Ö'),
1283 ('|', '*'),
1284 ('}', 'Ä'),
1285 ('~', '>'),
1286 ],
1287 "com.apple.keylayout.Swedish-Pro" => &[
1288 ('"', '^'),
1289 ('$', '€'),
1290 ('&', '/'),
1291 ('(', ')'),
1292 (')', '='),
1293 ('*', '('),
1294 ('/', '´'),
1295 (':', 'Å'),
1296 (';', 'å'),
1297 ('<', ';'),
1298 ('=', '`'),
1299 ('>', ':'),
1300 ('@', '"'),
1301 ('[', 'ö'),
1302 ('\'', '¨'),
1303 ('\\', '\''),
1304 (']', 'ä'),
1305 ('^', '&'),
1306 ('`', '<'),
1307 ('{', 'Ö'),
1308 ('|', '*'),
1309 ('}', 'Ä'),
1310 ('~', '>'),
1311 ],
1312 "com.apple.keylayout.SwedishSami-PC" => &[
1313 ('"', 'ˆ'),
1314 ('&', '/'),
1315 ('(', ')'),
1316 (')', '='),
1317 ('*', '('),
1318 ('/', '´'),
1319 (':', 'Å'),
1320 (';', 'å'),
1321 ('<', ';'),
1322 ('=', '`'),
1323 ('>', ':'),
1324 ('@', '"'),
1325 ('[', 'ö'),
1326 ('\'', '¨'),
1327 ('\\', '@'),
1328 (']', 'ä'),
1329 ('^', '&'),
1330 ('`', '<'),
1331 ('{', 'Ö'),
1332 ('|', '*'),
1333 ('}', 'Ä'),
1334 ('~', '>'),
1335 ],
1336 "com.apple.keylayout.SwissFrench" => &[
1337 ('!', '+'),
1338 ('"', '`'),
1339 ('#', '*'),
1340 ('$', 'ç'),
1341 ('&', '/'),
1342 ('(', ')'),
1343 (')', '='),
1344 ('*', '('),
1345 ('+', '!'),
1346 ('/', '\''),
1347 (':', 'ü'),
1348 (';', 'è'),
1349 ('<', ';'),
1350 ('=', '¨'),
1351 ('>', ':'),
1352 ('@', '"'),
1353 ('[', 'é'),
1354 ('\'', '^'),
1355 ('\\', '$'),
1356 (']', 'à'),
1357 ('^', '&'),
1358 ('`', '<'),
1359 ('{', 'ö'),
1360 ('|', '£'),
1361 ('}', 'ä'),
1362 ('~', '>'),
1363 ],
1364 "com.apple.keylayout.SwissGerman" => &[
1365 ('!', '+'),
1366 ('"', '`'),
1367 ('#', '*'),
1368 ('$', 'ç'),
1369 ('&', '/'),
1370 ('(', ')'),
1371 (')', '='),
1372 ('*', '('),
1373 ('+', '!'),
1374 ('/', '\''),
1375 (':', 'è'),
1376 (';', 'ü'),
1377 ('<', ';'),
1378 ('=', '¨'),
1379 ('>', ':'),
1380 ('@', '"'),
1381 ('[', 'ö'),
1382 ('\'', '^'),
1383 ('\\', '$'),
1384 (']', 'ä'),
1385 ('^', '&'),
1386 ('`', '<'),
1387 ('{', 'é'),
1388 ('|', '£'),
1389 ('}', 'à'),
1390 ('~', '>'),
1391 ],
1392 "com.apple.keylayout.Turkish" => &[
1393 ('"', '-'),
1394 ('#', '"'),
1395 ('$', '\''),
1396 ('%', '('),
1397 ('&', ')'),
1398 ('(', '%'),
1399 (')', ':'),
1400 ('*', '_'),
1401 (',', 'ö'),
1402 ('-', 'ş'),
1403 ('.', 'ç'),
1404 ('/', '.'),
1405 (':', '$'),
1406 ('<', 'Ö'),
1407 ('>', 'Ç'),
1408 ('@', '*'),
1409 ('[', 'ğ'),
1410 ('\'', ','),
1411 ('\\', 'ü'),
1412 (']', 'ı'),
1413 ('^', '/'),
1414 ('_', 'Ş'),
1415 ('`', '<'),
1416 ('{', 'Ğ'),
1417 ('|', 'Ü'),
1418 ('}', 'I'),
1419 ('~', '>'),
1420 ],
1421 "com.apple.keylayout.Turkish-QWERTY-PC" => &[
1422 ('"', 'I'),
1423 ('#', '^'),
1424 ('$', '+'),
1425 ('&', '/'),
1426 ('(', ')'),
1427 (')', '='),
1428 ('*', '('),
1429 ('+', ':'),
1430 (',', 'ö'),
1431 ('.', 'ç'),
1432 ('/', '*'),
1433 (':', 'Ş'),
1434 (';', 'ş'),
1435 ('<', 'Ö'),
1436 ('=', '.'),
1437 ('>', 'Ç'),
1438 ('@', '\''),
1439 ('[', 'ğ'),
1440 ('\'', 'ı'),
1441 ('\\', ','),
1442 (']', 'ü'),
1443 ('^', '&'),
1444 ('`', '<'),
1445 ('{', 'Ğ'),
1446 ('|', ';'),
1447 ('}', 'Ü'),
1448 ('~', '>'),
1449 ],
1450 "com.apple.keylayout.Turkish-Standard" => &[
1451 ('"', 'Ş'),
1452 ('#', '^'),
1453 ('&', '\''),
1454 ('(', ')'),
1455 (')', '='),
1456 ('*', '('),
1457 (',', '.'),
1458 ('.', ','),
1459 (':', 'Ç'),
1460 (';', 'ç'),
1461 ('<', ':'),
1462 ('=', '*'),
1463 ('>', ';'),
1464 ('@', '"'),
1465 ('[', 'ğ'),
1466 ('\'', 'ş'),
1467 ('\\', 'ü'),
1468 (']', 'ı'),
1469 ('^', '&'),
1470 ('`', 'ö'),
1471 ('{', 'Ğ'),
1472 ('|', 'Ü'),
1473 ('}', 'I'),
1474 ('~', 'Ö'),
1475 ],
1476 "com.apple.keylayout.Turkmen" => &[
1477 ('C', 'Ç'),
1478 ('Q', 'Ä'),
1479 ('V', 'Ý'),
1480 ('X', 'Ü'),
1481 ('[', 'ň'),
1482 ('\\', 'ş'),
1483 (']', 'ö'),
1484 ('^', '№'),
1485 ('`', 'ž'),
1486 ('c', 'ç'),
1487 ('q', 'ä'),
1488 ('v', 'ý'),
1489 ('x', 'ü'),
1490 ('{', 'Ň'),
1491 ('|', 'Ş'),
1492 ('}', 'Ö'),
1493 ('~', 'Ž'),
1494 ],
1495 "com.apple.keylayout.USInternational-PC" => &[('^', 'ˆ'), ('~', '˜')],
1496 "com.apple.keylayout.Welsh" => &[('#', '£')],
1497
1498 _ => return None,
1499 };
1500
1501 Some(HashMap::from_iter(mappings.iter().cloned()))
1502}
1503