]> code.delx.au - gnu-emacs-elpa/blob - packages/hydra/hydra-examples.el
Add 'packages/loc-changes/' from commit 'efbe022eaeef0ccc54ffe219216974a786c3301c'
[gnu-emacs-elpa] / packages / hydra / hydra-examples.el
1 ;;; hydra-examples.el --- Some applications for Hydra
2
3 ;; Copyright (C) 2015 Free Software Foundation, Inc.
4
5 ;; Author: Oleh Krehel
6
7 ;; This file is part of GNU Emacs.
8
9 ;; GNU Emacs is free software: you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation, either version 3 of the License, or
12 ;; (at your option) any later version.
13
14 ;; GNU Emacs is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
21
22 ;;; Commentary:
23 ;;
24 ;; These are the sample Hydras.
25 ;;
26 ;; If you want to use them plainly, set `hydra-examples-verbatim' to t
27 ;; before requiring this file. But it's probably better to only look
28 ;; at them and use them as templates for building your own.
29
30 ;;; Code:
31
32 (require 'hydra)
33
34 ;;* Examples
35 ;;** Example 1: text scale
36 (when (bound-and-true-p hydra-examples-verbatim)
37 (defhydra hydra-zoom (global-map "<f2>")
38 "zoom"
39 ("g" text-scale-increase "in")
40 ("l" text-scale-decrease "out")))
41
42 ;; This example generates three commands:
43 ;;
44 ;; `hydra-zoom/text-scale-increase'
45 ;; `hydra-zoom/text-scale-decrease'
46 ;; `hydra-zoom/body'
47 ;;
48 ;; In addition, two of them are bound like this:
49 ;;
50 ;; (global-set-key (kbd "<f2> g") 'hydra-zoom/text-scale-increase)
51 ;; (global-set-key (kbd "<f2> l") 'hydra-zoom/text-scale-decrease)
52 ;;
53 ;; Note that you can substitute `global-map' with e.g. `emacs-lisp-mode-map' if you need.
54 ;; The functions generated will be the same, except the binding code will change to:
55 ;;
56 ;; (define-key emacs-lisp-mode-map [f2 103]
57 ;; (function hydra-zoom/text-scale-increase))
58 ;; (define-key emacs-lisp-mode-map [f2 108]
59 ;; (function hydra-zoom/text-scale-decrease))
60
61 ;;** Example 2: move window splitter
62 (when (bound-and-true-p hydra-examples-verbatim)
63 (defhydra hydra-splitter (global-map "C-M-s")
64 "splitter"
65 ("h" hydra-move-splitter-left)
66 ("j" hydra-move-splitter-down)
67 ("k" hydra-move-splitter-up)
68 ("l" hydra-move-splitter-right)))
69
70 ;;** Example 3: jump to error
71 (when (bound-and-true-p hydra-examples-verbatim)
72 (defhydra hydra-error (global-map "M-g")
73 "goto-error"
74 ("h" first-error "first")
75 ("j" next-error "next")
76 ("k" previous-error "prev")
77 ("v" recenter-top-bottom "recenter")
78 ("q" nil "quit")))
79
80 ;; This example introduces only one new thing: since the command
81 ;; passed to the "q" head is nil, it will quit the Hydra without doing
82 ;; anything. Heads that quit the Hydra instead of continuing are
83 ;; referred to as having blue :color. All the other heads have red
84 ;; :color, unless other is specified.
85
86 ;;** Example 4: toggle rarely used modes
87 (when (bound-and-true-p hydra-examples-verbatim)
88 (global-set-key
89 (kbd "C-c C-v")
90 (defhydra hydra-toggle (:color blue)
91 "toggle"
92 ("a" abbrev-mode "abbrev")
93 ("d" toggle-debug-on-error "debug")
94 ("f" auto-fill-mode "fill")
95 ("t" toggle-truncate-lines "truncate")
96 ("w" whitespace-mode "whitespace")
97 ("q" nil "cancel"))))
98
99 ;; Note that in this case, `defhydra' returns the `hydra-toggle/body'
100 ;; symbol, which is then passed to `global-set-key'.
101 ;;
102 ;; Another new thing is that both the keymap and the body prefix are
103 ;; skipped. This means that `defhydra' will bind nothing - that's why
104 ;; `global-set-key' is necessary.
105 ;;
106 ;; One more new thing is that you can assign a :color to the body. All
107 ;; heads will inherit this color. The code above is very much equivalent to:
108 ;;
109 ;; (global-set-key (kbd "C-c C-v a") 'abbrev-mode)
110 ;; (global-set-key (kbd "C-c C-v d") 'toggle-debug-on-error)
111 ;;
112 ;; The differences are:
113 ;;
114 ;; * You get a hint immediately after "C-c C-v"
115 ;; * You can cancel and call a command immediately, e.g. "C-c C-v C-n"
116 ;; is equivalent to "C-n" with Hydra approach, while it will error
117 ;; that "C-c C-v C-n" isn't bound with the usual approach.
118
119 ;;** Example 5: mini-vi
120 (defun hydra-vi/pre ()
121 (set-cursor-color "#e52b50"))
122
123 (defun hydra-vi/post ()
124 (set-cursor-color "#ffffff"))
125
126 (when (bound-and-true-p hydra-examples-verbatim)
127 (global-set-key
128 (kbd "C-z")
129 (defhydra hydra-vi (:pre hydra-vi/pre :post hydra-vi/post :color amaranth)
130 "vi"
131 ("l" forward-char)
132 ("h" backward-char)
133 ("j" next-line)
134 ("k" previous-line)
135 ("m" set-mark-command "mark")
136 ("a" move-beginning-of-line "beg")
137 ("e" move-end-of-line "end")
138 ("d" delete-region "del" :color blue)
139 ("y" kill-ring-save "yank" :color blue)
140 ("q" nil "quit"))))
141
142 ;; This example introduces :color amaranth. It's similar to red,
143 ;; except while you can quit red with any binding which isn't a Hydra
144 ;; head, you can quit amaranth only with a blue head. So you can quit
145 ;; this mode only with "d", "y", "q" or "C-g".
146 ;;
147 ;; Another novelty are the :pre and :post handlers. :pre will be
148 ;; called before each command, while :post will be called when the
149 ;; Hydra quits. In this case, they're used to override the cursor
150 ;; color while Hydra is active.
151
152 ;;** Example 6: selective global bind
153 (when (bound-and-true-p hydra-examples-verbatim)
154 (defhydra hydra-next-error (global-map "C-x")
155 "next-error"
156 ("`" next-error "next")
157 ("j" next-error "next" :bind nil)
158 ("k" previous-error "previous" :bind nil)))
159
160 ;; This example will bind "C-x `" in `global-map', but it will not
161 ;; bind "C-x j" and "C-x k".
162 ;; You can still "C-x `jjk" though.
163
164 ;;* Windmove helpers
165 (require 'windmove)
166
167 (defun hydra-move-splitter-left (arg)
168 "Move window splitter left."
169 (interactive "p")
170 (if (let ((windmove-wrap-around))
171 (windmove-find-other-window 'right))
172 (shrink-window-horizontally arg)
173 (enlarge-window-horizontally arg)))
174
175 (defun hydra-move-splitter-right (arg)
176 "Move window splitter right."
177 (interactive "p")
178 (if (let ((windmove-wrap-around))
179 (windmove-find-other-window 'right))
180 (enlarge-window-horizontally arg)
181 (shrink-window-horizontally arg)))
182
183 (defun hydra-move-splitter-up (arg)
184 "Move window splitter up."
185 (interactive "p")
186 (if (let ((windmove-wrap-around))
187 (windmove-find-other-window 'up))
188 (enlarge-window arg)
189 (shrink-window arg)))
190
191 (defun hydra-move-splitter-down (arg)
192 "Move window splitter down."
193 (interactive "p")
194 (if (let ((windmove-wrap-around))
195 (windmove-find-other-window 'up))
196 (shrink-window arg)
197 (enlarge-window arg)))
198
199 ;;* Obsoletes
200 (defvar hydra-example-text-scale
201 '(("g" text-scale-increase "zoom in")
202 ("l" text-scale-decrease "zoom out"))
203 "A two-headed hydra for text scale manipulation.")
204 (make-obsolete-variable
205 'hydra-example-text-scale
206 "Don't use `hydra-example-text-scale', just write your own
207 `defhydra' using hydra-examples.el as a template"
208 "0.9.0")
209
210 (defvar hydra-example-move-window-splitter
211 '(("h" hydra-move-splitter-left)
212 ("j" hydra-move-splitter-down)
213 ("k" hydra-move-splitter-up)
214 ("l" hydra-move-splitter-right))
215 "A four-headed hydra for the window splitter manipulation.
216 Works best if you have not more than 4 windows.")
217 (make-obsolete-variable
218 'hydra-example-move-window-splitter
219 "Don't use `hydra-example-move-window-splitter', just write your own
220 `defhydra' using hydra-examples.el as a template"
221 "0.9.0")
222
223 (defvar hydra-example-goto-error
224 '(("h" first-error "first")
225 ("j" next-error "next")
226 ("k" previous-error "prev"))
227 "A three-headed hydra for jumping between \"errors\".
228 Useful for e.g. `occur', `rgrep' and the like.")
229 (make-obsolete-variable
230 'hydra-example-goto-error
231 "Don't use `hydra-example-goto-error', just write your own
232 `defhydra' using hydra-examples.el as a template"
233 "0.9.0")
234
235 (defvar hydra-example-windmove
236 '(("h" windmove-left)
237 ("j" windmove-down)
238 ("k" windmove-up)
239 ("l" windmove-right))
240 "A four-headed hydra for `windmove'.")
241 (make-obsolete-variable
242 'hydra-example-windmove
243 "Don't use `hydra-example-windmove', just write your own
244 `defhydra' using hydra-examples.el as a template"
245 "0.9.0")
246
247 (provide 'hydra-examples)
248 ;;; hydra-examples.el ends here