]> code.delx.au - gnu-emacs-elpa/blob - packages/hydra/hydra-test.el
Merge commit '243c680396edc99db85cc3152a7bbf020aa7a233' from ace-window
[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 (kp-subtract . hydra--negative-argument)
68 (kp-9 . hydra--digit-argument)
69 (kp-8 . hydra--digit-argument)
70 (kp-7 . hydra--digit-argument)
71 (kp-6 . hydra--digit-argument)
72 (kp-5 . hydra--digit-argument)
73 (kp-4 . hydra--digit-argument)
74 (kp-3 . hydra--digit-argument)
75 (kp-2 . hydra--digit-argument)
76 (kp-1 . hydra--digit-argument)
77 (kp-0 . hydra--digit-argument)
78 (57 . hydra--digit-argument)
79 (56 . hydra--digit-argument)
80 (55 . hydra--digit-argument)
81 (54 . hydra--digit-argument)
82 (53 . hydra--digit-argument)
83 (52 . hydra--digit-argument)
84 (51 . hydra--digit-argument)
85 (50 . hydra--digit-argument)
86 (49 . hydra--digit-argument)
87 (48 . hydra--digit-argument)
88 (45 . hydra--negative-argument)
89 (21 . hydra--universal-argument))))
90 t (lambda nil (hydra-cleanup))))))
91 (defun hydra-error/next-error nil "Create a hydra with a \"M-g\" body and the heads:
92
93 \"h\": `first-error',
94 \"j\": `next-error',
95 \"k\": `previous-error',
96 \"SPC\": `hydra-repeat'
97
98 The body can be accessed via `hydra-error/body'.
99
100 Call the head: `next-error'."
101 (interactive)
102 (hydra-disable)
103 (catch (quote hydra-disable)
104 (condition-case err (prog1 t (call-interactively (function next-error)))
105 ((quit error)
106 (message "%S" err)
107 (unless hydra-lv (sit-for 0.8))
108 nil))
109 (when hydra-is-helpful (hydra-error/hint))
110 (setq hydra-last
111 (hydra-set-transient-map
112 (setq hydra-curr-map
113 (quote (keymap (7 . hydra-keyboard-quit)
114 (32 . hydra-repeat)
115 (107 . hydra-error/previous-error)
116 (106 . hydra-error/next-error)
117 (104 . hydra-error/first-error)
118 (kp-subtract . hydra--negative-argument)
119 (kp-9 . hydra--digit-argument)
120 (kp-8 . hydra--digit-argument)
121 (kp-7 . hydra--digit-argument)
122 (kp-6 . hydra--digit-argument)
123 (kp-5 . hydra--digit-argument)
124 (kp-4 . hydra--digit-argument)
125 (kp-3 . hydra--digit-argument)
126 (kp-2 . hydra--digit-argument)
127 (kp-1 . hydra--digit-argument)
128 (kp-0 . hydra--digit-argument)
129 (57 . hydra--digit-argument)
130 (56 . hydra--digit-argument)
131 (55 . hydra--digit-argument)
132 (54 . hydra--digit-argument)
133 (53 . hydra--digit-argument)
134 (52 . hydra--digit-argument)
135 (51 . hydra--digit-argument)
136 (50 . hydra--digit-argument)
137 (49 . hydra--digit-argument)
138 (48 . hydra--digit-argument)
139 (45 . hydra--negative-argument)
140 (21 . hydra--universal-argument))))
141 t (lambda nil (hydra-cleanup))))))
142 (defun hydra-error/previous-error nil "Create a hydra with a \"M-g\" body and the heads:
143
144 \"h\": `first-error',
145 \"j\": `next-error',
146 \"k\": `previous-error',
147 \"SPC\": `hydra-repeat'
148
149 The body can be accessed via `hydra-error/body'.
150
151 Call the head: `previous-error'."
152 (interactive)
153 (hydra-disable)
154 (catch (quote hydra-disable)
155 (condition-case err (prog1 t (call-interactively (function previous-error)))
156 ((quit error)
157 (message "%S" err)
158 (unless hydra-lv (sit-for 0.8))
159 nil))
160 (when hydra-is-helpful (hydra-error/hint))
161 (setq hydra-last
162 (hydra-set-transient-map
163 (setq hydra-curr-map
164 (quote (keymap (7 . hydra-keyboard-quit)
165 (32 . hydra-repeat)
166 (107 . hydra-error/previous-error)
167 (106 . hydra-error/next-error)
168 (104 . hydra-error/first-error)
169 (kp-subtract . hydra--negative-argument)
170 (kp-9 . hydra--digit-argument)
171 (kp-8 . hydra--digit-argument)
172 (kp-7 . hydra--digit-argument)
173 (kp-6 . hydra--digit-argument)
174 (kp-5 . hydra--digit-argument)
175 (kp-4 . hydra--digit-argument)
176 (kp-3 . hydra--digit-argument)
177 (kp-2 . hydra--digit-argument)
178 (kp-1 . hydra--digit-argument)
179 (kp-0 . hydra--digit-argument)
180 (57 . hydra--digit-argument)
181 (56 . hydra--digit-argument)
182 (55 . hydra--digit-argument)
183 (54 . hydra--digit-argument)
184 (53 . hydra--digit-argument)
185 (52 . hydra--digit-argument)
186 (51 . hydra--digit-argument)
187 (50 . hydra--digit-argument)
188 (49 . hydra--digit-argument)
189 (48 . hydra--digit-argument)
190 (45 . hydra--negative-argument)
191 (21 . hydra--universal-argument))))
192 t (lambda nil (hydra-cleanup))))))
193 (unless (keymapp (lookup-key global-map (kbd "M-g")))
194 (define-key global-map (kbd "M-g")
195 nil))
196 (define-key global-map [134217831 104]
197 (function hydra-error/first-error))
198 (define-key global-map [134217831 106]
199 (function hydra-error/next-error))
200 (define-key global-map [134217831 107]
201 (function hydra-error/previous-error))
202 (defun hydra-error/hint nil
203 (if hydra-lv (lv-message (format #("error: [h]: first, [j]: next, [k]: prev, [SPC]: rep." 8 9 (face hydra-face-red)
204 20 21 (face hydra-face-red)
205 31 32 (face hydra-face-red)
206 42 45 (face hydra-face-red))))
207 (message (format #("error: [h]: first, [j]: next, [k]: prev, [SPC]: rep." 8 9 (face hydra-face-red)
208 20 21 (face hydra-face-red)
209 31 32 (face hydra-face-red)
210 42 45 (face hydra-face-red))))))
211 (defun hydra-error/body nil "Create a hydra with a \"M-g\" body and the heads:
212
213 \"h\": `first-error',
214 \"j\": `next-error',
215 \"k\": `previous-error',
216 \"SPC\": `hydra-repeat'
217
218 The body can be accessed via `hydra-error/body'."
219 (interactive)
220 (hydra-disable)
221 (catch (quote hydra-disable)
222 (when hydra-is-helpful (hydra-error/hint))
223 (setq hydra-last
224 (hydra-set-transient-map
225 (setq hydra-curr-map
226 (quote
227 (keymap (7 . hydra-keyboard-quit)
228 (32 . hydra-repeat)
229 (107 . hydra-error/previous-error)
230 (106 . hydra-error/next-error)
231 (104 . hydra-error/first-error)
232 (kp-subtract . hydra--negative-argument)
233 (kp-9 . hydra--digit-argument)
234 (kp-8 . hydra--digit-argument)
235 (kp-7 . hydra--digit-argument)
236 (kp-6 . hydra--digit-argument)
237 (kp-5 . hydra--digit-argument)
238 (kp-4 . hydra--digit-argument)
239 (kp-3 . hydra--digit-argument)
240 (kp-2 . hydra--digit-argument)
241 (kp-1 . hydra--digit-argument)
242 (kp-0 . hydra--digit-argument)
243 (57 . hydra--digit-argument)
244 (56 . hydra--digit-argument)
245 (55 . hydra--digit-argument)
246 (54 . hydra--digit-argument)
247 (53 . hydra--digit-argument)
248 (52 . hydra--digit-argument)
249 (51 . hydra--digit-argument)
250 (50 . hydra--digit-argument)
251 (49 . hydra--digit-argument)
252 (48 . hydra--digit-argument)
253 (45 . hydra--negative-argument)
254 (21 . hydra--universal-argument))))
255 t (lambda nil (hydra-cleanup))))
256 (setq prefix-arg current-prefix-arg)))))))
257
258 (ert-deftest hydra-blue-toggle ()
259 (should
260 (equal
261 (macroexpand
262 '(defhydra hydra-toggle (:color blue)
263 "toggle"
264 ("t" toggle-truncate-lines "truncate")
265 ("f" auto-fill-mode "fill")
266 ("a" abbrev-mode "abbrev")
267 ("q" nil "cancel")))
268 '(progn
269 (defun hydra-toggle/toggle-truncate-lines nil "Create a hydra with no body and the heads:
270
271 \"t\": `toggle-truncate-lines',
272 \"f\": `auto-fill-mode',
273 \"a\": `abbrev-mode',
274 \"q\": `nil'
275
276 The body can be accessed via `hydra-toggle/body'.
277
278 Call the head: `toggle-truncate-lines'."
279 (interactive)
280 (hydra-disable)
281 (hydra-cleanup)
282 (catch (quote hydra-disable)
283 (call-interactively (function toggle-truncate-lines))))
284 (defun hydra-toggle/auto-fill-mode nil "Create a hydra with no body and the heads:
285
286 \"t\": `toggle-truncate-lines',
287 \"f\": `auto-fill-mode',
288 \"a\": `abbrev-mode',
289 \"q\": `nil'
290
291 The body can be accessed via `hydra-toggle/body'.
292
293 Call the head: `auto-fill-mode'."
294 (interactive)
295 (hydra-disable)
296 (hydra-cleanup)
297 (catch (quote hydra-disable)
298 (call-interactively (function auto-fill-mode))))
299 (defun hydra-toggle/abbrev-mode nil "Create a hydra with no body and the heads:
300
301 \"t\": `toggle-truncate-lines',
302 \"f\": `auto-fill-mode',
303 \"a\": `abbrev-mode',
304 \"q\": `nil'
305
306 The body can be accessed via `hydra-toggle/body'.
307
308 Call the head: `abbrev-mode'."
309 (interactive)
310 (hydra-disable)
311 (hydra-cleanup)
312 (catch (quote hydra-disable)
313 (call-interactively (function abbrev-mode))))
314 (defun hydra-toggle/nil nil "Create a hydra with no body and the heads:
315
316 \"t\": `toggle-truncate-lines',
317 \"f\": `auto-fill-mode',
318 \"a\": `abbrev-mode',
319 \"q\": `nil'
320
321 The body can be accessed via `hydra-toggle/body'.
322
323 Call the head: `nil'."
324 (interactive)
325 (hydra-disable)
326 (hydra-cleanup)
327 (catch (quote hydra-disable)))
328 (defun hydra-toggle/hint nil
329 (if hydra-lv (lv-message (format #("toggle: [t]: truncate, [f]: fill, [a]: abbrev, [q]: cancel." 9 10 (face hydra-face-blue)
330 24 25 (face hydra-face-blue)
331 35 36 (face hydra-face-blue)
332 48 49 (face hydra-face-blue))))
333 (message (format #("toggle: [t]: truncate, [f]: fill, [a]: abbrev, [q]: cancel." 9 10 (face hydra-face-blue)
334 24 25 (face hydra-face-blue)
335 35 36 (face hydra-face-blue)
336 48 49 (face hydra-face-blue))))))
337 (defun hydra-toggle/body nil "Create a hydra with no body and the heads:
338
339 \"t\": `toggle-truncate-lines',
340 \"f\": `auto-fill-mode',
341 \"a\": `abbrev-mode',
342 \"q\": `nil'
343
344 The body can be accessed via `hydra-toggle/body'."
345 (interactive)
346 (hydra-disable)
347 (catch (quote hydra-disable)
348 (when hydra-is-helpful (hydra-toggle/hint))
349 (setq hydra-last
350 (hydra-set-transient-map
351 (setq hydra-curr-map
352 (quote
353 (keymap (7 . hydra-keyboard-quit)
354 (113 . hydra-toggle/nil)
355 (97 . hydra-toggle/abbrev-mode)
356 (102 . hydra-toggle/auto-fill-mode)
357 (116 . hydra-toggle/toggle-truncate-lines)
358 (kp-subtract . hydra--negative-argument)
359 (kp-9 . hydra--digit-argument)
360 (kp-8 . hydra--digit-argument)
361 (kp-7 . hydra--digit-argument)
362 (kp-6 . hydra--digit-argument)
363 (kp-5 . hydra--digit-argument)
364 (kp-4 . hydra--digit-argument)
365 (kp-3 . hydra--digit-argument)
366 (kp-2 . hydra--digit-argument)
367 (kp-1 . hydra--digit-argument)
368 (kp-0 . hydra--digit-argument)
369 (57 . hydra--digit-argument)
370 (56 . hydra--digit-argument)
371 (55 . hydra--digit-argument)
372 (54 . hydra--digit-argument)
373 (53 . hydra--digit-argument)
374 (52 . hydra--digit-argument)
375 (51 . hydra--digit-argument)
376 (50 . hydra--digit-argument)
377 (49 . hydra--digit-argument)
378 (48 . hydra--digit-argument)
379 (45 . hydra--negative-argument)
380 (21 . hydra--universal-argument))))
381 t (lambda nil (hydra-cleanup))))
382 (setq prefix-arg current-prefix-arg)))))))
383
384 (ert-deftest hydra-amaranth-vi ()
385 (should
386 (equal
387 (macroexpand
388 '(defhydra hydra-vi
389 (:pre
390 (set-cursor-color "#e52b50")
391 :post
392 (set-cursor-color "#ffffff")
393 :color amaranth)
394 "vi"
395 ("j" next-line)
396 ("k" previous-line)
397 ("q" nil "quit")))
398 '(progn
399 (defun hydra-vi/next-line nil "Create a hydra with no body and the heads:
400
401 \"j\": `next-line',
402 \"k\": `previous-line',
403 \"q\": `nil'
404
405 The body can be accessed via `hydra-vi/body'.
406
407 Call the head: `next-line'."
408 (interactive)
409 (set-cursor-color "#e52b50")
410 (hydra-disable)
411 (catch (quote hydra-disable)
412 (condition-case err (prog1 t (call-interactively (function next-line)))
413 ((quit error) (message "%S" err)
414 (unless hydra-lv (sit-for 0.8))
415 nil))
416 (when hydra-is-helpful (hydra-vi/hint))
417 (setq hydra-last
418 (hydra-set-transient-map
419 (setq hydra-curr-map
420 (quote
421 (keymap (t lambda nil (interactive)
422 (message "An amaranth Hydra can only exit through a blue head")
423 (hydra-set-transient-map hydra-curr-map t)
424 (when hydra-is-helpful (unless hydra-lv (sit-for 0.8))
425 (hydra-vi/hint)))
426 (7 . hydra-keyboard-quit)
427 (113 . hydra-vi/nil)
428 (107 . hydra-vi/previous-line)
429 (106 . hydra-vi/next-line)
430 (kp-subtract . hydra--negative-argument)
431 (kp-9 . hydra--digit-argument)
432 (kp-8 . hydra--digit-argument)
433 (kp-7 . hydra--digit-argument)
434 (kp-6 . hydra--digit-argument)
435 (kp-5 . hydra--digit-argument)
436 (kp-4 . hydra--digit-argument)
437 (kp-3 . hydra--digit-argument)
438 (kp-2 . hydra--digit-argument)
439 (kp-1 . hydra--digit-argument)
440 (kp-0 . hydra--digit-argument)
441 (57 . hydra--digit-argument)
442 (56 . hydra--digit-argument)
443 (55 . hydra--digit-argument)
444 (54 . hydra--digit-argument)
445 (53 . hydra--digit-argument)
446 (52 . hydra--digit-argument)
447 (51 . hydra--digit-argument)
448 (50 . hydra--digit-argument)
449 (49 . hydra--digit-argument)
450 (48 . hydra--digit-argument)
451 (45 . hydra--negative-argument)
452 (21 . hydra--universal-argument))))
453 t (lambda nil (hydra-cleanup))))))
454 (defun hydra-vi/previous-line nil "Create a hydra with no body and the heads:
455
456 \"j\": `next-line',
457 \"k\": `previous-line',
458 \"q\": `nil'
459
460 The body can be accessed via `hydra-vi/body'.
461
462 Call the head: `previous-line'."
463 (interactive)
464 (set-cursor-color "#e52b50")
465 (hydra-disable)
466 (catch (quote hydra-disable)
467 (condition-case err (prog1 t (call-interactively (function previous-line)))
468 ((quit error) (message "%S" err)
469 (unless hydra-lv (sit-for 0.8))
470 nil))
471 (when hydra-is-helpful (hydra-vi/hint))
472 (setq hydra-last
473 (hydra-set-transient-map
474 (setq hydra-curr-map
475 (quote
476 (keymap (t lambda nil (interactive)
477 (message "An amaranth Hydra can only exit through a blue head")
478 (hydra-set-transient-map hydra-curr-map t)
479 (when hydra-is-helpful (unless hydra-lv (sit-for 0.8))
480 (hydra-vi/hint)))
481 (7 . hydra-keyboard-quit)
482 (113 . hydra-vi/nil)
483 (107 . hydra-vi/previous-line)
484 (106 . hydra-vi/next-line)
485 (kp-subtract . hydra--negative-argument)
486 (kp-9 . hydra--digit-argument)
487 (kp-8 . hydra--digit-argument)
488 (kp-7 . hydra--digit-argument)
489 (kp-6 . hydra--digit-argument)
490 (kp-5 . hydra--digit-argument)
491 (kp-4 . hydra--digit-argument)
492 (kp-3 . hydra--digit-argument)
493 (kp-2 . hydra--digit-argument)
494 (kp-1 . hydra--digit-argument)
495 (kp-0 . hydra--digit-argument)
496 (57 . hydra--digit-argument)
497 (56 . hydra--digit-argument)
498 (55 . hydra--digit-argument)
499 (54 . hydra--digit-argument)
500 (53 . hydra--digit-argument)
501 (52 . hydra--digit-argument)
502 (51 . hydra--digit-argument)
503 (50 . hydra--digit-argument)
504 (49 . hydra--digit-argument)
505 (48 . hydra--digit-argument)
506 (45 . hydra--negative-argument)
507 (21 . hydra--universal-argument))))
508 t (lambda nil (hydra-cleanup))))))
509 (defun hydra-vi/nil nil "Create a hydra with no body and the heads:
510
511 \"j\": `next-line',
512 \"k\": `previous-line',
513 \"q\": `nil'
514
515 The body can be accessed via `hydra-vi/body'.
516
517 Call the head: `nil'."
518 (interactive)
519 (set-cursor-color "#e52b50")
520 (hydra-disable)
521 (hydra-cleanup)
522 (catch (quote hydra-disable)
523 (set-cursor-color "#ffffff")))
524 (defun hydra-vi/hint nil
525 (if hydra-lv (lv-message (format #("vi: j, k, [q]: quit." 4 5 (face hydra-face-amaranth)
526 7 8 (face hydra-face-amaranth)
527 11 12 (face hydra-face-blue))))
528 (message (format #("vi: j, k, [q]: quit." 4 5 (face hydra-face-amaranth)
529 7 8 (face hydra-face-amaranth)
530 11 12 (face hydra-face-blue))))))
531 (defun hydra-vi/body nil "Create a hydra with no body and the heads:
532
533 \"j\": `next-line',
534 \"k\": `previous-line',
535 \"q\": `nil'
536
537 The body can be accessed via `hydra-vi/body'."
538 (interactive)
539 (set-cursor-color "#e52b50")
540 (hydra-disable)
541 (catch (quote hydra-disable)
542 (when hydra-is-helpful (hydra-vi/hint))
543 (setq hydra-last
544 (hydra-set-transient-map
545 (setq hydra-curr-map
546 (quote
547 (keymap (t lambda nil (interactive)
548 (message "An amaranth Hydra can only exit through a blue head")
549 (hydra-set-transient-map hydra-curr-map t)
550 (when hydra-is-helpful (unless hydra-lv (sit-for 0.8))
551 (hydra-vi/hint)))
552 (7 . hydra-keyboard-quit)
553 (113 . hydra-vi/nil)
554 (107 . hydra-vi/previous-line)
555 (106 . hydra-vi/next-line)
556 (kp-subtract . hydra--negative-argument)
557 (kp-9 . hydra--digit-argument)
558 (kp-8 . hydra--digit-argument)
559 (kp-7 . hydra--digit-argument)
560 (kp-6 . hydra--digit-argument)
561 (kp-5 . hydra--digit-argument)
562 (kp-4 . hydra--digit-argument)
563 (kp-3 . hydra--digit-argument)
564 (kp-2 . hydra--digit-argument)
565 (kp-1 . hydra--digit-argument)
566 (kp-0 . hydra--digit-argument)
567 (57 . hydra--digit-argument)
568 (56 . hydra--digit-argument)
569 (55 . hydra--digit-argument)
570 (54 . hydra--digit-argument)
571 (53 . hydra--digit-argument)
572 (52 . hydra--digit-argument)
573 (51 . hydra--digit-argument)
574 (50 . hydra--digit-argument)
575 (49 . hydra--digit-argument)
576 (48 . hydra--digit-argument)
577 (45 . hydra--negative-argument)
578 (21 . hydra--universal-argument))))
579 t (lambda nil (hydra-cleanup))))
580 (setq prefix-arg current-prefix-arg)))))))
581
582 (ert-deftest defhydradio ()
583 (should (equal
584 (macroexpand
585 '(defhydradio hydra-test ()
586 (num "Num" [0 1 2 3 4 5 6 7 8 9 10])
587 (str "Str" ["foo" "bar" "baz"])))
588 '(progn
589 (defvar hydra-test/num 0
590 "Num")
591 (put 'hydra-test/num 'range [0 1 2 3 4 5 6 7 8 9 10])
592 (defun hydra-test/num ()
593 (hydra--cycle-radio 'hydra-test/num))
594 (defvar hydra-test/str "foo"
595 "Str")
596 (put 'hydra-test/str 'range ["foo" "bar" "baz"])
597 (defun hydra-test/str ()
598 (hydra--cycle-radio 'hydra-test/str))
599 (defvar hydra-test/names '(hydra-test/num hydra-test/str))))))
600
601 (ert-deftest hydra-blue-compat ()
602 (should
603 (equal
604 (macroexpand
605 '(defhydra hydra-toggle (:color blue)
606 "toggle"
607 ("t" toggle-truncate-lines "truncate")
608 ("f" auto-fill-mode "fill")
609 ("a" abbrev-mode "abbrev")
610 ("q" nil "cancel")))
611 (macroexpand
612 '(defhydra hydra-toggle (:exit t)
613 "toggle"
614 ("t" toggle-truncate-lines "truncate")
615 ("f" auto-fill-mode "fill")
616 ("a" abbrev-mode "abbrev")
617 ("q" nil "cancel"))))))
618
619 (ert-deftest hydra-amaranth-compat ()
620 (should
621 (equal
622 (macroexpand
623 '(defhydra hydra-vi
624 (:pre
625 (set-cursor-color "#e52b50")
626 :post
627 (set-cursor-color "#ffffff")
628 :color amaranth)
629 "vi"
630 ("j" next-line)
631 ("k" previous-line)
632 ("q" nil "quit")))
633 (macroexpand
634 '(defhydra hydra-vi
635 (:pre
636 (set-cursor-color "#e52b50")
637 :post
638 (set-cursor-color "#ffffff")
639 :foreign-keys warn)
640 "vi"
641 ("j" next-line)
642 ("k" previous-line)
643 ("q" nil "quit"))))))
644
645 (ert-deftest hydra-pink-compat ()
646 (should
647 (equal
648 (macroexpand
649 '(defhydra hydra-zoom (global-map "<f2>"
650 :color pink)
651 "zoom"
652 ("g" text-scale-increase "in")
653 ("l" text-scale-decrease "out")
654 ("q" nil "quit")))
655 (macroexpand
656 '(defhydra hydra-zoom (global-map "<f2>"
657 :foreign-keys run)
658 "zoom"
659 ("g" text-scale-increase "in")
660 ("l" text-scale-decrease "out")
661 ("q" nil "quit"))))))
662
663 (ert-deftest hydra-teal-compat ()
664 (should
665 (equal
666 (macroexpand
667 '(defhydra hydra-zoom (global-map "<f2>"
668 :color teal)
669 "zoom"
670 ("g" text-scale-increase "in")
671 ("l" text-scale-decrease "out")
672 ("q" nil "quit")))
673 (macroexpand
674 '(defhydra hydra-zoom (global-map "<f2>"
675 :foreign-keys warn
676 :exit t)
677 "zoom"
678 ("g" text-scale-increase "in")
679 ("l" text-scale-decrease "out")
680 ("q" nil "quit"))))))
681
682 (ert-deftest hydra-format ()
683 (should (equal
684 (let ((hydra-fontify-head-function
685 'hydra-fontify-head-greyscale))
686 (hydra--format
687 'hydra-toggle
688 nil
689 "
690 _a_ abbrev-mode: %`abbrev-mode
691 _d_ debug-on-error: %`debug-on-error
692 _f_ auto-fill-mode: %`auto-fill-function
693 " '(("a" abbrev-mode nil)
694 ("d" toggle-debug-on-error nil)
695 ("f" auto-fill-mode nil)
696 ("g" golden-ratio-mode nil)
697 ("t" toggle-truncate-lines nil)
698 ("w" whitespace-mode nil)
699 ("q" nil "quit"))))
700 '(concat (format "%s abbrev-mode: %S
701 %s debug-on-error: %S
702 %s auto-fill-mode: %S
703 " "{a}" abbrev-mode "{d}" debug-on-error "{f}" auto-fill-function) "[[q]]: quit"))))
704
705 (ert-deftest hydra-format-with-sexp ()
706 (should (equal
707 (let ((hydra-fontify-head-function
708 'hydra-fontify-head-greyscale))
709 (hydra--format
710 'hydra-toggle nil
711 "\n_n_ narrow-or-widen-dwim %(progn (message \"checking\")(buffer-narrowed-p))asdf\n"
712 '(("n" narrow-to-region nil) ("q" nil "cancel"))))
713 '(concat (format "%s narrow-or-widen-dwim %Sasdf\n"
714 "{n}"
715 (progn
716 (message "checking")
717 (buffer-narrowed-p)))
718 "[[q]]: cancel"))))
719
720 (ert-deftest hydra-compat-colors-1 ()
721 (should (equal (hydra--head-color
722 '("e" (message "Exiting now") "blue")
723 '(nil nil :color blue))
724 'blue))
725 (should (equal (hydra--head-color
726 '("c" (message "Continuing") "red" :color red)
727 '(nil nil :color blue))
728 'red))
729 (should (equal (hydra--head-color
730 '("e" (message "Exiting now") "blue")
731 '(nil nil :exit t))
732 'blue))
733 (should (equal (hydra--head-color
734 '("c" (message "Continuing") "red" :exit nil)
735 '(nil nil :exit t))
736 'red))
737 (equal (hydra--head-color
738 '("a" abbrev-mode nil)
739 '(nil nil :color teal))
740 'teal)
741 (equal (hydra--head-color
742 '("a" abbrev-mode :exit nil)
743 '(nil nil :color teal))
744 'amaranth))
745
746 (ert-deftest hydra-compat-colors-2 ()
747 (should
748 (equal
749 (macroexpand
750 '(defhydra hydra-test (:color amaranth)
751 ("a" fun-a)
752 ("b" fun-b :color blue)
753 ("c" fun-c :color blue)
754 ("d" fun-d :color blue)
755 ("e" fun-e :color blue)
756 ("f" fun-f :color blue)))
757 (macroexpand
758 '(defhydra hydra-test (:color teal)
759 ("a" fun-a :color red)
760 ("b" fun-b)
761 ("c" fun-c)
762 ("d" fun-d)
763 ("e" fun-e)
764 ("f" fun-f))))))
765
766 (ert-deftest hydra-compat-colors-3 ()
767 (should
768 (equal
769 (macroexpand
770 '(defhydra hydra-test ()
771 ("a" fun-a)
772 ("b" fun-b :color blue)
773 ("c" fun-c :color blue)
774 ("d" fun-d :color blue)
775 ("e" fun-e :color blue)
776 ("f" fun-f :color blue)))
777 (macroexpand
778 '(defhydra hydra-test (:color blue)
779 ("a" fun-a :color red)
780 ("b" fun-b)
781 ("c" fun-c)
782 ("d" fun-d)
783 ("e" fun-e)
784 ("f" fun-f))))))
785
786 (ert-deftest hydra-compat-colors-4 ()
787 (should
788 (equal
789 (macroexpand
790 '(defhydra hydra-test ()
791 ("a" fun-a)
792 ("b" fun-b :exit t)
793 ("c" fun-c :exit t)
794 ("d" fun-d :exit t)
795 ("e" fun-e :exit t)
796 ("f" fun-f :exit t)))
797 (macroexpand
798 '(defhydra hydra-test (:exit t)
799 ("a" fun-a :exit nil)
800 ("b" fun-b)
801 ("c" fun-c)
802 ("d" fun-d)
803 ("e" fun-e)
804 ("f" fun-f))))))
805
806 (ert-deftest hydra-zoom-duplicate-1 ()
807 (should
808 (equal
809 (macroexpand
810 '(defhydra hydra-zoom ()
811 "zoom"
812 ("r" (text-scale-set 0) "reset")
813 ("0" (text-scale-set 0) :bind nil :exit t)
814 ("1" (text-scale-set 0) nil :bind nil :exit t)))
815 '(progn
816 (defun hydra-zoom/lambda-r nil "Create a hydra with no body and the heads:
817
818 \"r\": `(text-scale-set 0)',
819 \"0\": `(text-scale-set 0)',
820 \"1\": `(text-scale-set 0)'
821
822 The body can be accessed via `hydra-zoom/body'.
823
824 Call the head: `(text-scale-set 0)'."
825 (interactive)
826 (hydra-disable)
827 (catch (quote hydra-disable)
828 (condition-case err (prog1 t (call-interactively (function (lambda nil (interactive)
829 (text-scale-set 0)))))
830 ((quit error)
831 (message "%S" err)
832 (unless hydra-lv (sit-for 0.8))
833 nil))
834 (when hydra-is-helpful (hydra-zoom/hint))
835 (setq hydra-last
836 (hydra-set-transient-map
837 (setq hydra-curr-map
838 (quote (keymap (7 . hydra-keyboard-quit)
839 (114 . hydra-zoom/lambda-r)
840 (kp-subtract . hydra--negative-argument)
841 (kp-9 . hydra--digit-argument)
842 (kp-8 . hydra--digit-argument)
843 (kp-7 . hydra--digit-argument)
844 (kp-6 . hydra--digit-argument)
845 (kp-5 . hydra--digit-argument)
846 (kp-4 . hydra--digit-argument)
847 (kp-3 . hydra--digit-argument)
848 (kp-2 . hydra--digit-argument)
849 (kp-1 . hydra--digit-argument)
850 (kp-0 . hydra--digit-argument)
851 (57 . hydra--digit-argument)
852 (56 . hydra--digit-argument)
853 (55 . hydra--digit-argument)
854 (54 . hydra--digit-argument)
855 (53 . hydra--digit-argument)
856 (52 . hydra--digit-argument)
857 (51 . hydra--digit-argument)
858 (50 . hydra--digit-argument)
859 (49 . hydra-zoom/lambda-0)
860 (48 . hydra-zoom/lambda-0)
861 (45 . hydra--negative-argument)
862 (21 . hydra--universal-argument))))
863 t (lambda nil (hydra-cleanup))))))
864 (defun hydra-zoom/lambda-0 nil "Create a hydra with no body and the heads:
865
866 \"r\": `(text-scale-set 0)',
867 \"0\": `(text-scale-set 0)',
868 \"1\": `(text-scale-set 0)'
869
870 The body can be accessed via `hydra-zoom/body'.
871
872 Call the head: `(text-scale-set 0)'."
873 (interactive)
874 (hydra-disable)
875 (hydra-cleanup)
876 (catch (quote hydra-disable)
877 (call-interactively (function (lambda nil (interactive)
878 (text-scale-set 0))))))
879 (defun hydra-zoom/hint nil
880 (if hydra-lv (lv-message (format #("zoom: [r 0]: reset." 7 8 (face hydra-face-red)
881 9 10 (face hydra-face-blue))))
882 (message (format #("zoom: [r 0]: reset." 7 8 (face hydra-face-red)
883 9 10 (face hydra-face-blue))))))
884 (defun hydra-zoom/body nil "Create a hydra with no body and the heads:
885
886 \"r\": `(text-scale-set 0)',
887 \"0\": `(text-scale-set 0)',
888 \"1\": `(text-scale-set 0)'
889
890 The body can be accessed via `hydra-zoom/body'."
891 (interactive)
892 (hydra-disable)
893 (catch (quote hydra-disable)
894 (when hydra-is-helpful (hydra-zoom/hint))
895 (setq hydra-last
896 (hydra-set-transient-map
897 (setq hydra-curr-map
898 (quote (keymap (7 . hydra-keyboard-quit)
899 (114 . hydra-zoom/lambda-r)
900 (kp-subtract . hydra--negative-argument)
901 (kp-9 . hydra--digit-argument)
902 (kp-8 . hydra--digit-argument)
903 (kp-7 . hydra--digit-argument)
904 (kp-6 . hydra--digit-argument)
905 (kp-5 . hydra--digit-argument)
906 (kp-4 . hydra--digit-argument)
907 (kp-3 . hydra--digit-argument)
908 (kp-2 . hydra--digit-argument)
909 (kp-1 . hydra--digit-argument)
910 (kp-0 . hydra--digit-argument)
911 (57 . hydra--digit-argument)
912 (56 . hydra--digit-argument)
913 (55 . hydra--digit-argument)
914 (54 . hydra--digit-argument)
915 (53 . hydra--digit-argument)
916 (52 . hydra--digit-argument)
917 (51 . hydra--digit-argument)
918 (50 . hydra--digit-argument)
919 (49 . hydra-zoom/lambda-0)
920 (48 . hydra-zoom/lambda-0)
921 (45 . hydra--negative-argument)
922 (21 . hydra--universal-argument))))
923 t (lambda nil (hydra-cleanup))))
924 (setq prefix-arg current-prefix-arg)))))))
925
926 (ert-deftest hydra-zoom-duplicate-2 ()
927 (should
928 (equal
929 (macroexpand
930 '(defhydra hydra-zoom ()
931 "zoom"
932 ("r" (text-scale-set 0) "reset")
933 ("0" (text-scale-set 0) :bind nil :exit t)
934 ("1" (text-scale-set 0) nil :bind nil)))
935 '(progn
936 (defun hydra-zoom/lambda-r nil "Create a hydra with no body and the heads:
937
938 \"r\": `(text-scale-set 0)',
939 \"0\": `(text-scale-set 0)',
940 \"1\": `(text-scale-set 0)'
941
942 The body can be accessed via `hydra-zoom/body'.
943
944 Call the head: `(text-scale-set 0)'."
945 (interactive)
946 (hydra-disable)
947 (catch (quote hydra-disable)
948 (condition-case err (prog1 t (call-interactively (function (lambda nil (interactive)
949 (text-scale-set 0)))))
950 ((quit error)
951 (message "%S" err)
952 (unless hydra-lv (sit-for 0.8))
953 nil))
954 (when hydra-is-helpful (hydra-zoom/hint))
955 (setq hydra-last
956 (hydra-set-transient-map
957 (setq hydra-curr-map
958 (quote (keymap (7 . hydra-keyboard-quit)
959 (114 . hydra-zoom/lambda-r)
960 (kp-subtract . hydra--negative-argument)
961 (kp-9 . hydra--digit-argument)
962 (kp-8 . hydra--digit-argument)
963 (kp-7 . hydra--digit-argument)
964 (kp-6 . hydra--digit-argument)
965 (kp-5 . hydra--digit-argument)
966 (kp-4 . hydra--digit-argument)
967 (kp-3 . hydra--digit-argument)
968 (kp-2 . hydra--digit-argument)
969 (kp-1 . hydra--digit-argument)
970 (kp-0 . hydra--digit-argument)
971 (57 . hydra--digit-argument)
972 (56 . hydra--digit-argument)
973 (55 . hydra--digit-argument)
974 (54 . hydra--digit-argument)
975 (53 . hydra--digit-argument)
976 (52 . hydra--digit-argument)
977 (51 . hydra--digit-argument)
978 (50 . hydra--digit-argument)
979 (49 . hydra-zoom/lambda-r)
980 (48 . hydra-zoom/lambda-0)
981 (45 . hydra--negative-argument)
982 (21 . hydra--universal-argument))))
983 t (lambda nil (hydra-cleanup))))))
984 (defun hydra-zoom/lambda-0 nil "Create a hydra with no body and the heads:
985
986 \"r\": `(text-scale-set 0)',
987 \"0\": `(text-scale-set 0)',
988 \"1\": `(text-scale-set 0)'
989
990 The body can be accessed via `hydra-zoom/body'.
991
992 Call the head: `(text-scale-set 0)'."
993 (interactive)
994 (hydra-disable)
995 (hydra-cleanup)
996 (catch (quote hydra-disable)
997 (call-interactively (function (lambda nil (interactive)
998 (text-scale-set 0))))))
999 (defun hydra-zoom/hint nil
1000 (if hydra-lv (lv-message (format #("zoom: [r 0]: reset." 7 8 (face hydra-face-red)
1001 9 10 (face hydra-face-blue))))
1002 (message (format #("zoom: [r 0]: reset." 7 8 (face hydra-face-red)
1003 9 10 (face hydra-face-blue))))))
1004 (defun hydra-zoom/body nil "Create a hydra with no body and the heads:
1005
1006 \"r\": `(text-scale-set 0)',
1007 \"0\": `(text-scale-set 0)',
1008 \"1\": `(text-scale-set 0)'
1009
1010 The body can be accessed via `hydra-zoom/body'."
1011 (interactive)
1012 (hydra-disable)
1013 (catch (quote hydra-disable)
1014 (when hydra-is-helpful (hydra-zoom/hint))
1015 (setq hydra-last
1016 (hydra-set-transient-map
1017 (setq hydra-curr-map
1018 (quote (keymap (7 . hydra-keyboard-quit)
1019 (114 . hydra-zoom/lambda-r)
1020 (kp-subtract . hydra--negative-argument)
1021 (kp-9 . hydra--digit-argument)
1022 (kp-8 . hydra--digit-argument)
1023 (kp-7 . hydra--digit-argument)
1024 (kp-6 . hydra--digit-argument)
1025 (kp-5 . hydra--digit-argument)
1026 (kp-4 . hydra--digit-argument)
1027 (kp-3 . hydra--digit-argument)
1028 (kp-2 . hydra--digit-argument)
1029 (kp-1 . hydra--digit-argument)
1030 (kp-0 . hydra--digit-argument)
1031 (57 . hydra--digit-argument)
1032 (56 . hydra--digit-argument)
1033 (55 . hydra--digit-argument)
1034 (54 . hydra--digit-argument)
1035 (53 . hydra--digit-argument)
1036 (52 . hydra--digit-argument)
1037 (51 . hydra--digit-argument)
1038 (50 . hydra--digit-argument)
1039 (49 . hydra-zoom/lambda-r)
1040 (48 . hydra-zoom/lambda-0)
1041 (45 . hydra--negative-argument)
1042 (21 . hydra--universal-argument))))
1043 t (lambda nil (hydra-cleanup))))
1044 (setq prefix-arg current-prefix-arg)))))))
1045
1046 (ert-deftest hydra--pad ()
1047 (should (equal (hydra--pad '(a b c) 3)
1048 '(a b c)))
1049 (should (equal (hydra--pad '(a) 3)
1050 '(a nil nil))))
1051
1052 (ert-deftest hydra--matrix ()
1053 (should (equal (hydra--matrix '(a b c) 2 2)
1054 '((a b) (c nil))))
1055 (should (equal (hydra--matrix '(a b c d e f g h i) 4 3)
1056 '((a b c d) (e f g h) (i nil nil nil)))))
1057
1058 (ert-deftest hydra--cell ()
1059 (should (equal (hydra--cell "% -75s %%`%s" '(hydra-lv hydra-verbose))
1060 "When non-nil, `lv-message' (not `message') will be used to display hints. %`hydra-lv^^^^^
1061 When non-nil, hydra will issue some non essential style warnings. %`hydra-verbose")))
1062
1063 (ert-deftest hydra--vconcat ()
1064 (should (equal (hydra--vconcat '("abc\ndef" "012\n34" "def\nabc"))
1065 "abc012def\ndef34abc")))
1066
1067 (defhydradio hydra-tng ()
1068 (picard "_p_ Captain Jean Luc Picard:")
1069 (riker "_r_ Commander William Riker:")
1070 (data "_d_ Lieutenant Commander Data:")
1071 (worf "_w_ Worf:")
1072 (la-forge "_f_ Geordi La Forge:")
1073 (troi "_t_ Deanna Troi:")
1074 (dr-crusher "_c_ Doctor Beverly Crusher:")
1075 (phaser "_h_ Set phasers to " [stun kill]))
1076
1077 (ert-deftest hydra--table ()
1078 (let ((hydra-cell-format "% -30s %% -8`%s"))
1079 (should (equal (hydra--table hydra-tng/names 5 2)
1080 (substring "
1081 _p_ Captain Jean Luc Picard: % -8`hydra-tng/picard^^ _t_ Deanna Troi: % -8`hydra-tng/troi^^^^^^
1082 _r_ Commander William Riker: % -8`hydra-tng/riker^^^ _c_ Doctor Beverly Crusher: % -8`hydra-tng/dr-crusher
1083 _d_ Lieutenant Commander Data: % -8`hydra-tng/data^^^^ _h_ Set phasers to % -8`hydra-tng/phaser^^^^
1084 _w_ Worf: % -8`hydra-tng/worf^^^^
1085 _f_ Geordi La Forge: % -8`hydra-tng/la-forge" 1)))
1086 (should (equal (hydra--table hydra-tng/names 4 3)
1087 (substring "
1088 _p_ Captain Jean Luc Picard: % -8`hydra-tng/picard _f_ Geordi La Forge: % -8`hydra-tng/la-forge^^
1089 _r_ Commander William Riker: % -8`hydra-tng/riker^ _t_ Deanna Troi: % -8`hydra-tng/troi^^^^^^
1090 _d_ Lieutenant Commander Data: % -8`hydra-tng/data^^ _c_ Doctor Beverly Crusher: % -8`hydra-tng/dr-crusher
1091 _w_ Worf: % -8`hydra-tng/worf^^ _h_ Set phasers to % -8`hydra-tng/phaser^^^^" 1)))))
1092
1093 (provide 'hydra-test)
1094
1095 ;;; hydra-test.el ends here