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

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

[elpa] master 9b86656 01/27: Initial import


From: Oleh Krehel
Subject: [elpa] master 9b86656 01/27: Initial import
Date: Sat, 24 Jan 2015 20:36:28 +0000

branch: master
commit 9b866564f4b881ad54214659f2853de207074b33
Author: Oleh Krehel <address@hidden>
Commit: Oleh Krehel <address@hidden>

    Initial import
---
 README.md |   24 +++++++++++
 hydra.el  |  137 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 161 insertions(+), 0 deletions(-)

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..bb153d7
--- /dev/null
+++ b/README.md
@@ -0,0 +1,24 @@
+This 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 a 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 auto-magically.
+
+Here's how I use the examples bundled with Hydra:
+
+    (hydra-create "C-M-w" hydra-example-move-window-splitter)
+
+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.
+
+![hydra](http://oremacs.com/download/Hydra.png)
diff --git a/hydra.el b/hydra.el
new file mode 100644
index 0000000..2cfcc53
--- /dev/null
+++ b/hydra.el
@@ -0,0 +1,137 @@
+;;; hydra.el --- make bindings that stick around.
+
+;; Copyright (C) 2015 Oleh Krehel
+
+;; Author: Oleh Krehel <address@hidden>
+;; URL: https://github.com/abo-abo/hydra
+;; Version: 0.1.0
+;; Keywords: bindings
+
+;; This file is not part of GNU Emacs
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This program 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.
+
+;; For a full copy of the GNU General Public License
+;; 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 I use the examples bundled with Hydra:
+;;
+;;    (hydra-create "C-M-w" hydra-example-move-window-splitter)
+;;
+;; You can expand the examples in-place, it still looks elegant:
+;;
+;;     (hydra-create "<f2>"
+;;       '(("g" . text-scale-increase)
+;;         ("l" . text-scale-decrease)))
+
+;;; Code:
+
+(defmacro hydra-create (body heads)
+  "Create a hydra with a BODY prefix and HEADS.
+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."
+  (declare (indent 1))
+  (let* ((keymap (make-sparse-keymap))
+         (heads (eval heads))
+         (names (mapcar
+                 (lambda (x)
+                   (define-key keymap (car x)
+                     (intern (format "hydra-%s-%S" body (cdr x)))))
+                 heads)))
+    `(progn
+       (when (global-key-binding ,(kbd body))
+         (global-set-key ,(kbd body) nil))
+       ,@(cl-mapcar
+          (lambda (head name)
+            `(defun ,name ()
+               ,(format
+                 "Create a hydra with a \"%s\" body and the heads:
+
+%s.
+
+Call the head: `%S'."
+                 body
+                 (mapconcat
+                  (lambda (x)
+                    (format "\"%s\":    `%S'" (car x) (cdr x)))
+                  heads ",\n")
+                 (cdr head))
+               (interactive)
+               (call-interactively #',(cdr head))
+               (set-transient-map ',keymap t)))
+          heads names)
+       ,@(cl-mapcar
+          (lambda (head name)
+            `(global-set-key ,(kbd (concat body " " (car head))) #',name))
+          heads names))))
+
+(defvar hydra-example-text-scale
+  '(("g" . text-scale-increase)
+    ("l" . text-scale-decrease))
+  "A two-headed hydra for text scale manipulation.")
+
+(require 'windmove)
+
+(defun move-splitter-left ()
+  "Move window splitter left."
+  (interactive)
+  (if (windmove-find-other-window 'right)
+      (shrink-window-horizontally 1)
+    (enlarge-window-horizontally 1)))
+
+(defun move-splitter-right ()
+  "Move window splitter right."
+  (interactive)
+  (if (windmove-find-other-window 'right)
+      (enlarge-window-horizontally 1)
+    (shrink-window-horizontally 1)))
+
+(defun move-splitter-up ()
+  "Move window splitter up."
+  (interactive)
+  (if (windmove-find-other-window 'up)
+      (enlarge-window 1)
+    (shrink-window 1)))
+
+(defun move-splitter-down ()
+  "Move window splitter down."
+  (interactive)
+  (if (windmove-find-other-window 'up)
+      (shrink-window 1)
+    (enlarge-window 1)))
+
+(defvar hydra-example-move-window-splitter
+  '(("h" . move-splitter-left)
+    ("j" . move-splitter-down)
+    ("k" . move-splitter-up)
+    ("l" . move-splitter-right)))
+
+(provide 'hydra)
+
+;;; hydra.el ends here



reply via email to

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