comparison lisp/derived.el @ 40344:d184455da497

(derived-mode-hook-name, derived-mode-map-name) (derived-mode-syntax-table-name, derived-mode-abbrev-table-name): define defsubsts before they are first used
author Sam Steingold <sds@gnu.org>
date Fri, 26 Oct 2001 17:51:38 +0000
parents 628cde7da5bc
children b5584ab9e544
comparison
equal deleted inserted replaced
40343:25129ef47b45 40344:d184455da497
79 ;; sense. Second, it is possible to build even further, and make 79 ;; sense. Second, it is possible to build even further, and make
80 ;; a derived mode from a derived mode. The commands 80 ;; a derived mode from a derived mode. The commands
81 ;; 81 ;;
82 ;; (define-derived-mode html-mode hypertext-mode "HTML") 82 ;; (define-derived-mode html-mode hypertext-mode "HTML")
83 ;; [various key definitions] 83 ;; [various key definitions]
84 ;; 84 ;;
85 ;; will add a new major mode for HTML with very little fuss. 85 ;; will add a new major mode for HTML with very little fuss.
86 ;; 86 ;;
87 ;; Note also the function `derived-mode-p' which can tell if the current 87 ;; Note also the function `derived-mode-p' which can tell if the current
88 ;; mode derives from another. In a hypertext-mode, buffer, for example, 88 ;; mode derives from another. In a hypertext-mode, buffer, for example,
89 ;; (derived-mode-p 'text-mode) would return non-nil. This should always 89 ;; (derived-mode-p 'text-mode) would return non-nil. This should always
90 ;; be used in place of (eq major-mode 'text-mode). 90 ;; be used in place of (eq major-mode 'text-mode).
91 91
92 ;;; Code: 92 ;;; Code:
93
94 ;;; PRIVATE: defsubst must be defined before they are first used
95
96 (defsubst derived-mode-hook-name (mode)
97 "Construct the mode hook name based on mode name MODE."
98 (intern (concat (symbol-name mode) "-hook")))
99
100 (defsubst derived-mode-map-name (mode)
101 "Construct a map name based on a MODE name."
102 (intern (concat (symbol-name mode) "-map")))
103
104 (defsubst derived-mode-syntax-table-name (mode)
105 "Construct a syntax-table name based on a MODE name."
106 (intern (concat (symbol-name mode) "-syntax-table")))
107
108 (defsubst derived-mode-abbrev-table-name (mode)
109 "Construct an abbrev-table name based on a MODE name."
110 (intern (concat (symbol-name mode) "-abbrev-table")))
93 111
94 ;; PUBLIC: define a new major mode which inherits from an existing one. 112 ;; PUBLIC: define a new major mode which inherits from an existing one.
95 113
96 ;;;###autoload 114 ;;;###autoload
97 (defmacro define-derived-mode (child parent name &optional docstring &rest body) 115 (defmacro define-derived-mode (child parent name &optional docstring &rest body)
137 (let ((map (derived-mode-map-name child)) 155 (let ((map (derived-mode-map-name child))
138 (syntax (derived-mode-syntax-table-name child)) 156 (syntax (derived-mode-syntax-table-name child))
139 (abbrev (derived-mode-abbrev-table-name child)) 157 (abbrev (derived-mode-abbrev-table-name child))
140 (hook (derived-mode-hook-name child)) 158 (hook (derived-mode-hook-name child))
141 (docstring (derived-mode-make-docstring parent child docstring))) 159 (docstring (derived-mode-make-docstring parent child docstring)))
142 160
143 `(progn 161 `(progn
144 (defvar ,map (make-sparse-keymap)) 162 (defvar ,map (make-sparse-keymap))
145 (defvar ,syntax (make-syntax-table)) 163 (defvar ,syntax (make-syntax-table))
146 (defvar ,abbrev) 164 (defvar ,abbrev)
147 (define-abbrev-table ',abbrev nil) 165 (define-abbrev-table ',abbrev nil)
148 (put ',child 'derived-mode-parent ',parent) 166 (put ',child 'derived-mode-parent ',parent)
149 167
150 (defun ,child () 168 (defun ,child ()
151 ,docstring 169 ,docstring
152 (interactive) 170 (interactive)
153 ; Run the parent. 171 ; Run the parent.
154 (delay-mode-hooks 172 (delay-mode-hooks
173 (lambda (symbol) 191 (lambda (symbol)
174 (or (intern-soft (symbol-name symbol) ,abbrev) 192 (or (intern-soft (symbol-name symbol) ,abbrev)
175 (define-abbrev ,abbrev (symbol-name symbol) 193 (define-abbrev ,abbrev (symbol-name symbol)
176 (symbol-value symbol) (symbol-function symbol)))) 194 (symbol-value symbol) (symbol-function symbol))))
177 local-abbrev-table)))) 195 local-abbrev-table))))
178 196
179 (use-local-map ,map) 197 (use-local-map ,map)
180 (set-syntax-table ,syntax) 198 (set-syntax-table ,syntax)
181 (setq local-abbrev-table ,abbrev) 199 (setq local-abbrev-table ,abbrev)
182 ; Splice in the body (if any). 200 ; Splice in the body (if any).
183 ,@body 201 ,@body
209 mode) 227 mode)
210 228
211 229
212 ;;; PRIVATE 230 ;;; PRIVATE
213 231
214 (defsubst derived-mode-hook-name (mode)
215 "Construct the mode hook name based on mode name MODE."
216 (intern (concat (symbol-name mode) "-hook")))
217
218 (defsubst derived-mode-map-name (mode)
219 "Construct a map name based on a MODE name."
220 (intern (concat (symbol-name mode) "-map")))
221
222 (defsubst derived-mode-syntax-table-name (mode)
223 "Construct a syntax-table name based on a MODE name."
224 (intern (concat (symbol-name mode) "-syntax-table")))
225
226 (defsubst derived-mode-abbrev-table-name (mode)
227 "Construct an abbrev-table name based on a MODE name."
228 (intern (concat (symbol-name mode) "-abbrev-table")))
229
230 (defun derived-mode-make-docstring (parent child &optional docstring) 232 (defun derived-mode-make-docstring (parent child &optional docstring)
231 "Construct a docstring for a new mode if none is provided." 233 "Construct a docstring for a new mode if none is provided."
232 234
233 (let ((map (derived-mode-map-name child)) 235 (let ((map (derived-mode-map-name child))
234 (syntax (derived-mode-syntax-table-name child)) 236 (syntax (derived-mode-syntax-table-name child))
247 249
248 `%s', `%s' and `%s' 250 `%s', `%s' and `%s'
249 251
250 which more-or-less shadow %s's corresponding tables." 252 which more-or-less shadow %s's corresponding tables."
251 parent map abbrev syntax parent)))) 253 parent map abbrev syntax parent))))
252 254
253 (unless (string-match (regexp-quote (symbol-name hook)) docstring) 255 (unless (string-match (regexp-quote (symbol-name hook)) docstring)
254 ;; Make sure the docstring mentions the mode's hook 256 ;; Make sure the docstring mentions the mode's hook
255 (setq docstring 257 (setq docstring
256 (concat docstring 258 (concat docstring
257 (if (null parent) 259 (if (null parent)
262 docstring) nil 264 docstring) nil
263 (format "`%s' " parent)) 265 (format "`%s' " parent))
264 "might have run,\nthis mode ")) 266 "might have run,\nthis mode "))
265 (format "runs the hook `%s'" hook) 267 (format "runs the hook `%s'" hook)
266 ", as the final step\nduring initialization."))) 268 ", as the final step\nduring initialization.")))
267 269
268 (unless (string-match "\\\\[{[]" docstring) 270 (unless (string-match "\\\\[{[]" docstring)
269 ;; And don't forget to put the mode's keymap 271 ;; And don't forget to put the mode's keymap
270 (setq docstring (concat docstring "\n\n\\{" (symbol-name map) "}"))) 272 (setq docstring (concat docstring "\n\n\\{" (symbol-name map) "}")))
271 273
272 docstring)) 274 docstring))
406 (lambda (symbol) 408 (lambda (symbol)
407 (or (intern-soft (symbol-name symbol) new) 409 (or (intern-soft (symbol-name symbol) new)
408 (define-abbrev new (symbol-name symbol) 410 (define-abbrev new (symbol-name symbol)
409 (symbol-value symbol) (symbol-function symbol)))) 411 (symbol-value symbol) (symbol-function symbol))))
410 old))) 412 old)))
411 413
412 (provide 'derived) 414 (provide 'derived)
413 415
414 ;;; derived.el ends here 416 ;;; derived.el ends here