branch: master commit 11323ece73ecbf9e7fea3e20a26d3c0aeb41e01f Author: Oleh Krehel <ohwoeo...@gmail.com> Commit: Oleh Krehel <ohwoeo...@gmail.com>
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)