]> code.delx.au - gnu-emacs-elpa/blob - packages/hydra/hydra-test.el
Add 'packages/tiny/' from commit '159c3f74e75970808b83fe4b732f180cb76872a3'
[gnu-emacs-elpa] / packages / hydra / hydra-test.el
1 ;;; hydra-test.el --- Tests for Hydra
2
3 ;; Copyright (C) 2015 Free Software Foundation, Inc.
4
5 ;; Author: Oleh Krehel
6
7 ;; This file is part of GNU Emacs.
8
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.
13
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.
18
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/>.
21
22 ;;; Commentary:
23 ;;
24
25 ;;; Code:
26
27 (require 'ert)
28
29 (ert-deftest hydra-red-error ()
30 (should
31 (equal
32 (macroexpand
33 '(defhydra hydra-error (global-map "M-g")
34 "error"
35 ("h" first-error "first")
36 ("j" next-error "next")
37 ("k" previous-error "prev")
38 ("SPC" hydra-repeat "rep" :bind nil)))
39 '(progn
40 (defun hydra-error/first-error nil "Create a hydra with a \"M-g\" body and the heads:
41
42 \"h\": `first-error',
43 \"j\": `next-error',
44 \"k\": `previous-error',
45 \"SPC\": `hydra-repeat'
46
47 The body can be accessed via `hydra-error/body'.
48
49 Call the head: `first-error'."
50 (interactive)
51 (hydra-disable)
52 (catch (quote hydra-disable)
53 (condition-case err (prog1 t (call-interactively (function first-error)))
54 ((quit error)
55 (message "%S" err)
56 (unless hydra-lv (sit-for 0.8))
57 nil))
58 (when hydra-is-helpful (hydra-error/hint))
59 (setq hydra-last
60 (hydra-set-transient-map
61 (setq hydra-curr-map
62 (quote (keymap (7 . hydra-keyboard-quit)
63 (32 . hydra-repeat)
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:
93
94 \"h\": `first-error',
95 \"j\": `next-error',
96 \"k\": `previous-error',
97 \"SPC\": `hydra-repeat'
98
99 The body can be accessed via `hydra-error/body'.
100
101 Call the head: `next-error'."
102 (interactive)
103 (hydra-disable)
104 (catch (quote hydra-disable)
105 (condition-case err (prog1 t (call-interactively (function next-error)))
106 ((quit error)
107 (message "%S" err)
108 (unless hydra-lv (sit-for 0.8))
109 nil))
110 (when hydra-is-helpful (hydra-error/hint))
111 (setq hydra-last
112 (hydra-set-transient-map
113 (setq hydra-curr-map
114 (quote (keymap (7 . hydra-keyboard-quit)
115 (32 . hydra-repeat)
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:
145
146 \"h\": `first-error',
147 \"j\": `next-error',
148 \"k\": `previous-error',
149 \"SPC\": `hydra-repeat'
150
151 The body can be accessed via `hydra-error/body'.
152
153 Call the head: `previous-error'."
154 (interactive)
155 (hydra-disable)
156 (catch (quote hydra-disable)
157 (condition-case err (prog1 t (call-interactively (function previous-error)))
158 ((quit error)
159 (message "%S" err)
160 (unless hydra-lv (sit-for 0.8))
161 nil))
162 (when hydra-is-helpful (hydra-error/hint))
163 (setq hydra-last
164 (hydra-set-transient-map
165 (setq hydra-curr-map
166 (quote (keymap (7 . hydra-keyboard-quit)
167 (32 . hydra-repeat)
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")
198 nil))
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:
215
216 \"h\": `first-error',
217 \"j\": `next-error',
218 \"k\": `previous-error',
219 \"SPC\": `hydra-repeat'
220
221 The body can be accessed via `hydra-error/body'."
222 (interactive)
223 (hydra-disable)
224 (catch (quote hydra-disable)
225 (when hydra-is-helpful (hydra-error/hint))
226 (setq hydra-last
227 (hydra-set-transient-map
228 (setq hydra-curr-map
229 (quote (keymap (7 . hydra-keyboard-quit)
230 (32 . hydra-repeat)
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)))))))
260
261 (ert-deftest hydra-blue-toggle ()
262 (should
263 (equal
264 (macroexpand
265 '(defhydra hydra-toggle (:color blue)
266 "toggle"
267 ("t" toggle-truncate-lines "truncate")
268 ("f" auto-fill-mode "fill")
269 ("a" abbrev-mode "abbrev")
270 ("q" nil "cancel")))
271 '(progn
272 (defun hydra-toggle/toggle-truncate-lines nil "Create a hydra with no body and the heads:
273
274 \"t\": `toggle-truncate-lines',
275 \"f\": `auto-fill-mode',
276 \"a\": `abbrev-mode',
277 \"q\": `nil'
278
279 The body can be accessed via `hydra-toggle/body'.
280
281 Call the head: `toggle-truncate-lines'."
282 (interactive)
283 (hydra-disable)
284 (hydra-cleanup)
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:
288
289 \"t\": `toggle-truncate-lines',
290 \"f\": `auto-fill-mode',
291 \"a\": `abbrev-mode',
292 \"q\": `nil'
293
294 The body can be accessed via `hydra-toggle/body'.
295
296 Call the head: `auto-fill-mode'."
297 (interactive)
298 (hydra-disable)
299 (hydra-cleanup)
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:
303
304 \"t\": `toggle-truncate-lines',
305 \"f\": `auto-fill-mode',
306 \"a\": `abbrev-mode',
307 \"q\": `nil'
308
309 The body can be accessed via `hydra-toggle/body'.
310
311 Call the head: `abbrev-mode'."
312 (interactive)
313 (hydra-disable)
314 (hydra-cleanup)
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:
318
319 \"t\": `toggle-truncate-lines',
320 \"f\": `auto-fill-mode',
321 \"a\": `abbrev-mode',
322 \"q\": `nil'
323
324 The body can be accessed via `hydra-toggle/body'.
325
326 Call the head: `nil'."
327 (interactive)
328 (hydra-disable)
329 (hydra-cleanup)
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:
341
342 \"t\": `toggle-truncate-lines',
343 \"f\": `auto-fill-mode',
344 \"a\": `abbrev-mode',
345 \"q\": `nil'
346
347 The body can be accessed via `hydra-toggle/body'."
348 (interactive)
349 (hydra-disable)
350 (catch (quote hydra-disable)
351 (when hydra-is-helpful (hydra-toggle/hint))
352 (setq hydra-last
353 (hydra-set-transient-map
354 (setq hydra-curr-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)))))))
386
387 (ert-deftest hydra-amaranth-vi ()
388 (should
389 (equal
390 (macroexpand
391 '(defhydra hydra-vi
392 (:pre
393 (set-cursor-color "#e52b50")
394 :post
395 (set-cursor-color "#ffffff")
396 :color amaranth)
397 "vi"
398 ("j" next-line)
399 ("k" previous-line)
400 ("q" nil "quit")))
401 '(progn
402 (defun hydra-vi/hydra-keyboard-quit nil "Create a hydra with no body and the heads:
403
404 \"\a\": `hydra-keyboard-quit',
405 \"j\": `next-line',
406 \"k\": `previous-line',
407 \"q\": `nil'
408
409 The body can be accessed via `hydra-vi/body'.
410
411 Call the head: `hydra-keyboard-quit'."
412 (interactive)
413 (set-cursor-color "#e52b50")
414 (hydra-disable)
415 (hydra-cleanup)
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:
420
421 \"\a\": `hydra-keyboard-quit',
422 \"j\": `next-line',
423 \"k\": `previous-line',
424 \"q\": `nil'
425
426 The body can be accessed via `hydra-vi/body'.
427
428 Call the head: `next-line'."
429 (interactive)
430 (set-cursor-color "#e52b50")
431 (hydra-disable)
432 (catch (quote hydra-disable)
433 (condition-case err (prog1 t (call-interactively (function next-line)))
434 ((quit error)
435 (message "%S" err)
436 (unless hydra-lv (sit-for 0.8))
437 nil))
438 (when hydra-is-helpful (hydra-vi/hint))
439 (setq hydra-last
440 (hydra-set-transient-map
441 (setq hydra-curr-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))
446 (hydra-vi/hint)))
447 (113 . hydra-vi/nil)
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:
477
478 \"\a\": `hydra-keyboard-quit',
479 \"j\": `next-line',
480 \"k\": `previous-line',
481 \"q\": `nil'
482
483 The body can be accessed via `hydra-vi/body'.
484
485 Call the head: `previous-line'."
486 (interactive)
487 (set-cursor-color "#e52b50")
488 (hydra-disable)
489 (catch (quote hydra-disable)
490 (condition-case err (prog1 t (call-interactively (function previous-line)))
491 ((quit error)
492 (message "%S" err)
493 (unless hydra-lv (sit-for 0.8))
494 nil))
495 (when hydra-is-helpful (hydra-vi/hint))
496 (setq hydra-last
497 (hydra-set-transient-map
498 (setq hydra-curr-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))
503 (hydra-vi/hint)))
504 (113 . hydra-vi/nil)
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:
534
535 \"\a\": `hydra-keyboard-quit',
536 \"j\": `next-line',
537 \"k\": `previous-line',
538 \"q\": `nil'
539
540 The body can be accessed via `hydra-vi/body'.
541
542 Call the head: `nil'."
543 (interactive)
544 (set-cursor-color "#e52b50")
545 (hydra-disable)
546 (hydra-cleanup)
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:
557
558 \"\a\": `hydra-keyboard-quit',
559 \"j\": `next-line',
560 \"k\": `previous-line',
561 \"q\": `nil'
562
563 The body can be accessed via `hydra-vi/body'."
564 (interactive)
565 (set-cursor-color "#e52b50")
566 (hydra-disable)
567 (catch (quote hydra-disable)
568 (when hydra-is-helpful (hydra-vi/hint))
569 (setq hydra-last
570 (hydra-set-transient-map
571 (setq hydra-curr-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))
576 (hydra-vi/hint)))
577 (113 . hydra-vi/nil)
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)))))))
607
608 (ert-deftest defhydradio ()
609 (should (equal
610 (macroexpand
611 '(defhydradio hydra-test ()
612 (num "Num" [0 1 2 3 4 5 6 7 8 9 10])
613 (str "Str" ["foo" "bar" "baz"])))
614 '(progn
615 (defvar hydra-test/num 0
616 "Num")
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"
621 "Str")
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))))))
626
627 (ert-deftest hydra-blue-compat ()
628 (should
629 (equal
630 (macroexpand
631 '(defhydra hydra-toggle (:color blue)
632 "toggle"
633 ("t" toggle-truncate-lines "truncate")
634 ("f" auto-fill-mode "fill")
635 ("a" abbrev-mode "abbrev")
636 ("q" nil "cancel")))
637 (macroexpand
638 '(defhydra hydra-toggle (:exit t)
639 "toggle"
640 ("t" toggle-truncate-lines "truncate")
641 ("f" auto-fill-mode "fill")
642 ("a" abbrev-mode "abbrev")
643 ("q" nil "cancel"))))))
644
645 (ert-deftest hydra-amaranth-compat ()
646 (should
647 (equal
648 (macroexpand
649 '(defhydra hydra-vi
650 (:pre
651 (set-cursor-color "#e52b50")
652 :post
653 (set-cursor-color "#ffffff")
654 :color amaranth)
655 "vi"
656 ("j" next-line)
657 ("k" previous-line)
658 ("q" nil "quit")))
659 (macroexpand
660 '(defhydra hydra-vi
661 (:pre
662 (set-cursor-color "#e52b50")
663 :post
664 (set-cursor-color "#ffffff")
665 :foreign-keys warn)
666 "vi"
667 ("j" next-line)
668 ("k" previous-line)
669 ("q" nil "quit"))))))
670
671 (ert-deftest hydra-pink-compat ()
672 (should
673 (equal
674 (macroexpand
675 '(defhydra hydra-zoom (global-map "<f2>"
676 :color pink)
677 "zoom"
678 ("g" text-scale-increase "in")
679 ("l" text-scale-decrease "out")
680 ("q" nil "quit")))
681 (macroexpand
682 '(defhydra hydra-zoom (global-map "<f2>"
683 :foreign-keys run)
684 "zoom"
685 ("g" text-scale-increase "in")
686 ("l" text-scale-decrease "out")
687 ("q" nil "quit"))))))
688
689 (ert-deftest hydra-teal-compat ()
690 (should
691 (equal
692 (macroexpand
693 '(defhydra hydra-zoom (global-map "<f2>"
694 :color teal)
695 "zoom"
696 ("g" text-scale-increase "in")
697 ("l" text-scale-decrease "out")
698 ("q" nil "quit")))
699 (macroexpand
700 '(defhydra hydra-zoom (global-map "<f2>"
701 :foreign-keys warn
702 :exit t)
703 "zoom"
704 ("g" text-scale-increase "in")
705 ("l" text-scale-decrease "out")
706 ("q" nil "quit"))))))
707
708 (ert-deftest hydra-format ()
709 (should (equal
710 (let ((hydra-fontify-head-function
711 'hydra-fontify-head-greyscale))
712 (hydra--format
713 'hydra-toggle
714 nil
715 "
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)
725 ("q" nil "quit"))))
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"))))
730
731 (ert-deftest hydra-format-with-sexp ()
732 (should (equal
733 (let ((hydra-fontify-head-function
734 'hydra-fontify-head-greyscale))
735 (hydra--format
736 'hydra-toggle nil
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"
740 "{n}"
741 (progn
742 (message "checking")
743 (buffer-narrowed-p)))
744 "[[q]]: cancel"))))
745
746 (ert-deftest hydra-compat-colors-1 ()
747 (should (equal (hydra--head-color
748 '("e" (message "Exiting now") "blue")
749 '(nil nil :color blue))
750 'blue))
751 (should (equal (hydra--head-color
752 '("c" (message "Continuing") "red" :color red)
753 '(nil nil :color blue))
754 'red))
755 (should (equal (hydra--head-color
756 '("e" (message "Exiting now") "blue")
757 '(nil nil :exit t))
758 'blue))
759 (should (equal (hydra--head-color
760 '("c" (message "Continuing") "red" :exit nil)
761 '(nil nil :exit t))
762 'red))
763 (equal (hydra--head-color
764 '("a" abbrev-mode nil)
765 '(nil nil :color teal))
766 'teal)
767 (equal (hydra--head-color
768 '("a" abbrev-mode :exit nil)
769 '(nil nil :color teal))
770 'amaranth))
771
772 (ert-deftest hydra-compat-colors-2 ()
773 (should
774 (equal
775 (macroexpand
776 '(defhydra hydra-test (:color amaranth)
777 ("a" fun-a)
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)))
783 (macroexpand
784 '(defhydra hydra-test (:color teal)
785 ("a" fun-a :color red)
786 ("b" fun-b)
787 ("c" fun-c)
788 ("d" fun-d)
789 ("e" fun-e)
790 ("f" fun-f))))))
791
792 (ert-deftest hydra-compat-colors-3 ()
793 (should
794 (equal
795 (macroexpand
796 '(defhydra hydra-test ()
797 ("a" fun-a)
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)))
803 (macroexpand
804 '(defhydra hydra-test (:color blue)
805 ("a" fun-a :color red)
806 ("b" fun-b)
807 ("c" fun-c)
808 ("d" fun-d)
809 ("e" fun-e)
810 ("f" fun-f))))))
811
812 (ert-deftest hydra-compat-colors-4 ()
813 (should
814 (equal
815 (macroexpand
816 '(defhydra hydra-test ()
817 ("a" fun-a)
818 ("b" fun-b :exit t)
819 ("c" fun-c :exit t)
820 ("d" fun-d :exit t)
821 ("e" fun-e :exit t)
822 ("f" fun-f :exit t)))
823 (macroexpand
824 '(defhydra hydra-test (:exit t)
825 ("a" fun-a :exit nil)
826 ("b" fun-b)
827 ("c" fun-c)
828 ("d" fun-d)
829 ("e" fun-e)
830 ("f" fun-f))))))
831
832 (ert-deftest hydra-zoom-duplicate-1 ()
833 (should
834 (equal
835 (macroexpand
836 '(defhydra hydra-zoom ()
837 "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)))
841 '(progn
842 (defun hydra-zoom/lambda-r nil "Create a hydra with no body and the heads:
843
844 \"r\": `(text-scale-set 0)',
845 \"0\": `(text-scale-set 0)',
846 \"1\": `(text-scale-set 0)'
847
848 The body can be accessed via `hydra-zoom/body'.
849
850 Call the head: `(text-scale-set 0)'."
851 (interactive)
852 (hydra-disable)
853 (catch (quote hydra-disable)
854 (condition-case err (prog1 t (call-interactively (function (lambda nil (interactive)
855 (text-scale-set 0)))))
856 ((quit error)
857 (message "%S" err)
858 (unless hydra-lv (sit-for 0.8))
859 nil))
860 (when hydra-is-helpful (hydra-zoom/hint))
861 (setq hydra-last
862 (hydra-set-transient-map
863 (setq hydra-curr-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:
892
893 \"r\": `(text-scale-set 0)',
894 \"0\": `(text-scale-set 0)',
895 \"1\": `(text-scale-set 0)'
896
897 The body can be accessed via `hydra-zoom/body'.
898
899 Call the head: `(text-scale-set 0)'."
900 (interactive)
901 (hydra-disable)
902 (hydra-cleanup)
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:
912
913 \"r\": `(text-scale-set 0)',
914 \"0\": `(text-scale-set 0)',
915 \"1\": `(text-scale-set 0)'
916
917 The body can be accessed via `hydra-zoom/body'."
918 (interactive)
919 (hydra-disable)
920 (catch (quote hydra-disable)
921 (when hydra-is-helpful (hydra-zoom/hint))
922 (setq hydra-last
923 (hydra-set-transient-map
924 (setq hydra-curr-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)))))))
953
954 (ert-deftest hydra-zoom-duplicate-2 ()
955 (should
956 (equal
957 (macroexpand
958 '(defhydra hydra-zoom ()
959 "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)))
963 '(progn
964 (defun hydra-zoom/lambda-r nil "Create a hydra with no body and the heads:
965
966 \"r\": `(text-scale-set 0)',
967 \"0\": `(text-scale-set 0)',
968 \"1\": `(text-scale-set 0)'
969
970 The body can be accessed via `hydra-zoom/body'.
971
972 Call the head: `(text-scale-set 0)'."
973 (interactive)
974 (hydra-disable)
975 (catch (quote hydra-disable)
976 (condition-case err (prog1 t (call-interactively (function (lambda nil (interactive)
977 (text-scale-set 0)))))
978 ((quit error)
979 (message "%S" err)
980 (unless hydra-lv (sit-for 0.8))
981 nil))
982 (when hydra-is-helpful (hydra-zoom/hint))
983 (setq hydra-last
984 (hydra-set-transient-map
985 (setq hydra-curr-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:
1014
1015 \"r\": `(text-scale-set 0)',
1016 \"0\": `(text-scale-set 0)',
1017 \"1\": `(text-scale-set 0)'
1018
1019 The body can be accessed via `hydra-zoom/body'.
1020
1021 Call the head: `(text-scale-set 0)'."
1022 (interactive)
1023 (hydra-disable)
1024 (hydra-cleanup)
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:
1034
1035 \"r\": `(text-scale-set 0)',
1036 \"0\": `(text-scale-set 0)',
1037 \"1\": `(text-scale-set 0)'
1038
1039 The body can be accessed via `hydra-zoom/body'."
1040 (interactive)
1041 (hydra-disable)
1042 (catch (quote hydra-disable)
1043 (when hydra-is-helpful (hydra-zoom/hint))
1044 (setq hydra-last
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)))))))
1075
1076 (ert-deftest hydra--pad ()
1077 (should (equal (hydra--pad '(a b c) 3)
1078 '(a b c)))
1079 (should (equal (hydra--pad '(a) 3)
1080 '(a nil nil))))
1081
1082 (ert-deftest hydra--matrix ()
1083 (should (equal (hydra--matrix '(a b c) 2 2)
1084 '((a b) (c nil))))
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)))))
1087
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")))
1092
1093 (ert-deftest hydra--vconcat ()
1094 (should (equal (hydra--vconcat '("abc\ndef" "012\n34" "def\nabc"))
1095 "abc012def\ndef34abc")))
1096
1097 (defhydradio hydra-tng ()
1098 (picard "_p_ Captain Jean Luc Picard:")
1099 (riker "_r_ Commander William Riker:")
1100 (data "_d_ Lieutenant Commander Data:")
1101 (worf "_w_ Worf:")
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]))
1106
1107 (ert-deftest hydra--table ()
1108 (let ((hydra-cell-format "% -30s %% -8`%s"))
1109 (should (equal (hydra--table hydra-tng/names 5 2)
1110 (substring "
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)
1117 (substring "
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)))))
1122
1123 (provide 'hydra-test)
1124
1125 ;;; hydra-test.el ends here