emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] master 0b6ef70 1/6: Add support for `universal-argument' and `dig


From: Oleh Krehel
Subject: [elpa] master 0b6ef70 1/6: Add support for `universal-argument' and `digit-argument'
Date: Wed, 04 Feb 2015 18:51:19 +0000

branch: master
commit 0b6ef70836d3734a377aee3a13a1f471a5dd2c73
Author: Oleh Krehel <address@hidden>
Commit: Oleh Krehel <address@hidden>

    Add support for `universal-argument' and `digit-argument'
    
    * hydra.el (hydra-base-map): Model after `universal-argument-map'; all
      Hydra keymaps will inherit from this one.
    (hydra-curr-map): Current Hydra keymap. This is necessary for
    e.g. `hydra--digit-argument' to return to the orignial keymap.
    (hydra--universal-argument): New function.
    (hydra--digit-argument): New function.
    (hydra--negative-argument): New function.
    (hydra--hint): Fix dangling `body-color'.
    (defhydra): keymap will inherit `hydra-base-map'.
    `hydra-current-map' will be set by red heads. In red heads, make the
    function call after `set-transient-map' so that e.g. "Beginning of
    buffer" error will not exit the Hydra.
    
    * hydra-test.el: Update tests.
    
    Fixes #13.
---
 Makefile      |    8 ++-
 hydra-test.el |  300 +++++++++++++++++++++++++++++++++++++-------------------
 hydra.el      |  150 +++++++++++++++++++++--------
 3 files changed, 313 insertions(+), 145 deletions(-)

diff --git a/Makefile b/Makefile
index 97bcea6..b2d473d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,12 +1,18 @@
 EMACS = emacs
 # EMACS = emacs-24.3
 
+LOAD = -l hydra.el -l hydra-test.el
+
 .PHONY: all test clean
 
 all: test
 
 test:
-       $(EMACS) -batch -l hydra.el -l hydra-test.el -f 
ert-run-tests-batch-and-exit
+       $(EMACS) -batch $(LOAD) -f ert-run-tests-batch-and-exit
+
+compile:
+       $(EMACS) -q $(LOAD) -l init.el --eval "(progn (mapc #'byte-compile-file 
'(\"hydra.el\" \"init.el\")) (switch-to-buffer \"*Compile-Log*\") (ert t))"
+       make clean
 
 clean:
        rm -f *.elc
diff --git a/hydra-test.el b/hydra-test.el
index f3b3c27..07d0a74 100644
--- a/hydra-test.el
+++ b/hydra-test.el
@@ -36,8 +36,7 @@
        ("j" next-error "next")
        ("k" previous-error "prev")))
     '(progn
