el/dot-emacs.el: Fix configuration for SQL mode.
[profile] / el / dot-emacs.el
index 4b53771..bc512b4 100644 (file)
 ;;;--------------------------------------------------------------------------
 ;;; Check command-line.
 
 ;;;--------------------------------------------------------------------------
 ;;; Check command-line.
 
+(defgroup mdw nil
+  "Customization for mdw's Emacs configuration."
+  :prefix "mdw-")
+
+(defun mdw-check-command-line-switch (switch)
+  (let ((probe nil) (next command-line-args) (found nil))
+    (while next
+      (cond ((string= (car next) switch)
+            (setq found t)
+            (if probe (rplacd probe (cdr next))
+              (setq command-line-args (cdr next))))
+           (t
+            (setq probe next)))
+      (setq next (cdr next)))
+    found))
+
 (defvar mdw-fast-startup nil
   "Whether .emacs should optimize for rapid startup.
 This may be at the expense of cool features.")
 (defvar mdw-fast-startup nil
   "Whether .emacs should optimize for rapid startup.
 This may be at the expense of cool features.")
-(let ((probe nil) (next command-line-args))
-  (while next
-    (cond ((string= (car next) "--mdw-fast-startup")
-          (setq mdw-fast-startup t)
-          (if probe
-              (rplacd probe (cdr next))
-            (setq command-line-args (cdr next))))
-         (t
-          (setq probe next)))
-    (setq next (cdr next))))
+(setq mdw-fast-startup
+      (mdw-check-command-line-switch "--mdw-fast-startup"))
+
+(defvar mdw-splashy-startup nil
+  "Whether to show a splash screen and related frippery.")
+(setq mdw-splashy-startup
+      (mdw-check-command-line-switch "--mdw-splashy-startup"))
 
 ;;;--------------------------------------------------------------------------
 ;;; Some general utilities.
 
 (eval-when-compile
 
 ;;;--------------------------------------------------------------------------
 ;;; Some general utilities.
 
 (eval-when-compile
-  (unless (fboundp 'make-regexp)
-    (load "make-regexp"))
+  (unless (fboundp 'make-regexp) (load "make-regexp"))
   (require 'cl))
 
 (defmacro mdw-regexps (&rest list)
   (require 'cl))
 
 (defmacro mdw-regexps (&rest list)
@@ -85,23 +97,34 @@ This may be at the expense of cool features.")
   "Read the configuration variable named SYM."
   (unless mdw-config
     (setq mdw-config
   "Read the configuration variable named SYM."
   (unless mdw-config
     (setq mdw-config
-         (flet ((replace (what with)
-                  (goto-char (point-min))
-                  (while (re-search-forward what nil t)
-                    (replace-match with t))))
-           (with-temp-buffer
-             (insert-file-contents "~/.mdw.conf")
-             (replace  "^[ \t]*\\(#.*\\|\\)\n" "")
-             (replace (concat "^[ \t]*"
-                              "\\([-a-zA-Z0-9_.]*\\)"
-                              "[ \t]*=[ \t]*"
-                              "\\(.*[^ \t\n]\\|\\)"
-                              "[ \t]**\\(\n\\|$\\)")
-                      "(\\1 . \"\\2\")\n")
-             (car (read-from-string
-                   (concat "(" (buffer-string) ")")))))))
+           (flet ((replace (what with)
+                    (goto-char (point-min))
+                    (while (re-search-forward what nil t)
+                      (replace-match with t))))
+             (with-temp-buffer
+               (insert-file-contents "~/.mdw.conf")
+               (replace  "^[ \t]*\\(#.*\\)?\n" "")
+               (replace (concat "^[ \t]*"
+                                "\\([-a-zA-Z0-9_.]*\\)"
+                                "[ \t]*=[ \t]*"
+                                "\\(.*[^ \t\n]\\)?"
+                                "[ \t]**\\(\n\\|$\\)")
+                        "(\\1 . \"\\2\")\n")
+               (car (read-from-string
+                     (concat "(" (buffer-string) ")")))))))
   (cdr (assq sym mdw-config)))
 
   (cdr (assq sym mdw-config)))
 
+;; Width configuration.
+
+(defcustom mdw-column-width
+  (string-to-number (or (mdw-config 'emacs-width) "77"))
+  "Width of Emacs columns."
+  :type 'integer)
+(defcustom mdw-text-width mdw-column-width
+  "Expected width of text within columns."
+  :type 'integer
+  :safe 'integerp)
+
 ;; Local variables hacking.
 
 (defun run-local-vars-mode-hook ()
 ;; Local variables hacking.
 
 (defun run-local-vars-mode-hook ()
@@ -151,6 +174,17 @@ library."
     (set-frame-parameter frame 'menu-bar-lines 0)
     (set-frame-parameter frame 'menu-bar-lines old)))
 
     (set-frame-parameter frame 'menu-bar-lines 0)
     (set-frame-parameter frame 'menu-bar-lines old)))
 
+;; Page motion.
+
+(defun mdw-fixup-page-position ()
+  (unless (eq (char-before (point)) ?\f)
+    (forward-line 0)))
+
+(defadvice backward-page (after mdw-fixup compile activate)
+  (mdw-fixup-page-position))
+(defadvice forward-page (after mdw-fixup compile activate)
+  (mdw-fixup-page-position))
+
 ;; Splitting windows.
 
 (unless (fboundp 'scroll-bar-columns)
 ;; Splitting windows.
 
 (unless (fboundp 'scroll-bar-columns)
@@ -191,13 +225,16 @@ fringes is not taken out of the allowance for WIDTH, unlike
         ((>= width 0) (+ width (mdw-horizontal-window-overhead)))
         ((< width 0) width))))
 
         ((>= width 0) (+ width (mdw-horizontal-window-overhead)))
         ((< width 0) width))))
 
+(defun mdw-preferred-column-width ()
+  "Return the preferred column width."
+  (if (and window-system (mdw-emacs-version-p 22)) mdw-column-width
+    (1+ mdw-column-width)))
+
 (defun mdw-divvy-window (&optional width)
   "Split a wide window into appropriate widths."
   (interactive "P")
 (defun mdw-divvy-window (&optional width)
   "Split a wide window into appropriate widths."
   (interactive "P")
-  (setq width (cond (width (prefix-numeric-value width))
-                   ((and window-system (mdw-emacs-version-p 22))
-                    77)
-                   (t 78)))
+  (setq width (if width (prefix-numeric-value width)
+               (mdw-preferred-column-width)))
   (let* ((win (selected-window))
         (sb-width (mdw-horizontal-window-overhead))
         (c (/ (+ (window-width) sb-width)
   (let* ((win (selected-window))
         (sb-width (mdw-horizontal-window-overhead))
         (c (/ (+ (window-width) sb-width)
@@ -208,10 +245,53 @@ fringes is not taken out of the allowance for WIDTH, unlike
       (other-window 1))
     (select-window win)))
 
       (other-window 1))
     (select-window win)))
 
+(defun mdw-set-frame-width (columns &optional width)
+  "Set the current frame to be the correct width for COLUMNS columns.
+
+If WIDTH is non-nil, then it provides the width for the new columns.  (This
+can be set interactively with a prefix argument.)"
+  (interactive "nColumns: 
+P")
+  (setq width (if width (prefix-numeric-value width)
+               (mdw-preferred-column-width)))
+  (let ((sb-width (mdw-horizontal-window-overhead)))
+    (set-frame-width (selected-frame)
+                    (- (* columns (+ width sb-width))
+                       sb-width))
+    (mdw-divvy-window width)))
+
+(defcustom mdw-frame-width-fudge
+  (cond ((<= emacs-major-version 20) 1)
+       ((= emacs-major-version 26) 3)
+       (t 0))
+  "The number of extra columns to add to the desired frame width.
+
+This is sadly necessary because Emacs 26 is broken in this regard."
+  :type 'integer)
+
+(defcustom mdw-frame-colour-alist
+  '((black . ("#000000" . "#ffffff"))
+    (red . ("#2a0000" . "#ffffff"))
+    (green . ("#002a00" . "#ffffff"))
+    (blue . ("#00002a" . "#ffffff")))
+  "Alist mapping symbol names to (FOREGROUND . BACKGROUND) colour pairs."
+  :type '(alist :key-type symbol :value-type (cons color color)))
+
+(defun mdw-set-frame-colour (colour &optional frame)
+  (interactive "xColour name or (FOREGROUND . BACKGROUND) pair: 
+")
+  (when (and colour (symbolp colour))
+    (let ((entry (assq colour mdw-frame-colour-alist)))
+      (unless entry (error "Unknown colour `%s'" colour))
+      (setf colour (cdr entry))))
+  (set-frame-parameter frame 'background-color (car colour))
+  (set-frame-parameter frame 'foreground-color (cdr colour)))
+
 ;; Don't raise windows unless I say so.
 
 ;; Don't raise windows unless I say so.
 
-(defvar mdw-inhibit-raise-frame nil
-  "*Whether `raise-frame' should do nothing when the frame is mapped.")
+(defcustom mdw-inhibit-raise-frame nil
+  "Whether `raise-frame' should do nothing when the frame is mapped."
+  :type 'boolean)
 
 (defadvice raise-frame
     (around mdw-inhibit (&optional frame) activate compile)
 
 (defadvice raise-frame
     (around mdw-inhibit (&optional frame) activate compile)
@@ -230,6 +310,8 @@ frame is actually mapped on the screen."
        ad-do-it)))
 
 (mdw-advise-to-inhibit-raise-frame select-frame-set-input-focus)
        ad-do-it)))
 
 (mdw-advise-to-inhibit-raise-frame select-frame-set-input-focus)
+(mdw-advise-to-inhibit-raise-frame appt-disp-window)
+(mdw-advise-to-inhibit-raise-frame mouse-select-window)
 
 ;; Bug fix for markdown-mode, which breaks point positioning during
 ;; `query-replace'.
 
 ;; Bug fix for markdown-mode, which breaks point positioning during
 ;; `query-replace'.
@@ -285,6 +367,9 @@ it's currently off."
 
 ;; Functions for sexp diary entries.
 
 
 ;; Functions for sexp diary entries.
 
+(defvar mdw-diary-for-org-mode-p nil
+  "Display diary along with the agenda?")
+
 (defun mdw-not-org-mode (form)
   "As FORM, but not in Org mode agenda."
   (and (not mdw-diary-for-org-mode-p)
 (defun mdw-not-org-mode (form)
   "As FORM, but not in Org mode agenda."
   (and (not mdw-diary-for-org-mode-p)
@@ -313,9 +398,9 @@ as output rather than a string."
         (months ["Chaos" "Discord" "Confusion"
                  "Bureaucracy" "Aftermath"])
         (day-count [0 31 59 90 120 151 181 212 243 273 304 334])
         (months ["Chaos" "Discord" "Confusion"
                  "Bureaucracy" "Aftermath"])
         (day-count [0 31 59 90 120 151 181 212 243 273 304 334])
-        (year (- (extract-calendar-year date) 1900))
-        (month (1- (extract-calendar-month date)))
-        (day (1- (extract-calendar-day date)))
+        (year (- (calendar-extract-year date) 1900))
+        (month (1- (calendar-extract-month date)))
+        (day (1- (calendar-extract-day date)))
         (julian (+ (aref day-count month) day))
         (dyear (+ year 3066)))
     (if (and (= month 1) (= day 28))
         (julian (+ (aref day-count month) day))
         (dyear (+ year 3066)))
     (if (and (= month 1) (= day 28))
@@ -364,37 +449,57 @@ as output rather than a string."
                                (nth 2 when))))))))
     (eq w d)))
 
                                (nth 2 when))))))))
     (eq w d)))
 
-(defvar mdw-diary-for-org-mode-p nil)
-
 (defadvice org-agenda-list (around mdw-preserve-links activate)
   (let ((mdw-diary-for-org-mode-p t))
     ad-do-it))
 
 (defadvice org-agenda-list (around mdw-preserve-links activate)
   (let ((mdw-diary-for-org-mode-p t))
     ad-do-it))
 
-(defadvice diary-add-to-list (before mdw-trim-leading-space activate)
+(defcustom diary-time-regexp nil
+  "Regexp matching times in the diary buffer."
+  :type 'regexp)
+
+(defadvice diary-add-to-list (before mdw-trim-leading-space compile activate)
   "Trim leading space from the diary entry string."
   (save-match-data
   "Trim leading space from the diary entry string."
   (save-match-data
-    (let ((str (ad-get-arg 1)))
-      (ad-set-arg 1
-                 (cond ((null str) nil)
+    (let ((str (ad-get-arg 1))
+         (done nil) old)
+      (while (not done)
+       (setq old str)
+       (setq str (cond ((null str) nil)
+                       ((string-match "\\(^\\|\n\\)[ \t]+" str)
+                        (replace-match "\\1" nil nil str))
                        ((and mdw-diary-for-org-mode-p
                              (string-match (concat
                        ((and mdw-diary-for-org-mode-p
                              (string-match (concat
-                                            "^[ \t]*"
+                                            "\\(^\\|\n\\)"
                                             "\\(" diary-time-regexp
                                             "\\(-" diary-time-regexp "\\)?"
                                             "\\(" diary-time-regexp
                                             "\\(-" diary-time-regexp "\\)?"
-                                            "\\)[ \t]+")
+                                            "\\)"
+                                            "\\(\t[ \t]*\\| [ \t]+\\)")
                                            str))
                                            str))
-                        (replace-match "\\1 " nil nil str))
-                       ((string-match "^[ \t]+" str)
-                        (replace-match "" nil nil str))
+                        (replace-match "\\1\\2 " nil nil str))
                        ((and (not mdw-diary-for-org-mode-p)
                              (string-match "\\[\\[[^][]*]\\[\\([^][]*\\)]]"
                                            str))
                         (replace-match "\\1" nil nil str))
                        ((and (not mdw-diary-for-org-mode-p)
                              (string-match "\\[\\[[^][]*]\\[\\([^][]*\\)]]"
                                            str))
                         (replace-match "\\1" nil nil str))
-                       (t str))))))
+                       (t str)))
+       (if (equal str old) (setq done t)))
+      (ad-set-arg 1 str))))
+
+(defadvice org-bbdb-anniversaries (after mdw-fixup-list compile activate)
+  "Return a string rather than a list."
+  (with-temp-buffer
+    (let ((anyp nil))
+      (dolist (e (let ((ee ad-return-value))
+                  (if (atom ee) (list ee) ee)))
+       (when e
+         (when anyp (insert ?\n))
+         (insert e)
+         (setq anyp t)))
+      (setq ad-return-value
+             (and anyp (buffer-string))))))
 
 ;; Fighting with Org-mode's evil key maps.
 
 
 ;; Fighting with Org-mode's evil key maps.
 
-(defvar mdw-evil-keymap-keys
+(defcustom mdw-evil-keymap-keys
   '(([S-up] . [?\C-c up])
     ([S-down] . [?\C-c down])
     ([S-left] . [?\C-c left])
   '(([S-up] . [?\C-c up])
     ([S-down] . [?\C-c down])
     ([S-left] . [?\C-c left])
@@ -405,7 +510,9 @@ as output rather than a string."
     (([M-right] [?\e right]) . [C-right]))
   "Defines evil keybindings to clobber in `mdw-clobber-evil-keymap'.
 The value is an alist mapping evil keys (as a list, or singleton)
     (([M-right] [?\e right]) . [C-right]))
   "Defines evil keybindings to clobber in `mdw-clobber-evil-keymap'.
 The value is an alist mapping evil keys (as a list, or singleton)
-to good keys (in the same form).")
+to good keys (in the same form)."
+  :type '(alist :key-type (choice key-sequence (repeat key-sequence))
+               :value-type key-sequence))
 
 (defun mdw-clobber-evil-keymap (keymap)
   "Replace evil key bindings in the KEYMAP.
 
 (defun mdw-clobber-evil-keymap (keymap)
   "Replace evil key bindings in the KEYMAP.
@@ -429,25 +536,58 @@ Evil key bindings are defined in `mdw-evil-keymap-keys'."
        (dolist (key replacements)
          (define-key keymap key binding))))))
 
        (dolist (key replacements)
          (define-key keymap key binding))))))
 
-(eval-after-load "org-latex"
-  '(progn
-     (push '("strayman"
-            "\\documentclass{strayman}
+(defcustom mdw-org-latex-defs
+  '(("strayman"
+     "\\documentclass{strayman}
 \\usepackage[utf8]{inputenc}
 \\usepackage[palatino, helvetica, courier, maths=cmr]{mdwfonts}
 \\usepackage[utf8]{inputenc}
 \\usepackage[palatino, helvetica, courier, maths=cmr]{mdwfonts}
-\\usepackage[T1]{fontenc}
 \\usepackage{graphicx, tikz, mdwtab, mdwmath, crypto, longtable}"
 \\usepackage{graphicx, tikz, mdwtab, mdwmath, crypto, longtable}"
-            ("\\section{%s}" . "\\section*{%s}")
-            ("\\subsection{%s}" . "\\subsection*{%s}")
-            ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
-            ("\\paragraph{%s}" . "\\paragraph*{%s}")
-            ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
-          org-export-latex-classes)))
+     ("\\section{%s}" . "\\section*{%s}")
+     ("\\subsection{%s}" . "\\subsection*{%s}")
+     ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
+     ("\\paragraph{%s}" . "\\paragraph*{%s}")
+     ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
+  "Additional LaTeX class definitions."
+  :type '(alist :key-type string
+               :value-type (list string
+                                 (alist :inline t
+                                        :key-type string
+                                        :value-type string))))
+
+(eval-after-load "org-latex"
+  '(setq org-export-latex-classes
+          (append mdw-org-latex-defs org-export-latex-classes)))
+
+(eval-after-load "ox-latex"
+  '(setq org-latex-classes (append mdw-org-latex-defs org-latex-classes)
+        org-latex-caption-above nil
+        org-latex-default-packages-alist '(("AUTO" "inputenc" t)
+                                           ("T1" "fontenc" t)
+                                           ("" "fixltx2e" nil)
+                                           ("" "graphicx" t)
+                                           ("" "longtable" nil)
+                                           ("" "float" nil)
+                                           ("" "wrapfig" nil)
+                                           ("" "rotating" nil)
+                                           ("normalem" "ulem" t)
+                                           ("" "textcomp" t)
+                                           ("" "marvosym" t)
+                                           ("" "wasysym" t)
+                                           ("" "amssymb" t)
+                                           ("" "hyperref" nil)
+                                           "\\tolerance=1000")))
+
 
 (setq org-export-docbook-xslt-proc-command "xsltproc --output %o %s %i"
       org-export-docbook-xsl-fo-proc-command "fop %i.safe %o"
       org-export-docbook-xslt-stylesheet
 
 (setq org-export-docbook-xslt-proc-command "xsltproc --output %o %s %i"
       org-export-docbook-xsl-fo-proc-command "fop %i.safe %o"
       org-export-docbook-xslt-stylesheet
-      "/usr/share/xml/docbook/stylesheet/docbook-xsl/fo/docbook.xsl")
+       "/usr/share/xml/docbook/stylesheet/docbook-xsl/fo/docbook.xsl")
+
+;; Glasses.
+
+(setq glasses-separator "-"
+      glasses-separate-parentheses-p nil
+      glasses-uncapitalize-p t)
 
 ;; Some hacks to do with window placement.
 
 
 ;; Some hacks to do with window placement.
 
@@ -457,19 +597,22 @@ Evil key bindings are defined in `mdw-evil-keymap-keys'."
   (let ((home-frame (selected-frame))
        (buffer (get-buffer buffer-or-name))
        (safe-buffer (get-buffer "*scratch*")))
   (let ((home-frame (selected-frame))
        (buffer (get-buffer buffer-or-name))
        (safe-buffer (get-buffer "*scratch*")))
-    (mapc (lambda (frame)
-           (or (eq frame home-frame)
-               (mapc (lambda (window)
-                       (and (eq (window-buffer window) buffer)
-                            (set-window-buffer window safe-buffer)))
-                     (window-list frame))))
-         (frame-list))))
+    (dolist (frame (frame-list))
+      (unless (eq frame home-frame)
+       (dolist (window (window-list frame))
+         (when (eq (window-buffer window) buffer)
+           (set-window-buffer window safe-buffer)))))))
 
 (defvar mdw-inhibit-walk-windows nil
   "If non-nil, then `walk-windows' does nothing.
 This is used by advice on `switch-to-buffer-other-frame' to inhibit finding
 buffers in random frames.")
 
 
 (defvar mdw-inhibit-walk-windows nil
   "If non-nil, then `walk-windows' does nothing.
 This is used by advice on `switch-to-buffer-other-frame' to inhibit finding
 buffers in random frames.")
 
+(setq display-buffer--other-frame-action
+       '((display-buffer-reuse-window display-buffer-pop-up-frame)
+         (reusable-frames . nil)
+         (inhibit-same-window . t)))
+
 (defadvice walk-windows (around mdw-inhibit activate)
   "If `mdw-inhibit-walk-windows' is non-nil, then do nothing."
   (and (not mdw-inhibit-walk-windows)
 (defadvice walk-windows (around mdw-inhibit activate)
   "If `mdw-inhibit-walk-windows' is non-nil, then do nothing."
   (and (not mdw-inhibit-walk-windows)
@@ -486,6 +629,147 @@ Even if an existing window in some random frame looks tempting."
 Pretend they don't exist.  They might be on other display devices."
   (ad-set-arg 2 nil))
 
 Pretend they don't exist.  They might be on other display devices."
   (ad-set-arg 2 nil))
 
+(setq even-window-sizes nil
+      even-window-heights nil)
+
+;; Rename buffers along with files.
+
+(defvar mdw-inhibit-rename-buffer nil
+  "If non-nil, `rename-file' won't rename the buffer visiting the file.")
+
+(defmacro mdw-advise-to-inhibit-rename-buffer (function)
+  "Advise FUNCTION to set `mdw-inhibit-rename-buffer' while it runs.
+
+This will prevent `rename-file' from renaming the buffer."
+  `(defadvice ,function (around mdw-inhibit-rename-buffer compile activate)
+     "Don't rename the buffer when renaming the underlying file."
+     (let ((mdw-inhibit-rename-buffer t))
+       ad-do-it)))
+(mdw-advise-to-inhibit-rename-buffer recode-file-name)
+(mdw-advise-to-inhibit-rename-buffer set-visited-file-name)
+(mdw-advise-to-inhibit-rename-buffer backup-buffer)
+
+(defadvice rename-file (after mdw-rename-buffers (from to &optional forcep)
+                       compile activate)
+  "If a buffer is visiting the file, rename it to match the new name.
+
+Don't do this if `mdw-inhibit-rename-buffer' is non-nil."
+  (unless mdw-inhibit-rename-buffer
+    (let ((buffer (get-file-buffer from)))
+      (when buffer
+       (let ((to (if (not (string= (file-name-nondirectory to) "")) to
+                   (concat to (file-name-nondirectory from)))))
+         (with-current-buffer buffer
+           (set-visited-file-name to nil t)))))))
+
+;;;--------------------------------------------------------------------------
+;;; Improved compilation machinery.
+
+;; Uprated version of M-x compile.
+
+(setq compile-command
+       (let ((ncpu (with-temp-buffer
+                     (insert-file-contents "/proc/cpuinfo")
+                     (buffer-string)
+                     (count-matches "^processor\\s-*:"))))
+         (format "nice make -j%d -k" (* 2 ncpu))))
+
+(defun mdw-compilation-buffer-name (mode)
+  (concat "*" (downcase mode) ": "
+         (abbreviate-file-name default-directory) "*"))
+(setq compilation-buffer-name-function 'mdw-compilation-buffer-name)
+
+(eval-after-load "compile"
+  '(progn
+     (define-key compilation-shell-minor-mode-map "\C-c\M-g" 'recompile)))
+
+(defadvice compile (around hack-environment compile activate)
+  "Hack the environment inherited by inferiors in the compilation."
+  (let ((process-environment (copy-tree process-environment)))
+    (setenv "LD_PRELOAD" nil)
+    ad-do-it))
+
+(defun mdw-compile (command &optional directory comint)
+  "Initiate a compilation COMMAND, maybe in a different DIRECTORY.
+The DIRECTORY may be nil to not change.  If COMINT is t, then
+start an interactive compilation.
+
+Interactively, prompt for the command if the variable
+`compilation-read-command' is non-nil, or if requested through
+the prefix argument.  Prompt for the directory, and run
+interactively, if requested through the prefix.
+
+Use a prefix of 4, 6, 12, or 14, or type C-u between one and three times, to
+force prompting for a directory.
+
+Use a prefix of 2, 6, 10, or 14, or type C-u three times, to force
+prompting for the command.
+
+Use a prefix of 8, 10, 12, or 14, or type C-u twice or three times,
+to force interactive compilation."
+  (interactive
+   (let* ((prefix (prefix-numeric-value current-prefix-arg))
+         (command (eval compile-command))
+         (dir (and (plusp (logand prefix #x54))
+                   (read-directory-name "Compile in directory: "))))
+     (list (if (or compilation-read-command
+                  (plusp (logand prefix #x42)))
+              (compilation-read-command command)
+            command)
+          dir
+          (plusp (logand prefix #x58)))))
+  (let ((default-directory (or directory default-directory)))
+    (compile command comint)))
+
+;; Flymake support.
+
+(defun mdw-find-build-dir (build-file)
+  (catch 'found
+    (let* ((src-dir (file-name-as-directory (expand-file-name ".")))
+          (dir src-dir))
+      (loop
+       (when (file-exists-p (concat dir build-file))
+         (throw 'found dir))
+       (let ((sub (expand-file-name (file-relative-name src-dir dir)
+                                    (concat dir "build/"))))
+         (catch 'give-up
+           (loop
+             (when (file-exists-p (concat sub build-file))
+               (throw 'found sub))
+             (when (string= sub dir) (throw 'give-up nil))
+             (setq sub (file-name-directory (directory-file-name sub))))))
+       (when (string= dir
+                      (setq dir (file-name-directory
+                                 (directory-file-name dir))))
+         (throw 'found nil))))))
+
+(defun mdw-flymake-make-init ()
+  (let ((build-dir (mdw-find-build-dir "Makefile")))
+    (and build-dir
+        (let ((tmp-src (flymake-init-create-temp-buffer-copy
+                        #'flymake-create-temp-inplace)))
+          (flymake-get-syntax-check-program-args
+           tmp-src build-dir t t
+           #'flymake-get-make-cmdline)))))
+
+(setq flymake-allowed-file-name-masks
+       '(("\\.\\(?:[cC]\\|cc\\|cpp\\|cxx\\|c\\+\\+\\)\\'"
+          mdw-flymake-make-init)
+         ("\\.\\(?:[hH]\\|hh\\|hpp\\|hxx\\|h\\+\\+\\)\\'"
+          mdw-flymake-master-make-init)
+         ("\\.p[lm]" flymake-perl-init)))
+
+(setq flymake-mode-map
+       (let ((map (if (boundp 'flymake-mode-map)
+                      flymake-mode-map
+                    (make-sparse-keymap))))
+         (define-key map [?\C-c ?\C-f ?\C-p] 'flymake-goto-prev-error)
+         (define-key map [?\C-c ?\C-f ?\C-n] 'flymake-goto-next-error)
+         (define-key map [?\C-c ?\C-f ?\C-c] 'flymake-compile)
+         (define-key map [?\C-c ?\C-f ?\C-k] 'flymake-stop-all-syntax-checks)
+         (define-key map [?\C-c ?\C-f ?\C-e] 'flymake-popup-current-error-menu)
+         map))
+
 ;;;--------------------------------------------------------------------------
 ;;; Mail and news hacking.
 
 ;;;--------------------------------------------------------------------------
 ;;; Mail and news hacking.
 
@@ -504,8 +788,8 @@ Not much right now.  Just support for doing MailCrypt stuff."
            (make-local-variable 'paragraph-separate)
            (make-local-variable 'paragraph-start)
            (setq paragraph-start
            (make-local-variable 'paragraph-separate)
            (make-local-variable 'paragraph-start)
            (setq paragraph-start
-                 (concat "[ \t]*[-_][-_][-_]+$\\|^-- \\|-----\\|"
-                         paragraph-start))
+                   (concat "[ \t]*[-_][-_][-_]+$\\|^-- \\|-----\\|"
+                           paragraph-start))
            (setq paragraph-separate
                  (concat "[ \t]*[-_][-_][-_]+$\\|^-- \\|-----\\|"
                          paragraph-separate))))
            (setq paragraph-separate
                  (concat "[ \t]*[-_][-_][-_]+$\\|^-- \\|-----\\|"
                          paragraph-separate))))
@@ -561,10 +845,13 @@ so that it can be used for convenient filtering."
 
 ;; AUTHINFO GENERIC kludge.
 
 
 ;; AUTHINFO GENERIC kludge.
 
-(defvar nntp-authinfo-generic nil
+(defcustom nntp-authinfo-generic nil
   "Set to the `NNTPAUTH' string to pass on to `authinfo-kludge'.
 
   "Set to the `NNTPAUTH' string to pass on to `authinfo-kludge'.
 
-Use this to arrange for per-server settings.")
+Use this to arrange for per-server settings."
+  :type '(choice (const :tag "Use `NNTPAUTH' environment variable" nil)
+                string)
+  :safe 'stringp)
 
 (defun nntp-open-authinfo-kludge (buffer)
   "Open a connection to SERVER using `authinfo-kludge'."
 
 (defun nntp-open-authinfo-kludge (buffer)
   "Open a connection to SERVER using `authinfo-kludge'."
@@ -581,7 +868,92 @@ Use this to arrange for per-server settings.")
     proc))
 
 (eval-after-load "erc"
     proc))
 
 (eval-after-load "erc"
-    '(load "~/.ercrc.el"))
+  '(load "~/.ercrc.el"))
+
+;; Heavy-duty Gnus patching.
+
+(defun mdw-nnimap-transform-headers ()
+  (goto-char (point-min))
+  (let (article lines size string)
+    (block nil
+      (while (not (eobp))
+       (while (not (looking-at "\\* [0-9]+ FETCH"))
+         (delete-region (point) (progn (forward-line 1) (point)))
+         (when (eobp)
+           (return)))
+       (goto-char (match-end 0))
+       ;; Unfold quoted {number} strings.
+       (while (re-search-forward
+               "[^]][ (]{\\([0-9]+\\)}\r?\n"
+               (save-excursion
+                 ;; Start of the header section.
+                 (or (re-search-forward "] {[0-9]+}\r?\n" nil t)
+                     ;; Start of the next FETCH.
+                     (re-search-forward "\\* [0-9]+ FETCH" nil t)
+                     (point-max)))
+               t)
+         (setq size (string-to-number (match-string 1)))
+         (delete-region (+ (match-beginning 0) 2) (point))
+         (setq string (buffer-substring (point) (+ (point) size)))
+         (delete-region (point) (+ (point) size))
+         (insert (format "%S" (subst-char-in-string ?\n ?\s string)))
+         ;; [mdw] missing from upstream
+         (backward-char 1))
+       (beginning-of-line)
+       (setq article
+               (and (re-search-forward "UID \\([0-9]+\\)"
+                                       (line-end-position)
+                                       t)
+                    (match-string 1)))
+       (setq lines nil)
+       (setq size
+               (and (re-search-forward "RFC822.SIZE \\([0-9]+\\)"
+                                       (line-end-position)
+                                       t)
+                    (match-string 1)))
+       (beginning-of-line)
+       (when (search-forward "BODYSTRUCTURE" (line-end-position) t)
+         (let ((structure (ignore-errors
+                            (read (current-buffer)))))
+           (while (and (consp structure)
+                       (not (atom (car structure))))
+             (setq structure (car structure)))
+           (setq lines (if (and
+                            (stringp (car structure))
+                            (equal (upcase (nth 0 structure)) "MESSAGE")
+                            (equal (upcase (nth 1 structure)) "RFC822"))
+                           (nth 9 structure)
+                         (nth 7 structure)))))
+       (delete-region (line-beginning-position) (line-end-position))
+       (insert (format "211 %s Article retrieved." article))
+       (forward-line 1)
+       (when size
+         (insert (format "Chars: %s\n" size)))
+       (when lines
+         (insert (format "Lines: %s\n" lines)))
+       ;; Most servers have a blank line after the headers, but
+       ;; Davmail doesn't.
+       (unless (re-search-forward "^\r$\\|^)\r?$" nil t)
+         (goto-char (point-max)))
+       (delete-region (line-beginning-position) (line-end-position))
+       (insert ".")
+       (forward-line 1)))))
+
+(eval-after-load 'nnimap
+  '(defalias 'nnimap-transform-headers
+     (symbol-function 'mdw-nnimap-transform-headers)))
+
+(defadvice gnus-other-frame (around mdw-hack-frame-width compile activate)
+  "Always arrange for mail/news frames to be 80 columns wide."
+  (let ((default-frame-alist (cons `(width . ,(+ 80 mdw-frame-width-fudge))
+                                  (cl-delete 'width default-frame-alist
+                                             :key #'car))))
+    ad-do-it))
+
+;; Preferred programs.
+
+(setq mailcap-user-mime-data
+       '(((type . "application/pdf") (viewer . "mupdf %s"))))
 
 ;;;--------------------------------------------------------------------------
 ;;; Utility functions.
 
 ;;;--------------------------------------------------------------------------
 ;;; Utility functions.
@@ -650,7 +1022,7 @@ in REST."
                                     (erase-buffer)
                                     (shell-command "date +%Y-%m-%d" t)
                                     (goto-char (mark))
                                     (erase-buffer)
                                     (shell-command "date +%Y-%m-%d" t)
                                     (goto-char (mark))
-                                    (delete-backward-char 1)
+                                    (delete-char -1)
                                     (buffer-string))
                (kill-buffer buffer))))))
 
                                     (buffer-string))
                (kill-buffer buffer))))))
 
@@ -668,8 +1040,10 @@ in REST."
   ;; Now actually do the thing.
   (call-process "uuencode" file t nil name))
 
   ;; Now actually do the thing.
   (call-process "uuencode" file t nil name))
 
-(defvar np-file "~/.np"
-  "*Where the `now-playing' file is.")
+(defcustom np-file "~/.np"
+  "Where the `now-playing' file is."
+  :type 'file
+  :safe 'stringp)
 
 (defun np (&optional arg)
   "Grabs a `now-playing' string."
 
 (defun np (&optional arg)
   "Grabs a `now-playing' string."
@@ -693,7 +1067,8 @@ sequences separated by `.'."
        (cond ((null la) (throw 'done lb))
              ((null lb) (throw 'done nil))
              ((< (car la) (car lb)) (throw 'done t))
        (cond ((null la) (throw 'done lb))
              ((null lb) (throw 'done nil))
              ((< (car la) (car lb)) (throw 'done t))
-             ((= (car la) (car lb)) (setq la (cdr la) lb (cdr lb))))))))
+             ((= (car la) (car lb)) (setq la (cdr la) lb (cdr lb)))
+             (t (throw 'done nil)))))))
 
 (defun mdw-check-autorevert ()
   "Sets global-auto-revert-ignore-buffer appropriately for this buffer.
 
 (defun mdw-check-autorevert ()
   "Sets global-auto-revert-ignore-buffer appropriately for this buffer.
@@ -714,6 +1089,12 @@ tramp, which seems to get itself into a twist."
 (defadvice write-file (after mdw-autorevert activate)
   (mdw-check-autorevert))
 
 (defadvice write-file (after mdw-autorevert activate)
   (mdw-check-autorevert))
 
+(defun mdw-auto-revert ()
+  "Recheck all of the autorevertable buffers, and update VC modelines."
+  (interactive)
+  (let ((auto-revert-check-vc-info t))
+    (auto-revert-buffers)))
+
 ;;;--------------------------------------------------------------------------
 ;;; Dired hacking.
 
 ;;;--------------------------------------------------------------------------
 ;;; Dired hacking.
 
@@ -739,6 +1120,23 @@ options."
       (ad-set-arg 0 dir)
       ad-do-it)))
 
       (ad-set-arg 0 dir)
       ad-do-it)))
 
+(defun mdw-dired-run (args &optional syncp)
+  (interactive (let ((file (dired-get-filename t)))
+                (list (read-string (format "Arguments for %s: " file))
+                      current-prefix-arg)))
+  (funcall (if syncp 'shell-command 'async-shell-command)
+          (concat (shell-quote-argument (dired-get-filename nil))
+                  " " args)))
+
+(defadvice dired-do-flagged-delete
+    (around mdw-delete-if-prefix-argument activate compile)
+  (let ((delete-by-moving-to-trash (and (null current-prefix-arg)
+                                       delete-by-moving-to-trash)))
+    ad-do-it))
+
+(eval-after-load "dired"
+  '(define-key dired-mode-map "X" 'mdw-dired-run))
+
 ;;;--------------------------------------------------------------------------
 ;;; URL viewing.
 
 ;;;--------------------------------------------------------------------------
 ;;; URL viewing.
 
@@ -758,14 +1156,18 @@ If NEW-SESSION-P, start a new session."
            (w3m-browse-url url new-session-p))
        (select-window window)))))
 
            (w3m-browse-url url new-session-p))
        (select-window window)))))
 
-(defvar mdw-good-url-browsers
+(eval-after-load 'w3m
+  '(define-key w3m-mode-map [?\e ?\r] 'w3m-view-this-url-new-session))
+
+(defcustom mdw-good-url-browsers
   '(browse-url-mozilla
     browse-url-generic
     (w3m . mdw-w3m-browse-url)
     browse-url-w3)
   "List of good browsers for mdw-good-url-browsers.
 Each item is a browser function name, or a cons (CHECK . FUNC).
   '(browse-url-mozilla
     browse-url-generic
     (w3m . mdw-w3m-browse-url)
     browse-url-w3)
   "List of good browsers for mdw-good-url-browsers.
 Each item is a browser function name, or a cons (CHECK . FUNC).
-A symbol FOO stands for (FOO . FOO).")
+A symbol FOO stands for (FOO . FOO)."
+  :type '(repeat (choice function (cons function function))))
 
 (defun mdw-good-url-browser ()
   "Return a good URL browser.
 
 (defun mdw-good-url-browser ()
   "Return a good URL browser.
@@ -823,34 +1225,45 @@ CHECK is fboundp, and returning the correponding FUNC."
 
 ;; Useful variables.
 
 
 ;; Useful variables.
 
-(defvar mdw-fill-prefix nil
-  "*Used by `mdw-line-prefix' and `mdw-fill-paragraph'.
+(defcustom mdw-fill-prefix nil
+  "Used by `mdw-line-prefix' and `mdw-fill-paragraph'.
 If there's no fill prefix currently set (by the `fill-prefix'
 variable) and there's a match from one of the regexps here, it
 gets used to set the fill-prefix for the current operation.
 
 If there's no fill prefix currently set (by the `fill-prefix'
 variable) and there's a match from one of the regexps here, it
 gets used to set the fill-prefix for the current operation.
 
-The variable is a list of items of the form `REGEXP . PREFIX'; if
-the REGEXP matches, the PREFIX is used to set the fill prefix.
-It in turn is a list of things:
+The variable is a list of items of the form `PATTERN . PREFIX'; if
+the PATTERN matches, the PREFIX is used to set the fill prefix.
+
+A PATTERN is one of the following.
+
+  * STRING -- a regular expression, expected to match at point
+  * (eval . FORM) -- a Lisp form which must evaluate non-nil
+  * (if COND CONSEQ-PAT ALT-PAT) -- if COND evaluates non-nil, must match
+    CONSEQ-PAT; otherwise must match ALT-PAT
+  * (and PATTERN ...) -- must match all of the PATTERNs
+  * (or PATTERN ...) -- must match at least one PATTERN
+  * (not PATTERN) -- mustn't match (probably not useful)
+
+A PREFIX is a list of the following kinds of things:
 
 
-  STRING -- insert a literal string
-  (match . N) -- insert the thing matched by bracketed subexpression N
-  (pad . N) -- a string of whitespace the same width as subexpression N
-  (expr . FORM) -- the result of evaluating FORM")
+  * STRING -- insert a literal string
+  * (match . N) -- insert the thing matched by bracketed subexpression N
+  * (pad . N) -- a string of whitespace the same width as subexpression N
+  * (expr . FORM) -- the result of evaluating FORM
+
+Information about `bracketed subexpressions' comes from the match data,
+as modified during matching.")
 
 (make-variable-buffer-local 'mdw-fill-prefix)
 
 
 (make-variable-buffer-local 'mdw-fill-prefix)
 
-(defvar mdw-hanging-indents
+(defcustom mdw-hanging-indents
   (concat "\\(\\("
            "\\([*o+]\\|-[-#]?\\|[0-9]+\\.\\|\\[[0-9]+\\]\\|([a-zA-Z])\\)"
            "[ \t]+"
          "\\)?\\)")
   (concat "\\(\\("
            "\\([*o+]\\|-[-#]?\\|[0-9]+\\.\\|\\[[0-9]+\\]\\|([a-zA-Z])\\)"
            "[ \t]+"
          "\\)?\\)")
-  "*Standard regexp matching parts of a hanging indent.
-This is mainly useful in `auto-fill-mode'.")
-
-;; Setting things up.
-
-(fset 'mdw-do-auto-fill (symbol-function 'do-auto-fill))
+  "Standard regexp matching parts of a hanging indent.
+This is mainly useful in `auto-fill-mode'."
+  :type 'regexp)
 
 ;; Utility functions.
 
 
 ;; Utility functions.
 
@@ -864,16 +1277,41 @@ This is mainly useful in `auto-fill-mode'.")
          (funcall tabfun (point-min) (point-max))
          (setq s (buffer-substring (point-min) (1- (point-max)))))))))
 
          (funcall tabfun (point-min) (point-max))
          (setq s (buffer-substring (point-min) (1- (point-max)))))))))
 
-(defun mdw-examine-fill-prefixes (l)
-  "Given a list of dynamic fill prefixes, pick one which matches
-context and return the static fill prefix to use.  Point must be
-at the start of a line, and match data must be saved."
-  (cond ((not l) nil)
-              ((looking-at (car (car l)))
-               (mdw-maybe-tabify (apply #'concat
-                                        (mapcar #'mdw-do-prefix-match
-                                                (cdr (car l))))))
-              (t (mdw-examine-fill-prefixes (cdr l)))))
+(defun mdw-fill-prefix-match-p (pat)
+  "Return non-nil if PAT matches at the current position."
+  (cond ((stringp pat) (looking-at pat))
+       ((not (consp pat)) (error "Unknown pattern item `%S'" pat))
+       ((eq (car pat) 'eval) (eval (cdr pat)))
+       ((eq (car pat) 'if)
+        (if (or (null (cdr pat))
+                (null (cddr pat))
+                (null (cdddr pat))
+                (cddddr pat))
+            (error "Invalid `if' pattern `%S'" pat))
+        (mdw-fill-prefix-match-p (if (eval (cadr pat))
+                                     (caddr pat)
+                                   (cadddr pat))))
+       ((eq (car pat) 'and)
+        (let ((pats (cdr pat))
+              (ok t))
+          (while (and pats
+                      (or (mdw-fill-prefix-match-p (car pats))
+                          (setq ok nil)))
+            (setq pats (cdr pats)))
+          ok))
+       ((eq (car pat) 'or)
+        (let ((pats (cdr pat))
+              (ok nil))
+          (while (and pats
+                      (or (not (mdw-fill-prefix-match-p (car pats)))
+                          (progn (setq ok t) nil)))
+            (setq pats (cdr pats)))
+          ok))
+       ((eq (car pat) 'not)
+        (if (or (null (cdr pat)) (cddr pat))
+            (error "Invalid `not' pattern `%S'" pat))
+        (not (mdw-fill-prefix-match-p (car pats))))
+       (t (error "Unknown pattern form `%S'" pat))))
 
 (defun mdw-maybe-car (p)
   "If P is a pair, return (car P), otherwise just return P."
 
 (defun mdw-maybe-car (p)
   "If P is a pair, return (car P), otherwise just return P."
@@ -892,26 +1330,42 @@ at the start of a line, and match data must be saved."
   "Expand a dynamic prefix match element.
 See `mdw-fill-prefix' for details."
   (cond ((not (consp m)) (format "%s" m))
   "Expand a dynamic prefix match element.
 See `mdw-fill-prefix' for details."
   (cond ((not (consp m)) (format "%s" m))
-          ((eq (car m) 'match) (match-string (mdw-maybe-car (cdr m))))
-          ((eq (car m) 'pad) (mdw-padding (match-string
-                                           (mdw-maybe-car (cdr m)))))
-          ((eq (car m) 'eval) (eval (cdr m)))
-          (t "")))
+       ((eq (car m) 'match) (match-string (mdw-maybe-car (cdr m))))
+       ((eq (car m) 'pad) (mdw-padding (match-string
+                                        (mdw-maybe-car (cdr m)))))
+       ((eq (car m) 'eval) (eval (cdr m)))
+       (t "")))
+
+(defun mdw-examine-fill-prefixes (l)
+  "Given a list of dynamic fill prefixes, pick one which matches
+context and return the static fill prefix to use.  Point must be
+at the start of a line, and match data must be saved."
+  (let ((prefix nil))
+    (while (cond ((null l) nil)
+                ((mdw-fill-prefix-match-p (caar l))
+                 (setq prefix
+                         (mdw-maybe-tabify
+                          (apply #'concat
+                                 (mapcar #'mdw-do-prefix-match
+                                         (cdr (car l))))))
+                 nil))
+      (setq l (cdr l)))
+    prefix))
 
 (defun mdw-choose-dynamic-fill-prefix ()
   "Work out the dynamic fill prefix based on the variable `mdw-fill-prefix'."
   (cond ((and fill-prefix (not (string= fill-prefix ""))) fill-prefix)
 
 (defun mdw-choose-dynamic-fill-prefix ()
   "Work out the dynamic fill prefix based on the variable `mdw-fill-prefix'."
   (cond ((and fill-prefix (not (string= fill-prefix ""))) fill-prefix)
-          ((not mdw-fill-prefix) fill-prefix)
-          (t (save-excursion
-               (beginning-of-line)
-               (save-match-data
-                 (mdw-examine-fill-prefixes mdw-fill-prefix))))))
+       ((not mdw-fill-prefix) fill-prefix)
+       (t (save-excursion
+            (beginning-of-line)
+            (save-match-data
+              (mdw-examine-fill-prefixes mdw-fill-prefix))))))
 
 
-(defun do-auto-fill ()
+(defadvice do-auto-fill (around mdw-dynamic-fill-prefix () activate compile)
   "Handle auto-filling, working out a dynamic fill prefix in the
 case where there isn't a sensible static one."
   (let ((fill-prefix (mdw-choose-dynamic-fill-prefix)))
   "Handle auto-filling, working out a dynamic fill prefix in the
 case where there isn't a sensible static one."
   (let ((fill-prefix (mdw-choose-dynamic-fill-prefix)))
-    (mdw-do-auto-fill)))
+    ad-do-it))
 
 (defun mdw-fill-paragraph ()
   "Fill paragraph, getting a dynamic fill prefix."
 
 (defun mdw-fill-paragraph ()
   "Fill paragraph, getting a dynamic fill prefix."
@@ -919,23 +1373,108 @@ case where there isn't a sensible static one."
   (let ((fill-prefix (mdw-choose-dynamic-fill-prefix)))
     (fill-paragraph nil)))
 
   (let ((fill-prefix (mdw-choose-dynamic-fill-prefix)))
     (fill-paragraph nil)))
 
+(defun mdw-point-within-string-p ()
+  "Return non-nil if point is within a string."
+  (let ((state (syntax-ppss)))
+    (elt state 3)))
+
 (defun mdw-standard-fill-prefix (rx &optional mat)
   "Set the dynamic fill prefix, handling standard hanging indents and stuff.
 This is just a short-cut for setting the thing by hand, and by
 design it doesn't cope with anything approximating a complicated
 case."
   (setq mdw-fill-prefix
 (defun mdw-standard-fill-prefix (rx &optional mat)
   "Set the dynamic fill prefix, handling standard hanging indents and stuff.
 This is just a short-cut for setting the thing by hand, and by
 design it doesn't cope with anything approximating a complicated
 case."
   (setq mdw-fill-prefix
-          `((,(concat rx mdw-hanging-indents)
-             (match . 1)
-             (pad . ,(or mat 2))))))
+         `(((if (mdw-point-within-string-p)
+                ,(concat "\\(\\s-*\\)" mdw-hanging-indents)
+              ,(concat rx mdw-hanging-indents))
+            (match . 1)
+            (pad . ,(or mat 2))))))
+
+;;;--------------------------------------------------------------------------
+;;; Printing.
+
+;; Teach PostScript about a condensed variant of Courier.  I'm using 85% of
+;; the usual width, which happens to match `mdwfonts', and David Carlisle's
+;; `pslatex'.  (Once upon a time, I used 80%, but decided consistency with
+;; `pslatex' was useful.)
+(setq ps-user-defined-prologue "
+/CourierCondensed /Courier
+/CourierCondensed-Bold /Courier-Bold
+/CourierCondensed-Oblique /Courier-Oblique
+/CourierCondensed-BoldOblique /Courier-BoldOblique
+  4 { findfont [0.85 0 0 1 0 0] makefont definefont pop } repeat
+")
+
+;; Hack `ps-print''s settings.
+(eval-after-load 'ps-print
+  '(progn
+
+     ;; Notice that the comment-delimiters should be in italics too.
+     (pushnew 'font-lock-comment-delimiter-face ps-italic-faces)
+
+     ;; Select more suitable colours for the main kinds of tokens.  The
+     ;; colours set on the Emacs faces are chosen for use against a dark
+     ;; background, and work very badly on white paper.
+     (ps-extend-face '(font-lock-comment-face "darkgreen" nil italic))
+     (ps-extend-face '(font-lock-comment-delimiter-face "darkgreen" nil italic))
+     (ps-extend-face '(font-lock-string-face "RoyalBlue4" nil))
+     (ps-extend-face '(mdw-punct-face "sienna" nil))
+     (ps-extend-face '(mdw-number-face "OrangeRed3" nil))
+
+     ;; Teach `ps-print' about my condensed varsions of Courier.
+     (setq ps-font-info-database
+            (append '((CourierCondensed
+                       (fonts (normal . "CourierCondensed")
+                              (bold . "CourierCondensed-Bold")
+                              (italic . "CourierCondensed-Oblique")
+                              (bold-italic . "CourierCondensed-BoldOblique"))
+                       (size . 10.0)
+                       (line-height . 10.55)
+                       (space-width . 5.1)
+                       (avg-char-width . 5.1)))
+                    (cl-remove 'CourierCondensed ps-font-info-database
+                               :key #'car)))))
+
+;; Arrange to strip overlays from the buffer before we print .  This will
+;; prevent `flyspell' from interfering with the printout.  (It would be less
+;; bad if `ps-print' could merge the `flyspell' overlay face with the
+;; underlying `font-lock' face, but it can't (and that seems hard).  So
+;; instead we have this hack.
+;;
+;; The basic trick is to copy the relevant text from the buffer being printed
+;; into a temporary buffer and... just print that.  The text properties come
+;; with the text and end up in the new buffer, and the overlays get lost
+;; along the way.  Only problem is that the headers identifying the file
+;; being printed get confused, so remember the original buffer and reinstate
+;; it when constructing the headers.
+(defvar mdw-printing-buffer)
+
+(defadvice ps-generate-header
+    (around mdw-use-correct-buffer () activate compile)
+  "Print the correct name of the buffer being printed."
+  (with-current-buffer mdw-printing-buffer
+    ad-do-it))
+
+(defadvice ps-generate
+    (around mdw-strip-overlays (buffer from to genfunc) activate compile)
+  "Strip overlays -- in particular, from `flyspell' -- before printout."
+  (with-temp-buffer
+    (let ((mdw-printing-buffer buffer))
+      (insert-buffer-substring buffer from to)
+      (ad-set-arg 0 (current-buffer))
+      (ad-set-arg 1 (point-min))
+      (ad-set-arg 2 (point-max))
+      ad-do-it)))
 
 ;;;--------------------------------------------------------------------------
 ;;; Other common declarations.
 
 ;; Common mode settings.
 
 
 ;;;--------------------------------------------------------------------------
 ;;; Other common declarations.
 
 ;; Common mode settings.
 
-(defvar mdw-auto-indent t
-  "Whether to indent automatically after a newline.")
+(defcustom mdw-auto-indent t
+  "Whether to indent automatically after a newline."
+  :type 'boolean
+  :safe 'booleanp)
 
 (defun mdw-whitespace-mode (&optional arg)
   "Turn on/off whitespace mode, but don't highlight trailing space."
 
 (defun mdw-whitespace-mode (&optional arg)
   "Turn on/off whitespace mode, but don't highlight trailing space."
@@ -952,18 +1491,25 @@ case."
   (and mdw-auto-indent
        (cond ((eq major-mode 'lisp-mode)
              (local-set-key "\C-m" 'mdw-indent-newline-and-indent))
   (and mdw-auto-indent
        (cond ((eq major-mode 'lisp-mode)
              (local-set-key "\C-m" 'mdw-indent-newline-and-indent))
-            ((or (eq major-mode 'slime-repl-mode)
-                 (eq major-mode 'asm-mode))
+            ((derived-mode-p 'slime-repl-mode 'asm-mode 'comint-mode)
              nil)
             (t
              (local-set-key "\C-m" 'newline-and-indent))))
   (set (make-local-variable 'mdw-do-misc-mode-hacking) t)
   (local-set-key [C-return] 'newline)
   (make-local-variable 'page-delimiter)
              nil)
             (t
              (local-set-key "\C-m" 'newline-and-indent))))
   (set (make-local-variable 'mdw-do-misc-mode-hacking) t)
   (local-set-key [C-return] 'newline)
   (make-local-variable 'page-delimiter)
-  (setq page-delimiter "\f\\|^.*-\\{6\\}.*$")
+  (setq page-delimiter (concat       "^" "\f"
+                              "\\|" "^"
+                                    ".\\{0,4\\}"
+                                    "-\\{5\\}"
+                                    "\\(" " " ".*" " " "\\)?"
+                                    "-+"
+                                    ".\\{0,2\\}"
+                                    "$"))
   (setq comment-column 40)
   (auto-fill-mode 1)
   (setq comment-column 40)
   (auto-fill-mode 1)
-  (setq fill-column 77)
+  (setq fill-column mdw-text-width)
+  (flyspell-prog-mode)
   (and (fboundp 'gtags-mode)
        (gtags-mode))
   (if (fboundp 'hs-minor-mode)
   (and (fboundp 'gtags-mode)
        (gtags-mode))
   (if (fboundp 'hs-minor-mode)
@@ -973,6 +1519,7 @@ case."
   (trap (turn-on-font-lock)))
 
 (defun mdw-post-local-vars-misc-mode-config ()
   (trap (turn-on-font-lock)))
 
 (defun mdw-post-local-vars-misc-mode-config ()
+  (setq whitespace-line-column mdw-text-width)
   (when (and mdw-do-misc-mode-hacking
             (not buffer-read-only))
     (setq show-trailing-whitespace t)
   (when (and mdw-do-misc-mode-hacking
             (not buffer-read-only))
     (setq show-trailing-whitespace t)
@@ -1006,9 +1553,10 @@ case."
 
 ;; Backup file handling.
 
 
 ;; Backup file handling.
 
-(defvar mdw-backup-disable-regexps nil
-  "*List of regular expressions: if a file name matches any of
-these then the file is not backed up.")
+(defcustom mdw-backup-disable-regexps nil
+  "List of regular expressions: if a file name matches any of
+these then the file is not backed up."
+  :type '(repeat regexp))
 
 (defun mdw-backup-enable-predicate (name)
   "[mdw]'s default backup predicate.
 
 (defun mdw-backup-enable-predicate (name)
   "[mdw]'s default backup predicate.
@@ -1041,73 +1589,19 @@ doesn't match any of the regular expressions in
 (add-hook 'delete-frame-functions 'mdw-last-one-out-turn-off-the-lights)
 
 ;;;--------------------------------------------------------------------------
 (add-hook 'delete-frame-functions 'mdw-last-one-out-turn-off-the-lights)
 
 ;;;--------------------------------------------------------------------------
-;;; Where is point?
-
-(defvar mdw-point-overlay
-  (let ((ov (make-overlay 0 0))
-       (s "."))
-    (overlay-put ov 'priority 2)
-    (put-text-property 0 1 'display '(left-fringe vertical-bar) s)
-    (overlay-put ov 'before-string s)
-    (delete-overlay ov)
-    ov)
-  "An overlay used for showing where point is in the selected window.")
-
-(defun mdw-remove-point-overlay ()
-  "Remove the current-point overlay."
-  (delete-overlay mdw-point-overlay))
-
-(defun mdw-update-point-overlay ()
-  "Mark the current point position with an overlay."
-  (if (not mdw-point-overlay-mode)
-      (mdw-remove-point-overlay)
-    (overlay-put mdw-point-overlay 'window (selected-window))
-    (if (bolp)
-       (move-overlay mdw-point-overlay
-                     (point) (1+ (point)) (current-buffer))
-      (move-overlay mdw-point-overlay
-                   (1- (point)) (point) (current-buffer)))))
-
-(defvar mdw-point-overlay-buffers nil
-  "List of buffers using `mdw-point-overlay-mode'.")
-
-(define-minor-mode mdw-point-overlay-mode
-  "Indicate current line with an overlay."
-  :global nil
-  (let ((buffer (current-buffer)))
-    (setq mdw-point-overlay-buffers
-         (mapcan (lambda (buf)
-                   (if (and (buffer-live-p buf)
-                            (not (eq buf buffer)))
-                       (list buf)))
-                 mdw-point-overlay-buffers))
-    (if mdw-point-overlay-mode
-       (setq mdw-point-overlay-buffers
-             (cons buffer mdw-point-overlay-buffers))))
-  (cond (mdw-point-overlay-buffers
-        (add-hook 'pre-command-hook 'mdw-remove-point-overlay)
-        (add-hook 'post-command-hook 'mdw-update-point-overlay))
-       (t
-        (mdw-remove-point-overlay)
-        (remove-hook 'pre-command-hook 'mdw-remove-point-overlay)
-        (remove-hook 'post-command-hook 'mdw-update-point-overlay))))
-
-(define-globalized-minor-mode mdw-global-point-overlay-mode
-  mdw-point-overlay-mode
-  (lambda () (if (not (minibufferp)) (mdw-point-overlay-mode t))))
-
-;;;--------------------------------------------------------------------------
 ;;; Fullscreen-ness.
 
 ;;; Fullscreen-ness.
 
-(defvar mdw-full-screen-parameters
+(defcustom mdw-full-screen-parameters
   '((menu-bar-lines . 0)
   '((menu-bar-lines . 0)
-    ;(vertical-scroll-bars . nil)
+    ;;(vertical-scroll-bars . nil)
     )
     )
-  "Frame parameters to set when making a frame fullscreen.")
+  "Frame parameters to set when making a frame fullscreen."
+  :type '(alist :key-type symbol))
 
 
-(defvar mdw-full-screen-save
+(defcustom mdw-full-screen-save
   '(width height)
   '(width height)
-  "Extra frame parameters to save when setting fullscreen.")
+  "Extra frame parameters to save when setting fullscreen."
+  :type '(repeat symbol))
 
 (defun mdw-toggle-full-screen (&optional frame)
   "Show the FRAME fullscreen."
 
 (defun mdw-toggle-full-screen (&optional frame)
   "Show the FRAME fullscreen."
@@ -1155,22 +1649,22 @@ doesn't match any of the regular expressions in
   (((type w32)) :family "courier new" :height 85)
   (((type x)) :family "6x13" :foundry "trad" :height 130)
   (t :foreground "white" :background "black"))
   (((type w32)) :family "courier new" :height 85)
   (((type x)) :family "6x13" :foundry "trad" :height 130)
   (t :foreground "white" :background "black"))
-(if (mdw-emacs-version-p 23)
-    (mdw-define-face variable-pitch
-      (((type x)) :family "sans" :height 100))
-  (mdw-define-face variable-pitch
-    (((type x)) :family "helvetica" :height 90)))
+(mdw-define-face fixed-pitch-serif
+  (((type w32)) :family "courier new" :height 85 :weight bold)
+  (((type x)) :family "6x13" :foundry "trad" :height 130 :weight bold)
+  (t :foreground "white" :background "black" :weight bold))
+(mdw-define-face variable-pitch
+  (((type x)) :family "helvetica" :height 120))
 (mdw-define-face region
 (mdw-define-face region
-  (((type tty) (class color)) :background "blue")
-  (((type tty) (class mono)) :inverse-video t)
-  (t :background "grey30"))
+  (((min-colors 64)) :background "grey30")
+  (((class color)) :background "blue")
+  (t :inverse-video t))
 (mdw-define-face match
 (mdw-define-face match
-  (((type tty) (class color)) :background "blue")
-  (((type tty) (class mono)) :inverse-video t)
-  (t :background "blue"))
+  (((class color)) :background "blue")
+  (t :inverse-video t))
 (mdw-define-face mc/cursor-face
 (mdw-define-face mc/cursor-face
-  (((type tty) (class mono)) :inverse-video t)
-  (t :background "red"))
+  (((class color)) :background "red")
+  (t :inverse-video t))
 (mdw-define-face minibuffer-prompt
   (t :weight bold))
 (mdw-define-face mode-line
 (mdw-define-face minibuffer-prompt
   (t :weight bold))
 (mdw-define-face mode-line
@@ -1189,15 +1683,25 @@ doesn't match any of the regular expressions in
 (mdw-define-face fringe
   (t :foreground "yellow"))
 (mdw-define-face show-paren-match
 (mdw-define-face fringe
   (t :foreground "yellow"))
 (mdw-define-face show-paren-match
-  (((class color)) :background "darkgreen")
+  (((min-colors 64)) :background "darkgreen")
+  (((class color)) :background "green")
   (t :underline t))
 (mdw-define-face show-paren-mismatch
   (((class color)) :background "red")
   (t :inverse-video t))
 (mdw-define-face highlight
   (t :underline t))
 (mdw-define-face show-paren-mismatch
   (((class color)) :background "red")
   (t :inverse-video t))
 (mdw-define-face highlight
-  (((type x) (class color)) :background "DarkSeaGreen4")
-  (((type tty) (class color)) :background "cyan")
+  (((min-colors 64)) :background "DarkSeaGreen4")
+  (((class color)) :background "cyan")
+  (t :inverse-video t))
+
+(mdw-define-face viper-minibuffer-emacs (t nil))
+(mdw-define-face viper-minibuffer-insert (t nil))
+(mdw-define-face viper-minibuffer-vi (t nil))
+(mdw-define-face viper-replace-overlay
+  (((min-colors 64)) :background "darkred")
+  (((class color)) :background "red")
   (t :inverse-video t))
   (t :inverse-video t))
+(mdw-define-face viper-search (t :inherit isearch))
 
 (mdw-define-face holiday-face
   (t :background "red"))
 
 (mdw-define-face holiday-face
   (t :background "red"))
@@ -1209,6 +1713,13 @@ doesn't match any of the regular expressions in
 (mdw-define-face comint-highlight-input
   (t nil))
 
 (mdw-define-face comint-highlight-input
   (t nil))
 
+(mdw-define-face Man-underline
+  (((type tty)) :underline t)
+  (t :slant italic))
+
+(mdw-define-face ido-subdir
+  (t :foreground "cyan" :weight bold))
+
 (mdw-define-face dired-directory
   (t :foreground "cyan" :weight bold))
 (mdw-define-face dired-symlink
 (mdw-define-face dired-directory
   (t :foreground "cyan" :weight bold))
 (mdw-define-face dired-symlink
@@ -1219,8 +1730,12 @@ doesn't match any of the regular expressions in
 (mdw-define-face trailing-whitespace
   (((class color)) :background "red")
   (t :inverse-video t))
 (mdw-define-face trailing-whitespace
   (((class color)) :background "red")
   (t :inverse-video t))
+(mdw-define-face whitespace-line
+  (((class color)) :background "darkred")
+  (t :inverse-video t))
 (mdw-define-face mdw-punct-face
 (mdw-define-face mdw-punct-face
-  (((type tty)) :foreground "yellow") (t :foreground "burlywood2"))
+  (((min-colors 64)) :foreground "burlywood2")
+  (((class color)) :foreground "yellow"))
 (mdw-define-face mdw-number-face
   (t :foreground "yellow"))
 (mdw-define-face mdw-trivial-face)
 (mdw-define-face mdw-number-face
   (t :foreground "yellow"))
 (mdw-define-face mdw-trivial-face)
@@ -1239,81 +1754,109 @@ doesn't match any of the regular expressions in
 (mdw-define-face font-lock-variable-name-face
   (t :slant italic))
 (mdw-define-face font-lock-comment-delimiter-face
 (mdw-define-face font-lock-variable-name-face
   (t :slant italic))
 (mdw-define-face font-lock-comment-delimiter-face
-  (((class mono)) :weight bold)
-  (((type tty) (class color)) :foreground "green")
-  (t :slant italic :foreground "SeaGreen1"))
+  (((min-colors 64)) :slant italic :foreground "SeaGreen1")
+  (((class color)) :foreground "green")
+  (t :weight bold))
 (mdw-define-face font-lock-comment-face
 (mdw-define-face font-lock-comment-face
-  (((class mono)) :weight bold)
-  (((type tty) (class color)) :foreground "green")
-  (t :slant italic :foreground "SeaGreen1"))
+  (((min-colors 64)) :slant italic :foreground "SeaGreen1")
+  (((class color)) :foreground "green")
+  (t :weight bold))
 (mdw-define-face font-lock-string-face
 (mdw-define-face font-lock-string-face
-  (((class mono)) :weight bold)
-  (((class color)) :foreground "SkyBlue1"))
+  (((min-colors 64)) :foreground "SkyBlue1")
+  (((class color)) :foreground "cyan")
+  (t :weight bold))
 
 (mdw-define-face message-separator
   (t :background "red" :foreground "white" :weight bold))
 (mdw-define-face message-cited-text
   (default :slant italic)
 
 (mdw-define-face message-separator
   (t :background "red" :foreground "white" :weight bold))
 (mdw-define-face message-cited-text
   (default :slant italic)
-  (((type tty)) :foreground "cyan") (t :foreground "SkyBlue1"))
+  (((min-colors 64)) :foreground "SkyBlue1")
+  (((class color)) :foreground "cyan"))
 (mdw-define-face message-header-cc
   (default :slant italic)
 (mdw-define-face message-header-cc
   (default :slant italic)
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((min-colors 64)) :foreground "SeaGreen1")
+  (((class color)) :foreground "green"))
 (mdw-define-face message-header-newsgroups
   (default :slant italic)
 (mdw-define-face message-header-newsgroups
   (default :slant italic)
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((min-colors 64)) :foreground "SeaGreen1")
+  (((class color)) :foreground "green"))
 (mdw-define-face message-header-subject
 (mdw-define-face message-header-subject
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((min-colors 64)) :foreground "SeaGreen1")
+  (((class color)) :foreground "green"))
 (mdw-define-face message-header-to
 (mdw-define-face message-header-to
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((min-colors 64)) :foreground "SeaGreen1")
+  (((class color)) :foreground "green"))
 (mdw-define-face message-header-xheader
   (default :slant italic)
 (mdw-define-face message-header-xheader
   (default :slant italic)
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((min-colors 64)) :foreground "SeaGreen1")
+  (((class color)) :foreground "green"))
 (mdw-define-face message-header-other
   (default :slant italic)
 (mdw-define-face message-header-other
   (default :slant italic)
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((min-colors 64)) :foreground "SeaGreen1")
+  (((class color)) :foreground "green"))
 (mdw-define-face message-header-name
   (default :weight bold)
 (mdw-define-face message-header-name
   (default :weight bold)
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((min-colors 64)) :foreground "SeaGreen1")
+  (((class color)) :foreground "green"))
 
 (mdw-define-face which-func
   (t nil))
 
 (mdw-define-face gnus-header-name
   (default :weight bold)
 
 (mdw-define-face which-func
   (t nil))
 
 (mdw-define-face gnus-header-name
   (default :weight bold)
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((min-colors 64)) :foreground "SeaGreen1")
+  (((class color)) :foreground "green"))
 (mdw-define-face gnus-header-subject
 (mdw-define-face gnus-header-subject
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((min-colors 64)) :foreground "SeaGreen1")
+  (((class color)) :foreground "green"))
 (mdw-define-face gnus-header-from
 (mdw-define-face gnus-header-from
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((min-colors 64)) :foreground "SeaGreen1")
+  (((class color)) :foreground "green"))
 (mdw-define-face gnus-header-to
 (mdw-define-face gnus-header-to
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((min-colors 64)) :foreground "SeaGreen1")
+  (((class color)) :foreground "green"))
 (mdw-define-face gnus-header-content
   (default :slant italic)
 (mdw-define-face gnus-header-content
   (default :slant italic)
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((min-colors 64)) :foreground "SeaGreen1")
+  (((class color)) :foreground "green"))
 
 (mdw-define-face gnus-cite-1
 
 (mdw-define-face gnus-cite-1
-  (((type tty)) :foreground "cyan") (t :foreground "SkyBlue1"))
+  (((min-colors 64)) :foreground "SkyBlue1")
+  (((class color)) :foreground "cyan"))
 (mdw-define-face gnus-cite-2
 (mdw-define-face gnus-cite-2
-  (((type tty)) :foreground "blue") (t :foreground "RoyalBlue2"))
+  (((min-colors 64)) :foreground "RoyalBlue2")
+  (((class color)) :foreground "blue"))
 (mdw-define-face gnus-cite-3
 (mdw-define-face gnus-cite-3
-  (((type tty)) :foreground "magenta") (t :foreground "MediumOrchid"))
+  (((min-colors 64)) :foreground "MediumOrchid")
+  (((class color)) :foreground "magenta"))
 (mdw-define-face gnus-cite-4
 (mdw-define-face gnus-cite-4
-  (((type tty)) :foreground "red") (t :foreground "firebrick2"))
+  (((min-colors 64)) :foreground "firebrick2")
+  (((class color)) :foreground "red"))
 (mdw-define-face gnus-cite-5
 (mdw-define-face gnus-cite-5
-  (((type tty)) :foreground "yellow") (t :foreground "burlywood2"))
+  (((min-colors 64)) :foreground "burlywood2")
+  (((class color)) :foreground "yellow"))
 (mdw-define-face gnus-cite-6
 (mdw-define-face gnus-cite-6
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((min-colors 64)) :foreground "SeaGreen1")
+  (((class color)) :foreground "green"))
 (mdw-define-face gnus-cite-7
 (mdw-define-face gnus-cite-7
-  (((type tty)) :foreground "cyan") (t :foreground "SlateBlue1"))
+  (((min-colors 64)) :foreground "SlateBlue1")
+  (((class color)) :foreground "cyan"))
 (mdw-define-face gnus-cite-8
 (mdw-define-face gnus-cite-8
-  (((type tty)) :foreground "blue") (t :foreground "RoyalBlue2"))
+  (((min-colors 64)) :foreground "RoyalBlue2")
+  (((class color)) :foreground "blue"))
 (mdw-define-face gnus-cite-9
 (mdw-define-face gnus-cite-9
-  (((type tty)) :foreground "magenta") (t :foreground "purple2"))
+  (((min-colors 64)) :foreground "purple2")
+  (((class color)) :foreground "magenta"))
 (mdw-define-face gnus-cite-10
 (mdw-define-face gnus-cite-10
-  (((type tty)) :foreground "red") (t :foreground "DarkOrange2"))
+  (((min-colors 64)) :foreground "DarkOrange2")
+  (((class color)) :foreground "red"))
 (mdw-define-face gnus-cite-11
   (t :foreground "grey"))
 
 (mdw-define-face gnus-cite-11
   (t :foreground "grey"))
 
+(mdw-define-face gnus-emphasis-underline
+  (((type tty)) :underline t)
+  (t :slant italic))
+
 (mdw-define-face diff-header
   (t nil))
 (mdw-define-face diff-index
 (mdw-define-face diff-header
   (t nil))
 (mdw-define-face diff-index
@@ -1321,48 +1864,113 @@ doesn't match any of the regular expressions in
 (mdw-define-face diff-file-header
   (t :weight bold))
 (mdw-define-face diff-hunk-header
 (mdw-define-face diff-file-header
   (t :weight bold))
 (mdw-define-face diff-hunk-header
-  (t :foreground "SkyBlue1"))
+  (((min-colors 64)) :foreground "SkyBlue1")
+  (((class color)) :foreground "cyan"))
 (mdw-define-face diff-function
 (mdw-define-face diff-function
-  (t :foreground "SkyBlue1" :weight bold))
+  (default :weight bold)
+  (((min-colors 64)) :foreground "SkyBlue1")
+  (((class color)) :foreground "cyan"))
 (mdw-define-face diff-header
 (mdw-define-face diff-header
-  (t :background "grey10"))
+  (((min-colors 64)) :background "grey10"))
 (mdw-define-face diff-added
 (mdw-define-face diff-added
-  (t :foreground "green"))
+  (((class color)) :foreground "green"))
 (mdw-define-face diff-removed
 (mdw-define-face diff-removed
-  (t :foreground "red"))
+  (((class color)) :foreground "red"))
 (mdw-define-face diff-context
   (t nil))
 (mdw-define-face diff-refine-change
 (mdw-define-face diff-context
   (t nil))
 (mdw-define-face diff-refine-change
-  (((class color) (type x)) :background "RoyalBlue4")
+  (((min-colors 64)) :background "RoyalBlue4")
+  (t :underline t))
+(mdw-define-face diff-refine-removed
+  (((min-colors 64)) :background "#500")
+  (t :underline t))
+(mdw-define-face diff-refine-added
+  (((min-colors 64)) :background "#050")
   (t :underline t))
 
   (t :underline t))
 
-(mdw-define-face dylan-header-background
-  (((class color) (type x)) :background "NavyBlue")
-  (t :background "blue"))
+(setq ediff-force-faces t)
+(mdw-define-face ediff-current-diff-A
+  (((min-colors 64)) :background "darkred")
+  (((class color)) :background "red")
+  (t :inverse-video t))
+(mdw-define-face ediff-fine-diff-A
+  (((min-colors 64)) :background "red3")
+  (((class color)) :inverse-video t)
+  (t :inverse-video nil))
+(mdw-define-face ediff-even-diff-A
+  (((min-colors 64)) :background "#300"))
+(mdw-define-face ediff-odd-diff-A
+  (((min-colors 64)) :background "#300"))
+(mdw-define-face ediff-current-diff-B
+  (((min-colors 64)) :background "darkgreen")
+  (((class color)) :background "magenta")
+  (t :inverse-video t))
+(mdw-define-face ediff-fine-diff-B
+  (((min-colors 64)) :background "green4")
+  (((class color)) :inverse-video t)
+  (t :inverse-video nil))
+(mdw-define-face ediff-even-diff-B
+  (((min-colors 64)) :background "#020"))
+(mdw-define-face ediff-odd-diff-B
+  (((min-colors 64)) :background "#020"))
+(mdw-define-face ediff-current-diff-C
+  (((min-colors 64)) :background "darkblue")
+  (((class color)) :background "blue")
+  (t :inverse-video t))
+(mdw-define-face ediff-fine-diff-C
+  (((min-colors 64)) :background "blue1")
+  (((class color)) :inverse-video t)
+  (t :inverse-video nil))
+(mdw-define-face ediff-even-diff-C
+  (((min-colors 64)) :background "#004"))
+(mdw-define-face ediff-odd-diff-C
+  (((min-colors 64)) :background "#004"))
+(mdw-define-face ediff-current-diff-Ancestor
+  (((min-colors 64)) :background "#630")
+  (((class color)) :background "blue")
+  (t :inverse-video t))
+(mdw-define-face ediff-even-diff-Ancestor
+  (((min-colors 64)) :background "#320"))
+(mdw-define-face ediff-odd-diff-Ancestor
+  (((min-colors 64)) :background "#320"))
+
+(mdw-define-face magit-hash
+  (((min-colors 64)) :foreground "grey40")
+  (((class color)) :foreground "blue"))
+(mdw-define-face magit-diff-hunk-heading
+  (((min-colors 64)) :foreground "grey70" :background "grey25")
+  (((class color)) :foreground "yellow"))
+(mdw-define-face magit-diff-hunk-heading-highlight
+  (((min-colors 64)) :foreground "grey70" :background "grey35")
+  (((class color)) :foreground "yellow" :background "blue"))
+(mdw-define-face magit-diff-added
+  (((min-colors 64)) :foreground "#ddffdd" :background "#335533")
+  (((class color)) :foreground "green"))
+(mdw-define-face magit-diff-added-highlight
+  (((min-colors 64)) :foreground "#cceecc" :background "#336633")
+  (((class color)) :foreground "green" :background "blue"))
+(mdw-define-face magit-diff-removed
+  (((min-colors 64)) :foreground "#ffdddd" :background "#553333")
+  (((class color)) :foreground "red"))
+(mdw-define-face magit-diff-removed-highlight
+  (((min-colors 64)) :foreground "#eecccc" :background "#663333")
+  (((class color)) :foreground "red" :background "blue"))
+(mdw-define-face magit-blame-heading
+  (((min-colors 64)) :foreground "white" :background "grey25"
+                    :weight normal :slant normal)
+  (((class color)) :foreground "white" :background "blue"
+                  :weight normal :slant normal))
+(mdw-define-face magit-blame-name
+  (t :inherit magit-blame-heading :slant italic))
+(mdw-define-face magit-blame-date
+  (((min-colors 64)) :inherit magit-blame-heading :foreground "grey60")
+  (((class color)) :inherit magit-blame-heading :foreground "cyan"))
+(mdw-define-face magit-blame-summary
+  (t :inherit magit-blame-heading :weight bold))
 
 
-(mdw-define-face magit-diff-add
-  (t :foreground "green"))
-(mdw-define-face magit-diff-del
-  (t :foreground "red"))
-(mdw-define-face magit-diff-file-header
-  (t :weight bold))
-(mdw-define-face magit-diff-hunk-header
-  (t :foreground "SkyBlue1"))
-(mdw-define-face magit-item-highlight
-  (((type tty)) :background "blue")
-  (t :background "grey11"))
-(mdw-define-face magit-log-head-label-remote
-  (((type tty)) :background "cyan" :foreground "green")
-  (t :background "grey11" :foreground "DarkSeaGreen2" :box t))
-(mdw-define-face magit-log-head-label-local
-  (((type tty)) :background "cyan" :foreground "yellow")
-  (t :background "grey11" :foreground "LightSkyBlue1" :box t))
-(mdw-define-face magit-log-head-label-tags
-  (((type tty)) :background "red" :foreground "yellow")
-  (t :background "LemonChiffon1" :foreground "goldenrod4" :box t))
-(mdw-define-face magit-log-graph
-  (((type tty)) :foreground "magenta")
-  (t :foreground "grey80"))
+(mdw-define-face dylan-header-background
+  (((min-colors 64)) :background "NavyBlue")
+  (((class color)) :background "blue"))
 
 (mdw-define-face erc-input-face
   (t :foreground "red"))
 
 (mdw-define-face erc-input-face
   (t :foreground "red"))
@@ -1430,18 +2038,102 @@ doesn't match any of the regular expressions in
   (set-display-table-slot standard-display-table 5 bar))
 
 ;;;--------------------------------------------------------------------------
   (set-display-table-slot standard-display-table 5 bar))
 
 ;;;--------------------------------------------------------------------------
-;;; C programming configuration.
-
-;; Linux kernel hacking.
+;;; Where is point?
 
 
-(defvar linux-c-mode-hook)
+(mdw-define-face mdw-point-overlay-face
+  (((type graphic)))
+  (((min-colors 64)) :background "darkblue")
+  (((class color)) :background "blue")
+  (((type tty) (class mono)) :inverse-video t))
+
+(defcustom mdw-point-overlay-fringe-display '(vertical-bar . vertical-bar)
+  "Bitmaps to display in the left and right fringes in the current line."
+  :type '(cons symbol symbol))
+
+(defun mdw-configure-point-overlay ()
+  (let ((ov (make-overlay 0 0)))
+    (overlay-put ov 'priority 0)
+    (let* ((fringe (or mdw-point-overlay-fringe-display (cons nil nil)))
+          (left (car fringe)) (right (cdr fringe))
+          (s ""))
+      (when left
+       (let ((ss "."))
+         (put-text-property 0 1 'display `(left-fringe ,left) ss)
+         (setq s (concat s ss))))
+      (when right
+       (let ((ss "."))
+         (put-text-property 0 1 'display `(right-fringe ,right) ss)
+         (setq s (concat s ss))))
+      (when (or left right)
+       (overlay-put ov 'before-string s)))
+    (overlay-put ov 'face 'mdw-point-overlay-face)
+    (delete-overlay ov)
+    ov))
 
 
-(defun linux-c-mode ()
+(defvar mdw-point-overlay (mdw-configure-point-overlay)
+  "An overlay used for showing where point is in the selected window.")
+(defun mdw-reconfigure-point-overlay ()
   (interactive)
   (interactive)
-  (c-mode)
-  (setq major-mode 'linux-c-mode)
-  (setq mode-name "Linux C")
-  (run-hooks 'linux-c-mode-hook))
+  (setq mdw-point-overlay (mdw-configure-point-overlay)))
+
+(defun mdw-remove-point-overlay ()
+  "Remove the current-point overlay."
+  (delete-overlay mdw-point-overlay))
+
+(defun mdw-update-point-overlay ()
+  "Mark the current point position with an overlay."
+  (if (not mdw-point-overlay-mode)
+      (mdw-remove-point-overlay)
+    (overlay-put mdw-point-overlay 'window (selected-window))
+    (move-overlay mdw-point-overlay
+                 (line-beginning-position)
+                 (+ (line-end-position) 1))))
+
+(defvar mdw-point-overlay-buffers nil
+  "List of buffers using `mdw-point-overlay-mode'.")
+
+(define-minor-mode mdw-point-overlay-mode
+  "Indicate current line with an overlay."
+  :global nil
+  (let ((buffer (current-buffer)))
+    (setq mdw-point-overlay-buffers
+           (mapcan (lambda (buf)
+                     (if (and (buffer-live-p buf)
+                              (not (eq buf buffer)))
+                         (list buf)))
+                   mdw-point-overlay-buffers))
+    (if mdw-point-overlay-mode
+       (setq mdw-point-overlay-buffers
+               (cons buffer mdw-point-overlay-buffers))))
+  (cond (mdw-point-overlay-buffers
+        (add-hook 'pre-command-hook 'mdw-remove-point-overlay)
+        (add-hook 'post-command-hook 'mdw-update-point-overlay))
+       (t
+        (mdw-remove-point-overlay)
+        (remove-hook 'pre-command-hook 'mdw-remove-point-overlay)
+        (remove-hook 'post-command-hook 'mdw-update-point-overlay))))
+
+(define-globalized-minor-mode mdw-global-point-overlay-mode
+  mdw-point-overlay-mode
+  (lambda () (if (not (minibufferp)) (mdw-point-overlay-mode t))))
+
+(defvar mdw-terminal-title-alist nil)
+(defun mdw-update-terminal-title ()
+  (when (let ((term (frame-parameter nil 'tty-type)))
+         (and term (string-match "^xterm" term)))
+    (let* ((tty (frame-parameter nil 'tty))
+          (old (assoc tty mdw-terminal-title-alist))
+          (new (format-mode-line frame-title-format)))
+      (unless (and old (equal (cdr old) new))
+       (if old (rplacd old new)
+         (setq mdw-terminal-title-alist
+                 (cons (cons tty new) mdw-terminal-title-alist)))
+       (send-string-to-terminal (concat "\e]2;" new "\e\\"))))))
+
+(add-hook 'post-command-hook 'mdw-update-terminal-title)
+
+;;;--------------------------------------------------------------------------
+;;; C programming configuration.
 
 ;; Make C indentation nice.
 
 
 ;; Make C indentation nice.
 
@@ -1461,32 +2153,121 @@ doesn't match any of the regular expressions in
        c-basic-offset
       nil)))
 
        c-basic-offset
       nil)))
 
-(defun mdw-c-style ()
-  (c-add-style "[mdw] C and C++ style"
-              '((c-basic-offset . 2)
-                (comment-column . 40)
-                (c-class-key . "class")
-                (c-backslash-column . 72)
-                (c-offsets-alist
-                 (substatement-open . (add 0 c-indent-one-line-block))
-                 (defun-open . (add 0 c-indent-one-line-block))
-                 (arglist-cont-nonempty . mdw-c-lineup-arglist)
-                 (topmost-intro . mdw-c-indent-extern-mumble)
-                 (cpp-define-intro . 0)
-                 (knr-argdecl . 0)
-                 (inextern-lang . [0])
-                 (label . 0)
-                 (case-label . +)
-                 (access-label . -)
-                 (inclass . +)
-                 (inline-open . ++)
-                 (statement-cont . +)
-                 (statement-case-intro . +)))
-              t))
+(defun mdw-c-indent-arglist-nested (langelem)
+  "Indent continued argument lists.
+If we've nested more than one argument list, then only introduce a single
+indentation anyway."
+  (let ((context c-syntactic-context)
+       (pos (c-langelem-2nd-pos c-syntactic-element))
+       (should-indent-p t))
+    (while (and context
+               (eq (caar context) 'arglist-cont-nonempty))
+      (when (and (= (caddr (pop context)) pos)
+                context
+                (memq (caar context) '(arglist-intro
+                                       arglist-cont-nonempty)))
+       (setq should-indent-p nil)))
+    (if should-indent-p '+ 0)))
+
+(defvar mdw-define-c-styles-hook nil
+  "Hook run when `cc-mode' starts up to define styles.")
+
+(defun mdw-merge-style-alists (first second)
+  (let ((output nil))
+    (dolist (item first)
+      (let ((key (car item)) (value (cdr item)))
+       (if (string-suffix-p "-alist" (symbol-name key))
+           (push (cons key
+                       (mdw-merge-style-alists value
+                                               (cdr (assoc key second))))
+                 output)
+         (push item output))))
+    (dolist (item second)
+      (unless (assoc (car item) first)
+       (push item output)))
+    (nreverse output)))
+
+(cl-defmacro mdw-define-c-style (name (&optional parent) &rest assocs)
+  "Define a C style, called NAME (a symbol) based on PARENT, setting ASSOCs.
+A function, named `mdw-define-c-style/NAME', is defined to actually install
+the style using `c-add-style', and added to the hook
+`mdw-define-c-styles-hook'.  If CC Mode is already loaded, then the style is
+set."
+  (declare (indent defun))
+  (let* ((name-string (symbol-name name))
+        (var (intern (concat "mdw-c-style/" name-string)))
+        (func (intern (concat "mdw-define-c-style/" name-string))))
+    `(progn
+       (setq ,var
+              ,(if (null parent)
+                   `',assocs
+                 (let ((parent-list (intern (concat "mdw-c-style/"
+                                                    (symbol-name parent)))))
+                   `(mdw-merge-style-alists ',assocs ,parent-list))))
+       (defun ,func () (c-add-style ,name-string ,var))
+       (and (featurep 'cc-mode) (,func))
+       (add-hook 'mdw-define-c-styles-hook ',func)
+       ',name)))
+
+(eval-after-load "cc-mode"
+  '(run-hooks 'mdw-define-c-styles-hook))
+
+(mdw-define-c-style mdw-c ()
+  (c-basic-offset . 2)
+  (comment-column . 40)
+  (c-class-key . "class")
+  (c-backslash-column . 72)
+  (c-label-minimum-indentation . 0)
+  (c-offsets-alist (substatement-open . (add 0 c-indent-one-line-block))
+                  (defun-open . (add 0 c-indent-one-line-block))
+                  (arglist-cont-nonempty . mdw-c-lineup-arglist)
+                  (topmost-intro . mdw-c-indent-extern-mumble)
+                  (cpp-define-intro . 0)
+                  (knr-argdecl . 0)
+                  (inextern-lang . [0])
+                  (label . 0)
+                  (case-label . +)
+                  (access-label . -)
+                  (inclass . +)
+                  (inline-open . ++)
+                  (statement-cont . +)
+                  (statement-case-intro . +)))
+
+(mdw-define-c-style mdw-trustonic-c (mdw-c)
+  (c-basic-offset . 4)
+  (c-offsets-alist (access-label . -2)))
+
+(mdw-define-c-style mdw-trustonic-alec-c (mdw-trustonic-c)
+  (comment-column . 0)
+  (c-indent-comment-alist (anchored-comment . (column . 0))
+                         (end-block . (space . 1))
+                         (cpp-end-block . (space . 1))
+                         (other . (space . 1)))
+  (c-offsets-alist (arglist-cont-nonempty . mdw-c-indent-arglist-nested)))
+
+(defun mdw-set-default-c-style (modes style)
+  "Update the default CC Mode style for MODES to be STYLE.
+
+MODES may be a list of major mode names or a singleton.  STYLE is a style
+name, as a symbol."
+  (let ((modes (if (listp modes) modes (list modes)))
+       (style (symbol-name style)))
+    (setq c-default-style
+           (append (mapcar (lambda (mode)
+                             (cons mode style))
+                           modes)
+                   (remove-if (lambda (assoc)
+                                (memq (car assoc) modes))
+                              (if (listp c-default-style)
+                                  c-default-style
+                                (list (cons 'other c-default-style))))))))
+(setq c-default-style "mdw-c")
+
+(mdw-set-default-c-style '(c-mode c++-mode) 'mdw-c)
 
 (defvar mdw-c-comment-fill-prefix
   `((,(concat "\\([ \t]*/?\\)"
 
 (defvar mdw-c-comment-fill-prefix
   `((,(concat "\\([ \t]*/?\\)"
-             "\\(\*\\|//]\\)"
+             "\\(\\*\\|//\\)"
              "\\([ \t]*\\)"
              "\\([A-Za-z]+:[ \t]*\\)?"
              mdw-hanging-indents)
              "\\([ \t]*\\)"
              "\\([A-Za-z]+:[ \t]*\\)?"
              mdw-hanging-indents)
@@ -1501,11 +2282,7 @@ doesn't match any of the regular expressions in
   (modify-syntax-entry ?\n "> b")
 
   ;; Other stuff.
   (modify-syntax-entry ?\n "> b")
 
   ;; Other stuff.
-  (mdw-c-style)
-  (setq c-hanging-comment-ender-p nil
-       c-backslash-column 72
-       c-label-minimum-indentation 0
-       mdw-fill-prefix mdw-c-comment-fill-prefix)
+  (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
 
   ;; Now define things to be fontified.
   (make-local-variable 'font-lock-keywords)
 
   ;; Now define things to be fontified.
   (make-local-variable 'font-lock-keywords)
@@ -1625,7 +2402,7 @@ doesn't match any of the regular expressions in
                      "__typeof__"       ;GCC
                      "__volatile__"     ;GCC
                      ))
                      "__typeof__"       ;GCC
                      "__volatile__"     ;GCC
                      ))
-       (c-constants
+       (c-builtins
         (mdw-regexps "false"            ;C++, C99 macro
                      "this"             ;C++
                      "true"             ;C++, C99 macro
         (mdw-regexps "false"            ;C++, C99 macro
                      "this"             ;C++
                      "true"             ;C++, C99 macro
@@ -1640,52 +2417,56 @@ doesn't match any of the regular expressions in
                      "selector")))
 
     (setq font-lock-keywords
                      "selector")))
 
     (setq font-lock-keywords
-         (list
-
-          ;; Fontify include files as strings.
-          (list (concat "^[ \t]*\\#[ \t]*"
-                        "\\(include\\|import\\)"
-                        "[ \t]*\\(<[^>]+\\(>\\|\\)\\)")
-                '(2 font-lock-string-face))
-
-          ;; Preprocessor directives are `references'?.
-          (list (concat "^\\([ \t]*#[ \t]*\\(\\("
-                        preprocessor-keywords
-                        "\\)\\>\\|[0-9]+\\|$\\)\\)")
-                '(1 font-lock-keyword-face))
-
-          ;; Handle the keywords defined above.
-          (list (concat "@\\<\\(" objc-keywords "\\)\\>")
-                '(0 font-lock-keyword-face))
-
-          (list (concat "\\<\\(" c-keywords "\\)\\>")
-                '(0 font-lock-keyword-face))
-
-          (list (concat "\\<\\(" c-constants "\\)\\>")
-                '(0 font-lock-variable-name-face))
-
-          ;; Handle numbers too.
-          ;;
-          ;; This looks strange, I know.  It corresponds to the
-          ;; preprocessor's idea of what a number looks like, rather than
-          ;; anything sensible.
-          (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
-                        "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
-                '(0 mdw-number-face))
-
-          ;; And anything else is punctuation.
-          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face))))))
+           (list
+
+            ;; Fontify include files as strings.
+            (list (concat "^[ \t]*\\#[ \t]*"
+                          "\\(include\\|import\\)"
+                          "[ \t]*\\(<[^>]+>?\\)")
+                  '(2 font-lock-string-face))
+
+            ;; Preprocessor directives are `references'?.
+            (list (concat "^\\([ \t]*#[ \t]*\\(\\("
+                          preprocessor-keywords
+                          "\\)\\>\\|[0-9]+\\|$\\)\\)")
+                  '(1 font-lock-keyword-face))
+
+            ;; Handle the keywords defined above.
+            (list (concat "@\\<\\(" objc-keywords "\\)\\>")
+                  '(0 font-lock-keyword-face))
+
+            (list (concat "\\<\\(" c-keywords "\\)\\>")
+                  '(0 font-lock-keyword-face))
+
+            (list (concat "\\<\\(" c-builtins "\\)\\>")
+                  '(0 font-lock-variable-name-face))
+
+            ;; Handle numbers too.
+            ;;
+            ;; This looks strange, I know.  It corresponds to the
+            ;; preprocessor's idea of what a number looks like, rather than
+            ;; anything sensible.
+            (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
+                          "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
+                  '(0 mdw-number-face))
+
+            ;; And anything else is punctuation.
+            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+                  '(0 mdw-punct-face))))))
+
+(define-derived-mode sod-mode c-mode "Sod"
+  "Major mode for editing Sod code.")
+(push '("\\.sod$" . sod-mode) auto-mode-alist)
+
+(dolist (hook '(c-mode-hook objc-mode-hook c++-mode-hook))
+  (add-hook hook 'mdw-misc-mode-config t)
+  (add-hook hook 'mdw-fontify-c-and-c++ t))
 
 ;;;--------------------------------------------------------------------------
 ;;; AP calc mode.
 
 
 ;;;--------------------------------------------------------------------------
 ;;; AP calc mode.
 
-(defun apcalc-mode ()
-  (interactive)
-  (c-mode)
-  (setq major-mode 'apcalc-mode)
-  (setq mode-name "AP Calc")
-  (run-hooks 'apcalc-mode-hook))
+(define-derived-mode apcalc-mode c-mode "AP Calc"
+  "Major mode for editing Calc code.")
 
 (defun mdw-fontify-apcalc ()
 
 
 (defun mdw-fontify-apcalc ()
 
@@ -1694,9 +2475,6 @@ doesn't match any of the regular expressions in
   (modify-syntax-entry ?/ ". 14")
 
   ;; Other stuff.
   (modify-syntax-entry ?/ ". 14")
 
   ;; Other stuff.
-  (mdw-c-style)
-  (setq c-hanging-comment-ender-p nil)
-  (setq c-backslash-column 72)
   (setq comment-start "/* ")
   (setq comment-end " */")
   (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
   (setq comment-start "/* ")
   (setq comment-end " */")
   (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
@@ -1710,90 +2488,108 @@ doesn't match any of the regular expressions in
                      "show" "static" "switch" "while" "write")))
 
     (setq font-lock-keywords
                      "show" "static" "switch" "while" "write")))
 
     (setq font-lock-keywords
-         (list
+           (list
 
 
-          ;; Handle the keywords defined above.
-          (list (concat "\\<\\(" c-keywords "\\)\\>")
-                '(0 font-lock-keyword-face))
+            ;; Handle the keywords defined above.
+            (list (concat "\\<\\(" c-keywords "\\)\\>")
+                  '(0 font-lock-keyword-face))
 
 
-          ;; Handle numbers too.
-          ;;
-          ;; This looks strange, I know.  It corresponds to the
-          ;; preprocessor's idea of what a number looks like, rather than
-          ;; anything sensible.
-          (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
-                        "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
-                '(0 mdw-number-face))
+            ;; Handle numbers too.
+            ;;
+            ;; This looks strange, I know.  It corresponds to the
+            ;; preprocessor's idea of what a number looks like, rather than
+            ;; anything sensible.
+            (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
+                          "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
+                  '(0 mdw-number-face))
 
 
-          ;; And anything else is punctuation.
-          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face))))))
+            ;; And anything else is punctuation.
+            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+                  '(0 mdw-punct-face))))))
+
+(progn
+  (add-hook 'apcalc-mode-hook 'mdw-misc-mode-config t)
+  (add-hook 'apcalc-mode-hook 'mdw-fontify-apcalc t))
 
 ;;;--------------------------------------------------------------------------
 ;;; Java programming configuration.
 
 ;; Make indentation nice.
 
 
 ;;;--------------------------------------------------------------------------
 ;;; Java programming configuration.
 
 ;; Make indentation nice.
 
-(defun mdw-java-style ()
-  (c-add-style "[mdw] Java style"
-              '((c-basic-offset . 2)
-                (c-offsets-alist (substatement-open . 0)
-                                 (label . +)
-                                 (case-label . +)
-                                 (access-label . 0)
-                                 (inclass . +)
-                                 (statement-case-intro . +)))
-              t))
+(mdw-define-c-style mdw-java ()
+  (c-basic-offset . 2)
+  (c-backslash-column . 72)
+  (c-offsets-alist (substatement-open . 0)
+                  (label . +)
+                  (case-label . +)
+                  (access-label . 0)
+                  (inclass . +)
+                  (statement-case-intro . +)))
+(mdw-set-default-c-style 'java-mode 'mdw-java)
 
 ;; Declare Java fontification style.
 
 (defun mdw-fontify-java ()
 
 
 ;; Declare Java fontification style.
 
 (defun mdw-fontify-java ()
 
+  ;; Fiddle with some syntax codes.
+  (modify-syntax-entry ?@ ".")
+  (modify-syntax-entry ?@ "." font-lock-syntax-table)
+
   ;; Other stuff.
   ;; Other stuff.
-  (mdw-java-style)
-  (setq c-hanging-comment-ender-p nil)
-  (setq c-backslash-column 72)
   (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
 
   ;; Now define things to be fontified.
   (make-local-variable 'font-lock-keywords)
   (let ((java-keywords
   (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
 
   ;; Now define things to be fontified.
   (make-local-variable 'font-lock-keywords)
   (let ((java-keywords
-        (mdw-regexps "abstract" "boolean" "break" "byte" "case" "catch"
-                     "char" "class" "const" "continue" "default" "do"
-                     "double" "else" "extends" "final" "finally" "float"
-                     "for" "goto" "if" "implements" "import" "instanceof"
-                     "int" "interface" "long" "native" "new" "package"
-                     "private" "protected" "public" "return" "short"
-                     "static" "switch" "synchronized" "throw" "throws"
-                     "transient" "try" "void" "volatile" "while"))
-
-       (java-constants
+        (mdw-regexps "abstract" "assert"
+                     "boolean" "break" "byte"
+                     "case" "catch" "char" "class" "const" "continue"
+                     "default" "do" "double"
+                     "else" "enum" "extends"
+                     "final" "finally" "float" "for"
+                     "goto"
+                     "if" "implements" "import" "instanceof" "int"
+                     "interface"
+                     "long"
+                     "native" "new"
+                     "package" "private" "protected" "public"
+                     "return"
+                     "short" "static" "strictfp" "switch" "synchronized"
+                     "throw" "throws" "transient" "try"
+                     "void" "volatile"
+                     "while"))
+
+       (java-builtins
         (mdw-regexps "false" "null" "super" "this" "true")))
 
     (setq font-lock-keywords
         (mdw-regexps "false" "null" "super" "this" "true")))
 
     (setq font-lock-keywords
-         (list
-
-          ;; Handle the keywords defined above.
-          (list (concat "\\<\\(" java-keywords "\\)\\>")
-                '(0 font-lock-keyword-face))
-
-          ;; Handle the magic constants defined above.
-          (list (concat "\\<\\(" java-constants "\\)\\>")
-                '(0 font-lock-variable-name-face))
-
-          ;; Handle numbers too.
-          ;;
-          ;; The following isn't quite right, but it's close enough.
-          (list (concat "\\<\\("
-                        "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
-                        "[0-9]+\\(\\.[0-9]*\\|\\)"
-                        "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
-                        "[lLfFdD]?")
-                '(0 mdw-number-face))
-
-          ;; And anything else is punctuation.
-          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face))))))
+           (list
+
+            ;; Handle the keywords defined above.
+            (list (concat "\\<\\(" java-keywords "\\)\\>")
+                  '(0 font-lock-keyword-face))
+
+            ;; Handle the magic builtins defined above.
+            (list (concat "\\<\\(" java-builtins "\\)\\>")
+                  '(0 font-lock-variable-name-face))
+
+            ;; Handle numbers too.
+            ;;
+            ;; The following isn't quite right, but it's close enough.
+            (list (concat "\\<\\("
+                          "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
+                          "[0-9]+\\(\\.[0-9]*\\)?"
+                          "\\([eE][-+]?[0-9]+\\)?\\)"
+                          "[lLfFdD]?")
+                  '(0 mdw-number-face))
+
+            ;; And anything else is punctuation.
+            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+                  '(0 mdw-punct-face))))))
+
+(progn
+  (add-hook 'java-mode-hook 'mdw-misc-mode-config t)
+  (add-hook 'java-mode-hook 'mdw-fontify-java t))
 
 ;;;--------------------------------------------------------------------------
 ;;; Javascript programming configuration.
 
 ;;;--------------------------------------------------------------------------
 ;;; Javascript programming configuration.
@@ -1820,38 +2616,39 @@ doesn't match any of the regular expressions in
                      "private" "protected" "public" "return" "short"
                      "static" "super" "switch" "synchronized" "throw"
                      "throws" "transient" "try" "typeof" "var" "void"
                      "private" "protected" "public" "return" "short"
                      "static" "super" "switch" "synchronized" "throw"
                      "throws" "transient" "try" "typeof" "var" "void"
-                     "volatile" "while" "with" "yield"
-
-                     "boolean" "byte" "char" "double" "float" "int" "long"
-                     "short" "void"))
-       (javascript-constants
+                     "volatile" "while" "with" "yield"))
+       (javascript-builtins
         (mdw-regexps "false" "null" "undefined" "Infinity" "NaN" "true"
                      "arguments" "this")))
 
     (setq font-lock-keywords
         (mdw-regexps "false" "null" "undefined" "Infinity" "NaN" "true"
                      "arguments" "this")))
 
     (setq font-lock-keywords
-         (list
-
-          ;; Handle the keywords defined above.
-          (list (concat "\\_<\\(" javascript-keywords "\\)\\_>")
-                '(0 font-lock-keyword-face))
-
-          ;; Handle the predefined constants defined above.
-          (list (concat "\\_<\\(" javascript-constants "\\)\\_>")
-                '(0 font-lock-variable-name-face))
-
-          ;; Handle numbers too.
-          ;;
-          ;; The following isn't quite right, but it's close enough.
-          (list (concat "\\_<\\("
-                        "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
-                        "[0-9]+\\(\\.[0-9]*\\|\\)"
-                        "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
-                        "[lLfFdD]?")
-                '(0 mdw-number-face))
-
-          ;; And anything else is punctuation.
-          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face))))))
+           (list
+
+            ;; Handle the keywords defined above.
+            (list (concat "\\_<\\(" javascript-keywords "\\)\\_>")
+                  '(0 font-lock-keyword-face))
+
+            ;; Handle the predefined builtins defined above.
+            (list (concat "\\_<\\(" javascript-builtins "\\)\\_>")
+                  '(0 font-lock-variable-name-face))
+
+            ;; Handle numbers too.
+            ;;
+            ;; The following isn't quite right, but it's close enough.
+            (list (concat "\\_<\\("
+                          "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
+                          "[0-9]+\\(\\.[0-9]*\\)?"
+                          "\\([eE][-+]?[0-9]+\\)?\\)"
+                          "[lLfFdD]?")
+                  '(0 mdw-number-face))
+
+            ;; And anything else is punctuation.
+            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+                  '(0 mdw-punct-face))))))
+
+(progn
+  (add-hook 'js-mode-hook 'mdw-misc-mode-config t)
+  (add-hook 'js-mode-hook 'mdw-fontify-javascript t))
 
 ;;;--------------------------------------------------------------------------
 ;;; Scala programming configuration.
 
 ;;;--------------------------------------------------------------------------
 ;;; Scala programming configuration.
@@ -1875,81 +2672,78 @@ doesn't match any of the regular expressions in
        (punctuation "[-!%^&*=+:@#~/?\\|`]"))
 
     (setq font-lock-keywords
        (punctuation "[-!%^&*=+:@#~/?\\|`]"))
 
     (setq font-lock-keywords
-         (list
-
-          ;; Magical identifiers between backticks.
-          (list (concat "`\\([^`]+\\)`")
-                '(1 font-lock-variable-name-face))
-
-          ;; Handle the keywords defined above.
-          (list (concat "\\_<\\(" scala-keywords "\\)\\_>")
-                '(0 font-lock-keyword-face))
-
-          ;; Handle the constants defined above.
-          (list (concat "\\_<\\(" scala-constants "\\)\\_>")
-                '(0 font-lock-variable-name-face))
-
-          ;; Magical identifiers between backticks.
-          (list (concat "`\\([^`]+\\)`")
-                '(1 font-lock-variable-name-face))
-
-          ;; Handle numbers too.
-          ;;
-          ;; As usual, not quite right.
-          (list (concat "\\_<\\("
-                        "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
-                        "[0-9]+\\(\\.[0-9]*\\|\\)"
-                        "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
-                        "[lLfFdD]?")
-                '(0 mdw-number-face))
-
-          ;; Identifiers with trailing operators.
-          (list (concat "_\\(" punctuation "\\)+")
-                '(0 mdw-trivial-face))
-
-          ;; And everything else is punctuation.
-          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face)))
+           (list
+
+            ;; Magical identifiers between backticks.
+            (list (concat "`\\([^`]+\\)`")
+                  '(1 font-lock-variable-name-face))
+
+            ;; Handle the keywords defined above.
+            (list (concat "\\_<\\(" scala-keywords "\\)\\_>")
+                  '(0 font-lock-keyword-face))
+
+            ;; Handle the constants defined above.
+            (list (concat "\\_<\\(" scala-constants "\\)\\_>")
+                  '(0 font-lock-variable-name-face))
+
+            ;; Magical identifiers between backticks.
+            (list (concat "`\\([^`]+\\)`")
+                  '(1 font-lock-variable-name-face))
+
+            ;; Handle numbers too.
+            ;;
+            ;; As usual, not quite right.
+            (list (concat "\\_<\\("
+                          "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
+                          "[0-9]+\\(\\.[0-9]*\\)?"
+                          "\\([eE][-+]?[0-9]+\\)?\\)"
+                          "[lLfFdD]?")
+                  '(0 mdw-number-face))
+
+            ;; And everything else is punctuation.
+            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+                  '(0 mdw-punct-face)))
 
          font-lock-syntactic-keywords
 
          font-lock-syntactic-keywords
-         (list
-
-          ;; Single quotes around characters.  But not when used to quote
-          ;; symbol names.  Ugh.
-          (list (concat "\\('\\)"
-                        "\\(" "."
-                        "\\|" "\\\\" "\\(" "\\\\\\\\" "\\)*"
-                              "u+" "[0-9a-fA-F]\\{4\\}"
-                        "\\|" "\\\\" "[0-7]\\{1,3\\}"
-                        "\\|" "\\\\" "." "\\)"
-                        "\\('\\)")
-                '(1 "\"")
-                '(4 "\""))))))
+           (list
+
+            ;; Single quotes around characters.  But not when used to quote
+            ;; symbol names.  Ugh.
+            (list (concat "\\('\\)"
+                          "\\(" "."
+                          "\\|" "\\\\" "\\(" "\\\\\\\\" "\\)*"
+                          "u+" "[0-9a-fA-F]\\{4\\}"
+                          "\\|" "\\\\" "[0-7]\\{1,3\\}"
+                          "\\|" "\\\\" "." "\\)"
+                          "\\('\\)")
+                  '(1 "\"")
+                  '(4 "\""))))))
+
+(progn
+  (add-hook 'scala-mode-hook 'mdw-misc-mode-config t)
+  (add-hook 'scala-mode-hook 'mdw-fontify-scala t))
 
 ;;;--------------------------------------------------------------------------
 ;;; C# programming configuration.
 
 ;; Make indentation nice.
 
 
 ;;;--------------------------------------------------------------------------
 ;;; C# programming configuration.
 
 ;; Make indentation nice.
 
-(defun mdw-csharp-style ()
-  (c-add-style "[mdw] C# style"
-              '((c-basic-offset . 2)
-                (c-offsets-alist (substatement-open . 0)
-                                 (label . 0)
-                                 (case-label . +)
-                                 (access-label . 0)
-                                 (inclass . +)
-                                 (statement-case-intro . +)))
-              t))
+(mdw-define-c-style mdw-csharp ()
+  (c-basic-offset . 2)
+  (c-backslash-column . 72)
+  (c-offsets-alist (substatement-open . 0)
+                  (label . 0)
+                  (case-label . +)
+                  (access-label . 0)
+                  (inclass . +)
+                  (statement-case-intro . +)))
+(mdw-set-default-c-style 'csharp-mode 'mdw-csharp)
 
 ;; Declare C# fontification style.
 
 (defun mdw-fontify-csharp ()
 
   ;; Other stuff.
 
 ;; Declare C# fontification style.
 
 (defun mdw-fontify-csharp ()
 
   ;; Other stuff.
-  (mdw-csharp-style)
-  (setq c-hanging-comment-ender-p nil)
-  (setq c-backslash-column 72)
   (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
 
   ;; Now define things to be fontified.
   (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
 
   ;; Now define things to be fontified.
@@ -1969,37 +2763,39 @@ doesn't match any of the regular expressions in
                      "unsafe" "ushort" "using" "virtual" "void" "volatile"
                      "while" "yield"))
 
                      "unsafe" "ushort" "using" "virtual" "void" "volatile"
                      "while" "yield"))
 
-       (csharp-constants
+       (csharp-builtins
         (mdw-regexps "base" "false" "null" "this" "true")))
 
     (setq font-lock-keywords
         (mdw-regexps "base" "false" "null" "this" "true")))
 
     (setq font-lock-keywords
-         (list
-
-          ;; Handle the keywords defined above.
-          (list (concat "\\<\\(" csharp-keywords "\\)\\>")
-                '(0 font-lock-keyword-face))
-
-          ;; Handle the magic constants defined above.
-          (list (concat "\\<\\(" csharp-constants "\\)\\>")
-                '(0 font-lock-variable-name-face))
-
-          ;; Handle numbers too.
-          ;;
-          ;; The following isn't quite right, but it's close enough.
-          (list (concat "\\<\\("
-                        "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
-                        "[0-9]+\\(\\.[0-9]*\\|\\)"
-                        "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
-                        "[lLfFdD]?")
-                '(0 mdw-number-face))
-
-          ;; And anything else is punctuation.
-          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face))))))
+           (list
+
+            ;; Handle the keywords defined above.
+            (list (concat "\\<\\(" csharp-keywords "\\)\\>")
+                  '(0 font-lock-keyword-face))
+
+            ;; Handle the magic builtins defined above.
+            (list (concat "\\<\\(" csharp-builtins "\\)\\>")
+                  '(0 font-lock-variable-name-face))
+
+            ;; Handle numbers too.
+            ;;
+            ;; The following isn't quite right, but it's close enough.
+            (list (concat "\\<\\("
+                          "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
+                          "[0-9]+\\(\\.[0-9]*\\)?"
+                          "\\([eE][-+]?[0-9]+\\)?\\)"
+                          "[lLfFdD]?")
+                  '(0 mdw-number-face))
+
+            ;; And anything else is punctuation.
+            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+                  '(0 mdw-punct-face))))))
 
 (define-derived-mode csharp-mode java-mode "C#"
   "Major mode for editing C# code.")
 
 
 (define-derived-mode csharp-mode java-mode "C#"
   "Major mode for editing C# code.")
 
+(add-hook 'csharp-mode-hook 'mdw-fontify-csharp t)
+
 ;;;--------------------------------------------------------------------------
 ;;; F# programming configuration.
 
 ;;;--------------------------------------------------------------------------
 ;;; F# programming configuration.
 
@@ -2056,68 +2852,73 @@ doesn't match any of the regular expressions in
         (mdw-regexps "if" "indent" "else" "endif")))
 
     (setq font-lock-keywords
         (mdw-regexps "if" "indent" "else" "endif")))
 
     (setq font-lock-keywords
-         (list (list (concat "\\(^\\|[^\"]\\)"
-                             "\\(" "(\\*"
-                                   "[^*]*\\*+"
-                                   "\\(" "[^)*]" "[^*]*" "\\*+" "\\)*"
-                                   ")"
-                             "\\|"
-                                   "//.*"
-                             "\\)")
-                     '(2 font-lock-comment-face))
-
-               (list (concat "'" "\\("
-                                   "\\\\"
-                                   "\\(" "[ntbr'\\]"
-                                   "\\|" "[0-9][0-9][0-9]"
-                                   "\\|" "u" "[0-9a-fA-F]\\{4\\}"
-                                   "\\|" "U" "[0-9a-fA-F]\\{8\\}"
-                                   "\\)"
-                                 "\\|"
-                                 "." "\\)" "'"
-                             "\\|"
-                             "\"" "[^\"\\]*"
-                                   "\\(" "\\\\" "\\(.\\|\n\\)"
-                                         "[^\"\\]*" "\\)*"
-                             "\\(\"\\|\\'\\)")
-                     '(0 font-lock-string-face))
-
-               (list (concat "\\_<\\(" bang-keywords "\\)!" "\\|"
-                             "^#[ \t]*\\(" preprocessor-keywords "\\)\\_>"
-                             "\\|"
-                             "\\_<\\(" fsharp-keywords "\\)\\_>")
-                     '(0 font-lock-keyword-face))
-               (list (concat "\\<\\(" fsharp-builtins "\\)\\_>")
-                     '(0 font-lock-variable-name-face))
-
-               (list (concat "\\_<"
-                             "\\(" "0[bB][01]+" "\\|"
-                                   "0[oO][0-7]+" "\\|"
-                                   "0[xX][0-9a-fA-F]+" "\\)"
-                             "\\(" "lf\\|LF" "\\|"
-                                   "[uU]?[ysnlL]?" "\\)"
-                             "\\|"
-                             "\\_<"
-                             "[0-9]+" "\\("
-                               "[mMQRZING]"
+           (list (list (concat "\\(^\\|[^\"]\\)"
+                               "\\(" "(\\*"
+                                     "[^*]*\\*+"
+                                     "\\(" "[^)*]" "[^*]*" "\\*+" "\\)*"
+                                     ")"
                                "\\|"
                                "\\|"
-                               "\\(\\.[0-9]*\\)?"
-                               "\\([eE][-+]?[0-9]+\\)?"
-                               "[fFmM]?"
+                                     "//.*"
+                               "\\)")
+                       '(2 font-lock-comment-face))
+
+                 (list (concat "'" "\\("
+                                     "\\\\"
+                                     "\\(" "[ntbr'\\]"
+                                     "\\|" "[0-9][0-9][0-9]"
+                                     "\\|" "u" "[0-9a-fA-F]\\{4\\}"
+                                     "\\|" "U" "[0-9a-fA-F]\\{8\\}"
+                                     "\\)"
+                                   "\\|"
+                                   "." "\\)" "'"
                                "\\|"
                                "\\|"
-                               "[uU]?[ysnlL]?"
-                             "\\)")
-                     '(0 mdw-number-face))
+                               "\"" "[^\"\\]*"
+                                     "\\(" "\\\\" "\\(.\\|\n\\)"
+                                           "[^\"\\]*" "\\)*"
+                               "\\(\"\\|\\'\\)")
+                       '(0 font-lock-string-face))
+
+                 (list (concat "\\_<\\(" bang-keywords "\\)!" "\\|"
+                               "^#[ \t]*\\(" preprocessor-keywords "\\)\\_>"
+                               "\\|"
+                               "\\_<\\(" fsharp-keywords "\\)\\_>")
+                       '(0 font-lock-keyword-face))
+                 (list (concat "\\<\\(" fsharp-builtins "\\)\\_>")
+                       '(0 font-lock-variable-name-face))
+
+                 (list (concat "\\_<"
+                               "\\(" "0[bB][01]+" "\\|"
+                                     "0[oO][0-7]+" "\\|"
+                                     "0[xX][0-9a-fA-F]+" "\\)"
+                               "\\(" "lf\\|LF" "\\|"
+                                     "[uU]?[ysnlL]?" "\\)"
+                               "\\|"
+                               "\\_<"
+                               "[0-9]+" "\\("
+                                 "[mMQRZING]"
+                                 "\\|"
+                                 "\\(\\.[0-9]*\\)?"
+                                 "\\([eE][-+]?[0-9]+\\)?"
+                                 "[fFmM]?"
+                                 "\\|"
+                                 "[uU]?[ysnlL]?"
+                               "\\)")
+                       '(0 mdw-number-face))
 
 
-               (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                     '(0 mdw-punct-face))))))
+                 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+                       '(0 mdw-punct-face))))))
 
 (defun mdw-fontify-inferior-fsharp ()
   (mdw-fontify-fsharp)
   (setq font-lock-keywords
 
 (defun mdw-fontify-inferior-fsharp ()
   (mdw-fontify-fsharp)
   (setq font-lock-keywords
-       (append (list (list "^[#-]" '(0 font-lock-comment-face))
-                     (list "^>" '(0 font-lock-keyword-face)))
-               font-lock-keywords)))
+         (append (list (list "^[#-]" '(0 font-lock-comment-face))
+                       (list "^>" '(0 font-lock-keyword-face)))
+                 font-lock-keywords)))
+
+(progn
+  (add-hook 'fsharp-mode-hook 'mdw-misc-mode-config t)
+  (add-hook 'fsharp-mode-hook 'mdw-fontify-fsharp t)
+  (add-hook 'inferior-fsharp-mode-hooks 'mdw-fontify-inferior-fsharp t))
 
 ;;;--------------------------------------------------------------------------
 ;;; Go programming configuration.
 
 ;;;--------------------------------------------------------------------------
 ;;; Go programming configuration.
@@ -2142,44 +2943,47 @@ doesn't match any of the regular expressions in
                      "new" "panic" "real" "recover")))
 
     (setq font-lock-keywords
                      "new" "panic" "real" "recover")))
 
     (setq font-lock-keywords
-         (list
-
-          ;; Handle the keywords defined above.
-          (list (concat "\\<\\(" go-keywords "\\)\\>")
-                '(0 font-lock-keyword-face))
-          (list (concat "\\<\\(" go-intrinsics "\\)\\>")
-                '(0 font-lock-variable-name-face))
-
-          ;; Strings and characters.
-          (list (concat "'"
-                        "\\(" "[^\\']" "\\|"
-                              "\\\\"
-                              "\\(" "[abfnrtv\\'\"]" "\\|"
-                                    "[0-7]\\{3\\}" "\\|"
-                                    "x" "[0-9A-Fa-f]\\{2\\}" "\\|"
-                                    "u" "[0-9A-Fa-f]\\{4\\}" "\\|"
-                                    "U" "[0-9A-Fa-f]\\{8\\}" "\\)" "\\)"
-                        "'"
-                        "\\|"
-                        "\""
-                        "\\(" "[^\n\\\"]+" "\\|" "\\\\." "\\)*"
-                        "\\(\"\\|$\\)"
-                        "\\|"
-                        "`" "[^`]+" "`")
-                '(0 font-lock-string-face))
-
-          ;; Handle numbers too.
-          ;;
-          ;; The following isn't quite right, but it's close enough.
-          (list (concat "\\<\\("
-                        "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
-                        "[0-9]+\\(\\.[0-9]*\\|\\)"
-                        "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)")
-                '(0 mdw-number-face))
-
-          ;; And anything else is punctuation.
-          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face))))))
+           (list
+
+            ;; Handle the keywords defined above.
+            (list (concat "\\<\\(" go-keywords "\\)\\>")
+                  '(0 font-lock-keyword-face))
+            (list (concat "\\<\\(" go-intrinsics "\\)\\>")
+                  '(0 font-lock-variable-name-face))
+
+            ;; Strings and characters.
+            (list (concat "'"
+                          "\\(" "[^\\']" "\\|"
+                                "\\\\"
+                                "\\(" "[abfnrtv\\'\"]" "\\|"
+                                      "[0-7]\\{3\\}" "\\|"
+                                      "x" "[0-9A-Fa-f]\\{2\\}" "\\|"
+                                      "u" "[0-9A-Fa-f]\\{4\\}" "\\|"
+                                      "U" "[0-9A-Fa-f]\\{8\\}" "\\)" "\\)"
+                          "'"
+                          "\\|"
+                          "\""
+                          "\\(" "[^\n\\\"]+" "\\|" "\\\\." "\\)*"
+                          "\\(\"\\|$\\)"
+                          "\\|"
+                          "`" "[^`]+" "`")
+                  '(0 font-lock-string-face))
+
+            ;; Handle numbers too.
+            ;;
+            ;; The following isn't quite right, but it's close enough.
+            (list (concat "\\<\\("
+                          "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
+                          "[0-9]+\\(\\.[0-9]*\\)?"
+                          "\\([eE][-+]?[0-9]+\\)?\\)")
+                  '(0 mdw-number-face))
+
+            ;; And anything else is punctuation.
+            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+                  '(0 mdw-punct-face))))))
+(progn
+  (add-hook 'go-mode-hook 'mdw-misc-mode-config t)
+  (add-hook 'go-mode-hook 'mdw-fontify-go t))
 
 ;;;--------------------------------------------------------------------------
 ;;; Rust programming configuration.
 
 ;;;--------------------------------------------------------------------------
 ;;; Rust programming configuration.
@@ -2194,26 +2998,28 @@ doesn't match any of the regular expressions in
 (defun mdw-fontify-rust ()
 
   ;; Hack syntax categories.
 (defun mdw-fontify-rust ()
 
   ;; Hack syntax categories.
+  (modify-syntax-entry ?$ ".")
+  (modify-syntax-entry ?% ".")
   (modify-syntax-entry ?= ".")
 
   ;; Fontify keywords and things.
   (make-local-variable 'font-lock-keywords)
   (let ((rust-keywords
   (modify-syntax-entry ?= ".")
 
   ;; Fontify keywords and things.
   (make-local-variable 'font-lock-keywords)
   (let ((rust-keywords
-        (mdw-regexps "abstract" "alignof" "as"
+        (mdw-regexps "abstract" "alignof" "as" "async" "await"
                      "become" "box" "break"
                      "become" "box" "break"
-                     "const" "continue" "create"
-                     "do"
+                     "const" "continue" "crate"
+                     "do" "dyn"
                      "else" "enum" "extern"
                      "else" "enum" "extern"
-                     "false" "final" "fn" "for"
+                     "final" "fn" "for"
                      "if" "impl" "in"
                      "let" "loop"
                      "macro" "match" "mod" "move" "mut"
                      "offsetof" "override"
                      "if" "impl" "in"
                      "let" "loop"
                      "macro" "match" "mod" "move" "mut"
                      "offsetof" "override"
-                     "priv" "pub" "pure"
+                     "priv" "proc" "pub" "pure"
                      "ref" "return"
                      "ref" "return"
-                     "self" "sizeof" "static" "struct" "super"
-                     "true" "trait" "type" "typeof"
-                     "unsafe" "unsized" "use"
+                     "sizeof" "static" "struct" "super"
+                     "trait" "try" "type" "typeof"
+                     "union" "unsafe" "unsized" "use"
                      "virtual"
                      "where" "while"
                      "yield"))
                      "virtual"
                      "where" "while"
                      "yield"))
@@ -2223,60 +3029,63 @@ doesn't match any of the regular expressions in
                      "f32" "f64"
                      "i8" "i16" "i32" "i64" "isize"
                      "u8" "u16" "u32" "u64" "usize"
                      "f32" "f64"
                      "i8" "i16" "i32" "i64" "isize"
                      "u8" "u16" "u32" "u64" "usize"
-                     "char" "str")))
+                     "char" "str"
+                     "self" "Self")))
     (setq font-lock-keywords
     (setq font-lock-keywords
-         (list
-
-          ;; Handle the keywords defined above.
-          (list (concat "\\<\\(" rust-keywords "\\)\\>")
-                '(0 font-lock-keyword-face))
-          (list (concat "\\<\\(" rust-builtins "\\)\\>")
-                '(0 font-lock-variable-name-face))
-
-          ;; Handle numbers too.
-          (list (concat "\\<\\("
-                              "[0-9][0-9_]*"
-                              "\\(" "\\(\\.[0-9_]+\\)?[eE][-+]?[0-9_]+"
-                              "\\|" "\\.[0-9_]+"
-                              "\\)"
-                              "\\(f32\\|f64\\)?"
-                        "\\|" "\\(" "[0-9][0-9_]*"
-                              "\\|" "0x[0-9a-fA-F_]+"
-                              "\\|" "0o[0-7_]+"
-                              "\\|" "0b[01_]+"
-                              "\\)"
-                              "\\([ui]\\(8\\|16\\|32\\|64\\|s\\|size\\)\\)?"
-                        "\\)\\>")
-                '(0 mdw-number-face))
-
-          ;; And anything else is punctuation.
-          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face)))))
+           (list
+
+            ;; Handle the keywords defined above.
+            (list (concat "\\_<\\(" rust-keywords "\\)\\_>")
+                  '(0 font-lock-keyword-face))
+            (list (concat "\\_<\\(" rust-builtins "\\)\\_>")
+                  '(0 font-lock-variable-name-face))
+
+            ;; Handle numbers too.
+            (list (concat "\\_<\\("
+                                "[0-9][0-9_]*"
+                                "\\(" "\\(\\.[0-9_]+\\)?[eE][-+]?[0-9_]+"
+                                "\\|" "\\.[0-9_]+"
+                                "\\)"
+                                "\\(f32\\|f64\\)?"
+                          "\\|" "\\(" "[0-9][0-9_]*"
+                                "\\|" "0x[0-9a-fA-F_]+"
+                                "\\|" "0o[0-7_]+"
+                                "\\|" "0b[01_]+"
+                                "\\)"
+                                "\\([ui]\\(8\\|16\\|32\\|64\\|size\\)\\)?"
+                          "\\)\\_>")
+                  '(0 mdw-number-face))
+
+            ;; And anything else is punctuation.
+            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+                  '(0 mdw-punct-face)))))
 
   ;; Hack key bindings.
   (local-set-key [?{] 'mdw-self-insert-and-indent)
   (local-set-key [?}] 'mdw-self-insert-and-indent))
 
 
   ;; Hack key bindings.
   (local-set-key [?{] 'mdw-self-insert-and-indent)
   (local-set-key [?}] 'mdw-self-insert-and-indent))
 
+(progn
+  (add-hook 'rust-mode-hook 'mdw-misc-mode-config t)
+  (add-hook 'rust-mode-hook 'mdw-fontify-rust t))
+
 ;;;--------------------------------------------------------------------------
 ;;; Awk programming configuration.
 
 ;; Make Awk indentation nice.
 
 ;;;--------------------------------------------------------------------------
 ;;; Awk programming configuration.
 
 ;; Make Awk indentation nice.
 
-(defun mdw-awk-style ()
-  (c-add-style "[mdw] Awk style"
-              '((c-basic-offset . 2)
-                (c-offsets-alist (substatement-open . 0)
-                                 (statement-cont . 0)
-                                 (statement-case-intro . +)))
-              t))
+(mdw-define-c-style mdw-awk ()
+  (c-basic-offset . 2)
+  (c-offsets-alist (substatement-open . 0)
+                  (c-backslash-column . 72)
+                  (statement-cont . 0)
+                  (statement-case-intro . +)))
+(mdw-set-default-c-style 'awk-mode 'mdw-awk)
 
 ;; Declare Awk fontification style.
 
 (defun mdw-fontify-awk ()
 
   ;; Miscellaneous fiddling.
 
 ;; Declare Awk fontification style.
 
 (defun mdw-fontify-awk ()
 
   ;; Miscellaneous fiddling.
-  (mdw-awk-style)
-  (setq c-backslash-column 72)
   (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
 
   ;; Now define things to be fontified.
   (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
 
   ;; Now define things to be fontified.
@@ -2295,39 +3104,44 @@ doesn't match any of the regular expressions in
                      "systime" "tolower" "toupper" "while")))
 
     (setq font-lock-keywords
                      "systime" "tolower" "toupper" "while")))
 
     (setq font-lock-keywords
-         (list
-
-          ;; Handle the keywords defined above.
-          (list (concat "\\<\\(" c-keywords "\\)\\>")
-                '(0 font-lock-keyword-face))
-
-          ;; Handle numbers too.
-          ;;
-          ;; The following isn't quite right, but it's close enough.
-          (list (concat "\\<\\("
-                        "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
-                        "[0-9]+\\(\\.[0-9]*\\|\\)"
-                        "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
-                        "[uUlL]*")
-                '(0 mdw-number-face))
-
-          ;; And anything else is punctuation.
-          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face))))))
+           (list
+
+            ;; Handle the keywords defined above.
+            (list (concat "\\<\\(" c-keywords "\\)\\>")
+                  '(0 font-lock-keyword-face))
+
+            ;; Handle numbers too.
+            ;;
+            ;; The following isn't quite right, but it's close enough.
+            (list (concat "\\<\\("
+                          "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
+                          "[0-9]+\\(\\.[0-9]*\\)?"
+                          "\\([eE][-+]?[0-9]+\\)?\\)"
+                          "[uUlL]*")
+                  '(0 mdw-number-face))
+
+            ;; And anything else is punctuation.
+            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+                  '(0 mdw-punct-face))))))
+
+(progn
+  (add-hook 'awk-mode-hook 'mdw-misc-mode-config t)
+  (add-hook 'awk-mode-hook 'mdw-fontify-awk t))
 
 ;;;--------------------------------------------------------------------------
 ;;; Perl programming style.
 
 ;; Perl indentation style.
 
 
 ;;;--------------------------------------------------------------------------
 ;;; Perl programming style.
 
 ;; Perl indentation style.
 
-(setq perl-indent-level 2)
+(setq-default perl-indent-level 2)
 
 
-(setq cperl-indent-level 2)
-(setq cperl-continued-statement-offset 2)
-(setq cperl-continued-brace-offset 0)
-(setq cperl-brace-offset -2)
-(setq cperl-brace-imaginary-offset 0)
-(setq cperl-label-offset 0)
+(setq-default cperl-indent-level 2
+             cperl-continued-statement-offset 2
+             cperl-indent-region-fix-constructs nil
+             cperl-continued-brace-offset 0
+             cperl-brace-offset -2
+             cperl-brace-imaginary-offset 0
+             cperl-label-offset 0)
 
 ;; Define perl fontification style.
 
 
 ;; Define perl fontification style.
 
@@ -2361,21 +3175,21 @@ doesn't match any of the regular expressions in
                      "when" "while")))
 
     (setq font-lock-keywords
                      "when" "while")))
 
     (setq font-lock-keywords
-         (list
+           (list
 
 
-          ;; Set up the keywords defined above.
-          (list (concat "\\<\\(" perl-keywords "\\)\\>")
-                '(0 font-lock-keyword-face))
+            ;; Set up the keywords defined above.
+            (list (concat "\\<\\(" perl-keywords "\\)\\>")
+                  '(0 font-lock-keyword-face))
 
 
-          ;; At least numbers are simpler than C.
-          (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
-                        "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
-                        "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
-                '(0 mdw-number-face))
+            ;; At least numbers are simpler than C.
+            (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
+                          "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\)?"
+                          "\\([eE][-+]?[0-9_]+\\)?")
+                  '(0 mdw-number-face))
 
 
-          ;; And anything else is punctuation.
-          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face))))))
+            ;; And anything else is punctuation.
+            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+                  '(0 mdw-punct-face))))))
 
 (defun perl-number-tests (&optional arg)
   "Assign consecutive numbers to lines containing `#t'.  With ARG,
 
 (defun perl-number-tests (&optional arg)
   "Assign consecutive numbers to lines containing `#t'.  With ARG,
@@ -2392,33 +3206,43 @@ strip numbers instead."
       (if (re-search-forward "\\(tests\\s-*=>\\s-*\\)\\w*" nil t)
          (replace-match (format "\\1%d" i))))))
 
       (if (re-search-forward "\\(tests\\s-*=>\\s-*\\)\\w*" nil t)
          (replace-match (format "\\1%d" i))))))
 
+(dolist (hook '(perl-mode-hook cperl-mode-hook))
+  (add-hook hook 'mdw-misc-mode-config t)
+  (add-hook hook 'mdw-fontify-perl t))
+
 ;;;--------------------------------------------------------------------------
 ;;; Python programming style.
 
 ;;;--------------------------------------------------------------------------
 ;;; Python programming style.
 
+(setq-default py-indent-offset 2
+             python-indent 2
+             python-indent-offset 2
+             python-fill-docstring-style 'symmetric)
+
 (defun mdw-fontify-pythonic (keywords)
 
   ;; Miscellaneous fiddling.
   (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
   (setq indent-tabs-mode nil)
 (defun mdw-fontify-pythonic (keywords)
 
   ;; Miscellaneous fiddling.
   (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
   (setq indent-tabs-mode nil)
+  (set (make-local-variable 'forward-sexp-function) nil)
 
   ;; Now define fontification things.
   (make-local-variable 'font-lock-keywords)
   (setq font-lock-keywords
 
   ;; Now define fontification things.
   (make-local-variable 'font-lock-keywords)
   (setq font-lock-keywords
-       (list
+         (list
 
 
-        ;; Set up the keywords defined above.
-        (list (concat "\\_<\\(" keywords "\\)\\_>")
-              '(0 font-lock-keyword-face))
+          ;; Set up the keywords defined above.
+          (list (concat "\\_<\\(" keywords "\\)\\_>")
+                '(0 font-lock-keyword-face))
 
 
-        ;; At least numbers are simpler than C.
-        (list (concat "\\_<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
-                      "\\_<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
-                      "\\([eE]\\([-+]\\|\\)[0-9_]+\\|[lL]\\|\\)")
-              '(0 mdw-number-face))
+          ;; At least numbers are simpler than C.
+          (list (concat "\\_<0\\([xX][0-9a-fA-F]+\\|[oO]?[0-7]+\\|[bB][01]+\\)\\|"
+                        "\\_<[0-9][0-9]*\\(\\.[0-9]*\\)?"
+                        "\\([eE][-+]?[0-9]+\\|[lL]\\)?")
+                '(0 mdw-number-face))
 
 
-        ;; And anything else is punctuation.
-        (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-              '(0 mdw-punct-face)))))
+          ;; And anything else is punctuation.
+          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+                '(0 mdw-punct-face)))))
 
 ;; Define Python fontification styles.
 
 
 ;; Define Python fontification styles.
 
@@ -2433,21 +3257,81 @@ strip numbers instead."
 (defun mdw-fontify-pyrex ()
   (mdw-fontify-pythonic
    (mdw-regexps "and" "as" "assert" "break" "cdef" "class" "continue"
 (defun mdw-fontify-pyrex ()
   (mdw-fontify-pythonic
    (mdw-regexps "and" "as" "assert" "break" "cdef" "class" "continue"
-               "ctypedef" "def" "del" "elif" "else" "except" "exec"
+               "ctypedef" "def" "del" "elif" "else" "enum" "except" "exec"
                "extern" "finally" "for" "from" "global" "if"
                "import" "in" "is" "lambda" "not" "or" "pass" "print"
                "extern" "finally" "for" "from" "global" "if"
                "import" "in" "is" "lambda" "not" "or" "pass" "print"
-               "raise" "return" "struct" "try" "while" "with"
+               "property" "raise" "return" "struct" "try" "while" "with"
                "yield")))
 
                "yield")))
 
+(define-derived-mode pyrex-mode python-mode "Pyrex"
+  "Major mode for editing Pyrex source code")
+(setq auto-mode-alist
+       (append '(("\\.pyx$" . pyrex-mode)
+                 ("\\.pxd$" . pyrex-mode)
+                 ("\\.pxi$" . pyrex-mode))
+               auto-mode-alist))
+
+(progn
+  (add-hook 'python-mode-hook 'mdw-misc-mode-config t)
+  (add-hook 'python-mode-hook 'mdw-fontify-python t)
+  (add-hook 'pyrex-mode-hook 'mdw-fontify-pyrex t))
+
+;;;--------------------------------------------------------------------------
+;;; Lua programming style.
+
+(setq-default lua-indent-level 2)
+
+(defun mdw-fontify-lua ()
+
+  ;; Miscellaneous fiddling.
+  (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
+
+  ;; Now define fontification things.
+  (make-local-variable 'font-lock-keywords)
+  (let ((lua-keywords
+        (mdw-regexps "and" "break" "do" "else" "elseif" "end"
+                     "false" "for" "function" "goto" "if" "in" "local"
+                     "nil" "not" "or" "repeat" "return" "then" "true"
+                     "until" "while")))
+    (setq font-lock-keywords
+           (list
+
+            ;; Set up the keywords defined above.
+            (list (concat "\\_<\\(" lua-keywords "\\)\\_>")
+                  '(0 font-lock-keyword-face))
+
+            ;; At least numbers are simpler than C.
+            (list (concat "\\_<\\(" "0[xX]"
+                                    "\\(" "[0-9a-fA-F]+"
+                                          "\\(\\.[0-9a-fA-F]*\\)?"
+                                    "\\|" "\\.[0-9a-fA-F]+"
+                                    "\\)"
+                                    "\\([pP][-+]?[0-9]+\\)?"
+                              "\\|" "\\(" "[0-9]+"
+                                          "\\(\\.[0-9]*\\)?"
+                                    "\\|" "\\.[0-9]+"
+                                    "\\)"
+                                    "\\([eE][-+]?[0-9]+\\)?"
+                              "\\)")
+                  '(0 mdw-number-face))
+
+            ;; And anything else is punctuation.
+            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+                  '(0 mdw-punct-face))))))
+
+(progn
+  (add-hook 'lua-mode-hook 'mdw-misc-mode-config t)
+  (add-hook 'lua-mode-hook 'mdw-fontify-lua t))
+
 ;;;--------------------------------------------------------------------------
 ;;; Icon programming style.
 
 ;; Icon indentation style.
 
 ;;;--------------------------------------------------------------------------
 ;;; Icon programming style.
 
 ;; Icon indentation style.
 
-(setq icon-brace-offset 0
-      icon-continued-brace-offset 0
-      icon-continued-statement-offset 2
-      icon-indent-level 2)
+(setq-default icon-brace-offset 0
+             icon-continued-brace-offset 0
+             icon-continued-statement-offset 2
+             icon-indent-level 2)
 
 ;; Define Icon fontification style.
 
 
 ;; Define Icon fontification style.
 
@@ -2468,31 +3352,246 @@ strip numbers instead."
         (mdw-regexps "define" "else" "endif" "error" "ifdef" "ifndef"
                      "include" "line" "undef")))
     (setq font-lock-keywords
         (mdw-regexps "define" "else" "endif" "error" "ifdef" "ifndef"
                      "include" "line" "undef")))
     (setq font-lock-keywords
-         (list
+           (list
 
 
-          ;; Set up the keywords defined above.
-          (list (concat "\\<\\(" icon-keywords "\\)\\>")
-                '(0 font-lock-keyword-face))
+            ;; Set up the keywords defined above.
+            (list (concat "\\<\\(" icon-keywords "\\)\\>")
+                  '(0 font-lock-keyword-face))
 
 
-          ;; The things that Icon calls keywords.
-          (list "&\\sw+\\>" '(0 font-lock-variable-name-face))
+            ;; The things that Icon calls keywords.
+            (list "&\\sw+\\>" '(0 font-lock-variable-name-face))
 
 
-          ;; At least numbers are simpler than C.
-          (list (concat "\\<[0-9]+"
-                        "\\([rR][0-9a-zA-Z]+\\|"
-                        "\\.[0-9]+\\([eE][+-]?[0-9]+\\)?\\)\\>\\|"
-                        "\\.[0-9]+\\([eE][+-]?[0-9]+\\)?\\>")
-                '(0 mdw-number-face))
+            ;; At least numbers are simpler than C.
+            (list (concat "\\<[0-9]+"
+                          "\\([rR][0-9a-zA-Z]+\\|"
+                          "\\.[0-9]+\\([eE][+-]?[0-9]+\\)?\\)\\>\\|"
+                          "\\.[0-9]+\\([eE][+-]?[0-9]+\\)?\\>")
+                  '(0 mdw-number-face))
 
 
-          ;; Preprocessor.
-          (list (concat "^[ \t]*$[ \t]*\\<\\("
-                        preprocessor-keywords
-                        "\\)\\>")
-                '(0 font-lock-keyword-face))
+            ;; Preprocessor.
+            (list (concat "^[ \t]*$[ \t]*\\<\\("
+                          preprocessor-keywords
+                          "\\)\\>")
+                  '(0 font-lock-keyword-face))
 
 
-          ;; And anything else is punctuation.
-          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face))))))
+            ;; And anything else is punctuation.
+            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+                  '(0 mdw-punct-face))))))
+
+(progn
+  (add-hook 'icon-mode-hook 'mdw-misc-mode-config t)
+  (add-hook 'icon-mode-hook 'mdw-fontify-icon t))
+
+;;;--------------------------------------------------------------------------
+;;; Fortran mode.
+
+(defun mdw-fontify-fortran-common ()
+  (let ((fortran-keywords
+        (mdw-regexps "access"
+                     "assign"
+                     "associate"
+                     "backspace"
+                     "blank"
+                     "block\\s-*data"
+                     "call"
+                     "case"
+                     "character"
+                     "class"
+                     "close"
+                     "common"
+                     "complex"
+                     "continue"
+                     "critical"
+                     "data"
+                     "dimension"
+                     "do"
+                     "double\\s-*precision"
+                     "else" "elseif" "elsewhere"
+                     "end"
+                       "endblock" "endblockdata"
+                       "endcritical"
+                       "enddo"
+                       "endinterface"
+                       "endmodule"
+                       "endprocedure"
+                       "endprogram"
+                       "endselect"
+                       "endsubmodule"
+                       "endsubroutine"
+                       "endtype"
+                       "endwhere"
+                       "endenum"
+                       "end\\s-*file"
+                       "endforall"
+                       "endfunction"
+                       "endif"
+                     "entry"
+                     "enum"
+                     "equivalence"
+                     "err"
+                     "external"
+                     "file"
+                     "fmt"
+                     "forall"
+                     "form"
+                     "format"
+                     "function"
+                     "go\\s-*to"
+                     "if"
+                     "implicit"
+                     "in" "inout"
+                     "inquire"
+                     "include"
+                     "integer"
+                     "interface"
+                     "intrinsic"
+                     "iostat"
+                     "len"
+                     "logical"
+                     "module"
+                     "open"
+                     "out"
+                     "parameter"
+                     "pause"
+                     "procedure"
+                     "program"
+                     "precision"
+                     "program"
+                     "read"
+                     "real"
+                     "rec"
+                     "recl"
+                     "return"
+                     "rewind"
+                     "save"
+                     "select" "selectcase" "selecttype"
+                     "status"
+                     "stop"
+                     "submodule"
+                     "subroutine"
+                     "then"
+                     "to"
+                     "type"
+                     "unit"
+                     "where"
+                     "write"))
+       (fortran-operators (mdw-regexps "and"
+                                       "eq"
+                                       "eqv"
+                                       "false"
+                                       "ge"
+                                       "gt"
+                                       "le"
+                                       "lt"
+                                       "ne"
+                                       "neqv"
+                                       "not"
+                                       "or"
+                                       "true"))
+       (fortran-intrinsics (mdw-regexps "abs" "dabs" "iabs" "cabs"
+                                        "atan" "datan" "atan2" "datan2"
+                                        "cmplx"
+                                        "conjg"
+                                        "cos" "dcos" "ccos"
+                                        "dble"
+                                        "dim" "idim"
+                                        "exp" "dexp" "cexp"
+                                        "float"
+                                        "ifix"
+                                        "aimag"
+                                        "int" "aint" "idint"
+                                        "alog" "dlog" "clog"
+                                        "alog10" "dlog10"
+                                        "max"
+                                        "amax0" "amax1"
+                                        "max0" "max1"
+                                        "dmax1"
+                                        "min"
+                                        "amin0" "amin1"
+                                        "min0" "min1"
+                                        "dmin1"
+                                        "mod" "amod" "dmod"
+                                        "sin" "dsin" "csin"
+                                        "sign" "isign" "dsign"
+                                        "sngl"
+                                        "sqrt" "dsqrt" "csqrt"
+                                        "tanh"))
+       (preprocessor-keywords
+        (mdw-regexps "assert" "define" "elif" "else" "endif" "error"
+                     "ident" "if" "ifdef" "ifndef" "import" "include"
+                     "line" "pragma" "unassert" "undef" "warning")))
+    (setq font-lock-keywords-case-fold-search t
+           font-lock-keywords
+           (list
+
+            ;; Fontify include files as strings.
+            (list (concat "^[ \t]*\\#[ \t]*" "include"
+                          "[ \t]*\\(<[^>]+>?\\)")
+                  '(1 font-lock-string-face))
+
+            ;; Preprocessor directives are `references'?.
+            (list (concat "^\\([ \t]*#[ \t]*\\(\\("
+                          preprocessor-keywords
+                          "\\)\\>\\|[0-9]+\\|$\\)\\)")
+                  '(1 font-lock-keyword-face))
+
+            ;; Set up the keywords defined above.
+            (list (concat "\\<\\(" fortran-keywords "\\)\\>")
+                  '(0 font-lock-keyword-face))
+
+            ;; Set up the `.foo.' operators.
+            (list (concat "\\.\\(" fortran-operators "\\)\\.")
+                  '(0 font-lock-keyword-face))
+
+            ;; Set up the intrinsic functions.
+            (list (concat "\\<\\(" fortran-intrinsics "\\)\\>")
+                  '(0 font-lock-variable-name-face))
+
+            ;; Numbers.
+            (list (concat       "\\(" "\\<" "[0-9]+" "\\(\\.[0-9]*\\)?"
+                                "\\|" "\\.[0-9]+"
+                                "\\)"
+                                "\\(" "[de]" "[+-]?" "[0-9]+" "\\)?"
+                                "\\(" "_" "\\sw+" "\\)?"
+                          "\\|" "b'[01]*'" "\\|" "'[01]*'b"
+                          "\\|" "b\"[01]*\"" "\\|" "\"[01]*\"b"
+                          "\\|" "o'[0-7]*'" "\\|" "'[0-7]*'o"
+                          "\\|" "o\"[0-7]*\"" "\\|" "\"[0-7]*\"o"
+                          "\\|" "[xz]'[0-9a-f]*'" "\\|" "'[0-9a-f]*'[xz]"
+                          "\\|" "[xz]\"[0-9a-f]*\"" "\\|" "\"[0-9a-f]*\"[xz]")
+                  '(0 mdw-number-face))
+
+            ;; Any anything else is punctuation.
+            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+                  '(0 mdw-punct-face))))
+
+    (modify-syntax-entry ?/ "." font-lock-syntax-table)
+    (modify-syntax-entry ?< ".")
+    (modify-syntax-entry ?> ".")))
+
+(defun mdw-fontify-fortran () (mdw-fontify-fortran-common))
+(defun mdw-fontify-f90 () (mdw-fontify-fortran-common))
+
+(setq fortran-do-indent 2
+      fortran-if-indent 2
+      fortran-structure-indent 2
+      fortran-comment-line-start "*"
+      fortran-comment-indent-style 'relative
+      fortran-continuation-string "&"
+      fortran-continuation-indent 4)
+
+(setq f90-do-indent 2
+      f90-if-indent 2
+      f90-program-indent 2
+      f90-continuation-indent 4
+      f90-smart-end-names nil
+      f90-smart-end 'no-blink)
+
+(progn
+  (add-hook 'fortran-mode-hook 'mdw-misc-mode-config t)
+  (add-hook 'fortran-mode-hook 'mdw-fontify-fortran t)
+  (add-hook 'f90-mode-hook 'mdw-misc-mode-config t)
+  (add-hook 'f90-mode-hook 'mdw-fontify-f90 t))
 
 ;;;--------------------------------------------------------------------------
 ;;; Assembler mode.
 
 ;;;--------------------------------------------------------------------------
 ;;; Assembler mode.
@@ -2502,31 +3601,47 @@ strip numbers instead."
   (modify-syntax-entry ?. "w")
   (modify-syntax-entry ?\n ">")
   (setf fill-prefix nil)
   (modify-syntax-entry ?. "w")
   (modify-syntax-entry ?\n ">")
   (setf fill-prefix nil)
+  (modify-syntax-entry ?. "_")
+  (modify-syntax-entry ?* ". 23")
+  (modify-syntax-entry ?/ ". 124b")
+  (modify-syntax-entry ?\n "> b")
+  (local-set-key ";" 'self-insert-command)
   (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)"))
 
 (defun mdw-asm-set-comment ()
   (modify-syntax-entry ?; "."
                       )
   (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)"))
 
 (defun mdw-asm-set-comment ()
   (modify-syntax-entry ?; "."
                       )
-  (modify-syntax-entry asm-comment-char "<b")
+  (modify-syntax-entry asm-comment-char "< b")
   (setq comment-start (string asm-comment-char ? )))
 (add-hook 'asm-mode-local-variables-hook 'mdw-asm-set-comment)
 (put 'asm-comment-char 'safe-local-variable 'characterp)
 
   (setq comment-start (string asm-comment-char ? )))
 (add-hook 'asm-mode-local-variables-hook 'mdw-asm-set-comment)
 (put 'asm-comment-char 'safe-local-variable 'characterp)
 
+(progn
+  (add-hook 'asm-mode-hook 'mdw-misc-mode-config t)
+  (add-hook 'asm-mode-hook 'mdw-fontify-asm t))
+
 ;;;--------------------------------------------------------------------------
 ;;; TCL configuration.
 
 ;;;--------------------------------------------------------------------------
 ;;; TCL configuration.
 
+(setq-default tcl-indent-level 2)
+
 (defun mdw-fontify-tcl ()
 (defun mdw-fontify-tcl ()
-  (mapcar #'(lambda (ch) (modify-syntax-entry ch ".")) '(?$))
+  (dolist (ch '(?$))
+    (modify-syntax-entry ch "."))
   (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
   (make-local-variable 'font-lock-keywords)
   (setq font-lock-keywords
   (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
   (make-local-variable 'font-lock-keywords)
   (setq font-lock-keywords
-       (list
-        (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
-                      "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
-                      "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
-              '(0 mdw-number-face))
-        (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-              '(0 mdw-punct-face)))))
+         (list
+          (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
+                        "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\)?"
+                        "\\([eE][-+]?[0-9_]+\\)?")
+                '(0 mdw-number-face))
+          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+                '(0 mdw-punct-face)))))
+
+(progn
+  (add-hook 'tcl-mode-hook 'mdw-misc-mode-config t)
+  (add-hook 'tcl-mode-hook 'mdw-fontify-tcl t))
 
 ;;;--------------------------------------------------------------------------
 ;;; Dylan programming configuration.
 
 ;;;--------------------------------------------------------------------------
 ;;; Dylan programming configuration.
@@ -2570,34 +3685,38 @@ strip numbers instead."
                          "all-keys" "key" "next" "rest" "include"
                          "t" "f")))
     (setq font-lock-keywords
                          "all-keys" "key" "next" "rest" "include"
                          "t" "f")))
     (setq font-lock-keywords
-         (list (list (concat "\\<\\(" dylan-keywords
-                             "\\|" "with\\(out\\)?-" word
-                             "\\)\\>")
-                     '(0 font-lock-keyword-face))
-               (list (concat "\\<" word ":" "\\|"
-                             "#\\(" sharp-keywords "\\)\\>")
-                     '(0 font-lock-variable-name-face))
-               (list (concat "\\("
-                             "\\([-+]\\|\\<\\)[0-9]+" "\\("
-                               "\\(\\.[0-9]+\\)?" "\\([eE][-+][0-9]+\\)?"
-                               "\\|" "/[0-9]+"
-                             "\\)"
-                             "\\|" "\\.[0-9]+" "\\([eE][-+][0-9]+\\)?"
-                             "\\|" "#b[01]+"
-                             "\\|" "#o[0-7]+"
-                             "\\|" "#x[0-9a-zA-Z]+"
-                             "\\)\\>")
-                     '(0 mdw-number-face))
-               (list (concat "\\("
-                             "\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\|"
-                             "\\_<[-+*/=<>:&|]+\\_>"
-                             "\\)")
-                     '(0 mdw-punct-face))))))
+           (list (list (concat "\\<\\(" dylan-keywords
+                               "\\|" "with\\(out\\)?-" word
+                               "\\)\\>")
+                       '(0 font-lock-keyword-face))
+                 (list (concat "\\<" word ":" "\\|"
+                               "#\\(" sharp-keywords "\\)\\>")
+                       '(0 font-lock-variable-name-face))
+                 (list (concat "\\("
+                               "\\([-+]\\|\\<\\)[0-9]+" "\\("
+                                 "\\(\\.[0-9]+\\)?" "\\([eE][-+][0-9]+\\)?"
+                                 "\\|" "/[0-9]+"
+                               "\\)"
+                               "\\|" "\\.[0-9]+" "\\([eE][-+][0-9]+\\)?"
+                               "\\|" "#b[01]+"
+                               "\\|" "#o[0-7]+"
+                               "\\|" "#x[0-9a-zA-Z]+"
+                               "\\)\\>")
+                       '(0 mdw-number-face))
+                 (list (concat "\\("
+                               "\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\|"
+                               "\\_<[-+*/=<>:&|]+\\_>"
+                               "\\)")
+                       '(0 mdw-punct-face))))))
+
+(progn
+  (add-hook 'dylan-mode-hook 'mdw-misc-mode-config t)
+  (add-hook 'dylan-mode-hook 'mdw-fontify-dylan t))
 
 ;;;--------------------------------------------------------------------------
 ;;; Algol 68 configuration.
 
 
 ;;;--------------------------------------------------------------------------
 ;;; Algol 68 configuration.
 
-(setq a68-indent-step 2)
+(setq-default a68-indent-step 2)
 
 (defun mdw-fontify-algol-68 ()
 
 
 (defun mdw-fontify-algol-68 ()
 
@@ -2617,24 +3736,28 @@ strip numbers instead."
                (i 1 (1+ i)))
               ((>= i (length word)) regexp)))))
     (setq font-lock-keywords
                (i 1 (1+ i)))
               ((>= i (length word)) regexp)))))
     (setq font-lock-keywords
-         (list (list (concat "\\<COMMENT\\>"
-                             "\\(" not-comment "\\)\\{0,5\\}"
-                             "\\(\\'\\|\\<COMMENT\\>\\)")
-                     '(0 font-lock-comment-face))
-               (list (concat "\\<CO\\>"
-                             "\\([^C]+\\|C[^O]\\)\\{0,5\\}"
-                             "\\($\\|\\<CO\\>\\)")
-                     '(0 font-lock-comment-face))
-               (list "\\<[A-Z_]+\\>"
-                     '(0 font-lock-keyword-face))
-               (list (concat "\\<"
-                             "[0-9]+"
-                             "\\(\\.[0-9]+\\)?"
-                             "\\([eE][-+]?[0-9]+\\)?"
-                             "\\>")
-                     '(0 mdw-number-face))
-               (list "\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/"
-                     '(0 mdw-punct-face))))))
+           (list (list (concat "\\<COMMENT\\>"
+                               "\\(" not-comment "\\)\\{0,5\\}"
+                               "\\(\\'\\|\\<COMMENT\\>\\)")
+                       '(0 font-lock-comment-face))
+                 (list (concat "\\<CO\\>"
+                               "\\([^C]+\\|C[^O]\\)\\{0,5\\}"
+                               "\\($\\|\\<CO\\>\\)")
+                       '(0 font-lock-comment-face))
+                 (list "\\<[A-Z_]+\\>"
+                       '(0 font-lock-keyword-face))
+                 (list (concat "\\<"
+                               "[0-9]+"
+                               "\\(\\.[0-9]+\\)?"
+                               "\\([eE][-+]?[0-9]+\\)?"
+                               "\\>")
+                       '(0 mdw-number-face))
+                 (list "\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/"
+                       '(0 mdw-punct-face))))))
+
+(dolist (hook '(a68-mode-hook a68-mode-hooks))
+  (add-hook hook 'mdw-misc-mode-config t)
+  (add-hook hook 'mdw-fontify-algol-68 t))
 
 ;;;--------------------------------------------------------------------------
 ;;; REXX configuration.
 
 ;;;--------------------------------------------------------------------------
 ;;; REXX configuration.
@@ -2656,8 +3779,8 @@ strip numbers instead."
   (setq mdw-auto-indent nil)
   (local-set-key [?\C-m] 'mdw-rexx-indent-newline-indent)
   (local-set-key [?*] 'mdw-rexx-electric-*)
   (setq mdw-auto-indent nil)
   (local-set-key [?\C-m] 'mdw-rexx-indent-newline-indent)
   (local-set-key [?*] 'mdw-rexx-electric-*)
-  (mapcar #'(lambda (ch) (modify-syntax-entry ch "w"))
-         '(?! ?? ?# ?@ ?$))
+  (dolist (ch '(?! ?? ?# ?@ ?$)) (modify-syntax-entry ch "w"))
+  (dolist (ch '(?¬)) (modify-syntax-entry ch "."))
   (mdw-standard-fill-prefix "\\([ \t]*/?\*[ \t]*\\)")
 
   ;; Set up keywords and things for fontification.
   (mdw-standard-fill-prefix "\\([ \t]*/?\*[ \t]*\\)")
 
   ;; Set up keywords and things for fontification.
@@ -2694,24 +3817,33 @@ strip numbers instead."
                      "x2d")))
 
     (setq font-lock-keywords
                      "x2d")))
 
     (setq font-lock-keywords
-         (list
+           (list
 
 
-          ;; Set up the keywords defined above.
-          (list (concat "\\<\\(" rexx-keywords "\\)\\>")
-                '(0 font-lock-keyword-face))
+            ;; Set up the keywords defined above.
+            (list (concat "\\<\\(" rexx-keywords "\\)\\>")
+                  '(0 font-lock-keyword-face))
 
 
-          ;; Fontify all symbols the same way.
-          (list (concat "\\<\\([0-9.][A-Za-z0-9.!?_#@$]*[Ee][+-]?[0-9]+\\|"
-                        "[A-Za-z0-9.!?_#@$]+\\)")
-                '(0 font-lock-variable-name-face))
+            ;; Fontify all symbols the same way.
+            (list (concat "\\<\\([0-9.][A-Za-z0-9.!?_#@$]*[Ee][+-]?[0-9]+\\|"
+                          "[A-Za-z0-9.!?_#@$]+\\)")
+                  '(0 font-lock-variable-name-face))
 
 
-          ;; And everything else is punctuation.
-          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face))))))
+            ;; And everything else is punctuation.
+            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+                  '(0 mdw-punct-face))))))
+
+(progn
+  (add-hook 'rexx-mode-hook 'mdw-misc-mode-config t)
+  (add-hook 'rexx-mode-hook 'mdw-fontify-rexx t))
 
 ;;;--------------------------------------------------------------------------
 ;;; Standard ML programming style.
 
 
 ;;;--------------------------------------------------------------------------
 ;;; Standard ML programming style.
 
+(setq-default sml-nested-if-indent t
+             sml-case-indent nil
+             sml-indent-level 4
+             sml-type-of-indent nil)
+
 (defun mdw-fontify-sml ()
 
   ;; Make underscore an honorary letter.
 (defun mdw-fontify-sml ()
 
   ;; Make underscore an honorary letter.
@@ -2740,28 +3872,34 @@ strip numbers instead."
                      "where" "while" "with" "withtype")))
 
     (setq font-lock-keywords
                      "where" "while" "with" "withtype")))
 
     (setq font-lock-keywords
-         (list
+           (list
 
 
-          ;; Set up the keywords defined above.
-          (list (concat "\\<\\(" sml-keywords "\\)\\>")
-                '(0 font-lock-keyword-face))
+            ;; Set up the keywords defined above.
+            (list (concat "\\<\\(" sml-keywords "\\)\\>")
+                  '(0 font-lock-keyword-face))
 
 
-          ;; At least numbers are simpler than C.
-          (list (concat "\\<\\(\\~\\|\\)"
-                           "\\(0\\(\\([wW]\\|\\)[xX][0-9a-fA-F]+\\|"
-                                  "[wW][0-9]+\\)\\|"
-                               "\\([0-9]+\\(\\.[0-9]+\\|\\)"
-                                        "\\([eE]\\(\\~\\|\\)"
-                                               "[0-9]+\\|\\)\\)\\)")
-                '(0 mdw-number-face))
+            ;; At least numbers are simpler than C.
+            (list (concat "\\<\\~?"
+                             "\\(0\\([wW]?[xX][0-9a-fA-F]+\\|"
+                                    "[wW][0-9]+\\)\\|"
+                                 "\\([0-9]+\\(\\.[0-9]+\\)?"
+                                          "\\([eE]\\~?"
+                                                 "[0-9]+\\)?\\)\\)")
+                  '(0 mdw-number-face))
 
 
-          ;; And anything else is punctuation.
-          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face))))))
+            ;; And anything else is punctuation.
+            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+                  '(0 mdw-punct-face))))))
+
+(progn
+  (add-hook 'sml-mode-hook 'mdw-misc-mode-config t)
+  (add-hook 'sml-mode-hook 'mdw-fontify-sml t))
 
 ;;;--------------------------------------------------------------------------
 ;;; Haskell configuration.
 
 
 ;;;--------------------------------------------------------------------------
 ;;; Haskell configuration.
 
+(setq-default haskell-indent-offset 2)
+
 (defun mdw-fontify-haskell ()
 
   ;; Fiddle with syntax table to get comments right.
 (defun mdw-fontify-haskell ()
 
   ;; Fiddle with syntax table to get comments right.
@@ -2806,41 +3944,45 @@ strip numbers instead."
                      "SP" "STX" "SUB" "SYN" "US" "VT")))
 
     (setq font-lock-keywords
                      "SP" "STX" "SUB" "SYN" "US" "VT")))
 
     (setq font-lock-keywords
-         (list
-          (list (concat "{-" "[^-]*" "\\(-+[^-}][^-]*\\)*"
-                             "\\(-+}\\|-*\\'\\)"
-                        "\\|"
-                        "--.*$")
-                '(0 font-lock-comment-face))
-          (list (concat "\\_<\\(" haskell-keywords "\\)\\_>")
-                '(0 font-lock-keyword-face))
-          (list (concat "'\\("
-                        "[^\\]"
-                        "\\|"
-                        "\\\\"
-                        "\\(" "[abfnrtv\\\"']" "\\|"
-                              "^" "\\(" control-sequences "\\|"
-                                        "[]A-Z@[\\^_]" "\\)" "\\|"
-                              "\\|"
-                              "[0-9]+" "\\|"
-                              "[oO][0-7]+" "\\|"
-                              "[xX][0-9A-Fa-f]+"
-                        "\\)"
-                        "\\)'")
-                '(0 font-lock-string-face))
-          (list "\\_<[A-Z]\\(\\sw+\\|\\s_+\\)*\\_>"
-                '(0 font-lock-variable-name-face))
-          (list (concat "\\_<0\\([xX][0-9a-fA-F]+\\|[oO][0-7]+\\)\\|"
-                        "\\_<[0-9]+\\(\\.[0-9]*\\|\\)"
-                        "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)")
-                '(0 mdw-number-face))
-          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face))))))
+           (list
+            (list (concat "{-" "[^-]*" "\\(-+[^-}][^-]*\\)*"
+                               "\\(-+}\\|-*\\'\\)"
+                          "\\|"
+                          "--.*$")
+                  '(0 font-lock-comment-face))
+            (list (concat "\\_<\\(" haskell-keywords "\\)\\_>")
+                  '(0 font-lock-keyword-face))
+            (list (concat "'\\("
+                          "[^\\]"
+                          "\\|"
+                          "\\\\"
+                          "\\(" "[abfnrtv\\\"']" "\\|"
+                                "^" "\\(" control-sequences "\\|"
+                                          "[]A-Z@[\\^_]" "\\)" "\\|"
+                                "\\|"
+                                "[0-9]+" "\\|"
+                                "[oO][0-7]+" "\\|"
+                                "[xX][0-9A-Fa-f]+"
+                          "\\)"
+                          "\\)'")
+                  '(0 font-lock-string-face))
+            (list "\\_<[A-Z]\\(\\sw+\\|\\s_+\\)*\\_>"
+                  '(0 font-lock-variable-name-face))
+            (list (concat "\\_<0\\([xX][0-9a-fA-F]+\\|[oO][0-7]+\\)\\|"
+                          "\\_<[0-9]+\\(\\.[0-9]*\\)?"
+                          "\\([eE][-+]?[0-9]+\\)?")
+                  '(0 mdw-number-face))
+            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+                  '(0 mdw-punct-face))))))
+
+(progn
+  (add-hook 'haskell-mode-hook 'mdw-misc-mode-config t)
+  (add-hook 'haskell-mode-hook 'mdw-fontify-haskell t))
 
 ;;;--------------------------------------------------------------------------
 ;;; Erlang configuration.
 
 
 ;;;--------------------------------------------------------------------------
 ;;; Erlang configuration.
 
-(setq erlang-electric-commands nil)
+(setq-default erlang-electric-commands nil)
 
 (defun mdw-fontify-erlang ()
 
 
 (defun mdw-fontify-erlang ()
 
@@ -2858,17 +4000,21 @@ strip numbers instead."
                      "query" "receive" "rem" "try" "when" "xor")))
 
     (setq font-lock-keywords
                      "query" "receive" "rem" "try" "when" "xor")))
 
     (setq font-lock-keywords
-         (list
-          (list "%.*$"
-                '(0 font-lock-comment-face))
-          (list (concat "\\<\\(" erlang-keywords "\\)\\>")
-                '(0 font-lock-keyword-face))
-          (list (concat "^-\\sw+\\>")
-                '(0 font-lock-keyword-face))
-          (list "\\<[0-9]+\\(\\|#[0-9a-zA-Z]+\\|[eE][+-]?[0-9]+\\)\\>"
-                '(0 mdw-number-face))
-          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face))))))
+           (list
+            (list "%.*$"
+                  '(0 font-lock-comment-face))
+            (list (concat "\\<\\(" erlang-keywords "\\)\\>")
+                  '(0 font-lock-keyword-face))
+            (list (concat "^-\\sw+\\>")
+                  '(0 font-lock-keyword-face))
+            (list "\\<[0-9]+\\(#[0-9a-zA-Z]+\\|[eE][+-]?[0-9]+\\)?\\>"
+                  '(0 mdw-number-face))
+            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+                  '(0 mdw-punct-face))))))
+
+(progn
+  (add-hook 'erlang-mode-hook 'mdw-misc-mode-config t)
+  (add-hook 'erlang-mode-hook 'mdw-fontify-erlang t))
 
 ;;;--------------------------------------------------------------------------
 ;;; Texinfo configuration.
 
 ;;;--------------------------------------------------------------------------
 ;;; Texinfo configuration.
@@ -2881,32 +4027,41 @@ strip numbers instead."
   ;; Real fontification things.
   (make-local-variable 'font-lock-keywords)
   (setq font-lock-keywords
   ;; Real fontification things.
   (make-local-variable 'font-lock-keywords)
   (setq font-lock-keywords
-       (list
+         (list
 
 
-        ;; Environment names are keywords.
-        (list "@\\(end\\)  *\\([a-zA-Z]*\\)?"
-              '(2 font-lock-keyword-face))
+          ;; Environment names are keywords.
+          (list "@\\(end\\)  *\\([a-zA-Z]*\\)?"
+                '(2 font-lock-keyword-face))
 
 
-        ;; Unmark escaped magic characters.
-        (list "\\(@\\)\\([@{}]\\)"
-              '(1 font-lock-keyword-face)
-              '(2 font-lock-variable-name-face))
+          ;; Unmark escaped magic characters.
+          (list "\\(@\\)\\([@{}]\\)"
+                '(1 font-lock-keyword-face)
+                '(2 font-lock-variable-name-face))
 
 
-        ;; Make sure we get comments properly.
-        (list "@c\\(\\|omment\\)\\( .*\\)?$"
-              '(0 font-lock-comment-face))
+          ;; Make sure we get comments properly.
+          (list "@c\\(omment\\)?\\( .*\\)?$"
+                '(0 font-lock-comment-face))
 
 
-        ;; Command names are keywords.
-        (list "@\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
-              '(0 font-lock-keyword-face))
+          ;; Command names are keywords.
+          (list "@\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
+                '(0 font-lock-keyword-face))
 
 
-        ;; Fontify TeX special characters as punctuation.
-        (list "[{}]+"
-              '(0 mdw-punct-face)))))
+          ;; Fontify TeX special characters as punctuation.
+          (list "[{}]+"
+                '(0 mdw-punct-face)))))
+
+(dolist (hook '(texinfo-mode-hook TeXinfo-mode-hook))
+  (add-hook hook 'mdw-misc-mode-config t)
+  (add-hook hook 'mdw-fontify-texinfo t))
 
 ;;;--------------------------------------------------------------------------
 ;;; TeX and LaTeX configuration.
 
 
 ;;;--------------------------------------------------------------------------
 ;;; TeX and LaTeX configuration.
 
+(setq-default LaTeX-table-label "tbl:"
+             TeX-auto-untabify nil
+             LaTeX-syntactic-comments nil
+             LaTeX-fill-break-at-separators '(\\\[))
+
 (defun mdw-fontify-tex ()
   (setq ispell-parser 'tex)
   (turn-on-reftex)
 (defun mdw-fontify-tex ()
   (setq ispell-parser 'tex)
   (turn-on-reftex)
@@ -2917,7 +4072,7 @@ strip numbers instead."
   (local-set-key [?$] 'self-insert-command)
 
   ;; Make `tab' be useful, given that tab stops in TeX don't work well.
   (local-set-key [?$] 'self-insert-command)
 
   ;; Make `tab' be useful, given that tab stops in TeX don't work well.
-  (local-set-key "\C-i" 'indent-relative)
+  (local-set-key "\C-\M-i" 'indent-relative)
   (setq indent-tabs-mode nil)
 
   ;; Set fill prefix.
   (setq indent-tabs-mode nil)
 
   ;; Set fill prefix.
@@ -2926,71 +4081,175 @@ strip numbers instead."
   ;; Real fontification things.
   (make-local-variable 'font-lock-keywords)
   (setq font-lock-keywords
   ;; Real fontification things.
   (make-local-variable 'font-lock-keywords)
   (setq font-lock-keywords
-       (list
-
-        ;; Environment names are keywords.
-        (list (concat "\\\\\\(begin\\|end\\|newenvironment\\)"
-                      "{\\([^}\n]*\\)}")
-              '(2 font-lock-keyword-face))
-
-        ;; Suspended environment names are keywords too.
-        (list (concat "\\\\\\(suspend\\|resume\\)\\(\\[[^]]*\\]\\)?"
-                      "{\\([^}\n]*\\)}")
-              '(3 font-lock-keyword-face))
-
-        ;; Command names are keywords.
-        (list "\\\\\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
-              '(0 font-lock-keyword-face))
-
-        ;; Handle @/.../ for italics.
-        ;; (list "\\(@/\\)\\([^/]*\\)\\(/\\)"
-        ;;       '(1 font-lock-keyword-face)
-        ;;       '(3 font-lock-keyword-face))
-
-        ;; Handle @*...* for boldness.
-        ;; (list "\\(@\\*\\)\\([^*]*\\)\\(\\*\\)"
-        ;;       '(1 font-lock-keyword-face)
-        ;;       '(3 font-lock-keyword-face))
-
-        ;; Handle @`...' for literal syntax things.
-        ;; (list "\\(@`\\)\\([^']*\\)\\('\\)"
-        ;;       '(1 font-lock-keyword-face)
-        ;;       '(3 font-lock-keyword-face))
-
-        ;; Handle @<...> for nonterminals.
-        ;; (list "\\(@<\\)\\([^>]*\\)\\(>\\)"
-        ;;       '(1 font-lock-keyword-face)
-        ;;       '(3 font-lock-keyword-face))
-
-        ;; Handle other @-commands.
-        ;; (list "@\\([^a-zA-Z]\\|[a-zA-Z]*\\)"
-        ;;       '(0 font-lock-keyword-face))
-
-        ;; Make sure we get comments properly.
-        (list "%.*"
-              '(0 font-lock-comment-face))
-
-        ;; Fontify TeX special characters as punctuation.
-        (list "[$^_{}#&]"
-              '(0 mdw-punct-face)))))
+         (list
+
+          ;; Environment names are keywords.
+          (list (concat "\\\\\\(begin\\|end\\|newenvironment\\)"
+                        "{\\([^}\n]*\\)}")
+                '(2 font-lock-keyword-face))
+
+          ;; Suspended environment names are keywords too.
+          (list (concat "\\\\\\(suspend\\|resume\\)\\(\\[[^]]*\\]\\)?"
+                        "{\\([^}\n]*\\)}")
+                '(3 font-lock-keyword-face))
+
+          ;; Command names are keywords.
+          (list "\\\\\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
+                '(0 font-lock-keyword-face))
+
+          ;; Handle @/.../ for italics.
+          ;; (list "\\(@/\\)\\([^/]*\\)\\(/\\)"
+          ;;     '(1 font-lock-keyword-face)
+          ;;     '(3 font-lock-keyword-face))
+
+          ;; Handle @*...* for boldness.
+          ;; (list "\\(@\\*\\)\\([^*]*\\)\\(\\*\\)"
+          ;;     '(1 font-lock-keyword-face)
+          ;;     '(3 font-lock-keyword-face))
+
+          ;; Handle @`...' for literal syntax things.
+          ;; (list "\\(@`\\)\\([^']*\\)\\('\\)"
+          ;;     '(1 font-lock-keyword-face)
+          ;;     '(3 font-lock-keyword-face))
+
+          ;; Handle @<...> for nonterminals.
+          ;; (list "\\(@<\\)\\([^>]*\\)\\(>\\)"
+          ;;     '(1 font-lock-keyword-face)
+          ;;     '(3 font-lock-keyword-face))
+
+          ;; Handle other @-commands.
+          ;; (list "@\\([^a-zA-Z]\\|[a-zA-Z]*\\)"
+          ;;     '(0 font-lock-keyword-face))
+
+          ;; Make sure we get comments properly.
+          (list "%.*"
+                '(0 font-lock-comment-face))
+
+          ;; Fontify TeX special characters as punctuation.
+          (list "[$^_{}#&]"
+                '(0 mdw-punct-face)))))
+
+(setq TeX-install-font-lock 'tex-font-setup)
+
+(eval-after-load 'font-latex
+  '(defun font-latex-jit-lock-force-redisplay (buf start end)
+     "Compatibility for Emacsen not offering `jit-lock-force-redisplay'."
+     ;; The following block is an expansion of `jit-lock-force-redisplay'
+     ;; and involved macros taken from CVS Emacs on 2007-04-28.
+     (with-current-buffer buf
+       (let ((modified (buffer-modified-p)))
+        (unwind-protect
+            (let ((buffer-undo-list t)
+                  (inhibit-read-only t)
+                  (inhibit-point-motion-hooks t)
+                  (inhibit-modification-hooks t)
+                  deactivate-mark
+                  buffer-file-name
+                  buffer-file-truename)
+              (put-text-property start end 'fontified t))
+          (unless modified
+            (restore-buffer-modified-p nil)))))))
+
+(setq TeX-output-view-style
+       '(("^dvi$"
+          ("^landscape$" "^pstricks$\\|^pst-\\|^psfrag$")
+          "%(o?)dvips -t landscape %d -o && xdg-open %f")
+         ("^dvi$" "^pstricks$\\|^pst-\\|^psfrag$"
+          "%(o?)dvips %d -o && xdg-open %f")
+         ("^dvi$"
+          ("^a4\\(?:dutch\\|paper\\|wide\\)\\|sem-a4$" "^landscape$")
+          "%(o?)xdvi %dS -paper a4r -s 0 %d")
+         ("^dvi$" "^a4\\(?:dutch\\|paper\\|wide\\)\\|sem-a4$"
+          "%(o?)xdvi %dS -paper a4 %d")
+         ("^dvi$"
+          ("^a5\\(?:comb\\|paper\\)$" "^landscape$")
+          "%(o?)xdvi %dS -paper a5r -s 0 %d")
+         ("^dvi$" "^a5\\(?:comb\\|paper\\)$" "%(o?)xdvi %dS -paper a5 %d")
+         ("^dvi$" "^b5paper$" "%(o?)xdvi %dS -paper b5 %d")
+         ("^dvi$" "^letterpaper$" "%(o?)xdvi %dS -paper us %d")
+         ("^dvi$" "^legalpaper$" "%(o?)xdvi %dS -paper legal %d")
+         ("^dvi$" "^executivepaper$" "%(o?)xdvi %dS -paper 7.25x10.5in %d")
+         ("^dvi$" "." "%(o?)xdvi %dS %d")
+         ("^pdf$" "." "xdg-open %o")
+         ("^html?$" "." "sensible-browser %o")))
+
+(setq TeX-view-program-list
+       '(("mupdf" ("mupdf %o" (mode-io-correlate " %(outpage)")))))
+
+(setq TeX-view-program-selection
+       '(((output-dvi style-pstricks) "dvips and gv")
+         (output-dvi "xdvi")
+         (output-pdf "mupdf")
+         (output-html "sensible-browser")))
+
+(setq TeX-open-quote "\""
+      TeX-close-quote "\"")
+
+(setq reftex-use-external-file-finders t
+      reftex-auto-recenter-toc t)
+
+(setq reftex-label-alist
+       '(("theorem" ?T "th:" "~\\ref{%s}" t ("theorems?" "th\\.") -2)
+         ("axiom" ?A "ax:" "~\\ref{%s}" t ("axioms?" "ax\\.") -2)
+         ("definition" ?D "def:" "~\\ref{%s}" t ("definitions?" "def\\.") -2)
+         ("proposition" ?P "prop:" "~\\ref{%s}" t
+          ("propositions?" "prop\\.") -2)
+         ("lemma" ?L "lem:" "~\\ref{%s}" t ("lemmas?" "lem\\.") -2)
+         ("example" ?X "eg:" "~\\ref{%s}" t ("examples?") -2)
+         ("exercise" ?E "ex:" "~\\ref{%s}" t ("exercises?" "ex\\.") -2)
+         ("enumerate" ?i "i:" "~\\ref{%s}" item ("items?"))))
+(setq reftex-section-prefixes
+       '((0 . "part:")
+         (1 . "ch:")
+         (t . "sec:")))
+
+(setq bibtex-field-delimiters 'double-quotes
+      bibtex-align-at-equal-sign t
+      bibtex-entry-format '(realign opts-or-alts required-fields
+                           numerical-fields last-comma delimiters
+                           unify-case sort-fields braces)
+      bibtex-sort-ignore-string-entries nil
+      bibtex-maintain-sorted-entries 'entry-class
+      bibtex-include-OPTkey t
+      bibtex-autokey-names-stretch 1
+      bibtex-autokey-expand-strings t
+      bibtex-autokey-name-separator "-"
+      bibtex-autokey-year-length 4
+      bibtex-autokey-titleword-separator "-"
+      bibtex-autokey-name-year-separator "-"
+      bibtex-autokey-year-title-separator ":")
+
+(progn
+  (dolist (hook '(tex-mode-hook latex-mode-hook
+                               TeX-mode-hook LaTeX-mode-hook))
+    (add-hook hook 'mdw-misc-mode-config t)
+    (add-hook hook 'mdw-fontify-tex t))
+  (add-hook 'bibtex-mode-hook (lambda () (setq fill-column 76))))
+
+;;;--------------------------------------------------------------------------
+;;; HTML, CSS, and other web foolishness.
+
+(setq-default css-indent-offset 8)
 
 ;;;--------------------------------------------------------------------------
 ;;; SGML hacking.
 
 
 ;;;--------------------------------------------------------------------------
 ;;; SGML hacking.
 
+(setq-default psgml-html-build-new-buffer nil)
+
 (defun mdw-sgml-mode ()
   (interactive)
   (sgml-mode)
   (mdw-standard-fill-prefix "")
   (make-local-variable 'sgml-delimiters)
   (setq sgml-delimiters
 (defun mdw-sgml-mode ()
   (interactive)
   (sgml-mode)
   (mdw-standard-fill-prefix "")
   (make-local-variable 'sgml-delimiters)
   (setq sgml-delimiters
-       '("AND" "&" "COM" "--" "CRO" "&#" "DSC" "]" "DSO" "[" "DTGC" "]"
-         "DTGO" "[" "ERO" "&" "ETAGO" ":e" "GRPC" ")" "GRPO" "(" "LIT" "\""
-         "LITA" "'" "MDC" ">" "MDO" "<!" "MINUS" "-" "MSC" "]]" "NESTC" "{"
-         "NET" "}" "OPT" "?" "OR" "|" "PERO" "%" "PIC" ">" "PIO" "<?"
-         "PLUS" "+" "REFC" "." "REP" "*" "RNI" "#" "SEQ" "," "STAGO" ":"
-         "TAGC" "." "VI" "=" "MS-START" "<![" "MS-END" "]]>"
-         "XML-ECOM" "-->" "XML-PIC" "?>" "XML-SCOM" "<!--" "XML-TAGCE" "/>"
-         "NULL" ""))
+         '("AND" "&" "COM" "--" "CRO" "&#" "DSC" "]" "DSO" "[" "DTGC" "]"
+           "DTGO" "[" "ERO" "&" "ETAGO" ":e" "GRPC" ")" "GRPO" "(" "LIT"
+           "\"" "LITA" "'" "MDC" ">" "MDO" "<!" "MINUS" "-" "MSC" "]]"
+           "NESTC" "{" "NET" "}" "OPT" "?" "OR" "|" "PERO" "%" "PIC" ">"
+           "PIO" "<?" "PLUS" "+" "REFC" "." "REP" "*" "RNI" "#" "SEQ" ","
+           "STAGO" ":" "TAGC" "." "VI" "=" "MS-START" "<![" "MS-END" "]]>"
+           "XML-ECOM" "-->" "XML-PIC" "?>" "XML-SCOM" "<!--" "XML-TAGCE"
+           "/>" "NULL" ""))
   (setq major-mode 'mdw-sgml-mode)
   (setq mode-name "[mdw] SGML")
   (run-hooks 'mdw-sgml-mode-hook))
   (setq major-mode 'mdw-sgml-mode)
   (setq mode-name "[mdw] SGML")
   (run-hooks 'mdw-sgml-mode-hook))
@@ -2998,21 +4257,21 @@ strip numbers instead."
 ;;;--------------------------------------------------------------------------
 ;;; Configuration files.
 
 ;;;--------------------------------------------------------------------------
 ;;; Configuration files.
 
-(defvar mdw-conf-quote-normal nil
-  "*Control syntax category of quote characters `\"' and `''.
+(defcustom mdw-conf-quote-normal nil
+  "Control syntax category of quote characters `\"' and `''.
 If this is `t', consider quote characters to be normal
 punctuation, as for `conf-quote-normal'.  If this is `nil' then
 leave quote characters as quotes.  If this is a list, then
 consider the quote characters in the list to be normal
 punctuation.  If this is a single quote character, then consider
 If this is `t', consider quote characters to be normal
 punctuation, as for `conf-quote-normal'.  If this is `nil' then
 leave quote characters as quotes.  If this is a list, then
 consider the quote characters in the list to be normal
 punctuation.  If this is a single quote character, then consider
-that character only to be normal punctuation.")
+that character only to be normal punctuation."
+  :type '(choice boolean character (repeat character))
+  :safe 'mdw-conf-quote-normal-acceptable-value-p)
 (defun mdw-conf-quote-normal-acceptable-value-p (value)
   "Is the VALUE is an acceptable value for `mdw-conf-quote-normal'?"
   (or (booleanp value)
       (every (lambda (v) (memq v '(?\" ?')))
             (if (listp value) value (list value)))))
 (defun mdw-conf-quote-normal-acceptable-value-p (value)
   "Is the VALUE is an acceptable value for `mdw-conf-quote-normal'?"
   (or (booleanp value)
       (every (lambda (v) (memq v '(?\" ?')))
             (if (listp value) value (list value)))))
-(put 'mdw-conf-quote-normal 'safe-local-variable
-     'mdw-conf-quote-normal-acceptable-value-p)
 
 (defun mdw-fix-up-quote ()
   "Apply the setting of `mdw-conf-quote-normal'."
 
 (defun mdw-fix-up-quote ()
   "Apply the setting of `mdw-conf-quote-normal'."
@@ -3023,11 +4282,14 @@ that character only to be normal punctuation.")
           nil)
          (t
           (let ((table (copy-syntax-table (syntax-table))))
           nil)
          (t
           (let ((table (copy-syntax-table (syntax-table))))
-            (mapc (lambda (ch) (modify-syntax-entry ch "." table))
-                  (if (listp flag) flag (list flag)))
+            (dolist (ch (if (listp flag) flag (list flag)))
+              (modify-syntax-entry ch "." table))
             (set-syntax-table table)
             (and font-lock-mode (font-lock-fontify-buffer)))))))
             (set-syntax-table table)
             (and font-lock-mode (font-lock-fontify-buffer)))))))
-(add-hook 'conf-mode-local-variables-hook 'mdw-fix-up-quote t t)
+
+(progn
+  (add-hook 'conf-mode-hook 'mdw-misc-mode-config t)
+  (add-hook 'conf-mode-local-variables-hook 'mdw-fix-up-quote t t))
 
 ;;;--------------------------------------------------------------------------
 ;;; Shell scripts.
 
 ;;;--------------------------------------------------------------------------
 ;;; Shell scripts.
@@ -3094,8 +4356,12 @@ that character only to be normal punctuation.")
         (if assoc
             (rplacd assoc frag)
           (setq sh-mode-syntax-table-input
         (if assoc
             (rplacd assoc frag)
           (setq sh-mode-syntax-table-input
-                (cons (cons 'rc frag)
-                      sh-mode-syntax-table-input))))))
+                  (cons (cons 'rc frag)
+                        sh-mode-syntax-table-input))))))
+
+(progn
+  (add-hook 'sh-mode-hook 'mdw-misc-mode-config t)
+  (add-hook 'sh-mode-hook 'mdw-setup-sh-script-mode t))
 
 ;;;--------------------------------------------------------------------------
 ;;; Emacs shell mode.
 
 ;;;--------------------------------------------------------------------------
 ;;; Emacs shell mode.
@@ -3117,8 +4383,8 @@ that character only to be normal punctuation.")
                  (concat "~" (substring pwd (length home)))
                pwd))
            right)))
                  (concat "~" (substring pwd (length home)))
                pwd))
            right)))
-(setq eshell-prompt-function 'mdw-eshell-prompt)
-(setq eshell-prompt-regexp "^\\[[^]>]+\\(\\]\\|>>?\\)")
+(setq-default eshell-prompt-function 'mdw-eshell-prompt)
+(setq-default eshell-prompt-regexp "^\\[[^]>]+\\(\\]\\|>>?\\)")
 
 (defun eshell/e (file) (find-file file) nil)
 (defun eshell/ee (file) (find-file-other-window file) nil)
 
 (defun eshell/e (file) (find-file file) nil)
 (defun eshell/ee (file) (find-file-other-window file) nil)
@@ -3134,6 +4400,9 @@ that character only to be normal punctuation.")
 (mdw-define-face eshell-ls-readonly (t nil))
 (mdw-define-face eshell-ls-symlink (t :foreground "cyan"))
 
 (mdw-define-face eshell-ls-readonly (t nil))
 (mdw-define-face eshell-ls-symlink (t :foreground "cyan"))
 
+(defun mdw-eshell-hack () (setenv "LD_PRELOAD" nil))
+(add-hook 'eshell-mode-hook 'mdw-eshell-hack)
+
 ;;;--------------------------------------------------------------------------
 ;;; Messages-file mode.
 
 ;;;--------------------------------------------------------------------------
 ;;; Messages-file mode.
 
@@ -3166,17 +4435,17 @@ that character only to be normal punctuation.")
                      "set" "table" "tagged-optional"   "union"
                      "variadic" "vector" "version" "version-tag")))
     (setq messages-mode-keywords
                      "set" "table" "tagged-optional"   "union"
                      "variadic" "vector" "version" "version-tag")))
     (setq messages-mode-keywords
-         (list
-          (list (concat "\\<\\(" keywords "\\)\\>:")
-                '(0 font-lock-keyword-face))
-          '("\\([-a-zA-Z0-9]+:\\)" (0 font-lock-warning-face))
-          '("\\(\\<[a-z][-_a-zA-Z0-9]*\\)"
-            (0 font-lock-variable-name-face))
-          '("\\<\\([0-9]+\\)\\>" (0 mdw-number-face))
-          '("\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-            (0 mdw-punct-face)))))
+           (list
+            (list (concat "\\<\\(" keywords "\\)\\>:")
+                  '(0 font-lock-keyword-face))
+            '("\\([-a-zA-Z0-9]+:\\)" (0 font-lock-warning-face))
+            '("\\(\\<[a-z][-_a-zA-Z0-9]*\\)"
+              (0 font-lock-variable-name-face))
+            '("\\<\\([0-9]+\\)\\>" (0 mdw-number-face))
+            '("\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+              (0 mdw-punct-face)))))
   (setq font-lock-defaults
   (setq font-lock-defaults
-       '(messages-mode-keywords nil nil nil nil))
+         '(messages-mode-keywords nil nil nil nil))
   (run-hooks 'messages-file-hook))
 
 (defun messages-mode ()
   (run-hooks 'messages-file-hook))
 
 (defun messages-mode ()
@@ -3206,20 +4475,22 @@ that character only to be normal punctuation.")
                      "ident" "if" "ifdef" "ifndef" "import" "include"
                      "line" "pragma" "unassert" "undef" "warning")))
     (setq messages-mode-keywords
                      "ident" "if" "ifdef" "ifndef" "import" "include"
                      "line" "pragma" "unassert" "undef" "warning")))
     (setq messages-mode-keywords
-         (append (list (list (concat "^[ \t]*\\#[ \t]*"
-                                     "\\(include\\|import\\)"
-                                     "[ \t]*\\(<[^>]+\\(>\\|\\)\\)")
-                             '(2 font-lock-string-face))
-                       (list (concat "^\\([ \t]*#[ \t]*\\(\\("
-                                     preprocessor-keywords
-                                     "\\)\\>\\|[0-9]+\\|$\\)\\)")
-                             '(1 font-lock-keyword-face)))
-                 messages-mode-keywords)))
+           (append (list (list (concat "^[ \t]*\\#[ \t]*"
+                                       "\\(include\\|import\\)"
+                                       "[ \t]*\\(<[^>]+\\(>\\)?\\)")
+                               '(2 font-lock-string-face))
+                         (list (concat "^\\([ \t]*#[ \t]*\\(\\("
+                                       preprocessor-keywords
+                                       "\\)\\>\\|[0-9]+\\|$\\)\\)")
+                               '(1 font-lock-keyword-face)))
+                   messages-mode-keywords)))
   (run-hooks 'cpp-messages-mode-hook))
 
   (run-hooks 'cpp-messages-mode-hook))
 
-(add-hook 'messages-mode-hook 'mdw-misc-mode-config t)
-(add-hook 'cpp-messages-mode-hook 'mdw-misc-mode-config t)
-; (add-hook 'messages-file-hook 'mdw-fontify-messages t)
+(progn
+  (add-hook 'messages-mode-hook 'mdw-misc-mode-config t)
+  (add-hook 'cpp-messages-mode-hook 'mdw-misc-mode-config t)
+  ;; (add-hook 'messages-file-hook 'mdw-fontify-messages t)
+  )
 
 ;;;--------------------------------------------------------------------------
 ;;; Messages-file mode.
 
 ;;;--------------------------------------------------------------------------
 ;;; Messages-file mode.
@@ -3249,16 +4520,16 @@ that character only to be normal punctuation.")
         (mdw-regexps "each" "divert" "file" "if"
                      "perl" "set" "string" "type" "write")))
     (setq mallow-driver-mode-keywords
         (mdw-regexps "each" "divert" "file" "if"
                      "perl" "set" "string" "type" "write")))
     (setq mallow-driver-mode-keywords
-         (list
-          (list (concat "^%\\s *\\(}\\|\\(" keywords "\\)\\>\\).*$")
-                '(0 font-lock-keyword-face))
-          (list "^%\\s *\\(#.*\\|\\)$"
-                '(0 font-lock-comment-face))
-          (list "^%"
-                '(0 font-lock-keyword-face))
-          (list "^|?\\(.+\\)$" '(1 mallow-driver-text-face))
-          (list "\\${[^}]*}"
-                '(0 mallow-driver-substitution-face t)))))
+           (list
+            (list (concat "^%\\s *\\(}\\|\\(" keywords "\\)\\>\\).*$")
+                  '(0 font-lock-keyword-face))
+            (list "^%\\s *\\(#.*\\)?$"
+                  '(0 font-lock-comment-face))
+            (list "^%"
+                  '(0 font-lock-keyword-face))
+            (list "^|?\\(.+\\)$" '(1 mallow-driver-text-face))
+            (list "\\${[^}]*}"
+                  '(0 mallow-driver-substitution-face t)))))
   (setq font-lock-defaults
        '(mallow-driver-mode-keywords nil nil nil nil))
   (modify-syntax-entry ?\" "_" mallow-driver-mode-syntax-table)
   (setq font-lock-defaults
        '(mallow-driver-mode-keywords nil nil nil nil))
   (modify-syntax-entry ?\" "_" mallow-driver-mode-syntax-table)
@@ -3267,7 +4538,8 @@ that character only to be normal punctuation.")
   (setq comment-end "")
   (run-hooks 'mallow-driver-mode-hook))
 
   (setq comment-end "")
   (run-hooks 'mallow-driver-mode-hook))
 
-(add-hook 'mallow-driver-hook 'mdw-misc-mode-config t)
+(progn
+  (add-hook 'mallow-driver-hook 'mdw-misc-mode-config t))
 
 ;;;--------------------------------------------------------------------------
 ;;; NFast debugs.
 
 ;;;--------------------------------------------------------------------------
 ;;; NFast debugs.
@@ -3283,58 +4555,34 @@ that character only to be normal punctuation.")
   (make-local-variable 'nfast-debug-mode-keywords)
   (setq truncate-lines t)
   (setq nfast-debug-mode-keywords
   (make-local-variable 'nfast-debug-mode-keywords)
   (setq truncate-lines t)
   (setq nfast-debug-mode-keywords
-       (list
-        '("^\\(NFast_\\(Connect\\|Disconnect\\|Submit\\|Wait\\)\\)"
-          (0 font-lock-keyword-face))
-        (list (concat "^[ \t]+\\(\\("
-                      "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"
-                      "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"
-                      "[ \t]+\\)*"
-                      "[0-9a-fA-F]+\\)[ \t]*$")
-          '(0 mdw-number-face))
-        '("^[ \t]+\.status=[ \t]+\\<\\(OK\\)\\>"
-          (1 font-lock-keyword-face))
-        '("^[ \t]+\.status=[ \t]+\\<\\([a-zA-Z][0-9a-zA-Z]*\\)\\>"
-          (1 font-lock-warning-face))
-        '("^[ \t]+\.status[ \t]+\\<\\(zero\\)\\>"
-          (1 nil))
-        (list (concat "^[ \t]+\\.cmd=[ \t]+"
-                      "\\<\\([a-zA-Z][0-9a-zA-Z]*\\)\\>")
-          '(1 font-lock-keyword-face))
-        '("-?\\<\\([0-9]+\\|0x[0-9a-fA-F]+\\)\\>" (0 mdw-number-face))
-        '("^\\([ \t]+[a-z0-9.]+\\)" (0 font-lock-variable-name-face))
-        '("\\<\\([a-z][a-z0-9.]+\\)\\>=" (1 font-lock-variable-name-face))
-        '("\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" (0 mdw-punct-face))))
+         (list
+          '("^\\(NFast_\\(Connect\\|Disconnect\\|Submit\\|Wait\\)\\)"
+            (0 font-lock-keyword-face))
+          (list (concat "^[ \t]+\\(\\("
+                        "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"
+                        "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"
+                        "[ \t]+\\)*"
+                        "[0-9a-fA-F]+\\)[ \t]*$")
+                '(0 mdw-number-face))
+          '("^[ \t]+\.status=[ \t]+\\<\\(OK\\)\\>"
+            (1 font-lock-keyword-face))
+          '("^[ \t]+\.status=[ \t]+\\<\\([a-zA-Z][0-9a-zA-Z]*\\)\\>"
+            (1 font-lock-warning-face))
+          '("^[ \t]+\.status[ \t]+\\<\\(zero\\)\\>"
+            (1 nil))
+          (list (concat "^[ \t]+\\.cmd=[ \t]+"
+                        "\\<\\([a-zA-Z][0-9a-zA-Z]*\\)\\>")
+                '(1 font-lock-keyword-face))
+          '("-?\\<\\([0-9]+\\|0x[0-9a-fA-F]+\\)\\>" (0 mdw-number-face))
+          '("^\\([ \t]+[a-z0-9.]+\\)" (0 font-lock-variable-name-face))
+          '("\\<\\([a-z][a-z0-9.]+\\)\\>=" (1 font-lock-variable-name-face))
+          '("\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" (0 mdw-punct-face))))
   (setq font-lock-defaults
   (setq font-lock-defaults
-       '(nfast-debug-mode-keywords nil nil nil nil))
+         '(nfast-debug-mode-keywords nil nil nil nil))
   (run-hooks 'nfast-debug-mode-hook))
 
 ;;;--------------------------------------------------------------------------
   (run-hooks 'nfast-debug-mode-hook))
 
 ;;;--------------------------------------------------------------------------
-;;; Other languages.
-
-;; Smalltalk.
-
-(defun mdw-setup-smalltalk ()
-  (and mdw-auto-indent
-       (local-set-key "\C-m" 'smalltalk-newline-and-indent))
-  (make-local-variable 'mdw-auto-indent)
-  (setq mdw-auto-indent nil)
-  (local-set-key "\C-i" 'smalltalk-reindent))
-
-(defun mdw-fontify-smalltalk ()
-  (make-local-variable 'font-lock-keywords)
-  (setq font-lock-keywords
-       (list
-        (list "\\<[A-Z][a-zA-Z0-9]*\\>"
-              '(0 font-lock-keyword-face))
-        (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
-                      "[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
-                      "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
-              '(0 mdw-number-face))
-        (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-              '(0 mdw-punct-face)))))
-
-;; Lispy languages.
+;;; Lispy languages.
 
 ;; Unpleasant bodge.
 (unless (boundp 'slime-repl-mode-map)
 
 ;; Unpleasant bodge.
 (unless (boundp 'slime-repl-mode-map)
@@ -3358,9 +4606,15 @@ that character only to be normal punctuation.")
   (make-local-variable 'lisp-indent-function)
   (setq lisp-indent-function 'common-lisp-indent-function))
 
   (make-local-variable 'lisp-indent-function)
   (setq lisp-indent-function 'common-lisp-indent-function))
 
-(setq lisp-simple-loop-indentation 2
-      lisp-loop-keyword-indentation 6
-      lisp-loop-forms-indentation 6)
+(defmacro mdw-advise-hyperspec-lookup (func args)
+  `(defadvice ,func (around mdw-browse-w3m ,args activate compile)
+     (if (fboundp 'w3m)
+        (let ((browse-url-browser-function #'mdw-w3m-browse-url))
+          ad-do-it)
+       ad-do-it)))
+(mdw-advise-hyperspec-lookup common-lisp-hyperspec (symbol))
+(mdw-advise-hyperspec-lookup common-lisp-hyperspec-format (char))
+(mdw-advise-hyperspec-lookup common-lisp-hyperspec-lookup-reader-macro (char))
 
 (defun mdw-fontify-lispy ()
 
 
 (defun mdw-fontify-lispy ()
 
@@ -3369,33 +4623,243 @@ that character only to be normal punctuation.")
 
   ;; Not much fontification needed.
   (make-local-variable 'font-lock-keywords)
 
   ;; Not much fontification needed.
   (make-local-variable 'font-lock-keywords)
-  (setq font-lock-keywords
-       (list (list (concat "\\("
-                           "\\_<[-+]?"
-                           "\\(" "[0-9]+/[0-9]+"
-                           "\\|" "\\(" "[0-9]+" "\\(\\.[0-9]*\\)?" "\\|"
-                                       "\\.[0-9]+" "\\)"
-                                 "\\([dDeEfFlLsS][-+]?[0-9]+\\)?"
-                           "\\)"
-                           "\\|"
-                           "#"
-                           "\\(" "x" "[-+]?"
-                                 "[0-9A-Fa-f]+" "\\(/[0-9A-Fa-f]+\\)?"
-                           "\\|" "o" "[-+]?" "[0-7]+" "\\(/[0-7]+\\)?"
-                           "\\|" "b" "[-+]?" "[01]+" "\\(/[01]+\\)?"
-                           "\\|" "[0-9]+" "r" "[-+]?"
-                                 "[0-9a-zA-Z]+" "\\(/[0-9a-zA-Z]+\\)?"
-                           "\\)"
-                           "\\)\\_>")
-                   '(0 mdw-number-face))
-             (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                   '(0 mdw-punct-face)))))
+    (setq font-lock-keywords
+         (list (list (concat "\\("
+                             "\\_<[-+]?"
+                             "\\(" "[0-9]+/[0-9]+"
+                             "\\|" "\\(" "[0-9]+" "\\(\\.[0-9]*\\)?" "\\|"
+                                         "\\.[0-9]+" "\\)"
+                                   "\\([dDeEfFlLsS][-+]?[0-9]+\\)?"
+                             "\\)"
+                             "\\|"
+                             "#"
+                             "\\(" "x" "[-+]?"
+                                   "[0-9A-Fa-f]+" "\\(/[0-9A-Fa-f]+\\)?"
+                             "\\|" "o" "[-+]?" "[0-7]+" "\\(/[0-7]+\\)?"
+                             "\\|" "b" "[-+]?" "[01]+" "\\(/[01]+\\)?"
+                             "\\|" "[0-9]+" "r" "[-+]?"
+                                   "[0-9a-zA-Z]+" "\\(/[0-9a-zA-Z]+\\)?"
+                             "\\)"
+                             "\\)\\_>")
+                     '(0 mdw-number-face))
+               (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+                     '(0 mdw-punct-face)))))
+
+;; Special indentation.
+
+(defcustom mdw-lisp-loop-default-indent 2
+  "Default indent for simple `loop' body."
+  :type 'integer
+  :safe 'integerp)
+(defcustom mdw-lisp-setf-value-indent 2
+  "Default extra indent for `setf' values."
+  :type 'integer :safe 'integerp)
+
+(setq lisp-simple-loop-indentation 0
+      lisp-loop-keyword-indentation 0
+      lisp-loop-forms-indentation 2
+      lisp-lambda-list-keyword-parameter-alignment t)
+
+(defun mdw-indent-funcall
+    (path state &optional indent-point sexp-column normal-indent)
+  "Indent `funcall' more usefully.
+Essentially, treat `funcall foo' as a function name, and align the arguments
+to `foo'."
+  (and (or (not (consp path)) (null (cadr path)))
+       (save-excursion
+        (goto-char (cadr state))
+        (forward-char 1)
+        (let ((start-line (line-number-at-pos)))
+          (and (condition-case nil (progn (forward-sexp 3) t)
+                 (scan-error nil))
+               (progn
+                 (forward-sexp -1)
+                 (and (= start-line (line-number-at-pos))
+                      (current-column))))))))
+(progn
+  (put 'funcall 'common-lisp-indent-function 'mdw-indent-funcall)
+  (put 'funcall 'lisp-indent-function 'mdw-indent-funcall))
+
+(defun mdw-indent-setf
+    (path state &optional indent-point sexp-column normal-indent)
+  "Indent `setf' more usefully.
+If the values aren't on the same lines as their variables then indent them
+by `mdw-lisp-setf-value-indent' spaces."
+  (and (or (not (consp path)) (null (cadr path)))
+       (let ((basic-indent (save-excursion
+                            (goto-char (cadr state))
+                            (forward-char 1)
+                            (and (condition-case nil
+                                     (progn (forward-sexp 2) t)
+                                   (scan-error nil))
+                                 (progn
+                                   (forward-sexp -1)
+                                   (current-column)))))
+            (offset (if (consp path) (car path)
+                      (catch 'done
+                        (save-excursion
+                          (let ((start path)
+                                (count 0))
+                            (goto-char (cadr state))
+                            (forward-char 1)
+                            (while (< (point) start)
+                              (condition-case nil (forward-sexp 1)
+                                (scan-error (throw 'done nil)))
+                              (incf count))
+                            (1- count)))))))
+        (and basic-indent offset
+             (list (+ basic-indent
+                      (if (oddp offset) 0
+                        mdw-lisp-setf-value-indent))
+                   basic-indent)))))
+(progn
+  (put 'setf 'common-lisp-indent-functopion 'mdw-indent-setf)
+  (put 'psetf 'common-lisp-indent-function 'mdw-indent-setf)
+  (put 'setq 'common-lisp-indent-function 'mdw-indent-setf)
+  (put 'setf 'lisp-indent-function 'mdw-indent-setf)
+  (put 'setq 'lisp-indent-function 'mdw-indent-setf)
+  (put 'setq-local 'lisp-indent-function 'mdw-indent-setf)
+  (put 'setq-default 'lisp-indent-function 'mdw-indent-setf))
+
+(defadvice common-lisp-loop-part-indentation
+    (around mdw-fix-loop-indentation (indent-point state) activate compile)
+  "Improve `loop' indentation.
+If the first subform is on the same line as the `loop' keyword, then
+align the other subforms beneath it.  Otherwise, indent them
+`mdw-lisp-loop-default-indent' columns in from the opening parenthesis."
+
+  (let* ((loop-indentation (save-excursion
+                            (goto-char (elt state 1))
+                            (current-column))))
+
+    ;; Don't really care about this.
+    (when (and (boundp 'lisp-indent-backquote-substitution-mode)
+              (eq lisp-indent-backquote-substitution-mode 'corrected))
+      (save-excursion
+       (goto-char (elt state 1))
+       (cl-incf loop-indentation
+                (cond ((eq (char-before) ?,) -1)
+                      ((and (eq (char-before) ?@)
+                            (progn (backward-char)
+                                   (eq (char-before) ?,)))
+                       -2)
+                      (t 0)))))
+
+    ;; If the first loop item is on the same line as the `loop' itself then
+    ;; use that as the baseline.  Otherwise advance by the default indent.
+    (goto-char (cadr state))
+    (forward-char 1)
+    (let ((baseline-indent
+          (if (= (line-number-at-pos)
+                 (if (condition-case nil (progn (forward-sexp 2) t)
+                       (scan-error nil))
+                     (progn (forward-sexp -1) (line-number-at-pos))
+                   -1))
+              (current-column)
+            (+ loop-indentation mdw-lisp-loop-default-indent))))
+
+      (goto-char indent-point)
+      (beginning-of-line)
+
+      (setq ad-return-value
+             (list
+              (cond ((condition-case ()
+                         (save-excursion
+                           (goto-char (elt state 1))
+                           (forward-char 1)
+                           (forward-sexp 2)
+                           (backward-sexp 1)
+                           (not (looking-at "\\(:\\|\\sw\\)")))
+                       (error nil))
+                     (+ baseline-indent lisp-simple-loop-indentation))
+                    ((looking-at "^\\s-*\\(:?\\sw+\\|;\\)")
+                     (+ baseline-indent lisp-loop-keyword-indentation))
+                    (t
+                     (+ baseline-indent lisp-loop-forms-indentation)))
+
+              ;; Tell the caller that the next line needs recomputation,
+              ;; even though it doesn't start a sexp.
+              loop-indentation)))))
+
+;; SLIME setup.
+
+(defcustom mdw-friendly-name "[mdw]"
+  "How I want to be addressed."
+  :type 'string
+  :safe 'stringp)
+(defadvice slime-user-first-name
+    (around mdw-use-friendly-name compile activate)
+  (if mdw-friendly-name (setq ad-return-value mdw-friendly-name)
+    ad-do-it))
 
 
-(defun comint-send-and-indent ()
-  (interactive)
-  (comint-send-input)
+(eval-and-compile
+  (trap
+    (if (not mdw-fast-startup)
+       (progn
+         (require 'slime-autoloads)
+         (slime-setup '(slime-autodoc slime-c-p-c))))))
+
+(let ((stuff '((cmucl ("cmucl"))
+              (sbcl ("sbcl") :coding-system utf-8-unix)
+              (clisp ("clisp") :coding-system utf-8-unix))))
+  (or (boundp 'slime-lisp-implementations)
+      (setq slime-lisp-implementations nil))
+  (while stuff
+    (let* ((head (car stuff))
+          (found (assq (car head) slime-lisp-implementations)))
+      (setq stuff (cdr stuff))
+      (if found
+         (rplacd found (cdr head))
+       (setq slime-lisp-implementations
+               (cons head slime-lisp-implementations))))))
+(setq slime-default-lisp 'sbcl)
+
+;; Hooks.
+
+(progn
+  (dolist (hook '(emacs-lisp-mode-hook
+                 scheme-mode-hook
+                 lisp-mode-hook
+                 inferior-lisp-mode-hook
+                 lisp-interaction-mode-hook
+                 ielm-mode-hook
+                 slime-repl-mode-hook))
+    (add-hook hook 'mdw-misc-mode-config t)
+    (add-hook hook 'mdw-fontify-lispy t))
+  (add-hook 'lisp-mode-hook 'mdw-common-lisp-indent t)
+  (add-hook 'inferior-lisp-mode-hook
+           #'(lambda () (local-set-key "\C-m" 'comint-send-and-indent)) t))
+
+;;;--------------------------------------------------------------------------
+;;; Other languages.
+
+;; Smalltalk.
+
+(defun mdw-setup-smalltalk ()
   (and mdw-auto-indent
   (and mdw-auto-indent
-       (indent-for-tab-command)))
+       (local-set-key "\C-m" 'smalltalk-newline-and-indent))
+  (make-local-variable 'mdw-auto-indent)
+  (setq mdw-auto-indent nil)
+  (local-set-key "\C-i" 'smalltalk-reindent))
+
+(defun mdw-fontify-smalltalk ()
+  (make-local-variable 'font-lock-keywords)
+  (setq font-lock-keywords
+         (list
+          (list "\\<[A-Z][a-zA-Z0-9]*\\>"
+                '(0 font-lock-keyword-face))
+          (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
+                        "[0-9][0-9_]*\\(\\.[0-9_]*\\)?"
+                        "\\([eE][-+]?[0-9_]+\\)?")
+                '(0 mdw-number-face))
+          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+                '(0 mdw-punct-face)))))
+
+(progn
+  (add-hook 'smalltalk-mode 'mdw-misc-mode-config t)
+  (add-hook 'smalltalk-mode 'mdw-fontify-smalltalk t))
+
+;; m4.
 
 (defun mdw-setup-m4 ()
 
 
 (defun mdw-setup-m4 ()
 
@@ -3407,6 +4871,15 @@ that character only to be normal punctuation.")
   ;; Fill prefix.
   (mdw-standard-fill-prefix "\\([ \t]*\\(?:#+\\|\\<dnl\\>\\)[ \t]*\\)"))
 
   ;; Fill prefix.
   (mdw-standard-fill-prefix "\\([ \t]*\\(?:#+\\|\\<dnl\\>\\)[ \t]*\\)"))
 
+(dolist (hook '(m4-mode-hook autoconf-mode-hook autotest-mode-hook))
+  (add-hook hook #'mdw-misc-mode-config t)
+  (add-hook hook #'mdw-setup-m4 t))
+
+;; Make.
+
+(progn
+  (add-hook 'makefile-mode-hook 'mdw-misc-mode-config t))
+
 ;;;--------------------------------------------------------------------------
 ;;; Text mode.
 
 ;;;--------------------------------------------------------------------------
 ;;; Text mode.
 
@@ -3417,6 +4890,12 @@ that character only to be normal punctuation.")
    "\\([ \t]*\\([>#|:] ?\\)*[ \t]*\\)" 3)
   (auto-fill-mode 1))
 
    "\\([ \t]*\\([>#|:] ?\\)*[ \t]*\\)" 3)
   (auto-fill-mode 1))
 
+(eval-after-load "flyspell"
+  '(define-key flyspell-mode-map "\C-\M-i" nil))
+
+(progn
+  (add-hook 'text-mode-hook 'mdw-text-mode t))
+
 ;;;--------------------------------------------------------------------------
 ;;; Outline and hide/show modes.
 
 ;;;--------------------------------------------------------------------------
 ;;; Outline and hide/show modes.
 
@@ -3450,6 +4929,21 @@ that character only to be normal punctuation.")
   (auto-fill-mode -1)
   (setq tab-width 8))
 
   (auto-fill-mode -1)
   (setq tab-width 8))
 
+(defun comint-send-and-indent ()
+  (interactive)
+  (comint-send-input)
+  (and mdw-auto-indent
+       (indent-for-tab-command)))
+
+(defadvice comint-line-beginning-position
+    (around mdw-calculate-it-properly () activate compile)
+  "Calculate the actual line start for multi-line input."
+  (if (or comint-use-prompt-regexp
+         (eq (field-at-pos (point)) 'output))
+      ad-do-it
+    (setq ad-return-value
+           (constrain-to-field (line-beginning-position) (point)))))
+
 (defun term-send-meta-right () (interactive) (term-send-raw-string "\e\e[C"))
 (defun term-send-meta-left  () (interactive) (term-send-raw-string "\e\e[D"))
 (defun term-send-ctrl-uscore () (interactive) (term-send-raw-string "\C-_"))
 (defun term-send-meta-right () (interactive) (term-send-raw-string "\e\e[C"))
 (defun term-send-meta-left  () (interactive) (term-send-raw-string "\e\e[D"))
 (defun term-send-ctrl-uscore () (interactive) (term-send-raw-string "\C-_"))
@@ -3476,14 +4970,27 @@ This allows you to pass a list of arguments through `ansi-term'."
          (ad-set-arg 2 (car program))
          (ad-set-arg 4 (cdr program))))))
 
          (ad-set-arg 2 (car program))
          (ad-set-arg 4 (cdr program))))))
 
+(defadvice term-exec-1 (around hack-environment compile activate)
+  "Hack the environment inherited by inferiors in the terminal."
+  (let ((process-environment (copy-tree process-environment)))
+    (setenv "LD_PRELOAD" nil)
+    ad-do-it))
+
+(defadvice shell (around hack-environment compile activate)
+  "Hack the environment inherited by inferiors in the shell."
+  (let ((process-environment (copy-tree process-environment)))
+    (setenv "LD_PRELOAD" nil)
+    ad-do-it))
+
 (defun ssh (host)
   "Open a terminal containing an ssh session to the HOST."
   (interactive "sHost: ")
   (ansi-term (list "ssh" host) (format "ssh@%s" host)))
 
 (defun ssh (host)
   "Open a terminal containing an ssh session to the HOST."
   (interactive "sHost: ")
   (ansi-term (list "ssh" host) (format "ssh@%s" host)))
 
-(defvar git-grep-command
-  "env PAGER=cat git grep --no-color -nH -e "
-  "*The default command for \\[git-grep].")
+(defcustom git-grep-command
+  "env GIT_PAGER=cat git grep --no-color -nH -e "
+  "The default command for \\[git-grep]."
+  :type 'string)
 
 (defvar git-grep-history nil)
 
 
 (defvar git-grep-history nil)
 
@@ -3492,7 +4999,348 @@ This allows you to pass a list of arguments through `ansi-term'."
   (interactive
    (list (read-shell-command "Run git grep (like this): "
                             git-grep-command 'git-grep-history)))
   (interactive
    (list (read-shell-command "Run git grep (like this): "
                             git-grep-command 'git-grep-history)))
-  (grep command-args))
+  (let ((grep-use-null-device nil))
+    (grep command-args)))
+
+;;;--------------------------------------------------------------------------
+;;; Magit configuration.
+
+(setq magit-diff-refine-hunk 't
+      magit-view-git-manual-method 'man
+      magit-log-margin '(nil age magit-log-margin-width t 18)
+      magit-wip-after-save-local-mode-lighter ""
+      magit-wip-after-apply-mode-lighter ""
+      magit-wip-before-change-mode-lighter "")
+(eval-after-load "magit"
+  '(progn (global-magit-file-mode 1)
+         (magit-wip-after-save-mode 1)
+         (magit-wip-after-apply-mode 1)
+         (magit-wip-before-change-mode 1)
+         (add-to-list 'magit-no-confirm 'safe-with-wip)
+         (add-to-list 'magit-no-confirm 'trash)
+         (push '(:eval (if (or magit-wip-after-save-local-mode
+                               magit-wip-after-apply-mode
+                               magit-wip-before-change-mode)
+                           (format " wip:%s%s%s"
+                                   (if magit-wip-after-apply-mode "A" "")
+                                   (if magit-wip-before-change-mode "C" "")
+                                   (if magit-wip-after-save-local-mode "S" ""))))
+               minor-mode-alist)
+         (dolist (popup '(magit-diff-popup
+                          magit-diff-refresh-popup
+                          magit-diff-mode-refresh-popup
+                          magit-revision-mode-refresh-popup))
+           (magit-define-popup-switch popup ?R "Reverse diff" "-R"))
+         (magit-define-popup-switch 'magit-rebase-popup ?r
+                                    "Rebase merges" "--rebase-merges")))
+
+(defadvice magit-wip-commit-buffer-file
+    (around mdw-just-this-buffer activate compile)
+  (let ((magit-save-repository-buffers nil)) ad-do-it))
+
+(defadvice magit-discard
+    (around mdw-delete-if-prefix-argument activate compile)
+  (let ((magit-delete-by-moving-to-trash
+        (and (null current-prefix-arg)
+             magit-delete-by-moving-to-trash)))
+    ad-do-it))
+
+(setq magit-repolist-columns
+       '(("Name" 16 magit-repolist-column-ident nil)
+         ("Version" 18 magit-repolist-column-version nil)
+         ("St" 2 magit-repolist-column-dirty nil)
+         ("L<U" 3 mdw-repolist-column-unpulled-from-upstream nil)
+         ("L>U" 3 mdw-repolist-column-unpushed-to-upstream nil)
+         ("Path" 32 magit-repolist-column-path nil)))
+
+(setq magit-repository-directories '(("~/etc/profile" . 0)
+                                    ("~/src/" . 1)))
+
+(defadvice magit-list-repos (around mdw-dirname () activate compile)
+  "Make sure the returned names are directory names.
+Otherwise child processes get started in the wrong directory and
+there is sadness."
+  (setq ad-return-value (mapcar #'file-name-as-directory ad-do-it)))
+
+(defun mdw-repolist-column-unpulled-from-upstream (_id)
+  "Insert number of upstream commits not in the current branch."
+  (let ((upstream (magit-get-upstream-branch (magit-get-current-branch) t)))
+    (and upstream
+        (let ((n (cadr (magit-rev-diff-count "HEAD" upstream))))
+          (propertize (number-to-string n) 'face
+                      (if (> n 0) 'bold 'shadow))))))
+
+(defun mdw-repolist-column-unpushed-to-upstream (_id)
+  "Insert number of commits in the current branch but not its upstream."
+  (let ((upstream (magit-get-upstream-branch (magit-get-current-branch) t)))
+    (and upstream
+        (let ((n (car (magit-rev-diff-count "HEAD" upstream))))
+          (propertize (number-to-string n) 'face
+                      (if (> n 0) 'bold 'shadow))))))
+
+(defun mdw-try-smerge ()
+  (save-excursion
+    (goto-char (point-min))
+    (when (re-search-forward "^<<<<<<< " nil t)
+      (smerge-mode 1))))
+(add-hook 'find-file-hook 'mdw-try-smerge t)
+
+;;;--------------------------------------------------------------------------
+;;; GUD, and especially GDB.
+
+;; Inhibit window dedication.  I mean, seriously, wtf?
+(defadvice gdb-display-buffer (after mdw-undedicated (buf) compile activate)
+  "Don't make windows dedicated.  Seriously."
+  (set-window-dedicated-p ad-return-value nil))
+(defadvice gdb-set-window-buffer
+    (after mdw-undedicated (name &optional ignore-dedicated window)
+     compile activate)
+  "Don't make windows dedicated.  Seriously."
+  (set-window-dedicated-p (or window (selected-window)) nil))
+
+;;;--------------------------------------------------------------------------
+;;; SQL stuff.
+
+(setq sql-postgres-options '("-n" "-P" "pager=off")
+      sql-postgres-login-params
+       '((user :default "mdw")
+         (database :default "mdw")
+         (server :default "db.distorted.org.uk")))
+
+;;;--------------------------------------------------------------------------
+;;; Man pages.
+
+;; Turn off `noip' when running `man': it interferes with `man-db''s own
+;; seccomp(2)-based sandboxing, which is (in this case, at least) strictly
+;; better.
+(defadvice Man-getpage-in-background
+    (around mdw-inhibit-noip (topic) compile activate)
+  "Inhibit the `noip' preload hack when invoking `man'."
+  (let* ((old-preload (getenv "LD_PRELOAD"))
+        (preloads (and old-preload
+                       (save-match-data (split-string old-preload ":"))))
+        (any nil)
+        (filtered nil))
+    (save-match-data
+      (while preloads
+       (let ((item (pop preloads)))
+         (if (string-match  "\\(/\\|^\\)noip\.so\\(:\\|$\\)" item)
+             (setq any t)
+           (push item filtered)))))
+    (if any
+       (unwind-protect
+           (progn
+             (setenv "LD_PRELOAD"
+                     (and filtered
+                          (with-output-to-string
+                            (setq filtered (nreverse filtered))
+                            (let ((first t))
+                              (while filtered
+                                (if first (setq first nil)
+                                  (write-char ?:))
+                                (write-string (pop filtered)))))))
+             ad-do-it)
+         (setenv "LD_PRELOAD" old-preload))
+      ad-do-it)))
+
+;;;--------------------------------------------------------------------------
+;;; MPC configuration.
+
+(eval-when-compile (trap (require 'mpc)))
+
+(setq mpc-browser-tags '(Artist|Composer|Performer Album|Playlist))
+
+(defun mdw-mpc-now-playing ()
+  (interactive)
+  (require 'mpc)
+  (save-excursion
+    (set-buffer (mpc-proc-cmd (mpc-proc-cmd-list '("status" "currentsong"))))
+    (mpc--status-callback))
+  (let ((state (cdr (assq 'state mpc-status))))
+    (cond ((member state '("stop"))
+          (message "mpd stopped."))
+         ((member state '("play" "pause"))
+          (let* ((artist (cdr (assq 'Artist mpc-status)))
+                 (album (cdr (assq 'Album mpc-status)))
+                 (title (cdr (assq 'Title mpc-status)))
+                 (file (cdr (assq 'file mpc-status)))
+                 (duration-string (cdr (assq 'Time mpc-status)))
+                 (time-string (cdr (assq 'time mpc-status)))
+                 (time (and time-string
+                            (string-to-number
+                             (if (string-match ":" time-string)
+                                 (substring time-string
+                                            0 (match-beginning 0))
+                               (time-string)))))
+                 (duration (and duration-string
+                                (string-to-number duration-string)))
+                 (pos (and time duration
+                           (format " [%d:%02d/%d:%02d]"
+                                   (/ time 60) (mod time 60)
+                                   (/ duration 60) (mod duration 60))))
+                 (fmt (cond ((and artist title)
+                             (format "`%s' by %s%s" title artist
+                                     (if album (format ", from `%s'" album)
+                                       "")))
+                            (file
+                             (format "`%s' (no tags)" file))
+                            (t
+                             "(no idea what's playing!)"))))
+            (if (string= state "play")
+                (message "mpd playing %s%s" fmt (or pos ""))
+              (message "mpd paused in %s%s" fmt (or pos "")))))
+         (t
+          (message "mpd in unknown state `%s'" state)))))
+
+(defmacro mdw-define-mpc-wrapper (func bvl interactive &rest body)
+  `(defun ,func ,bvl
+     (interactive ,@interactive)
+     (require 'mpc)
+     ,@body
+     (mdw-mpc-now-playing)))
+
+(mdw-define-mpc-wrapper mdw-mpc-play-or-pause () nil
+  (if (member (cdr (assq 'state (mpc-cmd-status))) '("play"))
+      (mpc-pause)
+    (mpc-play)))
+
+(mdw-define-mpc-wrapper mdw-mpc-next () nil (mpc-next))
+(mdw-define-mpc-wrapper mdw-mpc-prev () nil (mpc-prev))
+(mdw-define-mpc-wrapper mdw-mpc-stop () nil (mpc-stop))
+
+(defun mdw-mpc-louder (step)
+  (interactive (list (if current-prefix-arg
+                        (prefix-numeric-value current-prefix-arg)
+                      +10)))
+  (mpc-proc-cmd (format "volume %+d" step)))
+
+(defun mdw-mpc-quieter (step)
+  (interactive (list (if current-prefix-arg
+                        (prefix-numeric-value current-prefix-arg)
+                      +10)))
+  (mpc-proc-cmd (format "volume %+d" (- step))))
+
+(defun mdw-mpc-hack-lines (arg interactivep func)
+  (if (and interactivep (use-region-p))
+      (let ((from (region-beginning)) (to (region-end)))
+       (goto-char from)
+       (beginning-of-line)
+       (funcall func)
+       (forward-line)
+       (while (< (point) to)
+         (funcall func)
+         (forward-line)))
+    (let ((n (prefix-numeric-value arg)))
+      (cond ((minusp n)
+            (unless (bolp)
+              (beginning-of-line)
+              (funcall func)
+              (incf n))
+            (while (minusp n)
+              (forward-line -1)
+              (funcall func)
+              (incf n)))
+           (t
+            (beginning-of-line)
+            (while (plusp n)
+              (funcall func)
+              (forward-line)
+              (decf n)))))))
+
+(defun mdw-mpc-select-one ()
+  (when (and (get-char-property (point) 'mpc-file)
+            (not (get-char-property (point) 'mpc-select)))
+    (mpc-select-toggle)))
+
+(defun mdw-mpc-unselect-one ()
+  (when (get-char-property (point) 'mpc-select)
+    (mpc-select-toggle)))
+
+(defun mdw-mpc-select (&optional arg interactivep)
+  (interactive (list current-prefix-arg t))
+  (mdw-mpc-hack-lines arg interactivep 'mdw-mpc-select-one))
+
+(defun mdw-mpc-unselect (&optional arg interactivep)
+  (interactive (list current-prefix-arg t))
+  (mdw-mpc-hack-lines arg interactivep 'mdw-mpc-unselect-one))
+
+(defun mdw-mpc-unselect-backwards (arg)
+  (interactive "p")
+  (mdw-mpc-hack-lines (- arg) t 'mdw-mpc-unselect-one))
+
+(defun mdw-mpc-unselect-all ()
+  (interactive)
+  (setq mpc-select nil)
+  (mpc-selection-refresh))
+
+(defun mdw-mpc-next-line (arg)
+  (interactive "p")
+  (beginning-of-line)
+  (forward-line arg))
+
+(defun mdw-mpc-previous-line (arg)
+  (interactive "p")
+  (beginning-of-line)
+  (forward-line (- arg)))
+
+(defun mdw-mpc-playlist-add (&optional arg interactivep)
+  (interactive (list current-prefix-arg t))
+  (let ((mpc-select mpc-select))
+    (when (or arg (and interactivep (use-region-p)))
+      (setq mpc-select nil)
+      (mdw-mpc-hack-lines arg interactivep 'mdw-mpc-select-one))
+    (setq mpc-select (reverse mpc-select))
+    (mpc-playlist-add)))
+
+(defun mdw-mpc-playlist-delete (&optional arg interactivep)
+  (interactive (list current-prefix-arg t))
+  (setq mpc-select (nreverse mpc-select))
+  (mpc-select-save
+    (when (or arg (and interactivep (use-region-p)))
+      (setq mpc-select nil)
+      (mpc-selection-refresh)
+      (mdw-mpc-hack-lines arg interactivep 'mdw-mpc-select-one))
+      (mpc-playlist-delete)))
+
+(defun mdw-mpc-hack-tagbrowsers ()
+  (setq-local mode-line-format
+               '("%e"
+                 mode-line-frame-identification
+                 mode-line-buffer-identification)))
+(add-hook 'mpc-tagbrowser-mode-hook 'mdw-mpc-hack-tagbrowsers)
+
+(defun mdw-mpc-hack-songs ()
+  (setq-local header-line-format
+             ;; '("MPC " mpc-volume " " mpc-current-song)
+             (list (propertize " " 'display '(space :align-to 0))
+                   ;; 'mpc-songs-format-description
+                   '(:eval
+                     (let ((deactivate-mark) (hscroll (window-hscroll)))
+                       (with-temp-buffer
+                         (mpc-format mpc-songs-format 'self hscroll)
+                         ;; That would be simpler than the hscroll handling in
+                         ;; mpc-format, but currently move-to-column does not
+                         ;; recognize :space display properties.
+                         ;; (move-to-column hscroll)
+                         ;; (delete-region (point-min) (point))
+                         (buffer-string)))))))
+(add-hook 'mpc-songs-mode-hook 'mdw-mpc-hack-songs)
+
+(eval-after-load "mpc"
+  '(progn
+     (define-key mpc-mode-map "m" 'mdw-mpc-select)
+     (define-key mpc-mode-map "u" 'mdw-mpc-unselect)
+     (define-key mpc-mode-map "\177" 'mdw-mpc-unselect-backwards)
+     (define-key mpc-mode-map "\e\177" 'mdw-mpc-unselect-all)
+     (define-key mpc-mode-map "n" 'mdw-mpc-next-line)
+     (define-key mpc-mode-map "p" 'mdw-mpc-previous-line)
+     (define-key mpc-mode-map "/" 'mpc-songs-search)
+     (setq mpc-songs-mode-map (make-sparse-keymap))
+     (set-keymap-parent mpc-songs-mode-map mpc-mode-map)
+     (define-key mpc-songs-mode-map "l" 'mpc-playlist)
+     (define-key mpc-songs-mode-map "+" 'mdw-mpc-playlist-add)
+     (define-key mpc-songs-mode-map "-" 'mdw-mpc-playlist-delete)
+     (define-key mpc-songs-mode-map "\r" 'mpc-songs-jump-to)))
 
 ;;;--------------------------------------------------------------------------
 ;;; Inferior Emacs Lisp.
 
 ;;;--------------------------------------------------------------------------
 ;;; Inferior Emacs Lisp.