chiark / gitweb /
el/dot-emacs.el: Better fontification for Ediff.
[profile] / el / dot-emacs.el
1 ;;; -*- mode: emacs-lisp; coding: utf-8 -*-
2 ;;;
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.
14 ;;;
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.
19 ;;;
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
24 ;;;--------------------------------------------------------------------------
25 ;;; Check command-line.
26
27 (defvar mdw-fast-startup nil
28   "Whether .emacs should optimize for rapid startup.
29 This may be at the expense of cool features.")
30 (let ((probe nil) (next command-line-args))
31   (while next
32     (cond ((string= (car next) "--mdw-fast-startup")
33            (setq mdw-fast-startup t)
34            (if probe
35                (rplacd probe (cdr next))
36              (setq command-line-args (cdr next))))
37           (t
38            (setq probe next)))
39     (setq next (cdr next))))
40
41 ;;;--------------------------------------------------------------------------
42 ;;; Some general utilities.
43
44 (eval-when-compile
45   (unless (fboundp 'make-regexp)
46     (load "make-regexp"))
47   (require 'cl))
48
49 (defmacro mdw-regexps (&rest list)
50   "Turn a LIST of strings into a single regular expression at compile-time."
51   (declare (indent nil)
52            (debug 0))
53   `',(make-regexp list))
54
55 (defun mdw-wrong ()
56   "This is not the key sequence you're looking for."
57   (interactive)
58   (error "wrong button"))
59
60 (defun mdw-emacs-version-p (major &optional minor)
61   "Return non-nil if the running Emacs is at least version MAJOR.MINOR."
62   (or (> emacs-major-version major)
63       (and (= emacs-major-version major)
64            (>= emacs-minor-version (or minor 0)))))
65
66 ;; Some error trapping.
67 ;;
68 ;; If individual bits of this file go tits-up, we don't particularly want
69 ;; the whole lot to stop right there and then, because it's bloody annoying.
70
71 (defmacro trap (&rest forms)
72   "Execute FORMS without allowing errors to propagate outside."
73   (declare (indent 0)
74            (debug t))
75   `(condition-case err
76        ,(if (cdr forms) (cons 'progn forms) (car forms))
77      (error (message "Error (trapped): %s in %s"
78                      (error-message-string err)
79                      ',forms))))
80
81 ;; Configuration reading.
82
83 (defvar mdw-config nil)
84 (defun mdw-config (sym)
85   "Read the configuration variable named SYM."
86   (unless mdw-config
87     (setq mdw-config
88           (flet ((replace (what with)
89                    (goto-char (point-min))
90                    (while (re-search-forward what nil t)
91                      (replace-match with t))))
92             (with-temp-buffer
93               (insert-file-contents "~/.mdw.conf")
94               (replace  "^[ \t]*\\(#.*\\|\\)\n" "")
95               (replace (concat "^[ \t]*"
96                                "\\([-a-zA-Z0-9_.]*\\)"
97                                "[ \t]*=[ \t]*"
98                                "\\(.*[^ \t\n]\\|\\)"
99                                "[ \t]**\\(\n\\|$\\)")
100                        "(\\1 . \"\\2\")\n")
101               (car (read-from-string
102                     (concat "(" (buffer-string) ")")))))))
103   (cdr (assq sym mdw-config)))
104
105 ;; Width configuration.
106
107 (defvar mdw-column-width
108   (string-to-number (or (mdw-config 'emacs-width) "77"))
109   "Width of Emacs columns.")
110 (defvar mdw-text-width mdw-column-width
111   "Expected width of text within columns.")
112 (put 'mdw-text-width 'safe-local-variable 'integerp)
113
114 ;; Local variables hacking.
115
116 (defun run-local-vars-mode-hook ()
117   "Run a hook for the major-mode after local variables have been processed."
118   (run-hooks (intern (concat (symbol-name major-mode)
119                              "-local-variables-hook"))))
120 (add-hook 'hack-local-variables-hook 'run-local-vars-mode-hook)
121
122 ;; Set up the load path convincingly.
123
124 (dolist (dir (append (and (boundp 'debian-emacs-flavor)
125                           (list (concat "/usr/share/"
126                                         (symbol-name debian-emacs-flavor)
127                                         "/site-lisp")))))
128   (dolist (sub (directory-files dir t))
129     (when (and (file-accessible-directory-p sub)
130                (not (member sub load-path)))
131       (setq load-path (nconc load-path (list sub))))))
132
133 ;; Is an Emacs library available?
134
135 (defun library-exists-p (name)
136   "Return non-nil if NAME is an available library.
137 Return non-nil if NAME.el (or NAME.elc) somewhere on the Emacs
138 load path.  The non-nil value is the filename we found for the
139 library."
140   (let ((path load-path) elt (foundp nil))
141     (while (and path (not foundp))
142       (setq elt (car path))
143       (setq path (cdr path))
144       (setq foundp (or (let ((file (concat elt "/" name ".elc")))
145                          (and (file-exists-p file) file))
146                        (let ((file (concat elt "/" name ".el")))
147                          (and (file-exists-p file) file)))))
148     foundp))
149
150 (defun maybe-autoload (symbol file &optional docstring interactivep type)
151   "Set an autoload if the file actually exists."
152   (and (library-exists-p file)
153        (autoload symbol file docstring interactivep type)))
154
155 (defun mdw-kick-menu-bar (&optional frame)
156   "Regenerate FRAME's menu bar so it doesn't have empty menus."
157   (interactive)
158   (unless frame (setq frame (selected-frame)))
159   (let ((old (frame-parameter frame 'menu-bar-lines)))
160     (set-frame-parameter frame 'menu-bar-lines 0)
161     (set-frame-parameter frame 'menu-bar-lines old)))
162
163 ;; Splitting windows.
164
165 (unless (fboundp 'scroll-bar-columns)
166   (defun scroll-bar-columns (side)
167     (cond ((eq side 'left) 0)
168           (window-system 3)
169           (t 1))))
170 (unless (fboundp 'fringe-columns)
171   (defun fringe-columns (side)
172     (cond ((not window-system) 0)
173           ((eq side 'left) 1)
174           (t 2))))
175
176 (defun mdw-horizontal-window-overhead ()
177   "Computes the horizontal window overhead.
178 This is the number of columns used by fringes, scroll bars and other such
179 cruft."
180   (if (not window-system)
181       1
182     (let ((tot 0))
183       (dolist (what '(scroll-bar fringe))
184         (dolist (side '(left right))
185           (incf tot (funcall (intern (concat (symbol-name what) "-columns"))
186                              side))))
187       tot)))
188
189 (defun mdw-split-window-horizontally (&optional width)
190   "Split a window horizontally.
191 Without a numeric argument, split the window approximately in
192 half.  With a numeric argument WIDTH, allocate WIDTH columns to
193 the left-hand window (if positive) or -WIDTH columns to the
194 right-hand window (if negative).  Space for scroll bars and
195 fringes is not taken out of the allowance for WIDTH, unlike
196 \\[split-window-horizontally]."
197   (interactive "P")
198   (split-window-horizontally
199    (cond ((null width) nil)
200          ((>= width 0) (+ width (mdw-horizontal-window-overhead)))
201          ((< width 0) width))))
202
203 (defun mdw-divvy-window (&optional width)
204   "Split a wide window into appropriate widths."
205   (interactive "P")
206   (setq width (cond (width (prefix-numeric-value width))
207                     ((and window-system (mdw-emacs-version-p 22))
208                      mdw-column-width)
209                     (t (1+ mdw-column-width))))
210   (let* ((win (selected-window))
211          (sb-width (mdw-horizontal-window-overhead))
212          (c (/ (+ (window-width) sb-width)
213                (+ width sb-width))))
214     (while (> c 1)
215       (setq c (1- c))
216       (split-window-horizontally (+ width sb-width))
217       (other-window 1))
218     (select-window win)))
219
220 ;; Don't raise windows unless I say so.
221
222 (defvar mdw-inhibit-raise-frame nil
223   "*Whether `raise-frame' should do nothing when the frame is mapped.")
224
225 (defadvice raise-frame
226     (around mdw-inhibit (&optional frame) activate compile)
227   "Don't actually do anything if `mdw-inhibit-raise-frame' is true, and the
228 frame is actually mapped on the screen."
229   (if mdw-inhibit-raise-frame
230       (make-frame-visible frame)
231     ad-do-it))
232
233 (defmacro mdw-advise-to-inhibit-raise-frame (function)
234   "Advise the FUNCTION not to raise frames, even if it wants to."
235   `(defadvice ,function
236        (around mdw-inhibit-raise (&rest hunoz) activate compile)
237      "Don't raise the window unless you have to."
238      (let ((mdw-inhibit-raise-frame t))
239        ad-do-it)))
240
241 (mdw-advise-to-inhibit-raise-frame select-frame-set-input-focus)
242 (mdw-advise-to-inhibit-raise-frame appt-disp-window)
243
244 ;; Bug fix for markdown-mode, which breaks point positioning during
245 ;; `query-replace'.
246 (defadvice markdown-check-change-for-wiki-link
247     (around mdw-save-match activate compile)
248   "Save match data around the `markdown-mode' `after-change-functions' hook."
249   (save-match-data ad-do-it))
250
251 ;; Bug fix for `bbdb-canonicalize-address': on Emacs 24, `run-hook-with-args'
252 ;; always returns nil, with the result that all email addresses are lost.
253 ;; Replace the function entirely.
254 (defadvice bbdb-canonicalize-address
255     (around mdw-bug-fix activate compile)
256   "Don't use `run-hook-with-args', because that doesn't work."
257   (let ((net (ad-get-arg 0)))
258
259     ;; Make sure this is a proper hook list.
260     (if (functionp bbdb-canonicalize-net-hook)
261         (setq bbdb-canonicalize-net-hook (list bbdb-canonicalize-net-hook)))
262
263     ;; Iterate over the hooks until things converge.
264     (let ((donep nil))
265       (while (not donep)
266         (let (next (changep nil)
267               hook (hooks bbdb-canonicalize-net-hook))
268           (while hooks
269             (setq hook (pop hooks))
270             (setq next (funcall hook net))
271             (if (not (equal next net))
272                 (setq changep t
273                       net next)))
274           (setq donep (not changep)))))
275     (setq ad-return-value net)))
276
277 ;; Transient mark mode hacks.
278
279 (defadvice exchange-point-and-mark
280     (around mdw-highlight (&optional arg) activate compile)
281   "Maybe don't actually exchange point and mark.
282 If `transient-mark-mode' is on and the mark is inactive, then
283 just activate it.  A non-trivial prefix argument will force the
284 usual behaviour.  A trivial prefix argument (i.e., just C-u) will
285 activate the mark and temporarily enable `transient-mark-mode' if
286 it's currently off."
287   (cond ((or mark-active
288              (and (not transient-mark-mode) (not arg))
289              (and arg (or (not (consp arg))
290                           (not (= (car arg) 4)))))
291          ad-do-it)
292         (t
293          (or transient-mark-mode (setq transient-mark-mode 'only))
294          (set-mark (mark t)))))
295
296 ;; Functions for sexp diary entries.
297
298 (defun mdw-not-org-mode (form)
299   "As FORM, but not in Org mode agenda."
300   (and (not mdw-diary-for-org-mode-p)
301        (eval form)))
302
303 (defun mdw-weekday (l)
304   "Return non-nil if `date' falls on one of the days of the week in L.
305 L is a list of day numbers (from 0 to 6 for Sunday through to
306 Saturday) or symbols `sunday', `monday', etc. (or a mixture).  If
307 the date stored in `date' falls on a listed day, then the
308 function returns non-nil."
309   (let ((d (calendar-day-of-week date)))
310     (or (memq d l)
311         (memq (nth d '(sunday monday tuesday wednesday
312                               thursday friday saturday)) l))))
313
314 (defun mdw-discordian-date (date)
315   "Return the Discordian calendar date corresponding to DATE.
316
317 The return value is (YOLD . st-tibs-day) or (YOLD SEASON DAYNUM DOW).
318
319 The original is by David Pearson.  I modified it to produce date components
320 as output rather than a string."
321   (let* ((days ["Sweetmorn" "Boomtime" "Pungenday"
322                 "Prickle-Prickle" "Setting Orange"])
323          (months ["Chaos" "Discord" "Confusion"
324                   "Bureaucracy" "Aftermath"])
325          (day-count [0 31 59 90 120 151 181 212 243 273 304 334])
326          (year (- (extract-calendar-year date) 1900))
327          (month (1- (extract-calendar-month date)))
328          (day (1- (extract-calendar-day date)))
329          (julian (+ (aref day-count month) day))
330          (dyear (+ year 3066)))
331     (if (and (= month 1) (= day 28))
332         (cons dyear 'st-tibs-day)
333       (list dyear
334             (aref months (floor (/ julian 73)))
335             (1+ (mod julian 73))
336             (aref days (mod julian 5))))))
337
338 (defun mdw-diary-discordian-date ()
339   "Convert the date in `date' to a string giving the Discordian date."
340   (let* ((ddate (mdw-discordian-date date))
341          (tail (format "in the YOLD %d" (car ddate))))
342     (if (eq (cdr ddate) 'st-tibs-day)
343         (format "St Tib's Day %s" tail)
344       (let ((season (cadr ddate))
345             (daynum (caddr ddate))
346             (dayname (cadddr ddate)))
347       (format "%s, the %d%s day of %s %s"
348               dayname
349               daynum
350               (let ((ldig (mod daynum 10)))
351                 (cond ((= ldig 1) "st")
352                       ((= ldig 2) "nd")
353                       ((= ldig 3) "rd")
354                       (t "th")))
355               season
356               tail)))))
357
358 (defun mdw-todo (&optional when)
359   "Return non-nil today, or on WHEN, whichever is later."
360   (let ((w (calendar-absolute-from-gregorian (calendar-current-date)))
361         (d (calendar-absolute-from-gregorian date)))
362     (if when
363         (setq w (max w (calendar-absolute-from-gregorian
364                         (cond
365                          ((not european-calendar-style)
366                           when)
367                          ((> (car when) 100)
368                           (list (nth 1 when)
369                                 (nth 2 when)
370                                 (nth 0 when)))
371                          (t
372                           (list (nth 1 when)
373                                 (nth 0 when)
374                                 (nth 2 when))))))))
375     (eq w d)))
376
377 (defvar mdw-diary-for-org-mode-p nil)
378
379 (defadvice org-agenda-list (around mdw-preserve-links activate)
380   (let ((mdw-diary-for-org-mode-p t))
381     ad-do-it))
382
383 (defadvice diary-add-to-list (before mdw-trim-leading-space compile activate)
384   "Trim leading space from the diary entry string."
385   (save-match-data
386     (let ((str (ad-get-arg 1))
387           (done nil) old)
388       (while (not done)
389         (setq old str)
390         (setq str (cond ((null str) nil)
391                         ((string-match "\\(^\\|\n\\)[ \t]+" str)
392                          (replace-match "\\1" nil nil str))
393                         ((and mdw-diary-for-org-mode-p
394                               (string-match (concat
395                                              "\\(^\\|\n\\)"
396                                              "\\(" diary-time-regexp
397                                              "\\(-" diary-time-regexp "\\)?"
398                                              "\\)"
399                                              "\\(\t[ \t]*\\| [ \t]+\\)")
400                                             str))
401                          (replace-match "\\1\\2 " nil nil str))
402                         ((and (not mdw-diary-for-org-mode-p)
403                               (string-match "\\[\\[[^][]*]\\[\\([^][]*\\)]]"
404                                             str))
405                          (replace-match "\\1" nil nil str))
406                         (t str)))
407         (if (equal str old) (setq done t)))
408       (ad-set-arg 1 str))))
409
410 (defadvice org-bbdb-anniversaries (after mdw-fixup-list compile activate)
411   "Return a string rather than a list."
412   (with-temp-buffer
413     (let ((anyp nil))
414       (dolist (e (let ((ee ad-return-value))
415                    (if (atom ee) (list ee) ee)))
416         (when e
417           (when anyp (insert ?\n))
418           (insert e)
419           (setq anyp t)))
420       (setq ad-return-value
421             (and anyp (buffer-string))))))
422
423 ;; Fighting with Org-mode's evil key maps.
424
425 (defvar mdw-evil-keymap-keys
426   '(([S-up] . [?\C-c up])
427     ([S-down] . [?\C-c down])
428     ([S-left] . [?\C-c left])
429     ([S-right] . [?\C-c right])
430     (([M-up] [?\e up]) . [C-up])
431     (([M-down] [?\e down]) . [C-down])
432     (([M-left] [?\e left]) . [C-left])
433     (([M-right] [?\e right]) . [C-right]))
434   "Defines evil keybindings to clobber in `mdw-clobber-evil-keymap'.
435 The value is an alist mapping evil keys (as a list, or singleton)
436 to good keys (in the same form).")
437
438 (defun mdw-clobber-evil-keymap (keymap)
439   "Replace evil key bindings in the KEYMAP.
440 Evil key bindings are defined in `mdw-evil-keymap-keys'."
441   (dolist (entry mdw-evil-keymap-keys)
442     (let ((binding nil)
443           (keys (if (listp (car entry))
444                     (car entry)
445                   (list (car entry))))
446           (replacements (if (listp (cdr entry))
447                             (cdr entry)
448                           (list (cdr entry)))))
449       (catch 'found
450         (dolist (key keys)
451           (setq binding (lookup-key keymap key))
452           (when binding
453             (throw 'found nil))))
454       (when binding
455         (dolist (key keys)
456           (define-key keymap key nil))
457         (dolist (key replacements)
458           (define-key keymap key binding))))))
459
460 (eval-after-load "org-latex"
461   '(progn
462      (push '("strayman"
463              "\\documentclass{strayman}
464 \\usepackage[utf8]{inputenc}
465 \\usepackage[palatino, helvetica, courier, maths=cmr]{mdwfonts}
466 \\usepackage[T1]{fontenc}
467 \\usepackage{graphicx, tikz, mdwtab, mdwmath, crypto, longtable}"
468              ("\\section{%s}" . "\\section*{%s}")
469              ("\\subsection{%s}" . "\\subsection*{%s}")
470              ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
471              ("\\paragraph{%s}" . "\\paragraph*{%s}")
472              ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
473            org-export-latex-classes)))
474
475 (setq org-export-docbook-xslt-proc-command "xsltproc --output %o %s %i"
476       org-export-docbook-xsl-fo-proc-command "fop %i.safe %o"
477       org-export-docbook-xslt-stylesheet
478       "/usr/share/xml/docbook/stylesheet/docbook-xsl/fo/docbook.xsl")
479
480 ;; Some hacks to do with window placement.
481
482 (defun mdw-clobber-other-windows-showing-buffer (buffer-or-name)
483   "Arrange that no windows on other frames are showing BUFFER-OR-NAME."
484   (interactive "bBuffer: ")
485   (let ((home-frame (selected-frame))
486         (buffer (get-buffer buffer-or-name))
487         (safe-buffer (get-buffer "*scratch*")))
488     (mapc (lambda (frame)
489             (or (eq frame home-frame)
490                 (mapc (lambda (window)
491                         (and (eq (window-buffer window) buffer)
492                              (set-window-buffer window safe-buffer)))
493                       (window-list frame))))
494           (frame-list))))
495
496 (defvar mdw-inhibit-walk-windows nil
497   "If non-nil, then `walk-windows' does nothing.
498 This is used by advice on `switch-to-buffer-other-frame' to inhibit finding
499 buffers in random frames.")
500
501 (defadvice walk-windows (around mdw-inhibit activate)
502   "If `mdw-inhibit-walk-windows' is non-nil, then do nothing."
503   (and (not mdw-inhibit-walk-windows)
504        ad-do-it))
505
506 (defadvice switch-to-buffer-other-frame
507     (around mdw-always-new-frame activate)
508   "Always make a new frame.
509 Even if an existing window in some random frame looks tempting."
510   (let ((mdw-inhibit-walk-windows t)) ad-do-it))
511
512 (defadvice display-buffer (before mdw-inhibit-other-frames activate)
513   "Don't try to do anything fancy with other frames.
514 Pretend they don't exist.  They might be on other display devices."
515   (ad-set-arg 2 nil))
516
517 ;;;--------------------------------------------------------------------------
518 ;;; Mail and news hacking.
519
520 (define-derived-mode  mdwmail-mode mail-mode "[mdw] mail"
521   "Major mode for editing news and mail messages from external programs.
522 Not much right now.  Just support for doing MailCrypt stuff."
523   :syntax-table nil
524   :abbrev-table nil
525   (run-hooks 'mail-setup-hook))
526
527 (define-key mdwmail-mode-map [?\C-c ?\C-c] 'disabled-operation)
528
529 (add-hook 'mdwail-mode-hook
530           (lambda ()
531             (set-buffer-file-coding-system 'utf-8)
532             (make-local-variable 'paragraph-separate)
533             (make-local-variable 'paragraph-start)
534             (setq paragraph-start
535                   (concat "[ \t]*[-_][-_][-_]+$\\|^-- \\|-----\\|"
536                           paragraph-start))
537             (setq paragraph-separate
538                   (concat "[ \t]*[-_][-_][-_]+$\\|^-- \\|-----\\|"
539                           paragraph-separate))))
540
541 ;; How to encrypt in mdwmail.
542
543 (defun mdwmail-mc-encrypt (&optional recip scm start end from sign)
544   (or start
545       (setq start (save-excursion
546                     (goto-char (point-min))
547                     (or (search-forward "\n\n" nil t) (point-min)))))
548   (or end
549       (setq end (point-max)))
550   (mc-encrypt-generic recip scm start end from sign))
551
552 ;; How to sign in mdwmail.
553
554 (defun mdwmail-mc-sign (key scm start end uclr)
555   (or start
556       (setq start (save-excursion
557                     (goto-char (point-min))
558                     (or (search-forward "\n\n" nil t) (point-min)))))
559   (or end
560       (setq end (point-max)))
561   (mc-sign-generic key scm start end uclr))
562
563 ;; Some signature mangling.
564
565 (defun mdwmail-mangle-signature ()
566   (save-excursion
567     (goto-char (point-min))
568     (perform-replace "\n-- \n" "\n-- " nil nil nil)))
569 (add-hook 'mail-setup-hook 'mdwmail-mangle-signature)
570 (add-hook 'message-setup-hook 'mdwmail-mangle-signature)
571
572 ;; Insert my login name into message-ids, so I can score replies.
573
574 (defadvice message-unique-id (after mdw-user-name last activate compile)
575   "Ensure that the user's name appears at the end of the message-id string,
576 so that it can be used for convenient filtering."
577   (setq ad-return-value (concat ad-return-value "." (user-login-name))))
578
579 ;; Tell my movemail hack where movemail is.
580 ;;
581 ;; This is needed to shup up warnings about LD_PRELOAD.
582
583 (let ((path exec-path))
584   (while path
585     (let ((try (expand-file-name "movemail" (car path))))
586       (if (file-executable-p try)
587           (setenv "REAL_MOVEMAIL" try))
588       (setq path (cdr path)))))
589
590 ;; AUTHINFO GENERIC kludge.
591
592 (defvar nntp-authinfo-generic nil
593   "Set to the `NNTPAUTH' string to pass on to `authinfo-kludge'.
594
595 Use this to arrange for per-server settings.")
596
597 (defun nntp-open-authinfo-kludge (buffer)
598   "Open a connection to SERVER using `authinfo-kludge'."
599   (let ((proc (start-process "nntpd" buffer
600                              "env" (concat "NNTPAUTH="
601                                            (or nntp-authinfo-generic
602                                                (getenv "NNTPAUTH")
603                                                (error "NNTPAUTH unset")))
604                              "authinfo-kludge" nntp-address)))
605     (set-buffer buffer)
606     (nntp-wait-for-string "^\r*200")
607     (beginning-of-line)
608     (delete-region (point-min) (point))
609     proc))
610
611 (eval-after-load "erc"
612     '(load "~/.ercrc.el"))
613
614 ;;;--------------------------------------------------------------------------
615 ;;; Utility functions.
616
617 (or (fboundp 'line-number-at-pos)
618     (defun line-number-at-pos (&optional pos)
619       (let ((opoint (or pos (point))) start)
620         (save-excursion
621           (save-restriction
622             (goto-char (point-min))
623             (widen)
624             (forward-line 0)
625             (setq start (point))
626             (goto-char opoint)
627             (forward-line 0)
628             (1+ (count-lines 1 (point))))))))
629
630 (defun mdw-uniquify-alist (&rest alists)
631   "Return the concatenation of the ALISTS with duplicate elements removed.
632 The first association with a given key prevails; others are
633 ignored.  The input lists are not modified, although they'll
634 probably become garbage."
635   (and alists
636        (let ((start-list (cons nil nil)))
637          (mdw-do-uniquify start-list
638                           start-list
639                           (car alists)
640                           (cdr alists)))))
641
642 (defun mdw-do-uniquify (done end l rest)
643   "A helper function for mdw-uniquify-alist.
644 The DONE argument is a list whose first element is `nil'.  It
645 contains the uniquified alist built so far.  The leading `nil' is
646 stripped off at the end of the operation; it's only there so that
647 DONE always references a cons cell.  END refers to the final cons
648 cell in the DONE list; it is modified in place each time to avoid
649 the overheads of `append'ing all the time.  The L argument is the
650 alist we're currently processing; the remaining alists are given
651 in REST."
652
653   ;; There are several different cases to deal with here.
654   (cond
655
656    ;; Current list isn't empty.  Add the first item to the DONE list if
657    ;; there's not an item with the same KEY already there.
658    (l (or (assoc (car (car l)) done)
659           (progn
660             (setcdr end (cons (car l) nil))
661             (setq end (cdr end))))
662       (mdw-do-uniquify done end (cdr l) rest))
663
664    ;; The list we were working on is empty.  Shunt the next list into the
665    ;; current list position and go round again.
666    (rest (mdw-do-uniquify done end (car rest) (cdr rest)))
667
668    ;; Everything's done.  Remove the leading `nil' from the DONE list and
669    ;; return it.  Finished!
670    (t (cdr done))))
671
672 (defun date ()
673   "Insert the current date in a pleasing way."
674   (interactive)
675   (insert (save-excursion
676             (let ((buffer (get-buffer-create "*tmp*")))
677               (unwind-protect (progn (set-buffer buffer)
678                                      (erase-buffer)
679                                      (shell-command "date +%Y-%m-%d" t)
680                                      (goto-char (mark))
681                                      (delete-backward-char 1)
682                                      (buffer-string))
683                 (kill-buffer buffer))))))
684
685 (defun uuencode (file &optional name)
686   "UUencodes a file, maybe calling it NAME, into the current buffer."
687   (interactive "fInput file name: ")
688
689   ;; If NAME isn't specified, then guess from the filename.
690   (if (not name)
691       (setq name
692             (substring file
693                        (or (string-match "[^/]*$" file) 0))))
694   (print (format "uuencode `%s' `%s'" file name))
695
696   ;; Now actually do the thing.
697   (call-process "uuencode" file t nil name))
698
699 (defvar np-file "~/.np"
700   "*Where the `now-playing' file is.")
701
702 (defun np (&optional arg)
703   "Grabs a `now-playing' string."
704   (interactive)
705   (save-excursion
706     (or arg (progn
707               (goto-char (point-max))
708               (insert "\nNP: ")
709               (insert-file-contents np-file)))))
710
711 (defun mdw-version-< (ver-a ver-b)
712   "Answer whether VER-A is strictly earlier than VER-B.
713 VER-A and VER-B are version numbers, which are strings containing digit
714 sequences separated by `.'."
715   (let* ((la (mapcar (lambda (x) (car (read-from-string x)))
716                      (split-string ver-a "\\.")))
717          (lb (mapcar (lambda (x) (car (read-from-string x)))
718                      (split-string ver-b "\\."))))
719     (catch 'done
720       (while t
721         (cond ((null la) (throw 'done lb))
722               ((null lb) (throw 'done nil))
723               ((< (car la) (car lb)) (throw 'done t))
724               ((= (car la) (car lb)) (setq la (cdr la) lb (cdr lb))))))))
725
726 (defun mdw-check-autorevert ()
727   "Sets global-auto-revert-ignore-buffer appropriately for this buffer.
728 This takes into consideration whether it's been found using
729 tramp, which seems to get itself into a twist."
730   (cond ((not (boundp 'global-auto-revert-ignore-buffer))
731          nil)
732         ((and (buffer-file-name)
733               (fboundp 'tramp-tramp-file-p)
734               (tramp-tramp-file-p (buffer-file-name)))
735          (unless global-auto-revert-ignore-buffer
736            (setq global-auto-revert-ignore-buffer 'tramp)))
737         ((eq global-auto-revert-ignore-buffer 'tramp)
738          (setq global-auto-revert-ignore-buffer nil))))
739
740 (defadvice find-file (after mdw-autorevert activate)
741   (mdw-check-autorevert))
742 (defadvice write-file (after mdw-autorevert activate)
743   (mdw-check-autorevert))
744
745 ;;;--------------------------------------------------------------------------
746 ;;; Dired hacking.
747
748 (defadvice dired-maybe-insert-subdir
749     (around mdw-marked-insertion first activate)
750   "The DIRNAME may be a list of directory names to insert.
751 Interactively, if files are marked, then insert all of them.
752 With a numeric prefix argument, select that many entries near
753 point; with a non-numeric prefix argument, prompt for listing
754 options."
755   (interactive
756    (list (dired-get-marked-files nil
757                                  (and (integerp current-prefix-arg)
758                                       current-prefix-arg)
759                                  #'file-directory-p)
760          (and current-prefix-arg
761               (not (integerp current-prefix-arg))
762               (read-string "Switches for listing: "
763                            (or dired-subdir-switches
764                                dired-actual-switches)))))
765   (let ((dirs (ad-get-arg 0)))
766     (dolist (dir (if (listp dirs) dirs (list dirs)))
767       (ad-set-arg 0 dir)
768       ad-do-it)))
769
770 ;;;--------------------------------------------------------------------------
771 ;;; URL viewing.
772
773 (defun mdw-w3m-browse-url (url &optional new-session-p)
774   "Invoke w3m on the URL in its current window, or at least a different one.
775 If NEW-SESSION-P, start a new session."
776   (interactive "sURL: \nP")
777   (save-excursion
778     (let ((window (selected-window)))
779       (unwind-protect
780           (progn
781             (select-window (or (and (not new-session-p)
782                                     (get-buffer-window "*w3m*"))
783                                (progn
784                                  (if (one-window-p t) (split-window))
785                                  (get-lru-window))))
786             (w3m-browse-url url new-session-p))
787         (select-window window)))))
788
789 (defvar mdw-good-url-browsers
790   '(browse-url-mozilla
791     browse-url-generic
792     (w3m . mdw-w3m-browse-url)
793     browse-url-w3)
794   "List of good browsers for mdw-good-url-browsers.
795 Each item is a browser function name, or a cons (CHECK . FUNC).
796 A symbol FOO stands for (FOO . FOO).")
797
798 (defun mdw-good-url-browser ()
799   "Return a good URL browser.
800 Trundle the list of such things, finding the first item for which
801 CHECK is fboundp, and returning the correponding FUNC."
802   (let ((bs mdw-good-url-browsers) b check func answer)
803     (while (and bs (not answer))
804       (setq b (car bs)
805             bs (cdr bs))
806       (if (consp b)
807           (setq check (car b) func (cdr b))
808         (setq check b func b))
809       (if (fboundp check)
810           (setq answer func)))
811     answer))
812
813 (eval-after-load "w3m-search"
814   '(progn
815      (dolist
816          (item
817           '(("g" "Google" "http://www.google.co.uk/search?q=%s")
818             ("gd" "Google Directory"
819              "http://www.google.com/search?cat=gwd/Top&q=%s")
820             ("gg" "Google Groups" "http://groups.google.com/groups?q=%s")
821             ("ward" "Ward's wiki" "http://c2.com/cgi/wiki?%s")
822             ("gi" "Images" "http://images.google.com/images?q=%s")
823             ("rfc" "RFC"
824              "http://metalzone.distorted.org.uk/ftp/pub/mirrors/rfc/rfc%s.txt.gz")
825             ("wp" "Wikipedia"
826              "http://en.wikipedia.org/wiki/Special:Search?go=Go&search=%s")
827             ("imdb" "IMDb" "http://www.imdb.com/Find?%s")
828             ("nc-wiki" "nCipher wiki"
829              "http://wiki.ncipher.com/wiki/bin/view/Devel/?topic=%s")
830             ("map" "Google maps" "http://maps.google.co.uk/maps?q=%s&hl=en")
831             ("lp" "Launchpad bug by number"
832              "https://bugs.launchpad.net/bugs/%s")
833             ("lppkg" "Launchpad bugs by package"
834              "https://bugs.launchpad.net/%s")
835             ("msdn" "MSDN"
836              "http://social.msdn.microsoft.com/Search/en-GB/?query=%s&ac=8")
837             ("debbug" "Debian bug by number"
838              "http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=%s")
839             ("debbugpkg" "Debian bugs by package"
840              "http://bugs.debian.org/cgi-bin/pkgreport.cgi?pkg=%s")
841             ("ljlogin" "LJ login" "http://www.livejournal.com/login.bml")))
842        (add-to-list 'w3m-search-engine-alist
843                     (list (cadr item) (caddr item) nil))
844        (add-to-list 'w3m-uri-replace-alist
845                     (list (concat "\\`" (car item) ":")
846                           'w3m-search-uri-replace
847                           (cadr item))))))
848
849 ;;;--------------------------------------------------------------------------
850 ;;; Paragraph filling.
851
852 ;; Useful variables.
853
854 (defvar mdw-fill-prefix nil
855   "*Used by `mdw-line-prefix' and `mdw-fill-paragraph'.
856 If there's no fill prefix currently set (by the `fill-prefix'
857 variable) and there's a match from one of the regexps here, it
858 gets used to set the fill-prefix for the current operation.
859
860 The variable is a list of items of the form `REGEXP . PREFIX'; if
861 the REGEXP matches, the PREFIX is used to set the fill prefix.
862 It in turn is a list of things:
863
864   STRING -- insert a literal string
865   (match . N) -- insert the thing matched by bracketed subexpression N
866   (pad . N) -- a string of whitespace the same width as subexpression N
867   (expr . FORM) -- the result of evaluating FORM")
868
869 (make-variable-buffer-local 'mdw-fill-prefix)
870
871 (defvar mdw-hanging-indents
872   (concat "\\(\\("
873             "\\([*o+]\\|-[-#]?\\|[0-9]+\\.\\|\\[[0-9]+\\]\\|([a-zA-Z])\\)"
874             "[ \t]+"
875           "\\)?\\)")
876   "*Standard regexp matching parts of a hanging indent.
877 This is mainly useful in `auto-fill-mode'.")
878
879 ;; Setting things up.
880
881 (fset 'mdw-do-auto-fill (symbol-function 'do-auto-fill))
882
883 ;; Utility functions.
884
885 (defun mdw-maybe-tabify (s)
886   "Tabify or untabify the string S, according to `indent-tabs-mode'."
887   (let ((tabfun (if indent-tabs-mode #'tabify #'untabify)))
888     (with-temp-buffer
889       (save-match-data
890         (insert s "\n")
891         (let ((start (point-min)) (end (point-max)))
892           (funcall tabfun (point-min) (point-max))
893           (setq s (buffer-substring (point-min) (1- (point-max)))))))))
894
895 (defun mdw-examine-fill-prefixes (l)
896   "Given a list of dynamic fill prefixes, pick one which matches
897 context and return the static fill prefix to use.  Point must be
898 at the start of a line, and match data must be saved."
899   (cond ((not l) nil)
900                ((looking-at (car (car l)))
901                 (mdw-maybe-tabify (apply #'concat
902                                          (mapcar #'mdw-do-prefix-match
903                                                  (cdr (car l))))))
904                (t (mdw-examine-fill-prefixes (cdr l)))))
905
906 (defun mdw-maybe-car (p)
907   "If P is a pair, return (car P), otherwise just return P."
908   (if (consp p) (car p) p))
909
910 (defun mdw-padding (s)
911   "Return a string the same width as S but made entirely from whitespace."
912   (let* ((l (length s)) (i 0) (n (make-string l ? )))
913     (while (< i l)
914       (if (= 9 (aref s i))
915           (aset n i 9))
916       (setq i (1+ i)))
917     n))
918
919 (defun mdw-do-prefix-match (m)
920   "Expand a dynamic prefix match element.
921 See `mdw-fill-prefix' for details."
922   (cond ((not (consp m)) (format "%s" m))
923            ((eq (car m) 'match) (match-string (mdw-maybe-car (cdr m))))
924            ((eq (car m) 'pad) (mdw-padding (match-string
925                                             (mdw-maybe-car (cdr m)))))
926            ((eq (car m) 'eval) (eval (cdr m)))
927            (t "")))
928
929 (defun mdw-choose-dynamic-fill-prefix ()
930   "Work out the dynamic fill prefix based on the variable `mdw-fill-prefix'."
931   (cond ((and fill-prefix (not (string= fill-prefix ""))) fill-prefix)
932            ((not mdw-fill-prefix) fill-prefix)
933            (t (save-excursion
934                 (beginning-of-line)
935                 (save-match-data
936                   (mdw-examine-fill-prefixes mdw-fill-prefix))))))
937
938 (defun do-auto-fill ()
939   "Handle auto-filling, working out a dynamic fill prefix in the
940 case where there isn't a sensible static one."
941   (let ((fill-prefix (mdw-choose-dynamic-fill-prefix)))
942     (mdw-do-auto-fill)))
943
944 (defun mdw-fill-paragraph ()
945   "Fill paragraph, getting a dynamic fill prefix."
946   (interactive)
947   (let ((fill-prefix (mdw-choose-dynamic-fill-prefix)))
948     (fill-paragraph nil)))
949
950 (defun mdw-standard-fill-prefix (rx &optional mat)
951   "Set the dynamic fill prefix, handling standard hanging indents and stuff.
952 This is just a short-cut for setting the thing by hand, and by
953 design it doesn't cope with anything approximating a complicated
954 case."
955   (setq mdw-fill-prefix
956            `((,(concat rx mdw-hanging-indents)
957               (match . 1)
958               (pad . ,(or mat 2))))))
959
960 ;;;--------------------------------------------------------------------------
961 ;;; Other common declarations.
962
963 ;; Common mode settings.
964
965 (defvar mdw-auto-indent t
966   "Whether to indent automatically after a newline.")
967
968 (defun mdw-whitespace-mode (&optional arg)
969   "Turn on/off whitespace mode, but don't highlight trailing space."
970   (interactive "P")
971   (when (and (boundp 'whitespace-style)
972              (fboundp 'whitespace-mode))
973     (let ((whitespace-style (remove 'trailing whitespace-style)))
974       (whitespace-mode arg))
975     (setq show-trailing-whitespace whitespace-mode)))
976
977 (defvar mdw-do-misc-mode-hacking nil)
978
979 (defun mdw-misc-mode-config ()
980   (and mdw-auto-indent
981        (cond ((eq major-mode 'lisp-mode)
982               (local-set-key "\C-m" 'mdw-indent-newline-and-indent))
983              ((or (eq major-mode 'slime-repl-mode)
984                   (eq major-mode 'asm-mode))
985               nil)
986              (t
987               (local-set-key "\C-m" 'newline-and-indent))))
988   (set (make-local-variable 'mdw-do-misc-mode-hacking) t)
989   (local-set-key [C-return] 'newline)
990   (make-local-variable 'page-delimiter)
991   (setq page-delimiter "\f\\|^.*-\\{6\\}.*$")
992   (setq comment-column 40)
993   (auto-fill-mode 1)
994   (setq fill-column mdw-text-width)
995   (and (fboundp 'gtags-mode)
996        (gtags-mode))
997   (if (fboundp 'hs-minor-mode)
998       (trap (hs-minor-mode t))
999     (outline-minor-mode t))
1000   (reveal-mode t)
1001   (trap (turn-on-font-lock)))
1002
1003 (defun mdw-post-local-vars-misc-mode-config ()
1004   (setq whitespace-line-column mdw-text-width)
1005   (when (and mdw-do-misc-mode-hacking
1006              (not buffer-read-only))
1007     (setq show-trailing-whitespace t)
1008     (mdw-whitespace-mode 1)))
1009 (add-hook 'hack-local-variables-hook 'mdw-post-local-vars-misc-mode-config)
1010
1011 (defmacro mdw-advise-update-angry-fruit-salad (&rest funcs)
1012   `(progn ,@(mapcar (lambda (func)
1013                       `(defadvice ,func
1014                            (after mdw-angry-fruit-salad activate)
1015                          (when mdw-do-misc-mode-hacking
1016                            (setq show-trailing-whitespace
1017                                  (not buffer-read-only))
1018                            (mdw-whitespace-mode (if buffer-read-only 0 1)))))
1019                     funcs)))
1020 (mdw-advise-update-angry-fruit-salad toggle-read-only
1021                                      read-only-mode
1022                                      view-mode
1023                                      view-mode-enable
1024                                      view-mode-disable)
1025
1026 (eval-after-load 'gtags
1027   '(progn
1028      (dolist (key '([mouse-2] [mouse-3]))
1029        (define-key gtags-mode-map key nil))
1030      (define-key gtags-mode-map [C-S-mouse-2] 'gtags-find-tag-by-event)
1031      (define-key gtags-select-mode-map [C-S-mouse-2]
1032        'gtags-select-tag-by-event)
1033      (dolist (map (list gtags-mode-map gtags-select-mode-map))
1034        (define-key map [C-S-mouse-3] 'gtags-pop-stack))))
1035
1036 ;; Backup file handling.
1037
1038 (defvar mdw-backup-disable-regexps nil
1039   "*List of regular expressions: if a file name matches any of
1040 these then the file is not backed up.")
1041
1042 (defun mdw-backup-enable-predicate (name)
1043   "[mdw]'s default backup predicate.
1044 Allows a backup if the standard predicate would allow it, and it
1045 doesn't match any of the regular expressions in
1046 `mdw-backup-disable-regexps'."
1047   (and (normal-backup-enable-predicate name)
1048        (let ((answer t) (list mdw-backup-disable-regexps))
1049          (save-match-data
1050            (while list
1051              (if (string-match (car list) name)
1052                  (setq answer nil))
1053              (setq list (cdr list)))
1054            answer))))
1055 (setq backup-enable-predicate 'mdw-backup-enable-predicate)
1056
1057 ;; Frame cleanup.
1058
1059 (defun mdw-last-one-out-turn-off-the-lights (frame)
1060   "Disconnect from an X display if this was the last frame on that display."
1061   (let ((frame-display (frame-parameter frame 'display)))
1062     (when (and frame-display
1063                (eq window-system 'x)
1064                (not (some (lambda (fr)
1065                             (and (not (eq fr frame))
1066                                  (string= (frame-parameter fr 'display)
1067                                           frame-display)))
1068                           (frame-list))))
1069       (run-with-idle-timer 0 nil #'x-close-connection frame-display))))
1070 (add-hook 'delete-frame-functions 'mdw-last-one-out-turn-off-the-lights)
1071
1072 ;;;--------------------------------------------------------------------------
1073 ;;; Where is point?
1074
1075 (defvar mdw-point-overlay
1076   (let ((ov (make-overlay 0 0))
1077         (s "."))
1078     (overlay-put ov 'priority 2)
1079     (put-text-property 0 1 'display '(left-fringe vertical-bar) s)
1080     (overlay-put ov 'before-string s)
1081     (delete-overlay ov)
1082     ov)
1083   "An overlay used for showing where point is in the selected window.")
1084
1085 (defun mdw-remove-point-overlay ()
1086   "Remove the current-point overlay."
1087   (delete-overlay mdw-point-overlay))
1088
1089 (defun mdw-update-point-overlay ()
1090   "Mark the current point position with an overlay."
1091   (if (not mdw-point-overlay-mode)
1092       (mdw-remove-point-overlay)
1093     (overlay-put mdw-point-overlay 'window (selected-window))
1094     (if (bolp)
1095         (move-overlay mdw-point-overlay
1096                       (point) (1+ (point)) (current-buffer))
1097       (move-overlay mdw-point-overlay
1098                     (1- (point)) (point) (current-buffer)))))
1099
1100 (defvar mdw-point-overlay-buffers nil
1101   "List of buffers using `mdw-point-overlay-mode'.")
1102
1103 (define-minor-mode mdw-point-overlay-mode
1104   "Indicate current line with an overlay."
1105   :global nil
1106   (let ((buffer (current-buffer)))
1107     (setq mdw-point-overlay-buffers
1108           (mapcan (lambda (buf)
1109                     (if (and (buffer-live-p buf)
1110                              (not (eq buf buffer)))
1111                         (list buf)))
1112                   mdw-point-overlay-buffers))
1113     (if mdw-point-overlay-mode
1114         (setq mdw-point-overlay-buffers
1115               (cons buffer mdw-point-overlay-buffers))))
1116   (cond (mdw-point-overlay-buffers
1117          (add-hook 'pre-command-hook 'mdw-remove-point-overlay)
1118          (add-hook 'post-command-hook 'mdw-update-point-overlay))
1119         (t
1120          (mdw-remove-point-overlay)
1121          (remove-hook 'pre-command-hook 'mdw-remove-point-overlay)
1122          (remove-hook 'post-command-hook 'mdw-update-point-overlay))))
1123
1124 (define-globalized-minor-mode mdw-global-point-overlay-mode
1125   mdw-point-overlay-mode
1126   (lambda () (if (not (minibufferp)) (mdw-point-overlay-mode t))))
1127
1128 ;;;--------------------------------------------------------------------------
1129 ;;; Fullscreen-ness.
1130
1131 (defvar mdw-full-screen-parameters
1132   '((menu-bar-lines . 0)
1133     ;(vertical-scroll-bars . nil)
1134     )
1135   "Frame parameters to set when making a frame fullscreen.")
1136
1137 (defvar mdw-full-screen-save
1138   '(width height)
1139   "Extra frame parameters to save when setting fullscreen.")
1140
1141 (defun mdw-toggle-full-screen (&optional frame)
1142   "Show the FRAME fullscreen."
1143   (interactive)
1144   (when window-system
1145     (cond ((frame-parameter frame 'fullscreen)
1146            (set-frame-parameter frame 'fullscreen nil)
1147            (modify-frame-parameters
1148             nil
1149             (or (frame-parameter frame 'mdw-full-screen-saved)
1150                 (mapcar (lambda (assoc)
1151                           (assq (car assoc) default-frame-alist))
1152                         mdw-full-screen-parameters))))
1153           (t
1154            (let ((saved (mapcar (lambda (param)
1155                                   (cons param (frame-parameter frame param)))
1156                                 (append (mapcar #'car
1157                                                 mdw-full-screen-parameters)
1158                                         mdw-full-screen-save))))
1159              (set-frame-parameter frame 'mdw-full-screen-saved saved))
1160            (modify-frame-parameters frame mdw-full-screen-parameters)
1161            (set-frame-parameter frame 'fullscreen 'fullboth)))))
1162
1163 ;;;--------------------------------------------------------------------------
1164 ;;; General fontification.
1165
1166 (make-face 'mdw-virgin-face)
1167
1168 (defmacro mdw-define-face (name &rest body)
1169   "Define a face, and make sure it's actually set as the definition."
1170   (declare (indent 1)
1171            (debug 0))
1172   `(progn
1173      (copy-face 'mdw-virgin-face ',name)
1174      (defvar ,name ',name)
1175      (put ',name 'face-defface-spec ',body)
1176      (face-spec-set ',name ',body nil)))
1177
1178 (mdw-define-face default
1179   (((type w32)) :family "courier new" :height 85)
1180   (((type x)) :family "6x13" :foundry "trad" :height 130)
1181   (((type color)) :foreground "white" :background "black")
1182   (t nil))
1183 (mdw-define-face fixed-pitch
1184   (((type w32)) :family "courier new" :height 85)
1185   (((type x)) :family "6x13" :foundry "trad" :height 130)
1186   (t :foreground "white" :background "black"))
1187 (if (mdw-emacs-version-p 23)
1188     (mdw-define-face variable-pitch
1189       (((type x)) :family "sans" :height 100))
1190   (mdw-define-face variable-pitch
1191     (((type x)) :family "helvetica" :height 90)))
1192 (mdw-define-face region
1193   (((type tty) (class color)) :background "blue")
1194   (((type tty) (class mono)) :inverse-video t)
1195   (t :background "grey30"))
1196 (mdw-define-face match
1197   (((type tty) (class color)) :background "blue")
1198   (((type tty) (class mono)) :inverse-video t)
1199   (t :background "blue"))
1200 (mdw-define-face mc/cursor-face
1201   (((type tty) (class mono)) :inverse-video t)
1202   (t :background "red"))
1203 (mdw-define-face minibuffer-prompt
1204   (t :weight bold))
1205 (mdw-define-face mode-line
1206   (((class color)) :foreground "blue" :background "yellow"
1207                    :box (:line-width 1 :style released-button))
1208   (t :inverse-video t))
1209 (mdw-define-face mode-line-inactive
1210   (((class color)) :foreground "yellow" :background "blue"
1211                    :box (:line-width 1 :style released-button))
1212   (t :inverse-video t))
1213 (mdw-define-face nobreak-space
1214   (((type tty)))
1215   (t :inherit escape-glyph :underline t))
1216 (mdw-define-face scroll-bar
1217   (t :foreground "black" :background "lightgrey"))
1218 (mdw-define-face fringe
1219   (t :foreground "yellow"))
1220 (mdw-define-face show-paren-match
1221   (((class color)) :background "darkgreen")
1222   (t :underline t))
1223 (mdw-define-face show-paren-mismatch
1224   (((class color)) :background "red")
1225   (t :inverse-video t))
1226 (mdw-define-face highlight
1227   (((type x) (class color)) :background "DarkSeaGreen4")
1228   (((type tty) (class color)) :background "cyan")
1229   (t :inverse-video t))
1230
1231 (mdw-define-face holiday-face
1232   (t :background "red"))
1233 (mdw-define-face calendar-today-face
1234   (t :foreground "yellow" :weight bold))
1235
1236 (mdw-define-face comint-highlight-prompt
1237   (t :weight bold))
1238 (mdw-define-face comint-highlight-input
1239   (t nil))
1240
1241 (mdw-define-face dired-directory
1242   (t :foreground "cyan" :weight bold))
1243 (mdw-define-face dired-symlink
1244   (t :foreground "cyan"))
1245 (mdw-define-face dired-perm-write
1246   (t nil))
1247
1248 (mdw-define-face trailing-whitespace
1249   (((class color)) :background "red")
1250   (t :inverse-video t))
1251 (mdw-define-face whitespace-line
1252   (((class color)) :background "darkred")
1253   (t :inverse-video t))
1254 (mdw-define-face mdw-punct-face
1255   (((type tty)) :foreground "yellow") (t :foreground "burlywood2"))
1256 (mdw-define-face mdw-number-face
1257   (t :foreground "yellow"))
1258 (mdw-define-face mdw-trivial-face)
1259 (mdw-define-face font-lock-function-name-face
1260   (t :slant italic))
1261 (mdw-define-face font-lock-keyword-face
1262   (t :weight bold))
1263 (mdw-define-face font-lock-constant-face
1264   (t :slant italic))
1265 (mdw-define-face font-lock-builtin-face
1266   (t :weight bold))
1267 (mdw-define-face font-lock-type-face
1268   (t :weight bold :slant italic))
1269 (mdw-define-face font-lock-reference-face
1270   (t :weight bold))
1271 (mdw-define-face font-lock-variable-name-face
1272   (t :slant italic))
1273 (mdw-define-face font-lock-comment-delimiter-face
1274   (((class mono)) :weight bold)
1275   (((type tty) (class color)) :foreground "green")
1276   (t :slant italic :foreground "SeaGreen1"))
1277 (mdw-define-face font-lock-comment-face
1278   (((class mono)) :weight bold)
1279   (((type tty) (class color)) :foreground "green")
1280   (t :slant italic :foreground "SeaGreen1"))
1281 (mdw-define-face font-lock-string-face
1282   (((class mono)) :weight bold)
1283   (((class color)) :foreground "SkyBlue1"))
1284
1285 (mdw-define-face message-separator
1286   (t :background "red" :foreground "white" :weight bold))
1287 (mdw-define-face message-cited-text
1288   (default :slant italic)
1289   (((type tty)) :foreground "cyan") (t :foreground "SkyBlue1"))
1290 (mdw-define-face message-header-cc
1291   (default :slant italic)
1292   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1293 (mdw-define-face message-header-newsgroups
1294   (default :slant italic)
1295   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1296 (mdw-define-face message-header-subject
1297   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1298 (mdw-define-face message-header-to
1299   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1300 (mdw-define-face message-header-xheader
1301   (default :slant italic)
1302   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1303 (mdw-define-face message-header-other
1304   (default :slant italic)
1305   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1306 (mdw-define-face message-header-name
1307   (default :weight bold)
1308   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1309
1310 (mdw-define-face which-func
1311   (t nil))
1312
1313 (mdw-define-face gnus-header-name
1314   (default :weight bold)
1315   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1316 (mdw-define-face gnus-header-subject
1317   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1318 (mdw-define-face gnus-header-from
1319   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1320 (mdw-define-face gnus-header-to
1321   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1322 (mdw-define-face gnus-header-content
1323   (default :slant italic)
1324   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1325
1326 (mdw-define-face gnus-cite-1
1327   (((type tty)) :foreground "cyan") (t :foreground "SkyBlue1"))
1328 (mdw-define-face gnus-cite-2
1329   (((type tty)) :foreground "blue") (t :foreground "RoyalBlue2"))
1330 (mdw-define-face gnus-cite-3
1331   (((type tty)) :foreground "magenta") (t :foreground "MediumOrchid"))
1332 (mdw-define-face gnus-cite-4
1333   (((type tty)) :foreground "red") (t :foreground "firebrick2"))
1334 (mdw-define-face gnus-cite-5
1335   (((type tty)) :foreground "yellow") (t :foreground "burlywood2"))
1336 (mdw-define-face gnus-cite-6
1337   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1338 (mdw-define-face gnus-cite-7
1339   (((type tty)) :foreground "cyan") (t :foreground "SlateBlue1"))
1340 (mdw-define-face gnus-cite-8
1341   (((type tty)) :foreground "blue") (t :foreground "RoyalBlue2"))
1342 (mdw-define-face gnus-cite-9
1343   (((type tty)) :foreground "magenta") (t :foreground "purple2"))
1344 (mdw-define-face gnus-cite-10
1345   (((type tty)) :foreground "red") (t :foreground "DarkOrange2"))
1346 (mdw-define-face gnus-cite-11
1347   (t :foreground "grey"))
1348
1349 (mdw-define-face diff-header
1350   (t nil))
1351 (mdw-define-face diff-index
1352   (t :weight bold))
1353 (mdw-define-face diff-file-header
1354   (t :weight bold))
1355 (mdw-define-face diff-hunk-header
1356   (t :foreground "SkyBlue1"))
1357 (mdw-define-face diff-function
1358   (t :foreground "SkyBlue1" :weight bold))
1359 (mdw-define-face diff-header
1360   (t :background "grey10"))
1361 (mdw-define-face diff-added
1362   (t :foreground "green"))
1363 (mdw-define-face diff-removed
1364   (t :foreground "red"))
1365 (mdw-define-face diff-context
1366   (t nil))
1367 (mdw-define-face diff-refine-change
1368   (((class color) (type x)) :background "RoyalBlue4")
1369   (t :underline t))
1370 (mdw-define-face diff-refine-removed
1371   (((class color) (type x)) :background "#500")
1372   (t :underline t))
1373 (mdw-define-face diff-refine-added
1374   (((class color) (type x)) :background "#050")
1375   (t :underline t))
1376
1377 (setq ediff-force-faces t)
1378 (mdw-define-face ediff-current-diff-A
1379   (((class color) (type x)) :background "darkred")
1380   (((class color) (type tty)) :background "red")
1381   (t :inverse-video t))
1382 (mdw-define-face ediff-fine-diff-A
1383   (((class color) (type x)) :background "red3")
1384   (((class color) (type tty)) :inverse-video t)
1385   (t :inverse-video nil))
1386 (mdw-define-face ediff-even-diff-A
1387   (((class color) (type x)) :background "#300"))
1388 (mdw-define-face ediff-odd-diff-A
1389   (((class color) (type x)) :background "#300"))
1390 (mdw-define-face ediff-current-diff-B
1391   (((class color) (type x)) :background "darkgreen")
1392   (((class color) (type tty)) :background "magenta")
1393   (t :inverse-video t))
1394 (mdw-define-face ediff-fine-diff-B
1395   (((class color) (type x)) :background "green4")
1396   (((class color) (type tty)) :inverse-video t)
1397   (t :inverse-video nil))
1398 (mdw-define-face ediff-even-diff-B
1399   (((class color) (type x)) :background "#020"))
1400 (mdw-define-face ediff-odd-diff-B
1401   (((class color) (type x)) :background "#020"))
1402 (mdw-define-face ediff-current-diff-C
1403   (((class color) (type x)) :background "darkblue")
1404   (((class color) (type tty)) :background "blue")
1405   (t :inverse-video t))
1406 (mdw-define-face ediff-fine-diff-C
1407   (((class color) (type x)) :background "blue1")
1408   (((class color) (type tty)) :inverse-video t)
1409   (t :inverse-video nil))
1410 (mdw-define-face ediff-even-diff-C
1411   (((class color) (type x)) :background "#004"))
1412 (mdw-define-face ediff-odd-diff-C
1413   (((class color) (type x)) :background "#004"))
1414 (mdw-define-face ediff-current-diff-Ancestor
1415   (((class color) (type x)) :background "#630")
1416   (((class color) (type tty)) :background "blue")
1417   (t :inverse-video t))
1418 (mdw-define-face ediff-even-diff-Ancestor
1419   (((class color) (type x)) :background "#320"))
1420 (mdw-define-face ediff-odd-diff-Ancestor
1421   (((class color) (type x)) :background "#320"))
1422
1423 (mdw-define-face dylan-header-background
1424   (((class color) (type x)) :background "NavyBlue")
1425   (t :background "blue"))
1426
1427 (mdw-define-face magit-diff-add
1428   (t :foreground "green"))
1429 (mdw-define-face magit-diff-del
1430   (t :foreground "red"))
1431 (mdw-define-face magit-diff-file-header
1432   (t :weight bold))
1433 (mdw-define-face magit-diff-hunk-header
1434   (t :foreground "SkyBlue1"))
1435 (mdw-define-face magit-item-highlight
1436   (((type tty)) :background "blue")
1437   (t :background "grey11"))
1438 (mdw-define-face magit-log-head-label-remote
1439   (((type tty)) :background "cyan" :foreground "green")
1440   (t :background "grey11" :foreground "DarkSeaGreen2" :box t))
1441 (mdw-define-face magit-log-head-label-local
1442   (((type tty)) :background "cyan" :foreground "yellow")
1443   (t :background "grey11" :foreground "LightSkyBlue1" :box t))
1444 (mdw-define-face magit-log-head-label-tags
1445   (((type tty)) :background "red" :foreground "yellow")
1446   (t :background "LemonChiffon1" :foreground "goldenrod4" :box t))
1447 (mdw-define-face magit-log-graph
1448   (((type tty)) :foreground "magenta")
1449   (t :foreground "grey80"))
1450
1451 (mdw-define-face erc-input-face
1452   (t :foreground "red"))
1453
1454 (mdw-define-face woman-bold
1455   (t :weight bold))
1456 (mdw-define-face woman-italic
1457   (t :slant italic))
1458
1459 (eval-after-load "rst"
1460   '(progn
1461      (mdw-define-face rst-level-1-face
1462        (t :foreground "SkyBlue1" :weight bold))
1463      (mdw-define-face rst-level-2-face
1464        (t :foreground "SeaGreen1" :weight bold))
1465      (mdw-define-face rst-level-3-face
1466        (t :weight bold))
1467      (mdw-define-face rst-level-4-face
1468        (t :slant italic))
1469      (mdw-define-face rst-level-5-face
1470        (t :underline t))
1471      (mdw-define-face rst-level-6-face
1472        ())))
1473
1474 (mdw-define-face p4-depot-added-face
1475   (t :foreground "green"))
1476 (mdw-define-face p4-depot-branch-op-face
1477   (t :foreground "yellow"))
1478 (mdw-define-face p4-depot-deleted-face
1479   (t :foreground "red"))
1480 (mdw-define-face p4-depot-unmapped-face
1481   (t :foreground "SkyBlue1"))
1482 (mdw-define-face p4-diff-change-face
1483   (t :foreground "yellow"))
1484 (mdw-define-face p4-diff-del-face
1485   (t :foreground "red"))
1486 (mdw-define-face p4-diff-file-face
1487   (t :foreground "SkyBlue1"))
1488 (mdw-define-face p4-diff-head-face
1489   (t :background "grey10"))
1490 (mdw-define-face p4-diff-ins-face
1491   (t :foreground "green"))
1492
1493 (mdw-define-face w3m-anchor-face
1494   (t :foreground "SkyBlue1" :underline t))
1495 (mdw-define-face w3m-arrived-anchor-face
1496   (t :foreground "SkyBlue1" :underline t))
1497
1498 (mdw-define-face whizzy-slice-face
1499   (t :background "grey10"))
1500 (mdw-define-face whizzy-error-face
1501   (t :background "darkred"))
1502
1503 ;; Ellipses used to indicate hidden text (and similar).
1504 (mdw-define-face mdw-ellipsis-face
1505   (((type tty)) :foreground "blue") (t :foreground "grey60"))
1506 (let ((dollar (make-glyph-code ?$ 'mdw-ellipsis-face))
1507       (backslash (make-glyph-code ?\\ 'mdw-ellipsis-face))
1508       (dot (make-glyph-code ?. 'mdw-ellipsis-face))
1509       (bar (make-glyph-code ?| mdw-ellipsis-face)))
1510   (set-display-table-slot standard-display-table 0 dollar)
1511   (set-display-table-slot standard-display-table 1 backslash)
1512   (set-display-table-slot standard-display-table 4
1513                           (vector dot dot dot))
1514   (set-display-table-slot standard-display-table 5 bar))
1515
1516 ;;;--------------------------------------------------------------------------
1517 ;;; C programming configuration.
1518
1519 ;; Make C indentation nice.
1520
1521 (defun mdw-c-lineup-arglist (langelem)
1522   "Hack for DWIMmery in c-lineup-arglist."
1523   (if (save-excursion
1524         (c-block-in-arglist-dwim (c-langelem-2nd-pos c-syntactic-element)))
1525       0
1526     (c-lineup-arglist langelem)))
1527
1528 (defun mdw-c-indent-extern-mumble (langelem)
1529   "Indent `extern \"...\" {' lines."
1530   (save-excursion
1531     (back-to-indentation)
1532     (if (looking-at
1533          "\\s-*\\<extern\\>\\s-*\"\\([^\\\\\"]+\\|\\.\\)*\"\\s-*{")
1534         c-basic-offset
1535       nil)))
1536
1537 (defun mdw-c-indent-arglist-nested (langelem)
1538   "Indent continued argument lists.
1539 If we've nested more than one argument list, then only introduce a single
1540 indentation anyway."
1541   (let ((context c-syntactic-context)
1542         (pos (c-langelem-2nd-pos c-syntactic-element))
1543         (should-indent-p t))
1544     (while (and context
1545                 (eq (caar context) 'arglist-cont-nonempty))
1546       (when (and (= (caddr (pop context)) pos)
1547                  context
1548                  (memq (caar context) '(arglist-intro
1549                                         arglist-cont-nonempty)))
1550         (setq should-indent-p nil)))
1551     (if should-indent-p '+ 0)))
1552
1553 (defvar mdw-define-c-styles-hook nil
1554   "Hook run when `cc-mode' starts up to define styles.")
1555
1556 (defmacro mdw-define-c-style (name &rest assocs)
1557   "Define a C style, called NAME (a symbol), setting ASSOCs.
1558 A function, named `mdw-define-c-style/NAME', is defined to actually install
1559 the style using `c-add-style', and added to the hook
1560 `mdw-define-c-styles-hook'.  If CC Mode is already loaded, then the style is
1561 set."
1562   (declare (indent defun))
1563   (let* ((name-string (symbol-name name))
1564          (func (intern (concat "mdw-define-c-style/" name-string))))
1565     `(progn
1566        (defun ,func () (c-add-style ,name-string ',assocs))
1567        (and (featurep 'cc-mode) (,func))
1568        (add-hook 'mdw-define-c-styles-hook ',func))))
1569
1570 (eval-after-load "cc-mode"
1571   '(run-hooks 'mdw-define-c-styles-hook))
1572
1573 (mdw-define-c-style mdw-trustonic-c
1574   (c-basic-offset . 4)
1575   (comment-column . 0)
1576   (c-indent-comment-alist (anchored-comment . (column . 0))
1577                           (end-block . (space . 1))
1578                           (cpp-end-block . (space . 1))
1579                           (other . (space . 1)))
1580   (c-class-key . "class")
1581   (c-backslash-column . 0)
1582   (c-auto-align-backslashes . nil)
1583   (c-label-minimum-indentation . 0)
1584   (c-offsets-alist (substatement-open . (add 0 c-indent-one-line-block))
1585                    (defun-open . (add 0 c-indent-one-line-block))
1586                    (arglist-cont-nonempty . mdw-c-indent-arglist-nested)
1587                    (topmost-intro . mdw-c-indent-extern-mumble)
1588                    (cpp-define-intro . 0)
1589                    (knr-argdecl . 0)
1590                    (inextern-lang . [0])
1591                    (label . 0)
1592                    (case-label . +)
1593                    (access-label . -2)
1594                    (inclass . +)
1595                    (inline-open . ++)
1596                    (statement-cont . +)
1597                    (statement-case-intro . +)))
1598
1599 (mdw-define-c-style mdw-c
1600   (c-basic-offset . 2)
1601   (comment-column . 40)
1602   (c-class-key . "class")
1603   (c-backslash-column . 72)
1604   (c-label-minimum-indentation . 0)
1605   (c-offsets-alist (substatement-open . (add 0 c-indent-one-line-block))
1606                    (defun-open . (add 0 c-indent-one-line-block))
1607                    (arglist-cont-nonempty . mdw-c-lineup-arglist)
1608                    (topmost-intro . mdw-c-indent-extern-mumble)
1609                    (cpp-define-intro . 0)
1610                    (knr-argdecl . 0)
1611                    (inextern-lang . [0])
1612                    (label . 0)
1613                    (case-label . +)
1614                    (access-label . -)
1615                    (inclass . +)
1616                    (inline-open . ++)
1617                    (statement-cont . +)
1618                    (statement-case-intro . +)))
1619
1620 (defun mdw-set-default-c-style (modes style)
1621   "Update the default CC Mode style for MODES to be STYLE.
1622
1623 MODES may be a list of major mode names or a singleton.  STYLE is a style
1624 name, as a symbol."
1625   (let ((modes (if (listp modes) modes (list modes)))
1626         (style (symbol-name style)))
1627     (setq c-default-style
1628           (append (mapcar (lambda (mode)
1629                             (cons mode style))
1630                           modes)
1631                   (remove-if (lambda (assoc)
1632                                (memq (car assoc) modes))
1633                              (if (listp c-default-style)
1634                                  c-default-style
1635                                (list (cons 'other c-default-style))))))))
1636 (setq c-default-style "mdw-c")
1637
1638 (mdw-set-default-c-style '(c-mode c++-mode) 'mdw-c)
1639
1640 (defvar mdw-c-comment-fill-prefix
1641   `((,(concat "\\([ \t]*/?\\)"
1642               "\\(\*\\|//]\\)"
1643               "\\([ \t]*\\)"
1644               "\\([A-Za-z]+:[ \t]*\\)?"
1645               mdw-hanging-indents)
1646      (pad . 1) (match . 2) (pad . 3) (pad . 4) (pad . 5)))
1647   "Fill prefix matching C comments (both kinds).")
1648
1649 (defun mdw-fontify-c-and-c++ ()
1650
1651   ;; Fiddle with some syntax codes.
1652   (modify-syntax-entry ?* ". 23")
1653   (modify-syntax-entry ?/ ". 124b")
1654   (modify-syntax-entry ?\n "> b")
1655
1656   ;; Other stuff.
1657   (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
1658
1659   ;; Now define things to be fontified.
1660   (make-local-variable 'font-lock-keywords)
1661   (let ((c-keywords
1662          (mdw-regexps "alignas"          ;C11 macro, C++11
1663                       "alignof"          ;C++11
1664                       "and"              ;C++, C95 macro
1665                       "and_eq"           ;C++, C95 macro
1666                       "asm"              ;K&R, C++, GCC
1667                       "atomic"           ;C11 macro, C++11 template type
1668                       "auto"             ;K&R, C89
1669                       "bitand"           ;C++, C95 macro
1670                       "bitor"            ;C++, C95 macro
1671                       "bool"             ;C++, C99 macro
1672                       "break"            ;K&R, C89
1673                       "case"             ;K&R, C89
1674                       "catch"            ;C++
1675                       "char"             ;K&R, C89
1676                       "char16_t"         ;C++11, C11 library type
1677                       "char32_t"         ;C++11, C11 library type
1678                       "class"            ;C++
1679                       "complex"          ;C99 macro, C++ template type
1680                       "compl"            ;C++, C95 macro
1681                       "const"            ;C89
1682                       "constexpr"        ;C++11
1683                       "const_cast"       ;C++
1684                       "continue"         ;K&R, C89
1685                       "decltype"         ;C++11
1686                       "defined"          ;C89 preprocessor
1687                       "default"          ;K&R, C89
1688                       "delete"           ;C++
1689                       "do"               ;K&R, C89
1690                       "double"           ;K&R, C89
1691                       "dynamic_cast"     ;C++
1692                       "else"             ;K&R, C89
1693                       ;; "entry"         ;K&R -- never used
1694                       "enum"             ;C89
1695                       "explicit"         ;C++
1696                       "export"           ;C++
1697                       "extern"           ;K&R, C89
1698                       "float"            ;K&R, C89
1699                       "for"              ;K&R, C89
1700                       ;; "fortran"       ;K&R
1701                       "friend"           ;C++
1702                       "goto"             ;K&R, C89
1703                       "if"               ;K&R, C89
1704                       "imaginary"        ;C99 macro
1705                       "inline"           ;C++, C99, GCC
1706                       "int"              ;K&R, C89
1707                       "long"             ;K&R, C89
1708                       "mutable"          ;C++
1709                       "namespace"        ;C++
1710                       "new"              ;C++
1711                       "noexcept"         ;C++11
1712                       "noreturn"         ;C11 macro
1713                       "not"              ;C++, C95 macro
1714                       "not_eq"           ;C++, C95 macro
1715                       "nullptr"          ;C++11
1716                       "operator"         ;C++
1717                       "or"               ;C++, C95 macro
1718                       "or_eq"            ;C++, C95 macro
1719                       "private"          ;C++
1720                       "protected"        ;C++
1721                       "public"           ;C++
1722                       "register"         ;K&R, C89
1723                       "reinterpret_cast" ;C++
1724                       "restrict"         ;C99
1725                       "return"           ;K&R, C89
1726                       "short"            ;K&R, C89
1727                       "signed"           ;C89
1728                       "sizeof"           ;K&R, C89
1729                       "static"           ;K&R, C89
1730                       "static_assert"    ;C11 macro, C++11
1731                       "static_cast"      ;C++
1732                       "struct"           ;K&R, C89
1733                       "switch"           ;K&R, C89
1734                       "template"         ;C++
1735                       "throw"            ;C++
1736                       "try"              ;C++
1737                       "thread_local"     ;C11 macro, C++11
1738                       "typedef"          ;C89
1739                       "typeid"           ;C++
1740                       "typeof"           ;GCC
1741                       "typename"         ;C++
1742                       "union"            ;K&R, C89
1743                       "unsigned"         ;K&R, C89
1744                       "using"            ;C++
1745                       "virtual"          ;C++
1746                       "void"             ;C89
1747                       "volatile"         ;C89
1748                       "wchar_t"          ;C++, C89 library type
1749                       "while"            ;K&R, C89
1750                       "xor"              ;C++, C95 macro
1751                       "xor_eq"           ;C++, C95 macro
1752                       "_Alignas"         ;C11
1753                       "_Alignof"         ;C11
1754                       "_Atomic"          ;C11
1755                       "_Bool"            ;C99
1756                       "_Complex"         ;C99
1757                       "_Generic"         ;C11
1758                       "_Imaginary"       ;C99
1759                       "_Noreturn"        ;C11
1760                       "_Pragma"          ;C99 preprocessor
1761                       "_Static_assert"   ;C11
1762                       "_Thread_local"    ;C11
1763                       "__alignof__"      ;GCC
1764                       "__asm__"          ;GCC
1765                       "__attribute__"    ;GCC
1766                       "__complex__"      ;GCC
1767                       "__const__"        ;GCC
1768                       "__extension__"    ;GCC
1769                       "__imag__"         ;GCC
1770                       "__inline__"       ;GCC
1771                       "__label__"        ;GCC
1772                       "__real__"         ;GCC
1773                       "__signed__"       ;GCC
1774                       "__typeof__"       ;GCC
1775                       "__volatile__"     ;GCC
1776                       ))
1777         (c-constants
1778          (mdw-regexps "false"            ;C++, C99 macro
1779                       "this"             ;C++
1780                       "true"             ;C++, C99 macro
1781                       ))
1782         (preprocessor-keywords
1783          (mdw-regexps "assert" "define" "elif" "else" "endif" "error"
1784                       "ident" "if" "ifdef" "ifndef" "import" "include"
1785                       "line" "pragma" "unassert" "undef" "warning"))
1786         (objc-keywords
1787          (mdw-regexps "class" "defs" "encode" "end" "implementation"
1788                       "interface" "private" "protected" "protocol" "public"
1789                       "selector")))
1790
1791     (setq font-lock-keywords
1792           (list
1793
1794            ;; Fontify include files as strings.
1795            (list (concat "^[ \t]*\\#[ \t]*"
1796                          "\\(include\\|import\\)"
1797                          "[ \t]*\\(<[^>]+\\(>\\|\\)\\)")
1798                  '(2 font-lock-string-face))
1799
1800            ;; Preprocessor directives are `references'?.
1801            (list (concat "^\\([ \t]*#[ \t]*\\(\\("
1802                          preprocessor-keywords
1803                          "\\)\\>\\|[0-9]+\\|$\\)\\)")
1804                  '(1 font-lock-keyword-face))
1805
1806            ;; Handle the keywords defined above.
1807            (list (concat "@\\<\\(" objc-keywords "\\)\\>")
1808                  '(0 font-lock-keyword-face))
1809
1810            (list (concat "\\<\\(" c-keywords "\\)\\>")
1811                  '(0 font-lock-keyword-face))
1812
1813            (list (concat "\\<\\(" c-constants "\\)\\>")
1814                  '(0 font-lock-variable-name-face))
1815
1816            ;; Handle numbers too.
1817            ;;
1818            ;; This looks strange, I know.  It corresponds to the
1819            ;; preprocessor's idea of what a number looks like, rather than
1820            ;; anything sensible.
1821            (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
1822                          "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
1823                  '(0 mdw-number-face))
1824
1825            ;; And anything else is punctuation.
1826            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1827                  '(0 mdw-punct-face))))))
1828
1829 ;;;--------------------------------------------------------------------------
1830 ;;; AP calc mode.
1831
1832 (define-derived-mode apcalc-mode c-mode "AP Calc"
1833   "Major mode for editing Calc code.")
1834
1835 (defun mdw-fontify-apcalc ()
1836
1837   ;; Fiddle with some syntax codes.
1838   (modify-syntax-entry ?* ". 23")
1839   (modify-syntax-entry ?/ ". 14")
1840
1841   ;; Other stuff.
1842   (setq comment-start "/* ")
1843   (setq comment-end " */")
1844   (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
1845
1846   ;; Now define things to be fontified.
1847   (make-local-variable 'font-lock-keywords)
1848   (let ((c-keywords
1849          (mdw-regexps "break" "case" "cd" "continue" "define" "default"
1850                       "do" "else" "exit" "for" "global" "goto" "help" "if"
1851                       "local" "mat" "obj" "print" "quit" "read" "return"
1852                       "show" "static" "switch" "while" "write")))
1853
1854     (setq font-lock-keywords
1855           (list
1856
1857            ;; Handle the keywords defined above.
1858            (list (concat "\\<\\(" c-keywords "\\)\\>")
1859                  '(0 font-lock-keyword-face))
1860
1861            ;; Handle numbers too.
1862            ;;
1863            ;; This looks strange, I know.  It corresponds to the
1864            ;; preprocessor's idea of what a number looks like, rather than
1865            ;; anything sensible.
1866            (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
1867                          "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
1868                  '(0 mdw-number-face))
1869
1870            ;; And anything else is punctuation.
1871            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1872                  '(0 mdw-punct-face))))))
1873
1874 ;;;--------------------------------------------------------------------------
1875 ;;; Java programming configuration.
1876
1877 ;; Make indentation nice.
1878
1879 (mdw-define-c-style mdw-java
1880   (c-basic-offset . 2)
1881   (c-backslash-column . 72)
1882   (c-offsets-alist (substatement-open . 0)
1883                    (label . +)
1884                    (case-label . +)
1885                    (access-label . 0)
1886                    (inclass . +)
1887                    (statement-case-intro . +)))
1888 (mdw-set-default-c-style 'java-mode 'mdw-java)
1889
1890 ;; Declare Java fontification style.
1891
1892 (defun mdw-fontify-java ()
1893
1894   ;; Other stuff.
1895   (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
1896
1897   ;; Now define things to be fontified.
1898   (make-local-variable 'font-lock-keywords)
1899   (let ((java-keywords
1900          (mdw-regexps "abstract" "boolean" "break" "byte" "case" "catch"
1901                       "char" "class" "const" "continue" "default" "do"
1902                       "double" "else" "extends" "final" "finally" "float"
1903                       "for" "goto" "if" "implements" "import" "instanceof"
1904                       "int" "interface" "long" "native" "new" "package"
1905                       "private" "protected" "public" "return" "short"
1906                       "static" "switch" "synchronized" "throw" "throws"
1907                       "transient" "try" "void" "volatile" "while"))
1908
1909         (java-constants
1910          (mdw-regexps "false" "null" "super" "this" "true")))
1911
1912     (setq font-lock-keywords
1913           (list
1914
1915            ;; Handle the keywords defined above.
1916            (list (concat "\\<\\(" java-keywords "\\)\\>")
1917                  '(0 font-lock-keyword-face))
1918
1919            ;; Handle the magic constants defined above.
1920            (list (concat "\\<\\(" java-constants "\\)\\>")
1921                  '(0 font-lock-variable-name-face))
1922
1923            ;; Handle numbers too.
1924            ;;
1925            ;; The following isn't quite right, but it's close enough.
1926            (list (concat "\\<\\("
1927                          "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1928                          "[0-9]+\\(\\.[0-9]*\\|\\)"
1929                          "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
1930                          "[lLfFdD]?")
1931                  '(0 mdw-number-face))
1932
1933            ;; And anything else is punctuation.
1934            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1935                  '(0 mdw-punct-face))))))
1936
1937 ;;;--------------------------------------------------------------------------
1938 ;;; Javascript programming configuration.
1939
1940 (defun mdw-javascript-style ()
1941   (setq js-indent-level 2)
1942   (setq js-expr-indent-offset 0))
1943
1944 (defun mdw-fontify-javascript ()
1945
1946   ;; Other stuff.
1947   (mdw-javascript-style)
1948   (setq js-auto-indent-flag t)
1949
1950   ;; Now define things to be fontified.
1951   (make-local-variable 'font-lock-keywords)
1952   (let ((javascript-keywords
1953          (mdw-regexps "abstract" "boolean" "break" "byte" "case" "catch"
1954                       "char" "class" "const" "continue" "debugger" "default"
1955                       "delete" "do" "double" "else" "enum" "export" "extends"
1956                       "final" "finally" "float" "for" "function" "goto" "if"
1957                       "implements" "import" "in" "instanceof" "int"
1958                       "interface" "let" "long" "native" "new" "package"
1959                       "private" "protected" "public" "return" "short"
1960                       "static" "super" "switch" "synchronized" "throw"
1961                       "throws" "transient" "try" "typeof" "var" "void"
1962                       "volatile" "while" "with" "yield"
1963
1964                       "boolean" "byte" "char" "double" "float" "int" "long"
1965                       "short" "void"))
1966         (javascript-constants
1967          (mdw-regexps "false" "null" "undefined" "Infinity" "NaN" "true"
1968                       "arguments" "this")))
1969
1970     (setq font-lock-keywords
1971           (list
1972
1973            ;; Handle the keywords defined above.
1974            (list (concat "\\_<\\(" javascript-keywords "\\)\\_>")
1975                  '(0 font-lock-keyword-face))
1976
1977            ;; Handle the predefined constants defined above.
1978            (list (concat "\\_<\\(" javascript-constants "\\)\\_>")
1979                  '(0 font-lock-variable-name-face))
1980
1981            ;; Handle numbers too.
1982            ;;
1983            ;; The following isn't quite right, but it's close enough.
1984            (list (concat "\\_<\\("
1985                          "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1986                          "[0-9]+\\(\\.[0-9]*\\|\\)"
1987                          "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
1988                          "[lLfFdD]?")
1989                  '(0 mdw-number-face))
1990
1991            ;; And anything else is punctuation.
1992            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1993                  '(0 mdw-punct-face))))))
1994
1995 ;;;--------------------------------------------------------------------------
1996 ;;; Scala programming configuration.
1997
1998 (defun mdw-fontify-scala ()
1999
2000   ;; Comment filling.
2001   (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
2002
2003   ;; Define things to be fontified.
2004   (make-local-variable 'font-lock-keywords)
2005   (let ((scala-keywords
2006          (mdw-regexps "abstract" "case" "catch" "class" "def" "do" "else"
2007                       "extends" "final" "finally" "for" "forSome" "if"
2008                       "implicit" "import" "lazy" "match" "new" "object"
2009                       "override" "package" "private" "protected" "return"
2010                       "sealed" "throw" "trait" "try" "type" "val"
2011                       "var" "while" "with" "yield"))
2012         (scala-constants
2013          (mdw-regexps "false" "null" "super" "this" "true"))
2014         (punctuation "[-!%^&*=+:@#~/?\\|`]"))
2015
2016     (setq font-lock-keywords
2017           (list
2018
2019            ;; Magical identifiers between backticks.
2020            (list (concat "`\\([^`]+\\)`")
2021                  '(1 font-lock-variable-name-face))
2022
2023            ;; Handle the keywords defined above.
2024            (list (concat "\\_<\\(" scala-keywords "\\)\\_>")
2025                  '(0 font-lock-keyword-face))
2026
2027            ;; Handle the constants defined above.
2028            (list (concat "\\_<\\(" scala-constants "\\)\\_>")
2029                  '(0 font-lock-variable-name-face))
2030
2031            ;; Magical identifiers between backticks.
2032            (list (concat "`\\([^`]+\\)`")
2033                  '(1 font-lock-variable-name-face))
2034
2035            ;; Handle numbers too.
2036            ;;
2037            ;; As usual, not quite right.
2038            (list (concat "\\_<\\("
2039                          "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
2040                          "[0-9]+\\(\\.[0-9]*\\|\\)"
2041                          "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
2042                          "[lLfFdD]?")
2043                  '(0 mdw-number-face))
2044
2045            ;; Identifiers with trailing operators.
2046            (list (concat "_\\(" punctuation "\\)+")
2047                  '(0 mdw-trivial-face))
2048
2049            ;; And everything else is punctuation.
2050            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2051                  '(0 mdw-punct-face)))
2052
2053           font-lock-syntactic-keywords
2054           (list
2055
2056            ;; Single quotes around characters.  But not when used to quote
2057            ;; symbol names.  Ugh.
2058            (list (concat "\\('\\)"
2059                          "\\(" "."
2060                          "\\|" "\\\\" "\\(" "\\\\\\\\" "\\)*"
2061                                "u+" "[0-9a-fA-F]\\{4\\}"
2062                          "\\|" "\\\\" "[0-7]\\{1,3\\}"
2063                          "\\|" "\\\\" "." "\\)"
2064                          "\\('\\)")
2065                  '(1 "\"")
2066                  '(4 "\""))))))
2067
2068 ;;;--------------------------------------------------------------------------
2069 ;;; C# programming configuration.
2070
2071 ;; Make indentation nice.
2072
2073 (mdw-define-c-style mdw-csharp
2074   (c-basic-offset . 2)
2075   (c-backslash-column . 72)
2076   (c-offsets-alist (substatement-open . 0)
2077                    (label . 0)
2078                    (case-label . +)
2079                    (access-label . 0)
2080                    (inclass . +)
2081                    (statement-case-intro . +)))
2082 (mdw-set-default-c-style 'csharp-mode 'mdw-csharp)
2083
2084 ;; Declare C# fontification style.
2085
2086 (defun mdw-fontify-csharp ()
2087
2088   ;; Other stuff.
2089   (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
2090
2091   ;; Now define things to be fontified.
2092   (make-local-variable 'font-lock-keywords)
2093   (let ((csharp-keywords
2094          (mdw-regexps "abstract" "as" "bool" "break" "byte" "case" "catch"
2095                       "char" "checked" "class" "const" "continue" "decimal"
2096                       "default" "delegate" "do" "double" "else" "enum"
2097                       "event" "explicit" "extern" "finally" "fixed" "float"
2098                       "for" "foreach" "goto" "if" "implicit" "in" "int"
2099                       "interface" "internal" "is" "lock" "long" "namespace"
2100                       "new" "object" "operator" "out" "override" "params"
2101                       "private" "protected" "public" "readonly" "ref"
2102                       "return" "sbyte" "sealed" "short" "sizeof"
2103                       "stackalloc" "static" "string" "struct" "switch"
2104                       "throw" "try" "typeof" "uint" "ulong" "unchecked"
2105                       "unsafe" "ushort" "using" "virtual" "void" "volatile"
2106                       "while" "yield"))
2107
2108         (csharp-constants
2109          (mdw-regexps "base" "false" "null" "this" "true")))
2110
2111     (setq font-lock-keywords
2112           (list
2113
2114            ;; Handle the keywords defined above.
2115            (list (concat "\\<\\(" csharp-keywords "\\)\\>")
2116                  '(0 font-lock-keyword-face))
2117
2118            ;; Handle the magic constants defined above.
2119            (list (concat "\\<\\(" csharp-constants "\\)\\>")
2120                  '(0 font-lock-variable-name-face))
2121
2122            ;; Handle numbers too.
2123            ;;
2124            ;; The following isn't quite right, but it's close enough.
2125            (list (concat "\\<\\("
2126                          "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
2127                          "[0-9]+\\(\\.[0-9]*\\|\\)"
2128                          "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
2129                          "[lLfFdD]?")
2130                  '(0 mdw-number-face))
2131
2132            ;; And anything else is punctuation.
2133            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2134                  '(0 mdw-punct-face))))))
2135
2136 (define-derived-mode csharp-mode java-mode "C#"
2137   "Major mode for editing C# code.")
2138
2139 ;;;--------------------------------------------------------------------------
2140 ;;; F# programming configuration.
2141
2142 (setq fsharp-indent-offset 2)
2143
2144 (defun mdw-fontify-fsharp ()
2145
2146   (let ((punct "=<>+-*/|&%!@?"))
2147     (do ((i 0 (1+ i)))
2148         ((>= i (length punct)))
2149       (modify-syntax-entry (aref punct i) ".")))
2150
2151   (modify-syntax-entry ?_ "_")
2152   (modify-syntax-entry ?( "(")
2153   (modify-syntax-entry ?) ")")
2154
2155   (setq indent-tabs-mode nil)
2156
2157   (let ((fsharp-keywords
2158          (mdw-regexps "abstract" "and" "as" "assert" "atomic"
2159                       "begin" "break"
2160                       "checked" "class" "component" "const" "constraint"
2161                       "constructor" "continue"
2162                       "default" "delegate" "do" "done" "downcast" "downto"
2163                       "eager" "elif" "else" "end" "exception" "extern"
2164                       "finally" "fixed" "for" "fori" "fun" "function"
2165                       "functor"
2166                       "global"
2167                       "if" "in" "include" "inherit" "inline" "interface"
2168                       "internal"
2169                       "lazy" "let"
2170                       "match" "measure" "member" "method" "mixin" "module"
2171                       "mutable"
2172                       "namespace" "new"
2173                       "object" "of" "open" "or" "override"
2174                       "parallel" "params" "private" "process" "protected"
2175                       "public" "pure"
2176                       "rec" "recursive" "return"
2177                       "sealed" "sig" "static" "struct"
2178                       "tailcall" "then" "to" "trait" "try" "type"
2179                       "upcast" "use"
2180                       "val" "virtual" "void" "volatile"
2181                       "when" "while" "with"
2182                       "yield"))
2183
2184         (fsharp-builtins
2185          (mdw-regexps "asr" "land" "lor" "lsl" "lsr" "lxor" "mod"
2186                       "base" "false" "null" "true"))
2187
2188         (bang-keywords
2189          (mdw-regexps "do" "let" "return" "use" "yield"))
2190
2191         (preprocessor-keywords
2192          (mdw-regexps "if" "indent" "else" "endif")))
2193
2194     (setq font-lock-keywords
2195           (list (list (concat "\\(^\\|[^\"]\\)"
2196                               "\\(" "(\\*"
2197                                     "[^*]*\\*+"
2198                                     "\\(" "[^)*]" "[^*]*" "\\*+" "\\)*"
2199                                     ")"
2200                               "\\|"
2201                                     "//.*"
2202                               "\\)")
2203                       '(2 font-lock-comment-face))
2204
2205                 (list (concat "'" "\\("
2206                                     "\\\\"
2207                                     "\\(" "[ntbr'\\]"
2208                                     "\\|" "[0-9][0-9][0-9]"
2209                                     "\\|" "u" "[0-9a-fA-F]\\{4\\}"
2210                                     "\\|" "U" "[0-9a-fA-F]\\{8\\}"
2211                                     "\\)"
2212                                   "\\|"
2213                                   "." "\\)" "'"
2214                               "\\|"
2215                               "\"" "[^\"\\]*"
2216                                     "\\(" "\\\\" "\\(.\\|\n\\)"
2217                                           "[^\"\\]*" "\\)*"
2218                               "\\(\"\\|\\'\\)")
2219                       '(0 font-lock-string-face))
2220
2221                 (list (concat "\\_<\\(" bang-keywords "\\)!" "\\|"
2222                               "^#[ \t]*\\(" preprocessor-keywords "\\)\\_>"
2223                               "\\|"
2224                               "\\_<\\(" fsharp-keywords "\\)\\_>")
2225                       '(0 font-lock-keyword-face))
2226                 (list (concat "\\<\\(" fsharp-builtins "\\)\\_>")
2227                       '(0 font-lock-variable-name-face))
2228
2229                 (list (concat "\\_<"
2230                               "\\(" "0[bB][01]+" "\\|"
2231                                     "0[oO][0-7]+" "\\|"
2232                                     "0[xX][0-9a-fA-F]+" "\\)"
2233                               "\\(" "lf\\|LF" "\\|"
2234                                     "[uU]?[ysnlL]?" "\\)"
2235                               "\\|"
2236                               "\\_<"
2237                               "[0-9]+" "\\("
2238                                 "[mMQRZING]"
2239                                 "\\|"
2240                                 "\\(\\.[0-9]*\\)?"
2241                                 "\\([eE][-+]?[0-9]+\\)?"
2242                                 "[fFmM]?"
2243                                 "\\|"
2244                                 "[uU]?[ysnlL]?"
2245                               "\\)")
2246                       '(0 mdw-number-face))
2247
2248                 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2249                       '(0 mdw-punct-face))))))
2250
2251 (defun mdw-fontify-inferior-fsharp ()
2252   (mdw-fontify-fsharp)
2253   (setq font-lock-keywords
2254         (append (list (list "^[#-]" '(0 font-lock-comment-face))
2255                       (list "^>" '(0 font-lock-keyword-face)))
2256                 font-lock-keywords)))
2257
2258 ;;;--------------------------------------------------------------------------
2259 ;;; Go programming configuration.
2260
2261 (defun mdw-fontify-go ()
2262
2263   (make-local-variable 'font-lock-keywords)
2264   (let ((go-keywords
2265          (mdw-regexps "break" "case" "chan" "const" "continue"
2266                       "default" "defer" "else" "fallthrough" "for"
2267                       "func" "go" "goto" "if" "import"
2268                       "interface" "map" "package" "range" "return"
2269                       "select" "struct" "switch" "type" "var"))
2270         (go-intrinsics
2271          (mdw-regexps "bool" "byte" "complex64" "complex128" "error"
2272                       "float32" "float64" "int" "uint8" "int16" "int32"
2273                       "int64" "rune" "string" "uint" "uint8" "uint16"
2274                       "uint32" "uint64" "uintptr" "void"
2275                       "false" "iota" "nil" "true"
2276                       "init" "main"
2277                       "append" "cap" "copy" "delete" "imag" "len" "make"
2278                       "new" "panic" "real" "recover")))
2279
2280     (setq font-lock-keywords
2281           (list
2282
2283            ;; Handle the keywords defined above.
2284            (list (concat "\\<\\(" go-keywords "\\)\\>")
2285                  '(0 font-lock-keyword-face))
2286            (list (concat "\\<\\(" go-intrinsics "\\)\\>")
2287                  '(0 font-lock-variable-name-face))
2288
2289            ;; Strings and characters.
2290            (list (concat "'"
2291                          "\\(" "[^\\']" "\\|"
2292                                "\\\\"
2293                                "\\(" "[abfnrtv\\'\"]" "\\|"
2294                                      "[0-7]\\{3\\}" "\\|"
2295                                      "x" "[0-9A-Fa-f]\\{2\\}" "\\|"
2296                                      "u" "[0-9A-Fa-f]\\{4\\}" "\\|"
2297                                      "U" "[0-9A-Fa-f]\\{8\\}" "\\)" "\\)"
2298                          "'"
2299                          "\\|"
2300                          "\""
2301                          "\\(" "[^\n\\\"]+" "\\|" "\\\\." "\\)*"
2302                          "\\(\"\\|$\\)"
2303                          "\\|"
2304                          "`" "[^`]+" "`")
2305                  '(0 font-lock-string-face))
2306
2307            ;; Handle numbers too.
2308            ;;
2309            ;; The following isn't quite right, but it's close enough.
2310            (list (concat "\\<\\("
2311                          "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
2312                          "[0-9]+\\(\\.[0-9]*\\|\\)"
2313                          "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)")
2314                  '(0 mdw-number-face))
2315
2316            ;; And anything else is punctuation.
2317            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2318                  '(0 mdw-punct-face))))))
2319
2320 ;;;--------------------------------------------------------------------------
2321 ;;; Rust programming configuration.
2322
2323 (setq-default rust-indent-offset 2)
2324
2325 (defun mdw-self-insert-and-indent (count)
2326   (interactive "p")
2327   (self-insert-command count)
2328   (indent-according-to-mode))
2329
2330 (defun mdw-fontify-rust ()
2331
2332   ;; Hack syntax categories.
2333   (modify-syntax-entry ?= ".")
2334
2335   ;; Fontify keywords and things.
2336   (make-local-variable 'font-lock-keywords)
2337   (let ((rust-keywords
2338          (mdw-regexps "abstract" "alignof" "as"
2339                       "become" "box" "break"
2340                       "const" "continue" "create"
2341                       "do"
2342                       "else" "enum" "extern"
2343                       "false" "final" "fn" "for"
2344                       "if" "impl" "in"
2345                       "let" "loop"
2346                       "macro" "match" "mod" "move" "mut"
2347                       "offsetof" "override"
2348                       "priv" "pub" "pure"
2349                       "ref" "return"
2350                       "self" "sizeof" "static" "struct" "super"
2351                       "true" "trait" "type" "typeof"
2352                       "unsafe" "unsized" "use"
2353                       "virtual"
2354                       "where" "while"
2355                       "yield"))
2356         (rust-builtins
2357          (mdw-regexps "array" "pointer" "slice" "tuple"
2358                       "bool" "true" "false"
2359                       "f32" "f64"
2360                       "i8" "i16" "i32" "i64" "isize"
2361                       "u8" "u16" "u32" "u64" "usize"
2362                       "char" "str")))
2363     (setq font-lock-keywords
2364           (list
2365
2366            ;; Handle the keywords defined above.
2367            (list (concat "\\<\\(" rust-keywords "\\)\\>")
2368                  '(0 font-lock-keyword-face))
2369            (list (concat "\\<\\(" rust-builtins "\\)\\>")
2370                  '(0 font-lock-variable-name-face))
2371
2372            ;; Handle numbers too.
2373            (list (concat "\\<\\("
2374                                "[0-9][0-9_]*"
2375                                "\\(" "\\(\\.[0-9_]+\\)?[eE][-+]?[0-9_]+"
2376                                "\\|" "\\.[0-9_]+"
2377                                "\\)"
2378                                "\\(f32\\|f64\\)?"
2379                          "\\|" "\\(" "[0-9][0-9_]*"
2380                                "\\|" "0x[0-9a-fA-F_]+"
2381                                "\\|" "0o[0-7_]+"
2382                                "\\|" "0b[01_]+"
2383                                "\\)"
2384                                "\\([ui]\\(8\\|16\\|32\\|64\\|s\\|size\\)\\)?"
2385                          "\\)\\>")
2386                  '(0 mdw-number-face))
2387
2388            ;; And anything else is punctuation.
2389            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2390                  '(0 mdw-punct-face)))))
2391
2392   ;; Hack key bindings.
2393   (local-set-key [?{] 'mdw-self-insert-and-indent)
2394   (local-set-key [?}] 'mdw-self-insert-and-indent))
2395
2396 ;;;--------------------------------------------------------------------------
2397 ;;; Awk programming configuration.
2398
2399 ;; Make Awk indentation nice.
2400
2401 (mdw-define-c-style mdw-awk
2402   (c-basic-offset . 2)
2403   (c-offsets-alist (substatement-open . 0)
2404                    (c-backslash-column . 72)
2405                    (statement-cont . 0)
2406                    (statement-case-intro . +)))
2407 (mdw-set-default-c-style 'awk-mode 'mdw-awk)
2408
2409 ;; Declare Awk fontification style.
2410
2411 (defun mdw-fontify-awk ()
2412
2413   ;; Miscellaneous fiddling.
2414   (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
2415
2416   ;; Now define things to be fontified.
2417   (make-local-variable 'font-lock-keywords)
2418   (let ((c-keywords
2419          (mdw-regexps "BEGIN" "END" "ARGC" "ARGIND" "ARGV" "CONVFMT"
2420                       "ENVIRON" "ERRNO" "FIELDWIDTHS" "FILENAME" "FNR"
2421                       "FS" "IGNORECASE" "NF" "NR" "OFMT" "OFS" "ORS" "RS"
2422                       "RSTART" "RLENGTH" "RT"   "SUBSEP"
2423                       "atan2" "break" "close" "continue" "cos" "delete"
2424                       "do" "else" "exit" "exp" "fflush" "file" "for" "func"
2425                       "function" "gensub" "getline" "gsub" "if" "in"
2426                       "index" "int" "length" "log" "match" "next" "rand"
2427                       "return" "print" "printf" "sin" "split" "sprintf"
2428                       "sqrt" "srand" "strftime" "sub" "substr" "system"
2429                       "systime" "tolower" "toupper" "while")))
2430
2431     (setq font-lock-keywords
2432           (list
2433
2434            ;; Handle the keywords defined above.
2435            (list (concat "\\<\\(" c-keywords "\\)\\>")
2436                  '(0 font-lock-keyword-face))
2437
2438            ;; Handle numbers too.
2439            ;;
2440            ;; The following isn't quite right, but it's close enough.
2441            (list (concat "\\<\\("
2442                          "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
2443                          "[0-9]+\\(\\.[0-9]*\\|\\)"
2444                          "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
2445                          "[uUlL]*")
2446                  '(0 mdw-number-face))
2447
2448            ;; And anything else is punctuation.
2449            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2450                  '(0 mdw-punct-face))))))
2451
2452 ;;;--------------------------------------------------------------------------
2453 ;;; Perl programming style.
2454
2455 ;; Perl indentation style.
2456
2457 (setq perl-indent-level 2)
2458
2459 (setq cperl-indent-level 2)
2460 (setq cperl-continued-statement-offset 2)
2461 (setq cperl-continued-brace-offset 0)
2462 (setq cperl-brace-offset -2)
2463 (setq cperl-brace-imaginary-offset 0)
2464 (setq cperl-label-offset 0)
2465
2466 ;; Define perl fontification style.
2467
2468 (defun mdw-fontify-perl ()
2469
2470   ;; Miscellaneous fiddling.
2471   (modify-syntax-entry ?$ "\\")
2472   (modify-syntax-entry ?$ "\\" font-lock-syntax-table)
2473   (modify-syntax-entry ?: "." font-lock-syntax-table)
2474   (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
2475
2476   ;; Now define fontification things.
2477   (make-local-variable 'font-lock-keywords)
2478   (let ((perl-keywords
2479          (mdw-regexps "and"
2480                       "break"
2481                       "cmp" "continue"
2482                       "default" "do"
2483                       "else" "elsif" "eq"
2484                       "for" "foreach"
2485                       "ge" "given" "gt" "goto"
2486                       "if"
2487                       "last" "le" "local" "lt"
2488                       "my"
2489                       "ne" "next"
2490                       "or" "our"
2491                       "package"
2492                       "redo" "require" "return"
2493                       "sub"
2494                       "undef" "unless" "until" "use"
2495                       "when" "while")))
2496
2497     (setq font-lock-keywords
2498           (list
2499
2500            ;; Set up the keywords defined above.
2501            (list (concat "\\<\\(" perl-keywords "\\)\\>")
2502                  '(0 font-lock-keyword-face))
2503
2504            ;; At least numbers are simpler than C.
2505            (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
2506                          "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
2507                          "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
2508                  '(0 mdw-number-face))
2509
2510            ;; And anything else is punctuation.
2511            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2512                  '(0 mdw-punct-face))))))
2513
2514 (defun perl-number-tests (&optional arg)
2515   "Assign consecutive numbers to lines containing `#t'.  With ARG,
2516 strip numbers instead."
2517   (interactive "P")
2518   (save-excursion
2519     (goto-char (point-min))
2520     (let ((i 0) (fmt (if arg "" " %4d")))
2521       (while (search-forward "#t" nil t)
2522         (delete-region (point) (line-end-position))
2523         (setq i (1+ i))
2524         (insert (format fmt i)))
2525       (goto-char (point-min))
2526       (if (re-search-forward "\\(tests\\s-*=>\\s-*\\)\\w*" nil t)
2527           (replace-match (format "\\1%d" i))))))
2528
2529 ;;;--------------------------------------------------------------------------
2530 ;;; Python programming style.
2531
2532 (defun mdw-fontify-pythonic (keywords)
2533
2534   ;; Miscellaneous fiddling.
2535   (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
2536   (setq indent-tabs-mode nil)
2537
2538   ;; Now define fontification things.
2539   (make-local-variable 'font-lock-keywords)
2540   (setq font-lock-keywords
2541         (list
2542
2543          ;; Set up the keywords defined above.
2544          (list (concat "\\_<\\(" keywords "\\)\\_>")
2545                '(0 font-lock-keyword-face))
2546
2547          ;; At least numbers are simpler than C.
2548          (list (concat "\\_<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
2549                        "\\_<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
2550                        "\\([eE]\\([-+]\\|\\)[0-9_]+\\|[lL]\\|\\)")
2551                '(0 mdw-number-face))
2552
2553          ;; And anything else is punctuation.
2554          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2555                '(0 mdw-punct-face)))))
2556
2557 ;; Define Python fontification styles.
2558
2559 (defun mdw-fontify-python ()
2560   (mdw-fontify-pythonic
2561    (mdw-regexps "and" "as" "assert" "break" "class" "continue" "def"
2562                 "del" "elif" "else" "except" "exec" "finally" "for"
2563                 "from" "global" "if" "import" "in" "is" "lambda"
2564                 "not" "or" "pass" "print" "raise" "return" "try"
2565                 "while" "with" "yield")))
2566
2567 (defun mdw-fontify-pyrex ()
2568   (mdw-fontify-pythonic
2569    (mdw-regexps "and" "as" "assert" "break" "cdef" "class" "continue"
2570                 "ctypedef" "def" "del" "elif" "else" "except" "exec"
2571                 "extern" "finally" "for" "from" "global" "if"
2572                 "import" "in" "is" "lambda" "not" "or" "pass" "print"
2573                 "raise" "return" "struct" "try" "while" "with"
2574                 "yield")))
2575
2576 ;;;--------------------------------------------------------------------------
2577 ;;; Icon programming style.
2578
2579 ;; Icon indentation style.
2580
2581 (setq icon-brace-offset 0
2582       icon-continued-brace-offset 0
2583       icon-continued-statement-offset 2
2584       icon-indent-level 2)
2585
2586 ;; Define Icon fontification style.
2587
2588 (defun mdw-fontify-icon ()
2589
2590   ;; Miscellaneous fiddling.
2591   (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
2592
2593   ;; Now define fontification things.
2594   (make-local-variable 'font-lock-keywords)
2595   (let ((icon-keywords
2596          (mdw-regexps "break" "by" "case" "create" "default" "do" "else"
2597                       "end" "every" "fail" "global" "if" "initial"
2598                       "invocable" "link" "local" "next" "not" "of"
2599                       "procedure" "record" "repeat" "return" "static"
2600                       "suspend" "then" "to" "until" "while"))
2601         (preprocessor-keywords
2602          (mdw-regexps "define" "else" "endif" "error" "ifdef" "ifndef"
2603                       "include" "line" "undef")))
2604     (setq font-lock-keywords
2605           (list
2606
2607            ;; Set up the keywords defined above.
2608            (list (concat "\\<\\(" icon-keywords "\\)\\>")
2609                  '(0 font-lock-keyword-face))
2610
2611            ;; The things that Icon calls keywords.
2612            (list "&\\sw+\\>" '(0 font-lock-variable-name-face))
2613
2614            ;; At least numbers are simpler than C.
2615            (list (concat "\\<[0-9]+"
2616                          "\\([rR][0-9a-zA-Z]+\\|"
2617                          "\\.[0-9]+\\([eE][+-]?[0-9]+\\)?\\)\\>\\|"
2618                          "\\.[0-9]+\\([eE][+-]?[0-9]+\\)?\\>")
2619                  '(0 mdw-number-face))
2620
2621            ;; Preprocessor.
2622            (list (concat "^[ \t]*$[ \t]*\\<\\("
2623                          preprocessor-keywords
2624                          "\\)\\>")
2625                  '(0 font-lock-keyword-face))
2626
2627            ;; And anything else is punctuation.
2628            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2629                  '(0 mdw-punct-face))))))
2630
2631 ;;;--------------------------------------------------------------------------
2632 ;;; Assembler mode.
2633
2634 (defun mdw-fontify-asm ()
2635   (modify-syntax-entry ?' "\"")
2636   (modify-syntax-entry ?. "w")
2637   (modify-syntax-entry ?\n ">")
2638   (setf fill-prefix nil)
2639   (local-set-key ";" 'self-insert-command)
2640   (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)"))
2641
2642 (defun mdw-asm-set-comment ()
2643   (modify-syntax-entry ?; "."
2644                        )
2645   (modify-syntax-entry asm-comment-char "<b")
2646   (setq comment-start (string asm-comment-char ? )))
2647 (add-hook 'asm-mode-local-variables-hook 'mdw-asm-set-comment)
2648 (put 'asm-comment-char 'safe-local-variable 'characterp)
2649
2650 ;;;--------------------------------------------------------------------------
2651 ;;; TCL configuration.
2652
2653 (defun mdw-fontify-tcl ()
2654   (mapcar #'(lambda (ch) (modify-syntax-entry ch ".")) '(?$))
2655   (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
2656   (make-local-variable 'font-lock-keywords)
2657   (setq font-lock-keywords
2658         (list
2659          (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
2660                        "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
2661                        "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
2662                '(0 mdw-number-face))
2663          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2664                '(0 mdw-punct-face)))))
2665
2666 ;;;--------------------------------------------------------------------------
2667 ;;; Dylan programming configuration.
2668
2669 (defun mdw-fontify-dylan ()
2670
2671   (make-local-variable 'font-lock-keywords)
2672
2673   ;; Horrors.  `dylan-mode' sets the `major-mode' name after calling this
2674   ;; hook, which undoes all of our configuration.
2675   (setq major-mode 'dylan-mode)
2676   (font-lock-set-defaults)
2677
2678   (let* ((word "[-_a-zA-Z!*@<>$%]+")
2679          (dylan-keywords (mdw-regexps
2680
2681                           "C-address" "C-callable-wrapper" "C-function"
2682                           "C-mapped-subtype" "C-pointer-type" "C-struct"
2683                           "C-subtype" "C-union" "C-variable"
2684
2685                           "above" "abstract" "afterwards" "all"
2686                           "begin" "below" "block" "by"
2687                           "case" "class" "cleanup" "constant" "create"
2688                           "define" "domain"
2689                           "else" "elseif" "end" "exception" "export"
2690                           "finally" "for" "from" "function"
2691                           "generic"
2692                           "handler"
2693                           "if" "in" "instance" "interface" "iterate"
2694                           "keyed-by"
2695                           "let" "library" "local"
2696                           "macro" "method" "module"
2697                           "otherwise"
2698                           "profiling"
2699                           "select" "slot" "subclass"
2700                           "table" "then" "to"
2701                           "unless" "until" "use"
2702                           "variable" "virtual"
2703                           "when" "while"))
2704          (sharp-keywords (mdw-regexps
2705                           "all-keys" "key" "next" "rest" "include"
2706                           "t" "f")))
2707     (setq font-lock-keywords
2708           (list (list (concat "\\<\\(" dylan-keywords
2709                               "\\|" "with\\(out\\)?-" word
2710                               "\\)\\>")
2711                       '(0 font-lock-keyword-face))
2712                 (list (concat "\\<" word ":" "\\|"
2713                               "#\\(" sharp-keywords "\\)\\>")
2714                       '(0 font-lock-variable-name-face))
2715                 (list (concat "\\("
2716                               "\\([-+]\\|\\<\\)[0-9]+" "\\("
2717                                 "\\(\\.[0-9]+\\)?" "\\([eE][-+][0-9]+\\)?"
2718                                 "\\|" "/[0-9]+"
2719                               "\\)"
2720                               "\\|" "\\.[0-9]+" "\\([eE][-+][0-9]+\\)?"
2721                               "\\|" "#b[01]+"
2722                               "\\|" "#o[0-7]+"
2723                               "\\|" "#x[0-9a-zA-Z]+"
2724                               "\\)\\>")
2725                       '(0 mdw-number-face))
2726                 (list (concat "\\("
2727                               "\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\|"
2728                               "\\_<[-+*/=<>:&|]+\\_>"
2729                               "\\)")
2730                       '(0 mdw-punct-face))))))
2731
2732 ;;;--------------------------------------------------------------------------
2733 ;;; Algol 68 configuration.
2734
2735 (setq a68-indent-step 2)
2736
2737 (defun mdw-fontify-algol-68 ()
2738
2739   ;; Fix up the syntax table.
2740   (modify-syntax-entry ?# "!" a68-mode-syntax-table)
2741   (dolist (ch '(?- ?+ ?= ?< ?> ?* ?/ ?| ?&))
2742     (modify-syntax-entry ch "." a68-mode-syntax-table))
2743
2744   (make-local-variable 'font-lock-keywords)
2745
2746   (let ((not-comment
2747          (let ((word "COMMENT"))
2748            (do ((regexp (concat "[^" (substring word 0 1) "]+")
2749                         (concat regexp "\\|"
2750                                 (substring word 0 i)
2751                                 "[^" (substring word i (1+ i)) "]"))
2752                 (i 1 (1+ i)))
2753                ((>= i (length word)) regexp)))))
2754     (setq font-lock-keywords
2755           (list (list (concat "\\<COMMENT\\>"
2756                               "\\(" not-comment "\\)\\{0,5\\}"
2757                               "\\(\\'\\|\\<COMMENT\\>\\)")
2758                       '(0 font-lock-comment-face))
2759                 (list (concat "\\<CO\\>"
2760                               "\\([^C]+\\|C[^O]\\)\\{0,5\\}"
2761                               "\\($\\|\\<CO\\>\\)")
2762                       '(0 font-lock-comment-face))
2763                 (list "\\<[A-Z_]+\\>"
2764                       '(0 font-lock-keyword-face))
2765                 (list (concat "\\<"
2766                               "[0-9]+"
2767                               "\\(\\.[0-9]+\\)?"
2768                               "\\([eE][-+]?[0-9]+\\)?"
2769                               "\\>")
2770                       '(0 mdw-number-face))
2771                 (list "\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/"
2772                       '(0 mdw-punct-face))))))
2773
2774 ;;;--------------------------------------------------------------------------
2775 ;;; REXX configuration.
2776
2777 (defun mdw-rexx-electric-* ()
2778   (interactive)
2779   (insert ?*)
2780   (rexx-indent-line))
2781
2782 (defun mdw-rexx-indent-newline-indent ()
2783   (interactive)
2784   (rexx-indent-line)
2785   (if abbrev-mode (expand-abbrev))
2786   (newline-and-indent))
2787
2788 (defun mdw-fontify-rexx ()
2789
2790   ;; Various bits of fiddling.
2791   (setq mdw-auto-indent nil)
2792   (local-set-key [?\C-m] 'mdw-rexx-indent-newline-indent)
2793   (local-set-key [?*] 'mdw-rexx-electric-*)
2794   (mapcar #'(lambda (ch) (modify-syntax-entry ch "w"))
2795           '(?! ?? ?# ?@ ?$))
2796   (mdw-standard-fill-prefix "\\([ \t]*/?\*[ \t]*\\)")
2797
2798   ;; Set up keywords and things for fontification.
2799   (make-local-variable 'font-lock-keywords-case-fold-search)
2800   (setq font-lock-keywords-case-fold-search t)
2801
2802   (setq rexx-indent 2)
2803   (setq rexx-end-indent rexx-indent)
2804   (setq rexx-cont-indent rexx-indent)
2805
2806   (make-local-variable 'font-lock-keywords)
2807   (let ((rexx-keywords
2808          (mdw-regexps "address" "arg" "by" "call" "digits" "do" "drop"
2809                       "else" "end" "engineering" "exit" "expose" "for"
2810                       "forever" "form" "fuzz" "if" "interpret" "iterate"
2811                       "leave" "linein" "name" "nop" "numeric" "off" "on"
2812                       "options" "otherwise" "parse" "procedure" "pull"
2813                       "push" "queue" "return" "say" "select" "signal"
2814                       "scientific" "source" "then" "trace" "to" "until"
2815                       "upper" "value" "var" "version" "when" "while"
2816                       "with"
2817
2818                       "abbrev" "abs" "bitand" "bitor" "bitxor" "b2x"
2819                       "center" "center" "charin" "charout" "chars"
2820                       "compare" "condition" "copies" "c2d" "c2x"
2821                       "datatype" "date" "delstr" "delword" "d2c" "d2x"
2822                       "errortext" "format" "fuzz" "insert" "lastpos"
2823                       "left" "length" "lineout" "lines" "max" "min"
2824                       "overlay" "pos" "queued" "random" "reverse" "right"
2825                       "sign" "sourceline" "space" "stream" "strip"
2826                       "substr" "subword" "symbol" "time" "translate"
2827                       "trunc" "value" "verify" "word" "wordindex"
2828                       "wordlength" "wordpos" "words" "xrange" "x2b" "x2c"
2829                       "x2d")))
2830
2831     (setq font-lock-keywords
2832           (list
2833
2834            ;; Set up the keywords defined above.
2835            (list (concat "\\<\\(" rexx-keywords "\\)\\>")
2836                  '(0 font-lock-keyword-face))
2837
2838            ;; Fontify all symbols the same way.
2839            (list (concat "\\<\\([0-9.][A-Za-z0-9.!?_#@$]*[Ee][+-]?[0-9]+\\|"
2840                          "[A-Za-z0-9.!?_#@$]+\\)")
2841                  '(0 font-lock-variable-name-face))
2842
2843            ;; And everything else is punctuation.
2844            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2845                  '(0 mdw-punct-face))))))
2846
2847 ;;;--------------------------------------------------------------------------
2848 ;;; Standard ML programming style.
2849
2850 (defun mdw-fontify-sml ()
2851
2852   ;; Make underscore an honorary letter.
2853   (modify-syntax-entry ?' "w")
2854
2855   ;; Set fill prefix.
2856   (mdw-standard-fill-prefix "\\([ \t]*(\*[ \t]*\\)")
2857
2858   ;; Now define fontification things.
2859   (make-local-variable 'font-lock-keywords)
2860   (let ((sml-keywords
2861          (mdw-regexps "abstype" "and" "andalso" "as"
2862                       "case"
2863                       "datatype" "do"
2864                       "else" "end" "eqtype" "exception"
2865                       "fn" "fun" "functor"
2866                       "handle"
2867                       "if" "in" "include" "infix" "infixr"
2868                       "let" "local"
2869                       "nonfix"
2870                       "of" "op" "open" "orelse"
2871                       "raise" "rec"
2872                       "sharing" "sig" "signature" "struct" "structure"
2873                       "then" "type"
2874                       "val"
2875                       "where" "while" "with" "withtype")))
2876
2877     (setq font-lock-keywords
2878           (list
2879
2880            ;; Set up the keywords defined above.
2881            (list (concat "\\<\\(" sml-keywords "\\)\\>")
2882                  '(0 font-lock-keyword-face))
2883
2884            ;; At least numbers are simpler than C.
2885            (list (concat "\\<\\(\\~\\|\\)"
2886                             "\\(0\\(\\([wW]\\|\\)[xX][0-9a-fA-F]+\\|"
2887                                    "[wW][0-9]+\\)\\|"
2888                                 "\\([0-9]+\\(\\.[0-9]+\\|\\)"
2889                                          "\\([eE]\\(\\~\\|\\)"
2890                                                 "[0-9]+\\|\\)\\)\\)")
2891                  '(0 mdw-number-face))
2892
2893            ;; And anything else is punctuation.
2894            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2895                  '(0 mdw-punct-face))))))
2896
2897 ;;;--------------------------------------------------------------------------
2898 ;;; Haskell configuration.
2899
2900 (defun mdw-fontify-haskell ()
2901
2902   ;; Fiddle with syntax table to get comments right.
2903   (modify-syntax-entry ?' "_")
2904   (modify-syntax-entry ?- ". 12")
2905   (modify-syntax-entry ?\n ">")
2906
2907   ;; Make punctuation be punctuation
2908   (let ((punct "=<>+-*/|&%!@?$.^:#`"))
2909     (do ((i 0 (1+ i)))
2910         ((>= i (length punct)))
2911       (modify-syntax-entry (aref punct i) ".")))
2912
2913   ;; Set fill prefix.
2914   (mdw-standard-fill-prefix "\\([ \t]*{?--?[ \t]*\\)")
2915
2916   ;; Fiddle with fontification.
2917   (make-local-variable 'font-lock-keywords)
2918   (let ((haskell-keywords
2919          (mdw-regexps "as"
2920                       "case" "ccall" "class"
2921                       "data" "default" "deriving" "do"
2922                       "else" "exists"
2923                       "forall" "foreign"
2924                       "hiding"
2925                       "if" "import" "in" "infix" "infixl" "infixr" "instance"
2926                       "let"
2927                       "mdo" "module"
2928                       "newtype"
2929                       "of"
2930                       "proc"
2931                       "qualified"
2932                       "rec"
2933                       "safe" "stdcall"
2934                       "then" "type"
2935                       "unsafe"
2936                       "where"))
2937         (control-sequences
2938          (mdw-regexps "ACK" "BEL" "BS" "CAN" "CR" "DC1" "DC2" "DC3" "DC4"
2939                       "DEL" "DLE" "EM" "ENQ" "EOT" "ESC" "ETB" "ETX" "FF"
2940                       "FS" "GS" "HT" "LF" "NAK" "NUL" "RS" "SI" "SO" "SOH"
2941                       "SP" "STX" "SUB" "SYN" "US" "VT")))
2942
2943     (setq font-lock-keywords
2944           (list
2945            (list (concat "{-" "[^-]*" "\\(-+[^-}][^-]*\\)*"
2946                               "\\(-+}\\|-*\\'\\)"
2947                          "\\|"
2948                          "--.*$")
2949                  '(0 font-lock-comment-face))
2950            (list (concat "\\_<\\(" haskell-keywords "\\)\\_>")
2951                  '(0 font-lock-keyword-face))
2952            (list (concat "'\\("
2953                          "[^\\]"
2954                          "\\|"
2955                          "\\\\"
2956                          "\\(" "[abfnrtv\\\"']" "\\|"
2957                                "^" "\\(" control-sequences "\\|"
2958                                          "[]A-Z@[\\^_]" "\\)" "\\|"
2959                                "\\|"
2960                                "[0-9]+" "\\|"
2961                                "[oO][0-7]+" "\\|"
2962                                "[xX][0-9A-Fa-f]+"
2963                          "\\)"
2964                          "\\)'")
2965                  '(0 font-lock-string-face))
2966            (list "\\_<[A-Z]\\(\\sw+\\|\\s_+\\)*\\_>"
2967                  '(0 font-lock-variable-name-face))
2968            (list (concat "\\_<0\\([xX][0-9a-fA-F]+\\|[oO][0-7]+\\)\\|"
2969                          "\\_<[0-9]+\\(\\.[0-9]*\\|\\)"
2970                          "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)")
2971                  '(0 mdw-number-face))
2972            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2973                  '(0 mdw-punct-face))))))
2974
2975 ;;;--------------------------------------------------------------------------
2976 ;;; Erlang configuration.
2977
2978 (setq erlang-electric-commands nil)
2979
2980 (defun mdw-fontify-erlang ()
2981
2982   ;; Set fill prefix.
2983   (mdw-standard-fill-prefix "\\([ \t]*{?%*[ \t]*\\)")
2984
2985   ;; Fiddle with fontification.
2986   (make-local-variable 'font-lock-keywords)
2987   (let ((erlang-keywords
2988          (mdw-regexps "after" "and" "andalso"
2989                       "band" "begin" "bnot" "bor" "bsl" "bsr" "bxor"
2990                       "case" "catch" "cond"
2991                       "div" "end" "fun" "if" "let" "not"
2992                       "of" "or" "orelse"
2993                       "query" "receive" "rem" "try" "when" "xor")))
2994
2995     (setq font-lock-keywords
2996           (list
2997            (list "%.*$"
2998                  '(0 font-lock-comment-face))
2999            (list (concat "\\<\\(" erlang-keywords "\\)\\>")
3000                  '(0 font-lock-keyword-face))
3001            (list (concat "^-\\sw+\\>")
3002                  '(0 font-lock-keyword-face))
3003            (list "\\<[0-9]+\\(\\|#[0-9a-zA-Z]+\\|[eE][+-]?[0-9]+\\)\\>"
3004                  '(0 mdw-number-face))
3005            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
3006                  '(0 mdw-punct-face))))))
3007
3008 ;;;--------------------------------------------------------------------------
3009 ;;; Texinfo configuration.
3010
3011 (defun mdw-fontify-texinfo ()
3012
3013   ;; Set fill prefix.
3014   (mdw-standard-fill-prefix "\\([ \t]*@c[ \t]+\\)")
3015
3016   ;; Real fontification things.
3017   (make-local-variable 'font-lock-keywords)
3018   (setq font-lock-keywords
3019         (list
3020
3021          ;; Environment names are keywords.
3022          (list "@\\(end\\)  *\\([a-zA-Z]*\\)?"
3023                '(2 font-lock-keyword-face))
3024
3025          ;; Unmark escaped magic characters.
3026          (list "\\(@\\)\\([@{}]\\)"
3027                '(1 font-lock-keyword-face)
3028                '(2 font-lock-variable-name-face))
3029
3030          ;; Make sure we get comments properly.
3031          (list "@c\\(\\|omment\\)\\( .*\\)?$"
3032                '(0 font-lock-comment-face))
3033
3034          ;; Command names are keywords.
3035          (list "@\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
3036                '(0 font-lock-keyword-face))
3037
3038          ;; Fontify TeX special characters as punctuation.
3039          (list "[{}]+"
3040                '(0 mdw-punct-face)))))
3041
3042 ;;;--------------------------------------------------------------------------
3043 ;;; TeX and LaTeX configuration.
3044
3045 (defun mdw-fontify-tex ()
3046   (setq ispell-parser 'tex)
3047   (turn-on-reftex)
3048
3049   ;; Don't make maths into a string.
3050   (modify-syntax-entry ?$ ".")
3051   (modify-syntax-entry ?$ "." font-lock-syntax-table)
3052   (local-set-key [?$] 'self-insert-command)
3053
3054   ;; Make `tab' be useful, given that tab stops in TeX don't work well.
3055   (local-set-key "\C-i" 'indent-relative)
3056   (setq indent-tabs-mode nil)
3057
3058   ;; Set fill prefix.
3059   (mdw-standard-fill-prefix "\\([ \t]*%+[ \t]*\\)")
3060
3061   ;; Real fontification things.
3062   (make-local-variable 'font-lock-keywords)
3063   (setq font-lock-keywords
3064         (list
3065
3066          ;; Environment names are keywords.
3067          (list (concat "\\\\\\(begin\\|end\\|newenvironment\\)"
3068                        "{\\([^}\n]*\\)}")
3069                '(2 font-lock-keyword-face))
3070
3071          ;; Suspended environment names are keywords too.
3072          (list (concat "\\\\\\(suspend\\|resume\\)\\(\\[[^]]*\\]\\)?"
3073                        "{\\([^}\n]*\\)}")
3074                '(3 font-lock-keyword-face))
3075
3076          ;; Command names are keywords.
3077          (list "\\\\\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
3078                '(0 font-lock-keyword-face))
3079
3080          ;; Handle @/.../ for italics.
3081          ;; (list "\\(@/\\)\\([^/]*\\)\\(/\\)"
3082          ;;       '(1 font-lock-keyword-face)
3083          ;;       '(3 font-lock-keyword-face))
3084
3085          ;; Handle @*...* for boldness.
3086          ;; (list "\\(@\\*\\)\\([^*]*\\)\\(\\*\\)"
3087          ;;       '(1 font-lock-keyword-face)
3088          ;;       '(3 font-lock-keyword-face))
3089
3090          ;; Handle @`...' for literal syntax things.
3091          ;; (list "\\(@`\\)\\([^']*\\)\\('\\)"
3092          ;;       '(1 font-lock-keyword-face)
3093          ;;       '(3 font-lock-keyword-face))
3094
3095          ;; Handle @<...> for nonterminals.
3096          ;; (list "\\(@<\\)\\([^>]*\\)\\(>\\)"
3097          ;;       '(1 font-lock-keyword-face)
3098          ;;       '(3 font-lock-keyword-face))
3099
3100          ;; Handle other @-commands.
3101          ;; (list "@\\([^a-zA-Z]\\|[a-zA-Z]*\\)"
3102          ;;       '(0 font-lock-keyword-face))
3103
3104          ;; Make sure we get comments properly.
3105          (list "%.*"
3106                '(0 font-lock-comment-face))
3107
3108          ;; Fontify TeX special characters as punctuation.
3109          (list "[$^_{}#&]"
3110                '(0 mdw-punct-face)))))
3111
3112 ;;;--------------------------------------------------------------------------
3113 ;;; SGML hacking.
3114
3115 (defun mdw-sgml-mode ()
3116   (interactive)
3117   (sgml-mode)
3118   (mdw-standard-fill-prefix "")
3119   (make-local-variable 'sgml-delimiters)
3120   (setq sgml-delimiters
3121         '("AND" "&" "COM" "--" "CRO" "&#" "DSC" "]" "DSO" "[" "DTGC" "]"
3122           "DTGO" "[" "ERO" "&" "ETAGO" ":e" "GRPC" ")" "GRPO" "(" "LIT" "\""
3123           "LITA" "'" "MDC" ">" "MDO" "<!" "MINUS" "-" "MSC" "]]" "NESTC" "{"
3124           "NET" "}" "OPT" "?" "OR" "|" "PERO" "%" "PIC" ">" "PIO" "<?"
3125           "PLUS" "+" "REFC" "." "REP" "*" "RNI" "#" "SEQ" "," "STAGO" ":"
3126           "TAGC" "." "VI" "=" "MS-START" "<![" "MS-END" "]]>"
3127           "XML-ECOM" "-->" "XML-PIC" "?>" "XML-SCOM" "<!--" "XML-TAGCE" "/>"
3128           "NULL" ""))
3129   (setq major-mode 'mdw-sgml-mode)
3130   (setq mode-name "[mdw] SGML")
3131   (run-hooks 'mdw-sgml-mode-hook))
3132
3133 ;;;--------------------------------------------------------------------------
3134 ;;; Configuration files.
3135
3136 (defvar mdw-conf-quote-normal nil
3137   "*Control syntax category of quote characters `\"' and `''.
3138 If this is `t', consider quote characters to be normal
3139 punctuation, as for `conf-quote-normal'.  If this is `nil' then
3140 leave quote characters as quotes.  If this is a list, then
3141 consider the quote characters in the list to be normal
3142 punctuation.  If this is a single quote character, then consider
3143 that character only to be normal punctuation.")
3144 (defun mdw-conf-quote-normal-acceptable-value-p (value)
3145   "Is the VALUE is an acceptable value for `mdw-conf-quote-normal'?"
3146   (or (booleanp value)
3147       (every (lambda (v) (memq v '(?\" ?')))
3148              (if (listp value) value (list value)))))
3149 (put 'mdw-conf-quote-normal 'safe-local-variable
3150      'mdw-conf-quote-normal-acceptable-value-p)
3151
3152 (defun mdw-fix-up-quote ()
3153   "Apply the setting of `mdw-conf-quote-normal'."
3154   (let ((flag mdw-conf-quote-normal))
3155     (cond ((eq flag t)
3156            (conf-quote-normal t))
3157           ((not flag)
3158            nil)
3159           (t
3160            (let ((table (copy-syntax-table (syntax-table))))
3161              (mapc (lambda (ch) (modify-syntax-entry ch "." table))
3162                    (if (listp flag) flag (list flag)))
3163              (set-syntax-table table)
3164              (and font-lock-mode (font-lock-fontify-buffer)))))))
3165 (add-hook 'conf-mode-local-variables-hook 'mdw-fix-up-quote t t)
3166
3167 ;;;--------------------------------------------------------------------------
3168 ;;; Shell scripts.
3169
3170 (defun mdw-setup-sh-script-mode ()
3171
3172   ;; Fetch the shell interpreter's name.
3173   (let ((shell-name sh-shell-file))
3174
3175     ;; Try reading the hash-bang line.
3176     (save-excursion
3177       (goto-char (point-min))
3178       (if (looking-at "#![ \t]*\\([^ \t\n]*\\)")
3179           (setq shell-name (match-string 1))))
3180
3181     ;; Now try to set the shell.
3182     ;;
3183     ;; Don't let `sh-set-shell' bugger up my script.
3184     (let ((executable-set-magic #'(lambda (s &rest r) s)))
3185       (sh-set-shell shell-name)))
3186
3187   ;; Don't insert here-document scaffolding automatically.
3188   (local-set-key "<" 'self-insert-command)
3189
3190   ;; Now enable my keys and the fontification.
3191   (mdw-misc-mode-config)
3192
3193   ;; Set the indentation level correctly.
3194   (setq sh-indentation 2)
3195   (setq sh-basic-offset 2))
3196
3197 (setq sh-shell-file "/bin/sh")
3198
3199 ;; Awful hacking to override the shell detection for particular scripts.
3200 (defmacro define-custom-shell-mode (name shell)
3201   `(defun ,name ()
3202      (interactive)
3203      (set (make-local-variable 'sh-shell-file) ,shell)
3204      (sh-mode)))
3205 (define-custom-shell-mode bash-mode "/bin/bash")
3206 (define-custom-shell-mode rc-mode "/usr/bin/rc")
3207 (put 'sh-shell-file 'permanent-local t)
3208
3209 ;; Hack the rc syntax table.  Backquotes aren't paired in rc.
3210 (eval-after-load "sh-script"
3211   '(or (assq 'rc sh-mode-syntax-table-input)
3212        (let ((frag '(nil
3213                      ?# "<"
3214                      ?\n ">#"
3215                      ?\" "\"\""
3216                      ?\' "\"\'"
3217                      ?$ "'"
3218                      ?\` "."
3219                      ?! "_"
3220                      ?% "_"
3221                      ?. "_"
3222                      ?^ "_"
3223                      ?~ "_"
3224                      ?, "_"
3225                      ?= "."
3226                      ?< "."
3227                      ?> "."))
3228              (assoc (assq 'rc sh-mode-syntax-table-input)))
3229          (if assoc
3230              (rplacd assoc frag)
3231            (setq sh-mode-syntax-table-input
3232                  (cons (cons 'rc frag)
3233                        sh-mode-syntax-table-input))))))
3234
3235 ;;;--------------------------------------------------------------------------
3236 ;;; Emacs shell mode.
3237
3238 (defun mdw-eshell-prompt ()
3239   (let ((left "[") (right "]"))
3240     (when (= (user-uid) 0)
3241       (setq left "«" right "»"))
3242     (concat left
3243             (save-match-data
3244               (replace-regexp-in-string "\\..*$" "" (system-name)))
3245             " "
3246             (let* ((pwd (eshell/pwd)) (npwd (length pwd))
3247                    (home (expand-file-name "~")) (nhome (length home)))
3248               (if (and (>= npwd nhome)
3249                        (or (= nhome npwd)
3250                            (= (elt pwd nhome) ?/))
3251                        (string= (substring pwd 0 nhome) home))
3252                   (concat "~" (substring pwd (length home)))
3253                 pwd))
3254             right)))
3255 (setq eshell-prompt-function 'mdw-eshell-prompt)
3256 (setq eshell-prompt-regexp "^\\[[^]>]+\\(\\]\\|>>?\\)")
3257
3258 (defun eshell/e (file) (find-file file) nil)
3259 (defun eshell/ee (file) (find-file-other-window file) nil)
3260 (defun eshell/w3m (url) (w3m-goto-url url) nil)
3261
3262 (mdw-define-face eshell-prompt (t :weight bold))
3263 (mdw-define-face eshell-ls-archive (t :weight bold :foreground "red"))
3264 (mdw-define-face eshell-ls-backup (t :foreground "lightgrey" :slant italic))
3265 (mdw-define-face eshell-ls-product (t :foreground "lightgrey" :slant italic))
3266 (mdw-define-face eshell-ls-clutter (t :foreground "lightgrey" :slant italic))
3267 (mdw-define-face eshell-ls-executable (t :weight bold))
3268 (mdw-define-face eshell-ls-directory (t :foreground "cyan" :weight bold))
3269 (mdw-define-face eshell-ls-readonly (t nil))
3270 (mdw-define-face eshell-ls-symlink (t :foreground "cyan"))
3271
3272 ;;;--------------------------------------------------------------------------
3273 ;;; Messages-file mode.
3274
3275 (defun messages-mode-guts ()
3276   (setq messages-mode-syntax-table (make-syntax-table))
3277   (set-syntax-table messages-mode-syntax-table)
3278   (modify-syntax-entry ?0 "w" messages-mode-syntax-table)
3279   (modify-syntax-entry ?1 "w" messages-mode-syntax-table)
3280   (modify-syntax-entry ?2 "w" messages-mode-syntax-table)
3281   (modify-syntax-entry ?3 "w" messages-mode-syntax-table)
3282   (modify-syntax-entry ?4 "w" messages-mode-syntax-table)
3283   (modify-syntax-entry ?5 "w" messages-mode-syntax-table)
3284   (modify-syntax-entry ?6 "w" messages-mode-syntax-table)
3285   (modify-syntax-entry ?7 "w" messages-mode-syntax-table)
3286   (modify-syntax-entry ?8 "w" messages-mode-syntax-table)
3287   (modify-syntax-entry ?9 "w" messages-mode-syntax-table)
3288   (make-local-variable 'comment-start)
3289   (make-local-variable 'comment-end)
3290   (make-local-variable 'indent-line-function)
3291   (setq indent-line-function 'indent-relative)
3292   (mdw-standard-fill-prefix "\\([ \t]*\\(;\\|/?\\*\\)+[ \t]*\\)")
3293   (make-local-variable 'font-lock-defaults)
3294   (make-local-variable 'messages-mode-keywords)
3295   (let ((keywords
3296          (mdw-regexps "array" "bitmap" "callback" "docs[ \t]+enum"
3297                       "export" "enum" "fixed-octetstring" "flags"
3298                       "harmless" "map" "nested" "optional"
3299                       "optional-tagged" "package" "primitive"
3300                       "primitive-nullfree" "relaxed[ \t]+enum"
3301                       "set" "table" "tagged-optional"   "union"
3302                       "variadic" "vector" "version" "version-tag")))
3303     (setq messages-mode-keywords
3304           (list
3305            (list (concat "\\<\\(" keywords "\\)\\>:")
3306                  '(0 font-lock-keyword-face))
3307            '("\\([-a-zA-Z0-9]+:\\)" (0 font-lock-warning-face))
3308            '("\\(\\<[a-z][-_a-zA-Z0-9]*\\)"
3309              (0 font-lock-variable-name-face))
3310            '("\\<\\([0-9]+\\)\\>" (0 mdw-number-face))
3311            '("\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
3312              (0 mdw-punct-face)))))
3313   (setq font-lock-defaults
3314         '(messages-mode-keywords nil nil nil nil))
3315   (run-hooks 'messages-file-hook))
3316
3317 (defun messages-mode ()
3318   (interactive)
3319   (fundamental-mode)
3320   (setq major-mode 'messages-mode)
3321   (setq mode-name "Messages")
3322   (messages-mode-guts)
3323   (modify-syntax-entry ?# "<" messages-mode-syntax-table)
3324   (modify-syntax-entry ?\n ">" messages-mode-syntax-table)
3325   (setq comment-start "# ")
3326   (setq comment-end "")
3327   (run-hooks 'messages-mode-hook))
3328
3329 (defun cpp-messages-mode ()
3330   (interactive)
3331   (fundamental-mode)
3332   (setq major-mode 'cpp-messages-mode)
3333   (setq mode-name "CPP Messages")
3334   (messages-mode-guts)
3335   (modify-syntax-entry ?* ". 23" messages-mode-syntax-table)
3336   (modify-syntax-entry ?/ ". 14" messages-mode-syntax-table)
3337   (setq comment-start "/* ")
3338   (setq comment-end " */")
3339   (let ((preprocessor-keywords
3340          (mdw-regexps "assert" "define" "elif" "else" "endif" "error"
3341                       "ident" "if" "ifdef" "ifndef" "import" "include"
3342                       "line" "pragma" "unassert" "undef" "warning")))
3343     (setq messages-mode-keywords
3344           (append (list (list (concat "^[ \t]*\\#[ \t]*"
3345                                       "\\(include\\|import\\)"
3346                                       "[ \t]*\\(<[^>]+\\(>\\|\\)\\)")
3347                               '(2 font-lock-string-face))
3348                         (list (concat "^\\([ \t]*#[ \t]*\\(\\("
3349                                       preprocessor-keywords
3350                                       "\\)\\>\\|[0-9]+\\|$\\)\\)")
3351                               '(1 font-lock-keyword-face)))
3352                   messages-mode-keywords)))
3353   (run-hooks 'cpp-messages-mode-hook))
3354
3355 (add-hook 'messages-mode-hook 'mdw-misc-mode-config t)
3356 (add-hook 'cpp-messages-mode-hook 'mdw-misc-mode-config t)
3357 ; (add-hook 'messages-file-hook 'mdw-fontify-messages t)
3358
3359 ;;;--------------------------------------------------------------------------
3360 ;;; Messages-file mode.
3361
3362 (defvar mallow-driver-substitution-face 'mallow-driver-substitution-face
3363   "Face to use for subsittution directives.")
3364 (make-face 'mallow-driver-substitution-face)
3365 (defvar mallow-driver-text-face 'mallow-driver-text-face
3366   "Face to use for body text.")
3367 (make-face 'mallow-driver-text-face)
3368
3369 (defun mallow-driver-mode ()
3370   (interactive)
3371   (fundamental-mode)
3372   (setq major-mode 'mallow-driver-mode)
3373   (setq mode-name "Mallow driver")
3374   (setq mallow-driver-mode-syntax-table (make-syntax-table))
3375   (set-syntax-table mallow-driver-mode-syntax-table)
3376   (make-local-variable 'comment-start)
3377   (make-local-variable 'comment-end)
3378   (make-local-variable 'indent-line-function)
3379   (setq indent-line-function 'indent-relative)
3380   (mdw-standard-fill-prefix "\\([ \t]*\\(;\\|/?\\*\\)+[ \t]*\\)")
3381   (make-local-variable 'font-lock-defaults)
3382   (make-local-variable 'mallow-driver-mode-keywords)
3383   (let ((keywords
3384          (mdw-regexps "each" "divert" "file" "if"
3385                       "perl" "set" "string" "type" "write")))
3386     (setq mallow-driver-mode-keywords
3387           (list
3388            (list (concat "^%\\s *\\(}\\|\\(" keywords "\\)\\>\\).*$")
3389                  '(0 font-lock-keyword-face))
3390            (list "^%\\s *\\(#.*\\|\\)$"
3391                  '(0 font-lock-comment-face))
3392            (list "^%"
3393                  '(0 font-lock-keyword-face))
3394            (list "^|?\\(.+\\)$" '(1 mallow-driver-text-face))
3395            (list "\\${[^}]*}"
3396                  '(0 mallow-driver-substitution-face t)))))
3397   (setq font-lock-defaults
3398         '(mallow-driver-mode-keywords nil nil nil nil))
3399   (modify-syntax-entry ?\" "_" mallow-driver-mode-syntax-table)
3400   (modify-syntax-entry ?\n ">" mallow-driver-mode-syntax-table)
3401   (setq comment-start "%# ")
3402   (setq comment-end "")
3403   (run-hooks 'mallow-driver-mode-hook))
3404
3405 (add-hook 'mallow-driver-hook 'mdw-misc-mode-config t)
3406
3407 ;;;--------------------------------------------------------------------------
3408 ;;; NFast debugs.
3409
3410 (defun nfast-debug-mode ()
3411   (interactive)
3412   (fundamental-mode)
3413   (setq major-mode 'nfast-debug-mode)
3414   (setq mode-name "NFast debug")
3415   (setq messages-mode-syntax-table (make-syntax-table))
3416   (set-syntax-table messages-mode-syntax-table)
3417   (make-local-variable 'font-lock-defaults)
3418   (make-local-variable 'nfast-debug-mode-keywords)
3419   (setq truncate-lines t)
3420   (setq nfast-debug-mode-keywords
3421         (list
3422          '("^\\(NFast_\\(Connect\\|Disconnect\\|Submit\\|Wait\\)\\)"
3423            (0 font-lock-keyword-face))
3424          (list (concat "^[ \t]+\\(\\("
3425                        "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"
3426                        "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"
3427                        "[ \t]+\\)*"
3428                        "[0-9a-fA-F]+\\)[ \t]*$")
3429            '(0 mdw-number-face))
3430          '("^[ \t]+\.status=[ \t]+\\<\\(OK\\)\\>"
3431            (1 font-lock-keyword-face))
3432          '("^[ \t]+\.status=[ \t]+\\<\\([a-zA-Z][0-9a-zA-Z]*\\)\\>"
3433            (1 font-lock-warning-face))
3434          '("^[ \t]+\.status[ \t]+\\<\\(zero\\)\\>"
3435            (1 nil))
3436          (list (concat "^[ \t]+\\.cmd=[ \t]+"
3437                        "\\<\\([a-zA-Z][0-9a-zA-Z]*\\)\\>")
3438            '(1 font-lock-keyword-face))
3439          '("-?\\<\\([0-9]+\\|0x[0-9a-fA-F]+\\)\\>" (0 mdw-number-face))
3440          '("^\\([ \t]+[a-z0-9.]+\\)" (0 font-lock-variable-name-face))
3441          '("\\<\\([a-z][a-z0-9.]+\\)\\>=" (1 font-lock-variable-name-face))
3442          '("\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" (0 mdw-punct-face))))
3443   (setq font-lock-defaults
3444         '(nfast-debug-mode-keywords nil nil nil nil))
3445   (run-hooks 'nfast-debug-mode-hook))
3446
3447 ;;;--------------------------------------------------------------------------
3448 ;;; Other languages.
3449
3450 ;; Smalltalk.
3451
3452 (defun mdw-setup-smalltalk ()
3453   (and mdw-auto-indent
3454        (local-set-key "\C-m" 'smalltalk-newline-and-indent))
3455   (make-local-variable 'mdw-auto-indent)
3456   (setq mdw-auto-indent nil)
3457   (local-set-key "\C-i" 'smalltalk-reindent))
3458
3459 (defun mdw-fontify-smalltalk ()
3460   (make-local-variable 'font-lock-keywords)
3461   (setq font-lock-keywords
3462         (list
3463          (list "\\<[A-Z][a-zA-Z0-9]*\\>"
3464                '(0 font-lock-keyword-face))
3465          (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
3466                        "[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
3467                        "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
3468                '(0 mdw-number-face))
3469          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
3470                '(0 mdw-punct-face)))))
3471
3472 ;; Lispy languages.
3473
3474 ;; Unpleasant bodge.
3475 (unless (boundp 'slime-repl-mode-map)
3476   (setq slime-repl-mode-map (make-sparse-keymap)))
3477
3478 (defun mdw-indent-newline-and-indent ()
3479   (interactive)
3480   (indent-for-tab-command)
3481   (newline-and-indent))
3482
3483 (eval-after-load "cl-indent"
3484   '(progn
3485      (mapc #'(lambda (pair)
3486                (put (car pair)
3487                     'common-lisp-indent-function
3488                     (cdr pair)))
3489       '((destructuring-bind . ((&whole 4 &rest 1) 4 &body))
3490         (multiple-value-bind . ((&whole 4 &rest 1) 4 &body))))))
3491
3492 (defun mdw-common-lisp-indent ()
3493   (make-local-variable 'lisp-indent-function)
3494   (setq lisp-indent-function 'common-lisp-indent-function))
3495
3496 (setq lisp-simple-loop-indentation 2
3497       lisp-loop-keyword-indentation 6
3498       lisp-loop-forms-indentation 6)
3499
3500 (defun mdw-fontify-lispy ()
3501
3502   ;; Set fill prefix.
3503   (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)")
3504
3505   ;; Not much fontification needed.
3506   (make-local-variable 'font-lock-keywords)
3507   (setq font-lock-keywords
3508         (list (list (concat "\\("
3509                             "\\_<[-+]?"
3510                             "\\(" "[0-9]+/[0-9]+"
3511                             "\\|" "\\(" "[0-9]+" "\\(\\.[0-9]*\\)?" "\\|"
3512                                         "\\.[0-9]+" "\\)"
3513                                   "\\([dDeEfFlLsS][-+]?[0-9]+\\)?"
3514                             "\\)"
3515                             "\\|"
3516                             "#"
3517                             "\\(" "x" "[-+]?"
3518                                   "[0-9A-Fa-f]+" "\\(/[0-9A-Fa-f]+\\)?"
3519                             "\\|" "o" "[-+]?" "[0-7]+" "\\(/[0-7]+\\)?"
3520                             "\\|" "b" "[-+]?" "[01]+" "\\(/[01]+\\)?"
3521                             "\\|" "[0-9]+" "r" "[-+]?"
3522                                   "[0-9a-zA-Z]+" "\\(/[0-9a-zA-Z]+\\)?"
3523                             "\\)"
3524                             "\\)\\_>")
3525                     '(0 mdw-number-face))
3526               (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
3527                     '(0 mdw-punct-face)))))
3528
3529 (defun comint-send-and-indent ()
3530   (interactive)
3531   (comint-send-input)
3532   (and mdw-auto-indent
3533        (indent-for-tab-command)))
3534
3535 (defun mdw-setup-m4 ()
3536
3537   ;; Inexplicably, Emacs doesn't match braces in m4 mode.  This is very
3538   ;; annoying: fix it.
3539   (modify-syntax-entry ?{ "(")
3540   (modify-syntax-entry ?} ")")
3541
3542   ;; Fill prefix.
3543   (mdw-standard-fill-prefix "\\([ \t]*\\(?:#+\\|\\<dnl\\>\\)[ \t]*\\)"))
3544
3545 ;;;--------------------------------------------------------------------------
3546 ;;; Text mode.
3547
3548 (defun mdw-text-mode ()
3549   (setq fill-column 72)
3550   (flyspell-mode t)
3551   (mdw-standard-fill-prefix
3552    "\\([ \t]*\\([>#|:] ?\\)*[ \t]*\\)" 3)
3553   (auto-fill-mode 1))
3554
3555 ;;;--------------------------------------------------------------------------
3556 ;;; Outline and hide/show modes.
3557
3558 (defun mdw-outline-collapse-all ()
3559   "Completely collapse everything in the entire buffer."
3560   (interactive)
3561   (save-excursion
3562     (goto-char (point-min))
3563     (while (< (point) (point-max))
3564       (hide-subtree)
3565       (forward-line))))
3566
3567 (setq hs-hide-comments-when-hiding-all nil)
3568
3569 (defadvice hs-hide-all (after hide-first-comment activate)
3570   (save-excursion (hs-hide-initial-comment-block)))
3571
3572 ;;;--------------------------------------------------------------------------
3573 ;;; Shell mode.
3574
3575 (defun mdw-sh-mode-setup ()
3576   (local-set-key [?\C-a] 'comint-bol)
3577   (add-hook 'comint-output-filter-functions
3578             'comint-watch-for-password-prompt))
3579
3580 (defun mdw-term-mode-setup ()
3581   (setq term-prompt-regexp shell-prompt-pattern)
3582   (make-local-variable 'mouse-yank-at-point)
3583   (make-local-variable 'transient-mark-mode)
3584   (setq mouse-yank-at-point t)
3585   (auto-fill-mode -1)
3586   (setq tab-width 8))
3587
3588 (defun term-send-meta-right () (interactive) (term-send-raw-string "\e\e[C"))
3589 (defun term-send-meta-left  () (interactive) (term-send-raw-string "\e\e[D"))
3590 (defun term-send-ctrl-uscore () (interactive) (term-send-raw-string "\C-_"))
3591 (defun term-send-meta-meta-something ()
3592   (interactive)
3593   (term-send-raw-string "\e\e")
3594   (term-send-raw))
3595 (eval-after-load 'term
3596   '(progn
3597      (define-key term-raw-map [?\e ?\e] nil)
3598      (define-key term-raw-map [?\e ?\e t] 'term-send-meta-meta-something)
3599      (define-key term-raw-map [?\C-/] 'term-send-ctrl-uscore)
3600      (define-key term-raw-map [M-right] 'term-send-meta-right)
3601      (define-key term-raw-map [?\e ?\M-O ?C] 'term-send-meta-right)
3602      (define-key term-raw-map [M-left] 'term-send-meta-left)
3603      (define-key term-raw-map [?\e ?\M-O ?D] 'term-send-meta-left)))
3604
3605 (defadvice term-exec (before program-args-list compile activate)
3606   "If the PROGRAM argument is a list, interpret it as (PROGRAM . SWITCHES).
3607 This allows you to pass a list of arguments through `ansi-term'."
3608   (let ((program (ad-get-arg 2)))
3609     (if (listp program)
3610         (progn
3611           (ad-set-arg 2 (car program))
3612           (ad-set-arg 4 (cdr program))))))
3613
3614 (defun ssh (host)
3615   "Open a terminal containing an ssh session to the HOST."
3616   (interactive "sHost: ")
3617   (ansi-term (list "ssh" host) (format "ssh@%s" host)))
3618
3619 (defvar git-grep-command
3620   "env PAGER=cat git grep --no-color -nH -e "
3621   "*The default command for \\[git-grep].")
3622
3623 (defvar git-grep-history nil)
3624
3625 (defun git-grep (command-args)
3626   "Run `git grep' with user-specified args and collect output in a buffer."
3627   (interactive
3628    (list (read-shell-command "Run git grep (like this): "
3629                              git-grep-command 'git-grep-history)))
3630   (grep command-args))
3631
3632 ;;;--------------------------------------------------------------------------
3633 ;;; Inferior Emacs Lisp.
3634
3635 (setq comint-prompt-read-only t)
3636
3637 (eval-after-load "comint"
3638   '(progn
3639      (define-key comint-mode-map "\C-w" 'comint-kill-region)
3640      (define-key comint-mode-map [C-S-backspace] 'comint-kill-whole-line)))
3641
3642 (eval-after-load "ielm"
3643   '(progn
3644      (define-key ielm-map "\C-w" 'comint-kill-region)
3645      (define-key ielm-map [C-S-backspace] 'comint-kill-whole-line)))
3646
3647 ;;;----- That's all, folks --------------------------------------------------
3648
3649 (provide 'dot-emacs)