-      (defun hydra-error/first-error ()
-        "Create a hydra with a \"M-g\" body and the heads:
+      (defun hydra-error/first-error nil "Create a hydra with a \"M-g\" body 
and the heads:
 
 \"h\":    `first-error',
 \"j\":    `next-error',
@@ -46,22 +45,41 @@
 The body can be accessed via `hydra-error/body'.
 
 Call the head: `first-error'."
-        (interactive)
-        (call-interactively #'first-error)
-        (when hydra-is-helpful
-          (message #("error: [h]: first, [j]: next, [k]: prev."
-                     8 9 (face font-lock-keyword-face)
-                     20 21 (face font-lock-keyword-face)
-                     31 32 (face font-lock-keyword-face))))
-        (setq hydra-last
-              (hydra-set-transient-map
-               '(keymap
-                 (107 . hydra-error/previous-error)
-                 (106 . hydra-error/next-error)
-                 (104 . hydra-error/first-error)) t)))
-
-      (defun hydra-error/next-error ()
-        "Create a hydra with a \"M-g\" body and the heads:
+             (interactive)
+             (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 '(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))
+             (call-interactively (function first-error)))
+      (defun hydra-error/next-error nil "Create a hydra with a \"M-g\" body 
and the heads:
 
 \"h\":    `first-error',
 \"j\":    `next-error',
@@ -70,22 +88,41 @@ Call the head: `first-error'."
 The body can be accessed via `hydra-error/body'.
 
 Call the head: `next-error'."
-        (interactive)
-        (call-interactively #'next-error)
-        (when hydra-is-helpful
-          (message #("error: [h]: first, [j]: next, [k]: prev."
-                     8 9 (face font-lock-keyword-face)
-                     20 21 (face font-lock-keyword-face)
-                     31 32 (face font-lock-keyword-face))))
-        (setq hydra-last
-              (hydra-set-transient-map
-               '(keymap
-                 (107 . hydra-error/previous-error)
-                 (106 . hydra-error/next-error)
-                 (104 . hydra-error/first-error)) t)))
-
-      (defun hydra-error/previous-error ()
-        "Create a hydra with a \"M-g\" body and the heads:
+             (interactive)
+             (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 '(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))
+             (call-interactively (function next-error)))
+      (defun hydra-error/previous-error nil "Create a hydra with a \"M-g\" 
body and the heads:
 
 \"h\":    `first-error',
 \"j\":    `next-error',
@@ -94,46 +131,89 @@ Call the head: `next-error'."
 The body can be accessed via `hydra-error/body'.
 
 Call the head: `previous-error'."
-        (interactive)
-        (call-interactively #'previous-error)
-        (when hydra-is-helpful
-          (message #("error: [h]: first, [j]: next, [k]: prev."
-                     8 9 (face font-lock-keyword-face)
-                     20 21 (face font-lock-keyword-face)
-                     31 32 (face font-lock-keyword-face))))
-        (setq hydra-last
-              (hydra-set-transient-map
-               '(keymap
-                 (107 . hydra-error/previous-error)
-                 (106 . hydra-error/next-error)
-                 (104 . hydra-error/first-error)) t)))
-
+             (interactive)
+             (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 '(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))
+             (call-interactively (function previous-error)))
       (unless (keymapp (lookup-key global-map (kbd "M-g")))
-        (define-key global-map (kbd "M-g") nil))
-      (define-key global-map [134217831 104] #'hydra-error/first-error)
-      (define-key global-map [134217831 106] #'hydra-error/next-error)
-      (define-key global-map [134217831 107] #'hydra-error/previous-error)
-
-      (defun hydra-error/body ()
-        "Create a hydra with a \"M-g\" body and the heads:
+        (define-key global-map (kbd "M-g")
+          nil))
+      (define-key global-map [134217831 104]
+       (function hydra-error/first-error))
+      (define-key global-map [134217831 106]
+       (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:
 
 \"h\":    `first-error',
 \"j\":    `next-error',
 \"k\":    `previous-error'
 
 The body can be accessed via `hydra-error/body'."
-        (interactive)
-        (when hydra-is-helpful
-          (message #("error: [h]: first, [j]: next, [k]: prev."
-                     8 9 (face font-lock-keyword-face)
-                     20 21 (face font-lock-keyword-face)
-                     31 32 (face font-lock-keyword-face))))
-        (setq hydra-last
-              (hydra-set-transient-map
-               '(keymap
-                 (107 . hydra-error/previous-error)
-                 (106 . hydra-error/next-error)
-                 (104 . hydra-error/first-error)) t)))))))
+             (interactive)
+             (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
+                    '(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)))))))
 
 (ert-deftest hydra-blue-toggle ()
   (should
@@ -146,8 +226,7 @@ The body can be accessed via `hydra-error/body'."
        ("a" abbrev-mode "abbrev")
        ("q" nil "cancel")))
     '(progn
