aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/emacs-lisp/easy-mmode.el98
1 files changed, 87 insertions, 11 deletions
diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el
index 8f8fcf49184..72b64a4a881 100644
--- a/lisp/emacs-lisp/easy-mmode.el
+++ b/lisp/emacs-lisp/easy-mmode.el
@@ -51,6 +51,8 @@
51 51
52;;; Code: 52;;; Code:
53 53
54(eval-when-compile (require 'cl))
55
54(defun easy-mmode-pretty-mode-name (mode &optional lighter) 56(defun easy-mmode-pretty-mode-name (mode &optional lighter)
55 "Turn the symbol MODE into a string intended for the user. 57 "Turn the symbol MODE into a string intended for the user.
56If provided LIGHTER will be used to help choose capitalization." 58If provided LIGHTER will be used to help choose capitalization."
@@ -87,7 +89,9 @@ BODY contains code that will be executed each time the mode is (dis)activated.
87 (pretty-name (easy-mmode-pretty-mode-name mode lighter)) 89 (pretty-name (easy-mmode-pretty-mode-name mode lighter))
88 (globalp nil) 90 (globalp nil)
89 ;; We might as well provide a best-guess default group. 91 ;; We might as well provide a best-guess default group.
90 (group (intern (replace-regexp-in-string "-mode\\'" "" mode-name))) 92 (group
93 (list 'quote
94 (intern (replace-regexp-in-string "-mode\\'" "" mode-name))))
91 (keymap-sym (intern (concat mode-name "-map"))) 95 (keymap-sym (intern (concat mode-name "-map")))
92 (hook (intern (concat mode-name "-hook"))) 96 (hook (intern (concat mode-name "-hook")))
93 (hook-on (intern (concat mode-name "-on-hook"))) 97 (hook-on (intern (concat mode-name "-on-hook")))
@@ -98,10 +102,11 @@ BODY contains code that will be executed each time the mode is (dis)activated.
98 (setq init-value (cdr init-value) globalp t)) 102 (setq init-value (cdr init-value) globalp t))
99 103
100 ;; Check keys. 104 ;; Check keys.
101 (while 105 (while (keywordp (car body))
102 (case (car body) 106 (case (pop body)
103 (:global (setq body (cdr body)) (setq globalp (pop body))) 107 (:global (setq globalp (pop body)))
104 (:group (setq body (cdr body)) (setq group (pop body))))) 108 (:group (setq group (pop body)))
109 (t (setq body (cdr body)))))
105 110
106 ;; Add default properties to LIGHTER. 111 ;; Add default properties to LIGHTER.
107 (unless (or (not (stringp lighter)) (get-text-property 0 'local-map lighter) 112 (unless (or (not (stringp lighter)) (get-text-property 0 'local-map lighter)
@@ -116,6 +121,8 @@ BODY contains code that will be executed each time the mode is (dis)activated.
116 `(progn 121 `(progn
117 ;; Define the variable to enable or disable the mode. 122 ;; Define the variable to enable or disable the mode.
118 ,(if globalp 123 ,(if globalp
124 ;; BEWARE! autoload.el depends on this `defcustom' coming
125 ;; as the first element after progn.
119 `(defcustom ,mode ,init-value 126 `(defcustom ,mode ,init-value
120 ,(format "Toggle %s. 127 ,(format "Toggle %s.
121Setting this variable directly does not take effect; 128Setting this variable directly does not take effect;
@@ -123,7 +130,7 @@ use either \\[customize] or the function `%s'."
123 pretty-name mode) 130 pretty-name mode)
124 :set (lambda (symbol value) (funcall symbol (or value 0))) 131 :set (lambda (symbol value) (funcall symbol (or value 0)))
125 :initialize 'custom-initialize-default 132 :initialize 'custom-initialize-default
126 :group ',group 133 :group ,group
127 :type 'boolean) 134 :type 'boolean)
128 `(progn 135 `(progn
129 (defvar ,mode ,init-value ,(format "Non-nil if %s is enabled. 136 (defvar ,mode ,init-value ,(format "Non-nil if %s is enabled.
@@ -143,7 +150,7 @@ Use the function `%s' to change this variable." pretty-name mode))
143 ;; The toggle's hook. 150 ;; The toggle's hook.
144 (defcustom ,hook nil 151 (defcustom ,hook nil
145 ,(format "Hook run at the end of function `%s'." mode-name) 152 ,(format "Hook run at the end of function `%s'." mode-name)
146 :group ',group 153 :group ,group
147 :type 'hook) 154 :type 'hook)
148 155
149 ;; The actual function. 156 ;; The actual function.
@@ -174,6 +181,75 @@ With zero or negative ARG turn mode off.
174 ,(if globalp `(if ,mode (,mode 1)))))) 181 ,(if globalp `(if ,mode (,mode 1))))))
175 182
176;;; 183;;;
184;;; make global minor mode
185;;;
186
187(defmacro easy-mmode-define-global-mode (global-mode mode turn-on
188 &rest keys)
189 "Make GLOBAL-MODE out of the MODE buffer-local minor mode.
190TURN-ON is a function that will be called with no args in every buffer
191 and that should try to turn MODE on if applicable for that buffer.
192KEYS is a list of CL-style keyword arguments:
193:group to specify the custom group."
194 (let* ((mode-name (symbol-name mode))
195 (global-mode-name (symbol-name global-mode))
196 (pretty-name (easy-mmode-pretty-mode-name mode))
197 (pretty-global-name (easy-mmode-pretty-mode-name global-mode))
198 ;; We might as well provide a best-guess default group.
199 (group
200 (list 'quote
201 (intern (replace-regexp-in-string "-mode\\'" "" mode-name))))
202 (buffers (intern (concat global-mode-name "-buffers")))
203 (cmmh (intern (concat global-mode-name "-cmmh"))))
204
205 ;; Check keys.
206 (while (keywordp (car keys))
207 (case (pop keys)
208 (:group (setq group (pop keys)))
209 (t (setq keys (cdr keys)))))
210
211 `(progn
212 ;; BEWARE! autoload.el depends on `define-minor-mode' coming
213 ;; as the first element after progn.
214
215 ;; The actual global minor-mode
216 (define-minor-mode ,global-mode
217 ,(format "Toggle %s in every buffer.
218With prefix ARG, turn %s on if and only if ARG is positive.
219%s is actually not turned on in every buffer but only in those
220in which `%s' turns it on."
221 pretty-name pretty-global-name pretty-name turn-on)
222 nil nil nil :global t :group ,group
223
224 ;; Setup hook to handle future mode changes and new buffers.
225 (if ,global-mode
226 (add-hook 'change-major-mode-hook ',cmmh)
227 (remove-hook 'change-major-mode-hook ',cmmh))
228
229 ;; Go through existing buffers.
230 (dolist (buf (buffer-list))
231 (with-current-buffer buf
232 (if ,global-mode (,turn-on) (,mode -1)))))
233
234 ;; List of buffers left to process.
235 (defvar ,buffers nil)
236
237 ;; The function that calls TURN-ON in each buffer.
238 (defun ,buffers ()
239 (while ,buffers
240 (when (buffer-name (car ,buffers))
241 (with-current-buffer (pop ,buffers)
242 (,turn-on))))
243 (remove-hook 'post-command-hook ',buffers)
244 (remove-hook 'after-find-file ',buffers))
245
246 ;; The function that catches kill-all-local-variables.
247 (defun ,cmmh ()
248 (add-to-list ',buffers (current-buffer))
249 (add-hook 'post-command-hook ',buffers)
250 (add-hook 'after-find-file ',buffers)))))
251
252;;;
177;;; easy-mmode-defmap 253;;; easy-mmode-defmap
178;;; 254;;;
179 255
@@ -200,10 +276,10 @@ ARGS is a list of additional arguments."
200 (while args 276 (while args
201 (let ((key (pop args)) 277 (let ((key (pop args))
202 (val (pop args))) 278 (val (pop args)))
203 (cond 279 (case key
204 ((eq key :dense) (setq dense val)) 280 (:dense (setq dense val))
205 ((eq key :inherit) (setq inherit val)) 281 (:inherit (setq inherit val))
206 ((eq key :group) ) 282 (:group)
207 ;;((eq key :suppress) (setq suppress val)) 283 ;;((eq key :suppress) (setq suppress val))
208 (t (message "Unknown argument %s in defmap" key))))) 284 (t (message "Unknown argument %s in defmap" key)))))
209 (unless (keymapp m) 285 (unless (keymapp m)