38436
|
1 ;;; easy-mmode.el --- easy definition for major and minor modes
|
18388
|
2
|
68648
|
3 ;; Copyright (C) 1997, 2000, 2001, 2002, 2003, 2004, 2005,
|
79704
|
4 ;; 2006, 2007, 2008 Free Software Foundation, Inc.
|
18388
|
5
|
38455
|
6 ;; Author: Georges Brun-Cottan <Georges.Brun-Cottan@inria.fr>
|
|
7 ;; Maintainer: Stefan Monnier <monnier@gnu.org>
|
|
8
|
|
9 ;; Keywords: extensions lisp
|
18388
|
10
|
|
11 ;; This file is part of GNU Emacs.
|
|
12
|
|
13 ;; GNU Emacs is free software; you can redistribute it and/or modify
|
|
14 ;; it under the terms of the GNU General Public License as published by
|
78217
|
15 ;; the Free Software Foundation; either version 3, or (at your option)
|
18388
|
16 ;; any later version.
|
|
17
|
|
18 ;; GNU Emacs is distributed in the hope that it will be useful,
|
|
19 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
21 ;; GNU General Public License for more details.
|
|
22
|
|
23 ;; You should have received a copy of the GNU General Public License
|
|
24 ;; along with GNU Emacs; see the file COPYING. If not, write to the
|
64085
|
25 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
26 ;; Boston, MA 02110-1301, USA.
|
18388
|
27
|
|
28 ;;; Commentary:
|
|
29
|
|
30 ;; Minor modes are useful and common. This package makes defining a
|
|
31 ;; minor mode easy, by focusing on the writing of the minor mode
|
|
32 ;; functionalities themselves. Moreover, this package enforces a
|
|
33 ;; conventional naming of user interface primitives, making things
|
|
34 ;; natural for the minor-mode end-users.
|
|
35
|
|
36 ;; For each mode, easy-mmode defines the following:
|
|
37 ;; <mode> : The minor mode predicate. A buffer-local variable.
|
|
38 ;; <mode>-map : The keymap possibly associated to <mode>.
|
29039
|
39 ;; see `define-minor-mode' documentation
|
18388
|
40 ;;
|
|
41 ;; eval
|
29039
|
42 ;; (pp (macroexpand '(define-minor-mode <your-mode> <doc>)))
|
18388
|
43 ;; to check the result before using it.
|
|
44
|
|
45 ;; The order in which minor modes are installed is important. Keymap
|
|
46 ;; lookup proceeds down minor-mode-map-alist, and the order there
|
|
47 ;; tends to be the reverse of the order in which the modes were
|
|
48 ;; installed. Perhaps there should be a feature to let you specify
|
|
49 ;; orderings.
|
|
50
|
28081
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
51 ;; Additionally to `define-minor-mode', the package provides convenient
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
52 ;; ways to define keymaps, and other helper functions for major and minor modes.
|
18388
|
53
|
28081
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
54 ;;; Code:
|
18388
|
55
|
29411
|
56 (eval-when-compile (require 'cl))
|
|
57
|
29406
f4b12c3efee8
(easy-mmode-define-toggle): Remove (inline into define-minor-mode).
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
58 (defun easy-mmode-pretty-mode-name (mode &optional lighter)
|
f4b12c3efee8
(easy-mmode-define-toggle): Remove (inline into define-minor-mode).
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
59 "Turn the symbol MODE into a string intended for the user.
|
62149
|
60 If provided, LIGHTER will be used to help choose capitalization by,
|
|
61 replacing its case-insensitive matches with the literal string in LIGHTER."
|
29406
f4b12c3efee8
(easy-mmode-define-toggle): Remove (inline into define-minor-mode).
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
62 (let* ((case-fold-search t)
|
62181
|
63 ;; Produce "Foo-Bar minor mode" from foo-bar-minor-mode.
|
32048
|
64 (name (concat (replace-regexp-in-string
|
62181
|
65 ;; If the original mode name included "-minor" (some
|
|
66 ;; of them don't, e.g. auto-revert-mode), then
|
|
67 ;; replace it with " minor".
|
32048
|
68 "-Minor" " minor"
|
62149
|
69 ;; "foo-bar-minor" -> "Foo-Bar-Minor"
|
32048
|
70 (capitalize (replace-regexp-in-string
|
62149
|
71 ;; "foo-bar-minor-mode" -> "foo-bar-minor"
|
32048
|
72 "-mode\\'" "" (symbol-name mode))))
|
29406
f4b12c3efee8
(easy-mmode-define-toggle): Remove (inline into define-minor-mode).
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
73 " mode")))
|
f4b12c3efee8
(easy-mmode-define-toggle): Remove (inline into define-minor-mode).
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
74 (if (not (stringp lighter)) name
|
62149
|
75 ;; Strip leading and trailing whitespace from LIGHTER.
|
|
76 (setq lighter (replace-regexp-in-string "\\`\\s-+\\|\\s-+\\'" ""
|
|
77 lighter))
|
|
78 ;; Replace any (case-insensitive) matches for LIGHTER in NAME
|
|
79 ;; with a literal LIGHTER. E.g., if NAME is "Iimage mode" and
|
|
80 ;; LIGHTER is " iImag", then this will produce "iImage mode".
|
|
81 ;; (LIGHTER normally comes from the mode-line string passed to
|
|
82 ;; define-minor-mode, and normally includes at least one leading
|
|
83 ;; space.)
|
|
84 (replace-regexp-in-string (regexp-quote lighter) lighter name t t))))
|
29399
|
85
|
18388
|
86 ;;;###autoload
|
26551
|
87 (defalias 'easy-mmode-define-minor-mode 'define-minor-mode)
|
|
88 ;;;###autoload
|
|
89 (defmacro define-minor-mode (mode doc &optional init-value lighter keymap &rest body)
|
18388
|
90 "Define a new minor mode MODE.
|
29406
f4b12c3efee8
(easy-mmode-define-toggle): Remove (inline into define-minor-mode).
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
91 This function defines the associated control variable MODE, keymap MODE-map,
|
62433
50ff61f0f99d
(define-minor-mode): Don't generate a defcustom for the mode hook variable.
Lute Kamstra <lute@gnu.org>
diff
changeset
|
92 and toggle command MODE.
|
18388
|
93
|
|
94 DOC is the documentation for the mode toggle command.
|
26551
|
95 Optional INIT-VALUE is the initial value of the mode's variable.
|
29039
|
96 Optional LIGHTER is displayed in the modeline when the mode is on.
|
18388
|
97 Optional KEYMAP is the default (defvar) keymap bound to the mode keymap.
|
29406
f4b12c3efee8
(easy-mmode-define-toggle): Remove (inline into define-minor-mode).
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
98 If it is a list, it is passed to `easy-mmode-define-keymap'
|
33131
|
99 in order to build a valid keymap. It's generally better to use
|
|
100 a separate MODE-map variable than to use this argument.
|
|
101 The above three arguments can be skipped if keyword arguments are
|
|
102 used (see below).
|
|
103
|
71683
|
104 BODY contains code to execute each time the mode is activated or deactivated.
|
71728
|
105 It is executed after toggling the mode,
|
77885
b210f1cabdb4
(define-minor-mode, easy-mmode-define-navigation): Fix typos in docstrings.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
106 and before running the hook variable `MODE-hook'.
|
62433
50ff61f0f99d
(define-minor-mode): Don't generate a defcustom for the mode hook variable.
Lute Kamstra <lute@gnu.org>
diff
changeset
|
107 Before the actual body code, you can write keyword arguments (alternating
|
50ff61f0f99d
(define-minor-mode): Don't generate a defcustom for the mode hook variable.
Lute Kamstra <lute@gnu.org>
diff
changeset
|
108 keywords and values). These following keyword arguments are supported (other
|
50ff61f0f99d
(define-minor-mode): Don't generate a defcustom for the mode hook variable.
Lute Kamstra <lute@gnu.org>
diff
changeset
|
109 keywords will be passed to `defcustom' if the minor mode is global):
|
47788
|
110 :group GROUP Custom group name to use in all generated `defcustom' forms.
|
61318
|
111 Defaults to MODE without the possible trailing \"-mode\".
|
61861
|
112 Don't use this default group name unless you have written a
|
|
113 `defgroup' to define that group properly.
|
47463
|
114 :global GLOBAL If non-nil specifies that the minor mode is not meant to be
|
61318
|
115 buffer-local, so don't make the variable MODE buffer-local.
|
47788
|
116 By default, the mode is buffer-local.
|
47463
|
117 :init-value VAL Same as the INIT-VALUE argument.
|
|
118 :lighter SPEC Same as the LIGHTER argument.
|
51320
|
119 :keymap MAP Same as the KEYMAP argument.
|
47788
|
120 :require SYM Same as in `defcustom'.
|
|
121
|
|
122 For example, you could write
|
|
123 (define-minor-mode foo-mode \"If enabled, foo on you!\"
|
50300
|
124 :lighter \" Foo\" :require 'foo :global t :group 'hassle :version \"27.5\"
|
47788
|
125 ...BODY CODE...)"
|
51320
|
126 (declare (debug (&define name stringp
|
|
127 [&optional [¬ keywordp] sexp
|
|
128 &optional [¬ keywordp] sexp
|
|
129 &optional [¬ keywordp] sexp]
|
|
130 [&rest [keywordp sexp]]
|
|
131 def-body)))
|
47788
|
132
|
33131
|
133 ;; Allow skipping the first three args.
|
|
134 (cond
|
|
135 ((keywordp init-value)
|
|
136 (setq body (list* init-value lighter keymap body)
|
|
137 init-value nil lighter nil keymap nil))
|
|
138 ((keywordp lighter)
|
|
139 (setq body (list* lighter keymap body) lighter nil keymap nil))
|
|
140 ((keywordp keymap) (push keymap body) (setq keymap nil)))
|
|
141
|
78860
|
142 (let* ((last-message (make-symbol "last-message"))
|
|
143 (mode-name (symbol-name mode))
|
29406
f4b12c3efee8
(easy-mmode-define-toggle): Remove (inline into define-minor-mode).
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
144 (pretty-name (easy-mmode-pretty-mode-name mode lighter))
|
29039
|
145 (globalp nil)
|
64357
25d7b8b15748
(define-minor-mode): Avoid constructing a defcustom with two :set or
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
146 (set nil)
|
64295
f2e16ba201e0
(define-minor-mode): Do not override explicitly specified :initialize keyword.
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
147 (initialize nil)
|
33162
|
148 (group nil)
|
64357
25d7b8b15748
(define-minor-mode): Avoid constructing a defcustom with two :set or
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
149 (type nil)
|
33162
|
150 (extra-args nil)
|
50300
|
151 (extra-keywords nil)
|
47463
|
152 (require t)
|
29406
f4b12c3efee8
(easy-mmode-define-toggle): Remove (inline into define-minor-mode).
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
153 (hook (intern (concat mode-name "-hook")))
|
f4b12c3efee8
(easy-mmode-define-toggle): Remove (inline into define-minor-mode).
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
154 (hook-on (intern (concat mode-name "-on-hook")))
|
50300
|
155 (hook-off (intern (concat mode-name "-off-hook")))
|
51320
|
156 keyw keymap-sym)
|
29406
f4b12c3efee8
(easy-mmode-define-toggle): Remove (inline into define-minor-mode).
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
157
|
f4b12c3efee8
(easy-mmode-define-toggle): Remove (inline into define-minor-mode).
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
158 ;; Check keys.
|
50300
|
159 (while (keywordp (setq keyw (car body)))
|
|
160 (setq body (cdr body))
|
|
161 (case keyw
|
33131
|
162 (:init-value (setq init-value (pop body)))
|
|
163 (:lighter (setq lighter (pop body)))
|
29411
|
164 (:global (setq globalp (pop body)))
|
33162
|
165 (:extra-args (setq extra-args (pop body)))
|
64357
25d7b8b15748
(define-minor-mode): Avoid constructing a defcustom with two :set or
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
166 (:set (setq set (list :set (pop body))))
|
64295
f2e16ba201e0
(define-minor-mode): Do not override explicitly specified :initialize keyword.
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
167 (:initialize (setq initialize (list :initialize (pop body))))
|
33162
|
168 (:group (setq group (nconc group (list :group (pop body)))))
|
64357
25d7b8b15748
(define-minor-mode): Avoid constructing a defcustom with two :set or
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
169 (:type (setq type (list :type (pop body))))
|
47463
|
170 (:require (setq require (pop body)))
|
51320
|
171 (:keymap (setq keymap (pop body)))
|
50300
|
172 (t (push keyw extra-keywords) (push (pop body) extra-keywords))))
|
32999
|
173
|
51320
|
174 (setq keymap-sym (if (and keymap (symbolp keymap)) keymap
|
|
175 (intern (concat mode-name "-map"))))
|
|
176
|
64357
25d7b8b15748
(define-minor-mode): Avoid constructing a defcustom with two :set or
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
177 (unless set (setq set '(:set 'custom-set-minor-mode)))
|
25d7b8b15748
(define-minor-mode): Avoid constructing a defcustom with two :set or
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
178
|
64295
f2e16ba201e0
(define-minor-mode): Do not override explicitly specified :initialize keyword.
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
179 (unless initialize
|
64357
25d7b8b15748
(define-minor-mode): Avoid constructing a defcustom with two :set or
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
180 (setq initialize '(:initialize 'custom-initialize-default)))
|
64295
f2e16ba201e0
(define-minor-mode): Do not override explicitly specified :initialize keyword.
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
181
|
33162
|
182 (unless group
|
|
183 ;; We might as well provide a best-guess default group.
|
|
184 (setq group
|
61318
|
185 `(:group ',(intern (replace-regexp-in-string
|
|
186 "-mode\\'" "" mode-name)))))
|
62635
a33f6ed6e52e
(define-global-minor-mode): Use `after-change-major-mode-hook' instead
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
187
|
64357
25d7b8b15748
(define-minor-mode): Avoid constructing a defcustom with two :set or
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
188 (unless type (setq type '(:type 'boolean)))
|
25d7b8b15748
(define-minor-mode): Avoid constructing a defcustom with two :set or
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
189
|
18388
|
190 `(progn
|
25408
|
191 ;; Define the variable to enable or disable the mode.
|
29414
|
192 ,(if (not globalp)
|
|
193 `(progn
|
|
194 (defvar ,mode ,init-value ,(format "Non-nil if %s is enabled.
|
35562
|
195 Use the command `%s' to change this variable." pretty-name mode))
|
29414
|
196 (make-variable-buffer-local ',mode))
|
|
197
|
65094
|
198 (let ((base-doc-string
|
|
199 (concat "Non-nil if %s is enabled.
|
77672
|
200 See the command `%s' for a description of this minor mode."
|
65094
|
201 (if body "
|
29039
|
202 Setting this variable directly does not take effect;
|
72587
e2ff121d30ca
(define-minor-mode): Reference manual about customization, rather than
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
203 either customize it (see the info node `Easy Customization')
|
e2ff121d30ca
(define-minor-mode): Reference manual about customization, rather than
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
204 or call the function `%s'."))))
|
63141
c531a8daedc6
(define-minor-mode): If BODY is empty, give the variable a doc string
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
205 `(defcustom ,mode ,init-value
|
c531a8daedc6
(define-minor-mode): If BODY is empty, give the variable a doc string
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
206 ,(format base-doc-string pretty-name mode mode)
|
64357
25d7b8b15748
(define-minor-mode): Avoid constructing a defcustom with two :set or
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
207 ,@set
|
64295
f2e16ba201e0
(define-minor-mode): Do not override explicitly specified :initialize keyword.
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
208 ,@initialize
|
33162
|
209 ,@group
|
64357
25d7b8b15748
(define-minor-mode): Avoid constructing a defcustom with two :set or
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
210 ,@type
|
65094
|
211 ,@(unless (eq require t) `(:require ,require))
|
|
212 ,@(nreverse extra-keywords))))
|
29406
f4b12c3efee8
(easy-mmode-define-toggle): Remove (inline into define-minor-mode).
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
213
|
f4b12c3efee8
(easy-mmode-define-toggle): Remove (inline into define-minor-mode).
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
214 ;; The actual function.
|
33162
|
215 (defun ,mode (&optional arg ,@extra-args)
|
29406
f4b12c3efee8
(easy-mmode-define-toggle): Remove (inline into define-minor-mode).
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
216 ,(or doc
|
33131
|
217 (format (concat "Toggle %s on or off.
|
|
218 Interactively, with no prefix argument, toggle the mode.
|
46900
3c3d686b25fa
(easy-mmode-define-global-mode): Use find-file-hook instead of find-file-hooks.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
219 With universal prefix ARG turn mode on.
|
29406
f4b12c3efee8
(easy-mmode-define-toggle): Remove (inline into define-minor-mode).
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
220 With zero or negative ARG turn mode off.
|
33131
|
221 \\{%s}") pretty-name keymap-sym))
|
46900
3c3d686b25fa
(easy-mmode-define-global-mode): Use find-file-hook instead of find-file-hooks.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
222 ;; Use `toggle' rather than (if ,mode 0 1) so that using
|
3c3d686b25fa
(easy-mmode-define-global-mode): Use find-file-hook instead of find-file-hooks.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
223 ;; repeat-command still does the toggling correctly.
|
3c3d686b25fa
(easy-mmode-define-global-mode): Use find-file-hook instead of find-file-hooks.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
224 (interactive (list (or current-prefix-arg 'toggle)))
|
78860
|
225 (let ((,last-message (current-message)))
|
|
226 (setq ,mode
|
|
227 (cond
|
|
228 ((eq arg 'toggle) (not ,mode))
|
|
229 (arg (> (prefix-numeric-value arg) 0))
|
|
230 (t
|
|
231 (if (null ,mode) t
|
|
232 (message
|
|
233 "Toggling %s off; better pass an explicit argument."
|
|
234 ',mode)
|
|
235 nil))))
|
|
236 ,@body
|
|
237 ;; The on/off hooks are here for backward compatibility only.
|
|
238 (run-hooks ',hook (if ,mode ',hook-on ',hook-off))
|
|
239 (if (called-interactively-p)
|
|
240 (progn
|
|
241 ,(if globalp `(customize-mark-as-set ',mode))
|
|
242 ;; Avoid overwriting a message shown by the body,
|
|
243 ;; but do overwrite previous messages.
|
|
244 (unless (and (current-message)
|
|
245 (not (equal ,last-message
|
|
246 (current-message))))
|
|
247 (message ,(format "%s %%sabled" pretty-name)
|
|
248 (if ,mode "en" "dis"))))))
|
47043
360c6fcdde04
(define-minor-mode): Use customize-mark-as-set for global minor modes.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
249 (force-mode-line-update)
|
29406
f4b12c3efee8
(easy-mmode-define-toggle): Remove (inline into define-minor-mode).
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
250 ;; Return the new setting.
|
f4b12c3efee8
(easy-mmode-define-toggle): Remove (inline into define-minor-mode).
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
251 ,mode)
|
51320
|
252
|
61318
|
253 ;; Autoloading a define-minor-mode autoloads everything
|
|
254 ;; up-to-here.
|
29548
71b284c55162
(define-minor-mode): If KEYMAP is a symbol, just use it.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
255 :autoload-end
|
71b284c55162
(define-minor-mode): If KEYMAP is a symbol, just use it.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
256
|
29414
|
257 ;; Define the minor-mode keymap.
|
29548
71b284c55162
(define-minor-mode): If KEYMAP is a symbol, just use it.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
258 ,(unless (symbolp keymap) ;nil is also a symbol.
|
29414
|
259 `(defvar ,keymap-sym
|
29548
71b284c55162
(define-minor-mode): If KEYMAP is a symbol, just use it.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
260 (let ((m ,keymap))
|
71b284c55162
(define-minor-mode): If KEYMAP is a symbol, just use it.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
261 (cond ((keymapp m) m)
|
71b284c55162
(define-minor-mode): If KEYMAP is a symbol, just use it.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
262 ((listp m) (easy-mmode-define-keymap m))
|
71b284c55162
(define-minor-mode): If KEYMAP is a symbol, just use it.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
263 (t (error "Invalid keymap %S" ,keymap))))
|
29414
|
264 ,(format "Keymap for `%s'." mode-name)))
|
|
265
|
29406
f4b12c3efee8
(easy-mmode-define-toggle): Remove (inline into define-minor-mode).
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
266 (add-minor-mode ',mode ',lighter
|
29548
71b284c55162
(define-minor-mode): If KEYMAP is a symbol, just use it.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
267 ,(if keymap keymap-sym
|
30876
76bba9fc3c22
(define-minor-mode): Use `symbol-value' to keep the byte-compiler quiet.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
268 `(if (boundp ',keymap-sym)
|
64586
675c97656ccc
(define-minor-mode): Never call the mode function using `eval-after-load'.
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
269 (symbol-value ',keymap-sym)))))))
|
28081
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
270
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
271 ;;;
|
29411
|
272 ;;; make global minor mode
|
|
273 ;;;
|
|
274
|
29414
|
275 ;;;###autoload
|
75643
39dd9f1dfbb0
(define-globalized-minor-mode): Rename from define-global-minor-mode.
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
276 (defalias 'easy-mmode-define-global-mode 'define-globalized-minor-mode)
|
61175
ef26a481327e
(define-global-minor-mode): Renamed from easy-mmode-define-global-mode.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
277 ;;;###autoload
|
75643
39dd9f1dfbb0
(define-globalized-minor-mode): Rename from define-global-minor-mode.
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
278 (defalias 'define-global-minor-mode 'define-globalized-minor-mode)
|
39dd9f1dfbb0
(define-globalized-minor-mode): Rename from define-global-minor-mode.
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
279 ;;;###autoload
|
39dd9f1dfbb0
(define-globalized-minor-mode): Rename from define-global-minor-mode.
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
280 (defmacro define-globalized-minor-mode (global-mode mode turn-on &rest keys)
|
74995
|
281 "Make a global mode GLOBAL-MODE corresponding to buffer-local minor MODE.
|
29411
|
282 TURN-ON is a function that will be called with no args in every buffer
|
|
283 and that should try to turn MODE on if applicable for that buffer.
|
66721
67170e911864
(define-global-minor-mode): Pass all specified keyword args on to
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
284 KEYS is a list of CL-style keyword arguments. As the minor mode
|
67170e911864
(define-global-minor-mode): Pass all specified keyword args on to
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
285 defined by this function is always global, any :global keyword is
|
67170e911864
(define-global-minor-mode): Pass all specified keyword args on to
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
286 ignored. Other keywords have the same meaning as in `define-minor-mode',
|
67170e911864
(define-global-minor-mode): Pass all specified keyword args on to
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
287 which see. In particular, :group specifies the custom group.
|
67170e911864
(define-global-minor-mode): Pass all specified keyword args on to
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
288 The most useful keywords are those that are passed on to the
|
67170e911864
(define-global-minor-mode): Pass all specified keyword args on to
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
289 `defcustom'. It normally makes no sense to pass the :lighter
|
75643
39dd9f1dfbb0
(define-globalized-minor-mode): Rename from define-global-minor-mode.
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
290 or :keymap keywords to `define-globalized-minor-mode', since these
|
66721
67170e911864
(define-global-minor-mode): Pass all specified keyword args on to
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
291 are usually passed to the buffer-local version of the minor mode.
|
63023
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
292
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
293 If MODE's set-up depends on the major mode in effect when it was
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
294 enabled, then disabling and reenabling MODE should make MODE work
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
295 correctly with the current major mode. This is important to
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
296 prevent problems with derived modes, that is, major modes that
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
297 call another major mode in their body."
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
298
|
33162
|
299 (let* ((global-mode-name (symbol-name global-mode))
|
29411
|
300 (pretty-name (easy-mmode-pretty-mode-name mode))
|
|
301 (pretty-global-name (easy-mmode-pretty-mode-name global-mode))
|
33162
|
302 (group nil)
|
66721
67170e911864
(define-global-minor-mode): Pass all specified keyword args on to
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
303 (extra-keywords nil)
|
63023
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
304 (MODE-buffers (intern (concat global-mode-name "-buffers")))
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
305 (MODE-enable-in-buffers
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
306 (intern (concat global-mode-name "-enable-in-buffers")))
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
307 (MODE-check-buffers
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
308 (intern (concat global-mode-name "-check-buffers")))
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
309 (MODE-cmhh (intern (concat global-mode-name "-cmhh")))
|
66721
67170e911864
(define-global-minor-mode): Pass all specified keyword args on to
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
310 (MODE-major-mode (intern (concat (symbol-name mode) "-major-mode")))
|
67170e911864
(define-global-minor-mode): Pass all specified keyword args on to
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
311 keyw)
|
29411
|
312
|
|
313 ;; Check keys.
|
66721
67170e911864
(define-global-minor-mode): Pass all specified keyword args on to
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
314 (while (keywordp (setq keyw (car keys)))
|
67170e911864
(define-global-minor-mode): Pass all specified keyword args on to
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
315 (setq keys (cdr keys))
|
67170e911864
(define-global-minor-mode): Pass all specified keyword args on to
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
316 (case keyw
|
33162
|
317 (:group (setq group (nconc group (list :group (pop keys)))))
|
66721
67170e911864
(define-global-minor-mode): Pass all specified keyword args on to
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
318 (:global (setq keys (cdr keys)))
|
67170e911864
(define-global-minor-mode): Pass all specified keyword args on to
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
319 (t (push keyw extra-keywords) (push (pop keys) extra-keywords))))
|
29411
|
320
|
33162
|
321 (unless group
|
|
322 ;; We might as well provide a best-guess default group.
|
|
323 (setq group
|
61318
|
324 `(:group ',(intern (replace-regexp-in-string
|
|
325 "-mode\\'" "" (symbol-name mode))))))
|
48838
|
326
|
29411
|
327 `(progn
|
63023
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
328 (defvar ,MODE-major-mode nil)
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
329 (make-variable-buffer-local ',MODE-major-mode)
|
29411
|
330 ;; The actual global minor-mode
|
|
331 (define-minor-mode ,global-mode
|
77424
d3f723361ea3
(define-globalized-minor-mode): Improve doc string of generated command.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
332 ,(format "Toggle %s in every possible buffer.
|
29411
|
333 With prefix ARG, turn %s on if and only if ARG is positive.
|
77424
d3f723361ea3
(define-globalized-minor-mode): Improve doc string of generated command.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
334 %s is enabled in all buffers where `%s' would do it.
|
d3f723361ea3
(define-globalized-minor-mode): Improve doc string of generated command.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
335 See `%s' for more information on %s."
|
d3f723361ea3
(define-globalized-minor-mode): Improve doc string of generated command.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
336 pretty-name pretty-global-name pretty-name turn-on
|
d3f723361ea3
(define-globalized-minor-mode): Improve doc string of generated command.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
337 mode pretty-name)
|
66721
67170e911864
(define-global-minor-mode): Pass all specified keyword args on to
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
338 :global t ,@group ,@(nreverse extra-keywords)
|
29411
|
339
|
|
340 ;; Setup hook to handle future mode changes and new buffers.
|
|
341 (if ,global-mode
|
29414
|
342 (progn
|
63023
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
343 (add-hook 'after-change-major-mode-hook
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
344 ',MODE-enable-in-buffers)
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
345 (add-hook 'find-file-hook ',MODE-check-buffers)
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
346 (add-hook 'change-major-mode-hook ',MODE-cmhh))
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
347 (remove-hook 'after-change-major-mode-hook ',MODE-enable-in-buffers)
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
348 (remove-hook 'find-file-hook ',MODE-check-buffers)
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
349 (remove-hook 'change-major-mode-hook ',MODE-cmhh))
|
29411
|
350
|
|
351 ;; Go through existing buffers.
|
|
352 (dolist (buf (buffer-list))
|
|
353 (with-current-buffer buf
|
33165
8b3f1e99c11a
(easy-mmode-define-global-mode): Only turn mode off if it's on.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
354 (if ,global-mode (,turn-on) (when ,mode (,mode -1))))))
|
29411
|
355
|
75643
39dd9f1dfbb0
(define-globalized-minor-mode): Rename from define-global-minor-mode.
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
356 ;; Autoloading define-globalized-minor-mode autoloads everything
|
62433
50ff61f0f99d
(define-minor-mode): Don't generate a defcustom for the mode hook variable.
Lute Kamstra <lute@gnu.org>
diff
changeset
|
357 ;; up-to-here.
|
29548
71b284c55162
(define-minor-mode): If KEYMAP is a symbol, just use it.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
358 :autoload-end
|
71b284c55162
(define-minor-mode): If KEYMAP is a symbol, just use it.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
359
|
29411
|
360 ;; List of buffers left to process.
|
63023
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
361 (defvar ,MODE-buffers nil)
|
29411
|
362
|
|
363 ;; The function that calls TURN-ON in each buffer.
|
63023
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
364 (defun ,MODE-enable-in-buffers ()
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
365 (dolist (buf ,MODE-buffers)
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
366 (when (buffer-live-p buf)
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
367 (with-current-buffer buf
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
368 (if ,mode
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
369 (unless (eq ,MODE-major-mode major-mode)
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
370 (,mode -1)
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
371 (,turn-on)
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
372 (setq ,MODE-major-mode major-mode))
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
373 (,turn-on)
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
374 (setq ,MODE-major-mode major-mode))))))
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
375 (put ',MODE-enable-in-buffers 'definition-name ',global-mode)
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
376
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
377 (defun ,MODE-check-buffers ()
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
378 (,MODE-enable-in-buffers)
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
379 (setq ,MODE-buffers nil)
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
380 (remove-hook 'post-command-hook ',MODE-check-buffers))
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
381 (put ',MODE-check-buffers 'definition-name ',global-mode)
|
29411
|
382
|
|
383 ;; The function that catches kill-all-local-variables.
|
63023
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
384 (defun ,MODE-cmhh ()
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
385 (add-to-list ',MODE-buffers (current-buffer))
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
386 (add-hook 'post-command-hook ',MODE-check-buffers))
|
cc9dd228e2e6
(define-global-minor-mode): Make it keep track of which major mode it
Luc Teirlinck <teirllm@auburn.edu>
diff
changeset
|
387 (put ',MODE-cmhh 'definition-name ',global-mode))))
|
29411
|
388
|
|
389 ;;;
|
28081
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
390 ;;; easy-mmode-defmap
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
391 ;;;
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
392
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
393 (if (fboundp 'set-keymap-parents)
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
394 (defalias 'easy-mmode-set-keymap-parents 'set-keymap-parents)
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
395 (defun easy-mmode-set-keymap-parents (m parents)
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
396 (set-keymap-parent
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
397 m
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
398 (cond
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
399 ((not (consp parents)) parents)
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
400 ((not (cdr parents)) (car parents))
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
401 (t (let ((m (copy-keymap (pop parents))))
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
402 (easy-mmode-set-keymap-parents m parents)
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
403 m))))))
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
404
|
31981
|
405 ;;;###autoload
|
28081
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
406 (defun easy-mmode-define-keymap (bs &optional name m args)
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
407 "Return a keymap built from bindings BS.
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
408 BS must be a list of (KEY . BINDING) where
|
29399
|
409 KEY and BINDINGS are suitable for `define-key'.
|
|
410 Optional NAME is passed to `make-sparse-keymap'.
|
|
411 Optional map M can be used to modify an existing map.
|
33433
|
412 ARGS is a list of additional keyword arguments."
|
50635
e0775ee7f599
(define-minor-mode): Only echo a message if the body didn't do so already.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
413 (let (inherit dense)
|
28081
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
414 (while args
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
415 (let ((key (pop args))
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
416 (val (pop args)))
|
29411
|
417 (case key
|
33433
|
418 (:name (setq name val))
|
29411
|
419 (:dense (setq dense val))
|
|
420 (:inherit (setq inherit val))
|
|
421 (:group)
|
28081
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
422 (t (message "Unknown argument %s in defmap" key)))))
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
423 (unless (keymapp m)
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
424 (setq bs (append m bs))
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
425 (setq m (if dense (make-keymap name) (make-sparse-keymap name))))
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
426 (dolist (b bs)
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
427 (let ((keys (car b))
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
428 (binding (cdr b)))
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
429 (dolist (key (if (consp keys) keys (list keys)))
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
430 (cond
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
431 ((symbolp key)
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
432 (substitute-key-definition key binding m global-map))
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
433 ((null binding)
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
434 (unless (keymapp (lookup-key m key)) (define-key m key binding)))
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
435 ((let ((o (lookup-key m key)))
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
436 (or (null o) (numberp o) (eq o 'undefined)))
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
437 (define-key m key binding))))))
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
438 (cond
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
439 ((keymapp inherit) (set-keymap-parent m inherit))
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
440 ((consp inherit) (easy-mmode-set-keymap-parents m inherit)))
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
441 m))
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
442
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
443 ;;;###autoload
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
444 (defmacro easy-mmode-defmap (m bs doc &rest args)
|
31981
|
445 `(defconst ,m
|
|
446 (easy-mmode-define-keymap ,bs nil (if (boundp ',m) ,m) ,(cons 'list args))
|
|
447 ,doc))
|
28081
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
448
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
449
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
450 ;;;
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
451 ;;; easy-mmode-defsyntax
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
452 ;;;
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
453
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
454 (defun easy-mmode-define-syntax (css args)
|
32491
2fc546f941df
(easy-mmode-define-syntax): Use plist-get and allow :inherit.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
455 (let ((st (make-syntax-table (plist-get args :copy)))
|
2fc546f941df
(easy-mmode-define-syntax): Use plist-get and allow :inherit.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
456 (parent (plist-get args :inherit)))
|
28081
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
457 (dolist (cs css)
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
458 (let ((char (car cs))
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
459 (syntax (cdr cs)))
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
460 (if (sequencep char)
|
84897
992e87082552
(easy-mmode-define-syntax): Use `mapc' rather than `mapcar'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
461 (mapc (lambda (c) (modify-syntax-entry c syntax st)) char)
|
28081
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
462 (modify-syntax-entry char syntax st))))
|
32491
2fc546f941df
(easy-mmode-define-syntax): Use plist-get and allow :inherit.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
463 (if parent (set-char-table-parent
|
2fc546f941df
(easy-mmode-define-syntax): Use plist-get and allow :inherit.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
464 st (if (symbolp parent) (symbol-value parent) parent)))
|
28081
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
465 st))
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
466
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
467 ;;;###autoload
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
468 (defmacro easy-mmode-defsyntax (st css doc &rest args)
|
32491
2fc546f941df
(easy-mmode-define-syntax): Use plist-get and allow :inherit.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
469 "Define variable ST as a syntax-table.
|
37406
|
470 CSS contains a list of syntax specifications of the form (CHAR . SYNTAX)."
|
28086
9ff6e6a6c6b5
(easy-mmode-defmap, easy-mmode-defsyntax): Autoload the functions used.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
471 `(progn
|
9ff6e6a6c6b5
(easy-mmode-defmap, easy-mmode-defsyntax): Autoload the functions used.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
472 (autoload 'easy-mmode-define-syntax "easy-mmode")
|
37406
|
473 (defconst ,st (easy-mmode-define-syntax ,css ,(cons 'list args)) ,doc)))
|
28081
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
474
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
475
|
6360842e5962
(easy-mmode-define-keymap): Extend to allow more flexibility.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
476
|
28235
963f1d516e92
* derived.el (define-derived-mode): Don't autoload anymore.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
477 ;;;
|
963f1d516e92
* derived.el (define-derived-mode): Don't autoload anymore.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
478 ;;; easy-mmode-define-navigation
|
963f1d516e92
* derived.el (define-derived-mode): Don't autoload anymore.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
479 ;;;
|
963f1d516e92
* derived.el (define-derived-mode): Don't autoload anymore.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
480
|
85463
|
481 (defmacro easy-mmode-define-navigation (base re &optional name endfun narrowfun
|
|
482 &rest body)
|
28235
963f1d516e92
* derived.el (define-derived-mode): Don't autoload anymore.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
483 "Define BASE-next and BASE-prev to navigate in the buffer.
|
963f1d516e92
* derived.el (define-derived-mode): Don't autoload anymore.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
484 RE determines the places the commands should move point to.
|
33358
|
485 NAME should describe the entities matched by RE. It is used to build
|
28235
963f1d516e92
* derived.el (define-derived-mode): Don't autoload anymore.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
486 the docstrings of the two functions.
|
963f1d516e92
* derived.el (define-derived-mode): Don't autoload anymore.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
487 BASE-next also tries to make sure that the whole entry is visible by
|
963f1d516e92
* derived.el (define-derived-mode): Don't autoload anymore.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
488 searching for its end (by calling ENDFUN if provided or by looking for
|
963f1d516e92
* derived.el (define-derived-mode): Don't autoload anymore.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
489 the next entry) and recentering if necessary.
|
53056
|
490 ENDFUN should return the end position (with or without moving point).
|
|
491 NARROWFUN non-nil means to check for narrowing before moving, and if
|
85463
|
492 found, do `widen' first and then call NARROWFUN with no args after moving.
|
|
493 BODY is executed after moving to the destination location."
|
|
494 (declare (indent 5) (debug (exp exp exp def-form def-form &rest def-body)))
|
28235
963f1d516e92
* derived.el (define-derived-mode): Don't autoload anymore.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
495 (let* ((base-name (symbol-name base))
|
963f1d516e92
* derived.el (define-derived-mode): Don't autoload anymore.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
496 (prev-sym (intern (concat base-name "-prev")))
|
53056
|
497 (next-sym (intern (concat base-name "-next")))
|
85463
|
498 (when-narrowed
|
|
499 (lambda (body)
|
|
500 (if (null narrowfun) body
|
|
501 `(let ((was-narrowed
|
|
502 (prog1 (or (< (- (point-max) (point-min)) (buffer-size)))
|
|
503 (widen))))
|
|
504 ,body
|
|
505 (when was-narrowed (,narrowfun)))))))
|
51643
|
506 (unless name (setq name base-name))
|
28235
963f1d516e92
* derived.el (define-derived-mode): Don't autoload anymore.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
507 `(progn
|
29406
f4b12c3efee8
(easy-mmode-define-toggle): Remove (inline into define-minor-mode).
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
508 (add-to-list 'debug-ignored-errors
|
f4b12c3efee8
(easy-mmode-define-toggle): Remove (inline into define-minor-mode).
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
509 ,(concat "^No \\(previous\\|next\\) " (regexp-quote name)))
|
28235
963f1d516e92
* derived.el (define-derived-mode): Don't autoload anymore.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
510 (defun ,next-sym (&optional count)
|
28239
21cd65af5197
(easy-mmode-define-navigation): Only use `ding' for interactive use
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
511 ,(format "Go to the next COUNT'th %s." name)
|
74306
e6443f563ae7
(easy-mmode-define-navigation): Fix interactive spec of the functions
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
512 (interactive "p")
|
28235
963f1d516e92
* derived.el (define-derived-mode): Don't autoload anymore.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
513 (unless count (setq count 1))
|
963f1d516e92
* derived.el (define-derived-mode): Don't autoload anymore.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
514 (if (< count 0) (,prev-sym (- count))
|
52881
|
515 (if (looking-at ,re) (setq count (1+ count)))
|
85463
|
516 ,(funcall when-narrowed
|
|
517 `(if (not (re-search-forward ,re nil t count))
|
|
518 (if (looking-at ,re)
|
|
519 (goto-char (or ,(if endfun `(,endfun)) (point-max)))
|
|
520 (error "No next %s" ,name))
|
|
521 (goto-char (match-beginning 0))
|
|
522 (when (and (eq (current-buffer) (window-buffer (selected-window)))
|
|
523 (interactive-p))
|
|
524 (let ((endpt (or (save-excursion
|
|
525 ,(if endfun `(,endfun)
|
|
526 `(re-search-forward ,re nil t 2)))
|
|
527 (point-max))))
|
|
528 (unless (pos-visible-in-window-p endpt nil t)
|
|
529 (recenter '(0)))))))
|
|
530 ,@body))
|
67293
32fa638322e0
(easy-mmode-define-navigation): Put `definition-name' properties on the
Juri Linkov <juri@jurta.org>
diff
changeset
|
531 (put ',next-sym 'definition-name ',base)
|
28235
963f1d516e92
* derived.el (define-derived-mode): Don't autoload anymore.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
532 (defun ,prev-sym (&optional count)
|
963f1d516e92
* derived.el (define-derived-mode): Don't autoload anymore.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
533 ,(format "Go to the previous COUNT'th %s" (or name base-name))
|
74306
e6443f563ae7
(easy-mmode-define-navigation): Fix interactive spec of the functions
Chong Yidong <cyd@stupidchicken.com>
diff
changeset
|
534 (interactive "p")
|
28235
963f1d516e92
* derived.el (define-derived-mode): Don't autoload anymore.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
535 (unless count (setq count 1))
|
963f1d516e92
* derived.el (define-derived-mode): Don't autoload anymore.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
536 (if (< count 0) (,next-sym (- count))
|
85463
|
537 ,(funcall when-narrowed
|
|
538 `(unless (re-search-backward ,re nil t count)
|
|
539 (error "No previous %s" ,name)))
|
|
540 ,@body))
|
67293
32fa638322e0
(easy-mmode-define-navigation): Put `definition-name' properties on the
Juri Linkov <juri@jurta.org>
diff
changeset
|
541 (put ',prev-sym 'definition-name ',base))))
|
53056
|
542
|
28086
9ff6e6a6c6b5
(easy-mmode-defmap, easy-mmode-defsyntax): Autoload the functions used.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
543
|
18388
|
544 (provide 'easy-mmode)
|
|
545
|
78860
|
546 ;; arch-tag: d48a5250-6961-4528-9cb0-3c9ea042a66a
|
18388
|
547 ;;; easy-mmode.el ends here
|