-      (defun toggle/toggle-truncate-lines ()
-        "Create a hydra with no body and the heads:
+      (defun toggle/toggle-truncate-lines nil "Create a hydra with no body and 
the heads:
 
 \"t\":    `toggle-truncate-lines',
 \"f\":    `auto-fill-mode',
@@ -157,11 +236,10 @@ The body can be accessed via `hydra-error/body'."
 The body can be accessed via `toggle/body'.
 
 Call the head: `toggle-truncate-lines'."
-        (interactive)
-        (hydra-disable)
-        (call-interactively #'toggle-truncate-lines))
-      (defun toggle/auto-fill-mode ()
-        "Create a hydra with no body and the heads:
+             (interactive)
+             (hydra-disable)
+             (call-interactively (function toggle-truncate-lines)))
+      (defun toggle/auto-fill-mode nil "Create a hydra with no body and the 
heads:
 
 \"t\":    `toggle-truncate-lines',
 \"f\":    `auto-fill-mode',
@@ -171,11 +249,10 @@ Call the head: `toggle-truncate-lines'."
 The body can be accessed via `toggle/body'.
 
 Call the head: `auto-fill-mode'."
-        (interactive)
-        (hydra-disable)
-        (call-interactively #'auto-fill-mode))
-      (defun toggle/abbrev-mode ()
-        "Create a hydra with no body and the heads:
+             (interactive)
+             (hydra-disable)
+             (call-interactively (function auto-fill-mode)))
+      (defun toggle/abbrev-mode nil "Create a hydra with no body and the heads:
 
 \"t\":    `toggle-truncate-lines',
 \"f\":    `auto-fill-mode',
@@ -185,11 +262,10 @@ Call the head: `auto-fill-mode'."
 The body can be accessed via `toggle/body'.
 
 Call the head: `abbrev-mode'."
-        (interactive)
-        (hydra-disable)
-        (call-interactively #'abbrev-mode))
-      (defun toggle/nil ()
-        "Create a hydra with no body and the heads:
+             (interactive)
+             (hydra-disable)
+             (call-interactively (function abbrev-mode)))
+      (defun toggle/nil nil "Create a hydra with no body and the heads:
 
 \"t\":    `toggle-truncate-lines',
 \"f\":    `auto-fill-mode',
@@ -199,10 +275,9 @@ Call the head: `abbrev-mode'."
 The body can be accessed via `toggle/body'.
 
 Call the head: `nil'."
-        (interactive)
-        (hydra-disable))
-      (defun toggle/body ()
-        "Create a hydra with no body and the heads:
+             (interactive)
+             (hydra-disable))
+      (defun toggle/body nil "Create a hydra with no body and the heads:
 
 \"t\":    `toggle-truncate-lines',
 \"f\":    `auto-fill-mode',
@@ -210,20 +285,41 @@ Call the head: `nil'."
 \"q\":    `nil'
 
 The body can be accessed via `toggle/body'."
-        (interactive)
-        (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
-               '(keymap (113 . toggle/nil)
-                 (97 . toggle/abbrev-mode)
-                 (102 . toggle/auto-fill-mode)
-                 (116 . toggle/toggle-truncate-lines))
-               t)))))))
+             (interactive)
+             (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
+                    '(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)))))))
 
 (provide 'hydra-test)
 
diff --git a/hydra.el b/hydra.el
index 95d3a42..03b3819 100644
--- a/hydra.el
+++ b/hydra.el
@@ -5,7 +5,7 @@
 ;; Author: Oleh Krehel <address@hidden>
 ;; Maintainer: Oleh Krehel <address@hidden>
 ;; URL: https://github.com/abo-abo/hydra
-;; Version: 0.5.0
+;; Version: 0.6.0
 ;; Keywords: bindings
 ;; Package-Requires: ((cl-lib "0.5"))
 
@@ -61,8 +61,15 @@
 ;;       ("l" text-scale-decrease "out"))
 
 ;;; Code:
+;;* Requires
 (require 'cl-lib)
 
+(defalias 'hydra-set-transient-map
+  (if (fboundp 'set-transient-map)
+      'set-transient-map
+    'set-temporary-overlay-map))
+
+;;* Customize
 (defgroup hydra nil
   "Make bindings that stick around."
   :group 'bindings
@@ -82,43 +89,65 @@
     '((t (:foreground "#758BC6" :bold t)))
   "Blue Hydra heads will vanquish the Hydra.")
 
-(defalias 'hydra-set-transient-map
-  (if (fboundp 'set-transient-map)
-      'set-transient-map
-    'set-temporary-overlay-map))
-
+;;* Universal Argument
+(defvar hydra-base-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [?\C-u] 'hydra--universal-argument)
+    (define-key map [?-] 'hydra--negative-argument)
+    (define-key map [?0] 'hydra--digit-argument)
+    (define-key map [?1] 'hydra--digit-argument)
+    (define-key map [?2] 'hydra--digit-argument)
+    (define-key map [?3] 'hydra--digit-argument)
+    (define-key map [?4] 'hydra--digit-argument)
+    (define-key map [?5] 'hydra--digit-argument)
+    (define-key map [?6] 'hydra--digit-argument)
+    (define-key map [?7] 'hydra--digit-argument)
+    (define-key map [?8] 'hydra--digit-argument)
+    (define-key map [?9] 'hydra--digit-argument)
+    (define-key map [kp-0] 'hydra--digit-argument)
+    (define-key map [kp-1] 'hydra--digit-argument)
+    (define-key map [kp-2] 'hydra--digit-argument)
+    (define-key map [kp-3] 'hydra--digit-argument)
+    (define-key map [kp-4] 'hydra--digit-argument)
+    (define-key map [kp-5] 'hydra--digit-argument)
+    (define-key map [kp-6] 'hydra--digit-argument)
+    (define-key map [kp-7] 'hydra--digit-argument)
+    (define-key map [kp-8] 'hydra--digit-argument)
+    (define-key map [kp-9] 'hydra--digit-argument)
+    (define-key map [kp-subtract] 'hydra--negative-argument)
+    map)
+  "Keymap that all Hydras inherit. See `universal-argument-map'.")
+
+(defvar hydra-curr-map
+  (make-sparse-keymap)
+  "Keymap of the current Hydra called.")
+
+(defun hydra--universal-argument (arg)
+  "Forward to (`universal-argument' ARG)."
+  (interactive "P")
+  (setq prefix-arg (if (consp arg)
+                       (list (* 4 (car arg)))
+                     (if (eq arg '-)
+                         (list -4)
+                       '(4))))
+  (hydra-set-transient-map hydra-curr-map))
+
+(defun hydra--digit-argument (arg)
+  "Forward to (`digit-argument' ARG)."
+  (interactive "P")
+  (let ((universal-argument-map hydra-curr-map))
+    (digit-argument arg)))
+
+(defun hydra--negative-argument (arg)
+  "Forward to (`negative-argument' ARG)."
+  (interactive "P")
+  (let ((universal-argument-map hydra-curr-map))
+    (negative-argument arg)))
+
+;;* Misc internals
 (defvar hydra-last nil
   "The result of the last `hydra-set-transient-map' call.")
 
-;;;###autoload
-(defmacro hydra-create (body heads &optional method)
-  "Create a hydra with a BODY prefix and HEADS with METHOD.
-This will result in `global-set-key' statements with the keys
-being the concatenation of BODY and each head in HEADS.  HEADS is
-an list of (KEY FUNCTION &optional HINT).
-
-After one of the HEADS is called via BODY+KEY, it and the other
-HEADS can be called with only KEY (no need for BODY).  This state
-is broken once any key binding that is not in HEADS is called.
-
-METHOD is a lambda takes two arguments: a KEY and a COMMAND.
-It defaults to `global-set-key'.
-When `(keymapp METHOD)`, it becomes:
-
-    (lambda (key command) (define-key METHOD key command))"
-  (declare (indent 1))
-  `(defhydra ,(intern
-               (concat
-                "hydra-" (replace-regexp-in-string " " "_" body)))
-       ,(cond ((hydra--callablep method)
-              method)
-             ((null method)
-              `(global-map ,body))
-             (t
-              (list method body)))
-     "hydra"
-     ,@(eval heads)))
-
 (defun hydra--callablep (x)
   "Test if X is callable."
   (or (functionp x)
@@ -141,8 +170,8 @@ When `(keymapp METHOD)`, it becomes:
     (red 'hydra-face-red)
     (t (error "Unknown color for %S" h))))
 
-(defun hydra--hint (docstring heads)
-  "Generate a hint from DOCSTRING and HEADS.
+(defun hydra--hint (docstring heads body-color)
+  "Generate a hint from DOCSTRING and HEADS and BODY-COLOR.
 It's intended for the echo area, when a Hydra is active."
   (format "%s: %s."
           docstring
@@ -183,6 +212,38 @@ HEADS is a list of heads."
     heads ",\n")
    (format "The body can be accessed via `%S'." body-name)))
 
+;;* Macros
+;;** hydra-create
+;;;###autoload
+(defmacro hydra-create (body heads &optional method)
+  "Create a hydra with a BODY prefix and HEADS with METHOD.
+This will result in `global-set-key' statements with the keys
+being the concatenation of BODY and each head in HEADS.  HEADS is
+an list of (KEY FUNCTION &optional HINT).
+
+After one of the HEADS is called via BODY+KEY, it and the other
+HEADS can be called with only KEY (no need for BODY).  This state
+is broken once any key binding that is not in HEADS is called.
+
+METHOD is a lambda takes two arguments: a KEY and a COMMAND.
+It defaults to `global-set-key'.
+When `(keymapp METHOD)`, it becomes:
+
+    (lambda (key command) (define-key METHOD key command))"
+  (declare (indent 1))
+  `(defhydra ,(intern
+               (concat
+                "hydra-" (replace-regexp-in-string " " "_" body)))
+       ,(cond ((hydra--callablep method)
+              method)
+             ((null method)
+              `(global-map ,body))
+             (t
+              (list method body)))
+     "hydra"
+     ,@(eval heads)))
+
+;;** defhydra
 ;;;###autoload
 (defmacro defhydra (name body &optional docstring &rest heads)
   "Create a hydra named NAME with a prefix BODY.
@@ -212,7 +273,7 @@ in turn can be either red or blue."
     (setq docstring "hydra"))
   (when (keywordp (car body))
     (setq body (cons nil (cons nil body))))
-  (let* ((keymap (make-sparse-keymap))
+  (let* ((keymap (copy-keymap hydra-base-map))
          (names (mapcar
                  (lambda (x)
                    (define-key keymap (kbd (car x))
@@ -228,7 +289,7 @@ in turn can be either red or blue."
          (method (if (hydra--callablep body)
                      body
                    (car body)))
-         (hint (hydra--hint docstring heads))
+         (hint (hydra--hint docstring heads body-color))
          (doc (hydra--doc body-key body-name heads)))
     `(progn
        ,@(cl-mapcar
@@ -240,11 +301,11 @@ in turn can be either red or blue."
                      `((hydra-disable)
                        ,@(unless (null (cadr head))
                                  `((call-interactively #',(cadr head)))))
-                     `((call-interactively #',(cadr head))
-                       (when hydra-is-helpful
+                     `((when hydra-is-helpful
                          (message ,hint))
                        (setq hydra-last
-                             (hydra-set-transient-map ',keymap t))))))
+                             (hydra-set-transient-map (setq hydra-curr-map 
',keymap) t))
+                       (call-interactively #',(cadr head))))))
           heads names)
        ,@(unless (or (null body-key)
                      (null method)
@@ -272,4 +333,9 @@ in turn can be either red or blue."
                (hydra-set-transient-map ',keymap t))))))
 
 (provide 'hydra)
+
+;;; Local Variables:
+;;; outline-regexp: ";;\\*+"
+;;; End:
+
 ;;; hydra.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]