[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] master 11b130e 17/17: Merge commit '0c08964462812942db51d177e6ea9
From: |
Oleh Krehel |
Subject: |
[elpa] master 11b130e 17/17: Merge commit '0c08964462812942db51d177e6ea922b26019e65' from hydra |
Date: |
Tue, 10 Feb 2015 07:13:29 +0000 |
branch: master
commit 11b130e1353349b0ac612811e598eb3c93f75365
Merge: 61bddf2 0c08964
Author: Oleh Krehel <address@hidden>
Commit: Oleh Krehel <address@hidden>
Merge commit '0c08964462812942db51d177e6ea922b26019e65' from hydra
---
packages/hydra/README.md | 59 +++-
packages/hydra/hydra-examples.el | 173 ++++++++-
packages/hydra/hydra-test.el | 758 ++++++++++++++++----------------------
packages/hydra/hydra.el | 243 ++++++++----
4 files changed, 679 insertions(+), 554 deletions(-)
diff --git a/packages/hydra/README.md b/packages/hydra/README.md
index 7272098..c7c1dff 100644
--- a/packages/hydra/README.md
+++ b/packages/hydra/README.md
@@ -16,29 +16,42 @@ Hydra, will still serve his orignal purpose, calling his
proper
command. This makes the Hydra very seamless, it's like a minor mode
that disables itself auto-magically.
-## Simplified usage
-
-Here's how to quickly bind the examples bundled with Hydra:
+## Sample global Hydras
+### Zoom
```cl
-(require 'hydra-examples)
-(hydra-create "C-M-y" hydra-example-move-window-splitter)
-(hydra-create "M-g" hydra-example-goto-error)
-(hydra-create "<f2>" hydra-example-text-scale)
+(defhydra hydra-zoom (global-map "<f2>")
+ "zoom"
+ ("g" text-scale-increase "in")
+ ("l" text-scale-decrease "out"))
```
-## Using Hydra for global bindings
+### Goto-error
-But it's much better to just take the examples as a template and write
-down everything explicitly:
+```cl
+(defhydra hydra-error (global-map "M-g")
+ "goto-error"
+ ("h" first-error "first")
+ ("j" next-error "next")
+ ("k" previous-error "prev")
+ ("v" recenter-top-bottom "recenter")
+ ("q" nil "quit"))
+```
+
+### Splitter
```cl
-(defhydra hydra-zoom (global-map "<f2>")
- "zoom"
- ("g" text-scale-increase "in")
- ("l" text-scale-decrease "out"))
+(require 'hydra-examples)
+(defhydra hydra-splitter (global-map "C-M-s")
+ "splitter"
+ ("h" hydra-move-splitter-left)
+ ("j" hydra-move-splitter-down)
+ ("k" hydra-move-splitter-up)
+ ("l" hydra-move-splitter-right))
```
+## Using the functions generated by `defhydra`
+
With the example above, you can e.g.:
```cl
@@ -234,6 +247,22 @@ use an amaranth Hydra instead of a red one, if for you the
cost of being able to
though certain bindings is less than the cost of accidentally exiting a red
Hydra by
pressing the wrong prefix.
-Note that it does not make sense to define a singe amaranth head, so this
color can only
+Note that it does not make sense to define a single amaranth head, so this
color can only
be assigned to the body. An amaranth body will always have some amaranth heads
and some
blue heads (otherwise, it's impossible to exit), no reds.
+
+## Generate simple lambdas in-place:
+
+Since version `0.9.0` it's possible to pass a single sexp instead of a
function name or a lambda
+to a head. This sexp will be wrapped in an interactive lambda. Here's an
example:
+
+```cl
+(defhydra hydra-launcher (:color blue)
+ "Launch"
+ ("h" man "man")
+ ("r" (browse-url "http://www.reddit.com/r/emacs/") "reddit")
+ ("w" (browse-url "http://www.emacswiki.org/") "emacswiki")
+ ("s" shell "shell")
+ ("q" nil "cancel"))
+(global-set-key (kbd "C-c r") 'hydra-launcher/body)
+```
diff --git a/packages/hydra/hydra-examples.el b/packages/hydra/hydra-examples.el
index 3dfc836..5167c50 100644
--- a/packages/hydra/hydra-examples.el
+++ b/packages/hydra/hydra-examples.el
@@ -21,26 +21,147 @@
;;; Commentary:
;;
-;; These are the sample Hydras that you can use.
+;; These are the sample Hydras.
;;
-;; Note that the better way to create Hydras is with `defhydra':
-;;
-;; (defhydra hydra-zoom (global-map "<f2>")
-;; "zoom"
-;; ("g" text-scale-increase "in")
-;; ("l" text-scale-decrease "out"))
-;;
-;; This way, you have more options, and everything is in one place.
+;; If you want to use them plainly, set `hydra-examples-verbatim' to t
+;; before requiring this file. But it's probably better to only look
+;; at them and use them as templates for building your own.
;;; Code:
(require 'hydra)
-(defvar hydra-example-text-scale
- '(("g" text-scale-increase "zoom in")
- ("l" text-scale-decrease "zoom out"))
- "A two-headed hydra for text scale manipulation.")
+;;* Examples
+;;** Example 1: text scale
+(when (bound-and-true-p hydra-examples-verbatim)
+ (defhydra hydra-zoom (global-map "<f2>")
+ "zoom"
+ ("g" text-scale-increase "in")
+ ("l" text-scale-decrease "out")))
+
+;; This example generates three commands:
+;;
+;; `hydra-zoom/text-scale-increase'
+;; `hydra-zoom/text-scale-decrease'
+;; `hydra-zoom/body'
+;;
+;; In addition, two of them are bound like this:
+;;
+;; (global-set-key (kbd "<f2> g") 'hydra-zoom/text-scale-increase)
+;; (global-set-key (kbd "<f2> l") 'hydra-zoom/text-scale-decrease)
+;;
+;; Note that you can substitute `global-map' with e.g. `emacs-lisp-mode-map'
if you need.
+;; The functions generated will be the same, except the binding code will
change to:
+;;
+;; (define-key emacs-lisp-mode-map [f2 103]
+;; (function hydra-zoom/text-scale-increase))
+;; (define-key emacs-lisp-mode-map [f2 108]
+;; (function hydra-zoom/text-scale-decrease))
+
+;;** Example 2: move window splitter
+(when (bound-and-true-p hydra-examples-verbatim)
+ (defhydra hydra-splitter (global-map "C-M-s")
+ "splitter"
+ ("h" hydra-move-splitter-left)
+ ("j" hydra-move-splitter-down)
+ ("k" hydra-move-splitter-up)
+ ("l" hydra-move-splitter-right)))
+;;** Example 3: jump to error
+(when (bound-and-true-p hydra-examples-verbatim)
+ (defhydra hydra-error (global-map "M-g")
+ "goto-error"
+ ("h" first-error "first")
+ ("j" next-error "next")
+ ("k" previous-error "prev")
+ ("v" recenter-top-bottom "recenter")
+ ("q" nil "quit")))
+
+;; This example introduces only one new thing: since the command
+;; passed to the "q" head is nil, it will quit the Hydra without doing
+;; anything. Heads that quit the Hydra instead of continuing are
+;; referred to as having blue :color. All the other heads have red
+;; :color, unless other is specified.
+
+;;** Example 4: toggle rarely used modes
+(when (bound-and-true-p hydra-examples-verbatim)
+ (global-set-key
+ (kbd "C-c C-v")
+ (defhydra hydra-toggle (:color blue)
+ "toggle"
+ ("a" abbrev-mode "abbrev")
+ ("d" toggle-debug-on-error "debug")
+ ("f" auto-fill-mode "fill")
+ ("t" toggle-truncate-lines "truncate")
+ ("w" whitespace-mode "whitespace")
+ ("q" nil "cancel"))))
+
+;; Note that in this case, `defhydra' returns the `hydra-toggle/body'
+;; symbol, which is then passed to `global-set-key'.
+;;
+;; Another new thing is that both the keymap and the body prefix are
+;; skipped. This means that `defhydra' will bind nothing - that's why
+;; `global-set-key' is necessary.
+;;
+;; One more new thing is that you can assign a :color to the body. All
+;; heads will inherit this color. The code above is very much equivalent to:
+;;
+;; (global-set-key (kbd "C-c C-v a") 'abbrev-mode)
+;; (global-set-key (kbd "C-c C-v d") 'toggle-debug-on-error)
+;;
+;; The differences are:
+;;
+;; * You get a hint immediately after "C-c C-v"
+;; * You can cancel and call a command immediately, e.g. "C-c C-v C-n"
+;; is equivalent to "C-n" with Hydra approach, while it will error
+;; that "C-c C-v C-n" isn't bound with the usual approach.
+
+;;** Example 5: mini-vi
+(defun hydra-vi/pre ()
+ (set-cursor-color "#e52b50"))
+
+(defun hydra-vi/post ()
+ (set-cursor-color "#ffffff"))
+
+(when (bound-and-true-p hydra-examples-verbatim)
+ (global-set-key
+ (kbd "C-z")
+ (defhydra hydra-vi (:pre hydra-vi/pre :post hydra-vi/post :color amaranth)
+ "vi"
+ ("l" forward-char)
+ ("h" backward-char)
+ ("j" next-line)
+ ("k" previous-line)
+ ("m" set-mark-command "mark")
+ ("a" move-beginning-of-line "beg")
+ ("e" move-end-of-line "end")
+ ("d" delete-region "del" :color blue)
+ ("y" kill-ring-save "yank" :color blue)
+ ("q" nil "quit"))))
+
+;; This example introduces :color amaranth. It's similar to red,
+;; except while you can quit red with any binding which isn't a Hydra
+;; head, you can quit amaranth only with a blue head. So you can quit
+;; this mode only with "d", "y", "q" or "C-g".
+;;
+;; Another novelty are the :pre and :post handlers. :pre will be
+;; called before each command, while :post will be called when the
+;; Hydra quits. In this case, they're used to override the cursor
+;; color while Hydra is active.
+
+;;** Example 6: selective global bind
+(when (bound-and-true-p hydra-examples-verbatim)
+ (defhydra hydra-next-error (global-map "C-x")
+ "next-error"
+ ("`" next-error "next")
+ ("j" next-error "next" :bind nil)
+ ("k" previous-error "previous" :bind nil)))
+
+;; This example will bind "C-x `" in `global-map', but it will not
+;; bind "C-x j" and "C-x k".
+;; You can still "C-x `jjk" though.
+
+;;* Windmove helpers
(require 'windmove)
(defun hydra-move-splitter-left (arg)
@@ -75,6 +196,17 @@
(shrink-window arg)
(enlarge-window arg)))
+;;* Obsoletes
+(defvar hydra-example-text-scale
+ '(("g" text-scale-increase "zoom in")
+ ("l" text-scale-decrease "zoom out"))
+ "A two-headed hydra for text scale manipulation.")
+(make-obsolete-variable
+ 'hydra-example-text-scale
+ "Don't use `hydra-example-text-scale', just write your own
+`defhydra' using hydra-examples.el as a template"
+ "0.9.0")
+
(defvar hydra-example-move-window-splitter
'(("h" hydra-move-splitter-left)
("j" hydra-move-splitter-down)
@@ -82,6 +214,11 @@
("l" hydra-move-splitter-right))
"A four-headed hydra for the window splitter manipulation.
Works best if you have not more than 4 windows.")
+(make-obsolete-variable
+ 'hydra-example-move-window-splitter
+ "Don't use `hydra-example-move-window-splitter', just write your own
+`defhydra' using hydra-examples.el as a template"
+ "0.9.0")
(defvar hydra-example-goto-error
'(("h" first-error "first")
@@ -89,6 +226,11 @@ Works best if you have not more than 4 windows.")
("k" previous-error "prev"))
"A three-headed hydra for jumping between \"errors\".
Useful for e.g. `occur', `rgrep' and the like.")
+(make-obsolete-variable
+ 'hydra-example-goto-error
+ "Don't use `hydra-example-goto-error', just write your own
+`defhydra' using hydra-examples.el as a template"
+ "0.9.0")
(defvar hydra-example-windmove
'(("h" windmove-left)
@@ -96,6 +238,11 @@ Useful for e.g. `occur', `rgrep' and the like.")
("k" windmove-up)
("l" windmove-right))
"A four-headed hydra for `windmove'.")
+(make-obsolete-variable
+ 'hydra-example-windmove
+ "Don't use `hydra-example-windmove', just write your own
+`defhydra' using hydra-examples.el as a template"
+ "0.9.0")
(provide 'hydra-examples)
;;; hydra-examples.el ends here
diff --git a/packages/hydra/hydra-test.el b/packages/hydra/hydra-test.el
index eee851a..f2311ab 100644
--- a/packages/hydra/hydra-test.el
+++ b/packages/hydra/hydra-test.el
@@ -46,8 +46,8 @@ The body can be accessed via `hydra-error/body'.
Call the head: `first-error'."
(interactive)
+ (hydra-disable)
(catch (quote hydra-disable)
- (hydra-disable)
(condition-case err (prog1 t (call-interactively (function
first-error)))
((debug error)
(message "%S" err)
@@ -58,32 +58,33 @@ Call the head: `first-error'."
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)))
+ (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:
@@ -95,8 +96,8 @@ The body can be accessed via `hydra-error/body'.
Call the head: `next-error'."
(interactive)
+ (hydra-disable)
(catch (quote hydra-disable)
- (hydra-disable)
(condition-case err (prog1 t (call-interactively (function
next-error)))
((debug error)
(message "%S" err)
@@ -107,32 +108,33 @@ Call the head: `next-error'."
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)))
+ (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:
@@ -144,8 +146,8 @@ The body can be accessed via `hydra-error/body'.
Call the head: `previous-error'."
(interactive)
+ (hydra-disable)
(catch (quote hydra-disable)
- (hydra-disable)
(condition-case err (prog1 t (call-interactively (function
previous-error)))
((debug error)
(message "%S" err)
@@ -156,32 +158,33 @@ Call the head: `previous-error'."
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)))
+ (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")))
(define-key global-map (kbd "M-g")
@@ -200,38 +203,42 @@ Call the head: `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 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)))))))
+ (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)))))))
(ert-deftest hydra-blue-toggle ()
(should
@@ -256,7 +263,8 @@ The body can be accessed via `toggle/body'.
Call the head: `toggle-truncate-lines'."
(interactive)
(hydra-disable)
- (call-interactively (function toggle-truncate-lines)))
+ (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:
\"t\": `toggle-truncate-lines',
@@ -269,7 +277,8 @@ The body can be accessed via `toggle/body'.
Call the head: `auto-fill-mode'."
(interactive)
(hydra-disable)
- (call-interactively (function auto-fill-mode)))
+ (catch (quote 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',
@@ -282,7 +291,8 @@ The body can be accessed via `toggle/body'.
Call the head: `abbrev-mode'."
(interactive)
(hydra-disable)
- (call-interactively (function abbrev-mode)))
+ (catch (quote hydra-disable)
+ (call-interactively (function abbrev-mode))))
(defun toggle/nil nil "Create a hydra with no body and the heads:
\"t\": `toggle-truncate-lines',
@@ -294,7 +304,8 @@ The body can be accessed via `toggle/body'.
Call the head: `nil'."
(interactive)
- (hydra-disable))
+ (hydra-disable)
+ (catch (quote hydra-disable)))
(defun toggle/body nil "Create a hydra with no body and the heads:
\"t\": `toggle-truncate-lines',
@@ -304,100 +315,19 @@ Call the head: `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)
- (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-amaranth-vi ()
- (should
- (equal
- (macroexpand
- '(defhydra hydra-vi
- (:pre
- (set-cursor-color "#40e0d0")
- :post
- (set-cursor-color "#ffffff")
- :color amaranth)
- "vi"
- ("l" forward-char)
- ("h" backward-char)
- ("j" next-line)
- ("k" previous-line)
- ("q" nil "quit")))
- '(progn
- (defun hydra-vi/forward-char nil "Create a hydra with no body and the
heads:
-
-\"l\": `forward-char',
-\"h\": `backward-char',
-\"j\": `next-line',
-\"k\": `previous-line',
-\"q\": `nil'
-
-The body can be accessed via `hydra-vi/body'.
-
-Call the head: `forward-char'."
- (interactive)
- (set-cursor-color "#40e0d0")
+ (hydra-disable)
(catch (quote hydra-disable)
- (hydra-disable)
- (condition-case err (prog1 t (call-interactively (function
forward-char)))
- ((debug error)
- (message "%S" err)
- (sit-for 0.8)
- nil))
- (when hydra-is-helpful (message #("vi: l, h, j, k, [q]: quit."
4 5 (face hydra-face-amaranth)
- 7 8 (face hydra-face-amaranth)
- 10 11 (face
hydra-face-amaranth)
- 13 14 (face
hydra-face-amaranth)
- 17 18 (face
hydra-face-blue))))
+ (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 (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: l, h, j,
k, [q]: quit." 4 5 (face hydra-face-amaranth)
- 7 8 (face
hydra-face-amaranth)
- 10 11 (face
hydra-face-amaranth)
- 13 14 (face
hydra-face-amaranth)
- 17 18 (face
hydra-face-blue)))))
- (113 . hydra-vi/nil)
- (107 . hydra-vi/previous-line)
- (106 . hydra-vi/next-line)
- (104 . hydra-vi/backward-char)
- (108 . hydra-vi/forward-char)
+ (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)
@@ -421,77 +351,27 @@ Call the head: `forward-char'."
(48 . hydra--digit-argument)
(45 . hydra--negative-argument)
(21 . hydra--universal-argument))))
- t (lambda nil (set-cursor-color "#ffffff"))))))
- (defun hydra-vi/backward-char nil "Create a hydra with no body and the
heads:
+ t))
+ (setq prefix-arg current-prefix-arg)))))))
-\"l\": `forward-char',
-\"h\": `backward-char',
-\"j\": `next-line',
-\"k\": `previous-line',
-\"q\": `nil'
-
-The body can be accessed via `hydra-vi/body'.
-
-Call the head: `backward-char'."
- (interactive)
- (set-cursor-color "#40e0d0")
- (catch (quote hydra-disable)
- (hydra-disable)
- (condition-case err (prog1 t (call-interactively (function
backward-char)))
- ((debug error)
- (message "%S" err)
- (sit-for 0.8)
- nil))
- (when hydra-is-helpful (message #("vi: l, h, j, k, [q]: quit."
4 5 (face hydra-face-amaranth)
- 7 8 (face hydra-face-amaranth)
- 10 11 (face
hydra-face-amaranth)
- 13 14 (face
hydra-face-amaranth)
- 17 18 (face
hydra-face-blue))))
- (setq hydra-last
- (hydra-set-transient-map
- (setq hydra-curr-map
- (quote (keymap (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: l, h, j,
k, [q]: quit." 4 5 (face hydra-face-amaranth)
- 7 8 (face
hydra-face-amaranth)
- 10 11 (face
hydra-face-amaranth)
- 13 14 (face
hydra-face-amaranth)
- 17 18 (face
hydra-face-blue)))))
- (113 . hydra-vi/nil)
- (107 . hydra-vi/previous-line)
- (106 . hydra-vi/next-line)
- (104 . hydra-vi/backward-char)
- (108 . hydra-vi/forward-char)
- (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 (lambda nil (set-cursor-color "#ffffff"))))))
- (defun hydra-vi/next-line nil "Create a hydra with no body and the heads:
+(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:
-\"l\": `forward-char',
-\"h\": `backward-char',
\"j\": `next-line',
\"k\": `previous-line',
\"q\": `nil'
@@ -499,65 +379,60 @@ Call the head: `backward-char'."
The body can be accessed via `hydra-vi/body'.
Call the head: `next-line'."
- (interactive)
- (set-cursor-color "#40e0d0")
- (catch (quote hydra-disable)
+ (interactive)
+ (set-cursor-color "#e52b50")
(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: l, h, j, k, [q]: quit."
4 5 (face hydra-face-amaranth)
- 7 8 (face hydra-face-amaranth)
- 10 11 (face
hydra-face-amaranth)
- 13 14 (face
hydra-face-amaranth)
- 17 18 (face
hydra-face-blue))))
- (setq hydra-last
- (hydra-set-transient-map
- (setq hydra-curr-map
- (quote (keymap (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: l, h, j,
k, [q]: quit." 4 5 (face hydra-face-amaranth)
- 7 8 (face
hydra-face-amaranth)
- 10 11 (face
hydra-face-amaranth)
- 13 14 (face
hydra-face-amaranth)
- 17 18 (face
hydra-face-blue)))))
- (113 . hydra-vi/nil)
- (107 . hydra-vi/previous-line)
- (106 . hydra-vi/next-line)
- (104 . hydra-vi/backward-char)
- (108 . hydra-vi/forward-char)
- (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 (lambda nil (set-cursor-color "#ffffff"))))))
- (defun hydra-vi/previous-line nil "Create a hydra with no body and the
heads:
+ (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:
-\"l\": `forward-char',
-\"h\": `backward-char',
\"j\": `next-line',
\"k\": `previous-line',
\"q\": `nil'
@@ -565,65 +440,60 @@ Call the head: `next-line'."
The body can be accessed via `hydra-vi/body'.
Call the head: `previous-line'."
- (interactive)
- (set-cursor-color "#40e0d0")
- (catch (quote hydra-disable)
+ (interactive)
+ (set-cursor-color "#e52b50")
(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: l, h, j, k, [q]: quit."
4 5 (face hydra-face-amaranth)
- 7 8 (face hydra-face-amaranth)
- 10 11 (face
hydra-face-amaranth)
- 13 14 (face
hydra-face-amaranth)
- 17 18 (face
hydra-face-blue))))
- (setq hydra-last
- (hydra-set-transient-map
- (setq hydra-curr-map
- (quote (keymap (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: l, h, j,
k, [q]: quit." 4 5 (face hydra-face-amaranth)
- 7 8 (face
hydra-face-amaranth)
- 10 11 (face
hydra-face-amaranth)
- 13 14 (face
hydra-face-amaranth)
- 17 18 (face
hydra-face-blue)))))
- (113 . hydra-vi/nil)
- (107 . hydra-vi/previous-line)
- (106 . hydra-vi/next-line)
- (104 . hydra-vi/backward-char)
- (108 . hydra-vi/forward-char)
- (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 (lambda nil (set-cursor-color "#ffffff"))))))
- (defun hydra-vi/nil nil "Create a hydra with no body and the heads:
+ (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:
-\"l\": `forward-char',
-\"h\": `backward-char',
\"j\": `next-line',
\"k\": `previous-line',
\"q\": `nil'
@@ -631,66 +501,66 @@ Call the head: `previous-line'."
The body can be accessed via `hydra-vi/body'.
Call the head: `nil'."
- (interactive)
- (set-cursor-color "#40e0d0")
- (hydra-disable)
- (set-cursor-color "#ffffff"))
- (defun hydra-vi/body nil "Create a hydra with no body and the heads:
+ (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:
-\"l\": `forward-char',
-\"h\": `backward-char',
\"j\": `next-line',
\"k\": `previous-line',
\"q\": `nil'
The body can be accessed via `hydra-vi/body'."
- (interactive)
- (set-cursor-color "#40e0d0")
- (when hydra-is-helpful (message #("vi: l, h, j, k, [q]: quit." 4
5 (face hydra-face-amaranth)
- 7 8 (face hydra-face-amaranth)
- 10 11 (face hydra-face-amaranth)
- 13 14 (face hydra-face-amaranth)
- 17 18 (face hydra-face-blue))))
- (setq hydra-last
- (hydra-set-transient-map
- (quote (keymap (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: l, h, j, k, [q]:
quit." 4 5 (face hydra-face-amaranth)
- 7 8 (face
hydra-face-amaranth)
- 10 11 (face
hydra-face-amaranth)
- 13 14 (face
hydra-face-amaranth)
- 17 18 (face
hydra-face-blue)))))
- (113 . hydra-vi/nil)
- (107 . hydra-vi/previous-line)
- (106 . hydra-vi/next-line)
- (104 . hydra-vi/backward-char)
- (108 . hydra-vi/forward-char)
- (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 (lambda nil (set-cursor-color "#ffffff")))))))))
+ (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))))))))
(provide 'hydra-test)
diff --git a/packages/hydra/hydra.el b/packages/hydra/hydra.el
index 6cbe705..2770fbc 100644
--- a/packages/hydra/hydra.el
+++ b/packages/hydra/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.8.0
+;; Version: 0.9.0
;; Keywords: bindings
;; Package-Requires: ((cl-lib "0.5"))
@@ -37,28 +37,42 @@
;; command. This makes the Hydra very seamless, it's like a minor
;; mode that disables itself automagically.
;;
-;; Here's how to use the examples bundled with Hydra:
+;; Here's an example Hydra, bound in the global map (you can use any
+;; keymap in place of `global-map'):
;;
-;; (require 'hydra-examples)
-;; (hydra-create "C-M-y" hydra-example-move-window-splitter)
-;; (hydra-create "M-g" hydra-example-goto-error)
+;; (defhydra hydra-zoom (global-map "<f2>")
+;; "zoom"
+;; ("g" text-scale-increase "in")
+;; ("l" text-scale-decrease "out"))
;;
-;; You can expand the examples in-place, it still looks elegant:
+;; It allows to start a command chain either like this:
+;; "<f2> gg4ll5g", or "<f2> lgllg".
;;
-;; (hydra-create "<f2>"
-;; '(("g" text-scale-increase "zoom in")
-;; ("l" text-scale-decrease "zoom out")))
+;; Here's another approach, when you just want a "callable keymap":
;;
-;; The third element of each list is the optional doc string that will
-;; be displayed in the echo area when `hydra-is-helpful' is t.
+;; (defhydra hydra-toggle (:color blue)
+;; "toggle"
+;; ("a" abbrev-mode "abbrev")
+;; ("d" toggle-debug-on-error "debug")
+;; ("f" auto-fill-mode "fill")
+;; ("t" toggle-truncate-lines "truncate")
+;; ("w" whitespace-mode "whitespace")
+;; ("q" nil "cancel"))
;;
-;; It's better to take the examples simply as templates and use
-;; `defhydra' instead of `hydra-create', since it's more flexible.
+;; This binds nothing so far, but if you follow up with:
;;
-;; (defhydra hydra-zoom (global-map "<f2>")
-;; "zoom"
-;; ("g" text-scale-increase "in")
-;; ("l" text-scale-decrease "out"))
+;; (global-set-key (kbd "C-c C-v") 'hydra-toggle/body)
+;;
+;; you will have bound "C-c C-v a", "C-c C-v d" etc.
+;;
+;; Knowing that `defhydra' defines e.g. `hydra-toggle/body' command,
+;; you can nest Hydras if you wish, with `hydra-toggle/body' possibly
+;; becoming a blue head of another Hydra.
+;;
+;; Initially, Hydra shipped with a simplified `hydra-create' macro, to
+;; which you could hook up the examples from hydra-examples.el. It's
+;; better to take the examples simply as templates and use `defhydra'
+;; instead of `hydra-create', since it's more flexible.
;;; Code:
;;* Requires
@@ -80,6 +94,11 @@
:type 'boolean
:group 'hydra)
+(defcustom hydra-keyboard-quit ""
+ "This binding will quit an amaranth Hydra.
+It's the only other way to quit it besides though a blue head.
+It's possible to set this to nil.")
+
(defface hydra-face-red
'((t (:foreground "#7F0055" :bold t)))
"Red Hydra heads will persist indefinitely."
@@ -158,14 +177,31 @@
(and (consp x)
(memq (car x) '(function quote)))))
+(defun hydra--make-callable (x)
+ "Generate a callable symbol from X.
+If X is a function symbol or a lambda, return it. Otherwise, it
+should be a single statement. Wrap it in an interactive lambda."
+ (if (or (symbolp x) (functionp x))
+ x
+ `(lambda ()
+ (interactive)
+ ,x)))
+
+(defun hydra--head-property (h prop &optional default)
+ "Return for Hydra head H the value of property PROP.
+Return DEFAULT if PROP is not in H."
+ (let ((plist (if (stringp (cl-caddr h))
+ (cl-cdddr h)
+ (cddr h))))
+ (if (memq prop h)
+ (plist-get plist prop)
+ default)))
+
(defun hydra--color (h body-color)
"Return the color of a Hydra head H with BODY-COLOR."
(if (null (cadr h))
'blue
- (let ((plist (if (stringp (cl-caddr h))
- (cl-cdddr h)
- (cddr h))))
- (or (plist-get plist :color) body-color))))
+ (or (hydra--head-property h :color) body-color)))
(defun hydra--face (h body-color)
"Return the face for a Hydra head H with BODY-COLOR."
@@ -226,6 +262,39 @@ HEADS is a list of heads."
heads ",\n")
(format "The body can be accessed via `%S'." body-name)))
+(defun hydra--make-defun (name cmd color
+ doc hint keymap
+ body-color body-pre body-post &optional other-post)
+ "Make a defun wrapper, using NAME, CMD, COLOR, DOC, HINT, and KEYMAP.
+BODY-COLOR, BODY-PRE, BODY-POST, and OTHER-POST are used as well."
+ `(defun ,name ()
+ ,doc
+ (interactive)
+ ,@(when body-pre (list body-pre))
+ (hydra-disable)
+ (catch 'hydra-disable
+ ,@(delq nil
+ (if (eq color 'blue)
+ `(,(when cmd `(call-interactively #',cmd))
+ ,body-post)
+ `(,(when cmd
+ `(condition-case err
+ (prog1 t
+ (call-interactively #',cmd))
+ ((debug error)
+ (message "%S" err)
+ (sit-for 0.8)
+ nil)))
+ (when hydra-is-helpful
+ (message ,hint))
+ (setq hydra-last
+ (hydra-set-transient-map
+ (setq hydra-curr-map ',keymap)
+ t
+ ,@(if (and (not (eq body-color 'amaranth))
body-post)
+ `((lambda () ,body-post)))))
+ ,other-post))))))
+
;;* Macros
;;** hydra-create
;;;###autoload
@@ -244,7 +313,8 @@ It defaults to `global-set-key'.
When `(keymapp METHOD)`, it becomes:
(lambda (key command) (define-key METHOD key command))"
- (declare (indent 1))
+ (declare (indent 1)
+ (obsolete defhydra "0.8.0"))
`(defhydra ,(intern
(concat
"hydra-" (replace-regexp-in-string " " "_" body)))
@@ -260,28 +330,41 @@ When `(keymapp METHOD)`, it becomes:
;;** defhydra
;;;###autoload
(defmacro defhydra (name body &optional docstring &rest heads)
- "Create a hydra named NAME with a prefix BODY.
+ "Create a Hydra - a family of functions with prefix NAME.
NAME should be a symbol, it will be the prefix of all functions
defined here.
-BODY should be either:
+BODY has the format:
- (BODY-MAP &optional BODY-KEY &rest PLIST)
-or:
+ (BODY-MAP BODY-KEY &rest PLIST)
- (lambda (KEY CMD) ...)
+DOCSTRING will be displayed in the echo area to identify the
+Hydra.
-BODY-MAP should be a keymap; `global-map' is acceptable here.
-BODY-KEY should be a string processable by `kbd'.
+Functions are created on basis of HEADS, each of which has the
+format:
-DOCSTRING will be displayed in the echo area to identify the
-hydra.
+ (KEY CMD &optional HINT &rest PLIST)
+
+BODY-MAP is a keymap; `global-map' is used quite often. Each
+function generated from HEADS will be bound in BODY-MAP to
+BODY-KEY + KEY, and will set the transient map so that all
+following heads can be called though KEY only.
-HEADS is a list of (KEY CMD &optional HINT &rest PLIST).
+The heads inherit their PLIST from the body and are allowed to
+override each key. The keys recognized are :color and :bind.
+:color can be:
-PLIST in both cases recognizes only the :color key so far, which
-in turn can be either red or blue."
+- red (default): this head will continue the Hydra state.
+- blue: this head will stop the Hydra state.
+- amaranth (applies to body only): similar to red, but no binding
+except a blue head can stop the Hydra state.
+
+:bind can be:
+- nil: this head will not be bound in BODY-MAP.
+- a lambda taking KEY and CMD used to bind a head"
+ (declare (indent 2))
(unless (stringp docstring)
(setq heads (cons docstring heads))
(setq docstring "hydra"))
@@ -305,14 +388,17 @@ in turn can be either red or blue."
'red)))
(body-pre (plist-get (cddr body) :pre))
(body-post (plist-get (cddr body) :post))
- (method (if (hydra--callablep body)
- body
- (car body)))
+ (method (or (plist-get body :bind)
+ (car body)))
(hint (hydra--hint docstring heads body-color))
(doc (hydra--doc body-key body-name heads)))
(when (and (or body-pre body-post)
(version< emacs-version "24.4"))
(error "At least Emacs 24.4 is needed for :pre and :post"))
+ (when (and body-pre (symbolp body-pre))
+ (setq body-pre `(funcall #',body-pre)))
+ (when (and body-post (symbolp body-post))
+ (setq body-post `(funcall #',body-post)))
(when (eq body-color 'amaranth)
(if (cl-some `(lambda (h)
(eq (hydra--color h ',body-color) 'blue))
@@ -325,35 +411,21 @@ in turn can be either red or blue."
(when hydra-is-helpful
(sit-for 0.8)
(message ,hint))))
- (error "An amaranth Hydra must have at least one blue head in order to
exit")))
+ (error "An amaranth Hydra must have at least one blue head in order to
exit"))
+ (when hydra-keyboard-quit
+ (define-key keymap hydra-keyboard-quit
+ `(lambda ()
+ (interactive)
+ (hydra-disable)
+ ,body-post))))
`(progn
,@(cl-mapcar
(lambda (head name)
- `(defun ,name ()
- ,(format "%s\n\nCall the head: `%S'." doc (cadr head))
- (interactive)
- ,@(if body-pre (list body-pre))
- ,@(if (eq (hydra--color head body-color) 'blue)
- `((hydra-disable)
- ,@(unless (null (cadr head))
- `((call-interactively #',(cadr head))))
- ,@(if body-post (list body-post)))
- `((catch 'hydra-disable
- (hydra-disable)
- (condition-case err
- (prog1 t
- (call-interactively #',(cadr head)))
- ((debug error)
- (message "%S" err)
- (sit-for 0.8)
- nil))
- (when hydra-is-helpful
- (message ,hint))
- (setq hydra-last
- (hydra-set-transient-map
- (setq hydra-curr-map ',keymap)
- t
- ,@(if body-post `((lambda ()
,body-post))))))))))
+ (hydra--make-defun
+ name (hydra--make-callable (cadr head)) (hydra--color head
body-color)
+ (format "%s\n\nCall the head: `%S'." doc (cadr head))
+ hint keymap
+ body-color body-pre body-post))
heads names)
,@(unless (or (null body-key)
(null method)
@@ -363,26 +435,33 @@ in turn can be either red or blue."
,@(delq nil
(cl-mapcar
(lambda (head name)
- (unless (or (null body-key) (null method))
- (list
- (if (hydra--callablep method)
- 'funcall
- 'define-key)
- method
- (vconcat (kbd body-key) (kbd (car head)))
- (list 'function name))))
+ (when (or body-key method)
+ (let ((bind (hydra--head-property head :bind 'default))
+ (final-key (if body-key
+ (vconcat (kbd body-key) (kbd (car
head)))
+ (kbd (car head)))))
+ (cond ((null bind) nil)
+
+ ((eq bind 'default)
+ (list
+ (if (hydra--callablep method)
+ 'funcall
+ 'define-key)
+ method
+ final-key
+ (list 'function name)))
+
+ ((hydra--callablep bind)
+ `(funcall (function ,bind)
+ ,final-key
+ (function ,name)))
+
+ (t
+ (error "Invalid :bind property %S" head))))))
heads names))
- (defun ,body-name ()
- ,doc
- (interactive)
- ,@(if body-pre (list body-pre))
- (when hydra-is-helpful
- (message ,hint))
- (setq hydra-last
- (hydra-set-transient-map
- ',keymap
- t
- ,@(if body-post `((lambda () ,body-post)))))))))
+ ,(hydra--make-defun body-name nil nil doc hint keymap
+ body-color body-pre body-post
+ '(setq prefix-arg current-prefix-arg)))))
(provide 'hydra)
- [elpa] master 9b31ead 08/17: Update semantics for local heads to `:bind nil', (continued)
- [elpa] master 9b31ead 08/17: Update semantics for local heads to `:bind nil', Oleh Krehel, 2015/02/10
- [elpa] master 969fa66 10/17: fix typo - single not singe, Oleh Krehel, 2015/02/10
- [elpa] master d41be74 11/17: `hydra/body' will pass the initial `current-prefix-arg' along, Oleh Krehel, 2015/02/10
- [elpa] master ad771a4 03/17: Move defun-creating code into a defun, Oleh Krehel, 2015/02/10
- [elpa] master 763bb2a 13/17: Allow lambda :bind property for body and heads, Oleh Krehel, 2015/02/10
- [elpa] master 0712a43 12/17: README.md: update, Oleh Krehel, 2015/02/10
- [elpa] master d10c26e 14/17: Update comments and mark the old examples obsolete, Oleh Krehel, 2015/02/10
- [elpa] master 0c08964 16/17: README.md: update, Oleh Krehel, 2015/02/10
- [elpa] master 4ca646e 15/17: Allow a sexp as head's CMD paramater, Oleh Krehel, 2015/02/10
- [elpa] master bb01930 09/17: Fix "catch 'hydra-disable", Oleh Krehel, 2015/02/10
- [elpa] master 11b130e 17/17: Merge commit '0c08964462812942db51d177e6ea922b26019e65' from hydra,
Oleh Krehel <=