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'."
52 (catch (quote hydra-disable)
53 (condition-case err (prog1 t (call-interactively (function first-error)))
56 (unless hydra-lv (sit-for 0.8))
58 (when hydra-is-helpful (hydra-error/hint))
60 (hydra-set-transient-map
62 (quote (keymap (7 . hydra-keyboard-quit)
64 (107 . hydra-error/previous-error)
65 (106 . hydra-error/next-error)
66 (104 . hydra-error/first-error)
67 (switch-frame . hydra--handle-switch-frame)
68 (kp-subtract . hydra--negative-argument)
69 (kp-9 . hydra--digit-argument)
70 (kp-8 . hydra--digit-argument)
71 (kp-7 . hydra--digit-argument)
72 (kp-6 . hydra--digit-argument)
73 (kp-5 . hydra--digit-argument)
74 (kp-4 . hydra--digit-argument)
75 (kp-3 . hydra--digit-argument)
76 (kp-2 . hydra--digit-argument)
77 (kp-1 . hydra--digit-argument)
78 (kp-0 . hydra--digit-argument)
79 (57 . hydra--digit-argument)
80 (56 . hydra--digit-argument)
81 (55 . hydra--digit-argument)
82 (54 . hydra--digit-argument)
83 (53 . hydra--digit-argument)
84 (52 . hydra--digit-argument)
85 (51 . hydra--digit-argument)
86 (50 . hydra--digit-argument)
87 (49 . hydra--digit-argument)
88 (48 . hydra--digit-argument)
89 (45 . hydra--negative-argument)
90 (21 . hydra--universal-argument))))
91 t (lambda nil (hydra-cleanup))))))
92 (defun hydra-error/next-error nil "Create a hydra with a \"M-g\" body and the heads:
96 \"k\": `previous-error',
97 \"SPC\": `hydra-repeat'
99 The body can be accessed via `hydra-error/body'.
101 Call the head: `next-error'."
104 (catch (quote hydra-disable)
105 (condition-case err (prog1 t (call-interactively (function next-error)))
108 (unless hydra-lv (sit-for 0.8))
110 (when hydra-is-helpful (hydra-error/hint))
112 (hydra-set-transient-map
114 (quote (keymap (7 . hydra-keyboard-quit)
116 (107 . hydra-error/previous-error)
117 (106 . hydra-error/next-error)
118 (104 . hydra-error/first-error)
119 (switch-frame . hydra--handle-switch-frame)
120 (kp-subtract . hydra--negative-argument)
121 (kp-9 . hydra--digit-argument)
122 (kp-8 . hydra--digit-argument)
123 (kp-7 . hydra--digit-argument)
124 (kp-6 . hydra--digit-argument)
125 (kp-5 . hydra--digit-argument)
126 (kp-4 . hydra--digit-argument)
127 (kp-3 . hydra--digit-argument)
128 (kp-2 . hydra--digit-argument)
129 (kp-1 . hydra--digit-argument)
130 (kp-0 . hydra--digit-argument)
131 (57 . hydra--digit-argument)
132 (56 . hydra--digit-argument)
133 (55 . hydra--digit-argument)
134 (54 . hydra--digit-argument)
135 (53 . hydra--digit-argument)
136 (52 . hydra--digit-argument)
137 (51 . hydra--digit-argument)
138 (50 . hydra--digit-argument)
139 (49 . hydra--digit-argument)
140 (48 . hydra--digit-argument)
141 (45 . hydra--negative-argument)
142 (21 . hydra--universal-argument))))
143 t (lambda nil (hydra-cleanup))))))
144 (defun hydra-error/previous-error nil "Create a hydra with a \"M-g\" body and the heads:
146 \"h\": `first-error',
148 \"k\": `previous-error',
149 \"SPC\": `hydra-repeat'
151 The body can be accessed via `hydra-error/body'.
153 Call the head: `previous-error'."
156 (catch (quote hydra-disable)
157 (condition-case err (prog1 t (call-interactively (function previous-error)))
160 (unless hydra-lv (sit-for 0.8))
162 (when hydra-is-helpful (hydra-error/hint))
164 (hydra-set-transient-map
166 (quote (keymap (7 . hydra-keyboard-quit)
168 (107 . hydra-error/previous-error)
169 (106 . hydra-error/next-error)
170 (104 . hydra-error/first-error)
171 (switch-frame . hydra--handle-switch-frame)
172 (kp-subtract . hydra--negative-argument)
173 (kp-9 . hydra--digit-argument)
174 (kp-8 . hydra--digit-argument)
175 (kp-7 . hydra--digit-argument)
176 (kp-6 . hydra--digit-argument)
177 (kp-5 . hydra--digit-argument)
178 (kp-4 . hydra--digit-argument)
179 (kp-3 . hydra--digit-argument)
180 (kp-2 . hydra--digit-argument)
181 (kp-1 . hydra--digit-argument)
182 (kp-0 . hydra--digit-argument)
183 (57 . hydra--digit-argument)
184 (56 . hydra--digit-argument)
185 (55 . hydra--digit-argument)
186 (54 . hydra--digit-argument)
187 (53 . hydra--digit-argument)
188 (52 . hydra--digit-argument)
189 (51 . hydra--digit-argument)
190 (50 . hydra--digit-argument)
191 (49 . hydra--digit-argument)
192 (48 . hydra--digit-argument)
193 (45 . hydra--negative-argument)
194 (21 . hydra--universal-argument))))
195 t (lambda nil (hydra-cleanup))))))
196 (unless (keymapp (lookup-key global-map (kbd "M-g")))
197 (define-key global-map (kbd "M-g")
199 (define-key global-map [134217831 104]
200 (function hydra-error/first-error))
201 (define-key global-map [134217831 106]
202 (function hydra-error/next-error))
203 (define-key global-map [134217831 107]
204 (function hydra-error/previous-error))
205 (defun hydra-error/hint nil
206 (if hydra-lv (lv-message (format #("error: [h]: first, [j]: next, [k]: prev, [SPC]: rep." 8 9 (face hydra-face-red)
207 20 21 (face hydra-face-red)
208 31 32 (face hydra-face-red)
209 42 45 (face hydra-face-red))))
210 (message (format #("error: [h]: first, [j]: next, [k]: prev, [SPC]: rep." 8 9 (face hydra-face-red)
211 20 21 (face hydra-face-red)
212 31 32 (face hydra-face-red)
213 42 45 (face hydra-face-red))))))
214 (defun hydra-error/body nil "Create a hydra with a \"M-g\" body and the heads:
216 \"h\": `first-error',
218 \"k\": `previous-error',
219 \"SPC\": `hydra-repeat'
221 The body can be accessed via `hydra-error/body'."
224 (catch (quote hydra-disable)
225 (when hydra-is-helpful (hydra-error/hint))
227 (hydra-set-transient-map
229 (quote (keymap (7 . hydra-keyboard-quit)
231 (107 . hydra-error/previous-error)
232 (106 . hydra-error/next-error)
233 (104 . hydra-error/first-error)
234 (switch-frame . hydra--handle-switch-frame)
235 (kp-subtract . hydra--negative-argument)
236 (kp-9 . hydra--digit-argument)
237 (kp-8 . hydra--digit-argument)
238 (kp-7 . hydra--digit-argument)
239 (kp-6 . hydra--digit-argument)
240 (kp-5 . hydra--digit-argument)
241 (kp-4 . hydra--digit-argument)
242 (kp-3 . hydra--digit-argument)
243 (kp-2 . hydra--digit-argument)
244 (kp-1 . hydra--digit-argument)
245 (kp-0 . hydra--digit-argument)
246 (57 . hydra--digit-argument)
247 (56 . hydra--digit-argument)
248 (55 . hydra--digit-argument)
249 (54 . hydra--digit-argument)
250 (53 . hydra--digit-argument)
251 (52 . hydra--digit-argument)
252 (51 . hydra--digit-argument)
253 (50 . hydra--digit-argument)
254 (49 . hydra--digit-argument)
255 (48 . hydra--digit-argument)
256 (45 . hydra--negative-argument)
257 (21 . hydra--universal-argument))))
258 t (lambda nil (hydra-cleanup))))
259 (setq prefix-arg current-prefix-arg)))))))
261 (ert-deftest hydra-blue-toggle ()
265 '(defhydra hydra-toggle (:color blue)
267 ("t" toggle-truncate-lines "truncate")
268 ("f" auto-fill-mode "fill")
269 ("a" abbrev-mode "abbrev")
272 (defun hydra-toggle/toggle-truncate-lines-and-exit nil "Create a hydra with no body and the heads:
274 \"t\": `toggle-truncate-lines',
275 \"f\": `auto-fill-mode',
276 \"a\": `abbrev-mode',
279 The body can be accessed via `hydra-toggle/body'.
281 Call the head: `toggle-truncate-lines'."
285 (catch (quote hydra-disable)
286 (call-interactively (function toggle-truncate-lines))))
287 (defun hydra-toggle/auto-fill-mode-and-exit nil "Create a hydra with no body and the heads:
289 \"t\": `toggle-truncate-lines',
290 \"f\": `auto-fill-mode',
291 \"a\": `abbrev-mode',
294 The body can be accessed via `hydra-toggle/body'.
296 Call the head: `auto-fill-mode'."
300 (catch (quote hydra-disable)
301 (call-interactively (function auto-fill-mode))))
302 (defun hydra-toggle/abbrev-mode-and-exit nil "Create a hydra with no body and the heads:
304 \"t\": `toggle-truncate-lines',
305 \"f\": `auto-fill-mode',
306 \"a\": `abbrev-mode',
309 The body can be accessed via `hydra-toggle/body'.
311 Call the head: `abbrev-mode'."
315 (catch (quote hydra-disable)
316 (call-interactively (function abbrev-mode))))
317 (defun hydra-toggle/nil nil "Create a hydra with no body and the heads:
319 \"t\": `toggle-truncate-lines',
320 \"f\": `auto-fill-mode',
321 \"a\": `abbrev-mode',
324 The body can be accessed via `hydra-toggle/body'.
326 Call the head: `nil'."
330 (catch (quote hydra-disable)))
331 (defun hydra-toggle/hint nil
332 (if hydra-lv (lv-message (format #("toggle: [t]: truncate, [f]: fill, [a]: abbrev, [q]: cancel." 9 10 (face hydra-face-blue)
333 24 25 (face hydra-face-blue)
334 35 36 (face hydra-face-blue)
335 48 49 (face hydra-face-blue))))
336 (message (format #("toggle: [t]: truncate, [f]: fill, [a]: abbrev, [q]: cancel." 9 10 (face hydra-face-blue)
337 24 25 (face hydra-face-blue)
338 35 36 (face hydra-face-blue)
339 48 49 (face hydra-face-blue))))))
340 (defun hydra-toggle/body nil "Create a hydra with no body and the heads:
342 \"t\": `toggle-truncate-lines',
343 \"f\": `auto-fill-mode',
344 \"a\": `abbrev-mode',
347 The body can be accessed via `hydra-toggle/body'."
350 (catch (quote hydra-disable)
351 (when hydra-is-helpful (hydra-toggle/hint))
353 (hydra-set-transient-map
355 (quote (keymap (7 . hydra-keyboard-quit)
356 (113 . hydra-toggle/nil)
357 (97 . hydra-toggle/abbrev-mode-and-exit)
358 (102 . hydra-toggle/auto-fill-mode-and-exit)
359 (116 . hydra-toggle/toggle-truncate-lines-and-exit)
360 (switch-frame . hydra--handle-switch-frame)
361 (kp-subtract . hydra--negative-argument)
362 (kp-9 . hydra--digit-argument)
363 (kp-8 . hydra--digit-argument)
364 (kp-7 . hydra--digit-argument)
365 (kp-6 . hydra--digit-argument)
366 (kp-5 . hydra--digit-argument)
367 (kp-4 . hydra--digit-argument)
368 (kp-3 . hydra--digit-argument)
369 (kp-2 . hydra--digit-argument)
370 (kp-1 . hydra--digit-argument)
371 (kp-0 . hydra--digit-argument)
372 (57 . hydra--digit-argument)
373 (56 . hydra--digit-argument)
374 (55 . hydra--digit-argument)
375 (54 . hydra--digit-argument)
376 (53 . hydra--digit-argument)
377 (52 . hydra--digit-argument)
378 (51 . hydra--digit-argument)
379 (50 . hydra--digit-argument)
380 (49 . hydra--digit-argument)
381 (48 . hydra--digit-argument)
382 (45 . hydra--negative-argument)
383 (21 . hydra--universal-argument))))
384 t (lambda nil (hydra-cleanup))))
385 (setq prefix-arg current-prefix-arg)))))))
387 (ert-deftest hydra-amaranth-vi ()
393 (set-cursor-color "#e52b50")
395 (set-cursor-color "#ffffff")
402 (defun hydra-vi/hydra-keyboard-quit-and-exit nil "Create a hydra with no body and the heads:
404 \"
\a\": `hydra-keyboard-quit',
406 \"k\": `previous-line',
409 The body can be accessed via `hydra-vi/body'.
411 Call the head: `hydra-keyboard-quit'."
413 (set-cursor-color "#e52b50")
416 (catch (quote hydra-disable)
417 (call-interactively (function hydra-keyboard-quit))
418 (set-cursor-color "#ffffff")))
419 (defun hydra-vi/next-line nil "Create a hydra with no body and the heads:
421 \"
\a\": `hydra-keyboard-quit',
423 \"k\": `previous-line',
426 The body can be accessed via `hydra-vi/body'.
428 Call the head: `next-line'."
430 (set-cursor-color "#e52b50")
432 (catch (quote hydra-disable)
433 (condition-case err (prog1 t (call-interactively (function next-line)))
436 (unless hydra-lv (sit-for 0.8))
438 (when hydra-is-helpful (hydra-vi/hint))
440 (hydra-set-transient-map
442 (quote (keymap (t lambda nil (interactive)
443 (message "An amaranth Hydra can only exit through a blue head")
444 (hydra-set-transient-map hydra-curr-map t)
445 (when hydra-is-helpful (unless hydra-lv (sit-for 0.8))
448 (107 . hydra-vi/previous-line)
449 (106 . hydra-vi/next-line)
450 (7 . hydra-vi/hydra-keyboard-quit-and-exit)
451 (switch-frame . hydra--handle-switch-frame)
452 (kp-subtract . hydra--negative-argument)
453 (kp-9 . hydra--digit-argument)
454 (kp-8 . hydra--digit-argument)
455 (kp-7 . hydra--digit-argument)
456 (kp-6 . hydra--digit-argument)
457 (kp-5 . hydra--digit-argument)
458 (kp-4 . hydra--digit-argument)
459 (kp-3 . hydra--digit-argument)
460 (kp-2 . hydra--digit-argument)
461 (kp-1 . hydra--digit-argument)
462 (kp-0 . hydra--digit-argument)
463 (57 . hydra--digit-argument)
464 (56 . hydra--digit-argument)
465 (55 . hydra--digit-argument)
466 (54 . hydra--digit-argument)
467 (53 . hydra--digit-argument)
468 (52 . hydra--digit-argument)
469 (51 . hydra--digit-argument)
470 (50 . hydra--digit-argument)
471 (49 . hydra--digit-argument)
472 (48 . hydra--digit-argument)
473 (45 . hydra--negative-argument)
474 (21 . hydra--universal-argument))))
475 t (lambda nil (hydra-cleanup))))))
476 (defun hydra-vi/previous-line nil "Create a hydra with no body and the heads:
478 \"
\a\": `hydra-keyboard-quit',
480 \"k\": `previous-line',
483 The body can be accessed via `hydra-vi/body'.
485 Call the head: `previous-line'."
487 (set-cursor-color "#e52b50")
489 (catch (quote hydra-disable)
490 (condition-case err (prog1 t (call-interactively (function previous-line)))
493 (unless hydra-lv (sit-for 0.8))
495 (when hydra-is-helpful (hydra-vi/hint))
497 (hydra-set-transient-map
499 (quote (keymap (t lambda nil (interactive)
500 (message "An amaranth Hydra can only exit through a blue head")
501 (hydra-set-transient-map hydra-curr-map t)
502 (when hydra-is-helpful (unless hydra-lv (sit-for 0.8))
505 (107 . hydra-vi/previous-line)
506 (106 . hydra-vi/next-line)
507 (7 . hydra-vi/hydra-keyboard-quit-and-exit)
508 (switch-frame . hydra--handle-switch-frame)
509 (kp-subtract . hydra--negative-argument)
510 (kp-9 . hydra--digit-argument)
511 (kp-8 . hydra--digit-argument)
512 (kp-7 . hydra--digit-argument)
513 (kp-6 . hydra--digit-argument)
514 (kp-5 . hydra--digit-argument)
515 (kp-4 . hydra--digit-argument)
516 (kp-3 . hydra--digit-argument)
517 (kp-2 . hydra--digit-argument)
518 (kp-1 . hydra--digit-argument)
519 (kp-0 . hydra--digit-argument)
520 (57 . hydra--digit-argument)
521 (56 . hydra--digit-argument)
522 (55 . hydra--digit-argument)
523 (54 . hydra--digit-argument)
524 (53 . hydra--digit-argument)
525 (52 . hydra--digit-argument)
526 (51 . hydra--digit-argument)
527 (50 . hydra--digit-argument)
528 (49 . hydra--digit-argument)
529 (48 . hydra--digit-argument)
530 (45 . hydra--negative-argument)
531 (21 . hydra--universal-argument))))
532 t (lambda nil (hydra-cleanup))))))
533 (defun hydra-vi/nil nil "Create a hydra with no body and the heads:
535 \"
\a\": `hydra-keyboard-quit',
537 \"k\": `previous-line',
540 The body can be accessed via `hydra-vi/body'.
542 Call the head: `nil'."
544 (set-cursor-color "#e52b50")
547 (catch (quote hydra-disable)
548 (set-cursor-color "#ffffff")))
549 (defun hydra-vi/hint nil
550 (if hydra-lv (lv-message (format #("vi: j, k, [q]: quit." 4 5 (face hydra-face-amaranth)
551 7 8 (face hydra-face-amaranth)
552 11 12 (face hydra-face-blue))))
553 (message (format #("vi: j, k, [q]: quit." 4 5 (face hydra-face-amaranth)
554 7 8 (face hydra-face-amaranth)
555 11 12 (face hydra-face-blue))))))
556 (defun hydra-vi/body nil "Create a hydra with no body and the heads:
558 \"
\a\": `hydra-keyboard-quit',
560 \"k\": `previous-line',
563 The body can be accessed via `hydra-vi/body'."
565 (set-cursor-color "#e52b50")
567 (catch (quote hydra-disable)
568 (when hydra-is-helpful (hydra-vi/hint))
570 (hydra-set-transient-map
572 (quote (keymap (t lambda nil (interactive)
573 (message "An amaranth Hydra can only exit through a blue head")
574 (hydra-set-transient-map hydra-curr-map t)
575 (when hydra-is-helpful (unless hydra-lv (sit-for 0.8))
578 (107 . hydra-vi/previous-line)
579 (106 . hydra-vi/next-line)
580 (7 . hydra-vi/hydra-keyboard-quit-and-exit)
581 (switch-frame . hydra--handle-switch-frame)
582 (kp-subtract . hydra--negative-argument)
583 (kp-9 . hydra--digit-argument)
584 (kp-8 . hydra--digit-argument)
585 (kp-7 . hydra--digit-argument)
586 (kp-6 . hydra--digit-argument)
587 (kp-5 . hydra--digit-argument)
588 (kp-4 . hydra--digit-argument)
589 (kp-3 . hydra--digit-argument)
590 (kp-2 . hydra--digit-argument)
591 (kp-1 . hydra--digit-argument)
592 (kp-0 . hydra--digit-argument)
593 (57 . hydra--digit-argument)
594 (56 . hydra--digit-argument)
595 (55 . hydra--digit-argument)
596 (54 . hydra--digit-argument)
597 (53 . hydra--digit-argument)
598 (52 . hydra--digit-argument)
599 (51 . hydra--digit-argument)
600 (50 . hydra--digit-argument)
601 (49 . hydra--digit-argument)
602 (48 . hydra--digit-argument)
603 (45 . hydra--negative-argument)
604 (21 . hydra--universal-argument))))
605 t (lambda nil (hydra-cleanup))))
606 (setq prefix-arg current-prefix-arg)))))))
608 (ert-deftest defhydradio ()
611 '(defhydradio hydra-test ()
612 (num "Num" [0 1 2 3 4 5 6 7 8 9 10])
613 (str "Str" ["foo" "bar" "baz"])))
615 (defvar hydra-test/num 0
617 (put 'hydra-test/num 'range [0 1 2 3 4 5 6 7 8 9 10])
618 (defun hydra-test/num ()
619 (hydra--cycle-radio 'hydra-test/num))
620 (defvar hydra-test/str "foo"
622 (put 'hydra-test/str 'range ["foo" "bar" "baz"])
623 (defun hydra-test/str ()
624 (hydra--cycle-radio 'hydra-test/str))
625 (defvar hydra-test/names '(hydra-test/num hydra-test/str))))))
627 (ert-deftest hydra-blue-compat ()
631 '(defhydra hydra-toggle (:color blue)
633 ("t" toggle-truncate-lines "truncate")
634 ("f" auto-fill-mode "fill")
635 ("a" abbrev-mode "abbrev")
638 '(defhydra hydra-toggle (:exit t)
640 ("t" toggle-truncate-lines "truncate")
641 ("f" auto-fill-mode "fill")
642 ("a" abbrev-mode "abbrev")
643 ("q" nil "cancel"))))))
645 (ert-deftest hydra-amaranth-compat ()
651 (set-cursor-color "#e52b50")
653 (set-cursor-color "#ffffff")
662 (set-cursor-color "#e52b50")
664 (set-cursor-color "#ffffff")
669 ("q" nil "quit"))))))
671 (ert-deftest hydra-pink-compat ()
675 '(defhydra hydra-zoom (global-map "<f2>"
678 ("g" text-scale-increase "in")
679 ("l" text-scale-decrease "out")
682 '(defhydra hydra-zoom (global-map "<f2>"
685 ("g" text-scale-increase "in")
686 ("l" text-scale-decrease "out")
687 ("q" nil "quit"))))))
689 (ert-deftest hydra-teal-compat ()
693 '(defhydra hydra-zoom (global-map "<f2>"
696 ("g" text-scale-increase "in")
697 ("l" text-scale-decrease "out")
700 '(defhydra hydra-zoom (global-map "<f2>"
704 ("g" text-scale-increase "in")
705 ("l" text-scale-decrease "out")
706 ("q" nil "quit"))))))
708 (ert-deftest hydra-format-1 ()
710 (let ((hydra-fontify-head-function
711 'hydra-fontify-head-greyscale))
716 _a_ abbrev-mode: %`abbrev-mode
717 _d_ debug-on-error: %`debug-on-error
718 _f_ auto-fill-mode: %`auto-fill-function
719 " '(("a" abbrev-mode nil)
720 ("d" toggle-debug-on-error nil)
721 ("f" auto-fill-mode nil)
722 ("g" golden-ratio-mode nil)
723 ("t" toggle-truncate-lines nil)
724 ("w" whitespace-mode nil)
726 '(concat (format "%s abbrev-mode: %S
727 %s debug-on-error: %S
728 %s auto-fill-mode: %S
729 " "{a}" abbrev-mode "{d}" debug-on-error "{f}" auto-fill-function) "[[q]]: quit"))))
731 (ert-deftest hydra-format-2 ()
733 (let ((hydra-fontify-head-function
734 'hydra-fontify-head-greyscale))
739 '(("a" (quote t) "" :cmd-name bar/lambda-a)
740 ("q" nil "" :cmd-name bar/nil))))
741 '(concat (format " bar %s\n" foo) "{a}, [q]"))))
743 (ert-deftest hydra-format-3 ()
745 (let ((hydra-fontify-head-function
746 'hydra-fontify-head-greyscale))
750 "\n_<SPC>_ ^^ace jump\n"
751 '(("<SPC>" ace-jump-char-mode nil :cmd-name bar/ace-jump-char-mode))))
752 '(concat (format "%s ace jump\n" "{<SPC>}") ""))))
754 (ert-deftest hydra-format-with-sexp-1 ()
756 (let ((hydra-fontify-head-function
757 'hydra-fontify-head-greyscale))
760 "\n_n_ narrow-or-widen-dwim %(progn (message \"checking\")(buffer-narrowed-p))asdf\n"
761 '(("n" narrow-to-region nil) ("q" nil "cancel"))))
762 '(concat (format "%s narrow-or-widen-dwim %Sasdf\n"
766 (buffer-narrowed-p)))
769 (ert-deftest hydra-format-with-sexp-2 ()
771 (let ((hydra-fontify-head-function
772 'hydra-fontify-head-greyscale))
775 "\n_n_ narrow-or-widen-dwim %s(progn (message \"checking\")(buffer-narrowed-p))asdf\n"
776 '(("n" narrow-to-region nil) ("q" nil "cancel"))))
777 '(concat (format "%s narrow-or-widen-dwim %sasdf\n"
781 (buffer-narrowed-p)))
784 (ert-deftest hydra-compat-colors-1 ()
785 (should (equal (hydra--head-color
786 '("e" (message "Exiting now") "blue")
787 '(nil nil :color blue))
789 (should (equal (hydra--head-color
790 '("c" (message "Continuing") "red" :color red)
791 '(nil nil :color blue))
793 (should (equal (hydra--head-color
794 '("e" (message "Exiting now") "blue")
797 (should (equal (hydra--head-color
798 '("j" next-line "" :exit t)
801 (should (equal (hydra--head-color
802 '("c" (message "Continuing") "red" :exit nil)
805 (equal (hydra--head-color
806 '("a" abbrev-mode nil)
807 '(nil nil :color teal))
809 (equal (hydra--head-color
810 '("a" abbrev-mode :exit nil)
811 '(nil nil :color teal))
814 (ert-deftest hydra-compat-colors-2 ()
818 '(defhydra hydra-test (:color amaranth)
820 ("b" fun-b :color blue)
821 ("c" fun-c :color blue)
822 ("d" fun-d :color blue)
823 ("e" fun-e :color blue)
824 ("f" fun-f :color blue)))
826 '(defhydra hydra-test (:color teal)
827 ("a" fun-a :color red)
834 (ert-deftest hydra-compat-colors-3 ()
838 '(defhydra hydra-test ()
840 ("b" fun-b :color blue)
841 ("c" fun-c :color blue)
842 ("d" fun-d :color blue)
843 ("e" fun-e :color blue)
844 ("f" fun-f :color blue)))
846 '(defhydra hydra-test (:color blue)
847 ("a" fun-a :color red)
854 (ert-deftest hydra-compat-colors-4 ()
858 '(defhydra hydra-test ()
864 ("f" fun-f :exit t)))
866 '(defhydra hydra-test (:exit t)
867 ("a" fun-a :exit nil)
874 (ert-deftest hydra-zoom-duplicate-1 ()
878 '(defhydra hydra-zoom ()
880 ("r" (text-scale-set 0) "reset")
881 ("0" (text-scale-set 0) :bind nil :exit t)
882 ("1" (text-scale-set 0) nil :bind nil :exit t)))
884 (defun hydra-zoom/lambda-r nil "Create a hydra with no body and the heads:
886 \"r\": `(text-scale-set 0)',
887 \"0\": `(text-scale-set 0)',
888 \"1\": `(text-scale-set 0)'
890 The body can be accessed via `hydra-zoom/body'.
892 Call the head: `(text-scale-set 0)'."
895 (catch (quote hydra-disable)
896 (condition-case err (prog1 t (call-interactively (function (lambda nil (interactive)
897 (text-scale-set 0)))))
900 (unless hydra-lv (sit-for 0.8))
902 (when hydra-is-helpful (hydra-zoom/hint))
904 (hydra-set-transient-map
906 (quote (keymap (7 . hydra-keyboard-quit)
907 (114 . hydra-zoom/lambda-r)
908 (switch-frame . hydra--handle-switch-frame)
909 (kp-subtract . hydra--negative-argument)
910 (kp-9 . hydra--digit-argument)
911 (kp-8 . hydra--digit-argument)
912 (kp-7 . hydra--digit-argument)
913 (kp-6 . hydra--digit-argument)
914 (kp-5 . hydra--digit-argument)
915 (kp-4 . hydra--digit-argument)
916 (kp-3 . hydra--digit-argument)
917 (kp-2 . hydra--digit-argument)
918 (kp-1 . hydra--digit-argument)
919 (kp-0 . hydra--digit-argument)
920 (57 . hydra--digit-argument)
921 (56 . hydra--digit-argument)
922 (55 . hydra--digit-argument)
923 (54 . hydra--digit-argument)
924 (53 . hydra--digit-argument)
925 (52 . hydra--digit-argument)
926 (51 . hydra--digit-argument)
927 (50 . hydra--digit-argument)
928 (49 . hydra-zoom/lambda-0-and-exit)
929 (48 . hydra-zoom/lambda-0-and-exit)
930 (45 . hydra--negative-argument)
931 (21 . hydra--universal-argument))))
932 t (lambda nil (hydra-cleanup))))))
933 (defun hydra-zoom/lambda-0-and-exit nil "Create a hydra with no body and the heads:
935 \"r\": `(text-scale-set 0)',
936 \"0\": `(text-scale-set 0)',
937 \"1\": `(text-scale-set 0)'
939 The body can be accessed via `hydra-zoom/body'.
941 Call the head: `(text-scale-set 0)'."
945 (catch (quote hydra-disable)
946 (call-interactively (function (lambda nil (interactive)
947 (text-scale-set 0))))))
948 (defun hydra-zoom/hint nil
949 (if hydra-lv (lv-message (format #("zoom: [r 0]: reset." 7 8 (face hydra-face-red)
950 9 10 (face hydra-face-blue))))
951 (message (format #("zoom: [r 0]: reset." 7 8 (face hydra-face-red)
952 9 10 (face hydra-face-blue))))))
953 (defun hydra-zoom/body nil "Create a hydra with no body and the heads:
955 \"r\": `(text-scale-set 0)',
956 \"0\": `(text-scale-set 0)',
957 \"1\": `(text-scale-set 0)'
959 The body can be accessed via `hydra-zoom/body'."
962 (catch (quote hydra-disable)
963 (when hydra-is-helpful (hydra-zoom/hint))
965 (hydra-set-transient-map
967 (quote (keymap (7 . hydra-keyboard-quit)
968 (114 . hydra-zoom/lambda-r)
969 (switch-frame . hydra--handle-switch-frame)
970 (kp-subtract . hydra--negative-argument)
971 (kp-9 . hydra--digit-argument)
972 (kp-8 . hydra--digit-argument)
973 (kp-7 . hydra--digit-argument)
974 (kp-6 . hydra--digit-argument)
975 (kp-5 . hydra--digit-argument)
976 (kp-4 . hydra--digit-argument)
977 (kp-3 . hydra--digit-argument)
978 (kp-2 . hydra--digit-argument)
979 (kp-1 . hydra--digit-argument)
980 (kp-0 . hydra--digit-argument)
981 (57 . hydra--digit-argument)
982 (56 . hydra--digit-argument)
983 (55 . hydra--digit-argument)
984 (54 . hydra--digit-argument)
985 (53 . hydra--digit-argument)
986 (52 . hydra--digit-argument)
987 (51 . hydra--digit-argument)
988 (50 . hydra--digit-argument)
989 (49 . hydra-zoom/lambda-0-and-exit)
990 (48 . hydra-zoom/lambda-0-and-exit)
991 (45 . hydra--negative-argument)
992 (21 . hydra--universal-argument))))
993 t (lambda nil (hydra-cleanup))))
994 (setq prefix-arg current-prefix-arg)))))))
996 (ert-deftest hydra-zoom-duplicate-2 ()
1000 '(defhydra hydra-zoom ()
1002 ("r" (text-scale-set 0) "reset")
1003 ("0" (text-scale-set 0) :bind nil :exit t)
1004 ("1" (text-scale-set 0) nil :bind nil)))
1006 (defun hydra-zoom/lambda-r nil "Create a hydra with no body and the heads:
1008 \"r\": `(text-scale-set 0)',
1009 \"0\": `(text-scale-set 0)',
1010 \"1\": `(text-scale-set 0)'
1012 The body can be accessed via `hydra-zoom/body'.
1014 Call the head: `(text-scale-set 0)'."
1017 (catch (quote hydra-disable)
1018 (condition-case err (prog1 t (call-interactively (function (lambda nil (interactive)
1019 (text-scale-set 0)))))
1022 (unless hydra-lv (sit-for 0.8))
1024 (when hydra-is-helpful (hydra-zoom/hint))
1026 (hydra-set-transient-map
1027 (setq hydra-curr-map
1028 (quote (keymap (7 . hydra-keyboard-quit)
1029 (114 . hydra-zoom/lambda-r)
1030 (switch-frame . hydra--handle-switch-frame)
1031 (kp-subtract . hydra--negative-argument)
1032 (kp-9 . hydra--digit-argument)
1033 (kp-8 . hydra--digit-argument)
1034 (kp-7 . hydra--digit-argument)
1035 (kp-6 . hydra--digit-argument)
1036 (kp-5 . hydra--digit-argument)
1037 (kp-4 . hydra--digit-argument)
1038 (kp-3 . hydra--digit-argument)
1039 (kp-2 . hydra--digit-argument)
1040 (kp-1 . hydra--digit-argument)
1041 (kp-0 . hydra--digit-argument)
1042 (57 . hydra--digit-argument)
1043 (56 . hydra--digit-argument)
1044 (55 . hydra--digit-argument)
1045 (54 . hydra--digit-argument)
1046 (53 . hydra--digit-argument)
1047 (52 . hydra--digit-argument)
1048 (51 . hydra--digit-argument)
1049 (50 . hydra--digit-argument)
1050 (49 . hydra-zoom/lambda-r)
1051 (48 . hydra-zoom/lambda-0-and-exit)
1052 (45 . hydra--negative-argument)
1053 (21 . hydra--universal-argument))))
1054 t (lambda nil (hydra-cleanup))))))
1055 (defun hydra-zoom/lambda-0-and-exit nil "Create a hydra with no body and the heads:
1057 \"r\": `(text-scale-set 0)',
1058 \"0\": `(text-scale-set 0)',
1059 \"1\": `(text-scale-set 0)'
1061 The body can be accessed via `hydra-zoom/body'.
1063 Call the head: `(text-scale-set 0)'."
1067 (catch (quote hydra-disable)
1068 (call-interactively (function (lambda nil (interactive)
1069 (text-scale-set 0))))))
1070 (defun hydra-zoom/hint nil
1071 (if hydra-lv (lv-message (format #("zoom: [r 0]: reset." 7 8 (face hydra-face-red)
1072 9 10 (face hydra-face-blue))))
1073 (message (format #("zoom: [r 0]: reset." 7 8 (face hydra-face-red)
1074 9 10 (face hydra-face-blue))))))
1075 (defun hydra-zoom/body nil "Create a hydra with no body and the heads:
1077 \"r\": `(text-scale-set 0)',
1078 \"0\": `(text-scale-set 0)',
1079 \"1\": `(text-scale-set 0)'
1081 The body can be accessed via `hydra-zoom/body'."
1084 (catch (quote hydra-disable)
1085 (when hydra-is-helpful (hydra-zoom/hint))
1087 (hydra-set-transient-map
1088 (setq hydra-curr-map
1089 (quote (keymap (7 . hydra-keyboard-quit)
1090 (114 . hydra-zoom/lambda-r)
1091 (switch-frame . hydra--handle-switch-frame)
1092 (kp-subtract . hydra--negative-argument)
1093 (kp-9 . hydra--digit-argument)
1094 (kp-8 . hydra--digit-argument)
1095 (kp-7 . hydra--digit-argument)
1096 (kp-6 . hydra--digit-argument)
1097 (kp-5 . hydra--digit-argument)
1098 (kp-4 . hydra--digit-argument)
1099 (kp-3 . hydra--digit-argument)
1100 (kp-2 . hydra--digit-argument)
1101 (kp-1 . hydra--digit-argument)
1102 (kp-0 . hydra--digit-argument)
1103 (57 . hydra--digit-argument)
1104 (56 . hydra--digit-argument)
1105 (55 . hydra--digit-argument)
1106 (54 . hydra--digit-argument)
1107 (53 . hydra--digit-argument)
1108 (52 . hydra--digit-argument)
1109 (51 . hydra--digit-argument)
1110 (50 . hydra--digit-argument)
1111 (49 . hydra-zoom/lambda-r)
1112 (48 . hydra-zoom/lambda-0-and-exit)
1113 (45 . hydra--negative-argument)
1114 (21 . hydra--universal-argument))))
1115 t (lambda nil (hydra-cleanup))))
1116 (setq prefix-arg current-prefix-arg)))))))
1118 (ert-deftest hydra--pad ()
1119 (should (equal (hydra--pad '(a b c) 3)
1121 (should (equal (hydra--pad '(a) 3)
1124 (ert-deftest hydra--matrix ()
1125 (should (equal (hydra--matrix '(a b c) 2 2)
1127 (should (equal (hydra--matrix '(a b c d e f g h i) 4 3)
1128 '((a b c d) (e f g h) (i nil nil nil)))))
1130 (ert-deftest hydra--cell ()
1131 (should (equal (hydra--cell "% -75s %%`%s" '(hydra-lv hydra-verbose))
1132 "When non-nil, `lv-message' (not `message') will be used to display hints. %`hydra-lv^^^^^
1133 When non-nil, hydra will issue some non essential style warnings. %`hydra-verbose")))
1135 (ert-deftest hydra--vconcat ()
1136 (should (equal (hydra--vconcat '("abc\ndef" "012\n34" "def\nabc"))
1137 "abc012def\ndef34abc")))
1139 (defhydradio hydra-tng ()
1140 (picard "_p_ Captain Jean Luc Picard:")
1141 (riker "_r_ Commander William Riker:")
1142 (data "_d_ Lieutenant Commander Data:")
1144 (la-forge "_f_ Geordi La Forge:")
1145 (troi "_t_ Deanna Troi:")
1146 (dr-crusher "_c_ Doctor Beverly Crusher:")
1147 (phaser "_h_ Set phasers to " [stun kill]))
1149 (ert-deftest hydra--table ()
1150 (let ((hydra-cell-format "% -30s %% -8`%s"))
1151 (should (equal (hydra--table hydra-tng/names 5 2)
1153 _p_ Captain Jean Luc Picard: % -8`hydra-tng/picard^^ _t_ Deanna Troi: % -8`hydra-tng/troi^^^^^^
1154 _r_ Commander William Riker: % -8`hydra-tng/riker^^^ _c_ Doctor Beverly Crusher: % -8`hydra-tng/dr-crusher
1155 _d_ Lieutenant Commander Data: % -8`hydra-tng/data^^^^ _h_ Set phasers to % -8`hydra-tng/phaser^^^^
1156 _w_ Worf: % -8`hydra-tng/worf^^^^
1157 _f_ Geordi La Forge: % -8`hydra-tng/la-forge" 1)))
1158 (should (equal (hydra--table hydra-tng/names 4 3)
1160 _p_ Captain Jean Luc Picard: % -8`hydra-tng/picard _f_ Geordi La Forge: % -8`hydra-tng/la-forge^^
1161 _r_ Commander William Riker: % -8`hydra-tng/riker^ _t_ Deanna Troi: % -8`hydra-tng/troi^^^^^^
1162 _d_ Lieutenant Commander Data: % -8`hydra-tng/data^^ _c_ Doctor Beverly Crusher: % -8`hydra-tng/dr-crusher
1163 _w_ Worf: % -8`hydra-tng/worf^^ _h_ Set phasers to % -8`hydra-tng/phaser^^^^" 1)))))
1165 (provide 'hydra-test)
1167 ;;; hydra-test.el ends here