[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] master f31d537 26/27: Add 'packages/hydra/' from commit 'cfac8bd9
From: |
Oleh Krehel |
Subject: |
[elpa] master f31d537 26/27: Add 'packages/hydra/' from commit 'cfac8bd9e73ea1e219250867b22881354fc2d56e' |
Date: |
Sat, 24 Jan 2015 20:36:38 +0000 |
branch: master
commit f31d537957ab67e08369b5be314e66a89ace3600
Merge: 685c83b cfac8bd
Author: Oleh Krehel <address@hidden>
Commit: Oleh Krehel <address@hidden>
Add 'packages/hydra/' from commit 'cfac8bd9e73ea1e219250867b22881354fc2d56e'
git-subtree-dir: packages/hydra
git-subtree-mainline: 685c83b6320396e3cc6d7b4eb79d7481fe059416
git-subtree-split: cfac8bd9e73ea1e219250867b22881354fc2d56e
---
packages/hydra/README.md | 77 +++++++++++++++++++
packages/hydra/hydra-examples.el | 85 +++++++++++++++++++++
packages/hydra/hydra.el | 154 ++++++++++++++++++++++++++++++++++++++
3 files changed, 316 insertions(+), 0 deletions(-)
diff --git a/packages/hydra/README.md b/packages/hydra/README.md
new file mode 100644
index 0000000..f7ddd40
--- /dev/null
+++ b/packages/hydra/README.md
@@ -0,0 +1,77 @@
+This is a package for GNU Emacs that can be used to tie related
+commands into a family of short bindings with a common prefix - a
+Hydra.
+
+Once you summon the Hydra through the prefixed binding (the body + any
+one head), all heads can be called in succession with only a short
+extension.
+
+The Hydra is vanquished once Hercules, any binding that isn't the
+Hydra's head, arrives. Note that Hercules, besides vanquishing the
+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.
+
+Here's how I use the examples bundled with Hydra:
+
+ (require 'hydra-examples)
+ (hydra-create "C-M-y" hydra-example-move-window-splitter)
+ (hydra-create "M-g" hydra-example-goto-error)
+
+You can expand the examples in-place, it still looks elegant:
+
+ (hydra-create "<f2>"
+ '(("g" text-scale-increase)
+ ("l" text-scale-decrease)))
+
+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 "C-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 "C-z"
+ '(("l" forward-char)
+ ("h" backward-char)
+ ("j" next-line)
+ ("k" previous-line))
+ lispy-mode-map)
+```
+
+## Can Hydras can be helpful?
+
+They can, if
+
+```cl
+(setq hydra-is-helpful t)
+```
+
+In that case, you'll get a hint in the echo area consisting of current Hydra's
heads.
+You can even add comments to the heads like this:
+
+```
+(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.")
+```
+
+With this, you'll see `hydra: [g]: zoom in, [l]: zoom out.` in your
+echo area, once the zoom Hydra becomes active.
diff --git a/packages/hydra/hydra-examples.el b/packages/hydra/hydra-examples.el
new file mode 100644
index 0000000..c07bd8e
--- /dev/null
+++ b/packages/hydra/hydra-examples.el
@@ -0,0 +1,85 @@
+;;; hydra-examples.el --- Some applications for Hydra
+
+;; Copyright (C) 2015 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; These are the sample Hydras that you can use.
+
+;;; 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.")
+
+(require 'windmove)
+
+(defun hydra-move-splitter-left ()
+ "Move window splitter left."
+ (interactive)
+ (if (let ((windmove-wrap-around))
+ (windmove-find-other-window 'right))
+ (shrink-window-horizontally 1)
+ (enlarge-window-horizontally 1)))
+
+(defun hydra-move-splitter-right ()
+ "Move window splitter right."
+ (interactive)
+ (if (let ((windmove-wrap-around))
+ (windmove-find-other-window 'right))
+ (enlarge-window-horizontally 1)
+ (shrink-window-horizontally 1)))
+
+(defun hydra-move-splitter-up ()
+ "Move window splitter up."
+ (interactive)
+ (if (let ((windmove-wrap-around))
+ (windmove-find-other-window 'up))
+ (enlarge-window 1)
+ (shrink-window 1)))
+
+(defun hydra-move-splitter-down ()
+ "Move window splitter down."
+ (interactive)
+ (if (let ((windmove-wrap-around))
+ (windmove-find-other-window 'up))
+ (shrink-window 1)
+ (enlarge-window 1)))
+
+(defvar hydra-example-move-window-splitter
+ '(("h" hydra-move-splitter-left)
+ ("j" hydra-move-splitter-down)
+ ("k" hydra-move-splitter-up)
+ ("l" hydra-move-splitter-right))
+ "A four-headed hydra for the window splitter manipulation.
+Works best if you have not more than 4 windows.")
+
+(defvar hydra-example-goto-error
+ '(("h" first-error "first")
+ ("j" next-error "next")
+ ("k" previous-error "prev"))
+ "A three-headed hydra for jumping between \"errors\".
+Useful for e.g. `occur', `rgrep' and the like.")
+
+(provide 'hydra-examples)
+;;; hydra-examples.el ends here
diff --git a/packages/hydra/hydra.el b/packages/hydra/hydra.el
new file mode 100644
index 0000000..932cea2
--- /dev/null
+++ b/packages/hydra/hydra.el
@@ -0,0 +1,154 @@
+;;; hydra.el --- Make bindings that stick around
+
+;; Copyright (C) 2015 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel <address@hidden>
+;; Maintainer: Oleh Krehel <address@hidden>
+;; URL: https://github.com/abo-abo/hydra
+;; Version: 0.3.0
+;; Keywords: bindings
+;; Package-Requires: ((cl-lib "0.5"))
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; This package can be used to tie related commands into a family of
+;; short bindings with a common prefix - a Hydra.
+;;
+;; Once you summon the Hydra (through the prefixed binding), all the
+;; heads can be called in succession with only a short extension.
+;; The Hydra is vanquished once Hercules, any binding that isn't the
+;; Hydra's head, arrives. Note that Hercules, besides vanquishing the
+;; 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 automagically.
+;;
+;; Here's how to use the examples bundled with Hydra:
+;;
+;; (require 'hydra-examples)
+;; (hydra-create "C-M-y" hydra-example-move-window-splitter)
+;; (hydra-create "M-g" hydra-example-goto-error)
+;;
+;; You can expand the examples in-place, it still looks elegant:
+;;
+;; (hydra-create "<f2>"
+;; '(("g" text-scale-increase "zoom in")
+;; ("l" text-scale-decrease "zoom out")))
+;;
+;; 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.
+
+;;; Code:
+(require 'cl-lib)
+
+(defgroup hydra nil
+ "Make bindings that stick around."
+ :group 'bindings
+ :prefix "hydra-")
+
+(defcustom hydra-is-helpful t
+ "When t, display a hint with possible bindings in the echo area."
+ :type 'boolean
+ :group 'hydra)
+
+(defalias 'hydra-set-transient-map
+ (if (fboundp 'set-transient-map)
+ 'set-transient-map
+ 'set-temporary-overlay-map))
+
+(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))
+ (let* ((keymap (make-sparse-keymap))
+ (heads (eval heads))
+ (names (mapcar
+ (lambda (x)
+ (define-key keymap (kbd (car x))
+ (intern (format "hydra-%s-%S" body (cadr x)))))
+ heads))
+ (hint (format "hydra: %s."
+ (mapconcat
+ (lambda (h)
+ (format
+ (if (cl-caddr h)
+ (concat "[%s]: " (cl-caddr h))
+ "%s")
+ (propertize (car h) 'face 'font-lock-keyword-face)))
+ heads ", ")))
+ (doc (format
+ "Create a hydra with a \"%s\" body and the heads:\n\n%s."
+ body
+ (mapconcat
+ (lambda (x)
+ (format "\"%s\": `%S'" (car x) (cadr x)))
+ heads ",\n")))
+ map
+ (method
+ (cond ((null method)
+ (unless (keymapp (global-key-binding (kbd body)))
+ (global-set-key (kbd body) nil))
+ 'global-set-key)
+ ((keymapp (setq map (eval method)))
+ (unless (keymapp (lookup-key map (kbd body)))
+ (define-key map (kbd body) nil))
+ `(lambda (key command)
+ (define-key ,method key command)))
+ (t
+ method))))
+ `(progn
+ ,@(cl-mapcar
+ (lambda (head name)
+ `(defun ,name ()
+ ,(format "%s\n\nCall the head: `%S'." doc (cadr head))
+ (interactive)
+ ,@(if (null (cadr head))
+ '((funcall hydra-last))
+ `((call-interactively #',(cadr head))
+ (when hydra-is-helpful
+ (message ,hint))
+ (setq hydra-last (hydra-set-transient-map ',keymap
t))))))
+ heads names)
+ (defun ,(intern (format "hydra-%s-body" body)) ()
+ ,doc
+ (interactive)
+ (when hydra-is-helpful
+ (message ,hint))
+ (setq hydra-last (hydra-set-transient-map ',keymap t)))
+ ,@(cl-mapcar
+ (lambda (head name)
+ `(,method ,(vconcat (kbd body) (kbd (car head))) #',name))
+ heads names))))
+
+(provide 'hydra)
+;;; hydra.el ends here
- [elpa] master dfe1273 19/27: Simplify and improve the generated defuns, (continued)
- [elpa] master dfe1273 19/27: Simplify and improve the generated defuns, Oleh Krehel, 2015/01/24
- [elpa] master 301b500 16/27: Don't undefine BODY's global binding when it's a prefix, Oleh Krehel, 2015/01/24
- [elpa] master 42538fa 18/27: Add a `next-error'/`previous-error'/`first-error' example, Oleh Krehel, 2015/01/24
- [elpa] master dc0246e 20/27: hydra-examples.el (hydra-example-goto-error): add doc, Oleh Krehel, 2015/01/24
- [elpa] master ddd96d1 23/27: hydra-examples.el: add a `windmove' Hydra, Oleh Krehel, 2015/01/24
- [elpa] master 64e5b91 22/27: Avoid evaling METHOD., Oleh Krehel, 2015/01/24
- [elpa] master 440c41c 24/27: Bump version, Oleh Krehel, 2015/01/24
- [elpa] master cfac8bd 21/27: Prepare for the first version in GNU ELPA, Oleh Krehel, 2015/01/24
- [elpa] master 7b78b37 27/27: Merge commit '440c41cc3f5137d694211719abaa38c0193a08a2' from hydra, Oleh Krehel, 2015/01/24
- [elpa] master 685c83b 25/27: Setup git subtree add for hydra, Oleh Krehel, 2015/01/24
- [elpa] master f31d537 26/27: Add 'packages/hydra/' from commit 'cfac8bd9e73ea1e219250867b22881354fc2d56e',
Oleh Krehel <=