branch: master
commit 11323ece73ecbf9e7fea3e20a26d3c0aeb41e01f
Author: Oleh Krehel <[email protected]>
Commit: Oleh Krehel <[email protected]>
Allow to use minor-mode-maps and more
* hydra.el (hydra-create): Add a third optional argument. When it's not
supplied, the behavior should remain the same. Otherwise, it's a
lambda that's used instead of `global-set-key', with the same semantics.
* README.md: Update.
re #1
---
README.md | 29 +++++++++++++++++++++++++++++
hydra.el | 26 ++++++++++++++++++++------
2 files changed, 49 insertions(+), 6 deletions(-)
diff --git a/README.md b/README.md
index 3e76618..928983f 100644
--- a/README.md
+++ b/README.md
@@ -26,3 +26,32 @@ You can expand the examples in-place, it still looks elegant:
See the [introductory blog
post](http://oremacs.com/2015/01/20/introducing-hydra/) for more information.

+
+## Using Hydra to define bindings other than global ones
+
+You can use the third optional argument of `hydra-create` for this (it
defaults to `global-set-key`).
+Here's an example:
+
+```cl
+(hydra-create "z"
+ '(("l" . forward-char)
+ ("h" . backward-char)
+ ("j" . next-line)
+ ("k" . previous-line))
+ (lambda (key command)
+ (define-key lispy-mode-map key command)))
+```
+
+For this simple case, there's even a shortcut: if you give a keymap as the
third argument,
+the lambda will be generated for you:
+
+```cl
+(hydra-create "z"
+ '(("l" . forward-char)
+ ("h" . backward-char)
+ ("j" . next-line)
+ ("k" . previous-line))
+ lispy-mode-map)
+```
+
+
diff --git a/hydra.el b/hydra.el
index d2886df..9479817 100644
--- a/hydra.el
+++ b/hydra.el
@@ -51,15 +51,21 @@
(require 'cl-lib)
;;;###autoload
-(defmacro hydra-create (body heads)
- "Create a hydra with a BODY prefix and HEADS.
+(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 alist of (KEY . FUNCTION).
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."
+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))
(let* ((keymap (make-sparse-keymap))
(heads (eval heads))
@@ -67,9 +73,17 @@ is broken once any key binding that is not in HEADS is
called."
(lambda (x)
(define-key keymap (car x)
(intern (format "hydra-%s-%S" body (cdr x)))))
- heads)))
+ heads))
+ (method (cond ((null method)
+ 'global-set-key)
+
+ ((keymapp (eval method))
+ `(lambda (key command) (define-key ,method key
command)))
+
+ (t
+ method))))
`(progn
- (global-set-key ,(kbd body) nil)
+ (,method ,(kbd body) nil)
,@(cl-mapcar
(lambda (head name)
`(defun ,name ()
@@ -91,7 +105,7 @@ Call the head: `%S'."
heads names)
,@(cl-mapcar
(lambda (head name)
- `(global-set-key ,(kbd (concat body " " (car head))) #',name))
+ `(,method ,(kbd (concat body " " (car head))) #',name))
heads names))))
(provide 'hydra)