el/dot-emacs.el (mdw-examine-fill-prefixes): Rewrite to be iterative.
[profile] / el / dot-emacs.el
index 6930bda..5bde809 100644 (file)
 ;;;--------------------------------------------------------------------------
 ;;; Check command-line.
 
+(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.")
-(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.
@@ -91,11 +100,11 @@ This may be at the expense of cool features.")
                     (replace-match with t))))
            (with-temp-buffer
              (insert-file-contents "~/.mdw.conf")
-             (replace  "^[ \t]*\\(#.*\\|\\)\n" "")
+             (replace  "^[ \t]*\\(#.*\\)?\n" "")
              (replace (concat "^[ \t]*"
                               "\\([-a-zA-Z0-9_.]*\\)"
                               "[ \t]*=[ \t]*"
-                              "\\(.*[^ \t\n]\\|\\)"
+                              "\\(.*[^ \t\n]\\)?"
                               "[ \t]**\\(\n\\|$\\)")
                       "(\\1 . \"\\2\")\n")
              (car (read-from-string
@@ -160,6 +169,17 @@ library."
     (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)
@@ -200,13 +220,16 @@ fringes is not taken out of the allowance for WIDTH, unlike
         ((>= 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")
-  (setq width (cond (width (prefix-numeric-value width))
-                   ((and window-system (mdw-emacs-version-p 22))
-                    mdw-column-width)
-                   (t (1+ mdw-column-width))))
+  (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)
@@ -220,16 +243,22 @@ fringes is not taken out of the allowance for WIDTH, unlike
 (defun mdw-set-frame-width (columns &optional width)
   (interactive "nColumns: 
 P")
-  (setq width (cond (width (prefix-numeric-value width))
-                   ((and window-system (mdw-emacs-version-p 22))
-                    mdw-column-width)
-                   (t (1+ mdw-column-width))))
+  (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)))
 
+(defvar 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.")
+
 ;; Don't raise windows unless I say so.
 
 (defvar mdw-inhibit-raise-frame nil
@@ -253,6 +282,7 @@ frame is actually mapped on the screen."
 
 (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'.
@@ -336,9 +366,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])
-        (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))
@@ -393,6 +423,8 @@ as output rather than a string."
   (let ((mdw-diary-for-org-mode-p t))
     ad-do-it))
 
+(defvar diary-time-regexp nil)
+
 (defadvice diary-add-to-list (before mdw-trim-leading-space compile activate)
   "Trim leading space from the diary entry string."
   (save-match-data
@@ -470,25 +502,52 @@ Evil key bindings are defined in `mdw-evil-keymap-keys'."
        (dolist (key replacements)
          (define-key keymap key binding))))))
 
-(eval-after-load "org-latex"
-  '(progn
-     (push '("strayman"
-            "\\documentclass{strayman}
+(defvar mdw-org-latex-defs
+  '(("strayman"
+     "\\documentclass{strayman}
 \\usepackage[utf8]{inputenc}
 \\usepackage[palatino, helvetica, courier, maths=cmr]{mdwfonts}
 \\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}"))))
+
+(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-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
       "/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.
 
 (defun mdw-clobber-other-windows-showing-buffer (buffer-or-name)
@@ -497,19 +556,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*")))
-    (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.")
 
+(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)
@@ -526,6 +588,37 @@ 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))
 
+(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
+       (with-current-buffer buffer
+         (set-visited-file-name to nil t))))))
+
 ;;;--------------------------------------------------------------------------
 ;;; Improved compilation machinery.
 
@@ -549,7 +642,7 @@ Pretend they don't exist.  They might be on other display devices."
 
 (defadvice compile (around hack-environment compile activate)
   "Hack the environment inherited by inferiors in the compilation."
-  (let ((process-environment process-environment))
+  (let ((process-environment (copy-tree process-environment)))
     (setenv "LD_PRELOAD" nil)
     ad-do-it))
 
@@ -731,6 +824,90 @@ Use this to arrange for per-server settings.")
 (eval-after-load "erc"
   '(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.
 
@@ -798,7 +975,7 @@ in REST."
                                     (erase-buffer)
                                     (shell-command "date +%Y-%m-%d" t)
                                     (goto-char (mark))
-                                    (delete-backward-char 1)
+                                    (delete-char -1)
                                     (buffer-string))
                (kill-buffer buffer))))))
 
@@ -863,6 +1040,27 @@ tramp, which seems to get itself into a twist."
 (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)))
+
+(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)))))
+
 ;;;--------------------------------------------------------------------------
 ;;; Dired hacking.
 
@@ -896,6 +1094,12 @@ options."
           (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))
 
@@ -918,9 +1122,11 @@ If NEW-SESSION-P, start a new session."
            (w3m-browse-url url new-session-p))
        (select-window window)))))
 
+(eval-after-load 'w3m
+  '(define-key w3m-mode-map [?\e ?\r] 'w3m-view-this-url-new-session))
+
 (defvar mdw-good-url-browsers
-  '(browse-url-chromium
-    browse-url-mozilla
+  '(browse-url-mozilla
     browse-url-generic
     (w3m . mdw-w3m-browse-url)
     browse-url-w3)
@@ -1021,17 +1227,6 @@ This is mainly useful in `auto-fill-mode'.")
          (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-maybe-car (p)
   "If P is a pair, return (car P), otherwise just return P."
   (if (consp p) (car p) p))
@@ -1055,6 +1250,22 @@ See `mdw-fill-prefix' for details."
        ((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)
+                ((looking-at (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)
@@ -1116,10 +1327,18 @@ case."
   (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 fill-column mdw-text-width)
+  (flyspell-prog-mode)
   (and (fboundp 'gtags-mode)
        (gtags-mode))
   (if (fboundp 'hs-minor-mode)
@@ -1256,11 +1475,12 @@ 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"))
-(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
   (((min-colors 64)) :background "grey30")
   (((class color)) :background "blue")
@@ -1310,6 +1530,10 @@ doesn't match any of the regular expressions in
 (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))
 
@@ -1446,6 +1670,10 @@ doesn't match any of the regular expressions in
 (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
@@ -1704,6 +1932,21 @@ doesn't match any of the regular expressions in
   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.
 
@@ -1744,50 +1987,47 @@ indentation anyway."
 (defvar mdw-define-c-styles-hook nil
   "Hook run when `cc-mode' starts up to define styles.")
 
-(defmacro mdw-define-c-style (name &rest assocs)
-  "Define a C style, called NAME (a symbol), setting ASSOCs.
+(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
-       (defun ,func () (c-add-style ,name-string ',assocs))
+       (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))))
+       (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-trustonic-c
-  (c-basic-offset . 4)
-  (comment-column . 0)
-  (c-indent-comment-alist (anchored-comment . (column . 0))
-                         (end-block . (space . 1))
-                         (cpp-end-block . (space . 1))
-                         (other . (space . 1)))
-  (c-class-key . "class")
-  (c-backslash-column . 0)
-  (c-auto-align-backslashes . nil)
-  (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-indent-arglist-nested)
-                  (topmost-intro . mdw-c-indent-extern-mumble)
-                  (cpp-define-intro . 0)
-                  (knr-argdecl . 0)
-                  (inextern-lang . [0])
-                  (label . 0)
-                  (case-label . +)
-                  (access-label . -2)
-                  (inclass . +)
-                  (inline-open . ++)
-                  (statement-cont . +)
-                  (statement-case-intro . +)))
-
-(mdw-define-c-style mdw-c
+(mdw-define-c-style mdw-c ()
   (c-basic-offset . 2)
   (comment-column . 40)
   (c-class-key . "class")
@@ -1808,6 +2048,18 @@ set."
                   (statement-cont . +)
                   (statement-case-intro . +)))
 
+(mdw-define-c-style mdw-trustonic-basic-c (mdw-c)
+  (c-basic-offset . 4)
+  (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 (access-label . -2)))
+
+(mdw-define-c-style mdw-trustonic-c (mdw-trustonic-basic-c)
+  (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.
 
@@ -1830,7 +2082,7 @@ name, as a symbol."
 
 (defvar mdw-c-comment-fill-prefix
   `((,(concat "\\([ \t]*/?\\)"
-             "\\(\*\\|//]\\)"
+             "\\(\\*\\|//\\)"
              "\\([ \t]*\\)"
              "\\([A-Za-z]+:[ \t]*\\)?"
              mdw-hanging-indents)
@@ -1965,7 +2217,7 @@ name, as a symbol."
                      "__typeof__"       ;GCC
                      "__volatile__"     ;GCC
                      ))
-       (c-constants
+       (c-builtins
         (mdw-regexps "false"            ;C++, C99 macro
                      "this"             ;C++
                      "true"             ;C++, C99 macro
@@ -1985,7 +2237,7 @@ name, as a symbol."
           ;; Fontify include files as strings.
           (list (concat "^[ \t]*\\#[ \t]*"
                         "\\(include\\|import\\)"
-                        "[ \t]*\\(<[^>]+\\(>\\|\\)\\)")
+                        "[ \t]*\\(<[^>]+>?\\)")
                 '(2 font-lock-string-face))
 
           ;; Preprocessor directives are `references'?.
@@ -2001,7 +2253,7 @@ name, as a symbol."
           (list (concat "\\<\\(" c-keywords "\\)\\>")
                 '(0 font-lock-keyword-face))
 
-          (list (concat "\\<\\(" c-constants "\\)\\>")
+          (list (concat "\\<\\(" c-builtins "\\)\\>")
                 '(0 font-lock-variable-name-face))
 
           ;; Handle numbers too.
@@ -2021,6 +2273,10 @@ name, as a symbol."
   "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.
 
@@ -2066,12 +2322,16 @@ name, as a symbol."
           (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.
 
-(mdw-define-c-style mdw-java
+(mdw-define-c-style mdw-java ()
   (c-basic-offset . 2)
   (c-backslash-column . 72)
   (c-offsets-alist (substatement-open . 0)
@@ -2086,22 +2346,35 @@ name, as a symbol."
 
 (defun mdw-fontify-java ()
 
+  ;; Fiddle with some syntax codes.
+  (modify-syntax-entry ?@ ".")
+  (modify-syntax-entry ?@ "." font-lock-syntax-table)
+
   ;; Other stuff.
   (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
@@ -2111,8 +2384,8 @@ name, as a symbol."
           (list (concat "\\<\\(" java-keywords "\\)\\>")
                 '(0 font-lock-keyword-face))
 
-          ;; Handle the magic constants defined above.
-          (list (concat "\\<\\(" java-constants "\\)\\>")
+          ;; Handle the magic builtins defined above.
+          (list (concat "\\<\\(" java-builtins "\\)\\>")
                 '(0 font-lock-variable-name-face))
 
           ;; Handle numbers too.
@@ -2120,8 +2393,8 @@ name, as a symbol."
           ;; 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-9]+\\(\\.[0-9]*\\)?"
+                        "\\([eE][-+]?[0-9]+\\)?\\)"
                         "[lLfFdD]?")
                 '(0 mdw-number-face))
 
@@ -2129,6 +2402,10 @@ name, as a symbol."
           (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.
 
@@ -2154,11 +2431,8 @@ name, as a symbol."
                      "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")))
 
@@ -2169,8 +2443,8 @@ name, as a symbol."
           (list (concat "\\_<\\(" javascript-keywords "\\)\\_>")
                 '(0 font-lock-keyword-face))
 
-          ;; Handle the predefined constants defined above.
-          (list (concat "\\_<\\(" javascript-constants "\\)\\_>")
+          ;; Handle the predefined builtins defined above.
+          (list (concat "\\_<\\(" javascript-builtins "\\)\\_>")
                 '(0 font-lock-variable-name-face))
 
           ;; Handle numbers too.
@@ -2178,8 +2452,8 @@ name, as a symbol."
           ;; 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-9]+\\(\\.[0-9]*\\)?"
+                        "\\([eE][-+]?[0-9]+\\)?\\)"
                         "[lLfFdD]?")
                 '(0 mdw-number-face))
 
@@ -2187,6 +2461,10 @@ name, as a symbol."
           (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.
 
@@ -2232,15 +2510,11 @@ name, as a symbol."
           ;; As usual, not quite right.
           (list (concat "\\_<\\("
                         "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
-                        "[0-9]+\\(\\.[0-9]*\\|\\)"
-                        "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
+                        "[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)))
@@ -2260,12 +2534,16 @@ name, as a symbol."
                 '(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.
 
-(mdw-define-c-style mdw-csharp
+(mdw-define-c-style mdw-csharp ()
   (c-basic-offset . 2)
   (c-backslash-column . 72)
   (c-offsets-alist (substatement-open . 0)
@@ -2300,7 +2578,7 @@ name, as a symbol."
                      "unsafe" "ushort" "using" "virtual" "void" "volatile"
                      "while" "yield"))
 
-       (csharp-constants
+       (csharp-builtins
         (mdw-regexps "base" "false" "null" "this" "true")))
 
     (setq font-lock-keywords
@@ -2310,8 +2588,8 @@ name, as a symbol."
           (list (concat "\\<\\(" csharp-keywords "\\)\\>")
                 '(0 font-lock-keyword-face))
 
-          ;; Handle the magic constants defined above.
-          (list (concat "\\<\\(" csharp-constants "\\)\\>")
+          ;; Handle the magic builtins defined above.
+          (list (concat "\\<\\(" csharp-builtins "\\)\\>")
                 '(0 font-lock-variable-name-face))
 
           ;; Handle numbers too.
@@ -2319,8 +2597,8 @@ name, as a symbol."
           ;; 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-9]+\\(\\.[0-9]*\\)?"
+                        "\\([eE][-+]?[0-9]+\\)?\\)"
                         "[lLfFdD]?")
                 '(0 mdw-number-face))
 
@@ -2331,6 +2609,8 @@ name, as a symbol."
 (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.
 
@@ -2450,6 +2730,11 @@ name, as a symbol."
                      (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.
 
@@ -2504,13 +2789,16 @@ name, as a symbol."
           ;; 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-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.
@@ -2525,26 +2813,28 @@ name, as a symbol."
 (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
-        (mdw-regexps "abstract" "alignof" "as"
+        (mdw-regexps "abstract" "alignof" "as" "async" "await"
                      "become" "box" "break"
-                     "const" "continue" "create"
-                     "do"
+                     "const" "continue" "crate"
+                     "do" "dyn"
                      "else" "enum" "extern"
-                     "false" "final" "fn" "for"
+                     "final" "fn" "for"
                      "if" "impl" "in"
                      "let" "loop"
                      "macro" "match" "mod" "move" "mut"
                      "offsetof" "override"
-                     "priv" "pub" "pure"
+                     "priv" "proc" "pub" "pure"
                      "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"))
@@ -2554,7 +2844,8 @@ name, as a symbol."
                      "f32" "f64"
                      "i8" "i16" "i32" "i64" "isize"
                      "u8" "u16" "u32" "u64" "usize"
-                     "char" "str")))
+                     "char" "str"
+                     "self" "Self")))
     (setq font-lock-keywords
          (list
 
@@ -2576,7 +2867,7 @@ name, as a symbol."
                               "\\|" "0o[0-7_]+"
                               "\\|" "0b[01_]+"
                               "\\)"
-                              "\\([ui]\\(8\\|16\\|32\\|64\\|s\\|size\\)\\)?"
+                              "\\([ui]\\(8\\|16\\|32\\|64\\|size\\)\\)?"
                         "\\)\\_>")
                 '(0 mdw-number-face))
 
@@ -2588,12 +2879,16 @@ name, as a symbol."
   (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.
 
-(mdw-define-c-style mdw-awk
+(mdw-define-c-style mdw-awk ()
   (c-basic-offset . 2)
   (c-offsets-alist (substatement-open . 0)
                   (c-backslash-column . 72)
@@ -2635,8 +2930,8 @@ name, as a symbol."
           ;; 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-9]+\\(\\.[0-9]*\\)?"
+                        "\\([eE][-+]?[0-9]+\\)?\\)"
                         "[uUlL]*")
                 '(0 mdw-number-face))
 
@@ -2644,19 +2939,23 @@ name, as a symbol."
           (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.
 
-(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-continued-brace-offset 0
+             cperl-brace-offset -2
+             cperl-brace-imaginary-offset 0
+             cperl-label-offset 0)
 
 ;; Define perl fontification style.
 
@@ -2698,8 +2997,8 @@ name, as a symbol."
 
           ;; 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-9][0-9_]*\\(\\.[0-9_]*\\)?"
+                        "\\([eE][-+]?[0-9_]+\\)?")
                 '(0 mdw-number-face))
 
           ;; And anything else is punctuation.
@@ -2721,9 +3020,18 @@ strip numbers instead."
       (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.
 
+(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.
@@ -2740,9 +3048,9 @@ strip numbers instead."
               '(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]\\|\\)")
+        (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.
@@ -2776,10 +3084,15 @@ strip numbers instead."
                ("\\.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 lua-indent-level 2)
+(setq-default lua-indent-level 2)
 
 (defun mdw-fontify-lua ()
 
@@ -2819,15 +3132,19 @@ strip numbers instead."
           (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.
 
-(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.
 
@@ -2874,6 +3191,10 @@ strip numbers instead."
           (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))
+
 ;;;--------------------------------------------------------------------------
 ;;; Assembler mode.
 
@@ -2882,33 +3203,48 @@ strip numbers instead."
   (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 ?; "."
                       )
-  (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)
 
+(progn
+  (add-hook 'asm-mode-hook 'mdw-misc-mode-config t)
+  (add-hook 'asm-mode-hook 'mdw-fontify-asm t))
+
 ;;;--------------------------------------------------------------------------
 ;;; TCL configuration.
 
+(setq-default tcl-indent-level 2)
+
 (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
        (list
         (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
-                      "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
-                      "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
+                      "\\<[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.
 
@@ -2975,10 +3311,14 @@ strip numbers instead."
                              "\\)")
                      '(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.
 
-(setq a68-indent-step 2)
+(setq-default a68-indent-step 2)
 
 (defun mdw-fontify-algol-68 ()
 
@@ -3017,6 +3357,10 @@ strip numbers instead."
                (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.
 
@@ -3037,8 +3381,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-*)
-  (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.
@@ -3090,9 +3434,18 @@ strip numbers instead."
           (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.
 
+(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.
@@ -3128,21 +3481,27 @@ strip numbers instead."
                 '(0 font-lock-keyword-face))
 
           ;; At least numbers are simpler than C.
-          (list (concat "\\<\\(\\~\\|\\)"
-                           "\\(0\\(\\([wW]\\|\\)[xX][0-9a-fA-F]+\\|"
+          (list (concat "\\<\\~?"
+                           "\\(0\\([wW]?[xX][0-9a-fA-F]+\\|"
                                   "[wW][0-9]+\\)\\|"
-                               "\\([0-9]+\\(\\.[0-9]+\\|\\)"
-                                        "\\([eE]\\(\\~\\|\\)"
-                                               "[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 'sml-mode-hook 'mdw-misc-mode-config t)
+  (add-hook 'sml-mode-hook 'mdw-fontify-sml t))
+
 ;;;--------------------------------------------------------------------------
 ;;; Haskell configuration.
 
+(setq-default haskell-indent-offset 2)
+
 (defun mdw-fontify-haskell ()
 
   ;; Fiddle with syntax table to get comments right.
@@ -3212,16 +3571,20 @@ strip numbers instead."
           (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-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.
 
-(setq erlang-electric-commands nil)
+(setq-default erlang-electric-commands nil)
 
 (defun mdw-fontify-erlang ()
 
@@ -3246,11 +3609,15 @@ strip numbers instead."
                 '(0 font-lock-keyword-face))
           (list (concat "^-\\sw+\\>")
                 '(0 font-lock-keyword-face))
-          (list "\\<[0-9]+\\(\\|#[0-9a-zA-Z]+\\|[eE][+-]?[0-9]+\\)\\>"
+          (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.
 
@@ -3274,7 +3641,7 @@ strip numbers instead."
               '(2 font-lock-variable-name-face))
 
         ;; Make sure we get comments properly.
-        (list "@c\\(\\|omment\\)\\( .*\\)?$"
+        (list "@c\\(omment\\)?\\( .*\\)?$"
               '(0 font-lock-comment-face))
 
         ;; Command names are keywords.
@@ -3285,9 +3652,18 @@ strip numbers instead."
         (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.
 
+(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)
@@ -3355,6 +3731,8 @@ strip numbers instead."
         (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'."
@@ -3374,12 +3752,92 @@ strip numbers instead."
           (unless modified
             (restore-buffer-modified-p nil)))))))
 
-(setq LaTeX-syntactic-comments nil
-      LaTeX-fill-break-at-separators '(\\\[))
+(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 2)
 
 ;;;--------------------------------------------------------------------------
 ;;; SGML hacking.
 
+(setq-default psgml-html-build-new-buffer nil)
+
 (defun mdw-sgml-mode ()
   (interactive)
   (sgml-mode)
@@ -3426,11 +3884,14 @@ that character only to be normal punctuation.")
           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)))))))
-(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.
@@ -3500,6 +3961,10 @@ that character only to be normal punctuation.")
                 (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.
 
@@ -3520,8 +3985,8 @@ that character only to be normal punctuation.")
                  (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)
@@ -3614,7 +4079,7 @@ that character only to be normal punctuation.")
     (setq messages-mode-keywords
          (append (list (list (concat "^[ \t]*\\#[ \t]*"
                                      "\\(include\\|import\\)"
-                                     "[ \t]*\\(<[^>]+\\(>\\|\\)\\)")
+                                     "[ \t]*\\(<[^>]+\\(>\\)?\\)")
                              '(2 font-lock-string-face))
                        (list (concat "^\\([ \t]*#[ \t]*\\(\\("
                                      preprocessor-keywords
@@ -3623,9 +4088,11 @@ that character only to be normal punctuation.")
                  messages-mode-keywords)))
   (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.
@@ -3658,7 +4125,7 @@ that character only to be normal punctuation.")
          (list
           (list (concat "^%\\s *\\(}\\|\\(" keywords "\\)\\>\\).*$")
                 '(0 font-lock-keyword-face))
-          (list "^%\\s *\\(#.*\\|\\)$"
+          (list "^%\\s *\\(#.*\\)?$"
                 '(0 font-lock-comment-face))
           (list "^%"
                 '(0 font-lock-keyword-face))
@@ -3673,7 +4140,8 @@ that character only to be normal punctuation.")
   (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.
@@ -3716,31 +4184,7 @@ that character only to be normal punctuation.")
   (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)
@@ -3764,9 +4208,19 @@ that character only to be normal punctuation.")
   (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)
+(setq-default 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 ()
 
@@ -3797,20 +4251,75 @@ that character only to be normal punctuation.")
              (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
                    '(0 mdw-punct-face)))))
 
-(defun comint-send-and-indent ()
-  (interactive)
-  (comint-send-input)
+;; SLIME setup.
+
+(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
-       (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))
 
-(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 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 ()
 
@@ -3822,6 +4331,15 @@ that character only to be normal punctuation.")
   ;; 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.
 
@@ -3835,6 +4353,9 @@ that character only to be normal punctuation.")
 (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.
 
@@ -3896,13 +4417,13 @@ This allows you to pass a list of arguments through `ansi-term'."
 
 (defadvice term-exec-1 (around hack-environment compile activate)
   "Hack the environment inherited by inferiors in the terminal."
-  (let ((process-environment process-environment))
+  (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 process-environment))
+  (let ((process-environment (copy-tree process-environment)))
     (setenv "LD_PRELOAD" nil)
     ad-do-it))
 
@@ -3912,7 +4433,7 @@ This allows you to pass a list of arguments through `ansi-term'."
   (ansi-term (list "ssh" host) (format "ssh@%s" host)))
 
 (defvar git-grep-command
-  "env PAGER=cat git grep --no-color -nH -e "
+  "env GIT_PAGER=cat git grep --no-color -nH -e "
   "*The default command for \\[git-grep].")
 
 (defvar git-grep-history nil)
@@ -3922,12 +4443,13 @@ 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)))
-  (grep command-args))
+  (let ((grep-use-null-device nil))
+    (grep command-args)))
 
 ;;;--------------------------------------------------------------------------
 ;;; Magit configuration.
 
-(setq magit-diff-refine-hunk 'all
+(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 ""
@@ -3939,6 +4461,7 @@ This allows you to pass a list of arguments through `ansi-term'."
          (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)
@@ -3957,6 +4480,13 @@ This allows you to pass a list of arguments through `ansi-term'."
     (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)
@@ -3998,6 +4528,55 @@ there is sadness."
 (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))
+
+;;;--------------------------------------------------------------------------
+;;; 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)))