aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/generic.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/generic.el')
-rw-r--r--lisp/generic.el74
1 files changed, 53 insertions, 21 deletions
diff --git a/lisp/generic.el b/lisp/generic.el
index e20f73688c7..e170d05e0f3 100644
--- a/lisp/generic.el
+++ b/lisp/generic.el
@@ -185,7 +185,8 @@ the regexp in `generic-find-file-regexp'. If the value is nil,
185;;;###autoload 185;;;###autoload
186(defmacro define-generic-mode (mode comment-list keyword-list 186(defmacro define-generic-mode (mode comment-list keyword-list
187 font-lock-list auto-mode-list 187 font-lock-list auto-mode-list
188 function-list &optional docstring) 188 function-list &optional docstring
189 &rest custom-keyword-args)
189 "Create a new generic mode MODE. 190 "Create a new generic mode MODE.
190 191
191MODE is the name of the command for the generic mode; it need not 192MODE is the name of the command for the generic mode; it need not
@@ -216,59 +217,90 @@ as soon as `define-generic-mode' is called.
216FUNCTION-LIST is a list of functions to call to do some 217FUNCTION-LIST is a list of functions to call to do some
217additional setup. 218additional setup.
218 219
220The optional CUSTOM-KEYWORD-ARGS are pairs of keywords and
221values. They will be passed to the generated `defcustom' form of
222the mode hook variable MODE-hook. You can specify keyword
223arguments without specifying a docstring.
224
219See the file generic-x.el for some examples of `define-generic-mode'." 225See the file generic-x.el for some examples of `define-generic-mode'."
220 (let* ((name-unquoted (if (eq (car-safe mode) 'quote) ; Backward compatibility. 226 (declare (debug (sexp def-form def-form def-form form def-form
221 (eval mode) 227 &optional stringp))
222 mode)) 228 (indent 1))
223 (name-string (symbol-name name-unquoted)) 229
230 ;; Backward compatibility.
231 (when (eq (car-safe mode) 'quote)
232 (setq mode (eval mode)))
233
234 (when (and docstring (not (stringp docstring)))
235 ;; DOCSTRING is not a string so we assume that it's actually the
236 ;; first keyword of CUSTOM-KEYWORD-ARGS.
237 (push docstring custom-keyword-args)
238 (setq docstring nil))
239
240 (let* ((mode-name (symbol-name mode))
224 (pretty-name (capitalize (replace-regexp-in-string 241 (pretty-name (capitalize (replace-regexp-in-string
225 "-mode\\'" "" name-string)))) 242 "-mode\\'" "" mode-name)))
243 (mode-hook (intern (concat mode-name "-hook"))))
244
245 (unless (plist-get custom-keyword-args :group)
246 (setq custom-keyword-args
247 (plist-put custom-keyword-args
248 :group `(or (custom-current-group)
249 ',(intern (replace-regexp-in-string
250 "-mode\\'" "" mode-name))))))
226 251
227 `(progn 252 `(progn
228 ;; Add a new entry. 253 ;; Add a new entry.
229 (add-to-list 'generic-mode-list ,name-string) 254 (add-to-list 'generic-mode-list ,mode-name)
230 255
231 ;; Add it to auto-mode-alist 256 ;; Add it to auto-mode-alist
232 (dolist (re ,auto-mode-list) 257 (dolist (re ,auto-mode-list)
233 (add-to-list 'auto-mode-alist (cons re ',name-unquoted))) 258 (add-to-list 'auto-mode-alist (cons re ',mode)))
259
260 (defcustom ,mode-hook nil
261 ,(concat "Hook run when entering " pretty-name " mode.")
262 :type 'hook
263 ,@custom-keyword-args)
234 264
235 (defun ,name-unquoted () 265 (defun ,mode ()
236 ,(or docstring 266 ,(or docstring
237 (concat pretty-name " mode.\n" 267 (concat pretty-name " mode.\n"
238 "This a generic mode defined with `define-generic-mode'.")) 268 "This a generic mode defined with `define-generic-mode'."))
239 (interactive) 269 (interactive)
240 (generic-mode-internal ',name-unquoted ,comment-list ,keyword-list 270 (generic-mode-internal ',mode ,comment-list ,keyword-list
241 ,font-lock-list ,function-list))))) 271 ,font-lock-list ,function-list)))))
242 272
243;;;###autoload 273;;;###autoload
244(defun generic-mode-internal (mode comments keywords font-lock-list funs) 274(defun generic-mode-internal (mode comment-list keyword-list
275 font-lock-list function-list)
245 "Go into the generic mode MODE." 276 "Go into the generic mode MODE."
246 (let* ((modename (symbol-name mode)) 277 (let* ((mode-name (symbol-name mode))
247 (generic-mode-hooks (intern (concat modename "-hook")))
248 (pretty-name (capitalize (replace-regexp-in-string 278 (pretty-name (capitalize (replace-regexp-in-string
249 "-mode\\'" "" modename)))) 279 "-mode\\'" "" mode-name)))
280 (mode-hook (intern (concat mode-name "-hook"))))
250 281
251 (kill-all-local-variables) 282 (kill-all-local-variables)
252 283
253 (setq major-mode mode 284 (setq major-mode mode
254 mode-name pretty-name) 285 mode-name pretty-name)
255 286
256 (generic-mode-set-comments comments) 287 (generic-mode-set-comments comment-list)
257 288
258 ;; Font-lock functionality. 289 ;; Font-lock functionality.
259 ;; Font-lock-defaults is always set even if there are no keywords 290 ;; Font-lock-defaults is always set even if there are no keywords
260 ;; or font-lock expressions, so comments can be highlighted. 291 ;; or font-lock expressions, so comments can be highlighted.
261 (setq generic-font-lock-keywords 292 (setq generic-font-lock-keywords
262 (append 293 (append
263 (when keywords 294 (when keyword-list
264 (list (generic-make-keywords-list keywords font-lock-keyword-face))) 295 (list (generic-make-keywords-list keyword-list
296 font-lock-keyword-face)))
265 font-lock-list)) 297 font-lock-list))
266 (setq font-lock-defaults '(generic-font-lock-keywords nil)) 298 (setq font-lock-defaults '(generic-font-lock-keywords nil))
267 299
268 ;; Call a list of functions 300 ;; Call a list of functions
269 (mapcar 'funcall funs) 301 (mapcar 'funcall function-list)
270 302
271 (run-hooks generic-mode-hooks))) 303 (run-mode-hooks mode-hook)))
272 304
273;;;###autoload 305;;;###autoload
274(defun generic-mode (mode) 306(defun generic-mode (mode)
@@ -359,7 +391,7 @@ Some generic modes are defined in `generic-x.el'."
359 imenu-case-fold-search t)) 391 imenu-case-fold-search t))
360 392
361;; This generic mode is always defined 393;; This generic mode is always defined
362(define-generic-mode default-generic-mode (list ?#) nil nil nil nil) 394(define-generic-mode default-generic-mode (list ?#) nil nil nil nil :group 'generic)
363 395
364;; A more general solution would allow us to enter generic-mode for 396;; A more general solution would allow us to enter generic-mode for
365;; *any* comment character, but would require us to synthesize a new 397;; *any* comment character, but would require us to synthesize a new
@@ -392,7 +424,7 @@ This hook will be installed if the variable
392 424
393(defun generic-mode-ini-file-find-file-hook () 425(defun generic-mode-ini-file-find-file-hook ()
394 "Hook function to enter Default-Generic mode automatically for INI files. 426 "Hook function to enter Default-Generic mode automatically for INI files.
395Done if the first few lines of a file in Fundamental mode look like an 427Done if the first few lines of a file in Fundamental mode look like an
396INI file. This hook is NOT installed by default." 428INI file. This hook is NOT installed by default."
397 (and (eq major-mode 'fundamental-mode) 429 (and (eq major-mode 'fundamental-mode)
398 (save-excursion 430 (save-excursion