comparison lisp/textmodes/conf-mode.el @ 66524:33e9ace34df4

(conf-mode-initialize): New function. (conf-mode): Remove optional args. Use delay-mode-hooks to recognize recursive calls. (conf-unix-mode, conf-windows-mode, conf-javaprop-mode, conf-space-mode) (conf-colon-mode, conf-ppd-mode, conf-xdefaults-mode): Use define-derived-mode and conf-mode-initialize.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Sat, 29 Oct 2005 16:01:37 +0000
parents fe198c9ace5c
children 067115a6e738
comparison
equal deleted inserted replaced
66523:7ca34a6ac6c6 66524:33e9ace34df4
199 ;; section { ... } (do this last because some assign ...{...) 199 ;; section { ... } (do this last because some assign ...{...)
200 ("^[ \t]*\\([^:\n]+\\)[ \t\n]*{[^{}]*?$" 1 'font-lock-type-face prepend)) 200 ("^[ \t]*\\([^:\n]+\\)[ \t\n]*{[^{}]*?$" 1 'font-lock-type-face prepend))
201 "Keywords to hilight in Conf Colon mode.") 201 "Keywords to hilight in Conf Colon mode.")
202 202
203 (defvar conf-assignment-sign ?= 203 (defvar conf-assignment-sign ?=
204 "What sign is used for assignments.") 204 "Sign used for assignments (char or string).")
205 205
206 (defvar conf-assignment-regexp ".+?\\([ \t]*=[ \t]*\\)" 206 (defvar conf-assignment-regexp ".+?\\([ \t]*=[ \t]*\\)"
207 "Regexp to recognize assignments. 207 "Regexp to recognize assignments.
208 It is anchored after the first sexp on a line. There must a 208 It is anchored after the first sexp on a line. There must be a
209 grouping for the assignment sign, including leading and trailing 209 grouping for the assignment sign, including leading and trailing
210 whitespace.") 210 whitespace.")
211 211
212 212
213 ;; If anybody can figure out how to get the same effect by configuring 213 ;; If anybody can figure out how to get the same effect by configuring
277 (scan-error depth)))) 277 (scan-error depth))))
278 278
279 279
280 280
281 ;;;###autoload 281 ;;;###autoload
282 (defun conf-mode (&optional comment syntax-table name) 282 (defun conf-mode ()
283 "Mode for Unix and Windows Conf files and Java properties. 283 "Mode for Unix and Windows Conf files and Java properties.
284 Most conf files know only three kinds of constructs: parameter 284 Most conf files know only three kinds of constructs: parameter
285 assignments optionally grouped into sections and comments. Yet 285 assignments optionally grouped into sections and comments. Yet
286 there is a great range of variation in the exact syntax of conf 286 there is a great range of variation in the exact syntax of conf
287 files. See below for various wrapper commands that set up the 287 files. See below for various wrapper commands that set up the
309 `conf-ppd-mode' and `conf-xdefaults-mode'. 309 `conf-ppd-mode' and `conf-xdefaults-mode'.
310 310
311 \\{conf-mode-map}" 311 \\{conf-mode-map}"
312 312
313 (interactive) 313 (interactive)
314 (if (not comment) 314 ;; `conf-mode' plays two roles: it's the parent of several sub-modes
315 ;; but it's also the function that chooses between those submodes.
316 ;; To tell the difference between those two cases where the function
317 ;; might be called, we check `delay-mode-hooks'.
318 ;; (adopted from tex-mode.el)
319 (if (not delay-mode-hooks)
320 ;; try to guess sub-mode of conf-mode based on buffer content
315 (let ((unix 0) (win 0) (equal 0) (colon 0) (space 0) (jp 0)) 321 (let ((unix 0) (win 0) (equal 0) (colon 0) (space 0) (jp 0))
316 (save-excursion 322 (save-excursion
317 (goto-char (point-min)) 323 (goto-char (point-min))
318 (while (not (eobp)) 324 (while (not (eobp))
319 (skip-chars-forward " \t\f") 325 (skip-chars-forward " \t\f")
336 ((> colon (max equal space)) (conf-colon-mode)) 342 ((> colon (max equal space)) (conf-colon-mode))
337 ((> space (max equal colon)) (conf-space-mode)) 343 ((> space (max equal colon)) (conf-space-mode))
338 ((or (> win unix) (and (= win unix) (eq system-type 'windows-nt))) 344 ((or (> win unix) (and (= win unix) (eq system-type 'windows-nt)))
339 (conf-windows-mode)) 345 (conf-windows-mode))
340 (t (conf-unix-mode)))) 346 (t (conf-unix-mode))))
347
341 (kill-all-local-variables) 348 (kill-all-local-variables)
342 (use-local-map conf-mode-map) 349 (use-local-map conf-mode-map)
343
344 (setq major-mode 'conf-mode 350 (setq major-mode 'conf-mode
345 mode-name name) 351 mode-name "Conf[?]")
346 (set (make-local-variable 'font-lock-defaults) 352 (set (make-local-variable 'font-lock-defaults)
347 '(conf-font-lock-keywords nil t nil nil)) 353 '(conf-font-lock-keywords nil t nil nil))
348 (set (make-local-variable 'comment-start) comment) 354 ;; Let newcomment.el decide this for itself.
349 (set (make-local-variable 'comment-start-skip)
350 (concat (regexp-quote comment-start) "+\\s *"))
351 ;; Let newcomment.el decide this for himself.
352 ;; (set (make-local-variable 'comment-use-syntax) t) 355 ;; (set (make-local-variable 'comment-use-syntax) t)
353 (set (make-local-variable 'parse-sexp-ignore-comments) t) 356 (set (make-local-variable 'parse-sexp-ignore-comments) t)
354 (set (make-local-variable 'outline-regexp) 357 (set (make-local-variable 'outline-regexp)
355 "[ \t]*\\(?:\\[\\|.+[ \t\n]*{\\)") 358 "[ \t]*\\(?:\\[\\|.+[ \t\n]*{\\)")
356 (set (make-local-variable 'outline-heading-end-regexp) 359 (set (make-local-variable 'outline-heading-end-regexp)
357 "[\n}]") 360 "[\n}]")
358 (set (make-local-variable 'outline-level) 361 (set (make-local-variable 'outline-level)
359 'conf-outline-level) 362 'conf-outline-level)
360 (set-syntax-table syntax-table) 363 (set-syntax-table conf-mode-syntax-table)
361 (setq imenu-generic-expression 364 (setq imenu-generic-expression
362 '(("Parameters" "^[ \t]*\\(.+?\\)[ \t]*=" 1) 365 '(("Parameters" "^[ \t]*\\(.+?\\)[ \t]*=" 1)
363 ;; [section] 366 ;; [section]
364 (nil "^[ \t]*\\[[ \t]*\\(.+\\)[ \t]*\\]" 1) 367 (nil "^[ \t]*\\[[ \t]*\\(.+\\)[ \t]*\\]" 1)
365 ;; section { ... } 368 ;; section { ... }
366 (nil "^[ \t]*\\([^=:{} \t\n][^=:{}\n]+\\)[ \t\n]*{" 1))) 369 (nil "^[ \t]*\\([^=:{} \t\n][^=:{}\n]+\\)[ \t\n]*{" 1)))
367
368 (run-mode-hooks 'conf-mode-hook))) 370 (run-mode-hooks 'conf-mode-hook)))
369 371
370 ;;;###autoload 372 (defun conf-mode-initialize (comment &optional font-lock)
371 (defun conf-unix-mode () 373 "Intitializations for sub-modes of conf-mode.
374 COMMENT initializes `comment-start' and `comment-start-skip'.
375 The optional arg FONT-LOCK is the value for FONT-LOCK-KEYWORDS."
376 (set (make-local-variable 'comment-start) comment)
377 (set (make-local-variable 'comment-start-skip)
378 (concat (regexp-quote comment-start) "+\\s *"))
379 (if font-lock
380 (set (make-local-variable 'font-lock-defaults)
381 `(,font-lock nil t nil nil))))
382
383 ;;;###autoload
384 (define-derived-mode conf-unix-mode conf-mode "Conf[Unix]"
372 "Conf Mode starter for Unix style Conf files. 385 "Conf Mode starter for Unix style Conf files.
373 Comments start with `#'. 386 Comments start with `#'.
374 For details see `conf-mode'. Example: 387 For details see `conf-mode'. Example:
375 388
376 # Conf mode font-locks this right on Unix and with \\[conf-unix-mode] 389 # Conf mode font-locks this right on Unix and with \\[conf-unix-mode]
378 \[Desktop Entry] 391 \[Desktop Entry]
379 Encoding=UTF-8 392 Encoding=UTF-8
380 Name=The GIMP 393 Name=The GIMP
381 Name[ca]=El GIMP 394 Name[ca]=El GIMP
382 Name[cs]=GIMP" 395 Name[cs]=GIMP"
383 (interactive) 396 (conf-mode-initialize "#"))
384 (conf-mode "#" conf-unix-mode-syntax-table "Conf[Unix]")) 397
385 398 ;;;###autoload
386 ;;;###autoload 399 (define-derived-mode conf-windows-mode conf-mode "Conf[WinIni]"
387 (defun conf-windows-mode ()
388 "Conf Mode starter for Windows style Conf files. 400 "Conf Mode starter for Windows style Conf files.
389 Comments start with `;'. 401 Comments start with `;'.
390 For details see `conf-mode'. Example: 402 For details see `conf-mode'. Example:
391 403
392 ; Conf mode font-locks this right on Windows and with \\[conf-windows-mode] 404 ; Conf mode font-locks this right on Windows and with \\[conf-windows-mode]
395 Default={5984FFE0-28D4-11CF-AE66-08002B2E1262} 407 Default={5984FFE0-28D4-11CF-AE66-08002B2E1262}
396 {5984FFE0-28D4-11CF-AE66-08002B2E1262}={5984FFE0-28D4-11CF-AE66-08002B2E1262} 408 {5984FFE0-28D4-11CF-AE66-08002B2E1262}={5984FFE0-28D4-11CF-AE66-08002B2E1262}
397 409
398 \[{5984FFE0-28D4-11CF-AE66-08002B2E1262}] 410 \[{5984FFE0-28D4-11CF-AE66-08002B2E1262}]
399 PersistMoniker=file://Folder.htt" 411 PersistMoniker=file://Folder.htt"
400 (interactive) 412 (conf-mode-initialize ";"))
401 (conf-mode ";" conf-mode-syntax-table "Conf[WinIni]"))
402 413
403 ;; Here are a few more or less widespread styles. There are others, so 414 ;; Here are a few more or less widespread styles. There are others, so
404 ;; obscure, they are not covered. E.g. RFC 2614 allows both Unix and Windows 415 ;; obscure, they are not covered. E.g. RFC 2614 allows both Unix and Windows
405 ;; comments. Or the donkey has (* Pascal comments *) -- roll your own starter 416 ;; comments. Or the donkey has (* Pascal comments *) -- roll your own starter
406 ;; if you need it. 417 ;; if you need it.
407 418
408 ;;;###autoload 419 ;;;###autoload
409 (defun conf-javaprop-mode () 420 (define-derived-mode conf-javaprop-mode conf-mode "Conf[JavaProp]"
410 "Conf Mode starter for Java properties files. 421 "Conf Mode starter for Java properties files.
411 Comments start with `#' but are also recognized with `//' or 422 Comments start with `#' but are also recognized with `//' or
412 between `/*' and `*/'. 423 between `/*' and `*/'.
413 For details see `conf-mode'. Example: 424 For details see `conf-mode'. Example:
414 425
420 name=value 431 name=value
421 name value 432 name value
422 x.1 = 433 x.1 =
423 x.2.y.1.z.1 = 434 x.2.y.1.z.1 =
424 x.2.y.1.z.2.zz =" 435 x.2.y.1.z.2.zz ="
425 (interactive) 436 (conf-mode-initialize "#" 'conf-javaprop-font-lock-keywords)
426 (conf-mode "#" conf-javaprop-mode-syntax-table "Conf[JavaProp]")
427 (set (make-local-variable 'conf-assignment-column) 437 (set (make-local-variable 'conf-assignment-column)
428 conf-javaprop-assignment-column) 438 conf-javaprop-assignment-column)
429 (set (make-local-variable 'conf-assignment-regexp) 439 (set (make-local-variable 'conf-assignment-regexp)
430 ".+?\\([ \t]*[=: \t][ \t]*\\|$\\)") 440 ".+?\\([ \t]*[=: \t][ \t]*\\|$\\)")
431 (set (make-local-variable 'conf-font-lock-keywords)
432 conf-javaprop-font-lock-keywords)
433 (setq comment-start-skip "\\(?:#+\\|/[/*]+\\)\\s *") 441 (setq comment-start-skip "\\(?:#+\\|/[/*]+\\)\\s *")
434 (setq imenu-generic-expression 442 (setq imenu-generic-expression
435 '(("Parameters" "^[ \t]*\\(.+?\\)[=: \t]" 1)))) 443 '(("Parameters" "^[ \t]*\\(.+?\\)[=: \t]" 1))))
436 444
437 ;;;###autoload 445 ;;;###autoload
438 (defun conf-space-mode (&optional keywords) 446 (define-derived-mode conf-space-mode conf-unix-mode "Conf[Space]"
439 "Conf Mode starter for space separated conf files. 447 "Conf Mode starter for space separated conf files.
440 \"Assignments\" are with ` '. Keywords before the parameters are 448 \"Assignments\" are with ` '. Keywords before the parameters are
441 recognized according to `conf-space-keywords'. Interactively 449 recognized according to `conf-space-keywords'. Interactively
442 with a prefix ARG of `0' no keywords will be recognized. With 450 with a prefix ARG of `0' no keywords will be recognized. With
443 any other prefix arg you will be prompted for a regexp to match 451 any other prefix arg you will be prompted for a regexp to match
444 the keywords. Programmatically you can pass such a regexp as 452 the keywords.
445 KEYWORDS, or any non-nil non-string for no keywords.
446 453
447 For details see `conf-mode'. Example: 454 For details see `conf-mode'. Example:
448 455
449 # Conf mode font-locks this right with \\[conf-space-mode] (space separated) 456 # Conf mode font-locks this right with \\[conf-space-mode] (space separated)
450 457
455 # Or with keywords (from a recognized file name): 462 # Or with keywords (from a recognized file name):
456 class desktop 463 class desktop
457 # Standard multimedia devices 464 # Standard multimedia devices
458 add /dev/audio desktop 465 add /dev/audio desktop
459 add /dev/mixer desktop" 466 add /dev/mixer desktop"
460 (interactive 467 (conf-mode-initialize "#" 'conf-space-font-lock-keywords)
461 (list (if current-prefix-arg
462 (if (> (prefix-numeric-value current-prefix-arg) 0)
463 (read-string "Regexp to match keywords: ")
464 t))))
465 (conf-unix-mode)
466 (setq mode-name "Conf[Space]")
467 (set (make-local-variable 'conf-assignment-sign) 468 (set (make-local-variable 'conf-assignment-sign)
468 nil) 469 nil)
469 (set (make-local-variable 'conf-font-lock-keywords)
470 conf-space-font-lock-keywords)
471 ;; This doesn't seem right, but the next two depend on conf-space-keywords 470 ;; This doesn't seem right, but the next two depend on conf-space-keywords
472 ;; being set, while after-change-major-mode-hook might set up imenu, needing 471 ;; being set, while after-change-major-mode-hook might set up imenu, needing
473 ;; the following result: 472 ;; the following result:
474 (hack-local-variables-prop-line) 473 (hack-local-variables-prop-line)
475 (hack-local-variables) 474 (hack-local-variables)
476 (if keywords 475 (cond (current-prefix-arg
477 (set (make-local-variable 'conf-space-keywords) 476 (set (make-local-variable 'conf-space-keywords)
478 (if (stringp keywords) keywords)) 477 (if (> (prefix-numeric-value current-prefix-arg) 0)
479 (or conf-space-keywords 478 (read-string "Regexp to match keywords: "))))
480 (not buffer-file-name) 479 (conf-space-keywords)
481 (set (make-local-variable 'conf-space-keywords) 480 (buffer-file-name
482 (assoc-default buffer-file-name conf-space-keywords-alist 481 (set (make-local-variable 'conf-space-keywords)
483 'string-match)))) 482 (assoc-default buffer-file-name conf-space-keywords-alist
483 'string-match))))
484 (set (make-local-variable 'conf-assignment-regexp) 484 (set (make-local-variable 'conf-assignment-regexp)
485 (if conf-space-keywords 485 (if conf-space-keywords
486 (concat "\\(?:" conf-space-keywords "\\)[ \t]+.+?\\([ \t]+\\|$\\)") 486 (concat "\\(?:" conf-space-keywords "\\)[ \t]+.+?\\([ \t]+\\|$\\)")
487 ".+?\\([ \t]+\\|$\\)")) 487 ".+?\\([ \t]+\\|$\\)"))
488 (setq imenu-generic-expression 488 (setq imenu-generic-expression
493 "\\)[ \t]+\\([^ \t\n]+\\)\\(?:[ \t]\\|$\\)") 493 "\\)[ \t]+\\([^ \t\n]+\\)\\(?:[ \t]\\|$\\)")
494 "^[ \t]*\\([^ \t\n[]+\\)\\(?:[ \t]\\|$\\)") 494 "^[ \t]*\\([^ \t\n[]+\\)\\(?:[ \t]\\|$\\)")
495 1)))) 495 1))))
496 496
497 ;;;###autoload 497 ;;;###autoload
498 (defun conf-colon-mode (&optional comment syntax-table name) 498 (define-derived-mode conf-colon-mode conf-unix-mode "Conf[Colon]"
499 "Conf Mode starter for Colon files. 499 "Conf Mode starter for Colon files.
500 \"Assignments\" are with `:'. 500 \"Assignments\" are with `:'.
501 For details see `conf-mode'. Example: 501 For details see `conf-mode'. Example:
502 502
503 # Conf mode font-locks this right with \\[conf-colon-mode] (colon) 503 # Conf mode font-locks this right with \\[conf-colon-mode] (colon)
504 504
505 <Multi_key> <exclam> <exclam> : \"\\241\" exclamdown 505 <Multi_key> <exclam> <exclam> : \"\\241\" exclamdown
506 <Multi_key> <c> <slash> : \"\\242\" cent" 506 <Multi_key> <c> <slash> : \"\\242\" cent"
507 (interactive) 507 (conf-mode-initialize "#" 'conf-colon-font-lock-keywords)
508 (if comment
509 (conf-mode comment syntax-table name)
510 (conf-unix-mode)
511 (setq mode-name "Conf[Colon]"))
512 (set (make-local-variable 'conf-assignment-space) 508 (set (make-local-variable 'conf-assignment-space)
513 conf-colon-assignment-space) 509 conf-colon-assignment-space)
514 (set (make-local-variable 'conf-assignment-column) 510 (set (make-local-variable 'conf-assignment-column)
515 conf-colon-assignment-column) 511 conf-colon-assignment-column)
516 (set (make-local-variable 'conf-assignment-sign) 512 (set (make-local-variable 'conf-assignment-sign)
517 ?:) 513 ?:)
518 (set (make-local-variable 'conf-assignment-regexp) 514 (set (make-local-variable 'conf-assignment-regexp)
519 ".+?\\([ \t]*:[ \t]*\\)") 515 ".+?\\([ \t]*:[ \t]*\\)")
520 (set (make-local-variable 'conf-font-lock-keywords)
521 conf-colon-font-lock-keywords)
522 (setq imenu-generic-expression 516 (setq imenu-generic-expression
523 `(("Parameters" "^[ \t]*\\(.+?\\)[ \t]*:" 1) 517 `(("Parameters" "^[ \t]*\\(.+?\\)[ \t]*:" 1)
524 ,@(cdr imenu-generic-expression)))) 518 ,@(cdr imenu-generic-expression))))
525 519
526 ;;;###autoload 520 ;;;###autoload
527 (defun conf-ppd-mode () 521 (define-derived-mode conf-ppd-mode conf-colon-mode "Conf[PPD]"
528 "Conf Mode starter for Adobe/CUPS PPD files. 522 "Conf Mode starter for Adobe/CUPS PPD files.
529 Comments start with `*%' and \"assignments\" are with `:'. 523 Comments start with `*%' and \"assignments\" are with `:'.
530 For details see `conf-mode'. Example: 524 For details see `conf-mode'. Example:
531 525
532 *% Conf mode font-locks this right with \\[conf-ppd-mode] (PPD) 526 *% Conf mode font-locks this right with \\[conf-ppd-mode] (PPD)
533 527
534 *DefaultTransfer: Null 528 *DefaultTransfer: Null
535 *Transfer Null.Inverse: \"{ 1 exch sub }\"" 529 *Transfer Null.Inverse: \"{ 1 exch sub }\""
536 (interactive) 530 (conf-mode-initialize "*%")
537 (conf-colon-mode "*%" conf-ppd-mode-syntax-table "Conf[PPD]")
538 ;; no sections, they match within PostScript code 531 ;; no sections, they match within PostScript code
539 (setq imenu-generic-expression (list (car imenu-generic-expression)))) 532 (setq imenu-generic-expression (list (car imenu-generic-expression))))
540 533
541 ;;;###autoload 534 ;;;###autoload
542 (defun conf-xdefaults-mode () 535 (define-derived-mode conf-xdefaults-mode conf-colon-mode "Conf[Xdefaults]"
543 "Conf Mode starter for Xdefaults files. 536 "Conf Mode starter for Xdefaults files.
544 Comments start with `!' and \"assignments\" are with `:'. 537 Comments start with `!' and \"assignments\" are with `:'.
545 For details see `conf-mode'. Example: 538 For details see `conf-mode'. Example:
546 539
547 ! Conf mode font-locks this right with \\[conf-xdefaults-mode] (.Xdefaults) 540 ! Conf mode font-locks this right with \\[conf-xdefaults-mode] (.Xdefaults)
548 541
549 *background: gray99 542 *background: gray99
550 *foreground: black" 543 *foreground: black"
551 (interactive) 544 (conf-mode-initialize "!"))
552 (conf-colon-mode "!" conf-xdefaults-mode-syntax-table "Conf[Xdefaults]"))
553 545
554 (provide 'conf-mode) 546 (provide 'conf-mode)
555 547
556 ;; arch-tag: 0a3805b2-0371-4d3a-8498-8897116b2356 548 ;; arch-tag: 0a3805b2-0371-4d3a-8498-8897116b2356
557 ;;; conf-mode.el ends here 549 ;;; conf-mode.el ends here