dot/e16-bindings: New bindings for fiddling with window opacity.
[profile] / el / dot-emacs.el
index f535f10..1704f7d 100644 (file)
@@ -48,6 +48,8 @@ This may be at the expense of cool features.")
 
 (defmacro mdw-regexps (&rest list)
   "Turn a LIST of strings into a single regular expression at compile-time."
+  (declare (indent nil)
+          (debug 0))
   `',(make-regexp list))
 
 ;; Some error trapping.
@@ -57,6 +59,8 @@ This may be at the expense of cool features.")
 
 (defmacro trap (&rest forms)
   "Execute FORMS without allowing errors to propagate outside."
+  (declare (indent 0)
+          (debug t))
   `(condition-case err
        ,(if (cdr forms) (cons 'progn forms) (car forms))
      (error (message "Error (trapped): %s in %s"
@@ -133,6 +137,33 @@ library."
          ((eq side 'left) 1)
          (t 2))))
 
+(defun mdw-horizontal-window-overhead ()
+  "Computes the horizontal window overhead.
+This is the number of columns used by fringes, scroll bars and other such
+cruft."
+  (if (not window-system)
+      1
+    (let ((tot 0))
+      (dolist (what '(scroll-bar fringe))
+       (dolist (side '(left right))
+         (incf tot (funcall (intern (concat (symbol-name what) "-columns"))
+                            side))))
+      tot)))
+
+(defun mdw-split-window-horizontally (&optional width)
+  "Split a window horizontally.
+Without a numeric argument, split the window approximately in
+half.  With a numeric argument WIDTH, allocate WIDTH columns to
+the left-hand window (if positive) or -WIDTH columns to the
+right-hand window (if negative).  Space for scroll bars and
+fringes is not taken out of the allowance for WIDTH, unlike
+\\[split-window-horizontally]."
+  (interactive "P")
+  (split-window-horizontally
+   (cond ((null width) nil)
+        ((>= width 0) (+ width (mdw-horizontal-window-overhead)))
+        ((< width 0) width))))
+
 (defun mdw-divvy-window (&optional width)
   "Split a wide window into appropriate widths."
   (interactive "P")
@@ -142,16 +173,7 @@ library."
                     77)
                    (t 78)))
   (let* ((win (selected-window))
-        (sb-width (if (not window-system)
-                      1
-                    (let ((tot 0))
-                      (dolist (what '(scroll-bar fringe))
-                        (dolist (side '(left right))
-                          (incf tot
-                                (funcall (intern (concat (symbol-name what)
-                                                         "-columns"))
-                                         side))))
-                      tot)))
+        (sb-width (mdw-horizontal-window-overhead))
         (c (/ (+ (window-width) sb-width)
               (+ width sb-width))))
     (while (> c 1)
@@ -160,6 +182,25 @@ library."
       (other-window 1))
     (select-window win)))
 
+;; Transient mark mode hacks.
+
+(defadvice exchange-point-and-mark
+    (around mdw-highlight (&optional arg) activate compile)
+  "Maybe don't actually exchange point and mark.
+If `transient-mark-mode' is on and the mark is inactive, then
+just activate it.  A non-trivial prefix argument will force the
+usual behaviour.  A trivial prefix argument (i.e., just C-u) will
+activate the mark and temporarily enable `transient-mark-mode' if
+it's currently off."
+  (cond ((or mark-active
+            (and (not transient-mark-mode) (not arg))
+            (and arg (or (not (consp arg))
+                         (not (= (car arg) 4)))))
+        ad-do-it)
+       (t
+        (or transient-mark-mode (setq transient-mark-mode 'only))
+        (set-mark (mark t)))))
+
 ;; Functions for sexp diary entries.
 
 (defun mdw-weekday (l)
@@ -229,7 +270,7 @@ Evil key bindings are defined in `mdw-evil-keymap-keys'."
        (dolist (key replacements)
          (define-key keymap key binding))))))
 
-(eval-after-load "org"
+(eval-after-load "org-latex"
   '(progn
      (push '("strayman"
             "\\documentclass{strayman}
@@ -317,6 +358,9 @@ so that it can be used for convenient filtering."
          (setenv "REAL_MOVEMAIL" try))
       (setq path (cdr path)))))
 
+(eval-after-load "erc"
+    '(load "~/.ercrc.el"))
+
 ;;;--------------------------------------------------------------------------
 ;;; Utility functions.
 
@@ -345,7 +389,6 @@ probably become garbage."
                          (car alists)
                          (cdr alists)))))
 
-
 (defun mdw-do-uniquify (done end l rest)
   "A helper function for mdw-uniquify-alist.
 The DONE argument is a list whose first element is `nil'.  It
@@ -415,6 +458,21 @@ in REST."
              (insert "\nNP: ")
              (insert-file-contents np-file)))))
 
+(defun mdw-version-< (ver-a ver-b)
+  "Answer whether VER-A is strictly earlier than VER-B.
+VER-A and VER-B are version numbers, which are strings containing digit
+sequences separated by `.'."
+  (let* ((la (mapcar (lambda (x) (car (read-from-string x)))
+                    (split-string ver-a "\\.")))
+        (lb (mapcar (lambda (x) (car (read-from-string x)))
+                    (split-string ver-b "\\."))))
+    (catch 'done
+      (while 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))))))))
+
 (defun mdw-check-autorevert ()
   "Sets global-auto-revert-ignore-buffer appropriately for this buffer.
 This takes into consideration whether it's been found using
@@ -479,7 +537,8 @@ If NEW-SESSION-P, start a new session."
        (select-window window)))))
 
 (defvar mdw-good-url-browsers
-  '((w3m . mdw-w3m-browse-url)
+  '(browse-url-generic
+    (w3m . mdw-w3m-browse-url)
     browse-url-w3
     browse-url-mozilla)
   "List of good browsers for mdw-good-url-browsers.
@@ -561,7 +620,7 @@ It in turn is a list of things:
 
 (defvar mdw-hanging-indents
   (concat "\\(\\("
-           "\\([*o]\\|-[-#]?\\|[0-9]+\\.\\|\\[[0-9]+\\]\\|([a-zA-Z])\\)"
+           "\\([*o+]\\|-[-#]?\\|[0-9]+\\.\\|\\[[0-9]+\\]\\|([a-zA-Z])\\)"
            "[ \t]+"
          "\\)?\\)")
   "*Standard regexp matching parts of a hanging indent.
@@ -662,6 +721,15 @@ case."
 (defvar mdw-auto-indent t
   "Whether to indent automatically after a newline.")
 
+(defun mdw-whitespace-mode (&optional arg)
+  "Turn on/off whitespace mode, but don't highlight trailing space."
+  (interactive "P")
+  (when (and (boundp 'whitespace-style)
+            (fboundp 'whitespace-mode))
+    (let ((whitespace-style (remove 'trailing whitespace-style)))
+      (whitespace-mode arg))
+    (setq show-trailing-whitespace whitespace-mode)))
+
 (defun mdw-misc-mode-config ()
   (and mdw-auto-indent
        (cond ((eq major-mode 'lisp-mode)
@@ -672,30 +740,33 @@ case."
             (t
              (local-set-key "\C-m" 'newline-and-indent))))
   (local-set-key [C-return] 'newline)
-  (make-variable-buffer-local 'page-delimiter)
+  (make-local-variable 'page-delimiter)
   (setq page-delimiter "\f\\|^.*-\\{6\\}.*$")
   (setq comment-column 40)
   (auto-fill-mode 1)
   (setq fill-column 77)
   (setq show-trailing-whitespace t)
+  (mdw-whitespace-mode 1)
   (and (fboundp 'gtags-mode)
        (gtags-mode))
-  (outline-minor-mode t)
-  (hs-minor-mode t)
-  (mdw-set-font))
+  (if (fboundp 'hs-minor-mode)
+      (hs-minor-mode t)
+    (outline-minor-mode t))
+  (reveal-mode t)
+  (trap (turn-on-font-lock)))
 
-(eval-after-load 'gtags
-  '(dolist (key '([mouse-2] [mouse-3]))
-     (define-key gtags-mode-map key nil)))
+(defun mdw-post-config-mode-hack ()
+  (mdw-whitespace-mode 1))
 
-;; Set up all sorts of faces.
-
-(defvar mdw-set-font nil)
-
-(defvar mdw-punct-face 'mdw-punct-face "Face to use for punctuation")
-(make-face 'mdw-punct-face)
-(defvar mdw-number-face 'mdw-number-face "Face to use for numbers")
-(make-face 'mdw-number-face)
+(eval-after-load 'gtags
+  '(progn
+     (dolist (key '([mouse-2] [mouse-3]))
+       (define-key gtags-mode-map key nil))
+     (define-key gtags-mode-map [C-S-mouse-2] 'gtags-find-tag-by-event)
+     (define-key gtags-select-mode-map [C-S-mouse-2]
+       'gtags-select-tag-by-event)
+     (dolist (map (list gtags-mode-map gtags-select-mode-map))
+       (define-key map [C-S-mouse-3] 'gtags-pop-stack))))
 
 ;; Backup file handling.
 
@@ -726,140 +797,200 @@ doesn't match any of the regular expressions in
     (when (and frame-display
               (eq window-system 'x)
               (not (some (lambda (fr)
-                           (message "checking frame %s" frame)
                            (and (not (eq fr frame))
-                                (string= (frame-parameter frame 'display)
-                                         frame-display)
-                                (progn "frame %s still uses us" nil)))
+                                (string= (frame-parameter fr 'display)
+                                         frame-display)))
                          (frame-list))))
-      (message "turn out the lights")
       (run-with-idle-timer 0 nil #'x-close-connection frame-display))))
 (add-hook 'delete-frame-functions 'mdw-last-one-out-turn-off-the-lights)
 
 ;;;--------------------------------------------------------------------------
 ;;; General fontification.
 
-(defun mdw-set-fonts (frame faces)
-  (while faces
-    (let ((face (caar faces)))
-      (or (facep face) (make-face face))
-      (set-face-attribute face frame
-                         :family 'unspecified
-                         :width 'unspecified
-                         :height 'unspecified
-                         :weight 'unspecified
-                         :slant 'unspecified
-                         :foreground 'unspecified
-                         :background 'unspecified
-                         :underline 'unspecified
-                         :overline 'unspecified
-                         :strike-through 'unspecified
-                         :box 'unspecified
-                         :inverse-video 'unspecified
-                         :stipple 'unspecified
-                         ;:font 'unspecified
-                         :inherit 'unspecified)
-      (apply 'set-face-attribute face frame (cdar faces))
-      (setq faces (cdr faces)))))
-
-(defun mdw-do-set-font (&optional frame)
-  (interactive)
-  (mdw-set-fonts (and (boundp 'frame) frame)  `(
-    (default :foreground "white" :background "black"
-      ,@(cond ((eq window-system 'w32)
-              '(:family "courier new" :height 85))
-             ((eq window-system 'x)
-              '(:family "misc-fixed" :height 130 :width semi-condensed))))
-    (fixed-pitch)
-    (minibuffer-prompt)
-    (mode-line :foreground "blue" :background "yellow"
-              :box (:line-width 1 :style released-button))
-    (mode-line-inactive :foreground "yellow" :background "blue"
-                       :box (:line-width 1 :style released-button))
-    (scroll-bar :foreground "black" :background "lightgrey")
-    (fringe :foreground "yellow" :background "black")
-    (show-paren-match-face :background "darkgreen")
-    (show-paren-mismatch-face :background "red")
-    (font-lock-warning-face :background "red" :weight bold)
-    (highlight :background "DarkSeaGreen4")
-    (holiday-face :background "red")
-    (calendar-today-face :foreground "yellow" :weight bold)
-    (comint-highlight-prompt :weight bold)
-    (comint-highlight-input)
-    (font-lock-builtin-face :weight bold)
-    (font-lock-type-face :weight bold)
-    (region :background ,(if window-system "grey30" "blue"))
-    (isearch :background "palevioletred2")
-    (mdw-punct-face :foreground ,(if window-system "burlywood2" "yellow"))
-    (mdw-number-face :foreground "yellow")
-    (font-lock-function-name-face :weight bold)
-    (font-lock-variable-name-face :slant italic)
-    (font-lock-comment-delimiter-face
-       :foreground ,(if window-system "SeaGreen1" "green")
-       :slant italic)
-    (font-lock-comment-face
-       :foreground ,(if window-system "SeaGreen1" "green")
-       :slant italic)
-    (font-lock-string-face :foreground ,(if window-system "SkyBlue1" "cyan"))
-    (font-lock-keyword-face :weight bold)
-    (font-lock-constant-face :weight bold)
-    (font-lock-reference-face :weight bold)
-    (message-cited-text
-       :foreground ,(if window-system "SeaGreen1" "green")
-       :slant italic)
-    (message-separator :background "red" :foreground "white" :weight bold)
-    (message-header-cc
-       :foreground ,(if window-system "SeaGreen1" "green")
-       :weight bold)
-    (message-header-newsgroups
-       :foreground ,(if window-system "SeaGreen1" "green")
-       :weight bold)
-    (message-header-subject
-       :foreground ,(if window-system "SeaGreen1" "green")
-       :weight bold)
-    (message-header-to
-       :foreground ,(if window-system "SeaGreen1" "green")
-       :weight bold)
-    (message-header-xheader
-       :foreground ,(if window-system "SeaGreen1" "green")
-       :weight bold)
-    (message-header-other
-       :foreground ,(if window-system "SeaGreen1" "green")
-       :weight bold)
-    (message-header-name
-       :foreground ,(if window-system "SeaGreen1" "green"))
-    (woman-bold :weight bold)
-    (woman-italic :slant italic)
-    (p4-depot-added-face :foreground "green")
-    (p4-depot-branch-op-face :foreground "yellow")
-    (p4-depot-deleted-face :foreground "red")
-    (p4-depot-unmapped-face
-       :foreground ,(if window-system "SkyBlue1" "cyan"))
-    (p4-diff-change-face :foreground "yellow")
-    (p4-diff-del-face :foreground "red")
-    (p4-diff-file-face :foreground "SkyBlue1")
-    (p4-diff-head-face :background "grey10")
-    (p4-diff-ins-face :foreground "green")
-    (diff-index :weight bold)
-    (diff-file-header :weight bold)
-    (diff-hunk-header :foreground "SkyBlue1")
-    (diff-function :foreground "SkyBlue1" :weight bold)
-    (diff-header :background "grey10")
-    (diff-added :foreground "green")
-    (diff-removed :foreground "red")
-    (diff-context)
-    (whizzy-slice-face :background "grey10")
-    (whizzy-error-face :background "darkred")
-    (trailing-whitespace :background "red")
-)))
-
-(defun mdw-set-font ()
-  (trap
-    (turn-on-font-lock)
-    (if (not mdw-set-font)
-       (progn
-         (setq mdw-set-font t)
-         (mdw-do-set-font nil)))))
+(defmacro mdw-define-face (name &rest body)
+  "Define a face, and make sure it's actually set as the definition."
+  (declare (indent 1)
+          (debug 0))
+  `(progn
+     (make-face ',name)
+     (defvar ,name ',name)
+     (put ',name 'face-defface-spec ',body)
+     (face-spec-set ',name ',body nil)))
+
+(mdw-define-face default
+  (((type w32)) :family "courier new" :height 85)
+  (((type x)) :family "6x13" :height 130)
+  (((type color)) :foreground "white" :background "black")
+  (t nil))
+(mdw-define-face fixed-pitch
+  (((type w32)) :family "courier new" :height 85)
+  (((type x)) :family "6x13" :height 130)
+  (t :foreground "white" :background "black"))
+(if (>= emacs-major-version 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 region
+  (((type tty) (class color)) :background "blue")
+  (((type tty) (class mono)) :inverse-video t)
+  (t :background "grey30"))
+(mdw-define-face minibuffer-prompt
+  (t :weight bold))
+(mdw-define-face mode-line
+  (((class color)) :foreground "blue" :background "yellow"
+                  :box (:line-width 1 :style released-button))
+  (t :inverse-video t))
+(mdw-define-face mode-line-inactive
+  (((class color)) :foreground "yellow" :background "blue"
+                  :box (:line-width 1 :style released-button))
+  (t :inverse-video t))
+(mdw-define-face scroll-bar
+  (t :foreground "black" :background "lightgrey"))
+(mdw-define-face fringe
+  (t :foreground "yellow"))
+(mdw-define-face show-paren-match
+  (((class color)) :background "darkgreen")
+  (t :underline t))
+(mdw-define-face show-paren-mismatch
+  (((class color)) :background "red")
+  (t :inverse-video t))
+(mdw-define-face highlight
+  (((class color)) :background "DarkSeaGreen4")
+  (t :inverse-video t))
+
+(mdw-define-face holiday-face
+  (t :background "red"))
+(mdw-define-face calendar-today-face
+  (t :foreground "yellow" :weight bold))
+
+(mdw-define-face comint-highlight-prompt
+  (t :weight bold))
+(mdw-define-face comint-highlight-input
+  (t nil))
+
+(mdw-define-face dired-directory
+  (t :foreground "cyan" :weight bold))
+(mdw-define-face dired-symlink
+  (t :foreground "cyan"))
+(mdw-define-face dired-perm-write
+  (t nil))
+
+(mdw-define-face trailing-whitespace
+  (((class color)) :background "red")
+  (t :inverse-video t))
+(mdw-define-face mdw-punct-face
+  (((type tty)) :foreground "yellow") (t :foreground "burlywood2"))
+(mdw-define-face mdw-number-face
+  (t :foreground "yellow"))
+(mdw-define-face font-lock-function-name-face
+  (t :slant italic))
+(mdw-define-face font-lock-keyword-face
+  (t :weight bold))
+(mdw-define-face font-lock-constant-face
+  (t :slant italic))
+(mdw-define-face font-lock-builtin-face
+  (t :weight bold))
+(mdw-define-face font-lock-type-face
+  (t :weight bold :slant italic))
+(mdw-define-face font-lock-reference-face
+  (t :weight bold))
+(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"))
+(mdw-define-face font-lock-comment-face
+  (((class mono)) :weight bold)
+  (((type tty) (class color)) :foreground "green")
+  (t :slant italic :foreground "SeaGreen1"))
+(mdw-define-face font-lock-string-face
+  (((class mono)) :weight bold)
+  (((class color)) :foreground "SkyBlue1"))
+(mdw-define-face message-separator
+  (t :background "red" :foreground "white" :weight bold))
+(mdw-define-face message-cited-text
+  (default :slant italic)
+  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+(mdw-define-face message-header-cc
+  (default :weight bold)
+  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+(mdw-define-face message-header-newsgroups
+  (default :weight bold)
+  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+(mdw-define-face message-header-subject
+  (default :weight bold)
+  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+(mdw-define-face message-header-to
+  (default :weight bold)
+  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+(mdw-define-face message-header-xheader
+  (default :weight bold)
+  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+(mdw-define-face message-header-other
+  (default :weight bold)
+  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+(mdw-define-face message-header-name
+  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+(mdw-define-face which-func
+  (t nil))
+
+(mdw-define-face diff-index
+  (t :weight bold))
+(mdw-define-face diff-file-header
+  (t :weight bold))
+(mdw-define-face diff-hunk-header
+  (t :foreground "SkyBlue1"))
+(mdw-define-face diff-function
+  (t :foreground "SkyBlue1" :weight bold))
+(mdw-define-face diff-header
+  (t :background "grey10"))
+(mdw-define-face diff-added
+  (t :foreground "green"))
+(mdw-define-face diff-removed
+  (t :foreground "red"))
+(mdw-define-face diff-context
+  (t nil))
+
+(mdw-define-face erc-input-face
+  (t :foreground "red"))
+
+(mdw-define-face woman-bold
+  (t :weight bold))
+(mdw-define-face woman-italic
+  (t :slant italic))
+
+(mdw-define-face p4-depot-added-face
+  (t :foreground "green"))
+(mdw-define-face p4-depot-branch-op-face
+  (t :foreground "yellow"))
+(mdw-define-face p4-depot-deleted-face
+  (t :foreground "red"))
+(mdw-define-face p4-depot-unmapped-face
+  (t :foreground "SkyBlue1"))
+(mdw-define-face p4-diff-change-face
+  (t :foreground "yellow"))
+(mdw-define-face p4-diff-del-face
+  (t :foreground "red"))
+(mdw-define-face p4-diff-file-face
+  (t :foreground "SkyBlue1"))
+(mdw-define-face p4-diff-head-face
+  (t :background "grey10"))
+(mdw-define-face p4-diff-ins-face
+  (t :foreground "green"))
+
+(mdw-define-face whizzy-slice-face
+  (t :background "grey10"))
+(mdw-define-face whizzy-error-face
+  (t :background "darkred"))
+
+;; Ellipses used to indicate hidden text (and similar).
+(mdw-define-face mdw-ellipsis-face
+  (((type tty)) :foreground "blue") (t :foreground "grey60"))
+(let ((dot (make-glyph-code ?. 'mdw-ellipsis-face)))
+  (set-display-table-slot standard-display-table 4
+                         (vector dot dot dot)))
 
 ;;;--------------------------------------------------------------------------
 ;;; C programming configuration.
@@ -905,13 +1036,14 @@ doesn't match any of the regular expressions in
                  (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 . 0)
+                 (statement-cont . +)
                  (statement-case-intro . +)))
               t))
 
@@ -1081,7 +1213,9 @@ doesn't match any of the regular expressions in
 
           ;; And anything else is punctuation.
           (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face))))))
+                '(0 mdw-punct-face))))
+
+    (mdw-post-config-mode-hack)))
 
 ;;;--------------------------------------------------------------------------
 ;;; AP calc mode.
@@ -1133,7 +1267,9 @@ doesn't match any of the regular expressions in
 
           ;; And anything else is punctuation.
           (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face))))))
+                '(0 mdw-punct-face)))))
+
+  (mdw-post-config-mode-hack))
 
 ;;;--------------------------------------------------------------------------
 ;;; Java programming configuration.
@@ -1195,7 +1331,9 @@ doesn't match any of the regular expressions in
 
           ;; And anything else is punctuation.
           (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face))))))
+                '(0 mdw-punct-face)))))
+
+  (mdw-post-config-mode-hack))
 
 ;;;--------------------------------------------------------------------------
 ;;; C# programming configuration.
@@ -1262,12 +1400,49 @@ doesn't match any of the regular expressions in
 
           ;; And anything else is punctuation.
           (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face))))))
+                '(0 mdw-punct-face)))))
+
+  (mdw-post-config-mode-hack))
 
 (define-derived-mode csharp-mode java-mode "C#"
   "Major mode for editing C# code.")
 
 ;;;--------------------------------------------------------------------------
+;;; Go programming configuration.
+
+(defun mdw-fontify-go ()
+
+  (make-local-variable 'font-lock-keywords)
+  (let ((go-keywords
+        (mdw-regexps "break" "case" "chan" "const" "continue"
+                     "default" "defer" "else" "fallthrough" "for"
+                     "func" "go" "goto" "if" "import"
+                     "interface" "map" "package" "range" "return"
+                     "select" "struct" "switch" "type" "var")))
+
+    (setq font-lock-keywords
+         (list
+
+          ;; Handle the keywords defined above.
+          (list (concat "\\<\\(" go-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]+\\|\\)\\)")
+                '(0 mdw-number-face))
+
+          ;; And anything else is punctuation.
+          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+                '(0 mdw-punct-face)))))
+
+  (mdw-post-config-mode-hack))
+
+;;;--------------------------------------------------------------------------
 ;;; Awk programming configuration.
 
 ;; Make Awk indentation nice.
@@ -1323,7 +1498,9 @@ doesn't match any of the regular expressions in
 
           ;; And anything else is punctuation.
           (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face))))))
+                '(0 mdw-punct-face)))))
+
+  (mdw-post-config-mode-hack))
 
 ;;;--------------------------------------------------------------------------
 ;;; Perl programming style.
@@ -1370,7 +1547,9 @@ doesn't match any of the regular expressions in
 
           ;; And anything else is punctuation.
           (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face))))))
+                '(0 mdw-punct-face)))))
+
+  (mdw-post-config-mode-hack))
 
 (defun perl-number-tests (&optional arg)
   "Assign consecutive numbers to lines containing `#t'.  With ARG,
@@ -1394,6 +1573,7 @@ strip numbers instead."
 
   ;; Miscellaneous fiddling.
   (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
+  (setq indent-tabs-mode nil)
 
   ;; Now define fontification things.
   (make-local-variable 'font-lock-keywords)
@@ -1412,7 +1592,9 @@ strip numbers instead."
 
         ;; And anything else is punctuation.
         (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-              '(0 mdw-punct-face)))))
+              '(0 mdw-punct-face))))
+
+  (mdw-post-config-mode-hack))
 
 ;; Define Python fontification styles.
 
@@ -1486,7 +1668,9 @@ strip numbers instead."
 
           ;; And anything else is punctuation.
           (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face))))))
+                '(0 mdw-punct-face)))))
+
+  (mdw-post-config-mode-hack))
 
 ;;;--------------------------------------------------------------------------
 ;;; ARM assembler programming configuration.
@@ -1567,8 +1751,9 @@ strip numbers instead."
 
         ;; And anything else is punctuation.
         (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-              '(0 mdw-punct-face))))
+              '(0 mdw-punct-face)))
 
+  (mdw-post-config-mode-hack))
   (run-hooks 'arm-assembler-mode-hook))
 
 ;;;--------------------------------------------------------------------------
@@ -1594,7 +1779,8 @@ strip numbers instead."
                       "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
               '(0 mdw-number-face))
         (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-              '(0 mdw-punct-face)))))
+              '(0 mdw-punct-face))))
+  (mdw-post-config-mode-hack))
 
 ;;;--------------------------------------------------------------------------
 ;;; REXX configuration.
@@ -1667,7 +1853,9 @@ strip numbers instead."
 
           ;; And everything else is punctuation.
           (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face))))))
+                '(0 mdw-punct-face)))))
+
+  (mdw-post-config-mode-hack))
 
 ;;;--------------------------------------------------------------------------
 ;;; Standard ML programming style.
@@ -1717,7 +1905,9 @@ strip numbers instead."
 
           ;; And anything else is punctuation.
           (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face))))))
