Merge branch 'master' of git+ssh://ponder.ncipher.com/~mwooding/etc/profile
[profile] / dot-emacs.el
CommitLineData
502f4699 1;;; -*- mode: emacs-lisp; coding: utf-8 -*-
f617db13 2;;;
f617db13
MW
3;;; Functions and macros for .emacs
4;;;
5;;; (c) 2004 Mark Wooding
6;;;
7
8;;;----- Licensing notice ---------------------------------------------------
9;;;
10;;; This program 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 2 of the License, or
13;;; (at your option) any later version.
852cd5fb 14;;;
f617db13
MW
15;;; This program 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.
852cd5fb 19;;;
f617db13
MW
20;;; You should have received a copy of the GNU General Public License
21;;; along with this program; if not, write to the Free Software Foundation,
22;;; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
c7a8da49
MW
24;;;----- Check command-line -------------------------------------------------
25
26(defvar mdw-fast-startup nil
27 "Whether .emacs should optimize for rapid startup.
28This may be at the expense of cool features.")
29(let ((probe nil) (next command-line-args))
c7a8da49
MW
30 (while next
31 (cond ((string= (car next) "--mdw-fast-startup")
32 (setq mdw-fast-startup t)
33 (if probe
34 (rplacd probe (cdr next))
35 (setq command-line-args (cdr next))))
36 (t
37 (setq probe next)))
38 (setq next (cdr next))))
39
f617db13
MW
40;;;----- Some general utilities ---------------------------------------------
41
417dcddd
MW
42(eval-when-compile
43 (unless (fboundp 'make-regexp)
44 (load "make-regexp"))
45 (require 'cl))
c7a8da49
MW
46
47(defmacro mdw-regexps (&rest list)
48 "Turn a LIST of strings into a single regular expression at compile-time."
417dcddd 49 `',(make-regexp list))
c7a8da49 50
f617db13
MW
51;; --- Some error trapping ---
52;;
53;; If individual bits of this file go tits-up, we don't particularly want
54;; the whole lot to stop right there and then, because it's bloody annoying.
55
56(defmacro trap (&rest forms)
57 "Execute FORMS without allowing errors to propagate outside."
58 `(condition-case err
59 ,(if (cdr forms) (cons 'progn forms) (car forms))
8df912e4
MW
60 (error (message "Error (trapped): %s in %s"
61 (error-message-string err)
62 ',forms))))
f617db13 63
f141fe0f
MW
64;; --- Configuration reading ---
65
66(defvar mdw-config nil)
67(defun mdw-config (sym)
68 "Read the configuration variable named SYM."
69 (unless mdw-config
daff679f
MW
70 (setq mdw-config
71 (flet ((replace (what with)
72 (goto-char (point-min))
73 (while (re-search-forward what nil t)
74 (replace-match with t))))
75 (with-temp-buffer
76 (insert-file-contents "~/.mdw.conf")
77 (replace "^[ \t]*\\(#.*\\|\\)\n" "")
78 (replace (concat "^[ \t]*"
79 "\\([-a-zA-Z0-9_.]*\\)"
80 "[ \t]*=[ \t]*"
81 "\\(.*[^ \t\n]\\|\\)"
82 "[ \t]**\\(\n\\|$\\)")
83 "(\\1 . \"\\2\")\n")
84 (car (read-from-string
85 (concat "(" (buffer-string) ")")))))))
f141fe0f
MW
86 (cdr (assq sym mdw-config)))
87
cb6e2cd1
MW
88;; --- Is an Emacs library available? ---
89
90(defun library-exists-p (name)
91 "Return non-nil if NAME.el (or NAME.elc) is somewhere on the Emacs load
92path. The non-nil value is the filename we found for the library."
93 (let ((path load-path) elt (foundp nil))
94 (while (and path (not foundp))
95 (setq elt (car path))
96 (setq path (cdr path))
97 (setq foundp (or (let ((file (concat elt "/" name ".elc")))
98 (and (file-exists-p file) file))
99 (let ((file (concat elt "/" name ".el")))
100 (and (file-exists-p file) file)))))
101 foundp))
102
103(defun maybe-autoload (symbol file &optional docstring interactivep type)
104 "Set an autoload if the file actually exists."
105 (and (library-exists-p file)
106 (autoload symbol file docstring interactivep type)))
107
f617db13
MW
108;; --- Splitting windows ---
109
8c2b05d5
MW
110(unless (fboundp 'scroll-bar-columns)
111 (defun scroll-bar-columns (side)
112 (cond ((eq side 'left) 0)
113 (window-system 3)
114 (t 1))))
115(unless (fboundp 'fringe-columns)
116 (defun fringe-columns (side)
117 (cond ((not window-system) 0)
118 ((eq side 'left) 1)
119 (t 2))))
120
121(defun mdw-divvy-window (&optional width)
f617db13 122 "Split a wide window into appropriate widths."
8c2b05d5
MW
123 (interactive "P")
124 (setq width (cond (width (prefix-numeric-value width))
125 ((and window-system
126 (>= emacs-major-version 22))
127 77)
128 (t 78)))
b5d724dd
MW
129 (let* ((win (selected-window))
130 (sb-width (if (not window-system)
131 1
8c2b05d5
MW
132 (let ((tot 0))
133 (dolist (what '(scroll-bar fringe))
134 (dolist (side '(left right))
135 (incf tot
136 (funcall (intern (concat (symbol-name what)
137 "-columns"))
138 side))))
139 tot)))
b5d724dd 140 (c (/ (+ (window-width) sb-width)
8c2b05d5 141 (+ width sb-width))))
f617db13
MW
142 (while (> c 1)
143 (setq c (1- c))
8c2b05d5 144 (split-window-horizontally (+ width sb-width))
f617db13
MW
145 (other-window 1))
146 (select-window win)))
147
148;; --- Functions for sexp diary entries ---
149
150(defun mdw-weekday (l)
151 "Return non-nil if `date' falls on one of the days of the week in L.
152
153L is a list of day numbers (from 0 to 6 for Sunday through to Saturday) or
154symbols `sunday', `monday', etc. (or a mixture). If the date stored in
155`date' falls on a listed day, then the function returns non-nil."
156 (let ((d (calendar-day-of-week date)))
157 (or (memq d l)
158 (memq (nth d '(sunday monday tuesday wednesday
159 thursday friday saturday)) l))))
160
161(defun mdw-todo (&optional when)
162 "Return non-nil today, or on WHEN, whichever is later."
163 (let ((w (calendar-absolute-from-gregorian (calendar-current-date)))
164 (d (calendar-absolute-from-gregorian date)))
165 (if when
166 (setq w (max w (calendar-absolute-from-gregorian
167 (cond
168 ((not european-calendar-style)
169 when)
170 ((> (car when) 100)
171 (list (nth 1 when)
172 (nth 2 when)
173 (nth 0 when)))
174 (t
175 (list (nth 1 when)
176 (nth 0 when)
177 (nth 2 when))))))))
178 (eq w d)))
179
180;;;----- Utility functions --------------------------------------------------
181
b5d724dd
MW
182(or (fboundp 'line-number-at-pos)
183 (defun line-number-at-pos (&optional pos)
184 (let ((opoint (or pos (point))) start)
185 (save-excursion
186 (save-restriction
187 (goto-char (point-min))
188 (widen)
189 (forward-line 0)
190 (setq start (point))
191 (goto-char opoint)
192 (forward-line 0)
193 (1+ (count-lines 1 (point))))))))
459c9fb2 194
f617db13
MW
195;; --- mdw-uniquify-alist ---
196
197(defun mdw-uniquify-alist (&rest alists)
198
199 "Return the concatenation of the ALISTS with duplicate elements removed.
200
201The first association with a given key prevails; others are ignored. The
202input lists are not modified, although they'll probably become garbage."
203
204 (and alists
205 (let ((start-list (cons nil nil)))
206 (mdw-do-uniquify start-list
207 start-list
208 (car alists)
209 (cdr alists)))))
210
211;; --- mdw-do-uniquify ---
212;;
213;; The DONE argument is a list whose first element is `nil'. It contains the
214;; uniquified alist built so far. The leading `nil' is stripped off at the
215;; end of the operation; it's only there so that DONE always references a
216;; cons cell. END refers to the final cons cell in the DONE list; it is
217;; modified in place each time to avoid the overheads of `append'ing all the
218;; time. The L argument is the alist we're currently processing; the
219;; remaining alists are given in REST.
220
221(defun mdw-do-uniquify (done end l rest)
222 "A helper function for mdw-uniquify-alist."
223
224 ;; --- There are several different cases to deal with here ---
225
226 (cond
227
228 ;; --- Current list isn't empty ---
229 ;;
230 ;; Add the first item to the DONE list if there's not an item with the
231 ;; same KEY already there.
232
233 (l (or (assoc (car (car l)) done)
234 (progn
235 (setcdr end (cons (car l) nil))
236 (setq end (cdr end))))
237 (mdw-do-uniquify done end (cdr l) rest))
238
239 ;; --- The list we were working on is empty ---
240 ;;
241 ;; Shunt the next list into the current list position and go round again.
242
243 (rest (mdw-do-uniquify done end (car rest) (cdr rest)))
244
245 ;; --- Everything's done ---
246 ;;
247 ;; Remove the leading `nil' from the DONE list and return it. Finished!
248
249 (t (cdr done))))
250
251;; --- Insert a date ---
252
253(defun date ()
254 "Insert the current date in a pleasing way."
255 (interactive)
256 (insert (save-excursion
257 (let ((buffer (get-buffer-create "*tmp*")))
258 (unwind-protect (progn (set-buffer buffer)
259 (erase-buffer)
260 (shell-command "date +%Y-%m-%d" t)
261 (goto-char (mark))
262 (delete-backward-char 1)
263 (buffer-string))
264 (kill-buffer buffer))))))
265
266;; --- UUencoding ---
267
268(defun uuencode (file &optional name)
269 "UUencodes a file, maybe calling it NAME, into the current buffer."
270 (interactive "fInput file name: ")
271
272 ;; --- If NAME isn't specified, then guess from the filename ---
273
274 (if (not name)
275 (setq name
276 (substring file
277 (or (string-match "[^/]*$" file) 0))))
278
279 (print (format "uuencode `%s' `%s'" file name))
280
281 ;; --- Now actually do the thing ---
282
283 (call-process "uuencode" file t nil name))
284
285(defvar np-file "~/.np"
286 "*Where the `now-playing' file is.")
287
288(defun np (&optional arg)
289 "Grabs a `now-playing' string."
290 (interactive)
291 (save-excursion
292 (or arg (progn
852cd5fb 293 (goto-char (point-max))
f617db13 294 (insert "\nNP: ")
daff679f 295 (insert-file-contents np-file)))))
f617db13 296
c7a8da49
MW
297(defun mdw-check-autorevert ()
298 "Sets global-auto-revert-ignore-buffer appropriately for this buffer,
299taking into consideration whether it's been found using tramp, which seems to
300get itself into a twist."
46e69f55
MW
301 (cond ((not (boundp 'global-auto-revert-ignore-buffer))
302 nil)
303 ((and (buffer-file-name)
304 (fboundp 'tramp-tramp-file-p)
c7a8da49
MW
305 (tramp-tramp-file-p (buffer-file-name)))
306 (unless global-auto-revert-ignore-buffer
307 (setq global-auto-revert-ignore-buffer 'tramp)))
308 ((eq global-auto-revert-ignore-buffer 'tramp)
309 (setq global-auto-revert-ignore-buffer nil))))
310
311(defadvice find-file (after mdw-autorevert activate)
312 (mdw-check-autorevert))
313(defadvice write-file (after mdw-autorevert activate)
4d9f2d65 314 (mdw-check-autorevert))
f617db13
MW
315
316(defun mdwmail-mode ()
317 "Major mode for editing news and mail messages from external programs
318Not much right now. Just support for doing MailCrypt stuff."
319 (interactive)
320 (kill-all-local-variables)
321 (use-local-map text-mode-map)
322 (setq local-abbrev-table text-mode-abbrev-table)
323 (setq major-mode 'mdwmail-mode)
324 (setq mode-name "[mdw] mail")
bc091e80 325 (set-buffer-file-coding-system 'utf-8)
f617db13
MW
326 (make-local-variable 'paragraph-separate)
327 (make-local-variable 'paragraph-start)
328 (setq paragraph-start (concat "[ \t]*[-_][-_][-_]+$\\|^-- \\|-----\\|"
329 paragraph-start))
330 (setq paragraph-separate (concat "[ \t]*[-_][-_][-_]+$\\|^-- \\|-----\\|"
331 paragraph-separate))
332 (run-hooks 'text-mode-hook 'mdwmail-mode-hook 'mail-setup-hook))
333
334;; --- How to encrypt in mdwmail ---
335
336(defun mdwmail-mc-encrypt (&optional recip scm start end from sign)
337 (or start
338 (setq start (save-excursion
339 (goto-char (point-min))
340 (or (search-forward "\n\n" nil t) (point-min)))))
341 (or end
342 (setq end (point-max)))
343 (mc-encrypt-generic recip scm start end from sign))
344
345;; --- How to sign in mdwmail ---
346
347(defun mdwmail-mc-sign (key scm start end uclr)
348 (or start
349 (setq start (save-excursion
350 (goto-char (point-min))
351 (or (search-forward "\n\n" nil t) (point-min)))))
352 (or end
353 (setq end (point-max)))
354 (mc-sign-generic key scm start end uclr))
355
356;; --- Some signature mangling ---
357
358(defun mdwmail-mangle-signature ()
359 (save-excursion
360 (goto-char (point-min))
361 (perform-replace "\n-- \n" "\n-- " nil nil nil)))
362(add-hook 'mail-setup-hook 'mdwmail-mangle-signature)
363
5195cbc3
MW
364;;;----- Dired hacking ------------------------------------------------------
365
366(defadvice dired-maybe-insert-subdir
367 (around mdw-marked-insertion first activate)
368 "The DIRNAME may be a list of directory names to insert. Interactively, if
369files are marked, then insert all of them. With a numeric prefix argument,
370select that many entries near point; with a non-numeric prefix argument,
371prompt for listing options."
372 (interactive
373 (list (dired-get-marked-files nil
374 (and (integerp current-prefix-arg)
375 current-prefix-arg)
376 #'file-directory-p)
377 (and current-prefix-arg
378 (not (integerp current-prefix-arg))
379 (read-string "Switches for listing: "
380 (or dired-subdir-switches
381 dired-actual-switches)))))
382 (let ((dirs (ad-get-arg 0)))
383 (dolist (dir (if (listp dirs) dirs (list dirs)))
384 (ad-set-arg 0 dir)
385 ad-do-it)))
386
a203fba8
MW
387;;;----- URL viewing --------------------------------------------------------
388
389(defun mdw-w3m-browse-url (url &optional new-session-p)
390 "Invoke w3m on the URL in its current window, or at least a different one.
391If NEW-SESSION-P, start a new session."
392 (interactive "sURL: \nP")
393 (save-excursion
63fb20c1
MW
394 (let ((window (selected-window)))
395 (unwind-protect
396 (progn
397 (select-window (or (and (not new-session-p)
398 (get-buffer-window "*w3m*"))
399 (progn
400 (if (one-window-p t) (split-window))
401 (get-lru-window))))
402 (w3m-browse-url url new-session-p))
403 (select-window window)))))
a203fba8
MW
404
405(defvar mdw-good-url-browsers
406 '((w3m . mdw-w3m-browse-url)
407 browse-url-w3
408 browse-url-mozilla)
409 "List of good browsers for mdw-good-url-browsers; each item is a browser
410function name, or a cons (CHECK . FUNC). A symbol FOO stands for (FOO
411. FOO).")
412
413(defun mdw-good-url-browser ()
414 "Return a good URL browser. Trundle the list of such things, finding the
415first item for which CHECK is fboundp, and returning the correponding FUNC."
416 (let ((bs mdw-good-url-browsers) b check func answer)
417 (while (and bs (not answer))
418 (setq b (car bs)
419 bs (cdr bs))
420 (if (consp b)
421 (setq check (car b) func (cdr b))
422 (setq check b func b))
423 (if (fboundp check)
424 (setq answer func)))
425 answer))
426
f617db13
MW
427;;;----- Paragraph filling --------------------------------------------------
428
429;; --- Useful variables ---
430
431(defvar mdw-fill-prefix nil
432 "*Used by `mdw-line-prefix' and `mdw-fill-paragraph'. If there's
433no fill prefix currently set (by the `fill-prefix' variable) and there's
434a match from one of the regexps here, it gets used to set the fill-prefix
435for the current operation.
436
437The variable is a list of items of the form `REGEXP . PREFIX'; if the
438REGEXP matches, the PREFIX is used to set the fill prefix. It in turn is
439a list of things:
440
441 STRING -- insert a literal string
442 (match . N) -- insert the thing matched by bracketed subexpression N
443 (pad . N) -- a string of whitespace the same width as subexpression N
444 (expr . FORM) -- the result of evaluating FORM")
445
446(make-variable-buffer-local 'mdw-fill-prefix)
447
448(defvar mdw-hanging-indents
10fa2414
MW
449 (concat "\\(\\("
450 "\\([*o]\\|-[-#]?\\|[0-9]+\\.\\|\\[[0-9]+\\]\\|([a-zA-Z])\\)"
451 "[ \t]+"
452 "\\)?\\)")
f617db13
MW
453 "*Standard regular expression matching things which might be part of a
454hanging indent. This is mainly useful in `auto-fill-mode'.")
455
456;; --- Setting things up ---
457
458(fset 'mdw-do-auto-fill (symbol-function 'do-auto-fill))
459
460;; --- Utility functions ---
461
462(defun mdw-tabify (s)
463 "Tabify the string S. This is a horrid hack."
464 (save-excursion
465 (save-match-data
466 (let (start end)
467 (beginning-of-line)
468 (setq start (point-marker))
469 (insert s "\n")
470 (setq end (point-marker))
471 (tabify start end)
472 (setq s (buffer-substring start (1- end)))
473 (delete-region start end)
474 (set-marker start nil)
475 (set-marker end nil)
476 s))))
477
478(defun mdw-examine-fill-prefixes (l)
479 "Given a list of dynamic fill prefixes, pick one which matches context and
480return the static fill prefix to use. Point must be at the start of a line,
481and match data must be saved."
482 (cond ((not l) nil)
483 ((looking-at (car (car l)))
484 (mdw-tabify (apply (function concat)
485 (mapcar (function mdw-do-prefix-match)
486 (cdr (car l))))))
487 (t (mdw-examine-fill-prefixes (cdr l)))))
488
489(defun mdw-maybe-car (p)
490 "If P is a pair, return (car P), otherwise just return P."
491 (if (consp p) (car p) p))
492
493(defun mdw-padding (s)
494 "Return a string the same width as S but made entirely from whitespace."
495 (let* ((l (length s)) (i 0) (n (make-string l ? )))
496 (while (< i l)
497 (if (= 9 (aref s i))
498 (aset n i 9))
499 (setq i (1+ i)))
500 n))
501
502(defun mdw-do-prefix-match (m)
503 "Expand a dynamic prefix match element. See `mdw-fill-prefix' for
504details."
505 (cond ((not (consp m)) (format "%s" m))
506 ((eq (car m) 'match) (match-string (mdw-maybe-car (cdr m))))
507 ((eq (car m) 'pad) (mdw-padding (match-string
508 (mdw-maybe-car (cdr m)))))
509 ((eq (car m) 'eval) (eval (cdr m)))
510 (t "")))
511
512(defun mdw-choose-dynamic-fill-prefix ()
513 "Work out the dynamic fill prefix based on the variable `mdw-fill-prefix'."
514 (cond ((and fill-prefix (not (string= fill-prefix ""))) fill-prefix)
515 ((not mdw-fill-prefix) fill-prefix)
516 (t (save-excursion
517 (beginning-of-line)
518 (save-match-data
519 (mdw-examine-fill-prefixes mdw-fill-prefix))))))
520
521(defun do-auto-fill ()
522 "Handle auto-filling, working out a dynamic fill prefix in the case where
523there isn't a sensible static one."
524 (let ((fill-prefix (mdw-choose-dynamic-fill-prefix)))
525 (mdw-do-auto-fill)))
526
527(defun mdw-fill-paragraph ()
528 "Fill paragraph, getting a dynamic fill prefix."
529 (interactive)
530 (let ((fill-prefix (mdw-choose-dynamic-fill-prefix)))
531 (fill-paragraph nil)))
532
533(defun mdw-standard-fill-prefix (rx &optional mat)
534 "Set the dynamic fill prefix, handling standard hanging indents and stuff.
535This is just a short-cut for setting the thing by hand, and by design it
536doesn't cope with anything approximating a complicated case."
537 (setq mdw-fill-prefix
538 `((,(concat rx mdw-hanging-indents)
539 (match . 1)
540 (pad . ,(or mat 2))))))
541
542;;;----- Other common declarations ------------------------------------------
543
f617db13
MW
544;; --- Common mode settings ---
545
546(defvar mdw-auto-indent t
547 "Whether to indent automatically after a newline.")
548
549(defun mdw-misc-mode-config ()
550 (and mdw-auto-indent
551 (cond ((eq major-mode 'lisp-mode)
552 (local-set-key "\C-m" 'mdw-indent-newline-and-indent))
30c8a8fb
MW
553 ((or (eq major-mode 'slime-repl-mode)
554 (eq major-mode 'asm-mode))
555 nil)
f617db13
MW
556 (t
557 (local-set-key "\C-m" 'newline-and-indent))))
558 (local-set-key [C-return] 'newline)
8cb7626b
MW
559 (make-variable-buffer-local 'page-delimiter)
560 (setq page-delimiter "\f\\|^.*-\\{6\\}.*$")
f617db13
MW
561 (setq comment-column 40)
562 (auto-fill-mode 1)
563 (setq fill-column 77)
473ff3b0 564 (setq show-trailing-whitespace t)
f617db13
MW
565 (mdw-set-font))
566
567;; --- Set up all sorts of faces ---
568
569(defvar mdw-set-font nil)
570
571(defvar mdw-punct-face 'mdw-punct-face "Face to use for punctuation")
572(make-face 'mdw-punct-face)
573(defvar mdw-number-face 'mdw-number-face "Face to use for numbers")
574(make-face 'mdw-number-face)
575
2ae647c4
MW
576;; --- Backup file handling ---
577
578(defvar mdw-backup-disable-regexps nil
579 "*List of regular expressions: if a file name matches any of these then the
580file is not backed up.")
581
582(defun mdw-backup-enable-predicate (name)
583 "[mdw]'s default backup predicate: allows a backup if the
584standard predicate would allow it, and it doesn't match any of
585the regular expressions in `mdw-backup-disable-regexps'."
586 (and (normal-backup-enable-predicate name)
587 (let ((answer t) (list mdw-backup-disable-regexps))
588 (save-match-data
589 (while list
590 (if (string-match (car list) name)
591 (setq answer nil))
592 (setq list (cdr list)))
593 answer))))
594(setq backup-enable-predicate 'mdw-backup-enable-predicate)
595
f617db13
MW
596;;;----- General fontification ----------------------------------------------
597
473ff3b0
MW
598(defun mdw-set-fonts (frame faces)
599 (while faces
600 (let ((face (caar faces)))
601 (or (facep face) (make-face face))
602 (set-face-attribute face frame
603 :family 'unspecified
604 :width 'unspecified
605 :height 'unspecified
606 :weight 'unspecified
607 :slant 'unspecified
608 :foreground 'unspecified
609 :background 'unspecified
610 :underline 'unspecified
611 :overline 'unspecified
612 :strike-through 'unspecified
613 :box 'unspecified
614 :inverse-video 'unspecified
615 :stipple 'unspecified
616 ;:font 'unspecified
617 :inherit 'unspecified)
618 (apply 'set-face-attribute face frame (cdar faces))
619 (setq faces (cdr faces)))))
f617db13
MW
620
621(defun mdw-do-set-font (&optional frame)
622 (interactive)
623 (mdw-set-fonts (and (boundp 'frame) frame) `(
624 (default :foreground "white" :background "black"
625 ,@(cond ((eq window-system 'w32)
626 '(:family "courier new" :height 85))
627 ((eq window-system 'x)
9cbbe332 628 '(:family "misc-fixed" :height 130 :width semi-condensed))))
b5d724dd
MW
629 (fixed-pitch)
630 (minibuffer-prompt)
668e254c
MW
631 (mode-line :foreground "blue" :background "yellow"
632 :box (:line-width 1 :style released-button))
414d8484 633 (mode-line-inactive :foreground "yellow" :background "blue"
668e254c 634 :box (:line-width 1 :style released-button))
f617db13 635 (scroll-bar :foreground "black" :background "lightgrey")
414d8484 636 (fringe :foreground "yellow" :background "black")
f617db13
MW
637 (show-paren-match-face :background "darkgreen")
638 (show-paren-mismatch-face :background "red")
639 (font-lock-warning-face :background "red" :weight bold)
640 (highlight :background "DarkSeaGreen4")
641 (holiday-face :background "red")
642 (calendar-today-face :foreground "yellow" :weight bold)
643 (comint-highlight-prompt :weight bold)
644 (comint-highlight-input)
645 (font-lock-builtin-face :weight bold)
646 (font-lock-type-face :weight bold)
be048719 647 (region :background ,(if window-system "grey30" "blue"))
f617db13
MW
648 (isearch :background "palevioletred2")
649 (mdw-punct-face :foreground ,(if window-system "burlywood2" "yellow"))
650 (mdw-number-face :foreground "yellow")
651 (font-lock-function-name-face :weight bold)
652 (font-lock-variable-name-face :slant italic)
52696e46
MW
653 (font-lock-comment-delimiter-face
654 :foreground ,(if window-system "SeaGreen1" "green")
655 :slant italic)
f617db13
MW
656 (font-lock-comment-face
657 :foreground ,(if window-system "SeaGreen1" "green")
658 :slant italic)
659 (font-lock-string-face :foreground ,(if window-system "SkyBlue1" "cyan"))
660 (font-lock-keyword-face :weight bold)
661 (font-lock-constant-face :weight bold)
662 (font-lock-reference-face :weight bold)
8c521a22
MW
663 (woman-bold :weight bold)
664 (woman-italic :slant italic)
8b6bc589
MW
665 (diff-index :weight bold)
666 (diff-file-header :weight bold)
667 (diff-hunk-header :foreground "SkyBlue1")
668 (diff-function :foreground "SkyBlue1" :weight bold)
669 (diff-header :background "grey10")
670 (diff-added :foreground "green")
671 (diff-removed :foreground "red")
672 (diff-context)
f617db13
MW
673 (whizzy-slice-face :background "grey10")
674 (whizzy-error-face :background "darkred")
473ff3b0 675 (trailing-whitespace :background "red")
f617db13
MW
676)))
677
678(defun mdw-set-font ()
679 (trap
680 (turn-on-font-lock)
681 (if (not mdw-set-font)
682 (progn
683 (setq mdw-set-font t)
684 (mdw-do-set-font nil)))))
685
686;;;----- C programming configuration ----------------------------------------
687
688;; --- Linux kernel hacking ---
689
690(defvar linux-c-mode-hook)
691
692(defun linux-c-mode ()
693 (interactive)
694 (c-mode)
695 (setq major-mode 'linux-c-mode)
696 (setq mode-name "Linux C")
697 (run-hooks 'linux-c-mode-hook))
698
699;; --- Make C indentation nice ---
700
701(defun mdw-c-style ()
702 (c-add-style "[mdw] C and C++ style"
703 '((c-basic-offset . 2)
f617db13
MW
704 (comment-column . 40)
705 (c-class-key . "class")
706 (c-offsets-alist (substatement-open . 0)
707 (label . 0)
708 (case-label . +)
709 (access-label . -)
87c7cecb 710 (inclass . +)
f617db13
MW
711 (inline-open . ++)
712 (statement-cont . 0)
713 (statement-case-intro . +)))
714 t))
715
716(defun mdw-fontify-c-and-c++ ()
717
718 ;; --- Fiddle with some syntax codes ---
719
f617db13
MW
720 (modify-syntax-entry ?* ". 23")
721 (modify-syntax-entry ?/ ". 124b")
722 (modify-syntax-entry ?\n "> b")
723
724 ;; --- Other stuff ---
725
726 (mdw-c-style)
727 (setq c-hanging-comment-ender-p nil)
728 (setq c-backslash-column 72)
729 (setq c-label-minimum-indentation 0)
f617db13
MW
730 (setq mdw-fill-prefix
731 `((,(concat "\\([ \t]*/?\\)"
732 "\\([\*/][ \t]*\\)"
733 "\\([A-Za-z]+:[ \t]*\\)?"
734 mdw-hanging-indents)
735 (pad . 1) (match . 2) (pad . 3) (pad . 4))))
736
737 ;; --- Now define things to be fontified ---
738
02109a0d 739 (make-local-variable 'font-lock-keywords)
f617db13 740 (let ((c-keywords
8d6d55b9
MW
741 (mdw-regexps "and" ;C++
742 "and_eq" ;C++
743 "asm" ;K&R, GCC
744 "auto" ;K&R, C89
745 "bitand" ;C++
746 "bitor" ;C++
747 "bool" ;C++, C9X macro
748 "break" ;K&R, C89
749 "case" ;K&R, C89
750 "catch" ;C++
751 "char" ;K&R, C89
752 "class" ;C++
753 "complex" ;C9X macro, C++ template type
754 "compl" ;C++
755 "const" ;C89
756 "const_cast" ;C++
757 "continue" ;K&R, C89
758 "defined" ;C89 preprocessor
759 "default" ;K&R, C89
760 "delete" ;C++
761 "do" ;K&R, C89
762 "double" ;K&R, C89
763 "dynamic_cast" ;C++
764 "else" ;K&R, C89
765 ;; "entry" ;K&R -- never used
766 "enum" ;C89
767 "explicit" ;C++
768 "export" ;C++
769 "extern" ;K&R, C89
770 "false" ;C++, C9X macro
771 "float" ;K&R, C89
772 "for" ;K&R, C89
773 ;; "fortran" ;K&R
774 "friend" ;C++
775 "goto" ;K&R, C89
776 "if" ;K&R, C89
777 "imaginary" ;C9X macro
778 "inline" ;C++, C9X, GCC
779 "int" ;K&R, C89
780 "long" ;K&R, C89
781 "mutable" ;C++
782 "namespace" ;C++
783 "new" ;C++
784 "operator" ;C++
785 "or" ;C++
786 "or_eq" ;C++
787 "private" ;C++
788 "protected" ;C++
789 "public" ;C++
790 "register" ;K&R, C89
791 "reinterpret_cast" ;C++
792 "restrict" ;C9X
793 "return" ;K&R, C89
794 "short" ;K&R, C89
795 "signed" ;C89
796 "sizeof" ;K&R, C89
797 "static" ;K&R, C89
798 "static_cast" ;C++
799 "struct" ;K&R, C89
800 "switch" ;K&R, C89
801 "template" ;C++
802 "this" ;C++
803 "throw" ;C++
804 "true" ;C++, C9X macro
805 "try" ;C++
806 "this" ;C++
807 "typedef" ;C89
808 "typeid" ;C++
809 "typeof" ;GCC
810 "typename" ;C++
811 "union" ;K&R, C89
812 "unsigned" ;K&R, C89
813 "using" ;C++
814 "virtual" ;C++
815 "void" ;C89
816 "volatile" ;C89
817 "wchar_t" ;C++, C89 library type
818 "while" ;K&R, C89
819 "xor" ;C++
820 "xor_eq" ;C++
821 "_Bool" ;C9X
822 "_Complex" ;C9X
823 "_Imaginary" ;C9X
824 "_Pragma" ;C9X preprocessor
825 "__alignof__" ;GCC
826 "__asm__" ;GCC
827 "__attribute__" ;GCC
828 "__complex__" ;GCC
829 "__const__" ;GCC
830 "__extension__" ;GCC
831 "__imag__" ;GCC
832 "__inline__" ;GCC
833 "__label__" ;GCC
834 "__real__" ;GCC
835 "__signed__" ;GCC
836 "__typeof__" ;GCC
837 "__volatile__" ;GCC
838 ))
f617db13 839 (preprocessor-keywords
8d6d55b9
MW
840 (mdw-regexps "assert" "define" "elif" "else" "endif" "error"
841 "ident" "if" "ifdef" "ifndef" "import" "include"
842 "line" "pragma" "unassert" "undef" "warning"))
f617db13 843 (objc-keywords
8d6d55b9
MW
844 (mdw-regexps "class" "defs" "encode" "end" "implementation"
845 "interface" "private" "protected" "protocol" "public"
846 "selector")))
f617db13
MW
847
848 (setq font-lock-keywords
849 (list
f617db13
MW
850
851 ;; --- Fontify include files as strings ---
852
853 (list (concat "^[ \t]*\\#[ \t]*"
854 "\\(include\\|import\\)"
855 "[ \t]*\\(<[^>]+\\(>\\|\\)\\)")
856 '(2 font-lock-string-face))
857
858 ;; --- Preprocessor directives are `references'? ---
859
860 (list (concat "^\\([ \t]*#[ \t]*\\(\\("
861 preprocessor-keywords
862 "\\)\\>\\|[0-9]+\\|$\\)\\)")
863 '(1 font-lock-keyword-face))
864
865 ;; --- Handle the keywords defined above ---
866
867 (list (concat "@\\<\\(" objc-keywords "\\)\\>")
868 '(0 font-lock-keyword-face))
869
870 (list (concat "\\<\\(" c-keywords "\\)\\>")
871 '(0 font-lock-keyword-face))
872
873 ;; --- Handle numbers too ---
874 ;;
875 ;; This looks strange, I know. It corresponds to the
876 ;; preprocessor's idea of what a number looks like, rather than
877 ;; anything sensible.
878
879 (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
880 "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
881 '(0 mdw-number-face))
882
883 ;; --- And anything else is punctuation ---
884
885 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
886 '(0 mdw-punct-face))))))
887
888;;;----- AP calc mode -------------------------------------------------------
889
890(defun apcalc-mode ()
891 (interactive)
892 (c-mode)
893 (setq major-mode 'apcalc-mode)
894 (setq mode-name "AP Calc")
895 (run-hooks 'apcalc-mode-hook))
896
897(defun mdw-fontify-apcalc ()
898
899 ;; --- Fiddle with some syntax codes ---
900
f617db13
MW
901 (modify-syntax-entry ?* ". 23")
902 (modify-syntax-entry ?/ ". 14")
903
904 ;; --- Other stuff ---
905
906 (mdw-c-style)
907 (setq c-hanging-comment-ender-p nil)
908 (setq c-backslash-column 72)
909 (setq comment-start "/* ")
910 (setq comment-end " */")
911 (setq mdw-fill-prefix
912 `((,(concat "\\([ \t]*/?\\)"
913 "\\([\*/][ \t]*\\)"
914 "\\([A-Za-z]+:[ \t]*\\)?"
915 mdw-hanging-indents)
916 (pad . 1) (match . 2) (pad . 3) (pad . 4))))
917
918 ;; --- Now define things to be fontified ---
919
02109a0d 920 (make-local-variable 'font-lock-keywords)
f617db13 921 (let ((c-keywords
8d6d55b9
MW
922 (mdw-regexps "break" "case" "cd" "continue" "define" "default"
923 "do" "else" "exit" "for" "global" "goto" "help" "if"
924 "local" "mat" "obj" "print" "quit" "read" "return"
925 "show" "static" "switch" "while" "write")))
f617db13
MW
926
927 (setq font-lock-keywords
928 (list
f617db13
MW
929
930 ;; --- Handle the keywords defined above ---
931
932 (list (concat "\\<\\(" c-keywords "\\)\\>")
933 '(0 font-lock-keyword-face))
934
935 ;; --- Handle numbers too ---
936 ;;
937 ;; This looks strange, I know. It corresponds to the
938 ;; preprocessor's idea of what a number looks like, rather than
939 ;; anything sensible.
940
941 (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
942 "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
943 '(0 mdw-number-face))
944
945 ;; --- And anything else is punctuation ---
946
947 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
948 '(0 mdw-punct-face))))))
949
950;;;----- Java programming configuration -------------------------------------
951
952;; --- Make indentation nice ---
953
954(defun mdw-java-style ()
955 (c-add-style "[mdw] Java style"
956 '((c-basic-offset . 2)
f617db13
MW
957 (c-offsets-alist (substatement-open . 0)
958 (label . +)
959 (case-label . +)
960 (access-label . 0)
961 (inclass . +)
962 (statement-case-intro . +)))
963 t))
964
965;; --- Declare Java fontification style ---
966
967(defun mdw-fontify-java ()
968
969 ;; --- Other stuff ---
970
971 (mdw-java-style)
f617db13
MW
972 (setq c-hanging-comment-ender-p nil)
973 (setq c-backslash-column 72)
974 (setq comment-start "/* ")
975 (setq comment-end " */")
976 (setq mdw-fill-prefix
977 `((,(concat "\\([ \t]*/?\\)"
978 "\\([\*/][ \t]*\\)"
979 "\\([A-Za-z]+:[ \t]*\\)?"
980 mdw-hanging-indents)
981 (pad . 1) (match . 2) (pad . 3) (pad . 4))))
982
983 ;; --- Now define things to be fontified ---
984
02109a0d 985 (make-local-variable 'font-lock-keywords)
f617db13 986 (let ((java-keywords
8d6d55b9
MW
987 (mdw-regexps "abstract" "boolean" "break" "byte" "case" "catch"
988 "char" "class" "const" "continue" "default" "do"
989 "double" "else" "extends" "final" "finally" "float"
990 "for" "goto" "if" "implements" "import" "instanceof"
991 "int" "interface" "long" "native" "new" "package"
992 "private" "protected" "public" "return" "short"
993 "static" "super" "switch" "synchronized" "this"
994 "throw" "throws" "transient" "try" "void" "volatile"
995 "while"
996
997 "false" "null" "true")))
f617db13
MW
998
999 (setq font-lock-keywords
1000 (list
f617db13
MW
1001
1002 ;; --- Handle the keywords defined above ---
1003
1004 (list (concat "\\<\\(" java-keywords "\\)\\>")
1005 '(0 font-lock-keyword-face))
1006
1007 ;; --- Handle numbers too ---
1008 ;;
1009 ;; The following isn't quite right, but it's close enough.
1010
1011 (list (concat "\\<\\("
1012 "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1013 "[0-9]+\\(\\.[0-9]*\\|\\)"
1014 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
1015 "[lLfFdD]?")
1016 '(0 mdw-number-face))
1017
1018 ;; --- And anything else is punctuation ---
1019
1020 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1021 '(0 mdw-punct-face))))))
1022
e808c1e5
MW
1023;;;----- C# programming configuration ---------------------------------------
1024
1025;; --- Make indentation nice ---
1026
1027(defun mdw-csharp-style ()
1028 (c-add-style "[mdw] C# style"
1029 '((c-basic-offset . 2)
e808c1e5
MW
1030 (c-offsets-alist (substatement-open . 0)
1031 (label . 0)
1032 (case-label . +)
1033 (access-label . 0)
1034 (inclass . +)
1035 (statement-case-intro . +)))
1036 t))
1037
1038;; --- Declare C# fontification style ---
1039
1040(defun mdw-fontify-csharp ()
1041
1042 ;; --- Other stuff ---
1043
1044 (mdw-csharp-style)
e808c1e5
MW
1045 (setq c-hanging-comment-ender-p nil)
1046 (setq c-backslash-column 72)
1047 (setq comment-start "/* ")
1048 (setq comment-end " */")
1049 (setq mdw-fill-prefix
1050 `((,(concat "\\([ \t]*/?\\)"
1051 "\\([\*/][ \t]*\\)"
1052 "\\([A-Za-z]+:[ \t]*\\)?"
1053 mdw-hanging-indents)
1054 (pad . 1) (match . 2) (pad . 3) (pad . 4))))
1055
1056 ;; --- Now define things to be fontified ---
1057
1058 (make-local-variable 'font-lock-keywords)
1059 (let ((csharp-keywords
8d6d55b9
MW
1060 (mdw-regexps "abstract" "as" "base" "bool" "break"
1061 "byte" "case" "catch" "char" "checked"
1062 "class" "const" "continue" "decimal" "default"
1063 "delegate" "do" "double" "else" "enum"
1064 "event" "explicit" "extern" "false" "finally"
1065 "fixed" "float" "for" "foreach" "goto"
1066 "if" "implicit" "in" "int" "interface"
1067 "internal" "is" "lock" "long" "namespace"
1068 "new" "null" "object" "operator" "out"
1069 "override" "params" "private" "protected" "public"
1070 "readonly" "ref" "return" "sbyte" "sealed"
1071 "short" "sizeof" "stackalloc" "static" "string"
1072 "struct" "switch" "this" "throw" "true"
1073 "try" "typeof" "uint" "ulong" "unchecked"
1074 "unsafe" "ushort" "using" "virtual" "void"
1075 "volatile" "while" "yield")))
e808c1e5
MW
1076
1077 (setq font-lock-keywords
1078 (list
e808c1e5
MW
1079
1080 ;; --- Handle the keywords defined above ---
1081
1082 (list (concat "\\<\\(" csharp-keywords "\\)\\>")
1083 '(0 font-lock-keyword-face))
1084
1085 ;; --- Handle numbers too ---
1086 ;;
1087 ;; The following isn't quite right, but it's close enough.
1088
1089 (list (concat "\\<\\("
1090 "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1091 "[0-9]+\\(\\.[0-9]*\\|\\)"
1092 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
1093 "[lLfFdD]?")
1094 '(0 mdw-number-face))
1095
1096 ;; --- And anything else is punctuation ---
1097
1098 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1099 '(0 mdw-punct-face))))))
1100
1101(defun csharp-mode ()
1102 (interactive)
1103 (java-mode)
1104 (setq major-mode 'csharp-mode)
1105 (setq mode-name "C#")
1106 (mdw-fontify-csharp)
1107 (run-hooks 'csharp-mode-hook))
1108
f617db13
MW
1109;;;----- Awk programming configuration --------------------------------------
1110
1111;; --- Make Awk indentation nice ---
1112
1113(defun mdw-awk-style ()
1114 (c-add-style "[mdw] Awk style"
1115 '((c-basic-offset . 2)
f617db13
MW
1116 (c-offsets-alist (substatement-open . 0)
1117 (statement-cont . 0)
1118 (statement-case-intro . +)))
1119 t))
1120
1121;; --- Declare Awk fontification style ---
1122
1123(defun mdw-fontify-awk ()
1124
1125 ;; --- Miscellaneous fiddling ---
1126
f617db13
MW
1127 (mdw-awk-style)
1128 (setq c-backslash-column 72)
1129 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
1130
1131 ;; --- Now define things to be fontified ---
1132
02109a0d 1133 (make-local-variable 'font-lock-keywords)
f617db13 1134 (let ((c-keywords
8d6d55b9
MW
1135 (mdw-regexps "BEGIN" "END" "ARGC" "ARGIND" "ARGV" "CONVFMT"
1136 "ENVIRON" "ERRNO" "FIELDWIDTHS" "FILENAME" "FNR"
1137 "FS" "IGNORECASE" "NF" "NR" "OFMT" "OFS" "ORS" "RS"
1138 "RSTART" "RLENGTH" "RT" "SUBSEP"
1139 "atan2" "break" "close" "continue" "cos" "delete"
1140 "do" "else" "exit" "exp" "fflush" "file" "for" "func"
1141 "function" "gensub" "getline" "gsub" "if" "in"
1142 "index" "int" "length" "log" "match" "next" "rand"
1143 "return" "print" "printf" "sin" "split" "sprintf"
1144 "sqrt" "srand" "strftime" "sub" "substr" "system"
1145 "systime" "tolower" "toupper" "while")))
f617db13
MW
1146
1147 (setq font-lock-keywords
1148 (list
f617db13
MW
1149
1150 ;; --- Handle the keywords defined above ---
1151
1152 (list (concat "\\<\\(" c-keywords "\\)\\>")
1153 '(0 font-lock-keyword-face))
1154
1155 ;; --- Handle numbers too ---
1156 ;;
1157 ;; The following isn't quite right, but it's close enough.
1158
1159 (list (concat "\\<\\("
1160 "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1161 "[0-9]+\\(\\.[0-9]*\\|\\)"
1162 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
1163 "[uUlL]*")
1164 '(0 mdw-number-face))
1165
1166 ;; --- And anything else is punctuation ---
1167
1168 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1169 '(0 mdw-punct-face))))))
1170
1171;;;----- Perl programming style ---------------------------------------------
1172
1173;; --- Perl indentation style ---
1174
f617db13
MW
1175(setq cperl-indent-level 2)
1176(setq cperl-continued-statement-offset 2)
1177(setq cperl-continued-brace-offset 0)
1178(setq cperl-brace-offset -2)
1179(setq cperl-brace-imaginary-offset 0)
1180(setq cperl-label-offset 0)
1181
1182;; --- Define perl fontification style ---
1183
1184(defun mdw-fontify-perl ()
1185
1186 ;; --- Miscellaneous fiddling ---
1187
f617db13
MW
1188 (modify-syntax-entry ?$ "\\")
1189 (modify-syntax-entry ?$ "\\" font-lock-syntax-table)
1190 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
1191
1192 ;; --- Now define fontification things ---
1193
02109a0d 1194 (make-local-variable 'font-lock-keywords)
f617db13 1195 (let ((perl-keywords
8d6d55b9
MW
1196 (mdw-regexps "and" "cmp" "continue" "do" "else" "elsif" "eq"
1197 "for" "foreach" "ge" "gt" "goto" "if"
1198 "last" "le" "lt" "local" "my" "ne" "next" "or"
1199 "package" "redo" "require" "return" "sub"
1200 "undef" "unless" "until" "use" "while")))
f617db13
MW
1201
1202 (setq font-lock-keywords
1203 (list
f617db13
MW
1204
1205 ;; --- Set up the keywords defined above ---
1206
1207 (list (concat "\\<\\(" perl-keywords "\\)\\>")
1208 '(0 font-lock-keyword-face))
1209
1210 ;; --- At least numbers are simpler than C ---
1211
1212 (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
1213 "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
1214 "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
1215 '(0 mdw-number-face))
1216
1217 ;; --- And anything else is punctuation ---
1218
1219 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1220 '(0 mdw-punct-face))))))
1221
1222(defun perl-number-tests (&optional arg)
1223 "Assign consecutive numbers to lines containing `#t'. With ARG,
1224strip numbers instead."
1225 (interactive "P")
1226 (save-excursion
1227 (goto-char (point-min))
1228 (let ((i 0) (fmt (if arg "" " %4d")))
1229 (while (search-forward "#t" nil t)
1230 (delete-region (point) (line-end-position))
1231 (setq i (1+ i))
1232 (insert (format fmt i)))
1233 (goto-char (point-min))
1234 (if (re-search-forward "\\(tests\\s-*=>\\s-*\\)\\w*" nil t)
1235 (replace-match (format "\\1%d" i))))))
1236
1237;;;----- Python programming style -------------------------------------------
1238
1239;; --- Define Python fontification style ---
1240
f617db13
MW
1241(defun mdw-fontify-python ()
1242
1243 ;; --- Miscellaneous fiddling ---
1244
f617db13
MW
1245 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
1246
1247 ;; --- Now define fontification things ---
1248
02109a0d 1249 (make-local-variable 'font-lock-keywords)
f617db13 1250 (let ((python-keywords
8d6d55b9
MW
1251 (mdw-regexps "and" "as" "assert" "break" "class" "continue" "def"
1252 "del" "elif" "else" "except" "exec" "finally" "for"
1253 "from" "global" "if" "import" "in" "is" "lambda"
1254 "not" "or" "pass" "print" "raise" "return" "try"
e61fa1ae 1255 "while" "with" "yield")))
f617db13
MW
1256 (setq font-lock-keywords
1257 (list
f617db13
MW
1258
1259 ;; --- Set up the keywords defined above ---
1260
1261 (list (concat "\\<\\(" python-keywords "\\)\\>")
1262 '(0 font-lock-keyword-face))
1263
1264 ;; --- At least numbers are simpler than C ---
1265
1266 (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
1267 "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
1268 "\\([eE]\\([-+]\\|\\)[0-9_]+\\|[lL]\\|\\)")
1269 '(0 mdw-number-face))
1270
1271 ;; --- And anything else is punctuation ---
1272
1273 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1274 '(0 mdw-punct-face))))))
1275
1276;;;----- ARM assembler programming configuration ----------------------------
1277
1278;; --- There doesn't appear to be an Emacs mode for this yet ---
1279;;
1280;; Better do something about that, I suppose.
1281
1282(defvar arm-assembler-mode-map nil)
1283(defvar arm-assembler-abbrev-table nil)
1284(defvar arm-assembler-mode-syntax-table (make-syntax-table))
1285
1286(or arm-assembler-mode-map
1287 (progn
1288 (setq arm-assembler-mode-map (make-sparse-keymap))
1289 (define-key arm-assembler-mode-map "\C-m" 'arm-assembler-newline)
1290 (define-key arm-assembler-mode-map [C-return] 'newline)
1291 (define-key arm-assembler-mode-map "\t" 'tab-to-tab-stop)))
1292
1293(defun arm-assembler-mode ()
1294 "Major mode for ARM assembler programs"
1295 (interactive)
1296
1297 ;; --- Do standard major mode things ---
1298
1299 (kill-all-local-variables)
1300 (use-local-map arm-assembler-mode-map)
1301 (setq local-abbrev-table arm-assembler-abbrev-table)
1302 (setq major-mode 'arm-assembler-mode)
1303 (setq mode-name "ARM assembler")
1304
1305 ;; --- Set up syntax table ---
1306
1307 (set-syntax-table arm-assembler-mode-syntax-table)
1308 (modify-syntax-entry ?; ; Nasty hack
1309 "<" arm-assembler-mode-syntax-table)
1310 (modify-syntax-entry ?\n ">" arm-assembler-mode-syntax-table)
1311 (modify-syntax-entry ?_ "_" arm-assembler-mode-syntax-table)
1312
1313 (make-local-variable 'comment-start)
1314 (setq comment-start ";")
1315 (make-local-variable 'comment-end)
1316 (setq comment-end "")
1317 (make-local-variable 'comment-column)
1318 (setq comment-column 48)
1319 (make-local-variable 'comment-start-skip)
1320 (setq comment-start-skip ";+[ \t]*")
1321
1322 ;; --- Play with indentation ---
1323
1324 (make-local-variable 'indent-line-function)
1325 (setq indent-line-function 'indent-relative-maybe)
1326
1327 ;; --- Set fill prefix ---
1328
1329 (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)")
1330
1331 ;; --- Fiddle with fontification ---
1332
02109a0d 1333 (make-local-variable 'font-lock-keywords)
f617db13
MW
1334 (setq font-lock-keywords
1335 (list
f617db13
MW
1336
1337 ;; --- Handle numbers too ---
1338 ;;
1339 ;; The following isn't quite right, but it's close enough.
1340
1341 (list (concat "\\("
1342 "&[0-9a-fA-F]+\\|"
1343 "\\<[0-9]+\\(\\.[0-9]*\\|_[0-9a-zA-Z]+\\|\\)"
1344 "\\)")
1345 '(0 mdw-number-face))
1346
1347 ;; --- Do something about operators ---
1348
1349 (list "^[^ \t]*[ \t]+\\(GET\\|LNK\\)[ \t]+\\([^;\n]*\\)"
1350 '(1 font-lock-keyword-face)
1351 '(2 font-lock-string-face))
1352 (list ":[a-zA-Z]+:"
1353 '(0 font-lock-keyword-face))
1354
1355 ;; --- Do menemonics and directives ---
1356
1357 (list "^[^ \t]*[ \t]+\\([a-zA-Z]+\\)"
1358 '(1 font-lock-keyword-face))
1359
1360 ;; --- And anything else is punctuation ---
1361
1362 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1363 '(0 mdw-punct-face))))
1364
1365 (run-hooks 'arm-assembler-mode-hook))
1366
30c8a8fb
MW
1367;;;----- Assembler mode -----------------------------------------------------
1368
1369(defun mdw-fontify-asm ()
1370 (modify-syntax-entry ?' "\"")
1371 (modify-syntax-entry ?. "w")
1372 (setf fill-prefix nil)
1373 (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)"))
1374
f617db13
MW
1375;;;----- TCL configuration --------------------------------------------------
1376
1377(defun mdw-fontify-tcl ()
1378 (mapcar #'(lambda (ch) (modify-syntax-entry ch ".")) '(?$))
1379 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
02109a0d 1380 (make-local-variable 'font-lock-keywords)
f617db13
MW
1381 (setq font-lock-keywords
1382 (list
f617db13
MW
1383 (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
1384 "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
1385 "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
1386 '(0 mdw-number-face))
1387 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1388 '(0 mdw-punct-face)))))
1389
1390;;;----- REXX configuration -------------------------------------------------
1391
1392(defun mdw-rexx-electric-* ()
1393 (interactive)
1394 (insert ?*)
1395 (rexx-indent-line))
1396
1397(defun mdw-rexx-indent-newline-indent ()
1398 (interactive)
1399 (rexx-indent-line)
1400 (if abbrev-mode (expand-abbrev))
1401 (newline-and-indent))
1402
1403(defun mdw-fontify-rexx ()
1404
1405 ;; --- Various bits of fiddling ---
1406
1407 (setq mdw-auto-indent nil)
1408 (local-set-key [?\C-m] 'mdw-rexx-indent-newline-indent)
1409 (local-set-key [?*] 'mdw-rexx-electric-*)
1410 (mapcar #'(lambda (ch) (modify-syntax-entry ch "w"))
e443a4cd 1411 '(?! ?? ?# ?@ ?$))
f617db13
MW
1412 (mdw-standard-fill-prefix "\\([ \t]*/?\*[ \t]*\\)")
1413
1414 ;; --- Set up keywords and things for fontification ---
1415
1416 (make-local-variable 'font-lock-keywords-case-fold-search)
1417 (setq font-lock-keywords-case-fold-search t)
1418
1419 (setq rexx-indent 2)
1420 (setq rexx-end-indent rexx-indent)
f617db13
MW
1421 (setq rexx-cont-indent rexx-indent)
1422
02109a0d 1423 (make-local-variable 'font-lock-keywords)
f617db13 1424 (let ((rexx-keywords
8d6d55b9
MW
1425 (mdw-regexps "address" "arg" "by" "call" "digits" "do" "drop"
1426 "else" "end" "engineering" "exit" "expose" "for"
1427 "forever" "form" "fuzz" "if" "interpret" "iterate"
1428 "leave" "linein" "name" "nop" "numeric" "off" "on"
1429 "options" "otherwise" "parse" "procedure" "pull"
1430 "push" "queue" "return" "say" "select" "signal"
1431 "scientific" "source" "then" "trace" "to" "until"
1432 "upper" "value" "var" "version" "when" "while"
1433 "with"
1434
1435 "abbrev" "abs" "bitand" "bitor" "bitxor" "b2x"
1436 "center" "center" "charin" "charout" "chars"
1437 "compare" "condition" "copies" "c2d" "c2x"
1438 "datatype" "date" "delstr" "delword" "d2c" "d2x"
1439 "errortext" "format" "fuzz" "insert" "lastpos"
1440 "left" "length" "lineout" "lines" "max" "min"
1441 "overlay" "pos" "queued" "random" "reverse" "right"
1442 "sign" "sourceline" "space" "stream" "strip"
1443 "substr" "subword" "symbol" "time" "translate"
1444 "trunc" "value" "verify" "word" "wordindex"
1445 "wordlength" "wordpos" "words" "xrange" "x2b" "x2c"
1446 "x2d")))
f617db13
MW
1447
1448 (setq font-lock-keywords
1449 (list
f617db13
MW
1450
1451 ;; --- Set up the keywords defined above ---
1452
1453 (list (concat "\\<\\(" rexx-keywords "\\)\\>")
1454 '(0 font-lock-keyword-face))
1455
1456 ;; --- Fontify all symbols the same way ---
1457
1458 (list (concat "\\<\\([0-9.][A-Za-z0-9.!?_#@$]*[Ee][+-]?[0-9]+\\|"
1459 "[A-Za-z0-9.!?_#@$]+\\)")
1460 '(0 font-lock-variable-name-face))
1461
1462 ;; --- And everything else is punctuation ---
1463
1464 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1465 '(0 mdw-punct-face))))))
1466
1467;;;----- Standard ML programming style --------------------------------------
1468
1469(defun mdw-fontify-sml ()
1470
1471 ;; --- Make underscore an honorary letter ---
1472
f617db13
MW
1473 (modify-syntax-entry ?' "w")
1474
1475 ;; --- Set fill prefix ---
1476
1477 (mdw-standard-fill-prefix "\\([ \t]*(\*[ \t]*\\)")
1478
1479 ;; --- Now define fontification things ---
1480
02109a0d 1481 (make-local-variable 'font-lock-keywords)
f617db13 1482 (let ((sml-keywords
8d6d55b9
MW
1483 (mdw-regexps "abstype" "and" "andalso" "as"
1484 "case"
1485 "datatype" "do"
1486 "else" "end" "eqtype" "exception"
1487 "fn" "fun" "functor"
1488 "handle"
1489 "if" "in" "include" "infix" "infixr"
1490 "let" "local"
1491 "nonfix"
1492 "of" "op" "open" "orelse"
1493 "raise" "rec"
1494 "sharing" "sig" "signature" "struct" "structure"
1495 "then" "type"
1496 "val"
1497 "where" "while" "with" "withtype")))
f617db13
MW
1498
1499 (setq font-lock-keywords
1500 (list
f617db13
MW
1501
1502 ;; --- Set up the keywords defined above ---
1503
1504 (list (concat "\\<\\(" sml-keywords "\\)\\>")
1505 '(0 font-lock-keyword-face))
1506
1507 ;; --- At least numbers are simpler than C ---
1508
1509 (list (concat "\\<\\(\\~\\|\\)"
1510 "\\(0\\(\\([wW]\\|\\)[xX][0-9a-fA-F]+\\|"
852cd5fb
MW
1511 "[wW][0-9]+\\)\\|"
1512 "\\([0-9]+\\(\\.[0-9]+\\|\\)"
1513 "\\([eE]\\(\\~\\|\\)"
1514 "[0-9]+\\|\\)\\)\\)")
f617db13
MW
1515 '(0 mdw-number-face))
1516
1517 ;; --- And anything else is punctuation ---
1518
1519 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1520 '(0 mdw-punct-face))))))
1521
1522;;;----- Haskell configuration ----------------------------------------------
1523
1524(defun mdw-fontify-haskell ()
1525
1526 ;; --- Fiddle with syntax table to get comments right ---
1527
f617db13
MW
1528 (modify-syntax-entry ?' "\"")
1529 (modify-syntax-entry ?- ". 123")
1530 (modify-syntax-entry ?{ ". 1b")
1531 (modify-syntax-entry ?} ". 4b")
1532 (modify-syntax-entry ?\n ">")
1533
1534 ;; --- Set fill prefix ---
1535
1536 (mdw-standard-fill-prefix "\\([ \t]*{?--?[ \t]*\\)")
1537
1538 ;; --- Fiddle with fontification ---
1539
02109a0d 1540 (make-local-variable 'font-lock-keywords)
f617db13 1541 (let ((haskell-keywords
8d6d55b9
MW
1542 (mdw-regexps "as" "case" "ccall" "class" "data" "default"
1543 "deriving" "do" "else" "foreign" "hiding" "if"
1544 "import" "in" "infix" "infixl" "infixr" "instance"
1545 "let" "module" "newtype" "of" "qualified" "safe"
1546 "stdcall" "then" "type" "unsafe" "where")))
f617db13
MW
1547
1548 (setq font-lock-keywords
1549 (list
f617db13
MW
1550 (list "--.*$"
1551 '(0 font-lock-comment-face))
1552 (list (concat "\\<\\(" haskell-keywords "\\)\\>")
1553 '(0 font-lock-keyword-face))
1554 (list (concat "\\<0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1555 "\\<[0-9][0-9_]*\\(\\.[0-9]*\\|\\)"
1556 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)")
1557 '(0 mdw-number-face))
1558 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1559 '(0 mdw-punct-face))))))
1560
1561;;;----- Texinfo configuration ----------------------------------------------
1562
1563(defun mdw-fontify-texinfo ()
1564
1565 ;; --- Set fill prefix ---
1566
1567 (mdw-standard-fill-prefix "\\([ \t]*@c[ \t]+\\)")
1568
1569 ;; --- Real fontification things ---
1570
02109a0d 1571 (make-local-variable 'font-lock-keywords)
f617db13
MW
1572 (setq font-lock-keywords
1573 (list
f617db13
MW
1574
1575 ;; --- Environment names are keywords ---
1576
1577 (list "@\\(end\\) *\\([a-zA-Z]*\\)?"
1578 '(2 font-lock-keyword-face))
1579
1580 ;; --- Unmark escaped magic characters ---
1581
1582 (list "\\(@\\)\\([@{}]\\)"
1583 '(1 font-lock-keyword-face)
1584 '(2 font-lock-variable-name-face))
1585
1586 ;; --- Make sure we get comments properly ---
1587
1588 (list "@c\\(\\|omment\\)\\( .*\\)?$"
1589 '(0 font-lock-comment-face))
1590
1591 ;; --- Command names are keywords ---
1592
1593 (list "@\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
1594 '(0 font-lock-keyword-face))
1595
1596 ;; --- Fontify TeX special characters as punctuation ---
1597
1598 (list "[{}]+"
1599 '(0 mdw-punct-face)))))
1600
1601;;;----- TeX and LaTeX configuration ----------------------------------------
1602
1603(defun mdw-fontify-tex ()
1604 (setq ispell-parser 'tex)
1605
1606 ;; --- Don't make maths into a string ---
1607
1608 (modify-syntax-entry ?$ ".")
1609 (modify-syntax-entry ?$ "." font-lock-syntax-table)
1610 (local-set-key [?$] 'self-insert-command)
1611
1612 ;; --- Set fill prefix ---
1613
1614 (mdw-standard-fill-prefix "\\([ \t]*%+[ \t]*\\)")
1615
1616 ;; --- Real fontification things ---
1617
02109a0d 1618 (make-local-variable 'font-lock-keywords)
f617db13
MW
1619 (setq font-lock-keywords
1620 (list
f617db13
MW
1621
1622 ;; --- Environment names are keywords ---
1623
1624 (list (concat "\\\\\\(begin\\|end\\|newenvironment\\)"
1625 "{\\([^}\n]*\\)}")
1626 '(2 font-lock-keyword-face))
1627
1628 ;; --- Suspended environment names are keywords too ---
1629
1630 (list (concat "\\\\\\(suspend\\|resume\\)\\(\\[[^]]*\\]\\)?"
1631 "{\\([^}\n]*\\)}")
1632 '(3 font-lock-keyword-face))
1633
1634 ;; --- Command names are keywords ---
1635
1636 (list "\\\\\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
1637 '(0 font-lock-keyword-face))
1638
1639 ;; --- Handle @/.../ for italics ---
1640
1641 ;; (list "\\(@/\\)\\([^/]*\\)\\(/\\)"
852cd5fb
MW
1642 ;; '(1 font-lock-keyword-face)
1643 ;; '(3 font-lock-keyword-face))
f617db13
MW
1644
1645 ;; --- Handle @*...* for boldness ---
1646
1647 ;; (list "\\(@\\*\\)\\([^*]*\\)\\(\\*\\)"
852cd5fb
MW
1648 ;; '(1 font-lock-keyword-face)
1649 ;; '(3 font-lock-keyword-face))
f617db13
MW
1650
1651 ;; --- Handle @`...' for literal syntax things ---
1652
1653 ;; (list "\\(@`\\)\\([^']*\\)\\('\\)"
852cd5fb
MW
1654 ;; '(1 font-lock-keyword-face)
1655 ;; '(3 font-lock-keyword-face))
f617db13
MW
1656
1657 ;; --- Handle @<...> for nonterminals ---
1658
1659 ;; (list "\\(@<\\)\\([^>]*\\)\\(>\\)"
852cd5fb
MW
1660 ;; '(1 font-lock-keyword-face)
1661 ;; '(3 font-lock-keyword-face))
f617db13
MW
1662
1663 ;; --- Handle other @-commands ---
1664
1665 ;; (list "@\\([^a-zA-Z]\\|[a-zA-Z]*\\)"
852cd5fb 1666 ;; '(0 font-lock-keyword-face))
f617db13
MW
1667
1668 ;; --- Make sure we get comments properly ---
1669
1670 (list "%.*"
1671 '(0 font-lock-comment-face))
1672
1673 ;; --- Fontify TeX special characters as punctuation ---
1674
1675 (list "[$^_{}#&]"
1676 '(0 mdw-punct-face)))))
1677
f25cf300
MW
1678;;;----- SGML hacking -------------------------------------------------------
1679
1680(defun mdw-sgml-mode ()
1681 (interactive)
1682 (sgml-mode)
1683 (mdw-standard-fill-prefix "")
1684 (make-variable-buffer-local 'sgml-delimiters)
1685 (setq sgml-delimiters
1686 '("AND" "&" "COM" "--" "CRO" "&#" "DSC" "]" "DSO" "[" "DTGC" "]"
1687 "DTGO" "[" "ERO" "&" "ETAGO" ":e" "GRPC" ")" "GRPO" "(" "LIT" "\""
1688 "LITA" "'" "MDC" ">" "MDO" "<!" "MINUS" "-" "MSC" "]]" "NESTC" "{"
1689 "NET" "}" "OPT" "?" "OR" "|" "PERO" "%" "PIC" ">" "PIO" "<?"
1690 "PLUS" "+" "REFC" "." "REP" "*" "RNI" "#" "SEQ" "," "STAGO" ":"
1691 "TAGC" "." "VI" "=" "MS-START" "<![" "MS-END" "]]>"
1692 "XML-ECOM" "-->" "XML-PIC" "?>" "XML-SCOM" "<!--" "XML-TAGCE" "/>"
1693 "NULL" ""))
1694 (setq major-mode 'mdw-sgml-mode)
1695 (setq mode-name "[mdw] SGML")
1696 (run-hooks 'mdw-sgml-mode-hook))
1697
f617db13
MW
1698;;;----- Shell scripts ------------------------------------------------------
1699
1700(defun mdw-setup-sh-script-mode ()
1701
1702 ;; --- Fetch the shell interpreter's name ---
1703
1704 (let ((shell-name sh-shell-file))
1705
1706 ;; --- Try reading the hash-bang line ---
1707
1708 (save-excursion
1709 (goto-char (point-min))
1710 (if (looking-at "#![ \t]*\\([^ \t\n]*\\)")
1711 (setq shell-name (match-string 1))))
1712
1713 ;; --- Now try to set the shell ---
1714 ;;
1715 ;; Don't let `sh-set-shell' bugger up my script.
1716
1717 (let ((executable-set-magic #'(lambda (s &rest r) s)))
1718 (sh-set-shell shell-name)))
1719
1720 ;; --- Now enable my keys and the fontification ---
1721
1722 (mdw-misc-mode-config)
1723
1724 ;; --- Set the indentation level correctly ---
1725
1726 (setq sh-indentation 2)
1727 (setq sh-basic-offset 2))
1728
1729;;;----- Messages-file mode -------------------------------------------------
1730
1731(defun message-mode-guts ()
1732 (setq messages-mode-syntax-table (make-syntax-table))
1733 (set-syntax-table messages-mode-syntax-table)
f617db13
MW
1734 (modify-syntax-entry ?0 "w" messages-mode-syntax-table)
1735 (modify-syntax-entry ?1 "w" messages-mode-syntax-table)
1736 (modify-syntax-entry ?2 "w" messages-mode-syntax-table)
1737 (modify-syntax-entry ?3 "w" messages-mode-syntax-table)
1738 (modify-syntax-entry ?4 "w" messages-mode-syntax-table)
1739 (modify-syntax-entry ?5 "w" messages-mode-syntax-table)
1740 (modify-syntax-entry ?6 "w" messages-mode-syntax-table)
1741 (modify-syntax-entry ?7 "w" messages-mode-syntax-table)
1742 (modify-syntax-entry ?8 "w" messages-mode-syntax-table)
1743 (modify-syntax-entry ?9 "w" messages-mode-syntax-table)
1744 (make-local-variable 'comment-start)
1745 (make-local-variable 'comment-end)
1746 (make-local-variable 'indent-line-function)
1747 (setq indent-line-function 'indent-relative)
1748 (mdw-standard-fill-prefix "\\([ \t]*\\(;\\|/?\\*\\)+[ \t]*\\)")
1749 (make-local-variable 'font-lock-defaults)
1750 (make-local-variable 'message-mode-keywords)
1751 (let ((keywords
8d6d55b9
MW
1752 (mdw-regexps "array" "bitmap" "callback" "docs[ \t]+enum"
1753 "export" "enum" "fixed-octetstring" "flags"
1754 "harmless" "map" "nested" "optional"
1755 "optional-tagged" "package" "primitive"
1756 "primitive-nullfree" "relaxed[ \t]+enum"
1757 "set" "table" "tagged-optional" "union"
1758 "variadic" "vector" "version" "version-tag")))
f617db13
MW
1759 (setq message-mode-keywords
1760 (list
1761 (list (concat "\\<\\(" keywords "\\)\\>:")
1762 '(0 font-lock-keyword-face))
1763 '("\\([-a-zA-Z0-9]+:\\)" (0 font-lock-warning-face))
1764 '("\\(\\<[a-z][-_a-zA-Z0-9]*\\)"
1765 (0 font-lock-variable-name-face))
1766 '("\\<\\([0-9]+\\)\\>" (0 mdw-number-face))
1767 '("\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1768 (0 mdw-punct-face)))))
1769 (setq font-lock-defaults
1770 '(message-mode-keywords nil nil nil nil))
1771 (run-hooks 'messages-file-hook))
1772
1773(defun messages-mode ()
1774 (interactive)
1775 (fundamental-mode)
1776 (setq major-mode 'messages-mode)
1777 (setq mode-name "Messages")
1778 (message-mode-guts)
1779 (modify-syntax-entry ?# "<" messages-mode-syntax-table)
1780 (modify-syntax-entry ?\n ">" messages-mode-syntax-table)
1781 (setq comment-start "# ")
1782 (setq comment-end "")
1783 (turn-on-font-lock-if-enabled)
1784 (run-hooks 'messages-mode-hook))
1785
1786(defun cpp-messages-mode ()
1787 (interactive)
1788 (fundamental-mode)
1789 (setq major-mode 'cpp-messages-mode)
1790 (setq mode-name "CPP Messages")
1791 (message-mode-guts)
1792 (modify-syntax-entry ?* ". 23" messages-mode-syntax-table)
1793 (modify-syntax-entry ?/ ". 14" messages-mode-syntax-table)
1794 (setq comment-start "/* ")
1795 (setq comment-end " */")
1796 (let ((preprocessor-keywords
8d6d55b9
MW
1797 (mdw-regexps "assert" "define" "elif" "else" "endif" "error"
1798 "ident" "if" "ifdef" "ifndef" "import" "include"
1799 "line" "pragma" "unassert" "undef" "warning")))
f617db13
MW
1800 (setq message-mode-keywords
1801 (append (list (list (concat "^[ \t]*\\#[ \t]*"
1802 "\\(include\\|import\\)"
1803 "[ \t]*\\(<[^>]+\\(>\\|\\)\\)")
1804 '(2 font-lock-string-face))
1805 (list (concat "^\\([ \t]*#[ \t]*\\(\\("
1806 preprocessor-keywords
852cd5fb 1807 "\\)\\>\\|[0-9]+\\|$\\)\\)")
f617db13
MW
1808 '(1 font-lock-keyword-face)))
1809 message-mode-keywords)))
f617db13 1810 (turn-on-font-lock-if-enabled)
297d60aa 1811 (run-hooks 'cpp-messages-mode-hook))
f617db13 1812
297d60aa
MW
1813(add-hook 'messages-mode-hook 'mdw-misc-mode-config t)
1814(add-hook 'cpp-messages-mode-hook 'mdw-misc-mode-config t)
f617db13
MW
1815; (add-hook 'messages-file-hook 'mdw-fontify-messages t)
1816
1817;;;----- Messages-file mode -------------------------------------------------
1818
1819(defvar mallow-driver-substitution-face 'mallow-driver-substitution-face
1820 "Face to use for subsittution directives.")
1821(make-face 'mallow-driver-substitution-face)
1822(defvar mallow-driver-text-face 'mallow-driver-text-face
1823 "Face to use for body text.")
1824(make-face 'mallow-driver-text-face)
1825
1826(defun mallow-driver-mode ()
1827 (interactive)
1828 (fundamental-mode)
1829 (setq major-mode 'mallow-driver-mode)
1830 (setq mode-name "Mallow driver")
1831 (setq mallow-driver-mode-syntax-table (make-syntax-table))
1832 (set-syntax-table mallow-driver-mode-syntax-table)
1833 (make-local-variable 'comment-start)
1834 (make-local-variable 'comment-end)
1835 (make-local-variable 'indent-line-function)
1836 (setq indent-line-function 'indent-relative)
1837 (mdw-standard-fill-prefix "\\([ \t]*\\(;\\|/?\\*\\)+[ \t]*\\)")
1838 (make-local-variable 'font-lock-defaults)
1839 (make-local-variable 'mallow-driver-mode-keywords)
1840 (let ((keywords
8d6d55b9
MW
1841 (mdw-regexps "each" "divert" "file" "if"
1842 "perl" "set" "string" "type" "write")))
f617db13
MW
1843 (setq mallow-driver-mode-keywords
1844 (list
1845 (list (concat "^%\\s *\\(}\\|\\(" keywords "\\)\\>\\).*$")
1846 '(0 font-lock-keyword-face))
1847 (list "^%\\s *\\(#.*\\|\\)$"
1848 '(0 font-lock-comment-face))
1849 (list "^%"
1850 '(0 font-lock-keyword-face))
1851 (list "^|?\\(.+\\)$" '(1 mallow-driver-text-face))
1852 (list "\\${[^}]*}"
1853 '(0 mallow-driver-substitution-face t)))))
1854 (setq font-lock-defaults
1855 '(mallow-driver-mode-keywords nil nil nil nil))
1856 (modify-syntax-entry ?\" "_" mallow-driver-mode-syntax-table)
1857 (modify-syntax-entry ?\n ">" mallow-driver-mode-syntax-table)
1858 (setq comment-start "%# ")
1859 (setq comment-end "")
1860 (turn-on-font-lock-if-enabled)
1861 (run-hooks 'mallow-driver-mode-hook))
1862
1863(add-hook 'mallow-driver-hook 'mdw-misc-mode-config t)
1864
1865;;;----- NFast debugs -------------------------------------------------------
1866
1867(defun nfast-debug-mode ()
1868 (interactive)
1869 (fundamental-mode)
1870 (setq major-mode 'nfast-debug-mode)
1871 (setq mode-name "NFast debug")
1872 (setq messages-mode-syntax-table (make-syntax-table))
1873 (set-syntax-table messages-mode-syntax-table)
1874 (make-local-variable 'font-lock-defaults)
1875 (make-local-variable 'nfast-debug-mode-keywords)
1876 (setq truncate-lines t)
1877 (setq nfast-debug-mode-keywords
1878 (list
1879 '("^\\(NFast_\\(Connect\\|Disconnect\\|Submit\\|Wait\\)\\)"
1880 (0 font-lock-keyword-face))
1881 (list (concat "^[ \t]+\\(\\("
1882 "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"
1883 "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"
1884 "[ \t]+\\)*"
1885 "[0-9a-fA-F]+\\)[ \t]*$")
1886 '(0 mdw-number-face))
1887 '("^[ \t]+\.status=[ \t]+\\<\\(OK\\)\\>"
1888 (1 font-lock-keyword-face))
1889 '("^[ \t]+\.status=[ \t]+\\<\\([a-zA-Z][0-9a-zA-Z]*\\)\\>"
1890 (1 font-lock-warning-face))
1891 '("^[ \t]+\.status[ \t]+\\<\\(zero\\)\\>"
1892 (1 nil))
1893 (list (concat "^[ \t]+\\.cmd=[ \t]+"
1894 "\\<\\([a-zA-Z][0-9a-zA-Z]*\\)\\>")
1895 '(1 font-lock-keyword-face))
1896 '("-?\\<\\([0-9]+\\|0x[0-9a-fA-F]+\\)\\>" (0 mdw-number-face))
1897 '("^\\([ \t]+[a-z0-9.]+\\)" (0 font-lock-variable-name-face))
1898 '("\\<\\([a-z][a-z0-9.]+\\)\\>=" (1 font-lock-variable-name-face))
1899 '("\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" (0 mdw-punct-face))))
1900 (setq font-lock-defaults
1901 '(nfast-debug-mode-keywords nil nil nil nil))
1902 (turn-on-font-lock-if-enabled)
1903 (run-hooks 'nfast-debug-mode-hook))
1904
1905;;;----- Other languages ----------------------------------------------------
1906
1907;; --- Smalltalk ---
1908
1909(defun mdw-setup-smalltalk ()
1910 (and mdw-auto-indent
1911 (local-set-key "\C-m" 'smalltalk-newline-and-indent))
1912 (make-variable-buffer-local 'mdw-auto-indent)
1913 (setq mdw-auto-indent nil)
1914 (local-set-key "\C-i" 'smalltalk-reindent))
1915
1916(defun mdw-fontify-smalltalk ()
02109a0d 1917 (make-local-variable 'font-lock-keywords)
f617db13
MW
1918 (setq font-lock-keywords
1919 (list
f617db13
MW
1920 (list "\\<[A-Z][a-zA-Z0-9]*\\>"
1921 '(0 font-lock-keyword-face))
1922 (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
1923 "[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
1924 "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
1925 '(0 mdw-number-face))
1926 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1927 '(0 mdw-punct-face)))))
1928
1929;; --- Lispy languages ---
1930
1931(defun mdw-indent-newline-and-indent ()
1932 (interactive)
1933 (indent-for-tab-command)
1934 (newline-and-indent))
1935
1936(eval-after-load "cl-indent"
1937 '(progn
1938 (mapc #'(lambda (pair)
1939 (put (car pair)
1940 'common-lisp-indent-function
1941 (cdr pair)))
1942 '((destructuring-bind . ((&whole 4 &rest 1) 4 &body))
1943 (multiple-value-bind . ((&whole 4 &rest 1) 4 &body))))))
1944
1945(defun mdw-common-lisp-indent ()
1946 (make-variable-buffer-local 'lisp-indent-function)
1947 (setq lisp-indent-function 'common-lisp-indent-function))
1948
1949(defun mdw-fontify-lispy ()
1950
1951 ;; --- Set fill prefix ---
1952
1953 (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)")
1954
1955 ;; --- Not much fontification needed ---
1956
02109a0d 1957 (make-local-variable 'font-lock-keywords)
f617db13
MW
1958 (setq font-lock-keywords
1959 (list
f617db13
MW
1960 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1961 '(0 mdw-punct-face)))))
1962
1963(defun comint-send-and-indent ()
1964 (interactive)
1965 (comint-send-input)
1966 (and mdw-auto-indent
1967 (indent-for-tab-command)))
1968
ec007bea
MW
1969(defun mdw-setup-m4 ()
1970 (mdw-standard-fill-prefix "\\([ \t]*\\(?:#+\\|\\<dnl\\>\\)[ \t]*\\)"))
1971
f617db13
MW
1972;;;----- Text mode ----------------------------------------------------------
1973
1974(defun mdw-text-mode ()
1975 (setq fill-column 72)
1976 (flyspell-mode t)
1977 (mdw-standard-fill-prefix
c7a8da49 1978 "\\([ \t]*\\([>#|:] ?\\)*[ \t]*\\)" 3)
f617db13
MW
1979 (auto-fill-mode 1))
1980
1981;;;----- Shell mode ---------------------------------------------------------
1982
1983(defun mdw-sh-mode-setup ()
1984 (local-set-key [?\C-a] 'comint-bol)
1985 (add-hook 'comint-output-filter-functions
1986 'comint-watch-for-password-prompt))
1987
1988(defun mdw-term-mode-setup ()
502f4699 1989 (setq term-prompt-regexp "^[^]#$%>»}\n]*[]#$%>»}] *")
f617db13
MW
1990 (make-local-variable 'mouse-yank-at-point)
1991 (make-local-variable 'transient-mark-mode)
1992 (setq mouse-yank-at-point t)
1993 (setq transient-mark-mode nil)
1994 (auto-fill-mode -1)
1995 (setq tab-width 8))
1996
1997;;;----- That's all, folks --------------------------------------------------
1998
1999(provide 'dot-emacs)