-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkeyamp.el
3423 lines (2936 loc) · 147 KB
/
keyamp.el
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
;;; keyamp.el --- Keyboard Amplifier -*- coding: utf-8; lexical-binding: t; -*-
;; Author: Egor Maltsev <[email protected]>
;; Version: 1.2 2025-01-07 Spectrum
;; __ _____ __
;; |__| |_____| |__|
;;
;; DEL SPC RET keys provide IDE workflow for ordinary on-screen keyboard.
;; This package is part of input model.
;;; Commentary:
;; Keyamp provides 3 modes: insert, command and repeat. Command mode
;; based on persistent transient keymap. Repeat mode adds transient
;; remaps on top of command mode for easy repeat of command chains
;; during screen positioning, cursor move and editing. Mode line front
;; space color indicates active transient keymap. Repeat mode turned
;; on/off automatically either by advice or with timer.
;; Try Keyboard Amplifier out with qwerty layout:
;; (setq keyamp-current-layout "qwerty")
;; (require 'keyamp)
;; (keyamp)
;;; Code:
(require 'keycom)
;; Macros
(defvar keyamp-layouts nil "A alist. Key is layout name, string type.
Value is an alist, each element is of the form (\"e\" . \"d\").
First char is QWERTY, second is corresponding char of the destination layout.
When a char is not in this alist, they are assumed to be the same.")
(push '("qwerty" . nil) keyamp-layouts)
(push
'("engineer-engram" .
(("-" . "#") ("=" . "%") ("`" . "`") ("q" . "b") ("w" . "y") ("e" . "o")
("r" . "u") ("t" . "'") ("y" . "\"") ("u" . "l") ("i" . "d") ("o" . "w")
("p" . "v") ("[" . "z") ("]" . "{") ("a" . "c") ("s" . "i") ("d" . "e")
("f" . "a") ("g" . ",") ("h" . ".") ("j" . "h") ("k" . "t") ("l" . "s")
(";" . "n") ("'" . "q") ("\\" . "}") ("z" . "g") ("x" . "x") ("c" . "j")
("v" . "k") ("b" . "-") ("n" . "?") ("m" . "r") ("," . "m") ("." . "f")
("/" . "p") ("_" . "|") ("+" . "^") ("~" . "~") ("Q" . "B") ("W" . "Y")
("E" . "O") ("R" . "U") ("T" . "(") ("Y" . ")") ("U" . "L") ("I" . "D")
("O" . "W") ("P" . "V") ("{" . "Z") ("}" . "[") ("A" . "C") ("S" . "I")
("D" . "E") ("F" . "A") ("G" . ";") ("H" . ":") ("J" . "H") ("K" . "T")
("L" . "S") (":" . "N") ("\"" . "Q") ("|" . "]") ("Z" . "G") ("X" . "X")
("C" . "J") ("V" . "K") ("B" . "_") ("N" . "!") ("M" . "R") ("<" . "M")
(">" . "F") ("?" . "P") ("1" . "1") ("2" . "2") ("3" . "3") ("4" . "4")
("5" . "5") ("6" . "6") ("7" . "7") ("8" . "8") ("9" . "9") ("0" . "0")
("!" . "@") ("@" . "&") ("#" . "/") ("$" . "$") ("%" . "<") ("^" . ">")
("&" . "*") ("*" . "=") ("(" . "+") (")" . "\\"))) keyamp-layouts)
(defvar keyamp--convert-table (cdr (assoc keyamp-current-layout keyamp-layouts))
"A alist that's the conversion table from QWERTY to current layout.
Value structure is one of the key's value of `keyamp-layouts'.
Value is programmatically set from value of `keyamp-current-layout'.
Do not manually set this variable.")
(defun keyamp--convert-kbd-str (Charstr)
"Return the corresponding char Charstr according to
`keyamp--convert-table'. Charstr must be a string that is, the argument
to `kbd'. E.g. \"a\" and \"a b c\". Each space separated token is
converted according to `keyamp--convert-table'."
(mapconcat 'identity
(mapcar
(lambda (x) (let ((xresult (assoc x keyamp--convert-table)))
(if xresult (cdr xresult) x)))
(split-string Charstr " +")) " "))
(defmacro keyamp--map (KeymapName KeyCmdAlist &optional Direct-p)
"Map `keymap-set' over a alist KEYCMDALIST, with key layout remap.
The key is remapped from QWERTY to the current keyboard layout by
`keyamp--convert-kbd-str'.
If Direct-p is t, do not remap key to current keyboard layout."
(declare (indent defun))
(let ((xkeymapName (make-symbol "keymap-name")))
`(let ((,xkeymapName ,KeymapName))
,@(mapcar
(lambda (xpair)
`(keymap-set ,xkeymapName
(,(if Direct-p #'identity #'keyamp--convert-kbd-str) ,(car xpair))
,(list 'quote (cdr xpair))))
(cadr KeyCmdAlist)))))
(defmacro keyamp--remap (KeymapName CmdCmdAlist)
"Map `keymap-set' remap over a alist CMDCMDALIST."
(declare (indent defun))
(let ((xkeymapName (make-symbol "keymap-name")))
`(let ((,xkeymapName ,KeymapName))
,@(mapcar
(lambda (xpair)
`(keymap-set ,xkeymapName
,(concat "<remap> <" (format "%s" (car xpair)) ">")
,(list 'quote (cdr xpair))))
(cadr CmdCmdAlist)))))
(defmacro keyamp--set (KeymapName CmdList &optional CommandMode InsertMode How TimeOut)
"Map `set-transient-map' using `advice-add' over a list CMDLIST.
- Advice default HOW :after might be changed by specific HOW;
- Activate COMMANDMODE or INSERTMODE mode optionally;
- Deactivate repeat mode after idle for TIMEOUT seconds;
- Ignore advice if defining or executing kbd macro."
(declare (indent defun))
(let ((xkeymapName (make-symbol "keymap-name")))
`(let ((,xkeymapName ,KeymapName))
,@(mapcar
(lambda (xcmd)
`(advice-add ,(list 'quote xcmd) (if ,How ,How :after)
(lambda (&rest _) "auto repeat"
(when (and (not (or defining-kbd-macro executing-kbd-macro))
(or (eq real-this-command 'repeat)
(eq this-command 'kill-region) ; exception
(eq this-command 'undo) ; exception
(eq this-command ,(list 'quote xcmd))))
(if (and ,CommandMode keyamp-insert-p)
(keyamp-command))
(keyamp-repeat-init ,xkeymapName)
(keyamp-cancel-repeat-idle-timer)
(if (and ,TimeOut (not keyamp-insert-p))
(setq keyamp--repeat-idle-timer
(run-with-idle-timer ,TimeOut nil 'keyamp-escape)))
(if ,InsertMode (keyamp-insert))))))
(cadr CmdList)))))
(defmacro keyamp--hook (KeymapName HookList &optional CommandMode InsertMode RepeatMode)
"Map `set-transient-map' using `add-hook' over a list HOOKLIST.
Activate command, insert or repeat mode optionally."
(declare (indent defun))
(let ((xkeymapName (make-symbol "keymap-name")))
`(let ((,xkeymapName ,KeymapName))
,@(mapcar
(lambda (xhook)
`(add-hook ,(list 'quote xhook)
(lambda () "auto repeat"
(if (and ,CommandMode keyamp-insert-p)
(keyamp-command))
(if (and ,InsertMode (not keyamp-insert-p))
(keyamp-insert))
(keyamp-repeat-init ,xkeymapName)
(if ,RepeatMode
(keyamp-command-execute 'keyamp--read-dummy)))))
(cadr HookList)))))
(defun keyamp--read-dummy () "Dummy for indication." (interactive))
(defun keyamp-command-execute (Command)
"Change this command to COMMAND and execute it. Indicate when not idle."
(setq this-command Command)
(command-execute Command)
(if (or (null (current-idle-time))
(< (time-convert (current-idle-time) 'integer) keyamp-idle-timeout))
(keyamp-transient)))
(defmacro keyamp--map-leader (KeymapName CmdCons)
"Map leader keys using `keyamp--map'."
(declare (indent defun))
(let ((xkeymapName (make-symbol "keymap-name")))
`(let ((,xkeymapName ,KeymapName))
(if (display-graphic-p)
(keyamp--map ,xkeymapName
'(("<backspace>" . ,(car (cadr CmdCons)))
("SPC" . ,(cdr (cadr CmdCons)))))
(keyamp--map ,xkeymapName
'(("DEL" . ,(car (cadr CmdCons))) ("SPC" . ,(cdr (cadr CmdCons)))))))))
(defmacro keyamp--map-tab (KeymapName Cmd)
"Map TAB or <tab> keys to CMD using `keyamp--map'."
(declare (indent defun))
(let ((xkeymapName (make-symbol "keymap-name")))
`(let ((,xkeymapName ,KeymapName))
(if (display-graphic-p)
(keyamp--map ,xkeymapName '(("<tab>" . ,Cmd)))
(keyamp--map ,xkeymapName '(("TAB" . ,Cmd)))))))
(defmacro keyamp--map-backtab (KeymapName Cmd)
"Map S-<tab> and <backtab> keys to CMD using `keyamp--map'."
(declare (indent defun))
(let ((xkeymapName (make-symbol "keymap-name")))
`(let ((,xkeymapName ,KeymapName))
(if (display-graphic-p)
(keyamp--map ,xkeymapName '(("S-<tab>" . ,Cmd))))
(keyamp--map ,xkeymapName '(("<backtab>" . ,Cmd))))))
(defmacro keyamp--map-return (KeymapName Cmd)
"Map RET or <return> keys to CMD using `keyamp--map'."
(declare (indent defun))
(let ((xkeymapName (make-symbol "keymap-name")))
`(let ((,xkeymapName ,KeymapName))
(if (display-graphic-p)
(keyamp--map ,xkeymapName '(("<return>" . ,Cmd)))
(keyamp--map ,xkeymapName '(("RET" . ,Cmd)))))))
(defmacro keyamp--map-escape (KeymapName Cmd)
"Map <escape> key to CMD using `keyamp--map'."
(declare (indent defun))
(let ((xkeymapName (make-symbol "keymap-name")))
`(let ((,xkeymapName ,KeymapName))
(keyamp--map ,xkeymapName '(("<escape>" . ,Cmd))))))
(defmacro with-sparse-keymap (&rest body)
"Make sparse keymap for next use in BODY."
(declare (indent defun))
`(let ((keymap (make-sparse-keymap)))
,@body))
(defmacro advice-add-macro (SymList How Fun)
"Map `advice-add' HOW over a list SYMLIST to FUN."
`(progn
,@(mapcar (lambda (xcmd) `(advice-add ,(list 'quote xcmd) ,How ,Fun))
(cadr SymList))))
;; Double remap
(defun keyamp-exe-remap (Key From To)
"Remap key from FROM command to TO command by default, but if remapped
already, then use existing remap instead. Execute resulting command."
(let ((x (keymap-lookup overriding-local-map (keyamp--convert-kbd-str Key))))
(keyamp-command-execute (cond ((or (equal x From) (not x)) To) (x x)))))
;; Double press
(defconst keyamp-double-press-timeout (/ 250 1000.0) "Double key press timeout.")
(defvar keyamp-double-press-timer nil "Double key press timer.")
(defun keyamp-double-press (Cmd)
"Execute COMMAND after second command call during `keyamp-double-press-timeout'."
(if (and (timerp keyamp-double-press-timer)
(eq this-command last-command)
(not (or defining-kbd-macro executing-kbd-macro)))
(keyamp-command-execute Cmd))
(setq keyamp-double-press-timer
(run-with-timer keyamp-double-press-timeout nil
(lambda () (setq keyamp-double-press-timer nil)))))
(defmacro keyamp--map-double (CmdCmdAlist)
"Map over alist CMDCMDALIST double press of CAR CMDCONS to CDR CMDCONS."
(declare (indent defun))
`(progn ,@(mapcar
(lambda (xpair)
`(advice-add ,(list 'quote (car xpair)) :after
(lambda (&rest _) "double press"
(keyamp-double-press ,(list 'quote (cdr xpair))))))
(cadr CmdCmdAlist))))
;; Triple press (hold down)
(defvar keyamp-defer-command-timer nil "Defer command timer.")
(defconst keyamp-key-repeat-delay (/ (if (display-graphic-p) 30 90) 1000.0)
"Key repeat delay. Higher value for network access.")
(defun keyamp-defer-command (Defer Command)
"Defer execution of COMMAND for DEFER."
(setq keyamp-defer-command-timer (run-with-timer Defer nil Command)))
(defun keyamp-cancel-defer-command-timer ()
"Cancel `keyamp-defer-command-timer'."
(when (timerp keyamp-defer-command-timer)
(cancel-timer keyamp-defer-command-timer)
(setq keyamp-defer-command-timer nil)))
(defun keyamp-defer-command-around (fun &rest _)
"Run `keyamp-defer-command' as around advice."
(if (memq last-command triple-press-direction-commands-list)
(before-last-command))
(keyamp-defer-command keyamp-key-repeat-delay fun))
;; Terminal ESC to <escape>
(defconst keyamp-tty-seq-timeout (/ 30 1000.0)
"Timeout to wait key sequence after ESC sent in tty.")
(defun keyamp-tty-ESC-filter (map)
"Map last ESC key from this single command keys to <escape>."
(if (and (let ((tty-seq (this-single-command-keys)))
(= ?\e (aref tty-seq (1- (length tty-seq)))))
(sit-for keyamp-tty-seq-timeout))
[escape] map))
(defun keyamp-lookup-key (map key)
(catch 'found
(map-keymap (lambda (k b) (if (equal key k) (throw 'found b))) map)))
(defun keyamp-catch-tty-ESC ()
"Setup key mappings of current terminal to turn a tty's ESC into <escape>."
(when (memq (terminal-live-p (frame-terminal)) '(t pc))
(let ((esc-binding (keyamp-lookup-key input-decode-map ?\e)))
(keymap-set input-decode-map
"ESC" `(menu-item "" ,esc-binding :filter keyamp-tty-ESC-filter)))
(keymap-set key-translation-map "ESC" "<escape>")))
;; Input source
(defconst keyamp-engineer-engram-to-russian-computer
'(("a" . "а") ("b" . "й") ("c" . "ф") ("d" . "ш") ("e" . "в")
("f" . "ю") ("g" . "я") ("h" . "о") ("i" . "ы") ("j" . "с")
("k" . "м") ("l" . "г") ("m" . "б") ("n" . "ж") ("o" . "у")
("q" . "э") ("r" . "ь") ("s" . "д") ("t" . "л") ("u" . "к")
("v" . "з") ("w" . "щ") ("x" . "ч") ("y" . "ц") ("z" . "х")
("." . "р") ("?" . "т") ("-" . "и") ("," . "п") ("'" . "е")
("`" . "ё") ("{" . "ъ") ("\"" . "н"))
"Mapping for `keyamp-map-input-source'")
(defun keyamp-quail-get-translation (From)
"Get translation Engineer Engram to russian-computer.
From character to character code."
(let ((to (alist-get From keyamp-engineer-engram-to-russian-computer
nil nil 'string-equal)))
(if (stringp to) (string-to-char to))))
(defun keyamp-map-input-source (Input-method)
"Build reverse mapping for INPUT-METHOD.
Use Russian input source for command mode. Respect Engineer Engram layout."
(require 'quail)
(let ((xinput (symbol-name Input-method)) (xmods '(nil (control)))
(message-log-max nil) (inhibit-message t))
(activate-input-method xinput)
(when (and current-input-method quail-keyboard-layout)
(dolist (xmap (cdr (quail-map)))
(let* ((xto (car xmap))
(xfrom (if (string-equal keyamp-current-layout "engineer-engram")
(keyamp-quail-get-translation (char-to-string xto))
(quail-get-translation (cadr xmap) (char-to-string xto) 1))))
(when (and (characterp xfrom) (characterp xto))
(dolist (x xmods)
(define-key local-function-key-map
(vector (append x (list xfrom)))
(vector (append x (list xto))))))))))
(activate-input-method nil))
(defun input-source (Source)
"Activate input method CDR SOURCE, message CAR SOURCE."
(activate-input-method (cdr Source)) (message "%s" (car Source)))
(defun toggle-input-source ()
"Toggle input method."
(interactive)
(require 'quail)
(if current-input-method
(input-source '("ABC" . nil))
(input-source '("АБВ" . russian-computer))))
;; Quail layout
(defconst quail-keyboard-layout-engineer-engram
"\
\
1@2&3/4$5<6>7*8=9+0\\#|%^`~ \
bByYoOuU'(\")lLdDwWvVzZ{[ \
cCiIeEaA,;.:hHtTsSnNqQ}] \
gGxXjJkK-_?!rRmMfFpP \
"
"Engineer Engram keyboard layout for Quail, e.g. for input method.")
(defun keyamp-push-quail-keyboard-layout ()
"Push keyboard layout to quail."
(push (cons "engineer-engram" quail-keyboard-layout-engineer-engram)
quail-keyboard-layout-alist))
(defun keyamp-qwerty-to-current-layout ()
"Toggle translation QWERTY layout to `keyamp-current-layout' on Emacs level.
Useful when `keyamp-current-layout' not available in OS or on keyboard level.
It is possible to have QWERTY keyboard using ANY custom layout in Emacs only."
(interactive)
(if (get 'keyamp-qwerty-to-current-layout 'state)
(progn (put 'keyamp-qwerty-to-current-layout 'state nil)
(quail-set-keyboard-layout "standard")
(if (eq 'keyamp-qwerty-to-current-layout this-command)
(message "Deactivated QWERTY keyboard to %s" keyamp-current-layout)))
(put 'keyamp-qwerty-to-current-layout 'state t)
(quail-set-keyboard-layout keyamp-current-layout)
(if (eq 'keyamp-qwerty-to-current-layout this-command)
(message "Activated QWERTY keyboard to %s" keyamp-current-layout)))
(let ((xl (alist-get keyamp-current-layout keyamp-layouts nil nil 'string-equal)))
(mapc (lambda (x)
(keymap-set key-translation-map
(car x)
(if (get 'keyamp-qwerty-to-current-layout 'state) (cdr x))))
xl)))
;; Keymaps
(defvar keyamp-map (make-sparse-keymap)
"Parent keymap of `keyamp-command-map'.
Define keys that are available in both command and insert modes here.")
(defvar keyamp-command-map (cons 'keymap keyamp-map)
"Keymap that takes precedence over all other keymaps in command mode.
Inherits bindings from `keyamp-map'.
In command mode, if no binding is found in this map `keyamp-map' is
checked, then if there is still no binding, the other active keymaps
are checked like normal. However, if a key is explicitly bound to nil
in this map, it will not be looked up in `keyamp-map' and lookup will
skip directly to the normally active maps.
In this way, bindings in `keyamp-map' can be disabled by this map.
Effectively, this map takes precedence over all others when command mode
is enabled.")
(define-prefix-command 'keyamp-lleader-map)
(define-prefix-command 'keyamp-rleader-map)
(keyamp--map keyamp-map
'(("<escape>" . keyamp-escape)
;; Control sequences for leaders. Russian converted from Engineer Engram.
;; The sequences are prefixes for key hold down in Karabiner.
("C-^" . keyamp-lleader-map) ("C-+" . keyamp-lleader-map)
("C-_" . keyamp-rleader-map) ("C-И" . keyamp-rleader-map)))
(keyamp--map-leader keyamp-command-map '(keyamp-lleader-map . keyamp-rleader-map))
(keyamp--map-return keyamp-command-map keyamp-insert)
;; Single keys mapping must double in Russian here. All prefix sequences mapped
;; automatically using `keyamp-map-input-source'. If missing then same.
(keyamp--map keyamp-command-map
'(;; left half
("`" . make-frame-command) ("ё" . make-frame-command) ("~" . keyamp-qwerty-to-current-layout) ("Ë" . keyamp-qwerty-to-current-layout)
("1" . kmacro-record) ("!" . self-insert-command)
("2" . kmacro-play) ("@" . self-insert-command)
("3" . kmacro-helper) ("#" . self-insert-command) ("№" . self-insert-command)
("4" . append-to-r1) ("$" . self-insert-command)
("5" . terminal-split) ("%" . self-insert-command)
("q" . insert-space-before) ("й" . insert-space-before) ("Q" . keyamp-self-insert-and-insert) ("Й" . keyamp-self-insert-and-insert)
("w" . backward-del-word) ("ц" . backward-del-word) ("W" . keyamp-self-insert-and-insert) ("Ц" . keyamp-self-insert-and-insert)
("e" . undo) ("у" . undo) ("E" . keyamp-self-insert-and-insert) ("У" . keyamp-self-insert-and-insert)
("r" . del-word) ("к" . del-word) ("R" . keyamp-self-insert-and-insert) ("К" . keyamp-self-insert-and-insert)
("t" . cut-text-block) ("е" . cut-text-block) ("T" . self-insert-command) ("Е" . keyamp-self-insert-and-insert)
("a" . shrink-whitespaces) ("ф" . shrink-whitespaces) ("A" . keyamp-self-insert-and-insert) ("Ф" . keyamp-self-insert-and-insert)
("s" . open-line) ("ы" . open-line) ("S" . keyamp-self-insert-and-insert) ("Ы" . keyamp-self-insert-and-insert)
("d" . del-back) ("в" . del-back) ("D" . keyamp-self-insert-and-insert) ("В" . keyamp-self-insert-and-insert)
("f" . newline) ("а" . newline) ("F" . keyamp-self-insert-and-insert) ("А" . keyamp-self-insert-and-insert)
("g" . activate-region) ("п" . activate-region) ("G" . self-insert-command) ("П" . keyamp-self-insert-and-insert)
("z" . toggle-comment) ("я" . toggle-comment) ("Z" . keyamp-self-insert-and-insert) ("Я" . keyamp-self-insert-and-insert)
("x" . cut-line) ("ч" . cut-line) ("X" . keyamp-self-insert-and-insert) ("Ч" . keyamp-self-insert-and-insert)
("c" . copy-line) ("с" . copy-line) ("C" . keyamp-self-insert-and-insert) ("С" . keyamp-self-insert-and-insert)
("v" . paste-or-prev) ("м" . paste-or-prev) ("V" . keyamp-self-insert-and-insert) ("М" . keyamp-self-insert-and-insert)
("b" . toggle-case) ("и" . toggle-case) ("B" . self-insert-command) ("И" . keyamp-self-insert-and-insert)
;; right half
("6" . pass) ("^" . self-insert-command)
("7" . jump-to-register) ("&" . keyamp-self-insert-and-insert)
("8" . point-to-register) ("*" . goto-match-br) ; QWERTY * → = Engineer Engram, QWERTY / → = RU PC Karabiner
("9" . proced-defer) ("(" . self-insert-command)
("0" . eshell-split) (")" . self-insert-command)
("-" . enlarge-window) ("_" . self-insert-command)
("=" . goto-match-br) ("+" . self-insert-command)
("y" . occur-cur-word) ("н" . occur-cur-word) ("Y" . self-insert-command) ("Н" . keyamp-self-insert-and-insert)
("u" . back-word) ("г" . back-word) ("U" . keyamp-self-insert-and-insert) ("Г" . keyamp-self-insert-and-insert)
("i" . previous-line) ("ш" . previous-line) ("I" . keyamp-self-insert-and-insert) ("Ш" . keyamp-self-insert-and-insert)
("o" . forw-word) ("щ" . forw-word) ("O" . keyamp-self-insert-and-insert) ("Щ" . keyamp-self-insert-and-insert)
("p" . jump-mark) ("з" . jump-mark) ("P" . keyamp-self-insert-and-insert) ("З" . keyamp-self-insert-and-insert)
("[" . alt-buf) ("х" . alt-buf) ("{" . keyamp-self-insert-and-insert) ("Х" . keyamp-self-insert-and-insert)
("]" . bookmark-bmenu-list) ("ъ" . bookmark-bmenu-list) ("}" . keyamp-self-insert-and-insert) ("Ъ" . keyamp-self-insert-and-insert)
("\\" . bookmark-set) ("|" . keyamp-self-insert-and-insert)
("h" . beg-of-line) ("р" . beg-of-line) ("H" . self-insert-command) ("Р" . keyamp-self-insert-and-insert)
("j" . backward-char) ("о" . backward-char) ("J" . keyamp-self-insert-and-insert) ("О" . keyamp-self-insert-and-insert)
("k" . next-line) ("л" . next-line) ("K" . keyamp-self-insert-and-insert) ("Л" . keyamp-self-insert-and-insert)
("l" . forward-char) ("д" . forward-char) ("L" . keyamp-self-insert-and-insert) ("Д" . keyamp-self-insert-and-insert)
(";" . end-of-lyne) ("ж" . end-of-lyne) (":" . keyamp-self-insert-and-insert) ("Ж" . keyamp-self-insert-and-insert)
("'" . alternate-frame) ("э" . alternate-frame) ("\"" . keyamp-self-insert-and-insert) ("Э" . keyamp-self-insert-and-insert)
("n" . isearch-forward) ("т" . isearch-forward) ("N" . keyamp-insert-N) ("Т" . keyamp-self-insert-and-insert)
("m" . backward-bracket) ("ь" . backward-bracket) ("M" . keyamp-self-insert-and-insert) ("Ь" . keyamp-self-insert-and-insert)
("," . other-win) ("б" . other-win) ("<" . keyamp-self-insert-and-insert) ("Б" . keyamp-self-insert-and-insert)
("." . forward-bracket) ("ю" . forward-bracket) (">" . keyamp-self-insert-and-insert) ("Ю" . keyamp-self-insert-and-insert)
("/" . goto-match-br) ("?" . keyamp-self-insert-and-insert)
("<left>" . back-char) ("<right>" . forw-char)
("<up>" . up-line) ("<down>" . down-line)))
(keyamp--map-leader keyamp-lleader-map '(select-block . select-quote))
(keyamp--map-return keyamp-lleader-map execute-extended-command)
(keyamp--map keyamp-lleader-map '(("C-t" . display-line-numbers-mode)))
(keyamp--map-escape keyamp-lleader-map ignore)
(keyamp--map-backtab keyamp-lleader-map prev-proj-buf)
(keyamp--map-tab keyamp-lleader-map read-only-mode)
(keyamp--map keyamp-lleader-map
'(;; left leader left half
("`" . revert-buffer)
("1" . periodic-chart)
("2" . kmacro-name-last-macro)
("3" . apply-macro-to-region-lines)
("4" . clear-r1)
("5" . repeat-complex-command)
("q" . reformat-lines)
("w" . org-ctrl-c-ctrl-c)
("e" . del-win)
("r" . query-replace)
("t" . copy-text-block)
("a" . kill-line)
("s" . prev-buf)
("d" . alt-buf)
("f" . next-buf)
("g" . new-empty-buffer)
("z" . universal-argument)
("x" . restart-emacs)
("c" . copy-to-r1)
("v" . paste-from-r1)
("b" . toggle-prev-letter-case)
;; left leader right half
("6" . quit)
("7" . number-to-register)
("8" . sql)
("9" . screenshot)
("0" . eww)
("-" . snake)
("=" . tetris)
("y" . find-name-dired)
("u" . flymake-goto-prev-error)
("i i" . copy-file-path)
("i DEL" . count-words) ("i SPC" . count-matches)
("i <escape>" . ignore) ("i RET" . show-in-desktop)
("o" . flymake-goto-next-error)
("p" . show-kill-ring)
("[" . toggle-frame-maximized)
("]" . write-file)
("\\" . bookmark-rename)
("h" . go-new)
("j l" . narrow-to-region-or-block)
("j k" . narrow-to-defun)
("j j" . widen)
("j DEL" . hl-line-mode) ("j SPC" . whitespace-mode)
("j <escape>" . ignore) ("j RET" . toggle-word-wrap)
("k s" . space-to-newline)
("k d" . delete-matching-lines) ("k k" . list-matching-lines)
("k f" . delete-non-matching-lines)
("k r" . quote-lines) ("k u" . escape-quotes)
("k t" . delete-duplicate-lines) ("k y" . slash-to-double-backslash)
("k v" . reformat-to-sentence-lines) ("k n" . double-backslash-to-slash)
("k w" . sort-lines-key-value) ("k o" . slash-to-backslash)
("k x" . insert-column-a-z) ("k ." . sort-lines-block-or-region)
("k c" . cycle-hyphen-lowline-space) ("k ," . sort-numeric-fields)
("k DEL" . ispell-word) ("k SPC" . flyspell-buffer)
("k <escape>" . ignore) ("k RET" . find-file)
("l" . describe-foo-at-point)
(";" . recentf-open-files)
("'" . sync)
("n" . list-timers)
("m" . yt-dlp)
("," . list-processes)
("." . open-last-closed)
("/" . goto-line)))
(if (display-graphic-p)
(keyamp--map keyamp-lleader-map
'(("i DEL" . nil) ("i <backspace>" . count-words)
("i RET" . nil) ("i <return>" . show-in-desktop)
("j DEL" . nil) ("j <backspace>" . hl-line-mode)
("j RET" . nil) ("j <return>" . toggle-truncate-lines)
("k DEL" . nil) ("k <backspace>" . ispell-word)
("k RET" . nil) ("k <return>" . find-file)
("<mouse-1>" . ignore)
("<mouse-2>" . ignore)
("<mouse-3>" . ignore)
("<down-mouse-1>" . mouse-drag-region-rectangle))))
(keyamp--map-leader keyamp-rleader-map '(select-line . select-word))
(keyamp--map-return keyamp-rleader-map open-file)
(keyamp--map keyamp-rleader-map '(("C-t" . toggle-truncate-lines)))
(keyamp--map-escape keyamp-rleader-map ignore)
(keyamp--map-backtab keyamp-rleader-map speedbar)
(keyamp--map-tab keyamp-rleader-map next-proj-buf)
(keyamp--map keyamp-rleader-map
'(;; right leader left half
("`" . find-next-dir-file)
("1" . view-lossage)
("2" . insert-kbd-macro)
("3" . config)
("4" . change-bracket-pairs)
("5" . json-pretty)
("q" . fill-or-unfill)
("w" . sun-moon)
("e e" . todo) ("e k" . weather)
("e DEL" . clock) ("e SPC" . calendar)
("e <escape>" . ignore) ("e RET" . insert-date)
("r" . query-replace-regexp)
("t" . calc)
("a" . mark-whole-buffer)
("s" . clean-whitespace)
("D" . repeat) ("В" . repeat)
("d e" . org-shiftup) ("d i" . async-shell-command)
("d d" . eval-region-or-sexp) ("d k" . run-current-file)
("d DEL" . stow) ("d SPC" . eval-defun)
("d <escape>" . ignore) ("d RET" . shell-command)
("f e" . insert-emacs-quote) ("f i" . insert-ascii-single-quote)
("f f" . insert-char) ("f j" . insert-brace)
("f k" . insert-paren)
("f s" . insert-formfeed) ("f l" . insert-square-bracket)
("f g" . insert-double-angle-quote) ("f h" . insert-double-curly-quote)
("f DEL" . insert-backtick-quote) ("f SPC" . insert-ascii-double-quote)
("f <escape>" . ignore) ("f RET" . emoji-insert)
("g" . python-new)
("z" . goto-char)
("x" . next-eww-buffer)
("c" . copy-all)
("v" . tasks)
("b" . title-case-region-or-line)
;; right leader right half
("6" . pass-generate)
("7" . copy-to-register)
("8" . insert-register)
("9" . org-insert-source-code)
("0" . toggle-theme)
("-" . enlarge-window-horizontally)
("=" . toggle-input-source)
("y" . search-string)
("u" . backward-punct)
("i" . beg-of-block)
("o" . forward-punct)
("p" . mark-defun)
("[" . open-last-closed)
("]" . rename-visited-file)
("\\" . bookmark-delete)
("h" . page-up-half)
("j" . isearch-wback)
("k" . end-of-block)
("l" . isearch-wforw)
(";" . page-dn-half)
("'" . toggle-frame-maximized)
("n" . toggle-case-fold-search)
("m" . dired-jump)
("," . delete-window)
("." . save-close-buf)
("/" . view-messages)
("*" . view-messages)))
(if (display-graphic-p)
(keyamp--map keyamp-rleader-map
'(("e DEL" . nil) ("e <backspace>" . clock)
("e RET" . nil) ("e <return>" . insert-date)
("d DEL" . nil) ("d <backspace>" . stow)
("d RET" . nil) ("d <return>" . shell-command)
("f DEL" . nil) ("f <backspace>" . insert-backtick-quote)
("f RET" . nil) ("f <return>" . emoji-insert)
("<mouse-1>" . ignore)
("<mouse-2>" . ignore)
("<mouse-3>" . ignore))))
(keyamp--map-double
'((keyamp-escape . alternate-frame) (activate-region . deactivate-region)
(beg-of-line . bookmark-jump) (end-of-lyne . switch-to-buffer)
(kmacro-record . keyamp-delete) (other-win . delete-other-windows)
(proced-defer . save-close-buf) (append-to-r1 . clear-r1)
(occur-cur-word . search-string)))
;; Remaps
(when (display-graphic-p)
(keymap-set global-map "<tab>" 'indent-for-tab-command) ; /lisp/indent.el.gz:816
(keymap-set key-translation-map "S-SPC" "<tab>")
(keymap-set key-translation-map "S-<backspace>" "<backtab>")
(keymap-set key-translation-map "S-<escape>" "C-h")
(keymap-set key-translation-map "S-<return>" "C-t"))
(setq help-map (make-sparse-keymap))
(fset 'help-command help-map)
(keyamp--map-leader help-map '(lookup-word-definition . translate))
(keyamp--map-escape help-map ignore)
(keyamp--map-return help-map lookup-web)
(keyamp--map-backtab help-map lookup-etymology)
(keyamp--map-tab help-map lookup-wikipedia)
(keyamp--map help-map
'(("e" . describe-char) ("i" . info)
("s" . info-lookup-symbol) ("j" . describe-function)
("d" . man) ("k" . describe-key)
("f" . elisp-index-search) ("l" . describe-variable)
("q" . describe-syntax) ("p" . apropos-documentation)
("w" . describe-bindings) ("o" . lookup-all-dictionaries)
("r" . describe-mode) ("u" . lookup-all-synonyms)
("a" . describe-face) (";" . lookup-wiktionary)
("g" . apropos-command) ("h" . describe-coding-system)
("z" . apropos-variable) ("x" . apropos-value)))
(keyamp--map global-map '(("C-r" . delete-other-windows) ("C-t" . hippie-expand)))
(when (display-graphic-p)
(keyamp--map global-map
'(("<prior>" . page-up-half) ("<next>" . page-dn-half)
("<double-mouse-1>" . select-word) ("<mouse-3>" . mouse-3)))
(advice-add 'mouse-set-point :around 'lookup-around)
(advice-add 'mouse-set-point :before 'scroll-one-pixel)
(advice-add 'mouse-set-point :after 'keyamp-command-if-insert)
(advice-add 'mouse-drag-region :before 'copy-selection))
(advice-add 'keyamp-insert :before 'delete-before)
(advice-add 'keyamp-insert :around 'lookup-around)
(advice-add 'keyamp-insert :around 'translate-around)
(with-sparse-keymap
;; Repeat using DEL/SPC or D. The concept widely used to form Repeat mode.
(keyamp--map-leader keymap '(del-back . del-back))
(keyamp--remap keymap '((del-back . repeat)))
(keyamp--set keymap '(repeat)))
(with-sparse-keymap
;; S-RET to call `hippie-expand'. Press RET to insert a possible expansion.
(keyamp--map-leader keymap '(hippie-expand-undo . self-insert-command))
(keyamp--map-return keymap hippie-expand)
(keyamp--set keymap '(hippie-expand)))
;; I-search
(with-sparse-keymap
;; After starting up an isearch press DEL to retreat to the previous
;; search string. Press SPC to pull string from kill ring into search string.
(keyamp--map-leader keymap '(isearch-ring-retreat . isearch-yank-kill))
;; Double press N to save modified file.
(keyamp--map keymap '(("n" . save-buffer-isearch-cancel) ("т" . save-buffer-isearch-cancel)))
(keyamp--hook keymap '(isearch-mode-hook) nil nil :repeat))
;; Hit TAB to repeat after typing in search string and set following transient
;; map. Backtab to repeat backward. S-DEL/S-SPC for Backtab/TAB.
(keyamp--map-leader isearch-mode-map '(isearch-del-char . isearch-printing-char))
(keyamp--map-escape isearch-mode-map isearch-cancel)
(keyamp--map-backtab isearch-mode-map isearch-back)
(keyamp--map-tab isearch-mode-map isearch-forw)
(keyamp--map isearch-mode-map '(("C-^" . keyamp-lleader-map)))
(keyamp--remap isearch-mode-map '((paste-from-r1 . isearch-yank-r1)))
(with-sparse-keymap
;; Find the occurrence of the current search string with J/L or DEL/SPC.
;; Press I/K or DEL/SPC to get search strings from the ring.
;; S-SPC to find the occurrence of the last search string.
(keyamp--map-leader keymap '(isearch-back . isearch-forw))
(keyamp--map keymap
'(("i" . isearch-ring-retreat) ("ш" . isearch-ring-retreat)
("j" . isearch-back) ("о" . isearch-back)
("k" . isearch-ring-advance) ("л" . isearch-ring-advance)
("l" . isearch-forw) ("д" . isearch-forw)))
(keyamp--set keymap
'(isearch-ring-retreat isearch-ring-advance
isearch-back isearch-forw
isearch-wforw isearch-wback
isearch-yank-kill))
(defun isearch-mode-exit-minibuffer ()
"Setup isearch transient after choice from the ring and exit minibuffer."
(when (eq real-this-command 'exit-minibuffer)
(keyamp-repeat-deactivate-init keymap)
(setq this-command 'isearch-forw)))
(add-hook 'isearch-mode-hook 'isearch-mode-exit-minibuffer 96))
(with-sparse-keymap
;; Press I/K or DEL/SPC to get search strings from the ring
;; then S-DEL/S-SPC to find the occurrence of the search string.
(keyamp--map-leader keymap '(hist-back . hist-forw))
(keyamp--map-escape keymap isearch-cancel-clean-are)
(keyamp--map-backtab keymap exit-minibuffer)
(keyamp--map-tab keymap exit-minibuffer)
(defun isearch-mode-setup-minibuffer ()
"Setup isearch transient in minibuffer before choice from the ring."
(if (isearch-minibuffer-prompt)
(keyamp-repeat-deactivate-init keymap)))
(add-hook 'minibuffer-setup-hook 'isearch-mode-setup-minibuffer 96)
(advice-add-macro '(hist-back hist-forw) :after 'isearch-mode-setup-minibuffer))
(defun keyamp-screen-TAB ()
"Tab key command for transient use."
(interactive)
(cond ((eq major-mode 'org-agenda-mode) (keyamp-command-execute 'todo))
((eq major-mode 'ibuffer-mode) (keyamp-command-execute 'ibuffer-select-group))
((eq major-mode 'gnus-group-mode) (keyamp-command-execute 'gnus-topic-select-group))
((eq last-command 'up-line) (keyamp-command-execute 'del-win)) ; see below default for down-line
(t (keyamp-command-execute 'page-dn-half))))
(defun keyamp-RET ()
"Return key command for transient use."
(interactive)
(if (eq major-mode 'eww-mode)
(keyamp-command-execute 'keyamp-insert) ; do translate
(if (display-graphic-p)
(keyamp-exe-remap "<return>" 'keyamp-insert 'keyamp-escape)
(keyamp-exe-remap "RET" 'keyamp-insert 'keyamp-escape))))
(defun keyamp-delete ()
"Keyamp do delete."
(interactive)
(cond ((eq major-mode 'dired-mode) (keyamp-command-execute 'dired-do-delete))
((eq major-mode 'ibuffer-mode) (keyamp-command-execute 'ibuffer-do-delete))
((eq major-mode 'eshell-mode) (keyamp-command-execute 'eshell-interrupt-process))
((eq major-mode 'vterm-mode) (keyamp-command-execute 'term-interrupt-subjob))
(t (keyamp-command-execute 'ignore))))
;; Repeat mode - screen commands
(defvar keyamp-delay-1 1 "Delay 1 second.")
(defvar keyamp-delay-2 2 "Delay 2 seconds.")
(defvar keyamp-delay-3 3 "Delay 3 seconds.")
(with-sparse-keymap
;; Leader layer to become transient main. Base map for next leaders adjustment
;; by transient maps which might be set by following target commands subsets.
(keyamp--map-leader keymap '(open-line . newline))
(keyamp--map-return keymap keyamp-escape)
(keyamp--map-backtab keymap page-up-half)
(keyamp--map-tab keymap keyamp-screen-TAB)
(keyamp--remap keymap
'((make-frame-command . delete-frame)
(insert-space-before . clock)
(backward-del-word . sun-moon)
(undo . del-win)
(del-word . toggle-gnus)
(cut-text-block . calc)
(goto-match-br . view-messages)
(shrink-whitespaces . calendar-split)
(del-back . alt-buf)
(toggle-comment . view-messages)
(cut-line . prev-eww-buffer)
(copy-line . screen-idle)
(paste-or-prev . tasks)
(toggle-case . downloads)
(backward-bracket . dired-jump)
(forward-bracket . save-close-buf)
(kmacro-helper . config)
(point-to-register . sql)
(up-line . view-messages)
(down-line . screen-idle)
(back-char . next-buf)
(forw-char . prev-buf)
(proced-defer . save-close-buf)
(kmacro-play . save-close-buf)
(append-to-r1 . recentf-open-files)))
(keyamp--set keymap
'(prev-buf next-buf
delete-other-windows split-window-below
delete-window save-close-buf
prev-proj-buf next-proj-buf
prev-eww-buffer next-eww-buffer
prev-eshell-buffer next-eshell-buffer
prev-vterm-buffer next-vterm-buffer
tasks config
previous-buffer next-buffer
find-prev-dir-file find-next-dir-file
shrink-window enlarge-window
shrink-window-horizontally enlarge-window-horizontally
org-agenda-tasks split-window-horizontally)))
(with-sparse-keymap
;; DEL/SPC to switch other window after split as a result of the commands.
(keyamp--map-leader keymap '(other-window . other-window))
(keyamp--map-return keymap delete-other-windows)
(keyamp--remap keymap '((down-line . delete-other-windows)))
(keyamp--set keymap
'(describe-foo-at-point describe-variable
describe-function describe-key
describe-mode describe-char
describe-face list-matching-lines
player occur-cur-word
run-current-file exec-query
view-messages sun-moon
clock async-shell-command
sync calendar-split)))
(with-sparse-keymap
(keyamp--remap keymap '((open-line . prev-buf) (newline . next-buf)))
(keyamp--set keymap
'(prev-buf next-buf delete-other-windows delete-window split-window-below
split-window-horizontally)))
(with-sparse-keymap
(keyamp--remap keymap '((open-line . prev-proj-buf) (newline . next-proj-buf)))
(keyamp--set keymap '(prev-proj-buf next-proj-buf)))
(with-sparse-keymap
(keyamp--map-backtab keymap page-up-half)
(keyamp--map-tab keymap keyamp-screen-TAB)
(keyamp--remap keymap
'((open-line . prev-eww-buffer) (newline . next-eww-buffer)
(del-back . eww-reload) (undo . justify-buffer)))
(keyamp--set keymap '(prev-eww-buffer next-eww-buffer)))
(with-sparse-keymap
(keyamp--map-backtab keymap page-up-half)
(keyamp--map-tab keymap keyamp-screen-TAB)
(keyamp--remap keymap '((open-line . prev-eshell-buffer) (newline . next-eshell-buffer)))
(keyamp--set keymap '(prev-eshell-buffer next-eshell-buffer)))
(with-sparse-keymap
(keyamp--map-backtab keymap page-up-half)
(keyamp--map-tab keymap keyamp-screen-TAB)
(keyamp--remap keymap '((open-line . prev-vterm-buffer) (newline . next-vterm-buffer)))
(keyamp--set keymap '(prev-vterm-buffer next-vterm-buffer)))
(with-sparse-keymap
(keyamp--remap keymap '((open-line . prev-buf) (newline . tasks)))
(keyamp--set keymap '(tasks org-agenda-tasks)))
(with-sparse-keymap
(keyamp--remap keymap '((open-line . prev-buf) (newline . config)))
(keyamp--set keymap '(config)))
(with-sparse-keymap
(keyamp--remap keymap '((open-line . previous-buffer) (newline . next-buffer)))
(keyamp--set keymap '(previous-buffer next-buffer)))
(with-sparse-keymap
(keyamp--remap keymap '((open-line . find-prev-dir-file) (newline . find-next-dir-file)))
(keyamp--set keymap '(find-prev-dir-file find-next-dir-file)))
(with-sparse-keymap
(keyamp--remap keymap
'((backward-bracket . dired-jump) (forward-bracket . save-close-buf)))
(keyamp--set keymap
'(dired-jump downloads dired-find-file ibuffer-visit-buffer open-last-closed
bookmark-jump widget-button-press alt-buf)))
(with-sparse-keymap
(keyamp--remap keymap
'((open-line . prev-buf) (newline . next-buf)
(forward-bracket . save-close-buf) (keyamp-insert . keyamp-escape)
(proced-defer . save-close-buf)))
(keyamp--set keymap '(save-close-buf)))
(with-sparse-keymap
(keyamp--remap keymap '((open-line . shrink-window) (newline . enlarge-window)))
(keyamp--set keymap '(shrink-window enlarge-window) nil nil nil keyamp-delay-2))
(with-sparse-keymap
(keyamp--remap keymap '((open-line . shrink-window-horizontally) (newline . enlarge-window-horizontally)))
(keyamp--set keymap '(enlarge-window-horizontally shrink-window-horizontally)
nil nil nil keyamp-delay-2))
(with-sparse-keymap
(keyamp--remap keymap '((make-frame-command . delete-frame)))
(keyamp--set keymap '(alternate-frame)))
(defun run-current-file-indicate ()
"Defer indicate for `run-current-file' after indicate modify."
(run-with-timer keyamp-delay-1 nil
'keyamp-blink-start keyamp-screen-color keyamp-read-color))
(advice-add 'run-current-file :after 'run-current-file-indicate)
;; Repeat mode - read commands
(with-sparse-keymap
;; Initiate by triple DEL/SPC (hold down).
;; I/K or DEL/SPC to move by lines. See `return-before'.
(keyamp--map-leader keymap '(up-line . down-line))
(keyamp--map-return keymap keyamp-RET)
(keyamp--map-backtab keymap page-up-half)
(keyamp--map-tab keymap keyamp-screen-TAB)
(keyamp--map keymap '(("<up>" . up-line-rev)))
(keyamp--remap keymap '((previous-line . up-line-rev) (next-line . down-line)))
(keyamp--set keymap '(up-line down-line))
(keyamp--hook keymap '(ibuffer-hook gnus-group-mode-hook) nil nil :repeat)
(defvar keyamp-lines-move-modes
'(occur-mode gnus-group-mode emms-playlist-mode
ibuffer-mode eww-mode messages-buffer-mode )