dot/emacs, el/dot-emacs.el: Support for Dylan code.
[profile] / el / dot-emacs.el
index 5a152f0..4f9bd59 100644 (file)
@@ -124,6 +124,14 @@ library."
   (and (library-exists-p file)
        (autoload symbol file docstring interactivep type)))
 
+(defun mdw-kick-menu-bar (&optional frame)
+  "Regenerate FRAME's menu bar so it doesn't have empty menus."
+  (interactive)
+  (unless frame (setq frame (selected-frame)))
+  (let ((old (frame-parameter frame 'menu-bar-lines)))
+    (set-frame-parameter frame 'menu-bar-lines 0)
+    (set-frame-parameter frame 'menu-bar-lines old)))
+
 ;; Splitting windows.
 
 (unless (fboundp 'scroll-bar-columns)
@@ -137,6 +145,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")
@@ -146,16 +181,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)
@@ -164,6 +190,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)
@@ -248,6 +293,11 @@ Evil key bindings are defined in `mdw-evil-keymap-keys'."
             ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
           org-export-latex-classes)))
 
+(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")
+
 ;;;--------------------------------------------------------------------------
 ;;; Mail and news hacking.
 
@@ -321,6 +371,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.
 
@@ -418,6 +471,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
@@ -482,7 +550,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.
@@ -564,7 +633,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.
@@ -576,21 +645,15 @@ This is mainly useful in `auto-fill-mode'.")
 
 ;; Utility functions.
 
-(defun mdw-tabify (s)
-  "Tabify the string S.  This is a horrid hack."
-  (save-excursion
-    (save-match-data
-      (let (start end)
-       (beginning-of-line)
-       (setq start (point-marker))
+(defun mdw-maybe-tabify (s)
+  "Tabify or untabify the string S, according to `indent-tabs-mode'."
+  (let ((tabfun (if indent-tabs-mode #'tabify #'untabify)))
+    (with-temp-buffer
+      (save-match-data
        (insert s "\n")
-       (setq end (point-marker))
-       (tabify start end)
-       (setq s (buffer-substring start (1- end)))
-       (delete-region start end)
-       (set-marker start nil)
-       (set-marker end nil)
-       s))))
+       (let ((start (point-min)) (end (point-max)))
+         (funcall tabfun (point-min) (point-max))
+         (setq s (buffer-substring (point-min) (1- (point-max)))))))))
 
 (defun mdw-examine-fill-prefixes (l)
   "Given a list of dynamic fill prefixes, pick one which matches
@@ -598,9 +661,9 @@ 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-tabify (apply (function concat)
-                                  (mapcar (function mdw-do-prefix-match)
-                                          (cdr (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)
@@ -665,6 +728,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)
@@ -675,24 +747,23 @@ 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)
-  (let ((whitespace-style (remove 'trailing whitespace-style)))
-    (trap (whitespace-mode t)))
+  (mdw-whitespace-mode 1)
   (and (fboundp 'gtags-mode)
        (gtags-mode))
-  (outline-minor-mode t)
-  (hs-minor-mode t)
+  (if (fboundp 'hs-minor-mode)
+      (trap (hs-minor-mode t))
+    (outline-minor-mode t))
   (reveal-mode t)
   (trap (turn-on-font-lock)))
 
 (defun mdw-post-config-mode-hack ()
-  (let ((whitespace-style (remove 'trailing whitespace-style)))
-    (trap (whitespace-mode t))))
+  (mdw-whitespace-mode 1))
 
 (eval-after-load 'gtags
   '(progn
@@ -733,26 +804,13 @@ 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 fr 'display)
-                                         frame-display)
-                                (progn "frame %s still uses us" nil)))
+                                         frame-display)))
                          (frame-list))))
       (run-with-idle-timer 0 nil #'x-close-connection frame-display))))
 (add-hook 'delete-frame-functions 'mdw-last-one-out-turn-off-the-lights)
 
-(defvar mdw-frame-parameters-alist
-  '((nil (menu-bar-lines . 0))))
-(defun mdw-set-frame-parameters (frame)
-  (let ((params (assq (if (fboundp 'window-system)
-                         (window-system frame)
-                       window-system)
-                     mdw-frame-parameters-alist)))
-    (when params
-      (modify-frame-parameters frame (cdr params)))))
-(add-hook 'after-make-frame-functions 'mdw-set-frame-parameters)
-
 ;;;--------------------------------------------------------------------------
 ;;; General fontification.
 
@@ -768,18 +826,18 @@ doesn't match any of the regular expressions in
 
 (mdw-define-face default
   (((type w32)) :family "courier new" :height 85)
-  (((type x)) :family "6x13" :height 130)
+  (((type x)) :family "6x13" :foundry "trad" :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)
+  (((type x)) :family "6x13" :foundry "trad" :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 120)))
+    (((type x)) :family "helvetica" :height 90)))
 (mdw-define-face region
   (((type tty) (class color)) :background "blue")
   (((type tty) (class mono)) :inverse-video t)
@@ -805,7 +863,8 @@ doesn't match any of the regular expressions in
   (((class color)) :background "red")
   (t :inverse-video t))
 (mdw-define-face highlight
-  (((class color)) :background "DarkSeaGreen4")
+  (((type x) (class color)) :background "DarkSeaGreen4")
+  (((type tty) (class color)) :background "cyan")
   (t :inverse-video t))
 
 (mdw-define-face holiday-face
@@ -815,7 +874,15 @@ doesn't match any of the regular expressions in
 
 (mdw-define-face comint-highlight-prompt
   (t :weight bold))
-(mdw-define-face comint-highlight-input)
+(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")
@@ -849,6 +916,7 @@ doesn't match any of the regular expressions in
 (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
@@ -874,7 +942,11 @@ doesn't match any of the regular expressions in
   (((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-header
+  (t nil))
 (mdw-define-face diff-index
   (t :weight bold))
 (mdw-define-face diff-file-header
@@ -889,7 +961,27 @@ doesn't match any of the regular expressions in
   (t :foreground "green"))
 (mdw-define-face diff-removed
   (t :foreground "red"))
-(mdw-define-face diff-context)
+(mdw-define-face diff-context
+  (t nil))
+(mdw-define-face diff-refine-change
+  (((class color) (type x)) :background "RoyalBlue4")
+  (t :underline t))
+
+(mdw-define-face dylan-header-background
+  (((class color) (type x)) :background "NavyBlue")
+  (t :background "blue"))
+
+(mdw-define-face magit-diff-add
+  (t :foreground "green"))
+(mdw-define-face magit-diff-del
+  (t :foreground "red"))
+(mdw-define-face magit-diff-file-header
+  (t :weight bold))
+(mdw-define-face magit-diff-hunk-header
+  (t :foreground "SkyBlue1"))
+(mdw-define-face magit-item-highlight
+  (((type tty)) :background "blue")
+  (t :background "DarkSeaGreen4"))
 
 (mdw-define-face erc-input-face
   (t :foreground "red"))
@@ -899,6 +991,21 @@ doesn't match any of the regular expressions in
 (mdw-define-face woman-italic
   (t :slant italic))
 
+(eval-after-load "rst"
+  '(progn
+     (mdw-define-face rst-level-1-face
+       (t :foreground "SkyBlue1" :weight bold))
+     (mdw-define-face rst-level-2-face
+       (t :foreground "SeaGreen1" :weight bold))
+     (mdw-define-face rst-level-3-face
+       (t :weight bold))
+     (mdw-define-face rst-level-4-face
+       (t :slant italic))
+     (mdw-define-face rst-level-5-face
+       (t :underline t))
+     (mdw-define-face rst-level-6-face
+       ())))
+
 (mdw-define-face p4-depot-added-face
   (t :foreground "green"))
 (mdw-define-face p4-depot-branch-op-face
@@ -918,11 +1025,29 @@ doesn't match any of the regular expressions in
 (mdw-define-face p4-diff-ins-face
   (t :foreground "green"))
 
+(mdw-define-face w3m-anchor-face
+  (t :foreground "SkyBlue1" :underline t))
+(mdw-define-face w3m-arrived-anchor-face
+  (t :foreground "SkyBlue1" :underline t))
+
 (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 ((dollar (make-glyph-code ?$ 'mdw-ellipsis-face))
+      (backslash (make-glyph-code ?\ 'mdw-ellipsis-face))
+      (dot (make-glyph-code ?. 'mdw-ellipsis-face))
+      (bar (make-glyph-code ?| mdw-ellipsis-face)))
+  (set-display-table-slot standard-display-table 0 dollar)
+  (set-display-table-slot standard-display-table 1 backslash)
+  (set-display-table-slot standard-display-table 4
+                         (vector dot dot dot))
+  (set-display-table-slot standard-display-table 5 bar))
+
 ;;;--------------------------------------------------------------------------
 ;;; C programming configuration.
 
@@ -967,13 +1092,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))
 
@@ -1266,6 +1392,66 @@ doesn't match any of the regular expressions in
   (mdw-post-config-mode-hack))
 
 ;;;--------------------------------------------------------------------------
+;;; Javascript programming configuration.
+
+(defun mdw-javascript-style ()
+  (setq js-indent-level 2)
+  (setq js-expr-indent-offset 0))
+
+(defun mdw-fontify-javascript ()
+
+  ;; Other stuff.
+  (mdw-javascript-style)
+  (setq js-auto-indent-flag t)
+
+  ;; Now define things to be fontified.
+  (make-local-variable 'font-lock-keywords)
+  (let ((javascript-keywords
+        (mdw-regexps "abstract" "boolean" "break" "byte" "case" "catch"
+                     "char" "class" "const" "continue" "debugger" "default"
+                     "delete" "do" "double" "else" "enum" "export" "extends"
+                     "final" "finally" "float" "for" "function" "goto" "if"
+                     "implements" "import" "in" "instanceof" "int"
+                     "interface" "let" "long" "native" "new" "package"
+                     "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
+        (mdw-regexps "false" "null" "undefined" "Infinity" "NaN" "true"
+                     "arguments" "this")))
+
+    (setq font-lock-keywords
+         (list
+
+          ;; Handle the keywords defined above.
+          (list (concat "\\_<\\(" javascript-keywords "\\)\\_>")
+                '(0 font-lock-keyword-face))
+
+          ;; Handle the predefined constants defined above.
+          (list (concat "\\_<\\(" javascript-constants "\\)\\_>")
+                '(0 font-lock-variable-name-face))
+
+          ;; Handle numbers too.
+          ;;
+          ;; The following isn't quite right, but it's close enough.
+          (list (concat "\\_<\\("
+                        "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
+                        "[0-9]+\\(\\.[0-9]*\\|\\)"
+                        "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
+                        "[lLfFdD]?")
+                '(0 mdw-number-face))
+
+          ;; And anything else is punctuation.
+          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+                '(0 mdw-punct-face)))))
+
+  (mdw-post-config-mode-hack))
+
+;;;--------------------------------------------------------------------------
 ;;; C# programming configuration.
 
 ;; Make indentation nice.
@@ -1437,6 +1623,7 @@ doesn't match any of the regular expressions in
 
 ;; Perl indentation style.
 
+(fset 'perl-mode 'cperl-mode)
 (setq cperl-indent-level 2)
 (setq cperl-continued-statement-offset 2)
 (setq cperl-continued-brace-offset 0)
@@ -1456,11 +1643,11 @@ doesn't match any of the regular expressions in
   ;; Now define fontification things.
   (make-local-variable 'font-lock-keywords)
   (let ((perl-keywords
-        (mdw-regexps "and" "cmp" "continue" "do" "else" "elsif" "eq"
-                     "for" "foreach" "ge" "gt" "goto" "if"
+        (mdw-regexps "and" "break" "cmp" "continue" "do" "else" "elsif" "eq"
+                     "for" "foreach" "ge" "given" "gt" "goto" "if"
                      "last" "le" "lt" "local" "my" "ne" "next" "or"
-                     "package" "redo" "require" "return" "sub"
-                     "undef" "unless" "until" "use" "while")))
+                     "our" "package" "redo" "require" "return" "sub"
+                     "undef" "unless" "until" "use" "when" "while")))
 
     (setq font-lock-keywords
          (list
@@ -1503,6 +1690,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)
@@ -1510,12 +1698,12 @@ strip numbers instead."
        (list
 
         ;; Set up the keywords defined above.
-        (list (concat "\\<\\(" keywords "\\)\\>")
+        (list (concat "\\_<\\(" keywords "\\)\\_>")
               '(0 font-lock-keyword-face))
 
         ;; At least numbers are simpler than C.
-        (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
-                      "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
+        (list (concat "\\_<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
+                      "\\_<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
                       "\\([eE]\\([-+]\\|\\)[0-9_]+\\|[lL]\\|\\)")
               '(0 mdw-number-face))
 
@@ -1636,6 +1824,7 @@ strip numbers instead."
                       "<" arm-assembler-mode-syntax-table)
   (modify-syntax-entry ?\n ">" arm-assembler-mode-syntax-table)
   (modify-syntax-entry ?_ "_" arm-assembler-mode-syntax-table)
+  (modify-syntax-entry ?' "\"'" arm-assembler-mode-syntax-table)
 
   (make-local-variable 'comment-start)
   (setq comment-start ";")
@@ -1680,9 +1869,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))
+  (mdw-post-config-mode-hack)
   (run-hooks 'arm-assembler-mode-hook))
 
 ;;;--------------------------------------------------------------------------
@@ -1712,6 +1901,74 @@ strip numbers instead."
   (mdw-post-config-mode-hack))
 
 ;;;--------------------------------------------------------------------------
+;;; Dylan programming configuration.
+
+(defun mdw-fontify-dylan ()
+
+  (make-local-variable 'font-lock-keywords)
+
+  ;; Horrors.  `dylan-mode' sets the `major-mode' name after calling this
+  ;; hook, which undoes all of our configuration.
+  (setq major-mode 'dylan-mode)
+  (font-lock-set-defaults)
+
+  (let* ((word "[-_a-zA-Z!*@<>$%]+")
+        (dylan-keywords (mdw-regexps
+
+                         "C-address" "C-callable-wrapper" "C-function"
+                         "C-mapped-subtype" "C-pointer-type" "C-struct"
+                         "C-subtype" "C-union" "C-variable"
+
+                         "above" "abstract" "afterwards" "all"
+                         "begin" "below" "block" "by"
+                         "case" "class" "cleanup" "constant" "create"
+                         "define" "domain"
+                         "else" "elseif" "end" "exception" "export"
+                         "finally" "for" "from" "function"
+                         "generic"
+                         "handler"
+                         "if" "in" "instance" "interface" "iterate"
+                         "keyed-by"
+                         "let" "library" "local"
+                         "macro" "method" "module"
+                         "otherwise"
+                         "profiling"
+                         "select" "slot" "subclass"
+                         "table" "then" "to"
+                         "unless" "until" "use"
+                         "variable" "virtual"
+                         "when" "while"))
+        (sharp-keywords (mdw-regexps
+                         "all-keys" "key" "next" "rest" "include"
+                         "t" "f")))
+    (setq font-lock-keywords
+         (list (list (concat "\\<\\(" dylan-keywords
+                             "\\|" (concat "with\\(out\\)?-" word)
+                             "\\|" (concat word ":")
+                             "\\)\\>")
+                     '(0 font-lock-keyword-face))
+               (list (concat "#\\(" sharp-keywords "\\)\\>")
+                     '(0 font-lock-variable-name-face))
+               (list (concat "\\("
+                             "\\([-+]\\|\\<\\)[0-9]+" "\\("
+                               "\\(\\.[0-9]+\\)?" "\\([eE][-+][0-9]+\\)?"
+                               "\\|" "/[0-9]+"
+                             "\\)"
+                             "\\|" "\\.[0-9]+" "\\([eE][-+][0-9]+\\)?"
+                             "\\|" "#b[01]+"
+                             "\\|" "#o[0-7]+"
+                             "\\|" "#x[0-9a-zA-Z]+"
+                             "\\)\\>")
+                     '(0 mdw-number-face))
+               (list (concat "\\("
+                             "\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\|"
+                             "\\_<[-+*/=<>:&|]+\\_>"
+                             "\\)")
+                     '(0 mdw-punct-face)))))
+
+  (mdw-post-config-mode-hack))
+
+;;;--------------------------------------------------------------------------
 ;;; REXX configuration.
 
 (defun mdw-rexx-electric-* ()
@@ -1880,8 +2137,7 @@ strip numbers instead."
 ;;;--------------------------------------------------------------------------
 ;;; Erlang configuration.
 
-(setq erlang-electric-commannds
-      '(erlang-electric-newline erlang-electric-semicolon))
+(setq erlang-electric-commands nil)
 
 (defun mdw-fontify-erlang ()
 
@@ -2024,7 +2280,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" "\""
@@ -2039,6 +2295,48 @@ strip numbers instead."
   (run-hooks 'mdw-sgml-mode-hook))
 
 ;;;--------------------------------------------------------------------------
+;;; Configuration files.
+
+(defvar mdw-conf-quote-normal nil
+  "*Control syntax category of quote characters `\"' and `''.
+If this is `t', consider quote characters to be normal
+punctuation, as for `conf-quote-normal'.  If this is `nil' then
+leave quote characters as quotes.  If this is a list, then
+consider the quote characters in the list to be normal
+punctuation.  If this is a single quote character, then consider
+that character only to be normal punctuation.")
+(defun mdw-conf-quote-normal-acceptable-value-p (value)
+  "Is the VALUE is an acceptable value for `mdw-conf-quote-normal'?"
+  (or (booleanp value)
+      (every (lambda (v) (memq v '(?\" ?')))
+            (if (listp value) value (list value)))))
+(put 'mdw-conf-quote-normal 'safe-local-variable '
+     mdw-conf-quote-normal-acceptable-value-p)
+
+(defun mdw-fix-up-quote ()
+  "Apply the setting of `mdw-conf-quote-normal'."
+  (let ((flag mdw-conf-quote-normal))
+    (cond ((eq flag t)
+          (conf-quote-normal t))
+         ((not flag)
+          nil)
+         (t
+          (let ((table (copy-syntax-table (syntax-table))))
+            (mapc (lambda (ch) (modify-syntax-entry ch "." table))
+                  (if (listp flag) flag (list flag)))
+            (set-syntax-table table)
+            (and font-lock-mode (font-lock-fontify-buffer)))))))
+(defun mdw-fix-up-quote-hack ()
+  "Unpleasant hack to call `mdw-fix-up-quote' at the right time.
+Annoyingly, `hack-local-variables' is done after `set-auto-mode'
+so we wouldn't see a local-variable setting of
+`mdw-conf-quote-normal' in `conf-mode-hook'.  Instead, wire
+ourselves onto `hack-local-variables-hook' here, and check the
+setting once it's actually been made."
+  (add-hook 'hack-local-variables-hook 'mdw-fix-up-quote t t))
+(add-hook 'conf-mode-hook 'mdw-fix-up-quote-hack t)
+
+;;;--------------------------------------------------------------------------
 ;;; Shell scripts.
 
 (defun mdw-setup-sh-script-mode ()
@@ -2065,6 +2363,44 @@ strip numbers instead."
   (setq sh-indentation 2)
   (setq sh-basic-offset 2))
 
+(setq sh-shell-file "/bin/sh")
+
+;; Awful hacking to override the shell detection for particular scripts.
+(defmacro define-custom-shell-mode (name shell)
+  `(defun ,name ()
+     (interactive)
+     (set (make-local-variable 'sh-shell-file) ,shell)
+     (sh-mode)))
+(define-custom-shell-mode bash-mode "/bin/bash")
+(define-custom-shell-mode rc-mode "/usr/bin/rc")
+(put 'sh-shell-file 'permanent-local t)
+
+;; Hack the rc syntax table.  Backquotes aren't paired in rc.
+(eval-after-load "sh-script"
+  '(or (assq 'rc sh-mode-syntax-table-input)
+       (let ((frag '(nil
+                    ?# "<"
+                    ?\n ">#"
+                    ?\" "\"\""
+                    ?\' "\"\'"
+                    ?$ "'"
+                    ?\` "."
+                    ?! "_"
+                    ?% "_"
+                    ?. "_"
+                    ?^ "_"
+                    ?~ "_"
+                    ?, "_"
+                    ?= "."
+                    ?< "."
+                    ?> "."))
+            (assoc (assq 'rc sh-mode-syntax-table-input)))
+        (if assoc
+            (rplacd assoc frag)
+          (setq sh-mode-syntax-table-input
+                (cons (cons 'rc frag)
+                      sh-mode-syntax-table-input))))))
+
 ;;;--------------------------------------------------------------------------
 ;;; Emacs shell mode.
 
@@ -2076,13 +2412,21 @@ strip numbers instead."
            (save-match-data
              (replace-regexp-in-string "\\..*$" "" (system-name)))
            " "
-           (eshell/pwd)
+           (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 "^\\[[^]]+\\]")
+(setq eshell-prompt-regexp "^\\[[^]>]+\\(\\]\\|>>?\\)")
 
-(defalias 'eshell/e 'find-file)
-(defalias 'eshell/w3m 'w3m-goto-url)
+(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"))
@@ -2149,7 +2493,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 ()
@@ -2176,7 +2519,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)
@@ -2227,7 +2569,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)
@@ -2270,7 +2611,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))
 
 ;;;--------------------------------------------------------------------------
@@ -2281,7 +2621,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))
 
@@ -2320,7 +2660,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
@@ -2410,6 +2750,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.