+                '(0 mdw-punct-face)))))
+
+  (mdw-post-config-mode-hack))
 
 ;;;--------------------------------------------------------------------------
 ;;; Haskell configuration.
@@ -1754,13 +1944,14 @@ strip numbers instead."
                         "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)")
                 '(0 mdw-number-face))
           (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face))))))
+                '(0 mdw-punct-face)))))
+
+  (mdw-post-config-mode-hack))
 
 ;;;--------------------------------------------------------------------------
 ;;; Erlang configuration.
 
-(setq erlang-electric-commannds
-      '(erlang-electric-newline erlang-electric-semicolon))
+(setq erlang-electric-commands nil)
 
 (defun mdw-fontify-erlang ()
 
@@ -1788,7 +1979,9 @@ strip numbers instead."
           (list "\\<[0-9]+\\(\\|#[0-9a-zA-Z]+\\|[eE][+-]?[0-9]+\\)\\>"
                 '(0 mdw-number-face))
           (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-                '(0 mdw-punct-face))))))
+                '(0 mdw-punct-face)))))
+
+  (mdw-post-config-mode-hack))
 
 ;;;--------------------------------------------------------------------------
 ;;; Texinfo configuration.
@@ -1822,7 +2015,9 @@ strip numbers instead."
 
         ;; Fontify TeX special characters as punctuation.
         (list "[{}]+"
-              '(0 mdw-punct-face)))))
+              '(0 mdw-punct-face))))
+
+  (mdw-post-config-mode-hack))
 
 ;;;--------------------------------------------------------------------------
 ;;; TeX and LaTeX configuration.
@@ -1888,7 +2083,9 @@ strip numbers instead."
 
         ;; Fontify TeX special characters as punctuation.
         (list "[$^_{}#&]"
-              '(0 mdw-punct-face)))))
+              '(0 mdw-punct-face))))
+
+  (mdw-post-config-mode-hack))
 
 ;;;--------------------------------------------------------------------------
 ;;; SGML hacking.
@@ -1897,7 +2094,7 @@ strip numbers instead."
   (interactive)
   (sgml-mode)
   (mdw-standard-fill-prefix "")
-  (make-variable-buffer-local 'sgml-delimiters)
+  (make-local-variable 'sgml-delimiters)
   (setq sgml-delimiters
        '("AND" "&" "COM" "--" "CRO" "&#" "DSC" "]" "DSO" "[" "DTGC" "]"
          "DTGO" "[" "ERO" "&" "ETAGO" ":e" "GRPC" ")" "GRPO" "(" "LIT" "\""
@@ -1939,6 +2136,43 @@ strip numbers instead."
   (setq sh-basic-offset 2))
 
 ;;;--------------------------------------------------------------------------
+;;; Emacs shell mode.
+
+(defun mdw-eshell-prompt ()
+  (let ((left "[") (right "]"))
+    (when (= (user-uid) 0)
+      (setq left "«" right "»"))
+    (concat left
+           (save-match-data
+             (replace-regexp-in-string "\\..*$" "" (system-name)))
+           " "
+           (let* ((pwd (eshell/pwd)) (npwd (length pwd))
+                  (home (expand-file-name "~")) (nhome (length home)))
+             (if (and (>= npwd nhome)
+                      (or (= nhome npwd)
+                          (= (elt pwd nhome) ?/))
+                      (string= (substring pwd 0 nhome) home))
+                 (concat "~" (substring pwd (length home)))
+               pwd))
+           right)))
+(setq eshell-prompt-function 'mdw-eshell-prompt)
+(setq eshell-prompt-regexp "^\\[[^]>]+\\(\\]\\|>>?\\)")
+
+(defun eshell/e (file) (find-file file) nil)
+(defun eshell/ee (file) (find-file-other-window file) nil)
+(defun eshell/w3m (url) (w3m-goto-url url) nil)
+
+(mdw-define-face eshell-prompt (t :weight bold))
+(mdw-define-face eshell-ls-archive (t :weight bold :foreground "red"))
+(mdw-define-face eshell-ls-backup (t :foreground "lightgrey" :slant italic))
+(mdw-define-face eshell-ls-product (t :foreground "lightgrey" :slant italic))
+(mdw-define-face eshell-ls-clutter (t :foreground "lightgrey" :slant italic))
+(mdw-define-face eshell-ls-executable (t :weight bold))
+(mdw-define-face eshell-ls-directory (t :foreground "cyan" :weight bold))
+(mdw-define-face eshell-ls-readonly (t nil))
+(mdw-define-face eshell-ls-symlink (t :foreground "cyan"))
+
+;;;--------------------------------------------------------------------------
 ;;; Messages-file mode.
 
 (defun messages-mode-guts ()
@@ -1993,7 +2227,6 @@ strip numbers instead."
   (modify-syntax-entry ?\n ">" messages-mode-syntax-table)
   (setq comment-start "# ")
   (setq comment-end "")
-  (turn-on-font-lock-if-enabled)
   (run-hooks 'messages-mode-hook))
 
 (defun cpp-messages-mode ()
@@ -2020,7 +2253,6 @@ strip numbers instead."
                                      "\\)\\>\\|[0-9]+\\|$\\)\\)")
                              '(1 font-lock-keyword-face)))
                  messages-mode-keywords)))
-  (turn-on-font-lock-if-enabled)
   (run-hooks 'cpp-messages-mode-hook))
 
 (add-hook 'messages-mode-hook 'mdw-misc-mode-config t)
@@ -2071,7 +2303,6 @@ strip numbers instead."
   (modify-syntax-entry ?\n ">" mallow-driver-mode-syntax-table)
   (setq comment-start "%# ")
   (setq comment-end "")
-  (turn-on-font-lock-if-enabled)
   (run-hooks 'mallow-driver-mode-hook))
 
 (add-hook 'mallow-driver-hook 'mdw-misc-mode-config t)
@@ -2114,7 +2345,6 @@ strip numbers instead."
         '("\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" (0 mdw-punct-face))))
   (setq font-lock-defaults
        '(nfast-debug-mode-keywords nil nil nil nil))
-  (turn-on-font-lock-if-enabled)
   (run-hooks 'nfast-debug-mode-hook))
 
 ;;;--------------------------------------------------------------------------
@@ -2125,7 +2355,7 @@ strip numbers instead."
 (defun mdw-setup-smalltalk ()
   (and mdw-auto-indent
        (local-set-key "\C-m" 'smalltalk-newline-and-indent))
-  (make-variable-buffer-local 'mdw-auto-indent)
+  (make-local-variable 'mdw-auto-indent)
   (setq mdw-auto-indent nil)
   (local-set-key "\C-i" 'smalltalk-reindent))
 
@@ -2140,7 +2370,8 @@ strip numbers instead."
                       "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
               '(0 mdw-number-face))
         (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-              '(0 mdw-punct-face)))))
+              '(0 mdw-punct-face))))
+  (mdw-post-config-mode-hack))
 
 ;; Lispy languages.
 
@@ -2163,7 +2394,7 @@ strip numbers instead."
        (multiple-value-bind . ((&whole 4 &rest 1) 4 &body))))))
 
 (defun mdw-common-lisp-indent ()
-  (make-variable-buffer-local 'lisp-indent-function)
+  (make-local-variable 'lisp-indent-function)
   (setq lisp-indent-function 'common-lisp-indent-function))
 
 (setq lisp-simple-loop-indentation 2
@@ -2180,7 +2411,9 @@ strip numbers instead."
   (setq font-lock-keywords
        (list
         (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
-              '(0 mdw-punct-face)))))
+              '(0 mdw-punct-face))))
+
+  (mdw-post-config-mode-hack))
 
 (defun comint-send-and-indent ()
   (interactive)
@@ -2215,6 +2448,9 @@ strip numbers instead."
 
 (setq hs-hide-comments-when-hiding-all nil)
 
+(defadvice hs-hide-all (after hide-first-comment activate)
+  (save-excursion (hs-hide-initial-comment-block)))
+
 ;;;--------------------------------------------------------------------------
 ;;; Shell mode.
 
@@ -2248,6 +2484,20 @@ strip numbers instead."
      (define-key term-raw-map [M-left] 'term-send-meta-left)
      (define-key term-raw-map [?\e ?\M-O ?D] 'term-send-meta-left)))
 
+(defadvice term-exec (before program-args-list compile activate)
+  "If the PROGRAM argument is a list, interpret it as (PROGRAM . SWITCHES).
+This allows you to pass a list of arguments through `ansi-term'."
+  (let ((program (ad-get-arg 2)))
+    (if (listp program)
+       (progn
+         (ad-set-arg 2 (car program))
+         (ad-set-arg 4 (cdr program))))))
+
+(defun ssh (host)
+  "Open a terminal containing an ssh session to the HOST."
+  (interactive "sHost: ")
+  (ansi-term (list "ssh" host) (format "ssh@%s" host)))
+
 ;;;--------------------------------------------------------------------------
 ;;; Inferior Emacs Lisp.