1 ;;; hydra-test.el --- Tests for Hydra
3 ;; Copyright (C) 2015 Free Software Foundation, Inc.
7 ;; This file is part of GNU Emacs.
9 ;; GNU Emacs is free software: you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation, either version 3 of the License, or
12 ;; (at your option) any later version.
14 ;; GNU Emacs is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
29 (ert-deftest hydra-red-error ()
33 '(defhydra hydra-error (global-map "M-g")
35 ("h" first-error "first")
36 ("j" next-error "next")
37 ("k" previous-error "prev")
38 ("SPC" hydra-repeat "rep" :bind nil)))
40 (defun hydra-error/first-error nil "Create a hydra with a \"M-g\" body and the heads:
44 \"k\": `previous-error',
45 \"SPC\": `hydra-repeat'
47 The body can be accessed via `hydra-error/body'.
49 Call the head: `first-error'."
53 (catch (quote hydra-disable)
54 (condition-case err (prog1 t (call-interactively (function first-error)))
57 (unless hydra-lv (sit-for 0.8))
59 (when hydra-is-helpful (hydra-error/hint))
61 (hydra-set-transient-map
63 (quote (keymap (7 . hydra-keyboard-quit)
65 (107 . hydra-error/previous-error)
66 (106 . hydra-error/next-error)
67 (104 . hydra-error/first-error)
68 (switch-frame . hydra--handle-switch-frame)
69 (kp-subtract . hydra--negative-argument)
70 (kp-9 . hydra--digit-argument)
71 (kp-8 . hydra--digit-argument)
72 (kp-7 . hydra--digit-argument)
73 (kp-6 . hydra--digit-argument)
74 (kp-5 . hydra--digit-argument)
75 (kp-4 . hydra--digit-argument)
76 (kp-3 . hydra--digit-argument)
77 (kp-2 . hydra--digit-argument)
78 (kp-1 . hydra--digit-argument)
79 (kp-0 . hydra--digit-argument)
80 (57 . hydra--digit-argument)
81 (56 . hydra--digit-argument)
82 (55 . hydra--digit-argument)
83 (54 . hydra--digit-argument)
84 (53 . hydra--digit-argument)
85 (52 . hydra--digit-argument)
86 (51 . hydra--digit-argument)
87 (50 . hydra--digit-argument)
88 (49 . hydra--digit-argument)
89 (48 . hydra--digit-argument)
90 (45 . hydra--negative-argument)
91 (21 . hydra--universal-argument))))
92 t (lambda nil (hydra-cleanup))))))
93 (defun hydra-error/next-error nil "Create a hydra with a \"M-g\" body and the heads:
97 \"k\": `previous-error',
98 \"SPC\": `hydra-repeat'
100 The body can be accessed via `hydra-error/body'.
102 Call the head: `next-error'."
106 (catch (quote hydra-disable)
107 (condition-case err (prog1 t (call-interactively (function next-error)))
110 (unless hydra-lv (sit-for 0.8))
112 (when hydra-is-helpful (hydra-error/hint))
114 (hydra-set-transient-map
116 (quote (keymap (7 . hydra-keyboard-quit)
118 (107 . hydra-error/previous-error)
119 (106 . hydra-error/next-error)
120 (104 . hydra-error/first-error)
121 (switch-frame . hydra--handle-switch-frame)
122 (kp-subtract . hydra--negative-argument)
123 (kp-9 . hydra--digit-argument)
124 (kp-8 . hydra--digit-argument)
125 (kp-7 . hydra--digit-argument)
126 (kp-6 . hydra--digit-argument)
127 (kp-5 . hydra--digit-argument)
128 (kp-4 . hydra--digit-argument)
129 (kp-3 . hydra--digit-argument)
130 (kp-2 . hydra--digit-argument)
131 (kp-1 . hydra--digit-argument)
132 (kp-0 . hydra--digit-argument)
133 (57 . hydra--digit-argument)
134 (56 . hydra--digit-argument)
135 (55 . hydra--digit-argument)
136 (54 . hydra--digit-argument)
137 (53 . hydra--digit-argument)
138 (52 . hydra--digit-argument)
139 (51 . hydra--digit-argument)
140 (50 . hydra--digit-argument)
141 (49 . hydra--digit-argument)
142 (48 . hydra--digit-argument)
143 (45 . hydra--negative-argument)
144 (21 . hydra--universal-argument))))
145 t (lambda nil (hydra-cleanup))))))
146 (defun hydra-error/previous-error nil "Create a hydra with a \"M-g\" body and the heads:
148 \"h\": `first-error',
150 \"k\": `previous-error',
151 \"SPC\": `hydra-repeat'
153 The body can be accessed via `hydra-error/body'.
155 Call the head: `previous-error'."
159 (catch (quote hydra-disable)
160 (condition-case err (prog1 t (call-interactively (function previous-error)))
163 (unless hydra-lv (sit-for 0.8))
165 (when hydra-is-helpful (hydra-error/hint))
167 (hydra-set-transient-map
169 (quote (keymap (7 . hydra-keyboard-quit)
171 (107 . hydra-error/previous-error)
172 (106 . hydra-error/next-error)
173 (104 . hydra-error/first-error)
174 (switch-frame . hydra--handle-switch-frame)
175 (kp-subtract . hydra--negative-argument)
176 (kp-9 . hydra--digit-argument)
177 (kp-8 . hydra--digit-argument)
178 (kp-7 . hydra--digit-argument)
179 (kp-6 . hydra--digit-argument)
180 (kp-5 . hydra--digit-argument)
181 (kp-4 . hydra--digit-argument)
182 (kp-3 . hydra--digit-argument)
183 (kp-2 . hydra--digit-argument)
184 (kp-1 . hydra--digit-argument)
185 (kp-0 . hydra--digit-argument)
186 (57 . hydra--digit-argument)
187 (56 . hydra--digit-argument)
188 (55 . hydra--digit-argument)
189 (54 . hydra--digit-argument)
190 (53 . hydra--digit-argument)
191 (52 . hydra--digit-argument)
192 (51 . hydra--digit-argument)
193 (50 . hydra--digit-argument)
194 (49 . hydra--digit-argument)
195 (48 . hydra--digit-argument)
196 (45 . hydra--negative-argument)
197 (21 . hydra--universal-argument))))
198 t (lambda nil (hydra-cleanup))))))
199 (unless (keymapp (lookup-key global-map (kbd "M-g")))
200 (define-key global-map (kbd "M-g")
202 (define-key global-map [134217831 104]
203 (function hydra-error/first-error))
204 (define-key global-map [134217831 106]
205 (function hydra-error/next-error))
206 (define-key global-map [134217831 107]
207 (function hydra-error/previous-error))
208 (defun hydra-error/hint nil
209 (if hydra-lv (lv-message (format #("error: [h]: first, [j]: next, [k]: prev, [SPC]: rep." 8 9 (face hydra-face-red)
210 20 21 (face hydra-face-red)
211 31 32 (face hydra-face-red)
212 42 45 (face hydra-face-red))))
213 (message (format #("error: [h]: first, [j]: next, [k]: prev, [SPC]: rep." 8 9 (face hydra-face-red)
214 20 21 (face hydra-face-red)
215 31 32 (face hydra-face-red)
216 42 45 (face hydra-face-red))))))
217 (defun hydra-error/body nil "Create a hydra with a \"M-g\" body and the heads:
219 \"h\": `first-error',
221 \"k\": `previous-error',
222 \"SPC\": `hydra-repeat'
224 The body can be accessed via `hydra-error/body'."
228 (catch (quote hydra-disable)
229 (when hydra-is-helpful (hydra-error/hint))
231 (hydra-set-transient-map
233 (quote (keymap (7 . hydra-keyboard-quit)
235 (107 . hydra-error/previous-error)
236 (106 . hydra-error/next-error)
237 (104 . hydra-error/first-error)
238 (switch-frame . hydra--handle-switch-frame)
239 (kp-subtract . hydra--negative-argument)
240 (kp-9 . hydra--digit-argument)
241 (kp-8 . hydra--digit-argument)
242 (kp-7 . hydra--digit-argument)
243 (kp-6 . hydra--digit-argument)
244 (kp-5 . hydra--digit-argument)
245 (kp-4 . hydra--digit-argument)
246 (kp-3 . hydra--digit-argument)
247 (kp-2 . hydra--digit-argument)
248 (kp-1 . hydra--digit-argument)
249 (kp-0 . hydra--digit-argument)
250 (57 . hydra--digit-argument)
251 (56 . hydra--digit-argument)
252 (55 . hydra--digit-argument)
253 (54 . hydra--digit-argument)
254 (53 . hydra--digit-argument)
255 (52 . hydra--digit-argument)
256 (51 . hydra--digit-argument)
257 (50 . hydra--digit-argument)
258 (49 . hydra--digit-argument)
259 (48 . hydra--digit-argument)
260 (45 . hydra--negative-argument)
261 (21 . hydra--universal-argument))))
262 t (lambda nil (hydra-cleanup))))
263 (setq prefix-arg current-prefix-arg)))))))
265 (ert-deftest hydra-blue-toggle ()
269 '(defhydra hydra-toggle (:color blue)
271 ("t" toggle-truncate-lines "truncate")
272 ("f" auto-fill-mode "fill")
273 ("a" abbrev-mode "abbrev")
276 (defun hydra-toggle/toggle-truncate-lines-and-exit nil "Create a hydra with no body and the heads:
278 \"t\": `toggle-truncate-lines',
279 \"f\": `auto-fill-mode',
280 \"a\": `abbrev-mode',
283 The body can be accessed via `hydra-toggle/body'.
285 Call the head: `toggle-truncate-lines'."
290 (catch (quote hydra-disable)
291 (call-interactively (function toggle-truncate-lines))))
292 (defun hydra-toggle/auto-fill-mode-and-exit nil "Create a hydra with no body and the heads:
294 \"t\": `toggle-truncate-lines',
295 \"f\": `auto-fill-mode',
296 \"a\": `abbrev-mode',
299 The body can be accessed via `hydra-toggle/body'.
301 Call the head: `auto-fill-mode'."
306 (catch (quote hydra-disable)
307 (call-interactively (function auto-fill-mode))))
308 (defun hydra-toggle/abbrev-mode-and-exit nil "Create a hydra with no body and the heads:
310 \"t\": `toggle-truncate-lines',
311 \"f\": `auto-fill-mode',
312 \"a\": `abbrev-mode',
315 The body can be accessed via `hydra-toggle/body'.
317 Call the head: `abbrev-mode'."
322 (catch (quote hydra-disable)
323 (call-interactively (function abbrev-mode))))
324 (defun hydra-toggle/nil nil "Create a hydra with no body and the heads:
326 \"t\": `toggle-truncate-lines',
327 \"f\": `auto-fill-mode',
328 \"a\": `abbrev-mode',
331 The body can be accessed via `hydra-toggle/body'.
333 Call the head: `nil'."
338 (catch (quote hydra-disable)))
339 (defun hydra-toggle/hint nil
340 (if hydra-lv (lv-message (format #("toggle: [t]: truncate, [f]: fill, [a]: abbrev, [q]: cancel." 9 10 (face hydra-face-blue)
341 24 25 (face hydra-face-blue)
342 35 36 (face hydra-face-blue)
343 48 49 (face hydra-face-blue))))
344 (message (format #("toggle: [t]: truncate, [f]: fill, [a]: abbrev, [q]: cancel." 9 10 (face hydra-face-blue)
345 24 25 (face hydra-face-blue)
346 35 36 (face hydra-face-blue)
347 48 49 (face hydra-face-blue))))))
348 (defun hydra-toggle/body nil "Create a hydra with no body and the heads:
350 \"t\": `toggle-truncate-lines',
351 \"f\": `auto-fill-mode',
352 \"a\": `abbrev-mode',
355 The body can be accessed via `hydra-toggle/body'."
359 (catch (quote hydra-disable)
360 (when hydra-is-helpful (hydra-toggle/hint))
362 (hydra-set-transient-map
364 (quote (keymap (7 . hydra-keyboard-quit)
365 (113 . hydra-toggle/nil)
366 (97 . hydra-toggle/abbrev-mode-and-exit)
367 (102 . hydra-toggle/auto-fill-mode-and-exit)
368 (116 . hydra-toggle/toggle-truncate-lines-and-exit)
369 (switch-frame . hydra--handle-switch-frame)
370 (kp-subtract . hydra--negative-argument)
371 (kp-9 . hydra--digit-argument)
372 (kp-8 . hydra--digit-argument)
373 (kp-7 . hydra--digit-argument)
374 (kp-6 . hydra--digit-argument)
375 (kp-5 . hydra--digit-argument)
376 (kp-4 . hydra--digit-argument)
377 (kp-3 . hydra--digit-argument)
378 (kp-2 . hydra--digit-argument)
379 (kp-1 . hydra--digit-argument)
380 (kp-0 . hydra--digit-argument)
381 (57 . hydra--digit-argument)
382 (56 . hydra--digit-argument)
383 (55 . hydra--digit-argument)
384 (54 . hydra--digit-argument)
385 (53 . hydra--digit-argument)
386 (52 . hydra--digit-argument)
387 (51 . hydra--digit-argument)
388 (50 . hydra--digit-argument)
389 (49 . hydra--digit-argument)
390 (48 . hydra--digit-argument)
391 (45 . hydra--negative-argument)
392 (21 . hydra--universal-argument))))
393 t (lambda nil (hydra-cleanup))))
394 (setq prefix-arg current-prefix-arg)))))))
396 (ert-deftest hydra-amaranth-vi ()
402 (set-cursor-color "#e52b50")
404 (set-cursor-color "#ffffff")
411 (defun hydra-vi/hydra-keyboard-quit-and-exit nil "Create a hydra with no body and the heads:
413 \"
\a\": `hydra-keyboard-quit',
415 \"k\": `previous-line',
418 The body can be accessed via `hydra-vi/body'.
420 Call the head: `hydra-keyboard-quit'."
423 (set-cursor-color "#e52b50")
426 (catch (quote hydra-disable)
427 (call-interactively (function hydra-keyboard-quit))
428 (set-cursor-color "#ffffff")))
429 (defun hydra-vi/next-line nil "Create a hydra with no body and the heads:
431 \"
\a\": `hydra-keyboard-quit',
433 \"k\": `previous-line',
436 The body can be accessed via `hydra-vi/body'.
438 Call the head: `next-line'."
441 (set-cursor-color "#e52b50")
443 (catch (quote hydra-disable)
444 (condition-case err (prog1 t (call-interactively (function next-line)))
447 (unless hydra-lv (sit-for 0.8))
449 (when hydra-is-helpful (hydra-vi/hint))
451 (hydra-set-transient-map
453 (quote (keymap (t lambda nil (interactive)
454 (message "An amaranth Hydra can only exit through a blue head")
455 (hydra-set-transient-map hydra-curr-map t)
456 (when hydra-is-helpful (unless hydra-lv (sit-for 0.8))
459 (107 . hydra-vi/previous-line)
460 (106 . hydra-vi/next-line)
461 (7 . hydra-vi/hydra-keyboard-quit-and-exit)
462 (switch-frame . hydra--handle-switch-frame)
463 (kp-subtract . hydra--negative-argument)
464 (kp-9 . hydra--digit-argument)
465 (kp-8 . hydra--digit-argument)
466 (kp-7 . hydra--digit-argument)
467 (kp-6 . hydra--digit-argument)
468 (kp-5 . hydra--digit-argument)
469 (kp-4 . hydra--digit-argument)
470 (kp-3 . hydra--digit-argument)
471 (kp-2 . hydra--digit-argument)
472 (kp-1 . hydra--digit-argument)
473 (kp-0 . hydra--digit-argument)
474 (57 . hydra--digit-argument)
475 (56 . hydra--digit-argument)
476 (55 . hydra--digit-argument)
477 (54 . hydra--digit-argument)
478 (53 . hydra--digit-argument)
479 (52 . hydra--digit-argument)
480 (51 . hydra--digit-argument)
481 (50 . hydra--digit-argument)
482 (49 . hydra--digit-argument)
483 (48 . hydra--digit-argument)
484 (45 . hydra--negative-argument)
485 (21 . hydra--universal-argument))))
486 t (lambda nil (hydra-cleanup))))))
487 (defun hydra-vi/previous-line nil "Create a hydra with no body and the heads:
489 \"
\a\": `hydra-keyboard-quit',
491 \"k\": `previous-line',
494 The body can be accessed via `hydra-vi/body'.
496 Call the head: `previous-line'."
499 (set-cursor-color "#e52b50")
501 (catch (quote hydra-disable)
502 (condition-case err (prog1 t (call-interactively (function previous-line)))
505 (unless hydra-lv (sit-for 0.8))
507 (when hydra-is-helpful (hydra-vi/hint))
509 (hydra-set-transient-map
511 (quote (keymap (t lambda nil (interactive)
512 (message "An amaranth Hydra can only exit through a blue head")
513 (hydra-set-transient-map hydra-curr-map t)
514 (when hydra-is-helpful (unless hydra-lv (sit-for 0.8))
517 (107 . hydra-vi/previous-line)
518 (106 . hydra-vi/next-line)
519 (7 . hydra-vi/hydra-keyboard-quit-and-exit)
520 (switch-frame . hydra--handle-switch-frame)
521 (kp-subtract . hydra--negative-argument)
522 (kp-9 . hydra--digit-argument)
523 (kp-8 . hydra--digit-argument)
524 (kp-7 . hydra--digit-argument)
525 (kp-6 . hydra--digit-argument)
526 (kp-5 . hydra--digit-argument)
527 (kp-4 . hydra--digit-argument)
528 (kp-3 . hydra--digit-argument)
529 (kp-2 . hydra--digit-argument)
530 (kp-1 . hydra--digit-argument)
531 (kp-0 . hydra--digit-argument)
532 (57 . hydra--digit-argument)
533 (56 . hydra--digit-argument)
534 (55 . hydra--digit-argument)
535 (54 . hydra--digit-argument)
536 (53 . hydra--digit-argument)
537 (52 . hydra--digit-argument)
538 (51 . hydra--digit-argument)
539 (50 . hydra--digit-argument)
540 (49 . hydra--digit-argument)
541 (48 . hydra--digit-argument)
542 (45 . hydra--negative-argument)
543 (21 . hydra--universal-argument))))
544 t (lambda nil (hydra-cleanup))))))
545 (defun hydra-vi/nil nil "Create a hydra with no body and the heads:
547 \"
\a\": `hydra-keyboard-quit',
549 \"k\": `previous-line',
552 The body can be accessed via `hydra-vi/body'.
554 Call the head: `nil'."
557 (set-cursor-color "#e52b50")
560 (catch (quote hydra-disable)
561 (set-cursor-color "#ffffff")))
562 (defun hydra-vi/hint nil
563 (if hydra-lv (lv-message (format #("vi: j, k, [q]: quit." 4 5 (face hydra-face-amaranth)
564 7 8 (face hydra-face-amaranth)
565 11 12 (face hydra-face-blue))))
566 (message (format #("vi: j, k, [q]: quit." 4 5 (face hydra-face-amaranth)
567 7 8 (face hydra-face-amaranth)
568 11 12 (face hydra-face-blue))))))
569 (defun hydra-vi/body nil "Create a hydra with no body and the heads:
571 \"
\a\": `hydra-keyboard-quit',
573 \"k\": `previous-line',
576 The body can be accessed via `hydra-vi/body'."
579 (set-cursor-color "#e52b50")
581 (catch (quote hydra-disable)
582 (when hydra-is-helpful (hydra-vi/hint))
584 (hydra-set-transient-map
586 (quote (keymap (t lambda nil (interactive)
587 (message "An amaranth Hydra can only exit through a blue head")
588 (hydra-set-transient-map hydra-curr-map t)
589 (when hydra-is-helpful (unless hydra-lv (sit-for 0.8))
592 (107 . hydra-vi/previous-line)
593 (106 . hydra-vi/next-line)
594 (7 . hydra-vi/hydra-keyboard-quit-and-exit)
595 (switch-frame . hydra--handle-switch-frame)
596 (kp-subtract . hydra--negative-argument)
597 (kp-9 . hydra--digit-argument)
598 (kp-8 . hydra--digit-argument)
599 (kp-7 . hydra--digit-argument)
600 (kp-6 . hydra--digit-argument)
601 (kp-5 . hydra--digit-argument)
602 (kp-4 . hydra--digit-argument)
603 (kp-3 . hydra--digit-argument)
604 (kp-2 . hydra--digit-argument)
605 (kp-1 . hydra--digit-argument)
606 (kp-0 . hydra--digit-argument)
607 (57 . hydra--digit-argument)
608 (56 . hydra--digit-argument)
609 (55 . hydra--digit-argument)
610 (54 . hydra--digit-argument)
611 (53 . hydra--digit-argument)
612 (52 . hydra--digit-argument)
613 (51 . hydra--digit-argument)
614 (50 . hydra--digit-argument)
615 (49 . hydra--digit-argument)
616 (48 . hydra--digit-argument)
617 (45 . hydra--negative-argument)
618 (21 . hydra--universal-argument))))
619 t (lambda nil (hydra-cleanup))))
620 (setq prefix-arg current-prefix-arg)))))))
622 (ert-deftest defhydradio ()
625 '(defhydradio hydra-test ()
626 (num "Num" [0 1 2 3 4 5 6 7 8 9 10])
627 (str "Str" ["foo" "bar" "baz"])))
629 (defvar hydra-test/num 0
631 (put 'hydra-test/num 'range [0 1 2 3 4 5 6 7 8 9 10])
632 (defun hydra-test/num ()
633 (hydra--cycle-radio 'hydra-test/num))
634 (defvar hydra-test/str "foo"
636 (put 'hydra-test/str 'range ["foo" "bar" "baz"])
637 (defun hydra-test/str ()
638 (hydra--cycle-radio 'hydra-test/str))
639 (defvar hydra-test/names '(hydra-test/num hydra-test/str))))))
641 (ert-deftest hydra-blue-compat ()
645 '(defhydra hydra-toggle (:color blue)
647 ("t" toggle-truncate-lines "truncate")
648 ("f" auto-fill-mode "fill")
649 ("a" abbrev-mode "abbrev")
652 '(defhydra hydra-toggle (:exit t)
654 ("t" toggle-truncate-lines "truncate")
655 ("f" auto-fill-mode "fill")
656 ("a" abbrev-mode "abbrev")
657 ("q" nil "cancel"))))))
659 (ert-deftest hydra-amaranth-compat ()
665 (set-cursor-color "#e52b50")
667 (set-cursor-color "#ffffff")
676 (set-cursor-color "#e52b50")
678 (set-cursor-color "#ffffff")
683 ("q" nil "quit"))))))
685 (ert-deftest hydra-pink-compat ()
689 '(defhydra hydra-zoom (global-map "<f2>"
692 ("g" text-scale-increase "in")
693 ("l" text-scale-decrease "out")
696 '(defhydra hydra-zoom (global-map "<f2>"
699 ("g" text-scale-increase "in")
700 ("l" text-scale-decrease "out")
701 ("q" nil "quit"))))))
703 (ert-deftest hydra-teal-compat ()
707 '(defhydra hydra-zoom (global-map "<f2>"
710 ("g" text-scale-increase "in")
711 ("l" text-scale-decrease "out")
714 '(defhydra hydra-zoom (global-map "<f2>"
718 ("g" text-scale-increase "in")
719 ("l" text-scale-decrease "out")
720 ("q" nil "quit"))))))
722 (ert-deftest hydra-format-1 ()
724 (let ((hydra-fontify-head-function
725 'hydra-fontify-head-greyscale))
730 _a_ abbrev-mode: %`abbrev-mode
731 _d_ debug-on-error: %`debug-on-error
732 _f_ auto-fill-mode: %`auto-fill-function
733 " '(("a" abbrev-mode nil)
734 ("d" toggle-debug-on-error nil)
735 ("f" auto-fill-mode nil)
736 ("g" golden-ratio-mode nil)
737 ("t" toggle-truncate-lines nil)
738 ("w" whitespace-mode nil)
740 '(concat (format "%s abbrev-mode: %S
741 %s debug-on-error: %S
742 %s auto-fill-mode: %S
743 " "{a}" abbrev-mode "{d}" debug-on-error "{f}" auto-fill-function) "[[q]]: quit"))))
745 (ert-deftest hydra-format-2 ()
747 (let ((hydra-fontify-head-function
748 'hydra-fontify-head-greyscale))
753 '(("a" (quote t) "" :cmd-name bar/lambda-a)
754 ("q" nil "" :cmd-name bar/nil))))
755 '(concat (format " bar %s\n" foo) "{a}, [q]"))))
757 (ert-deftest hydra-format-3 ()
759 (let ((hydra-fontify-head-function
760 'hydra-fontify-head-greyscale))
764 "\n_<SPC>_ ^^ace jump\n"
765 '(("<SPC>" ace-jump-char-mode nil :cmd-name bar/ace-jump-char-mode))))
766 '(concat (format "%s ace jump\n" "{<SPC>}") ""))))
768 (ert-deftest hydra-format-4 ()
770 (equal (hydra--format
774 '(("j" nil) ("k" nil)))
775 '(concat (format "%s,%s"
776 #("j" 0 1 (face hydra-face-blue))
777 #("k" 0 1 (face hydra-face-blue))) ""))))
779 (ert-deftest hydra-format-with-sexp-1 ()
781 (let ((hydra-fontify-head-function
782 'hydra-fontify-head-greyscale))
785 "\n_n_ narrow-or-widen-dwim %(progn (message \"checking\")(buffer-narrowed-p))asdf\n"
786 '(("n" narrow-to-region nil) ("q" nil "cancel"))))
787 '(concat (format "%s narrow-or-widen-dwim %Sasdf\n"
791 (buffer-narrowed-p)))
794 (ert-deftest hydra-format-with-sexp-2 ()
796 (let ((hydra-fontify-head-function
797 'hydra-fontify-head-greyscale))
800 "\n_n_ narrow-or-widen-dwim %s(progn (message \"checking\")(buffer-narrowed-p))asdf\n"
801 '(("n" narrow-to-region nil) ("q" nil "cancel"))))
802 '(concat (format "%s narrow-or-widen-dwim %sasdf\n"
806 (buffer-narrowed-p)))
809 (ert-deftest hydra-compat-colors-1 ()
810 (should (equal (hydra--head-color
811 '("e" (message "Exiting now") "blue")
812 '(nil nil :color blue))
814 (should (equal (hydra--head-color
815 '("c" (message "Continuing") "red" :color red)
816 '(nil nil :color blue))
818 (should (equal (hydra--head-color
819 '("e" (message "Exiting now") "blue")
822 (should (equal (hydra--head-color
823 '("j" next-line "" :exit t)
826 (should (equal (hydra--head-color
827 '("c" (message "Continuing") "red" :exit nil)
830 (equal (hydra--head-color
831 '("a" abbrev-mode nil)
832 '(nil nil :color teal))
834 (equal (hydra--head-color
835 '("a" abbrev-mode :exit nil)
836 '(nil nil :color teal))
839 (ert-deftest hydra-compat-colors-2 ()
843 '(defhydra hydra-test (:color amaranth)
845 ("b" fun-b :color blue)
846 ("c" fun-c :color blue)
847 ("d" fun-d :color blue)
848 ("e" fun-e :color blue)
849 ("f" fun-f :color blue)))
851 '(defhydra hydra-test (:color teal)
852 ("a" fun-a :color red)
859 (ert-deftest hydra-compat-colors-3 ()
863 '(defhydra hydra-test ()
865 ("b" fun-b :color blue)
866 ("c" fun-c :color blue)
867 ("d" fun-d :color blue)
868 ("e" fun-e :color blue)
869 ("f" fun-f :color blue)))
871 '(defhydra hydra-test (:color blue)
872 ("a" fun-a :color red)
879 (ert-deftest hydra-compat-colors-4 ()
883 '(defhydra hydra-test ()
889 ("f" fun-f :exit t)))
891 '(defhydra hydra-test (:exit t)
892 ("a" fun-a :exit nil)
899 (ert-deftest hydra-zoom-duplicate-1 ()
903 '(defhydra hydra-zoom ()
905 ("r" (text-scale-set 0) "reset")
906 ("0" (text-scale-set 0) :bind nil :exit t)
907 ("1" (text-scale-set 0) nil :bind nil :exit t)))
909 (defun hydra-zoom/lambda-r nil "Create a hydra with no body and the heads:
911 \"r\": `(text-scale-set 0)',
912 \"0\": `(text-scale-set 0)',
913 \"1\": `(text-scale-set 0)'
915 The body can be accessed via `hydra-zoom/body'.
917 Call the head: `(text-scale-set 0)'."
921 (catch (quote hydra-disable)
922 (condition-case err (prog1 t (call-interactively (function (lambda nil (interactive)
923 (text-scale-set 0)))))
926 (unless hydra-lv (sit-for 0.8))
928 (when hydra-is-helpful (hydra-zoom/hint))
930 (hydra-set-transient-map
932 (quote (keymap (7 . hydra-keyboard-quit)
933 (114 . hydra-zoom/lambda-r)
934 (switch-frame . hydra--handle-switch-frame)
935 (kp-subtract . hydra--negative-argument)
936 (kp-9 . hydra--digit-argument)
937 (kp-8 . hydra--digit-argument)
938 (kp-7 . hydra--digit-argument)
939 (kp-6 . hydra--digit-argument)
940 (kp-5 . hydra--digit-argument)
941 (kp-4 . hydra--digit-argument)
942 (kp-3 . hydra--digit-argument)
943 (kp-2 . hydra--digit-argument)
944 (kp-1 . hydra--digit-argument)
945 (kp-0 . hydra--digit-argument)
946 (57 . hydra--digit-argument)
947 (56 . hydra--digit-argument)
948 (55 . hydra--digit-argument)
949 (54 . hydra--digit-argument)
950 (53 . hydra--digit-argument)
951 (52 . hydra--digit-argument)
952 (51 . hydra--digit-argument)
953 (50 . hydra--digit-argument)
954 (49 . hydra-zoom/lambda-0-and-exit)
955 (48 . hydra-zoom/lambda-0-and-exit)
956 (45 . hydra--negative-argument)
957 (21 . hydra--universal-argument))))
958 t (lambda nil (hydra-cleanup))))))
959 (defun hydra-zoom/lambda-0-and-exit nil "Create a hydra with no body and the heads:
961 \"r\": `(text-scale-set 0)',
962 \"0\": `(text-scale-set 0)',
963 \"1\": `(text-scale-set 0)'
965 The body can be accessed via `hydra-zoom/body'.
967 Call the head: `(text-scale-set 0)'."
972 (catch (quote hydra-disable)
973 (call-interactively (function (lambda nil (interactive)
974 (text-scale-set 0))))))
975 (defun hydra-zoom/hint nil
976 (if hydra-lv (lv-message (format #("zoom: [r 0]: reset." 7 8 (face hydra-face-red)
977 9 10 (face hydra-face-blue))))
978 (message (format #("zoom: [r 0]: reset." 7 8 (face hydra-face-red)
979 9 10 (face hydra-face-blue))))))
980 (defun hydra-zoom/body nil "Create a hydra with no body and the heads:
982 \"r\": `(text-scale-set 0)',
983 \"0\": `(text-scale-set 0)',
984 \"1\": `(text-scale-set 0)'
986 The body can be accessed via `hydra-zoom/body'."
990 (catch (quote hydra-disable)
991 (when hydra-is-helpful (hydra-zoom/hint))
993 (hydra-set-transient-map
995 (quote (keymap (7 . hydra-keyboard-quit)
996 (114 . hydra-zoom/lambda-r)
997 (switch-frame . hydra--handle-switch-frame)
998 (kp-subtract . hydra--negative-argument)
999 (kp-9 . hydra--digit-argument)
1000 (kp-8 . hydra--digit-argument)
1001 (kp-7 . hydra--digit-argument)
1002 (kp-6 . hydra--digit-argument)
1003 (kp-5 . hydra--digit-argument)
1004 (kp-4 . hydra--digit-argument)
1005 (kp-3 . hydra--digit-argument)
1006 (kp-2 . hydra--digit-argument)
1007 (kp-1 . hydra--digit-argument)
1008 (kp-0 . hydra--digit-argument)
1009 (57 . hydra--digit-argument)
1010 (56 . hydra--digit-argument)
1011 (55 . hydra--digit-argument)
1012 (54 . hydra--digit-argument)
1013 (53 . hydra--digit-argument)
1014 (52 . hydra--digit-argument)
1015 (51 . hydra--digit-argument)
1016 (50 . hydra--digit-argument)
1017 (49 . hydra-zoom/lambda-0-and-exit)
1018 (48 . hydra-zoom/lambda-0-and-exit)
1019 (45 . hydra--negative-argument)
1020 (21 . hydra--universal-argument))))
1021 t (lambda nil (hydra-cleanup))))
1022 (setq prefix-arg current-prefix-arg)))))))
1024 (ert-deftest hydra-zoom-duplicate-2 ()
1028 '(defhydra hydra-zoom ()
1030 ("r" (text-scale-set 0) "reset")
1031 ("0" (text-scale-set 0) :bind nil :exit t)
1032 ("1" (text-scale-set 0) nil :bind nil)))
1034 (defun hydra-zoom/lambda-r nil "Create a hydra with no body and the heads:
1036 \"r\": `(text-scale-set 0)',
1037 \"0\": `(text-scale-set 0)',
1038 \"1\": `(text-scale-set 0)'
1040 The body can be accessed via `hydra-zoom/body'.
1042 Call the head: `(text-scale-set 0)'."
1046 (catch (quote hydra-disable)
1047 (condition-case err (prog1 t (call-interactively (function (lambda nil (interactive)
1048 (text-scale-set 0)))))
1051 (unless hydra-lv (sit-for 0.8))
1053 (when hydra-is-helpful (hydra-zoom/hint))
1055 (hydra-set-transient-map
1056 (setq hydra-curr-map
1057 (quote (keymap (7 . hydra-keyboard-quit)
1058 (114 . hydra-zoom/lambda-r)
1059 (switch-frame . hydra--handle-switch-frame)
1060 (kp-subtract . hydra--negative-argument)
1061 (kp-9 . hydra--digit-argument)
1062 (kp-8 . hydra--digit-argument)
1063 (kp-7 . hydra--digit-argument)
1064 (kp-6 . hydra--digit-argument)
1065 (kp-5 . hydra--digit-argument)
1066 (kp-4 . hydra--digit-argument)
1067 (kp-3 . hydra--digit-argument)
1068 (kp-2 . hydra--digit-argument)
1069 (kp-1 . hydra--digit-argument)
1070 (kp-0 . hydra--digit-argument)
1071 (57 . hydra--digit-argument)
1072 (56 . hydra--digit-argument)
1073 (55 . hydra--digit-argument)
1074 (54 . hydra--digit-argument)
1075 (53 . hydra--digit-argument)
1076 (52 . hydra--digit-argument)
1077 (51 . hydra--digit-argument)
1078 (50 . hydra--digit-argument)
1079 (49 . hydra-zoom/lambda-r)
1080 (48 . hydra-zoom/lambda-0-and-exit)
1081 (45 . hydra--negative-argument)
1082 (21 . hydra--universal-argument))))
1083 t (lambda nil (hydra-cleanup))))))
1084 (defun hydra-zoom/lambda-0-and-exit nil "Create a hydra with no body and the heads:
1086 \"r\": `(text-scale-set 0)',
1087 \"0\": `(text-scale-set 0)',
1088 \"1\": `(text-scale-set 0)'
1090 The body can be accessed via `hydra-zoom/body'.
1092 Call the head: `(text-scale-set 0)'."
1097 (catch (quote hydra-disable)
1098 (call-interactively (function (lambda nil (interactive)
1099 (text-scale-set 0))))))
1100 (defun hydra-zoom/hint nil
1101 (if hydra-lv (lv-message (format #("zoom: [r 0]: reset." 7 8 (face hydra-face-red)
1102 9 10 (face hydra-face-blue))))
1103 (message (format #("zoom: [r 0]: reset." 7 8 (face hydra-face-red)
1104 9 10 (face hydra-face-blue))))))
1105 (defun hydra-zoom/body nil "Create a hydra with no body and the heads:
1107 \"r\": `(text-scale-set 0)',
1108 \"0\": `(text-scale-set 0)',
1109 \"1\": `(text-scale-set 0)'
1111 The body can be accessed via `hydra-zoom/body'."
1115 (catch (quote hydra-disable)
1116 (when hydra-is-helpful (hydra-zoom/hint))
1118 (hydra-set-transient-map
1119 (setq hydra-curr-map
1120 (quote (keymap (7 . hydra-keyboard-quit)
1121 (114 . hydra-zoom/lambda-r)
1122 (switch-frame . hydra--handle-switch-frame)
1123 (kp-subtract . hydra--negative-argument)
1124 (kp-9 . hydra--digit-argument)
1125 (kp-8 . hydra--digit-argument)
1126 (kp-7 . hydra--digit-argument)
1127 (kp-6 . hydra--digit-argument)
1128 (kp-5 . hydra--digit-argument)
1129 (kp-4 . hydra--digit-argument)
1130 (kp-3 . hydra--digit-argument)
1131 (kp-2 . hydra--digit-argument)
1132 (kp-1 . hydra--digit-argument)
1133 (kp-0 . hydra--digit-argument)
1134 (57 . hydra--digit-argument)
1135 (56 . hydra--digit-argument)
1136 (55 . hydra--digit-argument)
1137 (54 . hydra--digit-argument)
1138 (53 . hydra--digit-argument)
1139 (52 . hydra--digit-argument)
1140 (51 . hydra--digit-argument)
1141 (50 . hydra--digit-argument)
1142 (49 . hydra-zoom/lambda-r)
1143 (48 . hydra-zoom/lambda-0-and-exit)
1144 (45 . hydra--negative-argument)
1145 (21 . hydra--universal-argument))))
1146 t (lambda nil (hydra-cleanup))))
1147 (setq prefix-arg current-prefix-arg)))))))
1149 (ert-deftest hydra--pad ()
1150 (should (equal (hydra--pad '(a b c) 3)
1152 (should (equal (hydra--pad '(a) 3)
1155 (ert-deftest hydra--matrix ()
1156 (should (equal (hydra--matrix '(a b c) 2 2)
1158 (should (equal (hydra--matrix '(a b c d e f g h i) 4 3)
1159 '((a b c d) (e f g h) (i nil nil nil)))))
1161 (ert-deftest hydra--cell ()
1162 (should (equal (hydra--cell "% -75s %%`%s" '(hydra-lv hydra-verbose))
1163 "When non-nil, `lv-message' (not `message') will be used to display hints. %`hydra-lv^^^^^
1164 When non-nil, hydra will issue some non essential style warnings. %`hydra-verbose")))
1166 (ert-deftest hydra--vconcat ()
1167 (should (equal (hydra--vconcat '("abc\ndef" "012\n34" "def\nabc"))
1168 "abc012def\ndef34abc")))
1170 (defhydradio hydra-tng ()
1171 (picard "_p_ Captain Jean Luc Picard:")
1172 (riker "_r_ Commander William Riker:")
1173 (data "_d_ Lieutenant Commander Data:")
1175 (la-forge "_f_ Geordi La Forge:")
1176 (troi "_t_ Deanna Troi:")
1177 (dr-crusher "_c_ Doctor Beverly Crusher:")
1178 (phaser "_h_ Set phasers to " [stun kill]))
1180 (ert-deftest hydra--table ()
1181 (let ((hydra-cell-format "% -30s %% -8`%s"))
1182 (should (equal (hydra--table hydra-tng/names 5 2)
1184 _p_ Captain Jean Luc Picard: % -8`hydra-tng/picard^^ _t_ Deanna Troi: % -8`hydra-tng/troi^^^^^^
1185 _r_ Commander William Riker: % -8`hydra-tng/riker^^^ _c_ Doctor Beverly Crusher: % -8`hydra-tng/dr-crusher
1186 _d_ Lieutenant Commander Data: % -8`hydra-tng/data^^^^ _h_ Set phasers to % -8`hydra-tng/phaser^^^^
1187 _w_ Worf: % -8`hydra-tng/worf^^^^
1188 _f_ Geordi La Forge: % -8`hydra-tng/la-forge" 1)))
1189 (should (equal (hydra--table hydra-tng/names 4 3)
1191 _p_ Captain Jean Luc Picard: % -8`hydra-tng/picard _f_ Geordi La Forge: % -8`hydra-tng/la-forge^^
1192 _r_ Commander William Riker: % -8`hydra-tng/riker^ _t_ Deanna Troi: % -8`hydra-tng/troi^^^^^^
1193 _d_ Lieutenant Commander Data: % -8`hydra-tng/data^^ _c_ Doctor Beverly Crusher: % -8`hydra-tng/dr-crusher
1194 _w_ Worf: % -8`hydra-tng/worf^^ _h_ Set phasers to % -8`hydra-tng/phaser^^^^" 1)))))
1196 (ert-deftest hydra--make-funcall ()
1197 (should (equal (let ((body-pre 'foo))
1198 (hydra--make-funcall body-pre)
1200 '(funcall (function foo)))))
1202 (provide 'hydra-test)
1204 ;;; hydra-test.el ends here