branch: master commit c8c6b8c7fc1367922236df16f53e338418378239 Author: Oleh Krehel <ohwoeo...@gmail.com> Commit: Oleh Krehel <ohwoeo...@gmail.com>
Fix blue/red heads with same cmd * hydra.el (hydra--make-defun): Update. (hydra--head-name): Change signature, since body is needed to determine the color. When the head will exit, add "-and-exit" to its name (except for the nil head and body). (defhydra): Update the call to `hydra--head-name', since it's not valid until the head has a hint. * hydra-test.el (hydra-blue-toggle): Update. (hydra-amaranth-vi): Update. (hydra-zoom-duplicate-1): Update. (hydra-zoom-duplicate-2): Update. Fixes #84 --- hydra-test.el | 44 ++++++++++++++++++++++++-------------------- hydra.el | 31 +++++++++++++++++++------------ 2 files changed, 43 insertions(+), 32 deletions(-) diff --git a/hydra-test.el b/hydra-test.el index 5209936..c82b559 100644 --- a/hydra-test.el +++ b/hydra-test.el @@ -269,7 +269,7 @@ The body can be accessed via `hydra-error/body'." ("a" abbrev-mode "abbrev") ("q" nil "cancel"))) '(progn - (defun hydra-toggle/toggle-truncate-lines nil "Create a hydra with no body and the heads: + (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', @@ -284,7 +284,7 @@ Call the head: `toggle-truncate-lines'." (hydra-cleanup) (catch (quote hydra-disable) (call-interactively (function toggle-truncate-lines)))) - (defun hydra-toggle/auto-fill-mode nil "Create a hydra with no body and the heads: + (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', @@ -299,7 +299,7 @@ Call the head: `auto-fill-mode'." (hydra-cleanup) (catch (quote hydra-disable) (call-interactively (function auto-fill-mode)))) - (defun hydra-toggle/abbrev-mode nil "Create a hydra with no body and the heads: + (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', @@ -354,9 +354,9 @@ The body can be accessed via `hydra-toggle/body'." (setq hydra-curr-map (quote (keymap (7 . hydra-keyboard-quit) (113 . hydra-toggle/nil) - (97 . hydra-toggle/abbrev-mode) - (102 . hydra-toggle/auto-fill-mode) - (116 . hydra-toggle/toggle-truncate-lines) + (97 . hydra-toggle/abbrev-mode-and-exit) + (102 . hydra-toggle/auto-fill-mode-and-exit) + (116 . hydra-toggle/toggle-truncate-lines-and-exit) (switch-frame . hydra--handle-switch-frame) (kp-subtract . hydra--negative-argument) (kp-9 . hydra--digit-argument) @@ -399,7 +399,7 @@ The body can be accessed via `hydra-toggle/body'." ("k" previous-line) ("q" nil "quit"))) '(progn - (defun hydra-vi/hydra-keyboard-quit nil "Create a hydra with no body and the heads: + (defun hydra-vi/hydra-keyboard-quit-and-exit nil "Create a hydra with no body and the heads: \"\": `hydra-keyboard-quit', \"j\": `next-line', @@ -447,7 +447,7 @@ Call the head: `next-line'." (113 . hydra-vi/nil) (107 . hydra-vi/previous-line) (106 . hydra-vi/next-line) - (7 . hydra-vi/hydra-keyboard-quit) + (7 . hydra-vi/hydra-keyboard-quit-and-exit) (switch-frame . hydra--handle-switch-frame) (kp-subtract . hydra--negative-argument) (kp-9 . hydra--digit-argument) @@ -504,7 +504,7 @@ Call the head: `previous-line'." (113 . hydra-vi/nil) (107 . hydra-vi/previous-line) (106 . hydra-vi/next-line) - (7 . hydra-vi/hydra-keyboard-quit) + (7 . hydra-vi/hydra-keyboard-quit-and-exit) (switch-frame . hydra--handle-switch-frame) (kp-subtract . hydra--negative-argument) (kp-9 . hydra--digit-argument) @@ -577,7 +577,7 @@ The body can be accessed via `hydra-vi/body'." (113 . hydra-vi/nil) (107 . hydra-vi/previous-line) (106 . hydra-vi/next-line) - (7 . hydra-vi/hydra-keyboard-quit) + (7 . hydra-vi/hydra-keyboard-quit-and-exit) (switch-frame . hydra--handle-switch-frame) (kp-subtract . hydra--negative-argument) (kp-9 . hydra--digit-argument) @@ -784,6 +784,10 @@ _f_ auto-fill-mode: %`auto-fill-function '(nil nil :exit t)) 'blue)) (should (equal (hydra--head-color + '("j" next-line "" :exit t) + '(nil nil)) + 'blue)) + (should (equal (hydra--head-color '("c" (message "Continuing") "red" :exit nil) '(nil nil :exit t)) 'red)) @@ -879,7 +883,7 @@ Call the head: `(text-scale-set 0)'." (hydra-disable) (catch (quote hydra-disable) (condition-case err (prog1 t (call-interactively (function (lambda nil (interactive) - (text-scale-set 0))))) + (text-scale-set 0))))) ((quit error) (message "%S" err) (unless hydra-lv (sit-for 0.8)) @@ -910,12 +914,12 @@ Call the head: `(text-scale-set 0)'." (52 . hydra--digit-argument) (51 . hydra--digit-argument) (50 . hydra--digit-argument) - (49 . hydra-zoom/lambda-0) - (48 . hydra-zoom/lambda-0) + (49 . hydra-zoom/lambda-0-and-exit) + (48 . hydra-zoom/lambda-0-and-exit) (45 . hydra--negative-argument) (21 . hydra--universal-argument)))) t (lambda nil (hydra-cleanup)))))) - (defun hydra-zoom/lambda-0 nil "Create a hydra with no body and the heads: + (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)', @@ -929,7 +933,7 @@ Call the head: `(text-scale-set 0)'." (hydra-cleanup) (catch (quote hydra-disable) (call-interactively (function (lambda nil (interactive) - (text-scale-set 0)))))) + (text-scale-set 0)))))) (defun hydra-zoom/hint nil (if hydra-lv (lv-message (format #("zoom: [r 0]: reset." 7 8 (face hydra-face-red) 9 10 (face hydra-face-blue)))) @@ -971,8 +975,8 @@ The body can be accessed via `hydra-zoom/body'." (52 . hydra--digit-argument) (51 . hydra--digit-argument) (50 . hydra--digit-argument) - (49 . hydra-zoom/lambda-0) - (48 . hydra-zoom/lambda-0) + (49 . hydra-zoom/lambda-0-and-exit) + (48 . hydra-zoom/lambda-0-and-exit) (45 . hydra--negative-argument) (21 . hydra--universal-argument)))) t (lambda nil (hydra-cleanup)))) @@ -1033,11 +1037,11 @@ Call the head: `(text-scale-set 0)'." (51 . hydra--digit-argument) (50 . hydra--digit-argument) (49 . hydra-zoom/lambda-r) - (48 . hydra-zoom/lambda-0) + (48 . hydra-zoom/lambda-0-and-exit) (45 . hydra--negative-argument) (21 . hydra--universal-argument)))) t (lambda nil (hydra-cleanup)))))) - (defun hydra-zoom/lambda-0 nil "Create a hydra with no body and the heads: + (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)', @@ -1094,7 +1098,7 @@ The body can be accessed via `hydra-zoom/body'." (51 . hydra--digit-argument) (50 . hydra--digit-argument) (49 . hydra-zoom/lambda-r) - (48 . hydra-zoom/lambda-0) + (48 . hydra-zoom/lambda-0-and-exit) (45 . hydra--negative-argument) (21 . hydra--universal-argument)))) t (lambda nil (hydra-cleanup)))) diff --git a/hydra.el b/hydra.el index 924fe57..1b8dbb6 100644 --- a/hydra.el +++ b/hydra.el @@ -556,7 +556,7 @@ DOC was generated with `hydra--doc'. HEAD is one of the HEADS passed to `defhydra'. BODY-PRE and BODY-POST are pre-processed in `defhydra'. OTHER-POST is an optional extension to the :post key of BODY." - (let ((name (hydra--head-name head name)) + (let ((name (hydra--head-name head name body)) (cmd (when (car head) (hydra--make-callable (cadr head)))) @@ -679,12 +679,16 @@ NAME, BODY and HEADS are parameters to `defhydra'." "An %S Hydra must have at least one blue head in order to exit" body-color)))))) -(defun hydra--head-name (h body-name) - "Return the symbol for head H of body BODY-NAME." - (intern (format "%S/%s" body-name - (if (symbolp (cadr h)) - (cadr h) - (concat "lambda-" (car h)))))) +(defun hydra--head-name (h name body) + "Return the symbol for head H of hydra with NAME and BODY." + (let ((str (format "%S/%s" name + (if (symbolp (cadr h)) + (cadr h) + (concat "lambda-" (car h)))))) + (when (and (memq (hydra--head-color h body) '(blue teal)) + (not (memq (cadr h) '(body nil)))) + (setq str (concat str "-and-exit"))) + (intern str))) (defun hydra--delete-duplicates (heads) "Return HEADS without entries that have the same CMD part. @@ -881,15 +885,15 @@ result of `defhydra'." (setq heads (cons (list hydra-keyboard-quit #'hydra-keyboard-quit nil :exit t) heads))) (dolist (h heads) - (let ((len (length h)) - (cmd-name (hydra--head-name h name))) + (let ((len (length h))) (cond ((< len 2) (error "Each head should have at least two items: %S" h)) ((= len 2) (setcdr (cdr h) (list - (hydra-plist-get-default (cddr body) :hint "") - :cmd-name cmd-name))) + (hydra-plist-get-default (cddr body) :hint ""))) + (setcdr (nthcdr 2 h) + (list :cmd-name (hydra--head-name h name body)))) (t (let ((hint (cl-caddr h))) (unless (or (null hint) @@ -897,7 +901,10 @@ result of `defhydra'." (setcdr (cdr h) (cons (hydra-plist-get-default (cddr body) :hint "") (cddr h)))) - (setcdr (cddr h) `(:cmd-name ,cmd-name ,@(cl-cdddr h)))))))) + (setcdr (cddr h) + `(:cmd-name + ,(hydra--head-name h name body) + ,@(cl-cdddr h)))))))) (let ((doc (hydra--doc body-key body-name heads)) (heads-nodup (hydra--delete-duplicates heads))) (mapc