(conf-space-keywords): Mark this regexp as safe if a string.
[bpt/emacs.git] / lisp / textmodes / conf-mode.el
1 ;;; conf-mode.el --- Simple major mode for editing conf/ini/properties files
2
3 ;; Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
4
5 ;; Author: Daniel Pfeiffer <occitan@esperanto.org>
6 ;; Keywords: conf ini windows java
7
8 ;; This file is part of GNU Emacs.
9
10 ;; GNU Emacs is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14
15 ;; GNU Emacs is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING. If not, write to the
22 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.
24
25 ;;; Commentary:
26 ;;
27 ;; This mode is designed to edit many similar varieties of Conf/Ini files and
28 ;; Java properties. It started out from Aurélien Tisné's ini-mode.
29 ;; `conf-space-keywords' were inspired by Robert Fitzgerald's any-ini-mode.
30
31
32 ;;; Code:
33
34 (require 'newcomment)
35
36 (defvar outline-heading-end-regexp)
37
38 ;; Variables:
39
40 (defgroup conf nil
41 "Configuration files."
42 :group 'data
43 :version "22.1")
44
45 (defcustom conf-assignment-column 24
46 "Align assignments to this column by default with \\[conf-align-assignments].
47 If this number is negative, the `=' comes before the whitespace. Use 0 to
48 not align (only setting space according to `conf-assignment-space')."
49 :type 'integer
50 :group 'conf)
51
52 (defcustom conf-javaprop-assignment-column 32
53 "Value for `conf-assignment-column' in Java properties buffers."
54 :type 'integer
55 :group 'conf)
56
57 (defcustom conf-colon-assignment-column (- (abs conf-assignment-column))
58 "Value for `conf-assignment-column' in Java properties buffers."
59 :type 'integer
60 :group 'conf)
61
62 (defcustom conf-assignment-space t
63 "Put at least one space around assignments when aligning."
64 :type 'boolean
65 :group 'conf)
66
67 (defcustom conf-colon-assignment-space nil
68 "Value for `conf-assignment-space' in colon style Conf mode buffers."
69 :type 'boolean
70 :group 'conf)
71
72
73 (defvar conf-mode-map
74 (let ((map (make-sparse-keymap)))
75 (define-key map "\C-c\C-u" 'conf-unix-mode)
76 (define-key map "\C-c\C-w" 'conf-windows-mode)
77 (define-key map "\C-c\C-j" 'conf-javaprop-mode)
78 (define-key map "\C-c\C-s" 'conf-space-keywords)
79 (define-key map "\C-c " 'conf-space-keywords)
80 (define-key map "\C-c\C-c" 'conf-colon-mode)
81 (define-key map "\C-c:" 'conf-colon-mode)
82 (define-key map "\C-c\C-x" 'conf-xdefaults-mode)
83 (define-key map "\C-c\C-p" 'conf-ppd-mode)
84 (define-key map "\C-c\C-q" 'conf-quote-normal)
85 (define-key map "\C-c\"" 'conf-quote-normal)
86 (define-key map "\C-c'" 'conf-quote-normal)
87 (define-key map "\C-c\C-a" 'conf-align-assignments)
88 map)
89 "Local keymap for `conf-mode' buffers.")
90
91 (defvar conf-mode-syntax-table
92 (let ((table (make-syntax-table)))
93 (modify-syntax-entry ?= "." table)
94 (modify-syntax-entry ?_ "_" table)
95 (modify-syntax-entry ?- "_" table)
96 (modify-syntax-entry ?. "_" table)
97 (modify-syntax-entry ?\' "\"" table)
98 (modify-syntax-entry ?\; "<" table)
99 (modify-syntax-entry ?\n ">" table)
100 (modify-syntax-entry ?\r ">" table)
101 table)
102 "Syntax table in use in Windows style `conf-mode' buffers.")
103
104 (defvar conf-unix-mode-syntax-table
105 (let ((table (make-syntax-table conf-mode-syntax-table)))
106 (modify-syntax-entry ?\# "<" table)
107 ;; override
108 (modify-syntax-entry ?\; "." table)
109 table)
110 "Syntax table in use in Unix style `conf-mode' buffers.")
111
112 (defvar conf-javaprop-mode-syntax-table
113 (let ((table (make-syntax-table conf-unix-mode-syntax-table)))
114 (modify-syntax-entry ?/ ". 124" table)
115 (modify-syntax-entry ?* ". 23b" table)
116 table)
117 "Syntax table in use in Java prperties buffers.")
118
119 (defvar conf-ppd-mode-syntax-table
120 (let ((table (make-syntax-table conf-mode-syntax-table)))
121 (modify-syntax-entry ?* ". 1" table)
122 (modify-syntax-entry ?% ". 2" table)
123 ;; override
124 (modify-syntax-entry ?\' "." table)
125 (modify-syntax-entry ?\; "." table)
126 table)
127 "Syntax table in use in PPD `conf-mode' buffers.")
128
129 (defvar conf-xdefaults-mode-syntax-table
130 (let ((table (make-syntax-table conf-mode-syntax-table)))
131 (modify-syntax-entry ?! "<" table)
132 ;; override
133 (modify-syntax-entry ?\; "." table)
134 table)
135 "Syntax table in use in Xdefaults style `conf-mode' buffers.")
136
137
138 (defvar conf-font-lock-keywords
139 `(;; [section] (do this first because it may look like a parameter)
140 ("^[ \t]*\\[\\(.+\\)\\]" 1 'font-lock-type-face)
141 ;; var=val or var[index]=val
142 ("^[ \t]*\\(.+?\\)\\(?:\\[\\(.*?\\)\\]\\)?[ \t]*="
143 (1 'font-lock-variable-name-face)
144 (2 'font-lock-constant-face nil t))
145 ;; section { ... } (do this last because some assign ...{...)
146 ("^[ \t]*\\([^=:\n]+?\\)[ \t\n]*{[^{}]*?$" 1 'font-lock-type-face prepend))
147 "Keywords to hilight in Conf mode.")
148
149 (defvar conf-javaprop-font-lock-keywords
150 '(;; var=val
151 ("^[ \t]*\\(.+?\\)\\(?:\\.\\([0-9]+\\)\\(?:\\.\\(.+?\\)\\(?:\\.\\([0-9]+\\)\\(?:\\.\\(.+?\\)\\(?:\\.\\([0-9]+\\)\\(\\..+?\\)?\\)?\\)?\\)?\\)?\\)?\\([:= \t]\\|$\\)"
152 (1 'font-lock-variable-name-face)
153 (2 'font-lock-constant-face nil t)
154 (3 'font-lock-variable-name-face nil t)
155 (4 'font-lock-constant-face nil t)
156 (5 'font-lock-variable-name-face nil t)
157 (6 'font-lock-constant-face nil t)
158 (7 'font-lock-variable-name-face nil t)))
159 "Keywords to hilight in Conf Java Properties mode.")
160
161 (defvar conf-space-keywords-alist
162 '(("\\`/etc/gpm/" . "key\\|name\\|foreground\\|background\\|border\\|head")
163 ("\\`/etc/magic\\'" . "[^ \t]+[ \t]+\\(?:[bl]?e?\\(?:short\\|long\\)\\|byte\\|string\\)[^ \t]*")
164 ("/mod\\(?:ules\\|probe\\)\\.conf" . "alias\\|in\\(?:clude\\|stall\\)\\|options\\|remove")
165 ("/manpath\\.config" . "MAN\\(?:DATORY_MANPATH\\|PATH_MAP\\|DB_MAP\\)")
166 ("/sensors\\.conf" . "chip\\|bus\\|label\\|compute\\|set\\|ignore")
167 ("/sane\\(\\.d\\)?/" . "option\\|device\\|port\\|usb\\|sc\\(?:si\\|anner\\)")
168 ("/resmgr\\.conf" . "class\\|add\\|allow\\|deny")
169 ("/dictionary\\.lst\\'" . "DICT\\|HYPH\\|THES")
170 ("/tuxracer/options" . "set"))
171 "File-name-based settings for the variable `conf-space-keywords'.")
172
173 (defvar conf-space-keywords nil
174 "Regexps for functions that may come before a space assignment.
175 This allows constructs such as
176 keyword var value
177 This variable is best set in the file local variables, or through
178 `conf-space-keywords-alist'.")
179 (put 'conf-space-keywords 'safe-local-variable 'stringp)
180
181 (defvar conf-space-font-lock-keywords
182 `(;; [section] (do this first because it may look like a parameter)
183 ("^[ \t]*\\[\\(.+\\)\\]" 1 'font-lock-type-face)
184 ;; section { ... } (do this first because it looks like a parameter)
185 ("^[ \t]*\\(.+?\\)[ \t\n]*{[^{}]*?$" 1 'font-lock-type-face)
186 ;; var val
187 (eval if conf-space-keywords
188 (list (concat "^[ \t]*\\(" conf-space-keywords "\\)[ \t]+\\([^\000- ]+\\)")
189 '(1 'font-lock-keyword-face)
190 '(2 'font-lock-variable-name-face))
191 '("^[ \t]*\\([^\000- ]+\\)" 1 'font-lock-variable-name-face)))
192 "Keywords to highlight in Conf Space mode.")
193
194 (defvar conf-colon-font-lock-keywords
195 `(;; [section] (do this first because it may look like a parameter)
196 ("^[ \t]*\\[\\(.+\\)\\]" 1 'font-lock-type-face)
197 ;; var: val
198 ("^[ \t]*\\(.+?\\)[ \t]*:"
199 (1 'font-lock-variable-name-face))
200 ;; section { ... } (do this last because some assign ...{...)
201 ("^[ \t]*\\([^:\n]+\\)[ \t\n]*{[^{}]*?$" 1 'font-lock-type-face prepend))
202 "Keywords to hilight in Conf Colon mode.")
203
204 (defvar conf-assignment-sign ?=
205 "Sign used for assignments (char or string).")
206
207 (defvar conf-assignment-regexp ".+?\\([ \t]*=[ \t]*\\)"
208 "Regexp to recognize assignments.
209 It is anchored after the first sexp on a line. There must be a
210 grouping for the assignment sign, including leading and trailing
211 whitespace.")
212
213
214 ;; If anybody can figure out how to get the same effect by configuring
215 ;; `align', I'd be glad to hear.
216 (defun conf-align-assignments (&optional arg)
217 (interactive "P")
218 (setq arg (if arg
219 (prefix-numeric-value arg)
220 conf-assignment-column))
221 (save-excursion
222 (goto-char (point-min))
223 (while (not (eobp))
224 (let ((cs (comment-beginning))) ; go before comment if within
225 (if cs (goto-char cs)))
226 (while (forward-comment 9)) ; max-int?
227 (when (and (not (eobp))
228 (looking-at conf-assignment-regexp))
229 (goto-char (match-beginning 1))
230 (delete-region (point) (match-end 1))
231 (if conf-assignment-sign
232 (if (>= arg 0)
233 (progn
234 (indent-to-column arg)
235 (or (not conf-assignment-space)
236 (memq (char-before (point)) '(?\s ?\t)) (insert ?\s))
237 (insert conf-assignment-sign
238 (if (and conf-assignment-space (not (eolp))) ?\s "")))
239 (insert (if conf-assignment-space ?\s "") conf-assignment-sign)
240 (unless (eolp)
241 (indent-to-column (- arg))
242 (or (not conf-assignment-space)
243 (memq (char-before (point)) '(?\s ?\t)) (insert ?\s))))
244 (unless (eolp)
245 (if (>= (current-column) (abs arg))
246 (insert ?\s)
247 (indent-to-column (abs arg))))))
248 (forward-line))))
249
250
251 (defun conf-quote-normal (arg)
252 "Set the syntax of ' and \" to punctuation.
253 With prefix arg, only do it for ' if 1, or only for \" if 2.
254 This only affects the current buffer. Some conf files use quotes
255 to delimit strings, while others allow quotes as simple parts of
256 the assigned value. In those files font locking will be wrong,
257 and you can correct it with this command. (Some files even do
258 both, i.e. quotes delimit strings, except when they are
259 unbalanced, but hey...)"
260 (interactive "P")
261 (let ((table (copy-syntax-table (syntax-table))))
262 (if (or (not arg) (= (prefix-numeric-value arg) 1))
263 (modify-syntax-entry ?\' "." table))
264 (if (or (not arg) (= (prefix-numeric-value arg) 2))
265 (modify-syntax-entry ?\" "." table))
266 (set-syntax-table table)
267 (and (boundp 'font-lock-mode)
268 font-lock-mode
269 (font-lock-fontify-buffer))))
270
271
272 (defun conf-outline-level ()
273 (let ((depth 0)
274 (pt (match-end 0)))
275 (condition-case nil
276 (while (setq pt (scan-lists pt -1 1)
277 depth (1+ depth)))
278 (scan-error depth))))
279
280 \f
281
282 ;;;###autoload
283 (defun conf-mode ()
284 "Mode for Unix and Windows Conf files and Java properties.
285 Most conf files know only three kinds of constructs: parameter
286 assignments optionally grouped into sections and comments. Yet
287 there is a great range of variation in the exact syntax of conf
288 files. See below for various wrapper commands that set up the
289 details for some of the most widespread variants.
290
291 This mode sets up font locking, outline, imenu and it provides
292 alignment support through `conf-align-assignments'. If strings
293 come out wrong, try `conf-quote-normal'.
294
295 Some files allow continuation lines, either with a backslash at
296 the end of line, or by indenting the next line (further). These
297 constructs cannot currently be recognized.
298
299 Because of this great variety of nuances, which are often not
300 even clearly specified, please don't expect it to get every file
301 quite right. Patches that clearly identify some special case,
302 without breaking the general ones, are welcome.
303
304 If instead you start this mode with the generic `conf-mode'
305 command, it will parse the buffer. It will generally well
306 identify the first four cases listed below. If the buffer
307 doesn't have enough contents to decide, this is identical to
308 `conf-windows-mode' on Windows, elsewhere to `conf-unix-mode'.
309 See also `conf-space-mode', `conf-colon-mode', `conf-javaprop-mode',
310 `conf-ppd-mode' and `conf-xdefaults-mode'.
311
312 \\{conf-mode-map}"
313
314 (interactive)
315 ;; `conf-mode' plays two roles: it's the parent of several sub-modes
316 ;; but it's also the function that chooses between those submodes.
317 ;; To tell the difference between those two cases where the function
318 ;; might be called, we check `delay-mode-hooks'.
319 ;; (adopted from tex-mode.el)
320 (if (not delay-mode-hooks)
321 ;; try to guess sub-mode of conf-mode based on buffer content
322 (let ((unix 0) (win 0) (equal 0) (colon 0) (space 0) (jp 0))
323 (save-excursion
324 (goto-char (point-min))
325 (while (not (eobp))
326 (skip-chars-forward " \t\f")
327 (cond ((eq (char-after) ?\#) (setq unix (1+ unix)))
328 ((eq (char-after) ?\;) (setq win (1+ win)))
329 ((eq (char-after) ?\[)) ; nop
330 ((eolp)) ; nop
331 ((eq (char-after) ?})) ; nop
332 ;; recognize at most double spaces within names
333 ((looking-at "[^ \t\n=:]+\\(?: ?[^ \t\n=:]+\\)*[ \t]*[=:]")
334 (if (eq (char-before (match-end 0)) ?=)
335 (setq equal (1+ equal))
336 (setq colon (1+ colon))))
337 ((looking-at "/[/*]") (setq jp (1+ jp)))
338 ((looking-at ".*{")) ; nop
339 ((setq space (1+ space))))
340 (forward-line)))
341 (cond
342 ((> jp (max unix win 3)) (conf-javaprop-mode))
343 ((> colon (max equal space)) (conf-colon-mode))
344 ((> space (max equal colon)) (conf-space-mode))
345 ((or (> win unix) (and (= win unix) (eq system-type 'windows-nt)))
346 (conf-windows-mode))
347 (t (conf-unix-mode))))
348
349 (kill-all-local-variables)
350 (use-local-map conf-mode-map)
351 (setq major-mode 'conf-mode
352 mode-name "Conf[?]")
353 (set (make-local-variable 'font-lock-defaults)
354 '(conf-font-lock-keywords nil t nil nil))
355 ;; Let newcomment.el decide this for itself.
356 ;; (set (make-local-variable 'comment-use-syntax) t)
357 (set (make-local-variable 'parse-sexp-ignore-comments) t)
358 (set (make-local-variable 'outline-regexp)
359 "[ \t]*\\(?:\\[\\|.+[ \t\n]*{\\)")
360 (set (make-local-variable 'outline-heading-end-regexp)
361 "[\n}]")
362 (set (make-local-variable 'outline-level)
363 'conf-outline-level)
364 (set-syntax-table conf-mode-syntax-table)
365 (setq imenu-generic-expression
366 '(("Parameters" "^[ \t]*\\(.+?\\)[ \t]*=" 1)
367 ;; [section]
368 (nil "^[ \t]*\\[[ \t]*\\(.+\\)[ \t]*\\]" 1)
369 ;; section { ... }
370 (nil "^[ \t]*\\([^=:{} \t\n][^=:{}\n]+\\)[ \t\n]*{" 1)))
371 (run-mode-hooks 'conf-mode-hook)))
372
373 (defun conf-mode-initialize (comment &optional font-lock)
374 "Intitializations for sub-modes of conf-mode.
375 COMMENT initializes `comment-start' and `comment-start-skip'.
376 The optional arg FONT-LOCK is the value for FONT-LOCK-KEYWORDS."
377 (set (make-local-variable 'comment-start) comment)
378 (set (make-local-variable 'comment-start-skip)
379 (concat (regexp-quote comment-start) "+\\s *"))
380 (if font-lock
381 (set (make-local-variable 'font-lock-defaults)
382 `(,font-lock nil t nil nil))))
383
384 ;;;###autoload
385 (define-derived-mode conf-unix-mode conf-mode "Conf[Unix]"
386 "Conf Mode starter for Unix style Conf files.
387 Comments start with `#'.
388 For details see `conf-mode'. Example:
389
390 # Conf mode font-locks this right on Unix and with \\[conf-unix-mode]
391
392 \[Desktop Entry]
393 Encoding=UTF-8
394 Name=The GIMP
395 Name[ca]=El GIMP
396 Name[cs]=GIMP"
397 (conf-mode-initialize "#"))
398
399 ;;;###autoload
400 (define-derived-mode conf-windows-mode conf-mode "Conf[WinIni]"
401 "Conf Mode starter for Windows style Conf files.
402 Comments start with `;'.
403 For details see `conf-mode'. Example:
404
405 ; Conf mode font-locks this right on Windows and with \\[conf-windows-mode]
406
407 \[ExtShellFolderViews]
408 Default={5984FFE0-28D4-11CF-AE66-08002B2E1262}
409 {5984FFE0-28D4-11CF-AE66-08002B2E1262}={5984FFE0-28D4-11CF-AE66-08002B2E1262}
410
411 \[{5984FFE0-28D4-11CF-AE66-08002B2E1262}]
412 PersistMoniker=file://Folder.htt"
413 (conf-mode-initialize ";"))
414
415 ;; Here are a few more or less widespread styles. There are others, so
416 ;; obscure, they are not covered. E.g. RFC 2614 allows both Unix and Windows
417 ;; comments. Or the donkey has (* Pascal comments *) -- roll your own starter
418 ;; if you need it.
419
420 ;;;###autoload
421 (define-derived-mode conf-javaprop-mode conf-mode "Conf[JavaProp]"
422 "Conf Mode starter for Java properties files.
423 Comments start with `#' but are also recognized with `//' or
424 between `/*' and `*/'.
425 For details see `conf-mode'. Example:
426
427 # Conf mode font-locks this right with \\[conf-javaprop-mode] (Java properties)
428 // another kind of comment
429 /* yet another */
430
431 name:value
432 name=value
433 name value
434 x.1 =
435 x.2.y.1.z.1 =
436 x.2.y.1.z.2.zz ="
437 (conf-mode-initialize "#" 'conf-javaprop-font-lock-keywords)
438 (set (make-local-variable 'conf-assignment-column)
439 conf-javaprop-assignment-column)
440 (set (make-local-variable 'conf-assignment-regexp)
441 ".+?\\([ \t]*[=: \t][ \t]*\\|$\\)")
442 (setq comment-start-skip "\\(?:#+\\|/[/*]+\\)\\s *")
443 (setq imenu-generic-expression
444 '(("Parameters" "^[ \t]*\\(.+?\\)[=: \t]" 1))))
445
446 ;;;###autoload
447 (define-derived-mode conf-space-mode conf-unix-mode "Conf[Space]"
448 "Conf Mode starter for space separated conf files.
449 \"Assignments\" are with ` '. Keywords before the parameters are
450 recognized according to the variable `conf-space-keywords-alist'.
451 Alternatively, you can specify a value for the file local variable
452 `conf-space-keywords'.
453 Use the function `conf-space-keywords' if you want to specify keywords
454 in an interactive fashion instead.
455
456 For details see `conf-mode'. Example:
457
458 # Conf mode font-locks this right with \\[conf-space-mode] (space separated)
459
460 image/jpeg jpeg jpg jpe
461 image/png png
462 image/tiff tiff tif
463
464 # Or with keywords (from a recognized file name):
465 class desktop
466 # Standard multimedia devices
467 add /dev/audio desktop
468 add /dev/mixer desktop"
469 (conf-mode-initialize "#" 'conf-space-font-lock-keywords)
470 (make-local-variable 'conf-assignment-sign)
471 (setq conf-assignment-sign nil)
472 (make-local-variable 'conf-space-keywords)
473 (cond (buffer-file-name
474 ;; We set conf-space-keywords directly, but a value which is
475 ;; in the local variables list or interactively specified
476 ;; (see the function conf-space-keywords) takes precedence.
477 (setq conf-space-keywords
478 (assoc-default buffer-file-name conf-space-keywords-alist
479 'string-match))))
480 (conf-space-mode-internal)
481 ;; In case the local variables list specifies conf-space-keywords,
482 ;; recompute other things from that afterward.
483 (add-hook 'hack-local-variables-hook 'conf-space-mode-internal nil t))
484
485 ;;;###autoload
486 (defun conf-space-keywords (keywords)
487 "Enter Conf Space mode using regexp KEYWORDS to match the keywords.
488 See `conf-space-mode'."
489 (interactive "sConf Space keyword regexp: ")
490 (delay-mode-hooks
491 (conf-space-mode))
492 (if (string-equal keywords "")
493 (setq keywords nil))
494 (setq conf-space-keywords keywords)
495 (conf-space-mode-internal)
496 (run-mode-hooks))
497
498 (defun conf-space-mode-internal ()
499 (make-local-variable 'conf-assignment-regexp)
500 (setq conf-assignment-regexp
501 (if conf-space-keywords
502 (concat "\\(?:" conf-space-keywords "\\)[ \t]+.+?\\([ \t]+\\|$\\)")
503 ".+?\\([ \t]+\\|$\\)"))
504 ;; If Font Lock is already enabled, reenable it with new
505 ;; conf-assignment-regexp.
506 (when (and font-lock-mode
507 (boundp 'font-lock-keywords)) ;see `normal-mode'
508 (font-lock-add-keywords nil nil)
509 (font-lock-mode 1))
510 ;; Copy so that we don't destroy shared structure.
511 (setq imenu-generic-expression (copy-sequence imenu-generic-expression))
512 ;; Get rid of any existing Parameters element.
513 (setq imenu-generic-expression
514 (delq (assoc "Parameters" imenu-generic-expression)
515 imenu-generic-expression))
516 ;; Add a new one based on conf-space-keywords.
517 (setq imenu-generic-expression
518 (cons `("Parameters"
519 ,(if conf-space-keywords
520 (concat "^[ \t]*\\(?:" conf-space-keywords
521 "\\)[ \t]+\\([^ \t\n]+\\)\\(?:[ \t]\\|$\\)")
522 "^[ \t]*\\([^ \t\n[]+\\)\\(?:[ \t]\\|$\\)")
523 1)
524 imenu-generic-expression)))
525
526 ;;;###autoload
527 (define-derived-mode conf-colon-mode conf-unix-mode "Conf[Colon]"
528 "Conf Mode starter for Colon files.
529 \"Assignments\" are with `:'.
530 For details see `conf-mode'. Example:
531
532 # Conf mode font-locks this right with \\[conf-colon-mode] (colon)
533
534 <Multi_key> <exclam> <exclam> : \"\\241\" exclamdown
535 <Multi_key> <c> <slash> : \"\\242\" cent"
536 (conf-mode-initialize "#" 'conf-colon-font-lock-keywords)
537 (set (make-local-variable 'conf-assignment-space)
538 conf-colon-assignment-space)
539 (set (make-local-variable 'conf-assignment-column)
540 conf-colon-assignment-column)
541 (set (make-local-variable 'conf-assignment-sign)
542 ?:)
543 (set (make-local-variable 'conf-assignment-regexp)
544 ".+?\\([ \t]*:[ \t]*\\)")
545 (setq imenu-generic-expression
546 `(("Parameters" "^[ \t]*\\(.+?\\)[ \t]*:" 1)
547 ,@(cdr imenu-generic-expression))))
548
549 ;;;###autoload
550 (define-derived-mode conf-ppd-mode conf-colon-mode "Conf[PPD]"
551 "Conf Mode starter for Adobe/CUPS PPD files.
552 Comments start with `*%' and \"assignments\" are with `:'.
553 For details see `conf-mode'. Example:
554
555 *% Conf mode font-locks this right with \\[conf-ppd-mode] (PPD)
556
557 *DefaultTransfer: Null
558 *Transfer Null.Inverse: \"{ 1 exch sub }\""
559 (conf-mode-initialize "*%")
560 ;; no sections, they match within PostScript code
561 (setq imenu-generic-expression (list (car imenu-generic-expression))))
562
563 ;;;###autoload
564 (define-derived-mode conf-xdefaults-mode conf-colon-mode "Conf[Xdefaults]"
565 "Conf Mode starter for Xdefaults files.
566 Comments start with `!' and \"assignments\" are with `:'.
567 For details see `conf-mode'. Example:
568
569 ! Conf mode font-locks this right with \\[conf-xdefaults-mode] (.Xdefaults)
570
571 *background: gray99
572 *foreground: black"
573 (conf-mode-initialize "!"))
574
575 (provide 'conf-mode)
576
577 ;; arch-tag: 0a3805b2-0371-4d3a-8498-8897116b2356
578 ;;; conf-mode.el ends here