X-Git-Url: https://code.delx.au/gnu-emacs-elpa/blobdiff_plain/785e186ee6f4a2890e86fdf4e42d8082196e58d5..fddedd20a99a84be82c14bc76c63c56d2fb9b570:/packages/hydra/hydra-test.el diff --git a/packages/hydra/hydra-test.el b/packages/hydra/hydra-test.el index f2311ab17..ab41e82e6 100644 --- a/packages/hydra/hydra-test.el +++ b/packages/hydra/hydra-test.el @@ -25,6 +25,8 @@ ;;; Code: (require 'ert) +(require 'hydra) +(message "Emacs version: %s" emacs-version) (ert-deftest hydra-red-error () (should @@ -34,343 +36,460 @@ "error" ("h" first-error "first") ("j" next-error "next") - ("k" previous-error "prev"))) + ("k" previous-error "prev") + ("SPC" hydra-repeat "rep" :bind nil))) '(progn - (defun hydra-error/first-error nil "Create a hydra with a \"M-g\" body and the heads: + (set + (defvar hydra-error/keymap nil + "Keymap for hydra-error.") + (quote + (keymap + (32 . hydra-repeat) + (107 . hydra-error/previous-error) + (106 . hydra-error/next-error) + (104 . hydra-error/first-error) + (kp-subtract . hydra--negative-argument) + (kp-9 . hydra--digit-argument) + (kp-8 . hydra--digit-argument) + (kp-7 . hydra--digit-argument) + (kp-6 . hydra--digit-argument) + (kp-5 . hydra--digit-argument) + (kp-4 . hydra--digit-argument) + (kp-3 . hydra--digit-argument) + (kp-2 . hydra--digit-argument) + (kp-1 . hydra--digit-argument) + (kp-0 . hydra--digit-argument) + (57 . hydra--digit-argument) + (56 . hydra--digit-argument) + (55 . hydra--digit-argument) + (54 . hydra--digit-argument) + (53 . hydra--digit-argument) + (52 . hydra--digit-argument) + (51 . hydra--digit-argument) + (50 . hydra--digit-argument) + (49 . hydra--digit-argument) + (48 . hydra--digit-argument) + (45 . hydra--negative-argument) + (21 . hydra--universal-argument)))) + (set + (defvar hydra-error/heads nil + "Heads for hydra-error.") + (quote + (("h" + first-error + "first" + :exit nil) + ("j" + next-error + "next" + :exit nil) + ("k" + previous-error + "prev" + :exit nil) + ("SPC" + hydra-repeat + "rep" + :bind nil + :exit nil)))) + (set + (defvar hydra-error/hint nil + "Dynamic hint for hydra-error.") + (quote + (format + #("error: [h]: first, [j]: next, [k]: prev, [SPC]: rep." + 8 9 (face hydra-face-red) + 20 21 (face hydra-face-red) + 31 32 (face hydra-face-red) + 42 45 (face hydra-face-red))))) + (defun hydra-error/first-error nil + "Create a hydra with a \"M-g\" body and the heads: \"h\": `first-error', \"j\": `next-error', -\"k\": `previous-error' +\"k\": `previous-error', +\"SPC\": `hydra-repeat' The body can be accessed via `hydra-error/body'. Call the head: `first-error'." - (interactive) - (hydra-disable) - (catch (quote hydra-disable) - (condition-case err (prog1 t (call-interactively (function first-error))) - ((debug error) - (message "%S" err) - (sit-for 0.8) - nil)) - (when hydra-is-helpful (message #("error: [h]: first, [j]: next, [k]: prev." 8 9 (face hydra-face-red) - 20 21 (face hydra-face-red) - 31 32 (face hydra-face-red)))) - (setq hydra-last - (hydra-set-transient-map - (setq hydra-curr-map - (quote (keymap (107 . hydra-error/previous-error) - (106 . hydra-error/next-error) - (104 . hydra-error/first-error) - (kp-subtract . hydra--negative-argument) - (kp-9 . hydra--digit-argument) - (kp-8 . hydra--digit-argument) - (kp-7 . hydra--digit-argument) - (kp-6 . hydra--digit-argument) - (kp-5 . hydra--digit-argument) - (kp-4 . hydra--digit-argument) - (kp-3 . hydra--digit-argument) - (kp-2 . hydra--digit-argument) - (kp-1 . hydra--digit-argument) - (kp-0 . hydra--digit-argument) - (57 . hydra--digit-argument) - (56 . hydra--digit-argument) - (55 . hydra--digit-argument) - (54 . hydra--digit-argument) - (53 . hydra--digit-argument) - (52 . hydra--digit-argument) - (51 . hydra--digit-argument) - (50 . hydra--digit-argument) - (49 . hydra--digit-argument) - (48 . hydra--digit-argument) - (45 . hydra--negative-argument) - (21 . hydra--universal-argument)))) - t)))) - (defun hydra-error/next-error nil "Create a hydra with a \"M-g\" body and the heads: + (interactive) + (hydra-default-pre) + (let ((hydra--ignore t)) + (hydra-keyboard-quit)) + (condition-case err + (progn + (setq this-command + (quote first-error)) + (call-interactively + (function first-error))) + ((quit error) + (message "%S" err) + (unless hydra-lv (sit-for 0.8)))) + (when hydra-is-helpful + (if hydra-lv + (lv-message + (eval hydra-error/hint)) + (message + (eval hydra-error/hint)))) + (hydra-set-transient-map + hydra-error/keymap + (lambda nil + (hydra-keyboard-quit) + nil) + nil)) + (defun hydra-error/next-error nil + "Create a hydra with a \"M-g\" body and the heads: \"h\": `first-error', \"j\": `next-error', -\"k\": `previous-error' +\"k\": `previous-error', +\"SPC\": `hydra-repeat' The body can be accessed via `hydra-error/body'. Call the head: `next-error'." - (interactive) - (hydra-disable) - (catch (quote hydra-disable) - (condition-case err (prog1 t (call-interactively (function next-error))) - ((debug error) - (message "%S" err) - (sit-for 0.8) - nil)) - (when hydra-is-helpful (message #("error: [h]: first, [j]: next, [k]: prev." 8 9 (face hydra-face-red) - 20 21 (face hydra-face-red) - 31 32 (face hydra-face-red)))) - (setq hydra-last - (hydra-set-transient-map - (setq hydra-curr-map - (quote (keymap (107 . hydra-error/previous-error) - (106 . hydra-error/next-error) - (104 . hydra-error/first-error) - (kp-subtract . hydra--negative-argument) - (kp-9 . hydra--digit-argument) - (kp-8 . hydra--digit-argument) - (kp-7 . hydra--digit-argument) - (kp-6 . hydra--digit-argument) - (kp-5 . hydra--digit-argument) - (kp-4 . hydra--digit-argument) - (kp-3 . hydra--digit-argument) - (kp-2 . hydra--digit-argument) - (kp-1 . hydra--digit-argument) - (kp-0 . hydra--digit-argument) - (57 . hydra--digit-argument) - (56 . hydra--digit-argument) - (55 . hydra--digit-argument) - (54 . hydra--digit-argument) - (53 . hydra--digit-argument) - (52 . hydra--digit-argument) - (51 . hydra--digit-argument) - (50 . hydra--digit-argument) - (49 . hydra--digit-argument) - (48 . hydra--digit-argument) - (45 . hydra--negative-argument) - (21 . hydra--universal-argument)))) - t)))) - (defun hydra-error/previous-error nil "Create a hydra with a \"M-g\" body and the heads: + (interactive) + (hydra-default-pre) + (let ((hydra--ignore t)) + (hydra-keyboard-quit)) + (condition-case err + (progn + (setq this-command + (quote next-error)) + (call-interactively + (function next-error))) + ((quit error) + (message "%S" err) + (unless hydra-lv (sit-for 0.8)))) + (when hydra-is-helpful + (if hydra-lv + (lv-message + (eval hydra-error/hint)) + (message + (eval hydra-error/hint)))) + (hydra-set-transient-map + hydra-error/keymap + (lambda nil + (hydra-keyboard-quit) + nil) + nil)) + (defun hydra-error/previous-error nil + "Create a hydra with a \"M-g\" body and the heads: \"h\": `first-error', \"j\": `next-error', -\"k\": `previous-error' +\"k\": `previous-error', +\"SPC\": `hydra-repeat' The body can be accessed via `hydra-error/body'. Call the head: `previous-error'." - (interactive) - (hydra-disable) - (catch (quote hydra-disable) - (condition-case err (prog1 t (call-interactively (function previous-error))) - ((debug error) - (message "%S" err) - (sit-for 0.8) - nil)) - (when hydra-is-helpful (message #("error: [h]: first, [j]: next, [k]: prev." 8 9 (face hydra-face-red) - 20 21 (face hydra-face-red) - 31 32 (face hydra-face-red)))) - (setq hydra-last - (hydra-set-transient-map - (setq hydra-curr-map - (quote (keymap (107 . hydra-error/previous-error) - (106 . hydra-error/next-error) - (104 . hydra-error/first-error) - (kp-subtract . hydra--negative-argument) - (kp-9 . hydra--digit-argument) - (kp-8 . hydra--digit-argument) - (kp-7 . hydra--digit-argument) - (kp-6 . hydra--digit-argument) - (kp-5 . hydra--digit-argument) - (kp-4 . hydra--digit-argument) - (kp-3 . hydra--digit-argument) - (kp-2 . hydra--digit-argument) - (kp-1 . hydra--digit-argument) - (kp-0 . hydra--digit-argument) - (57 . hydra--digit-argument) - (56 . hydra--digit-argument) - (55 . hydra--digit-argument) - (54 . hydra--digit-argument) - (53 . hydra--digit-argument) - (52 . hydra--digit-argument) - (51 . hydra--digit-argument) - (50 . hydra--digit-argument) - (49 . hydra--digit-argument) - (48 . hydra--digit-argument) - (45 . hydra--negative-argument) - (21 . hydra--universal-argument)))) - t)))) - (unless (keymapp (lookup-key global-map (kbd "M-g"))) + (interactive) + (hydra-default-pre) + (let ((hydra--ignore t)) + (hydra-keyboard-quit)) + (condition-case err + (progn + (setq this-command + (quote previous-error)) + (call-interactively + (function previous-error))) + ((quit error) + (message "%S" err) + (unless hydra-lv (sit-for 0.8)))) + (when hydra-is-helpful + (if hydra-lv + (lv-message + (eval hydra-error/hint)) + (message + (eval hydra-error/hint)))) + (hydra-set-transient-map + hydra-error/keymap + (lambda nil + (hydra-keyboard-quit) + nil) + nil)) + (unless (keymapp + (lookup-key + global-map + (kbd "M-g"))) (define-key global-map (kbd "M-g") nil)) (define-key global-map [134217831 104] - (function hydra-error/first-error)) + (function + hydra-error/first-error)) (define-key global-map [134217831 106] - (function hydra-error/next-error)) + (function + hydra-error/next-error)) (define-key global-map [134217831 107] - (function hydra-error/previous-error)) - (defun hydra-error/body nil "Create a hydra with a \"M-g\" body and the heads: + (function + hydra-error/previous-error)) + (defun hydra-error/body nil + "Create a hydra with a \"M-g\" body and the heads: \"h\": `first-error', \"j\": `next-error', -\"k\": `previous-error' +\"k\": `previous-error', +\"SPC\": `hydra-repeat' The body can be accessed via `hydra-error/body'." - (interactive) - (hydra-disable) - (catch (quote hydra-disable) - (when hydra-is-helpful (message #("error: [h]: first, [j]: next, [k]: prev." 8 9 (face hydra-face-red) - 20 21 (face hydra-face-red) - 31 32 (face hydra-face-red)))) - (setq hydra-last - (hydra-set-transient-map - (setq hydra-curr-map - (quote (keymap (107 . hydra-error/previous-error) - (106 . hydra-error/next-error) - (104 . hydra-error/first-error) - (kp-subtract . hydra--negative-argument) - (kp-9 . hydra--digit-argument) - (kp-8 . hydra--digit-argument) - (kp-7 . hydra--digit-argument) - (kp-6 . hydra--digit-argument) - (kp-5 . hydra--digit-argument) - (kp-4 . hydra--digit-argument) - (kp-3 . hydra--digit-argument) - (kp-2 . hydra--digit-argument) - (kp-1 . hydra--digit-argument) - (kp-0 . hydra--digit-argument) - (57 . hydra--digit-argument) - (56 . hydra--digit-argument) - (55 . hydra--digit-argument) - (54 . hydra--digit-argument) - (53 . hydra--digit-argument) - (52 . hydra--digit-argument) - (51 . hydra--digit-argument) - (50 . hydra--digit-argument) - (49 . hydra--digit-argument) - (48 . hydra--digit-argument) - (45 . hydra--negative-argument) - (21 . hydra--universal-argument)))) - t)) - (setq prefix-arg current-prefix-arg))))))) + (interactive) + (hydra-default-pre) + (let ((hydra--ignore nil)) + (hydra-keyboard-quit)) + (when hydra-is-helpful + (if hydra-lv + (lv-message + (eval hydra-error/hint)) + (message + (eval hydra-error/hint)))) + (hydra-set-transient-map + hydra-error/keymap + (lambda nil + (hydra-keyboard-quit) + nil) + nil) + (setq prefix-arg + current-prefix-arg)))))) (ert-deftest hydra-blue-toggle () (should (equal (macroexpand - '(defhydra toggle (:color blue) + '(defhydra hydra-toggle (:color blue) "toggle" ("t" toggle-truncate-lines "truncate") ("f" auto-fill-mode "fill") ("a" abbrev-mode "abbrev") ("q" nil "cancel"))) '(progn - (defun toggle/toggle-truncate-lines nil "Create a hydra with no body and the heads: + (set + (defvar hydra-toggle/keymap nil + "Keymap for hydra-toggle.") + (quote + (keymap + (113 . hydra-toggle/nil) + (97 . hydra-toggle/abbrev-mode-and-exit) + (102 . hydra-toggle/auto-fill-mode-and-exit) + (116 . hydra-toggle/toggle-truncate-lines-and-exit) + (kp-subtract . hydra--negative-argument) + (kp-9 . hydra--digit-argument) + (kp-8 . hydra--digit-argument) + (kp-7 . hydra--digit-argument) + (kp-6 . hydra--digit-argument) + (kp-5 . hydra--digit-argument) + (kp-4 . hydra--digit-argument) + (kp-3 . hydra--digit-argument) + (kp-2 . hydra--digit-argument) + (kp-1 . hydra--digit-argument) + (kp-0 . hydra--digit-argument) + (57 . hydra--digit-argument) + (56 . hydra--digit-argument) + (55 . hydra--digit-argument) + (54 . hydra--digit-argument) + (53 . hydra--digit-argument) + (52 . hydra--digit-argument) + (51 . hydra--digit-argument) + (50 . hydra--digit-argument) + (49 . hydra--digit-argument) + (48 . hydra--digit-argument) + (45 . hydra--negative-argument) + (21 . hydra--universal-argument)))) + (set + (defvar hydra-toggle/heads nil + "Heads for hydra-toggle.") + (quote + (("t" + toggle-truncate-lines + "truncate" + :exit t) + ("f" + auto-fill-mode + "fill" + :exit t) + ("a" + abbrev-mode + "abbrev" + :exit t) + ("q" nil "cancel" :exit t)))) + (set + (defvar hydra-toggle/hint nil + "Dynamic hint for hydra-toggle.") + (quote + (format + #("toggle: [t]: truncate, [f]: fill, [a]: abbrev, [q]: cancel." + 9 10 (face hydra-face-blue) + 24 25 (face hydra-face-blue) + 35 36 (face hydra-face-blue) + 48 49 (face hydra-face-blue))))) + (defun hydra-toggle/toggle-truncate-lines-and-exit nil + "Create a hydra with no body and the heads: \"t\": `toggle-truncate-lines', \"f\": `auto-fill-mode', \"a\": `abbrev-mode', \"q\": `nil' -The body can be accessed via `toggle/body'. +The body can be accessed via `hydra-toggle/body'. Call the head: `toggle-truncate-lines'." - (interactive) - (hydra-disable) - (catch (quote hydra-disable) - (call-interactively (function toggle-truncate-lines)))) - (defun toggle/auto-fill-mode nil "Create a hydra with no body and the heads: + (interactive) + (hydra-default-pre) + (hydra-keyboard-quit) + (progn + (setq this-command + (quote toggle-truncate-lines)) + (call-interactively + (function + toggle-truncate-lines)))) + (defun hydra-toggle/auto-fill-mode-and-exit nil + "Create a hydra with no body and the heads: \"t\": `toggle-truncate-lines', \"f\": `auto-fill-mode', \"a\": `abbrev-mode', \"q\": `nil' -The body can be accessed via `toggle/body'. +The body can be accessed via `hydra-toggle/body'. Call the head: `auto-fill-mode'." - (interactive) - (hydra-disable) - (catch (quote hydra-disable) - (call-interactively (function auto-fill-mode)))) - (defun toggle/abbrev-mode nil "Create a hydra with no body and the heads: + (interactive) + (hydra-default-pre) + (hydra-keyboard-quit) + (progn + (setq this-command + (quote auto-fill-mode)) + (call-interactively + (function auto-fill-mode)))) + (defun hydra-toggle/abbrev-mode-and-exit nil + "Create a hydra with no body and the heads: \"t\": `toggle-truncate-lines', \"f\": `auto-fill-mode', \"a\": `abbrev-mode', \"q\": `nil' -The body can be accessed via `toggle/body'. +The body can be accessed via `hydra-toggle/body'. Call the head: `abbrev-mode'." - (interactive) - (hydra-disable) - (catch (quote hydra-disable) - (call-interactively (function abbrev-mode)))) - (defun toggle/nil nil "Create a hydra with no body and the heads: + (interactive) + (hydra-default-pre) + (hydra-keyboard-quit) + (progn + (setq this-command + (quote abbrev-mode)) + (call-interactively + (function abbrev-mode)))) + (defun hydra-toggle/nil nil + "Create a hydra with no body and the heads: \"t\": `toggle-truncate-lines', \"f\": `auto-fill-mode', \"a\": `abbrev-mode', \"q\": `nil' -The body can be accessed via `toggle/body'. +The body can be accessed via `hydra-toggle/body'. Call the head: `nil'." - (interactive) - (hydra-disable) - (catch (quote hydra-disable))) - (defun toggle/body nil "Create a hydra with no body and the heads: + (interactive) + (hydra-default-pre) + (hydra-keyboard-quit)) + (defun hydra-toggle/body nil + "Create a hydra with no body and the heads: \"t\": `toggle-truncate-lines', \"f\": `auto-fill-mode', \"a\": `abbrev-mode', \"q\": `nil' -The body can be accessed via `toggle/body'." - (interactive) - (hydra-disable) - (catch (quote hydra-disable) - (when hydra-is-helpful (message #("toggle: [t]: truncate, [f]: fill, [a]: abbrev, [q]: cancel." 9 10 (face hydra-face-blue) - 24 25 (face hydra-face-blue) - 35 36 (face hydra-face-blue) - 48 49 (face hydra-face-blue)))) - (setq hydra-last - (hydra-set-transient-map - (setq hydra-curr-map - (quote (keymap (113 . toggle/nil) - (97 . toggle/abbrev-mode) - (102 . toggle/auto-fill-mode) - (116 . toggle/toggle-truncate-lines) - (kp-subtract . hydra--negative-argument) - (kp-9 . hydra--digit-argument) - (kp-8 . hydra--digit-argument) - (kp-7 . hydra--digit-argument) - (kp-6 . hydra--digit-argument) - (kp-5 . hydra--digit-argument) - (kp-4 . hydra--digit-argument) - (kp-3 . hydra--digit-argument) - (kp-2 . hydra--digit-argument) - (kp-1 . hydra--digit-argument) - (kp-0 . hydra--digit-argument) - (57 . hydra--digit-argument) - (56 . hydra--digit-argument) - (55 . hydra--digit-argument) - (54 . hydra--digit-argument) - (53 . hydra--digit-argument) - (52 . hydra--digit-argument) - (51 . hydra--digit-argument) - (50 . hydra--digit-argument) - (49 . hydra--digit-argument) - (48 . hydra--digit-argument) - (45 . hydra--negative-argument) - (21 . hydra--universal-argument)))) - t)) - (setq prefix-arg current-prefix-arg))))))) +The body can be accessed via `hydra-toggle/body'." + (interactive) + (hydra-default-pre) + (let ((hydra--ignore nil)) + (hydra-keyboard-quit)) + (when hydra-is-helpful + (if hydra-lv + (lv-message + (eval hydra-toggle/hint)) + (message + (eval hydra-toggle/hint)))) + (hydra-set-transient-map + hydra-toggle/keymap + (lambda nil + (hydra-keyboard-quit) + nil) + nil) + (setq prefix-arg + current-prefix-arg)))))) (ert-deftest hydra-amaranth-vi () - (unless (version< emacs-version "24.4") - (should - (equal - (macroexpand - '(defhydra hydra-vi - (:pre - (set-cursor-color "#e52b50") - :post - (set-cursor-color "#ffffff") - :color amaranth) - "vi" - ("j" next-line) - ("k" previous-line) - ("q" nil "quit"))) - '(progn - (defun hydra-vi/next-line nil "Create a hydra with no body and the heads: + (should + (equal + (macroexpand + '(defhydra hydra-vi + (:pre + (set-cursor-color "#e52b50") + :post + (set-cursor-color "#ffffff") + :color amaranth) + "vi" + ("j" next-line) + ("k" previous-line) + ("q" nil "quit"))) + '(progn + (set + (defvar hydra-vi/keymap nil + "Keymap for hydra-vi.") + (quote + (keymap + (113 . hydra-vi/nil) + (107 . hydra-vi/previous-line) + (106 . hydra-vi/next-line) + (kp-subtract . hydra--negative-argument) + (kp-9 . hydra--digit-argument) + (kp-8 . hydra--digit-argument) + (kp-7 . hydra--digit-argument) + (kp-6 . hydra--digit-argument) + (kp-5 . hydra--digit-argument) + (kp-4 . hydra--digit-argument) + (kp-3 . hydra--digit-argument) + (kp-2 . hydra--digit-argument) + (kp-1 . hydra--digit-argument) + (kp-0 . hydra--digit-argument) + (57 . hydra--digit-argument) + (56 . hydra--digit-argument) + (55 . hydra--digit-argument) + (54 . hydra--digit-argument) + (53 . hydra--digit-argument) + (52 . hydra--digit-argument) + (51 . hydra--digit-argument) + (50 . hydra--digit-argument) + (49 . hydra--digit-argument) + (48 . hydra--digit-argument) + (45 . hydra--negative-argument) + (21 . hydra--universal-argument)))) + (set + (defvar hydra-vi/heads nil + "Heads for hydra-vi.") + (quote + (("j" next-line "" :exit nil) + ("k" + previous-line + "" + :exit nil) + ("q" nil "quit" :exit t)))) + (set + (defvar hydra-vi/hint nil + "Dynamic hint for hydra-vi.") + (quote + (format + #("vi: j, k, [q]: quit." + 4 5 (face hydra-face-amaranth) + 7 8 (face hydra-face-amaranth) + 11 12 (face hydra-face-teal))))) + (defun hydra-vi/next-line nil + "Create a hydra with no body and the heads: \"j\": `next-line', \"k\": `previous-line', @@ -379,59 +498,33 @@ The body can be accessed via `toggle/body'." The body can be accessed via `hydra-vi/body'. Call the head: `next-line'." - (interactive) - (set-cursor-color "#e52b50") - (hydra-disable) - (catch (quote hydra-disable) - (condition-case err (prog1 t (call-interactively (function next-line))) - ((debug error) - (message "%S" err) - (sit-for 0.8) - nil)) - (when hydra-is-helpful (message #("vi: j, k, [q]: quit." 4 5 (face hydra-face-amaranth) - 7 8 (face hydra-face-amaranth) - 11 12 (face hydra-face-blue)))) - (setq hydra-last - (hydra-set-transient-map - (setq hydra-curr-map - (quote (keymap (7 lambda nil (interactive) - (hydra-disable) - (set-cursor-color "#ffffff")) - (t lambda nil (interactive) - (message "An amaranth Hydra can only exit through a blue head") - (hydra-set-transient-map hydra-curr-map t) - (when hydra-is-helpful (sit-for 0.8) - (message #("vi: j, k, [q]: quit." 4 5 (face hydra-face-amaranth) - 7 8 (face hydra-face-amaranth) - 11 12 (face hydra-face-blue))))) - (113 . hydra-vi/nil) - (107 . hydra-vi/previous-line) - (106 . hydra-vi/next-line) - (kp-subtract . hydra--negative-argument) - (kp-9 . hydra--digit-argument) - (kp-8 . hydra--digit-argument) - (kp-7 . hydra--digit-argument) - (kp-6 . hydra--digit-argument) - (kp-5 . hydra--digit-argument) - (kp-4 . hydra--digit-argument) - (kp-3 . hydra--digit-argument) - (kp-2 . hydra--digit-argument) - (kp-1 . hydra--digit-argument) - (kp-0 . hydra--digit-argument) - (57 . hydra--digit-argument) - (56 . hydra--digit-argument) - (55 . hydra--digit-argument) - (54 . hydra--digit-argument) - (53 . hydra--digit-argument) - (52 . hydra--digit-argument) - (51 . hydra--digit-argument) - (50 . hydra--digit-argument) - (49 . hydra--digit-argument) - (48 . hydra--digit-argument) - (45 . hydra--negative-argument) - (21 . hydra--universal-argument)))) - t)))) - (defun hydra-vi/previous-line nil "Create a hydra with no body and the heads: + (interactive) + (hydra-default-pre) + (set-cursor-color "#e52b50") + (let ((hydra--ignore t)) + (hydra-keyboard-quit)) + (condition-case err + (progn + (setq this-command + (quote next-line)) + (call-interactively + (function next-line))) + ((quit error) + (message "%S" err) + (unless hydra-lv (sit-for 0.8)))) + (when hydra-is-helpful + (if hydra-lv + (lv-message + (eval hydra-vi/hint)) + (message (eval hydra-vi/hint)))) + (hydra-set-transient-map + hydra-vi/keymap + (lambda nil + (hydra-keyboard-quit) + (set-cursor-color "#ffffff")) + (quote warn))) + (defun hydra-vi/previous-line nil + "Create a hydra with no body and the heads: \"j\": `next-line', \"k\": `previous-line', @@ -440,59 +533,33 @@ Call the head: `next-line'." The body can be accessed via `hydra-vi/body'. Call the head: `previous-line'." - (interactive) - (set-cursor-color "#e52b50") - (hydra-disable) - (catch (quote hydra-disable) - (condition-case err (prog1 t (call-interactively (function previous-line))) - ((debug error) - (message "%S" err) - (sit-for 0.8) - nil)) - (when hydra-is-helpful (message #("vi: j, k, [q]: quit." 4 5 (face hydra-face-amaranth) - 7 8 (face hydra-face-amaranth) - 11 12 (face hydra-face-blue)))) - (setq hydra-last - (hydra-set-transient-map - (setq hydra-curr-map - (quote (keymap (7 lambda nil (interactive) - (hydra-disable) - (set-cursor-color "#ffffff")) - (t lambda nil (interactive) - (message "An amaranth Hydra can only exit through a blue head") - (hydra-set-transient-map hydra-curr-map t) - (when hydra-is-helpful (sit-for 0.8) - (message #("vi: j, k, [q]: quit." 4 5 (face hydra-face-amaranth) - 7 8 (face hydra-face-amaranth) - 11 12 (face hydra-face-blue))))) - (113 . hydra-vi/nil) - (107 . hydra-vi/previous-line) - (106 . hydra-vi/next-line) - (kp-subtract . hydra--negative-argument) - (kp-9 . hydra--digit-argument) - (kp-8 . hydra--digit-argument) - (kp-7 . hydra--digit-argument) - (kp-6 . hydra--digit-argument) - (kp-5 . hydra--digit-argument) - (kp-4 . hydra--digit-argument) - (kp-3 . hydra--digit-argument) - (kp-2 . hydra--digit-argument) - (kp-1 . hydra--digit-argument) - (kp-0 . hydra--digit-argument) - (57 . hydra--digit-argument) - (56 . hydra--digit-argument) - (55 . hydra--digit-argument) - (54 . hydra--digit-argument) - (53 . hydra--digit-argument) - (52 . hydra--digit-argument) - (51 . hydra--digit-argument) - (50 . hydra--digit-argument) - (49 . hydra--digit-argument) - (48 . hydra--digit-argument) - (45 . hydra--negative-argument) - (21 . hydra--universal-argument)))) - t)))) - (defun hydra-vi/nil nil "Create a hydra with no body and the heads: + (interactive) + (hydra-default-pre) + (set-cursor-color "#e52b50") + (let ((hydra--ignore t)) + (hydra-keyboard-quit)) + (condition-case err + (progn + (setq this-command + (quote previous-line)) + (call-interactively + (function previous-line))) + ((quit error) + (message "%S" err) + (unless hydra-lv (sit-for 0.8)))) + (when hydra-is-helpful + (if hydra-lv + (lv-message + (eval hydra-vi/hint)) + (message (eval hydra-vi/hint)))) + (hydra-set-transient-map + hydra-vi/keymap + (lambda nil + (hydra-keyboard-quit) + (set-cursor-color "#ffffff")) + (quote warn))) + (defun hydra-vi/nil nil + "Create a hydra with no body and the heads: \"j\": `next-line', \"k\": `previous-line', @@ -501,66 +568,710 @@ Call the head: `previous-line'." The body can be accessed via `hydra-vi/body'. Call the head: `nil'." - (interactive) - (set-cursor-color "#e52b50") - (hydra-disable) - (catch (quote hydra-disable) - (set-cursor-color "#ffffff"))) - (defun hydra-vi/body nil "Create a hydra with no body and the heads: + (interactive) + (hydra-default-pre) + (set-cursor-color "#e52b50") + (hydra-keyboard-quit)) + (defun hydra-vi/body nil + "Create a hydra with no body and the heads: \"j\": `next-line', \"k\": `previous-line', \"q\": `nil' The body can be accessed via `hydra-vi/body'." + (interactive) + (hydra-default-pre) + (set-cursor-color "#e52b50") + (let ((hydra--ignore nil)) + (hydra-keyboard-quit)) + (when hydra-is-helpful + (if hydra-lv + (lv-message + (eval hydra-vi/hint)) + (message (eval hydra-vi/hint)))) + (hydra-set-transient-map + hydra-vi/keymap + (lambda nil + (hydra-keyboard-quit) + (set-cursor-color "#ffffff")) + (quote warn)) + (setq prefix-arg + current-prefix-arg)))))) + +(ert-deftest hydra-zoom-duplicate-1 () + (should + (equal + (macroexpand + '(defhydra hydra-zoom () + "zoom" + ("r" (text-scale-set 0) "reset") + ("0" (text-scale-set 0) :bind nil :exit t) + ("1" (text-scale-set 0) nil :bind nil :exit t))) + '(progn + (set + (defvar hydra-zoom/keymap nil + "Keymap for hydra-zoom.") + (quote + (keymap + (114 . hydra-zoom/lambda-r) + (kp-subtract . hydra--negative-argument) + (kp-9 . hydra--digit-argument) + (kp-8 . hydra--digit-argument) + (kp-7 . hydra--digit-argument) + (kp-6 . hydra--digit-argument) + (kp-5 . hydra--digit-argument) + (kp-4 . hydra--digit-argument) + (kp-3 . hydra--digit-argument) + (kp-2 . hydra--digit-argument) + (kp-1 . hydra--digit-argument) + (kp-0 . hydra--digit-argument) + (57 . hydra--digit-argument) + (56 . hydra--digit-argument) + (55 . hydra--digit-argument) + (54 . hydra--digit-argument) + (53 . hydra--digit-argument) + (52 . hydra--digit-argument) + (51 . hydra--digit-argument) + (50 . hydra--digit-argument) + (49 . hydra-zoom/lambda-0-and-exit) + (48 . hydra-zoom/lambda-0-and-exit) + (45 . hydra--negative-argument) + (21 . hydra--universal-argument)))) + (set + (defvar hydra-zoom/heads nil + "Heads for hydra-zoom.") + (quote + (("r" + (text-scale-set 0) + "reset" + :exit nil) + ("0" + (text-scale-set 0) + "" + :bind nil + :exit t) + ("1" + (text-scale-set 0) + nil + :bind nil + :exit t)))) + (set + (defvar hydra-zoom/hint nil + "Dynamic hint for hydra-zoom.") + (quote + (format + #("zoom: [r 0]: reset." + 7 8 (face hydra-face-red) + 9 10 (face hydra-face-blue))))) + (defun hydra-zoom/lambda-r nil + "Create a hydra with no body and the heads: + +\"r\": `(text-scale-set 0)', +\"0\": `(text-scale-set 0)', +\"1\": `(text-scale-set 0)' + +The body can be accessed via `hydra-zoom/body'. + +Call the head: `(text-scale-set 0)'." + (interactive) + (hydra-default-pre) + (let ((hydra--ignore t)) + (hydra-keyboard-quit)) + (condition-case err + (call-interactively + (function + (lambda nil (interactive) - (set-cursor-color "#e52b50") - (hydra-disable) - (catch (quote hydra-disable) - (when hydra-is-helpful (message #("vi: j, k, [q]: quit." 4 5 (face hydra-face-amaranth) - 7 8 (face hydra-face-amaranth) - 11 12 (face hydra-face-blue)))) - (setq hydra-last - (hydra-set-transient-map - (setq hydra-curr-map - (quote (keymap (7 lambda nil (interactive) - (hydra-disable) - (set-cursor-color "#ffffff")) - (t lambda nil (interactive) - (message "An amaranth Hydra can only exit through a blue head") - (hydra-set-transient-map hydra-curr-map t) - (when hydra-is-helpful (sit-for 0.8) - (message #("vi: j, k, [q]: quit." 4 5 (face hydra-face-amaranth) - 7 8 (face hydra-face-amaranth) - 11 12 (face hydra-face-blue))))) - (113 . hydra-vi/nil) - (107 . hydra-vi/previous-line) - (106 . hydra-vi/next-line) - (kp-subtract . hydra--negative-argument) - (kp-9 . hydra--digit-argument) - (kp-8 . hydra--digit-argument) - (kp-7 . hydra--digit-argument) - (kp-6 . hydra--digit-argument) - (kp-5 . hydra--digit-argument) - (kp-4 . hydra--digit-argument) - (kp-3 . hydra--digit-argument) - (kp-2 . hydra--digit-argument) - (kp-1 . hydra--digit-argument) - (kp-0 . hydra--digit-argument) - (57 . hydra--digit-argument) - (56 . hydra--digit-argument) - (55 . hydra--digit-argument) - (54 . hydra--digit-argument) - (53 . hydra--digit-argument) - (52 . hydra--digit-argument) - (51 . hydra--digit-argument) - (50 . hydra--digit-argument) - (49 . hydra--digit-argument) - (48 . hydra--digit-argument) - (45 . hydra--negative-argument) - (21 . hydra--universal-argument)))) - t)) - (setq prefix-arg current-prefix-arg)))))))) + (text-scale-set 0)))) + ((quit error) + (message "%S" err) + (unless hydra-lv (sit-for 0.8)))) + (when hydra-is-helpful + (if hydra-lv + (lv-message + (eval hydra-zoom/hint)) + (message + (eval hydra-zoom/hint)))) + (hydra-set-transient-map + hydra-zoom/keymap + (lambda nil + (hydra-keyboard-quit) + nil) + nil)) + (defun hydra-zoom/lambda-0-and-exit nil + "Create a hydra with no body and the heads: + +\"r\": `(text-scale-set 0)', +\"0\": `(text-scale-set 0)', +\"1\": `(text-scale-set 0)' + +The body can be accessed via `hydra-zoom/body'. + +Call the head: `(text-scale-set 0)'." + (interactive) + (hydra-default-pre) + (hydra-keyboard-quit) + (call-interactively + (function + (lambda nil + (interactive) + (text-scale-set 0))))) + (defun hydra-zoom/body nil + "Create a hydra with no body and the heads: + +\"r\": `(text-scale-set 0)', +\"0\": `(text-scale-set 0)', +\"1\": `(text-scale-set 0)' + +The body can be accessed via `hydra-zoom/body'." + (interactive) + (hydra-default-pre) + (let ((hydra--ignore nil)) + (hydra-keyboard-quit)) + (when hydra-is-helpful + (if hydra-lv + (lv-message + (eval hydra-zoom/hint)) + (message + (eval hydra-zoom/hint)))) + (hydra-set-transient-map + hydra-zoom/keymap + (lambda nil + (hydra-keyboard-quit) + nil) + nil) + (setq prefix-arg + current-prefix-arg)))))) + +(ert-deftest hydra-zoom-duplicate-2 () + (should + (equal + (macroexpand + '(defhydra hydra-zoom () + "zoom" + ("r" (text-scale-set 0) "reset") + ("0" (text-scale-set 0) :bind nil :exit t) + ("1" (text-scale-set 0) nil :bind nil))) + '(progn + (set + (defvar hydra-zoom/keymap nil + "Keymap for hydra-zoom.") + (quote + (keymap + (114 . hydra-zoom/lambda-r) + (kp-subtract . hydra--negative-argument) + (kp-9 . hydra--digit-argument) + (kp-8 . hydra--digit-argument) + (kp-7 . hydra--digit-argument) + (kp-6 . hydra--digit-argument) + (kp-5 . hydra--digit-argument) + (kp-4 . hydra--digit-argument) + (kp-3 . hydra--digit-argument) + (kp-2 . hydra--digit-argument) + (kp-1 . hydra--digit-argument) + (kp-0 . hydra--digit-argument) + (57 . hydra--digit-argument) + (56 . hydra--digit-argument) + (55 . hydra--digit-argument) + (54 . hydra--digit-argument) + (53 . hydra--digit-argument) + (52 . hydra--digit-argument) + (51 . hydra--digit-argument) + (50 . hydra--digit-argument) + (49 . hydra-zoom/lambda-r) + (48 . hydra-zoom/lambda-0-and-exit) + (45 . hydra--negative-argument) + (21 . hydra--universal-argument)))) + (set + (defvar hydra-zoom/heads nil + "Heads for hydra-zoom.") + (quote + (("r" + (text-scale-set 0) + "reset" + :exit nil) + ("0" + (text-scale-set 0) + "" + :bind nil + :exit t) + ("1" + (text-scale-set 0) + nil + :bind nil + :exit nil)))) + (set + (defvar hydra-zoom/hint nil + "Dynamic hint for hydra-zoom.") + (quote + (format + #("zoom: [r 0]: reset." + 7 8 (face hydra-face-red) + 9 10 (face hydra-face-blue))))) + (defun hydra-zoom/lambda-r nil + "Create a hydra with no body and the heads: + +\"r\": `(text-scale-set 0)', +\"0\": `(text-scale-set 0)', +\"1\": `(text-scale-set 0)' + +The body can be accessed via `hydra-zoom/body'. + +Call the head: `(text-scale-set 0)'." + (interactive) + (hydra-default-pre) + (let ((hydra--ignore t)) + (hydra-keyboard-quit)) + (condition-case err + (call-interactively + (function + (lambda nil + (interactive) + (text-scale-set 0)))) + ((quit error) + (message "%S" err) + (unless hydra-lv (sit-for 0.8)))) + (when hydra-is-helpful + (if hydra-lv + (lv-message + (eval hydra-zoom/hint)) + (message + (eval hydra-zoom/hint)))) + (hydra-set-transient-map + hydra-zoom/keymap + (lambda nil + (hydra-keyboard-quit) + nil) + nil)) + (defun hydra-zoom/lambda-0-and-exit nil + "Create a hydra with no body and the heads: + +\"r\": `(text-scale-set 0)', +\"0\": `(text-scale-set 0)', +\"1\": `(text-scale-set 0)' + +The body can be accessed via `hydra-zoom/body'. + +Call the head: `(text-scale-set 0)'." + (interactive) + (hydra-default-pre) + (hydra-keyboard-quit) + (call-interactively + (function + (lambda nil + (interactive) + (text-scale-set 0))))) + (defun hydra-zoom/body nil + "Create a hydra with no body and the heads: + +\"r\": `(text-scale-set 0)', +\"0\": `(text-scale-set 0)', +\"1\": `(text-scale-set 0)' + +The body can be accessed via `hydra-zoom/body'." + (interactive) + (hydra-default-pre) + (let ((hydra--ignore nil)) + (hydra-keyboard-quit)) + (when hydra-is-helpful + (if hydra-lv + (lv-message + (eval hydra-zoom/hint)) + (message + (eval hydra-zoom/hint)))) + (hydra-set-transient-map + hydra-zoom/keymap + (lambda nil + (hydra-keyboard-quit) + nil) + nil) + (setq prefix-arg + current-prefix-arg)))))) + +(ert-deftest defhydradio () + (should (equal + (macroexpand + '(defhydradio hydra-test () + (num "Num" [0 1 2 3 4 5 6 7 8 9 10]) + (str "Str" ["foo" "bar" "baz"]))) + '(progn + (defvar hydra-test/num 0 + "Num") + (put 'hydra-test/num 'range [0 1 2 3 4 5 6 7 8 9 10]) + (defun hydra-test/num () + (hydra--cycle-radio 'hydra-test/num)) + (defvar hydra-test/str "foo" + "Str") + (put 'hydra-test/str 'range ["foo" "bar" "baz"]) + (defun hydra-test/str () + (hydra--cycle-radio 'hydra-test/str)) + (defvar hydra-test/names '(hydra-test/num hydra-test/str)))))) + +(ert-deftest hydra-blue-compat () + (should + (equal + (macroexpand + '(defhydra hydra-toggle (:color blue) + "toggle" + ("t" toggle-truncate-lines "truncate") + ("f" auto-fill-mode "fill") + ("a" abbrev-mode "abbrev") + ("q" nil "cancel"))) + (macroexpand + '(defhydra hydra-toggle (:exit t) + "toggle" + ("t" toggle-truncate-lines "truncate") + ("f" auto-fill-mode "fill") + ("a" abbrev-mode "abbrev") + ("q" nil "cancel")))))) + +(ert-deftest hydra-amaranth-compat () + (should + (equal + (macroexpand + '(defhydra hydra-vi + (:pre + (set-cursor-color "#e52b50") + :post + (set-cursor-color "#ffffff") + :color amaranth) + "vi" + ("j" next-line) + ("k" previous-line) + ("q" nil "quit"))) + (macroexpand + '(defhydra hydra-vi + (:pre + (set-cursor-color "#e52b50") + :post + (set-cursor-color "#ffffff") + :foreign-keys warn) + "vi" + ("j" next-line) + ("k" previous-line) + ("q" nil "quit")))))) + +(ert-deftest hydra-pink-compat () + (should + (equal + (macroexpand + '(defhydra hydra-zoom (global-map "" + :color pink) + "zoom" + ("g" text-scale-increase "in") + ("l" text-scale-decrease "out") + ("q" nil "quit"))) + (macroexpand + '(defhydra hydra-zoom (global-map "" + :foreign-keys run) + "zoom" + ("g" text-scale-increase "in") + ("l" text-scale-decrease "out") + ("q" nil "quit")))))) + +(ert-deftest hydra-teal-compat () + (should + (equal + (macroexpand + '(defhydra hydra-zoom (global-map "" + :color teal) + "zoom" + ("g" text-scale-increase "in") + ("l" text-scale-decrease "out") + ("q" nil "quit"))) + (macroexpand + '(defhydra hydra-zoom (global-map "" + :foreign-keys warn + :exit t) + "zoom" + ("g" text-scale-increase "in") + ("l" text-scale-decrease "out") + ("q" nil "quit")))))) + +(ert-deftest hydra-format-1 () + (should (equal + (let ((hydra-fontify-head-function + 'hydra-fontify-head-greyscale)) + (hydra--format + 'hydra-toggle + nil + " +_a_ abbrev-mode: %`abbrev-mode +_d_ debug-on-error: %`debug-on-error +_f_ auto-fill-mode: %`auto-fill-function +" '(("a" abbrev-mode nil) + ("d" toggle-debug-on-error nil) + ("f" auto-fill-mode nil) + ("g" golden-ratio-mode nil) + ("t" toggle-truncate-lines nil) + ("w" whitespace-mode nil) + ("q" nil "quit")))) + '(concat (format "%s abbrev-mode: %S +%s debug-on-error: %S +%s auto-fill-mode: %S +" "{a}" abbrev-mode "{d}" debug-on-error "{f}" auto-fill-function) "[{q}]: quit")))) + +(ert-deftest hydra-format-2 () + (should (equal + (let ((hydra-fontify-head-function + 'hydra-fontify-head-greyscale)) + (hydra--format + 'bar + nil + "\n bar %s`foo\n" + '(("a" (quote t) "" :cmd-name bar/lambda-a :exit nil) + ("q" nil "" :cmd-name bar/nil :exit t)))) + '(concat (format " bar %s\n" foo) "{a}, [q]")))) + +(ert-deftest hydra-format-3 () + (should (equal + (let ((hydra-fontify-head-function + 'hydra-fontify-head-greyscale)) + (hydra--format + 'bar + nil + "\n__ ^^ace jump\n" + '(("" ace-jump-char-mode nil :cmd-name bar/ace-jump-char-mode)))) + '(concat (format "%s ace jump\n" "{}") "")))) + +(ert-deftest hydra-format-4 () + (should + (equal (hydra--format + nil + '(nil nil :hint nil) + "\n_j_,_k_" + '(("j" nil nil :exit t) ("k" nil nil :exit t))) + '(concat (format "%s,%s" + #("j" 0 1 (face hydra-face-blue)) + #("k" 0 1 (face hydra-face-blue))) "")))) + +(ert-deftest hydra-format-5 () + (should + (equal (hydra--format + nil nil "\n_-_: mark _u_: unmark\n" + '(("-" Buffer-menu-mark) + ("u" Buffer-menu-unmark))) + '(concat + (format + "%s: mark %s: unmark\n" + #("-" 0 1 (face hydra-face-red)) + #("u" 0 1 (face hydra-face-red))) + "")))) + +(ert-deftest hydra-format-with-sexp-1 () + (should (equal + (let ((hydra-fontify-head-function + 'hydra-fontify-head-greyscale)) + (hydra--format + 'hydra-toggle nil + "\n_n_ narrow-or-widen-dwim %(progn (message \"checking\")(buffer-narrowed-p))asdf\n" + '(("n" narrow-to-region nil) ("q" nil "cancel" :exit t)))) + '(concat (format "%s narrow-or-widen-dwim %Sasdf\n" + "{n}" + (progn + (message "checking") + (buffer-narrowed-p))) + "[[q]]: cancel")))) + +(ert-deftest hydra-format-with-sexp-2 () + (should (equal + (let ((hydra-fontify-head-function + 'hydra-fontify-head-greyscale)) + (hydra--format + 'hydra-toggle nil + "\n_n_ narrow-or-widen-dwim %s(progn (message \"checking\")(buffer-narrowed-p))asdf\n" + '(("n" narrow-to-region nil) ("q" nil "cancel" :exit t)))) + '(concat (format "%s narrow-or-widen-dwim %sasdf\n" + "{n}" + (progn + (message "checking") + (buffer-narrowed-p))) + "[[q]]: cancel")))) + +(ert-deftest hydra-compat-colors-2 () + (should + (equal + (macroexpand + '(defhydra hydra-test (:color amaranth) + ("a" fun-a) + ("b" fun-b :color blue) + ("c" fun-c :color blue) + ("d" fun-d :color blue) + ("e" fun-e :color blue) + ("f" fun-f :color blue))) + (macroexpand + '(defhydra hydra-test (:color teal) + ("a" fun-a :color red) + ("b" fun-b) + ("c" fun-c) + ("d" fun-d) + ("e" fun-e) + ("f" fun-f)))))) + +(ert-deftest hydra-compat-colors-3 () + (should + (equal + (macroexpand + '(defhydra hydra-test () + ("a" fun-a) + ("b" fun-b :color blue) + ("c" fun-c :color blue) + ("d" fun-d :color blue) + ("e" fun-e :color blue) + ("f" fun-f :color blue))) + (macroexpand + '(defhydra hydra-test (:color blue) + ("a" fun-a :color red) + ("b" fun-b) + ("c" fun-c) + ("d" fun-d) + ("e" fun-e) + ("f" fun-f)))))) + +(ert-deftest hydra-compat-colors-4 () + (should + (equal + (macroexpand + '(defhydra hydra-test () + ("a" fun-a) + ("b" fun-b :exit t) + ("c" fun-c :exit t) + ("d" fun-d :exit t) + ("e" fun-e :exit t) + ("f" fun-f :exit t))) + (macroexpand + '(defhydra hydra-test (:exit t) + ("a" fun-a :exit nil) + ("b" fun-b) + ("c" fun-c) + ("d" fun-d) + ("e" fun-e) + ("f" fun-f)))))) + +(ert-deftest hydra--pad () + (should (equal (hydra--pad '(a b c) 3) + '(a b c))) + (should (equal (hydra--pad '(a) 3) + '(a nil nil)))) + +(ert-deftest hydra--matrix () + (should (equal (hydra--matrix '(a b c) 2 2) + '((a b) (c nil)))) + (should (equal (hydra--matrix '(a b c d e f g h i) 4 3) + '((a b c d) (e f g h) (i nil nil nil))))) + +(ert-deftest hydra--cell () + (should (equal (hydra--cell "% -75s %%`%s" '(hydra-lv hydra-verbose)) + "When non-nil, `lv-message' (not `message') will be used to display hints. %`hydra-lv^^^^^ +When non-nil, hydra will issue some non essential style warnings. %`hydra-verbose"))) + +(ert-deftest hydra--vconcat () + (should (equal (hydra--vconcat '("abc\ndef" "012\n34" "def\nabc")) + "abc012def\ndef34abc"))) + +(defhydradio hydra-tng () + (picard "_p_ Captain Jean Luc Picard:") + (riker "_r_ Commander William Riker:") + (data "_d_ Lieutenant Commander Data:") + (worf "_w_ Worf:") + (la-forge "_f_ Geordi La Forge:") + (troi "_t_ Deanna Troi:") + (dr-crusher "_c_ Doctor Beverly Crusher:") + (phaser "_h_ Set phasers to " [stun kill])) + +(ert-deftest hydra--table () + (let ((hydra-cell-format "% -30s %% -8`%s")) + (should (equal (hydra--table hydra-tng/names 5 2) + (substring " +_p_ Captain Jean Luc Picard: % -8`hydra-tng/picard^^ _t_ Deanna Troi: % -8`hydra-tng/troi^^^^^^ +_r_ Commander William Riker: % -8`hydra-tng/riker^^^ _c_ Doctor Beverly Crusher: % -8`hydra-tng/dr-crusher +_d_ Lieutenant Commander Data: % -8`hydra-tng/data^^^^ _h_ Set phasers to % -8`hydra-tng/phaser^^^^ +_w_ Worf: % -8`hydra-tng/worf^^^^ +_f_ Geordi La Forge: % -8`hydra-tng/la-forge" 1))) + (should (equal (hydra--table hydra-tng/names 4 3) + (substring " +_p_ Captain Jean Luc Picard: % -8`hydra-tng/picard _f_ Geordi La Forge: % -8`hydra-tng/la-forge^^ +_r_ Commander William Riker: % -8`hydra-tng/riker^ _t_ Deanna Troi: % -8`hydra-tng/troi^^^^^^ +_d_ Lieutenant Commander Data: % -8`hydra-tng/data^^ _c_ Doctor Beverly Crusher: % -8`hydra-tng/dr-crusher +_w_ Worf: % -8`hydra-tng/worf^^ _h_ Set phasers to % -8`hydra-tng/phaser^^^^" 1))))) + +(ert-deftest hydra--make-funcall () + (should (equal (let ((body-pre 'foo)) + (hydra--make-funcall body-pre) + body-pre) + '(funcall (function foo))))) + +(defhydra hydra-simple-1 (global-map "C-c") + ("a" (insert "j")) + ("b" (insert "k")) + ("q" nil)) + +(defhydra hydra-simple-2 (global-map "C-c" :color amaranth) + ("c" self-insert-command) + ("d" self-insert-command) + ("q" nil)) + +(defhydra hydra-simple-3 (global-map "C-c") + ("g" goto-line) + ("1" find-file) + ("q" nil)) + +(defmacro hydra-with (in &rest body) + `(let ((temp-buffer (generate-new-buffer " *temp*"))) + (save-window-excursion + (unwind-protect + (progn + (switch-to-buffer temp-buffer) + (transient-mark-mode 1) + (insert ,in) + (goto-char (point-min)) + (when (search-forward "~" nil t) + (backward-delete-char 1) + (set-mark (point))) + (goto-char (point-max)) + (search-backward "|") + (delete-char 1) + (setq current-prefix-arg) + ,@body + (insert "|") + (when (region-active-p) + (exchange-point-and-mark) + (insert "~")) + (buffer-substring-no-properties + (point-min) + (point-max))) + (and (buffer-name temp-buffer) + (kill-buffer temp-buffer)))))) + +(ert-deftest hydra-integration-1 () + (should (string= (hydra-with "|" + (execute-kbd-macro + (kbd "C-c aabbaaqaabbaa"))) + "jjkkjjaabbaa|")) + (should (string= (hydra-with "|" + (condition-case nil + (execute-kbd-macro + (kbd "C-c aabb C-g")) + (quit nil)) + (execute-kbd-macro "aaqaabbaa")) + "jjkkaaqaabbaa|"))) + +(ert-deftest hydra-integration-2 () + (should (string= (hydra-with "|" + (execute-kbd-macro + (kbd "C-c c 1 c 2 d 4 c q"))) + "ccddcccc|")) + (should (string= (hydra-with "|" + (execute-kbd-macro + (kbd "C-c c 1 c C-u d C-u 10 c q"))) + "ccddddcccccccccc|"))) + +(ert-deftest hydra-integration-3 () + (should (string= (hydra-with "foo\nbar|" + (execute-kbd-macro + (kbd "C-c g 1 RET q"))) + "|foo\nbar"))) (provide 'hydra-test)