-
Notifications
You must be signed in to change notification settings - Fork 128
/
kanata.kbd
1454 lines (1285 loc) · 56.2 KB
/
kanata.kbd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
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
177
178
179
180
181
182
183
184
185
186
187
188
189
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
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
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
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
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
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
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
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
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
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
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
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#|
This is a sample configuration file that showcases every feature in kanata.
A more detailed and less terse configuration guide is found here:
https://github.com/jtroo/kanata/blob/main/docs/config.adoc
Other configuration samples are found here:
https://github.com/jtroo/kanata/tree/main/cfg_samples
If anything is confusing or hard to discover, please file an issue or
contribute a pull request to help improve the document.
Since it may be important for you to know, pressing and holding all of the
three following keys together at the same time will cause kanata to exit:
Left Control, Space, Escape
This is for the physical key input rather than after any remappings
that are done by kanata.
|#
;; Single-line comments are prefixed by double-semicolon. A single semicolon
;; is parsed as the keyboard key. Comments are ignored for the configuration
;; file.
#|
A multi-line comment block begin with an octothorphe followed by a pipe: `#|`.
To end the multi-line comment block, have a pipe followed by an octothorpe,
like the following sequence with the colon removed: `|:#`. The actual two
character sequence is not used because it would end this multi-line comment
block and cause a parsing error.
This configuration language is Lisp-like and uses S-Expression syntax.
If you're unfamiliar with Lisp, don't be alarmed. The maintainer jtroo is
also unfamiliar with Lisp. You don't need to know Lisp in-depth to
be able to configure kanata.
If you follow along with the examples, you should be fine. Kanata should
also hopefully have helpful error messages in case something goes wrong.
If you need help, please feel welcome to ask in the GitHub discussions.
|#
;; One defcfg entry may be added if desired. This is used for configuration
;; key-value pairs that change kanata's behaviour at a global level.
;; All defcfg options are optional.
(defcfg
;; Your keyboard device will likely differ from this. I believe /dev/input/by-id/
;; is preferable; I recall reading that it's less likely to change names on you,
;; but I didn't find any keyboard device in there in my VM. If you are on Linux
;; and omit this entry, kanata will try to attach to every device found on your
;; system that seems like a keyboard.
;; linux-dev /dev/input/by-path/platform-i8042-serio-0-event-kbd
;; If you want to read from multiple devices, separate them by `:`.
;; linux-dev /dev/input/<dev1>:/dev/input/<dev2>
;;
;; If you have a colon in your device path, add a backslash before it so that
;; kanata does not parse it as multiple devices.
;; linux-dev /dev/input/path-to\:device
;; Alternatively, you can use list syntax, where both backslashes and colons
;; are parsed literally. List items are separated by spaces or newlines.
;; Using quotation marks for each item is optional, and only required if an
;; item contains spaces.
;; linux-dev (
;; /dev/input/by-path/pci-0000:00:14.0-usb-0:1:1.0-event
;; /dev/input/by-id/usb-Dell_Dell_USB_Keyboard-event-kbd
;; )
;; The linux-dev-names-include entry is parsed identically to linux-dev. It
;; defines a list of device names that should be included. This is only
;; used if linux-dev is omitted.
;; linux-dev-names-include device-1-name:device\:2\:name
;; The linux-dev-names-exclude entry is parsed identically to linux-dev. It
;; defines a list of device names that should be excluded. This is only
;; used if linux-dev is omitted. This and linux-dev-names-include are not
;; mutually exclusive but in practice it probably makes sense to only use
;; one of them.
;; linux-dev-names-exclude device-1-name:device\:2\:name
;; By default, kanata will crash if no input devices are found. You can change
;; this behaviour by setting `linux-continue-if-no-devs-found`.
;;
;; linux-continue-if-no-devs-found yes
;; Kanata on Linux automatically detects and grabs input devices
;; when none of the explicit device configurations are in use.
;; In case kanata is undesirably grabbing mouse-like devices,
;; you can use a configuration item to change detection behaviour.
;;
;; linux-device-detect-mode keyboard-only
;; On Linux, you can ask kanata to run `xset r rate <delay> <rate>` on startup
;; and on live reload via the config below. The first number is the delay in ms
;; and the second number is the repeat rate in repeats/second.
;;
;; linux-x11-repeat-delay-rate 400,50
;; On linux, you can ask kanata to label itself as a trackpoint. This has several
;; effects on libinput including enabling middle mouse button scrolling and using
;; a different acceleration curve. Otherwise, a trackpoint intercepted by kanata
;; may not behave as expected.
;;
;; If using this feature, it is recommended to filter out any non-trackpoint
;; pointing devices using linux-only-linux-dev-names-include,
;; linux-only-linux-dev-names-exclude or linux-only-linux-dev to avoid changing
;; their behavior as well.
;;
;; linux-use-trackpoint-property yes
;; Unicode on Linux works by pressing Ctrl+Shift+U, typing the unicode hex value,
;; then pressing Enter. However, if you do remapping in userspace, e.g. via
;; xmodmap/xkb, the keycode "U" that kanata outputs may not become a keysym "u"
;; after the userspace remapping. This will be likely if you use non-US,
;; non-European keyboards on top of kanata. For unicode to work, kanata needs to
;; use the keycode that outputs the keysym "u", which might not be the keycode
;; "U".
;;
;; You can use `evtest` or `kanata --debug`, set your userspace key remapping,
;; then press the key that outputs the keysym "u" to see which underlying keycode
;; is sent. Then you can use this configuration to change kanata's behaviour.
;;
;; Example:
;;
;; linux-unicode-u-code v
;; Unicode on Linux terminates with the Enter key by default. This may not work in
;; some applications. The termination is configurable with the following options:
;;
;; - `enter`
;; - `space`
;; - `enter-space`
;; - `space-enter`
;;
;; Example:
;;
;; linux-unicode-termination space
;; Kanata on Linux needs to declare a "bus type" for its evdev output device.
;; The options are USB and I8042. The default is I8042.
;; Using USB can break disable-touchpad-while-typing on Wayland.
;; But using I8042 appears to break some other scenarios. Thus it is configurable.
;;
;; Examples:
;;
;; linux-output-device-bus-type USB
;; linux-output-device-bus-type I8042
;; There is an optional configuration entry for Windows to help mitigate strange
;; behaviour of AltGr if your layout uses that. Uncomment one of the items below
;; to change what kanata does with the key.
;;
;; For more context, see: https://github.com/jtroo/kanata/issues/55.
;;
;; windows-altgr cancel-lctl-press ;; remove the lctl press that comes as a combo with ralt
;; windows-altgr add-lctl-release ;; add an lctl release when ralt is released
;;
;; NOTE: even with these workarounds, putting lctl+ralt in your defsrc may
;; not work too well with other applications that use WH_KEYBOARD_LL.
;; Known applications with issues: GWSL/VcXsrv
;; Enable kanata to execute commands.
;;
;; I consider this feature a hazard so it is conditionally compiled out of
;; the default binary.
;;
;; This is dangerous because it allows kanata to execute arbitrary commands.
;; Using a binary compiled with the cmd feature enabled, uncomment below to
;; enable command execution:
;;
;; danger-enable-cmd yes
;; Enable processing of keys that are not in defsrc.
;; This is useful if you are only mapping a few keys in defsrc instead of
;; most of the keys on your keyboard. Without this, the tap-hold-release and
;; tap-hold-press actions will not activate for keys that are not in defsrc.
;;
;; The reason this is not enabled by default is because some keys may not
;; work correctly if they are intercepted. E.g. rctl/altgr on Windows; see the
;; windows-altgr configuration item above for context.
;;
;; process-unmapped-keys yes
;; We need to set it to yes in this kanata.kbd example config to allow the use of __ and ___
;; in the deflayer-custom-map example below in the file
;; This also accepts a list parameter (all-except key1 ... keyN)
;; which behaves like "yes" but excludes the keys within the list.
process-unmapped-keys (all-except f19)
;; Disable all keys not mapped in defsrc.
;; Only works if process-unmapped-keys is also yes.
;; block-unmapped-keys yes
;; Intercept mouse buttons for a specific mouse device.
;; The intended use case for this is for laptops such as a Thinkpad, which have
;; mouse buttons that may be useful to activate kanata actions with. This only
;; works with the Interception driver.
;;
;; To know what numbers to put into the string, you can run the
;; kanata-wintercept variant with this defcfg item defined with random numbers.
;; Then when a button is first pressed on the mouse device, kanata will print
;; its hwid in the log; you can then copy-paste that into this configuration
;; entry. If this defcfg item is not defined, the log will not print.
;;
;; windows-interception-mouse-hwid "70, 0, 90, 0, 20"
;; There is also a list version of windows-interception-mouse-hwid:
;;
;; windows-interception-mouse-hwids (
;; "70, 0, 60, 0"
;; "71, 0, 62, 0"
;; )
;; List configuration for kanata-wintercept variants
;; that allows intercepting only some connected keyboards.
;; Use similarly to mouse-hwid above.
;;
;; windows-interception-keyboard-hwids (
;; "90, 80, 11, 34"
;; "99, 88, 77, 66"
;; )
;; Transparent keys on layers will delegate to the corresponding defsrc key
;; when found on a layer activated by `layer-switch`. This config entry
;; changes the behaviour to delegate to the action of the first layer,
;; which is the layer active upon startup, that is in the same position.
;;
;; delegate-to-first-layer yes
;; This config entry alters the behavior of movemouse-accel actions.
;; By default, this setting is disabled - vertical and horizontal
;; acceleration are independent. Enabling this setting will emulate QMK mouse
;; move acceleration behavior, i.e. the acceleration state of new mouse
;; movement actions are inherited if others are already being pressed.
;;
;; movemouse-inherit-accel-state yes
;; This config entry alters the behavior of movemouseaccel actions.
;; This makes diagonal movements simultaneous to mitigate choppiness in
;; drawing apps, if you're using kanata mouse movements to draw for
;; whatever reason.
;;
;; movemouse-smooth-diagonals yes
;; This configuration allows you to customize the length limit on dynamic macros.
;; The default limit is 128 keys.
;;
;; dynamic-macro-max-presses 1000
;; This configuration makes multiple tap-hold actions that are activated near
;; in time expire their timeout quicker. Without this, the timeout for the 2nd
;; tap-hold onwards will start from 0ms after the previous tap-hold expires.
;;
concurrent-tap-hold yes
;; This configuration makes the release of one-shot-press and of the tap in a tap-hold
;; by the defined number of milliseconds (approximate).
;; The default value is 5.
;; While the release is delayed, further processing of inputs is also paused.
;; This means that there will be a minor input latency impact in the mentioned scenarios.
;; The reason for this configuration existing is that some environments
;; do not process the scenarios correctly due to the rapidity of the release.
;; Kanata does send the events in the correct order,
;; so the fault is more in the environment, but kanata provides a workaround anyway.
rapid-event-delay 5
;; This setting defaults to yes but can be configured to no to save on
;; logging. However, if --log-layer-changes is passed as a command line
;; argument, a "no" in the configuration file will be overridden and layer
;; changes will be logged.
;;
;; log-layer-changes no
;; This configuration will press and then immediately release the non-modifier key
;; as soon as the override activates, meaning you are unlikely as a human to ever
;; release modifiers first, which can result in unintended behaviour.
;;
;; The downside of this configuration is that the non-modifier key
;; does not remain held which is important to consider for your use cases.
override-release-on-activation yes
)
;; deflocalkeys-* enables you to define and use key names that match your locale
;; by defining OS code number mappings for that character.
;;
;; There are five variants of deflocalkeys-*:
;; - deflocalkeys-win
;; - deflocalkeys-winiov2
;; - deflocalkeys-wintercept
;; - deflocalkeys-linux
;; - deflocalkeys-macos
;;
;; Only one of each deflocalkeys-* variant is allowed. The variants that are
;; not applicable will be ignored, e.g. deflocalkeys-linux and deflocalkeys-wintercept
;; are both ignored when using the default Windows kanata binary.
;;
;; The configuration item is parsed similarly to defcfg; it is composed of
;; pairs of keys and values.
;;
;; You can check docs/locales.adoc for the mapping for your locale. If your
;; locale is not there, please ask for help if needed, and add the mapping for
;; your locale to the document.
;;
;; Web link for locales: https://github.com/jtroo/kanata/blob/main/docs/locales.adoc
;;
;; This example is for an Italian keyboard remapping in Linux. The numbers will
;; unfortunately differ between Linux, Windows-hooks, and Windows-interception.
;;
;; To see how you can discover key mappings for yourself, see the "Non-US keyboards"
;; section of docs/config.adoc.
;;
;; Web link or config: https://github.com/jtroo/kanata/blob/main/docs/config.adoc
(deflocalkeys-win
ì 187
)
(deflocalkeys-wintercept
ì 187
)
(deflocalkeys-winiov2
ì 187
)
(deflocalkeys-linux
ì 13
)
(deflocalkeys-macos
ì 13
)
;; Only one defsrc is allowed.
;;
;; defsrc defines the keys that will be intercepted by kanata. The order of the
;; keys matches the deflayer declarations and all deflayer declarations must
;; have the same number of keys as defsrc.
;;
;; The visual/spatial positioning is *not* mandatory; it is done by convention
;; for visual ease. These items are parsed as a long list with newlines being
;; ignored.
;;
;; If you are looking for other keys, the file src/keys/mod.rs should hopefully
;; provide some insight.
(defsrc
grv 1 2 3 4 5 6 7 8 9 0 - = bspc
tab q w e r t y u i o p [ ] \
caps a s d f g h j k l ; ' ret
lsft z x c v b n m , . / rsft
lctl lmet lalt spc ralt rmet rctl
)
;; The first layer defined is the layer that will be active by default when
;; kanata starts up. This layer is the standard QWERTY layout except for the
;; backtick/grave key (@grl) which is an alias for a tap-hold key.
(deflayer qwerty
@grl 1 2 3 4 5 6 7 8 9 0 - = bspc
tab q w e r t y u i o p [ ] \
caps a s d f g h j k l ; ' ret
lsft z x c v b n m , . / rsft
lctl lmet lalt spc ralt rmet rctl
)
;; The dvorak layer remaps the keys to the dvorak layout. There are several
;; tap-hold aliases configured on the left side.
(deflayer dvorak
@grl 1 2 3 4 5 6 7 8 9 0 [ ] bspc
tab ' , @.ms p y f g c r l / = \
@cap @anm @oar @ech @umc @ifk d h t n s - ret
lsft ; q j k x b m w v z rsft
lctl lmet lalt spc @ralt rmet @rcl
)
;; This is an alternative to deflayer and does not rely on defsrc.
;; It has the advantage of simpler config if only remapping a few keys.
;; You might still prefer the standard deflayer for its visual printing in
;; the log as you are learning a new configuration.
(deflayermap (custom-map-example)
caps esc
esc caps
;; You can use _ , __ or ___ instead of specifying a key name to map all
;; keys that are not explicitly mapped in the layer.
;; E.g. esc and caps above will not be overwritten.
;;
;; _ maps only keys that are in defsrc.
;; __ excludes mapping keys that are in defsrc.
;; ___ maps both, keys that are in `defsrc`, and keys that are not.
;;
;; The two- and three-underscore variants require
;; "process-unmapped-keys yes" in defcfg to work.
;; ___ XX ;; maps all keys that are not mapped explicitly in the layer
;; ;; (i.e. esc and caps above) to "no-op" to disable the key.
_ XX ;; maps all keys that are in defsrc and are not mapped in the layer
__ XX ;; maps all keys that are NOT in defsrc and are not mapped in the layer
)
;; defvar can be used to declare commonly-used values
(defvar
tap-timeout 100
hold-timeout 200
tt $tap-timeout
ht $hold-timeout
;; A list value in defvar that begins with concat behaves in a special manner
;; where strings will be joined together.
;;
;; Below results in 100200
a "hello"
b "world"
ct (concat $a " " $b)
)
(defalias
th1 (tap-hold $tt $ht caps lctl)
th2 (tap-hold $tt $ht spc lsft)
)
;; defalias is used to declare a shortcut for a more complicated action to keep
;; the deflayer declarations clean and aligned. The alignment in deflayers is not
;; necessary, but is strongly recommended for ease of understanding visually.
;;
;; Aliases are referred to by `@<alias_name>`. Aliases can refer to each other,
;; e.g. in the `anm` alias. However, an alias can only refer to another alias
;; that has been defined before it in the file.
(defalias
;; aliases to change the base layer to qwerty or dvorak
dvk (layer-switch dvorak)
qwr (layer-switch qwerty)
;; Aliases for layer "toggling". It's not quite toggling because the layer
;; will be active while the key is held and deactivated when the key is
;; released. An alternate action name you can use is layer-while-held.
;; However, the rest of this document will use The term "toggle" for brevity.
num (layer-toggle numbers)
chr (layer-toggle chords)
arr (layer-toggle arrows)
msc (layer-toggle misc)
lay (layer-toggle layers)
mse (layer-toggle mouse)
fks (layer-while-held fakekeys)
;; tap-hold aliases with tap for dvorak key, and hold for toggle layers
;; WARNING(Linux only): key repeat with tap-hold can behave unexpectedly.
;; For full context, see https://github.com/jtroo/kanata/discussions/422
;;
;; tap-hold parameter order:
;; 1. tap timeout
;; 2. hold timeout
;; 3. tap action
;; 4. hold action
;;
;; The hold timeout is the number of milliseconds after which the hold action
;; will activate.
;;
;; The tap timeout is best explained in a roundabout way. When you press and
;; hold a standard key on your keyboard (e.g. 'a'), your operating system will
;; read that and keep sending 'a' to the active application. To be able to
;; replicate this behaviour with a tap-hold key, you must press-release-press
;; the key within the tap timeout window (number is milliseconds). Simply
;; holding the key results in the hold action activating, which is why you
;; need to double-press for the tap action to stay pressed.
;;
;; There are two additional versions of tap-hold available:
;; 1. tap-hold-press: if there is a key press, the hold action is activated
;; 2. tap-hold-release: if there is a press and release of another key, the
;; hold action is activated
;;
;; These versions are useful if you don't want to wait for the whole hold
;; timeout to activate, but want to activate the hold action immediately
;; based on the next key press or press and release of another key. These
;; versions might be great to implement home row mods.
;;
;; If you come from kmonad, tap-hold-press and tap-hold-release are similar
;; to tap-hold-next and tap-hold-next-release, respectively. If you know
;; the underlying keyberon crate, tap-hold-press is the HoldOnOtherKeyPress
;; and tap-hold-release is the PermissiveHold configuration.
anm (tap-hold 200 200 a @num) ;; tap: a hold: numbers layer
oar (tap-hold 200 200 o @arr) ;; tap: o hold: arrows layer
ech (tap-hold 200 200 e @chr) ;; tap: e hold: chords layer
umc (tap-hold 200 200 u @msc) ;; tap: u hold: misc layer
grl (tap-hold 200 200 grv @lay) ;; tap: grave hold: layers layer
.ms (tap-hold 200 200 . @mse) ;; tap: . hold: mouse layer
ifk (tap-hold 200 200 i @fks) ;; tap: i hold: fake keys layer
;; There are additional variants of tap-hold-press and tap-hold-release that
;; activate the timeout action (the 5th parameter) when the action times out
;; as opposed to the hold action being activated by other keys.
;; tap: o hold: arrows layer timeout: backspace
oat (tap-hold-press-timeout 200 200 o @arr bspc)
;; tap: e hold: chords layer timeout: esc
ect (tap-hold-release-timeout 200 200 e @chr esc)
;; There is another variant of `tap-hold-release` that takes a 5th parameter
;; that is a list of keys that will trigger an early tap.
;; tap: u hold: misc layer early tap if any of: (a o e) are pressed
umk (tap-hold-release-keys 200 200 u @msc (a o e))
;; tap: u hold: misc layer always tap if any of: (a o e) are pressed
uek (tap-hold-except-keys 200 200 u @msc (a o e))
;; tap for capslk, hold for lctl
cap (tap-hold 200 200 caps lctl)
;; Below is an alias for the `multi` action which executes multiple actions
;; in order but at the same time.
;;
;; It may result in some incorrect/unexpected behaviour if combining complex
;; actions, so be reasonable with it. One reasonable use case is this alias:
;; press right-alt while also toggling to the `ralted` layer. The utility of
;; this is better revealed if you go see `ralted` and its aliases.
ralt (multi ralt (layer-toggle ralted))
)
;; Wrapping a top-level configuration item in a list beginning with
;; (environment (env-var-name env-var-value) ...configuration...)
;; will make the configuration only active if the environment variable matches.
(environment (LAPTOP lp1)
(defalias met @lp1met)
)
(environment (LAPTOP lp2)
(defalias met @lp2met)
)
;; NOTE: the configuration below is an older and less general variant
;; of the environment configuration above.
;;
;; The defaliasenvcond variant of defalias is parsed similarly, but there must
;; be a list parameter first. The list must contain two strings. In order,
;; these strings are: an environment variable name, and the environment
;; variable value. When the environment variable defined by name has the
;; corresponding value when running kanata, the aliases within will be active.
;; Otherwise, the aliases will be skipped.
(defaliasenvcond (LAPTOP lp1)
met @lp1met
)
(defaliasenvcond (LAPTOP lp2)
met @lp2met
)
(defalias
;; shifted keys
{ S-[
} S-]
: S-;
;; alias numbers as themselves for use in macro
8 8
0 0
)
(defalias
;; For the multi action, all keys are pressed for the whole sequence
;; but still in the listed order which may be undesirable, particularly
;; for modifiers like shift. You probably want to use macro instead.
;;
;; Chording can be more succinctly described by the modifier prefixes
;; `C-`, `A-`, `S-`, and `M-` for lctrl, lalt, lshift, lmeta, but are possible
;; by using `multi` as well. The lmeta key is also known by some other
;; names: "Windows", "GUI", "Command", "Super".
;;
;; For ralt/altgr, you can use either of: `RA-` or `AG-`. They both work the
;; same and only one is allowed in a single chord. This chord can be useful for
;; international layouts.
;;
;; A special behaviour of output chords is that if another key is pressed,
;; all of the chord keys will be released. For the explanation about why
;; this is the case, see the configuration guide.
;;
;; This use case for multi is typing an all-caps string.
alp (multi lsft a b c d e f g h i j k l m n o p q r s t u v w x y z)
;; Within multi you can also include reverse-release-order to release keys
;; from last-to-first order instead of first-to-last which is the default.
S-a-reversed (multi lsft a reverse-release-order)
;; Chords using the shortcut syntax. These ones are used for copying/pasting
;; from some Linux terminals.
csv C-S-v
csc C-S-c
;; Windows shortcut for displaying all windows
win M-tab
;; Accented e characters for France layout using altgr sequence. Showcases
;; both of the shortcuts. You can just use one version of shortcut at your
;; preference.
é AG-2
è RA-7
testmacro (macro AG-2 RA-7)
🙃 (unicode 🙃)
;; macro accepts keys, chords, and numbers (a delay in ms). Note that numbers
;; will be parsed as delays, so they will need to be aliased to be used.
lch (macro h t t p @: / / 100 l o c a l h o s t @: @8 @0 @8 @0)
tbm (macro A-(tab 200 tab 200 tab) 200 S-A-(tab 200 tab 200 tab))
hpy (macro S-i spc a m spc S-(h a p p y) spc m y S-f r S-i e S-n d @🙃)
rls (macro-release-cancel Digit1 500 bspc S-1 500 bspc S-2)
cop (macro-cancel-on-press Digit1 500 bspc S-1 500 bspc S-2)
rlpr (macro-release-cancel-and-cancel-on-press Digit1 500 bspc S-1 500 bspc S-2)
;; repeat variants will repeat while held, once ALL macros have ended,
;; including the held macro.
mr1 (macro-repeat mltp)
mr2 (macro-repeat-release-cancel mltp)
mr3 (macro-repeat-cancel-on-press mltp)
mr4 (macro-repeat-release-cancel-and-cancel-on-press mltp)
;; Kanata also supports dynamic macros. Dynamic macros can be nested, but
;; cannot recurse.
dms dynamic-macro-record-stop
dst (dynamic-macro-record-stop-truncate 3)
dr0 (dynamic-macro-record 0)
dr1 (dynamic-macro-record 1)
dr2 (dynamic-macro-record 2)
dp0 (dynamic-macro-play 0)
dp1 (dynamic-macro-play 1)
dp2 (dynamic-macro-play 2)
;; unmod will release all modifiers temporarily and send the .
;; So for example holding shift and tapping a @um1 key will still output 1.
um1 (unmod 1)
;; dead keys é (as opposed to using AltGr) that outputs É when shifted
dké (macro (unmod ') e)
;; unshift is like unmod but only releases shifts
;; In ISO German QWERTZ, force unshifted symbols even if shift is held
de{ (unshift ralt 7)
de[ (unshift ralt 8)
;; unmod can optionally take a list as the first parameter,
;; and then will only temporarily remove
;; the listed modifiers instead of all modifiers.
unalt-a (unmod (lalt ralt) a)
;; unicode accepts a single unicode character. The unicode character will
;; not be automatically repeated by holding the key down. The alias name
;; is the unicode character itself and is referenced by @🙁 in deflayer.
🙁 (unicode 🙁)
;; You may output parentheses or double quotes using unicode
;; by quotes as well as special quoting syntax.
lp1 (unicode r#"("#)
rp1 (unicode r#")"#)
dq (unicode r#"""#)
lp2 (unicode "(")
rp2 (unicode ")")
;; fork accepts two actions and a key list. The first (left) action will
;; activate by default. The second (right) action will activate if any of
;; the keys in the third parameter (right-trigger-keys) are currently active.
frk (fork @🙃 @🙁 (lsft rsft))
;; switch accepts triples of keys check, action, and fallthrough|break.
;; The default usage of keys check behaves similarly to fork.
;; However, it also accepts boolean operators and|or to allow more
;; complex use cases.
;;
;; The order of cases matters. If two different cases match the
;; currently pressed keys, the case listed earlier in the configuration
;; will activate first. If the early case uses break, the second case will
;; not activate at all. Otherwise if fallthrough is used, the second case
;; will also activate sequentially after the first case.
swt (switch
;; translating this keys check to some other common languages
;; this might look like:
;;
;; (a && b && (c || d) && (e || f))
((and a b (or c d) (or e f))) a break
;; this case behaves like fork, i.e.
;;
;; (or a b c)
;;
;; or for some other common languages:
;;
;; a || b || c
(a b c) b fallthrough
;; key-history evaluates to true if the n'th most recent typed key,
;; {n | n ∈ [1, 8]}, matches the given key.
((key-history a 1) (key-history b 8)) c break
;; key-timing evaluates to true if the n'th most recent typed key,
;; {n | n ∈ [1, 8]}, was typed at a time less-than/greater-than the
;; given number of milliseconds.
((key-timing 1 lt 3000) (key-timing 2 gt 30000) ) c break
((key-timing 7 less-than 200) (key-timing 8 greater-than 500)) c break
;; not means "not any of the list constituents".
;; The example below behaves like:
;;
;; !(a || b || c)
;;
;; and is equivalent to:
;;
;; ((not (or a b c)))
((not a b c)) c break
;; input logic
((input real lctl)) d break
((input virtual sft)) e break
((input-history real lsft 2)) f break
((input-history virtual ctl 2)) g break
;; layer evaluates to `true` if the active layer matches the given name
((layer dvorak)) x break
((layer qwerty)) y break
;; base-layer evaluates to `true` if the base layer matches the given name
;; The base layer is the most recent target of layer-switch.
;; The base layer is not always the active layer.
((base-layer dvorak)) x break
((base-layer qwerty)) y break
;; default case, empty list always evaluates to true.
;; break vs. fallthrough doesn't matter here
() c break
)
;; Having a cmd action in your configuration without explicitly enabling
;; `danger-enable-cmd` **and** using the cmd-enabled executable will make
;; kanata refuse to load your configuration. The aliases below are commented
;; out since commands aren't allowed by this configuration file.
;;
;; Note that the parameters to `cmd` are executed directly as opposed to
;; passed to a shell. So for example, `~` and `$HOME` would not refer
;; to your home directory on Linux.
;;
;; You can use:
;; `cmd bash -c "your_stuff_here"` to run your command inside of bash.
;;
;; cm1 (cmd bash -c "echo hello world")
;; cm2 (cmd rm -fr /tmp/testing)
;; One variant of `cmd` is `cmd-log`, which lets you control how
;; running command, stdout, stderr, and execution failure are logged.
;;
;; The command takes two extra arguments at the beginning `<log_level>`,
;; and `<error_log_level>`. `<log_level>` controls where the name
;; of the command is logged, as well as the success message and command
;; stdout and stderr.
;;
;; `<error_log_level>` is only used if there is a failure executing the initial
;; command. This can be if there is trouble spawning the command, or
;; the command is not found. This means if you use `bash -c "thisisntacommand"`, as
;; long as bash starts up correctly, nothing would be logged to this channel, but
;; something like `thisisntacommand` would be.
;;
;; The log level can be `debug`, `info`, `warn`, `error`, or `none`.
;;
;; cmd-log info error bash -c "echo these are the default levels"
;; cmd-log none none bash -c "echo nothing back in kanata logs"
;; cmd-log none error bash -c "only if command fails"
;; cmd-log debug debug bash -c "echo log, but require changing verbosity levels"
;; cmd-log warn warn bash -c "echo this probably isn't helpful"
;; Another variant of `cmd` is `cmd-output-keys`. This reads the output
;; of the command and treats it as an S-Expression, similarly to `macro`.
;; However, only delays, keys, chords, and chorded lists are supported.
;; Other actions are not.
;;
;; bash: type date-time as YYYY-MM-DD HH:MM
;; cmd-output-keys bash -c "date +'%F %R' | sed 's/./& /g' | sed 's/:/S-;/g' | sed 's/\(.\{20\}\)\(.*\)/\(\1 spc \2\)/'"
)
;; The underscore _ means transparent. The key on the base layer will be used
;; instead. XX means no-op. The key will do nothing.
;;
;; A similar concept to transparent, use-defsrc means the key will always
;; behave as the key as defined by defsrc.
(defalias src use-defsrc)
(deflayer numbers
@src _ _ _ _ _ nlk kp7 kp8 kp9 _ _ _ _
_ _ _ _ _ XX _ kp4 kp5 kp6 - _ _ _
_ _ C-z _ _ XX _ kp1 kp2 kp3 + _ _
_ C-z C-x C-c C-v XX _ kp0 kp0 . / _
_ _ _ _ _ _ _
)
;; The `lrld` action stands for "live reload".
;;
;; NOTE: live reload does not read changes to device-related configurations,
;; such as `linux-dev`, `macos-dev-names-include`,
;; or `windows-only-windows-interception-keyboard-hwids`.
;;
;; The variants `lrpv` and `lrnx` will cycle between multiple configuration files
;; if they are specified in the startup arguments.
;; The list action variant `lrld-num` takes a number parameter and
;; reloads the configuration file specified by the number, according to the
;; order passed into the arguments on kanata startup.
;;
;; Upon a successful reload, the kanata state will begin on the default base layer
;; in the configuration. E.g. in this example configuration, you would start on
;; the qwerty layer.
(deflayer layers
_ @qwr @dvk lrld lrpv lrnx (lrld-num 1) _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _
)
(defalias
;; Alias for one-shot which will activate an action until either the timeout
;; expires or a different key is pressed. The timeout is the first parameter
;; and the action is the second parameter.
;;
;; The intended use cases are pressing a modifier for exactly one key or
;; switching to another layer for exactly one key.
;;
;; If a one-shot key is held then it will act as a regular key. E.g. for os1
;; below, holding an @os1 key will keep lsft held and holding an @os3 key
;; will keep the layer set to misc.
os1 (one-shot 500 lsft)
os2 (one-shot 500 C-S-lalt)
os3 (one-shot 500 (layer-toggle misc))
;; Another name for one-shot is one-shot-press, since it ends on the first
;; press of another key.
;;
;; There is another variant one-shot-release which ends on the first release
;; of another key.
;;
;; There are further variants of both of these:
;; - one-shot-press-pcancel
;; - one-shot-release-pcancel
;;
;; These will cancel the one-shot action and all other active one-shot actions
;; if a one-shot key is repressed while already active.
osp (one-shot-press 500 lsft)
osr (one-shot-release 500 lsft)
opp (one-shot-press-pcancel 500 lsft)
orp (one-shot-release-pcancel 500 lsft)
;; one-shot-pause-processing can be useful in some cases
;; to preserve an activated one-shot state when it otherwise
;; would get deactivated by some action that isn't intended
;; to consume the one-shot.
;; The unit is number of milliseconds.
ops (one-shot-pause-processing 5)
;; Alias for tap-dance which will activate one of the actions in the action
;; list depending on how many taps were done. Tapping once will output the
;; first action and tapping N times will output the N'th action.
;;
;; The first parameter is a timeout. Tapping the same tap-dance key again
;; within the timeout will reset the timeout and advance the tap-dance to the
;; next key.
;;
;; The action activates either when any of the following happens:
;; - the timeout expires
;; - the tap sequence reaches the end
;; - a different key is pressed
td (tap-dance 200 (a b c d spc))
;; There is a variant of tap-dance — tap-dance-eager — that will activate
;; every action tapped in the sequence rather than a single one. The example
;; below is rather simple and behaves similarly to the original tap-dance.
td2 (tap-dance-eager 500 (
(macro a) ;; use macro to prevent auto-repeat of the key
(macro bspc b b)
(macro bspc bspc c c c)
))
;; arbitrary-code allows sending an arbitrary number as an OS code. This is
;; not cross platform! This can be useful for testing keys that are not yet
;; named or mapped in kanata. Please contribute findings with names and/order
;; mappings, either in a GitHub issue or as a pull request! This is currently
;; not supported with Windows using the interception driver.
ab1 (arbitrary-code 700)
)
(defalias
;; caps-word will add an lsft to the active key list for all alphanumeric keys
;; a-z, and the US layout minus key; meaning it will be converted to an
;; underscore.
;;
;; The caps-word state will also be cleared if any key that doesn't get auto-
;; capitalized and also doesn't belong in this list is pressed:
;; - 0-9
;; - kp0-kp9
;; - bspc, del
;; - up, down, left, rght
;;
;; The single parameter is a timeout in milliseconds after which the caps-word
;; state will be cleared and lsft will not be added anymore. The timer is reset
;; any time a capitalizable or extra non-terminating key is active.
cw (caps-word 2000)
;; Like caps-word, but you get to choose the key lists where lsft gets added.
;; This example is similar to the default caps-word behaviour but it moves the
;; 0-9 keys to capitalized key list from the extra non-terminating key list.
cwc (caps-word-custom
2000
(a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9)
(kp0 kp1 kp2 kp3 kp4 kp5 kp6 kp7 kp8 kp9 bspc del up down left rght)
)
)
;; -toggle variants of caps-word will terminate caps-word on repress if it is
;; currently active, otherwise caps-word will be activated.
(defalias
cwt (caps-word-toggle 2000)
cct (caps-word-custom-toggle
2000
(a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9)
(kp0 kp1 kp2 kp3 kp4 kp5 kp6 kp7 kp8 kp9 bspc del up down left rght)
)
)
;; Can see a new action `rpt` in this layer. This repeats the most recently
;; pressed key. Holding down the `rpt` key will not repeatedly send the key.
;; The intended use case is to be able to use a different finger to repeat a
;; double letter, as opposed to double-tapping a letter.
;;
;; The `rpt` action only repeats the last key output. For example, it won't
;; output a chord like `ctrl+c` if the previous key pressed was `C-c` - it
;; will only output `c`. There is a variant `rpt-any` which will repeat the
;; previous action and would work for that use case.
(deflayer misc
_ _ _ _ _ _ _ _ _ @é @è _ ì #|random custom key for testing|# _
_ _ @ab1 _ _ _ ins @{ @} [ ] _ _ +
@cw _ _ _ C-u _ del bspc esc ret _ _ _
@cwc C-z C-x C-c C-v _ _ _ @td @os1 @os2 @os3
rpt rpt-any _ _ _ _ _
)
(deflayer chords ;; you can put list actions directly in deflayer but it's ugly, so prefer aliases.
_ _ _ _ _ _ _ _ _ _ @🙁 (unicode 😀) _ _
_ _ _ _ _ _ _ _ @csc @hpy @lch @tbm _ _
_ @alp _ _ _ _ _ @ch1 @ch2 @ch4 @ch8 _ _
_ _ _ _ _ _ _ _ _ @csv _ _
_ _ _ _ _ _ _
)
(deflayer arrows
_ f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 _
_ _ _ _ _ _ _ pgup up pgdn _ _ _ _
_ _ _ _ _ _ home left down rght end _ _
_ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _
)
;; In Windows, using mouse buttons on the kanata window seems to cause it to hang.
;; Using the mouse on other windows seems to be fine though.
;;
;; The mouse buttons can be clicked using mlft, mrgt, mmid, mfwd and mbck, representing the
;; left, right, middle, forward and backward mouse buttons respectively. If the key is held, the
;; button press will also be held.
;;
;; If there are multiple mouse click actions within a single multi action, e.g.
;; (multi mrgt mlft), then all the buttons except the last will be clicked then
;; unclicked. The last button will remain held until key release. In the example
;; given, the button sequence will be:
;; press key->click right->unclick right->click left->release key->release left
;;
;; There are variants of the standard mouse buttons which "tap" the button.
;; These are mltp, mrtp, and mmtp. Rather than holding until key release, this
;; action will click and unclick the button once the key is pressed. Nothing
;; happens on key release. The action (multi lctl mltp) will result in the
;; sequence below:
;; press key->press lctl->click left->unclick left->release key->release lctl
;;
;; One can also see mouse movement actions at the lower right side, with the
;; arrow unicode characters.
(deflayer mouse
_ @mwu @mwd @mwl @mwr _ _ _ _ _ @ma↑ _ _ _
_ pgup bck _ fwd _ _ _ _ @ma← @ma↓ @ma→ _ _
_ pgdn mlft _ mrgt mmid _ mbck mfwd _ @ms↑ _ _
@fms _ mltp _ mrtp mmtp _ mbtp mftp @ms← @ms↓ @ms→
_ _ _ _ _ _ _
)
(defalias
;; Mouse wheel actions. The first number is the interval in milliseconds
;; between scroll actions. The second number is the distance in some arbitrary
;; unit. Play with the parameters to see what feels correct. Both numbers
;; must be in the range 1-65535
;;
;; In both Windows and Linux, 120 distance units is equivalent to a single
;; notch movement on a physical wheel. In Linux, not all desktop environments
;; support the REL_WHEEL_HI_RES event so if you experience issues with `mwheel`
;; actions in Linux, using a distance value that is multiple of 120 may help.
mwu (mwheel-up 50 120)
mwd (mwheel-down 50 120)