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 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 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 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)
358 (102 . hydra-toggle/auto-fill-mode)
359 (116 . hydra-toggle/toggle-truncate-lines)
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 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)
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)
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)
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 ()
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-with-sexp ()
733 (let ((hydra-fontify-head-function
734 'hydra-fontify-head-greyscale))
737 "\n_n_ narrow-or-widen-dwim %(progn (message \"checking\")(buffer-narrowed-p))asdf\n"
738 '(("n" narrow-to-region nil) ("q" nil "cancel"))))
739 '(concat (format "%s narrow-or-widen-dwim %Sasdf\n"
743 (buffer-narrowed-p)))
746 (ert-deftest hydra-compat-colors-1 ()
747 (should (equal (hydra--head-color
748 '("e" (message "Exiting now") "blue")
749 '(nil nil :color blue))
751 (should (equal (hydra--head-color
752 '("c" (message "Continuing") "red" :color red)
753 '(nil nil :color blue))
755 (should (equal (hydra--head-color
756 '("e" (message "Exiting now") "blue")
759 (should (equal (hydra--head-color
760 '("c" (message "Continuing") "red" :exit nil)
763 (equal (hydra--head-color
764 '("a" abbrev-mode nil)
765 '(nil nil :color teal))
767 (equal (hydra--head-color
768 '("a" abbrev-mode :exit nil)
769 '(nil nil :color teal))
772 (ert-deftest hydra-compat-colors-2 ()
776 '(defhydra hydra-test (:color amaranth)
778 ("b" fun-b :color blue)
779 ("c" fun-c :color blue)
780 ("d" fun-d :color blue)
781 ("e" fun-e :color blue)
782 ("f" fun-f :color blue)))
784 '(defhydra hydra-test (:color teal)
785 ("a" fun-a :color red)
792 (ert-deftest hydra-compat-colors-3 ()
796 '(defhydra hydra-test ()
798 ("b" fun-b :color blue)
799 ("c" fun-c :color blue)
800 ("d" fun-d :color blue)
801 ("e" fun-e :color blue)
802 ("f" fun-f :color blue)))
804 '(defhydra hydra-test (:color blue)
805 ("a" fun-a :color red)
812 (ert-deftest hydra-compat-colors-4 ()
816 '(defhydra hydra-test ()
822 ("f" fun-f :exit t)))
824 '(defhydra hydra-test (:exit t)
825 ("a" fun-a :exit nil)
832 (ert-deftest hydra-zoom-duplicate-1 ()
836 '(defhydra hydra-zoom ()
838 ("r" (text-scale-set 0) "reset")
839 ("0" (text-scale-set 0) :bind nil :exit t)
840 ("1" (text-scale-set 0) nil :bind nil :exit t)))
842 (defun hydra-zoom/lambda-r nil "Create a hydra with no body and the heads:
844 \"r\": `(text-scale-set 0)',
845 \"0\": `(text-scale-set 0)',
846 \"1\": `(text-scale-set 0)'
848 The body can be accessed via `hydra-zoom/body'.
850 Call the head: `(text-scale-set 0)'."
853 (catch (quote hydra-disable)
854 (condition-case err (prog1 t (call-interactively (function (lambda nil (interactive)
855 (text-scale-set 0)))))
858 (unless hydra-lv (sit-for 0.8))
860 (when hydra-is-helpful (hydra-zoom/hint))
862 (hydra-set-transient-map
864 (quote (keymap (7 . hydra-keyboard-quit)
865 (114 . hydra-zoom/lambda-r)
866 (switch-frame . hydra--handle-switch-frame)
867 (kp-subtract . hydra--negative-argument)
868 (kp-9 . hydra--digit-argument)
869 (kp-8 . hydra--digit-argument)
870 (kp-7 . hydra--digit-argument)
871 (kp-6 . hydra--digit-argument)
872 (kp-5 . hydra--digit-argument)
873 (kp-4 . hydra--digit-argument)
874 (kp-3 . hydra--digit-argument)
875 (kp-2 . hydra--digit-argument)
876 (kp-1 . hydra--digit-argument)
877 (kp-0 . hydra--digit-argument)
878 (57 . hydra--digit-argument)
879 (56 . hydra--digit-argument)
880 (55 . hydra--digit-argument)
881 (54 . hydra--digit-argument)
882 (53 . hydra--digit-argument)
883 (52 . hydra--digit-argument)
884 (51 . hydra--digit-argument)
885 (50 . hydra--digit-argument)
886 (49 . hydra-zoom/lambda-0)
887 (48 . hydra-zoom/lambda-0)
888 (45 . hydra--negative-argument)
889 (21 . hydra--universal-argument))))
890 t (lambda nil (hydra-cleanup))))))
891 (defun hydra-zoom/lambda-0 nil "Create a hydra with no body and the heads:
893 \"r\": `(text-scale-set 0)',
894 \"0\": `(text-scale-set 0)',
895 \"1\": `(text-scale-set 0)'
897 The body can be accessed via `hydra-zoom/body'.
899 Call the head: `(text-scale-set 0)'."
903 (catch (quote hydra-disable)
904 (call-interactively (function (lambda nil (interactive)
905 (text-scale-set 0))))))
906 (defun hydra-zoom/hint nil
907 (if hydra-lv (lv-message (format #("zoom: [r 0]: reset." 7 8 (face hydra-face-red)
908 9 10 (face hydra-face-blue))))
909 (message (format #("zoom: [r 0]: reset." 7 8 (face hydra-face-red)
910 9 10 (face hydra-face-blue))))))
911 (defun hydra-zoom/body nil "Create a hydra with no body and the heads:
913 \"r\": `(text-scale-set 0)',
914 \"0\": `(text-scale-set 0)',
915 \"1\": `(text-scale-set 0)'
917 The body can be accessed via `hydra-zoom/body'."
920 (catch (quote hydra-disable)
921 (when hydra-is-helpful (hydra-zoom/hint))
923 (hydra-set-transient-map
925 (quote (keymap (7 . hydra-keyboard-quit)
926 (114 . hydra-zoom/lambda-r)
927 (switch-frame . hydra--handle-switch-frame)
928 (kp-subtract . hydra--negative-argument)
929 (kp-9 . hydra--digit-argument)
930 (kp-8 . hydra--digit-argument)
931 (kp-7 . hydra--digit-argument)
932 (kp-6 . hydra--digit-argument)
933 (kp-5 . hydra--digit-argument)
934 (kp-4 . hydra--digit-argument)
935 (kp-3 . hydra--digit-argument)
936 (kp-2 . hydra--digit-argument)
937 (kp-1 . hydra--digit-argument)
938 (kp-0 . hydra--digit-argument)
939 (57 . hydra--digit-argument)
940 (56 . hydra--digit-argument)
941 (55 . hydra--digit-argument)
942 (54 . hydra--digit-argument)
943 (53 . hydra--digit-argument)
944 (52 . hydra--digit-argument)
945 (51 . hydra--digit-argument)
946 (50 . hydra--digit-argument)
947 (49 . hydra-zoom/lambda-0)
948 (48 . hydra-zoom/lambda-0)
949 (45 . hydra--negative-argument)
950 (21 . hydra--universal-argument))))
951 t (lambda nil (hydra-cleanup))))
952 (setq prefix-arg current-prefix-arg)))))))
954 (ert-deftest hydra-zoom-duplicate-2 ()
958 '(defhydra hydra-zoom ()
960 ("r" (text-scale-set 0) "reset")
961 ("0" (text-scale-set 0) :bind nil :exit t)
962 ("1" (text-scale-set 0) nil :bind nil)))
964 (defun hydra-zoom/lambda-r nil "Create a hydra with no body and the heads:
966 \"r\": `(text-scale-set 0)',
967 \"0\": `(text-scale-set 0)',
968 \"1\": `(text-scale-set 0)'
970 The body can be accessed via `hydra-zoom/body'.
972 Call the head: `(text-scale-set 0)'."
975 (catch (quote hydra-disable)
976 (condition-case err (prog1 t (call-interactively (function (lambda nil (interactive)
977 (text-scale-set 0)))))
980 (unless hydra-lv (sit-for 0.8))
982 (when hydra-is-helpful (hydra-zoom/hint))
984 (hydra-set-transient-map
986 (quote (keymap (7 . hydra-keyboard-quit)
987 (114 . hydra-zoom/lambda-r)
988 (switch-frame . hydra--handle-switch-frame)
989 (kp-subtract . hydra--negative-argument)
990 (kp-9 . hydra--digit-argument)
991 (kp-8 . hydra--digit-argument)
992 (kp-7 . hydra--digit-argument)
993 (kp-6 . hydra--digit-argument)
994 (kp-5 . hydra--digit-argument)
995 (kp-4 . hydra--digit-argument)
996 (kp-3 . hydra--digit-argument)
997 (kp-2 . hydra--digit-argument)
998 (kp-1 . hydra--digit-argument)
999 (kp-0 . hydra--digit-argument)
1000 (57 . hydra--digit-argument)
1001 (56 . hydra--digit-argument)
1002 (55 . hydra--digit-argument)
1003 (54 . hydra--digit-argument)
1004 (53 . hydra--digit-argument)
1005 (52 . hydra--digit-argument)
1006 (51 . hydra--digit-argument)
1007 (50 . hydra--digit-argument)
1008 (49 . hydra-zoom/lambda-r)
1009 (48 . hydra-zoom/lambda-0)
1010 (45 . hydra--negative-argument)
1011 (21 . hydra--universal-argument))))
1012 t (lambda nil (hydra-cleanup))))))
1013 (defun hydra-zoom/lambda-0 nil "Create a hydra with no body and the heads:
1015 \"r\": `(text-scale-set 0)',
1016 \"0\": `(text-scale-set 0)',
1017 \"1\": `(text-scale-set 0)'
1019 The body can be accessed via `hydra-zoom/body'.
1021 Call the head: `(text-scale-set 0)'."
1025 (catch (quote hydra-disable)
1026 (call-interactively (function (lambda nil (interactive)
1027 (text-scale-set 0))))))
1028 (defun hydra-zoom/hint nil
1029 (if hydra-lv (lv-message (format #("zoom: [r 0]: reset." 7 8 (face hydra-face-red)
1030 9 10 (face hydra-face-blue))))
1031 (message (format #("zoom: [r 0]: reset." 7 8 (face hydra-face-red)
1032 9 10 (face hydra-face-blue))))))
1033 (defun hydra-zoom/body nil "Create a hydra with no body and the heads:
1035 \"r\": `(text-scale-set 0)',
1036 \"0\": `(text-scale-set 0)',
1037 \"1\": `(text-scale-set 0)'
1039 The body can be accessed via `hydra-zoom/body'."
1042 (catch (quote hydra-disable)
1043 (when hydra-is-helpful (hydra-zoom/hint))
1045 (hydra-set-transient-map
1046 (setq hydra-curr-map
1047 (quote (keymap (7 . hydra-keyboard-quit)
1048 (114 . hydra-zoom/lambda-r)
1049 (switch-frame . hydra--handle-switch-frame)
1050 (kp-subtract . hydra--negative-argument)
1051 (kp-9 . hydra--digit-argument)
1052 (kp-8 . hydra--digit-argument)
1053 (kp-7 . hydra--digit-argument)
1054 (kp-6 . hydra--digit-argument)
1055 (kp-5 . hydra--digit-argument)
1056 (kp-4 . hydra--digit-argument)
1057 (kp-3 . hydra--digit-argument)
1058 (kp-2 . hydra--digit-argument)
1059 (kp-1 . hydra--digit-argument)
1060 (kp-0 . hydra--digit-argument)
1061 (57 . hydra--digit-argument)
1062 (56 . hydra--digit-argument)
1063 (55 . hydra--digit-argument)
1064 (54 . hydra--digit-argument)
1065 (53 . hydra--digit-argument)
1066 (52 . hydra--digit-argument)
1067 (51 . hydra--digit-argument)
1068 (50 . hydra--digit-argument)
1069 (49 . hydra-zoom/lambda-r)
1070 (48 . hydra-zoom/lambda-0)
1071 (45 . hydra--negative-argument)
1072 (21 . hydra--universal-argument))))
1073 t (lambda nil (hydra-cleanup))))
1074 (setq prefix-arg current-prefix-arg)))))))
1076 (ert-deftest hydra--pad ()
1077 (should (equal (hydra--pad '(a b c) 3)
1079 (should (equal (hydra--pad '(a) 3)
1082 (ert-deftest hydra--matrix ()
1083 (should (equal (hydra--matrix '(a b c) 2 2)
1085 (should (equal (hydra--matrix '(a b c d e f g h i) 4 3)
1086 '((a b c d) (e f g h) (i nil nil nil)))))
1088 (ert-deftest hydra--cell ()
1089 (should (equal (hydra--cell "% -75s %%`%s" '(hydra-lv hydra-verbose))
1090 "When non-nil, `lv-message' (not `message') will be used to display hints. %`hydra-lv^^^^^
1091 When non-nil, hydra will issue some non essential style warnings. %`hydra-verbose")))
1093 (ert-deftest hydra--vconcat ()
1094 (should (equal (hydra--vconcat '("abc\ndef" "012\n34" "def\nabc"))
1095 "abc012def\ndef34abc")))
1097 (defhydradio hydra-tng ()
1098 (picard "_p_ Captain Jean Luc Picard:")
1099 (riker "_r_ Commander William Riker:")
1100 (data "_d_ Lieutenant Commander Data:")
1102 (la-forge "_f_ Geordi La Forge:")
1103 (troi "_t_ Deanna Troi:")
1104 (dr-crusher "_c_ Doctor Beverly Crusher:")
1105 (phaser "_h_ Set phasers to " [stun kill]))
1107 (ert-deftest hydra--table ()
1108 (let ((hydra-cell-format "% -30s %% -8`%s"))
1109 (should (equal (hydra--table hydra-tng/names 5 2)
1111 _p_ Captain Jean Luc Picard: % -8`hydra-tng/picard^^ _t_ Deanna Troi: % -8`hydra-tng/troi^^^^^^
1112 _r_ Commander William Riker: % -8`hydra-tng/riker^^^ _c_ Doctor Beverly Crusher: % -8`hydra-tng/dr-crusher
1113 _d_ Lieutenant Commander Data: % -8`hydra-tng/data^^^^ _h_ Set phasers to % -8`hydra-tng/phaser^^^^
1114 _w_ Worf: % -8`hydra-tng/worf^^^^
1115 _f_ Geordi La Forge: % -8`hydra-tng/la-forge" 1)))
1116 (should (equal (hydra--table hydra-tng/names 4 3)
1118 _p_ Captain Jean Luc Picard: % -8`hydra-tng/picard _f_ Geordi La Forge: % -8`hydra-tng/la-forge^^
1119 _r_ Commander William Riker: % -8`hydra-tng/riker^ _t_ Deanna Troi: % -8`hydra-tng/troi^^^^^^
1120 _d_ Lieutenant Commander Data: % -8`hydra-tng/data^^ _c_ Doctor Beverly Crusher: % -8`hydra-tng/dr-crusher
1121 _w_ Worf: % -8`hydra-tng/worf^^ _h_ Set phasers to % -8`hydra-tng/phaser^^^^" 1)))))
1123 (provide 'hydra-test)
1125 ;;; hydra-test.el ends here