chiark / gitweb /
dot/emacs, el/dot-emacs.el: Use Chrome as the default URL browser.
[profile] / el / dot-emacs.el
1 ;;; -*- mode: emacs-lisp; coding: utf-8 -*-
2 ;;;
3 ;;; Functions and macros for .emacs
4 ;;;
5 ;;; (c) 2004 Mark Wooding
6 ;;;
7
8 ;;;----- Licensing notice ---------------------------------------------------
9 ;;;
10 ;;; This program is free software; you can redistribute it and/or modify
11 ;;; it under the terms of the GNU General Public License as published by
12 ;;; the Free Software Foundation; either version 2 of the License, or
13 ;;; (at your option) any later version.
14 ;;;
15 ;;; This program is distributed in the hope that it will be useful,
16 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;;; GNU General Public License for more details.
19 ;;;
20 ;;; You should have received a copy of the GNU General Public License
21 ;;; along with this program; if not, write to the Free Software Foundation,
22 ;;; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24 ;;;--------------------------------------------------------------------------
25 ;;; Check command-line.
26
27 (defvar mdw-fast-startup nil
28   "Whether .emacs should optimize for rapid startup.
29 This may be at the expense of cool features.")
30 (let ((probe nil) (next command-line-args))
31   (while next
32     (cond ((string= (car next) "--mdw-fast-startup")
33            (setq mdw-fast-startup t)
34            (if probe
35                (rplacd probe (cdr next))
36              (setq command-line-args (cdr next))))
37           (t
38            (setq probe next)))
39     (setq next (cdr next))))
40
41 ;;;--------------------------------------------------------------------------
42 ;;; Some general utilities.
43
44 (eval-when-compile
45   (unless (fboundp 'make-regexp)
46     (load "make-regexp"))
47   (require 'cl))
48
49 (defmacro mdw-regexps (&rest list)
50   "Turn a LIST of strings into a single regular expression at compile-time."
51   (declare (indent nil)
52            (debug 0))
53   `',(make-regexp list))
54
55 ;; Some error trapping.
56 ;;
57 ;; If individual bits of this file go tits-up, we don't particularly want
58 ;; the whole lot to stop right there and then, because it's bloody annoying.
59
60 (defmacro trap (&rest forms)
61   "Execute FORMS without allowing errors to propagate outside."
62   (declare (indent 0)
63            (debug t))
64   `(condition-case err
65        ,(if (cdr forms) (cons 'progn forms) (car forms))
66      (error (message "Error (trapped): %s in %s"
67                      (error-message-string err)
68                      ',forms))))
69
70 ;; Configuration reading.
71
72 (defvar mdw-config nil)
73 (defun mdw-config (sym)
74   "Read the configuration variable named SYM."
75   (unless mdw-config
76     (setq mdw-config
77           (flet ((replace (what with)
78                    (goto-char (point-min))
79                    (while (re-search-forward what nil t)
80                      (replace-match with t))))
81             (with-temp-buffer
82               (insert-file-contents "~/.mdw.conf")
83               (replace  "^[ \t]*\\(#.*\\|\\)\n" "")
84               (replace (concat "^[ \t]*"
85                                "\\([-a-zA-Z0-9_.]*\\)"
86                                "[ \t]*=[ \t]*"
87                                "\\(.*[^ \t\n]\\|\\)"
88                                "[ \t]**\\(\n\\|$\\)")
89                        "(\\1 . \"\\2\")\n")
90               (car (read-from-string
91                     (concat "(" (buffer-string) ")")))))))
92   (cdr (assq sym mdw-config)))
93
94 ;; Set up the load path convincingly.
95
96 (dolist (dir (append (and (boundp 'debian-emacs-flavor)
97                           (list (concat "/usr/share/"
98                                         (symbol-name debian-emacs-flavor)
99                                         "/site-lisp")))))
100   (dolist (sub (directory-files dir t))
101     (when (and (file-accessible-directory-p sub)
102                (not (member sub load-path)))
103       (setq load-path (nconc load-path (list sub))))))
104
105 ;; Is an Emacs library available?
106
107 (defun library-exists-p (name)
108   "Return non-nil if NAME is an available library.
109 Return non-nil if NAME.el (or NAME.elc) somewhere on the Emacs
110 load path.  The non-nil value is the filename we found for the
111 library."
112   (let ((path load-path) elt (foundp nil))
113     (while (and path (not foundp))
114       (setq elt (car path))
115       (setq path (cdr path))
116       (setq foundp (or (let ((file (concat elt "/" name ".elc")))
117                          (and (file-exists-p file) file))
118                        (let ((file (concat elt "/" name ".el")))
119                          (and (file-exists-p file) file)))))
120     foundp))
121
122 (defun maybe-autoload (symbol file &optional docstring interactivep type)
123   "Set an autoload if the file actually exists."
124   (and (library-exists-p file)
125        (autoload symbol file docstring interactivep type)))
126
127 ;; Splitting windows.
128
129 (unless (fboundp 'scroll-bar-columns)
130   (defun scroll-bar-columns (side)
131     (cond ((eq side 'left) 0)
132           (window-system 3)
133           (t 1))))
134 (unless (fboundp 'fringe-columns)
135   (defun fringe-columns (side)
136     (cond ((not window-system) 0)
137           ((eq side 'left) 1)
138           (t 2))))
139
140 (defun mdw-divvy-window (&optional width)
141   "Split a wide window into appropriate widths."
142   (interactive "P")
143   (setq width (cond (width (prefix-numeric-value width))
144                     ((and window-system
145                           (>= emacs-major-version 22))
146                      77)
147                     (t 78)))
148   (let* ((win (selected-window))
149          (sb-width (if (not window-system)
150                        1
151                      (let ((tot 0))
152                        (dolist (what '(scroll-bar fringe))
153                          (dolist (side '(left right))
154                            (incf tot
155                                  (funcall (intern (concat (symbol-name what)
156                                                           "-columns"))
157                                           side))))
158                        tot)))
159          (c (/ (+ (window-width) sb-width)
160                (+ width sb-width))))
161     (while (> c 1)
162       (setq c (1- c))
163       (split-window-horizontally (+ width sb-width))
164       (other-window 1))
165     (select-window win)))
166
167 ;; Transient mark mode hacks.
168
169 (defadvice exchange-point-and-mark
170     (around mdw-highlight (&optional arg) activate compile)
171   "Maybe don't actually exchange point and mark.
172 If `transient-mark-mode' is on and the mark is inactive, then
173 just activate it.  A non-trivial prefix argument will force the
174 usual behaviour.  A trivial prefix argument (i.e., just C-u) will
175 activate the mark and temporarily enable `transient-mark-mode' if
176 it's currently off."
177   (cond ((or mark-active
178              (and (not transient-mark-mode) (not arg))
179              (and arg (or (not (consp arg))
180                           (not (= (car arg) 4)))))
181          ad-do-it)
182         (t
183          (or transient-mark-mode (setq transient-mark-mode 'only))
184          (set-mark (mark t)))))
185
186 ;; Functions for sexp diary entries.
187
188 (defun mdw-weekday (l)
189   "Return non-nil if `date' falls on one of the days of the week in L.
190 L is a list of day numbers (from 0 to 6 for Sunday through to
191 Saturday) or symbols `sunday', `monday', etc. (or a mixture).  If
192 the date stored in `date' falls on a listed day, then the
193 function returns non-nil."
194   (let ((d (calendar-day-of-week date)))
195     (or (memq d l)
196         (memq (nth d '(sunday monday tuesday wednesday
197                               thursday friday saturday)) l))))
198
199 (defun mdw-todo (&optional when)
200   "Return non-nil today, or on WHEN, whichever is later."
201   (let ((w (calendar-absolute-from-gregorian (calendar-current-date)))
202         (d (calendar-absolute-from-gregorian date)))
203     (if when
204         (setq w (max w (calendar-absolute-from-gregorian
205                         (cond
206                          ((not european-calendar-style)
207                           when)
208                          ((> (car when) 100)
209                           (list (nth 1 when)
210                                 (nth 2 when)
211                                 (nth 0 when)))
212                          (t
213                           (list (nth 1 when)
214                                 (nth 0 when)
215                                 (nth 2 when))))))))
216     (eq w d)))
217
218 ;; Fighting with Org-mode's evil key maps.
219
220 (defvar mdw-evil-keymap-keys
221   '(([S-up] . [?\C-c up])
222     ([S-down] . [?\C-c down])
223     ([S-left] . [?\C-c left])
224     ([S-right] . [?\C-c right])
225     (([M-up] [?\e up]) . [C-up])
226     (([M-down] [?\e down]) . [C-down])
227     (([M-left] [?\e left]) . [C-left])
228     (([M-right] [?\e right]) . [C-right]))
229   "Defines evil keybindings to clobber in `mdw-clobber-evil-keymap'.
230 The value is an alist mapping evil keys (as a list, or singleton)
231 to good keys (in the same form).")
232
233 (defun mdw-clobber-evil-keymap (keymap)
234   "Replace evil key bindings in the KEYMAP.
235 Evil key bindings are defined in `mdw-evil-keymap-keys'."
236   (dolist (entry mdw-evil-keymap-keys)
237     (let ((binding nil)
238           (keys (if (listp (car entry))
239                     (car entry)
240                   (list (car entry))))
241           (replacements (if (listp (cdr entry))
242                             (cdr entry)
243                           (list (cdr entry)))))
244       (catch 'found
245         (dolist (key keys)
246           (setq binding (lookup-key keymap key))
247           (when binding
248             (throw 'found nil))))
249       (when binding
250         (dolist (key keys)
251           (define-key keymap key nil))
252         (dolist (key replacements)
253           (define-key keymap key binding))))))
254
255 (eval-after-load "org-latex"
256   '(progn
257      (push '("strayman"
258              "\\documentclass{strayman}
259 \\usepackage[utf8]{inputenc}
260 \\usepackage[palatino, helvetica, courier, maths=cmr]{mdwfonts}
261 \\usepackage[T1]{fontenc}
262 \\usepackage{graphicx, tikz, mdwtab, mdwmath, crypto, longtable}"
263              ("\\section{%s}" . "\\section*{%s}")
264              ("\\subsection{%s}" . "\\subsection*{%s}")
265              ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
266              ("\\paragraph{%s}" . "\\paragraph*{%s}")
267              ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
268            org-export-latex-classes)))
269
270 ;;;--------------------------------------------------------------------------
271 ;;; Mail and news hacking.
272
273 (define-derived-mode  mdwmail-mode mail-mode "[mdw] mail"
274   "Major mode for editing news and mail messages from external programs.
275 Not much right now.  Just support for doing MailCrypt stuff."
276   :syntax-table nil
277   :abbrev-table nil
278   (run-hooks 'mail-setup-hook))
279
280 (define-key mdwmail-mode-map [?\C-c ?\C-c] 'disabled-operation)
281
282 (add-hook 'mdwail-mode-hook
283           (lambda ()
284             (set-buffer-file-coding-system 'utf-8)
285             (make-local-variable 'paragraph-separate)
286             (make-local-variable 'paragraph-start)
287             (setq paragraph-start
288                   (concat "[ \t]*[-_][-_][-_]+$\\|^-- \\|-----\\|"
289                           paragraph-start))
290             (setq paragraph-separate
291                   (concat "[ \t]*[-_][-_][-_]+$\\|^-- \\|-----\\|"
292                           paragraph-separate))))
293
294 ;; How to encrypt in mdwmail.
295
296 (defun mdwmail-mc-encrypt (&optional recip scm start end from sign)
297   (or start
298       (setq start (save-excursion
299                     (goto-char (point-min))
300                     (or (search-forward "\n\n" nil t) (point-min)))))
301   (or end
302       (setq end (point-max)))
303   (mc-encrypt-generic recip scm start end from sign))
304
305 ;; How to sign in mdwmail.
306
307 (defun mdwmail-mc-sign (key scm start end uclr)
308   (or start
309       (setq start (save-excursion
310                     (goto-char (point-min))
311                     (or (search-forward "\n\n" nil t) (point-min)))))
312   (or end
313       (setq end (point-max)))
314   (mc-sign-generic key scm start end uclr))
315
316 ;; Some signature mangling.
317
318 (defun mdwmail-mangle-signature ()
319   (save-excursion
320     (goto-char (point-min))
321     (perform-replace "\n-- \n" "\n-- " nil nil nil)))
322 (add-hook 'mail-setup-hook 'mdwmail-mangle-signature)
323 (add-hook 'message-setup-hook 'mdwmail-mangle-signature)
324
325 ;; Insert my login name into message-ids, so I can score replies.
326
327 (defadvice message-unique-id (after mdw-user-name last activate compile)
328   "Ensure that the user's name appears at the end of the message-id string,
329 so that it can be used for convenient filtering."
330   (setq ad-return-value (concat ad-return-value "." (user-login-name))))
331
332 ;; Tell my movemail hack where movemail is.
333 ;;
334 ;; This is needed to shup up warnings about LD_PRELOAD.
335
336 (let ((path exec-path))
337   (while path
338     (let ((try (expand-file-name "movemail" (car path))))
339       (if (file-executable-p try)
340           (setenv "REAL_MOVEMAIL" try))
341       (setq path (cdr path)))))
342
343 ;;;--------------------------------------------------------------------------
344 ;;; Utility functions.
345
346 (or (fboundp 'line-number-at-pos)
347     (defun line-number-at-pos (&optional pos)
348       (let ((opoint (or pos (point))) start)
349         (save-excursion
350           (save-restriction
351             (goto-char (point-min))
352             (widen)
353             (forward-line 0)
354             (setq start (point))
355             (goto-char opoint)
356             (forward-line 0)
357             (1+ (count-lines 1 (point))))))))
358
359 (defun mdw-uniquify-alist (&rest alists)
360   "Return the concatenation of the ALISTS with duplicate elements removed.
361 The first association with a given key prevails; others are
362 ignored.  The input lists are not modified, although they'll
363 probably become garbage."
364   (and alists
365        (let ((start-list (cons nil nil)))
366          (mdw-do-uniquify start-list
367                           start-list
368                           (car alists)
369                           (cdr alists)))))
370
371 (defun mdw-do-uniquify (done end l rest)
372   "A helper function for mdw-uniquify-alist.
373 The DONE argument is a list whose first element is `nil'.  It
374 contains the uniquified alist built so far.  The leading `nil' is
375 stripped off at the end of the operation; it's only there so that
376 DONE always references a cons cell.  END refers to the final cons
377 cell in the DONE list; it is modified in place each time to avoid
378 the overheads of `append'ing all the time.  The L argument is the
379 alist we're currently processing; the remaining alists are given
380 in REST."
381
382   ;; There are several different cases to deal with here.
383   (cond
384
385    ;; Current list isn't empty.  Add the first item to the DONE list if
386    ;; there's not an item with the same KEY already there.
387    (l (or (assoc (car (car l)) done)
388           (progn
389             (setcdr end (cons (car l) nil))
390             (setq end (cdr end))))
391       (mdw-do-uniquify done end (cdr l) rest))
392
393    ;; The list we were working on is empty.  Shunt the next list into the
394    ;; current list position and go round again.
395    (rest (mdw-do-uniquify done end (car rest) (cdr rest)))
396
397    ;; Everything's done.  Remove the leading `nil' from the DONE list and
398    ;; return it.  Finished!
399    (t (cdr done))))
400
401 (defun date ()
402   "Insert the current date in a pleasing way."
403   (interactive)
404   (insert (save-excursion
405             (let ((buffer (get-buffer-create "*tmp*")))
406               (unwind-protect (progn (set-buffer buffer)
407                                      (erase-buffer)
408                                      (shell-command "date +%Y-%m-%d" t)
409                                      (goto-char (mark))
410                                      (delete-backward-char 1)
411                                      (buffer-string))
412                 (kill-buffer buffer))))))
413
414 (defun uuencode (file &optional name)
415   "UUencodes a file, maybe calling it NAME, into the current buffer."
416   (interactive "fInput file name: ")
417
418   ;; If NAME isn't specified, then guess from the filename.
419   (if (not name)
420       (setq name
421             (substring file
422                        (or (string-match "[^/]*$" file) 0))))
423   (print (format "uuencode `%s' `%s'" file name))
424
425   ;; Now actually do the thing.
426   (call-process "uuencode" file t nil name))
427
428 (defvar np-file "~/.np"
429   "*Where the `now-playing' file is.")
430
431 (defun np (&optional arg)
432   "Grabs a `now-playing' string."
433   (interactive)
434   (save-excursion
435     (or arg (progn
436               (goto-char (point-max))
437               (insert "\nNP: ")
438               (insert-file-contents np-file)))))
439
440 (defun mdw-version-< (ver-a ver-b)
441   "Answer whether VER-A is strictly earlier than VER-B.
442 VER-A and VER-B are version numbers, which are strings containing digit
443 sequences separated by `.'."
444   (let* ((la (mapcar (lambda (x) (car (read-from-string x)))
445                      (split-string ver-a "\\.")))
446          (lb (mapcar (lambda (x) (car (read-from-string x)))
447                      (split-string ver-b "\\."))))
448     (catch 'done
449       (while t
450         (cond ((null la) (throw 'done lb))
451               ((null lb) (throw 'done nil))
452               ((< (car la) (car lb)) (throw 'done t))
453               ((= (car la) (car lb)) (setq la (cdr la) lb (cdr lb))))))))
454
455 (defun mdw-check-autorevert ()
456   "Sets global-auto-revert-ignore-buffer appropriately for this buffer.
457 This takes into consideration whether it's been found using
458 tramp, which seems to get itself into a twist."
459   (cond ((not (boundp 'global-auto-revert-ignore-buffer))
460          nil)
461         ((and (buffer-file-name)
462               (fboundp 'tramp-tramp-file-p)
463               (tramp-tramp-file-p (buffer-file-name)))
464          (unless global-auto-revert-ignore-buffer
465            (setq global-auto-revert-ignore-buffer 'tramp)))
466         ((eq global-auto-revert-ignore-buffer 'tramp)
467          (setq global-auto-revert-ignore-buffer nil))))
468
469 (defadvice find-file (after mdw-autorevert activate)
470   (mdw-check-autorevert))
471 (defadvice write-file (after mdw-autorevert activate)
472   (mdw-check-autorevert))
473
474 ;;;--------------------------------------------------------------------------
475 ;;; Dired hacking.
476
477 (defadvice dired-maybe-insert-subdir
478     (around mdw-marked-insertion first activate)
479   "The DIRNAME may be a list of directory names to insert.
480 Interactively, if files are marked, then insert all of them.
481 With a numeric prefix argument, select that many entries near
482 point; with a non-numeric prefix argument, prompt for listing
483 options."
484   (interactive
485    (list (dired-get-marked-files nil
486                                  (and (integerp current-prefix-arg)
487                                       current-prefix-arg)
488                                  #'file-directory-p)
489          (and current-prefix-arg
490               (not (integerp current-prefix-arg))
491               (read-string "Switches for listing: "
492                            (or dired-subdir-switches
493                                dired-actual-switches)))))
494   (let ((dirs (ad-get-arg 0)))
495     (dolist (dir (if (listp dirs) dirs (list dirs)))
496       (ad-set-arg 0 dir)
497       ad-do-it)))
498
499 ;;;--------------------------------------------------------------------------
500 ;;; URL viewing.
501
502 (defun mdw-w3m-browse-url (url &optional new-session-p)
503   "Invoke w3m on the URL in its current window, or at least a different one.
504 If NEW-SESSION-P, start a new session."
505   (interactive "sURL: \nP")
506   (save-excursion
507     (let ((window (selected-window)))
508       (unwind-protect
509           (progn
510             (select-window (or (and (not new-session-p)
511                                     (get-buffer-window "*w3m*"))
512                                (progn
513                                  (if (one-window-p t) (split-window))
514                                  (get-lru-window))))
515             (w3m-browse-url url new-session-p))
516         (select-window window)))))
517
518 (defvar mdw-good-url-browsers
519   '(browse-url-generic
520     (w3m . mdw-w3m-browse-url)
521     browse-url-w3
522     browse-url-mozilla)
523   "List of good browsers for mdw-good-url-browsers.
524 Each item is a browser function name, or a cons (CHECK . FUNC).
525 A symbol FOO stands for (FOO . FOO).")
526
527 (defun mdw-good-url-browser ()
528   "Return a good URL browser.
529 Trundle the list of such things, finding the first item for which
530 CHECK is fboundp, and returning the correponding FUNC."
531   (let ((bs mdw-good-url-browsers) b check func answer)
532     (while (and bs (not answer))
533       (setq b (car bs)
534             bs (cdr bs))
535       (if (consp b)
536           (setq check (car b) func (cdr b))
537         (setq check b func b))
538       (if (fboundp check)
539           (setq answer func)))
540     answer))
541
542 (eval-after-load "w3m-search"
543   '(progn
544      (dolist
545          (item
546           '(("g" "Google" "http://www.google.co.uk/search?q=%s")
547             ("gd" "Google Directory"
548              "http://www.google.com/search?cat=gwd/Top&q=%s")
549             ("gg" "Google Groups" "http://groups.google.com/groups?q=%s")
550             ("ward" "Ward's wiki" "http://c2.com/cgi/wiki?%s")
551             ("gi" "Images" "http://images.google.com/images?q=%s")
552             ("rfc" "RFC"
553              "http://metalzone.distorted.org.uk/ftp/pub/mirrors/rfc/rfc%s.txt.gz")
554             ("wp" "Wikipedia"
555              "http://en.wikipedia.org/wiki/Special:Search?go=Go&search=%s")
556             ("imdb" "IMDb" "http://www.imdb.com/Find?%s")
557             ("nc-wiki" "nCipher wiki"
558              "http://wiki.ncipher.com/wiki/bin/view/Devel/?topic=%s")
559             ("map" "Google maps" "http://maps.google.co.uk/maps?q=%s&hl=en")
560             ("lp" "Launchpad bug by number"
561              "https://bugs.launchpad.net/bugs/%s")
562             ("lppkg" "Launchpad bugs by package"
563              "https://bugs.launchpad.net/%s")
564             ("msdn" "MSDN"
565              "http://social.msdn.microsoft.com/Search/en-GB/?query=%s&ac=8")
566             ("debbug" "Debian bug by number"
567              "http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=%s")
568             ("debbugpkg" "Debian bugs by package"
569              "http://bugs.debian.org/cgi-bin/pkgreport.cgi?pkg=%s")
570             ("ljlogin" "LJ login" "http://www.livejournal.com/login.bml")))
571        (add-to-list 'w3m-search-engine-alist
572                     (list (cadr item) (caddr item) nil))
573        (add-to-list 'w3m-uri-replace-alist
574                     (list (concat "\\`" (car item) ":")
575                           'w3m-search-uri-replace
576                           (cadr item))))))
577
578 ;;;--------------------------------------------------------------------------
579 ;;; Paragraph filling.
580
581 ;; Useful variables.
582
583 (defvar mdw-fill-prefix nil
584   "*Used by `mdw-line-prefix' and `mdw-fill-paragraph'.
585 If there's no fill prefix currently set (by the `fill-prefix'
586 variable) and there's a match from one of the regexps here, it
587 gets used to set the fill-prefix for the current operation.
588
589 The variable is a list of items of the form `REGEXP . PREFIX'; if
590 the REGEXP matches, the PREFIX is used to set the fill prefix.
591 It in turn is a list of things:
592
593   STRING -- insert a literal string
594   (match . N) -- insert the thing matched by bracketed subexpression N
595   (pad . N) -- a string of whitespace the same width as subexpression N
596   (expr . FORM) -- the result of evaluating FORM")
597
598 (make-variable-buffer-local 'mdw-fill-prefix)
599
600 (defvar mdw-hanging-indents
601   (concat "\\(\\("
602             "\\([*o+]\\|-[-#]?\\|[0-9]+\\.\\|\\[[0-9]+\\]\\|([a-zA-Z])\\)"
603             "[ \t]+"
604           "\\)?\\)")
605   "*Standard regexp matching parts of a hanging indent.
606 This is mainly useful in `auto-fill-mode'.")
607
608 ;; Setting things up.
609
610 (fset 'mdw-do-auto-fill (symbol-function 'do-auto-fill))
611
612 ;; Utility functions.
613
614 (defun mdw-tabify (s)
615   "Tabify the string S.  This is a horrid hack."
616   (save-excursion
617     (save-match-data
618       (let (start end)
619         (beginning-of-line)
620         (setq start (point-marker))
621         (insert s "\n")
622         (setq end (point-marker))
623         (tabify start end)
624         (setq s (buffer-substring start (1- end)))
625         (delete-region start end)
626         (set-marker start nil)
627         (set-marker end nil)
628         s))))
629
630 (defun mdw-examine-fill-prefixes (l)
631   "Given a list of dynamic fill prefixes, pick one which matches
632 context and return the static fill prefix to use.  Point must be
633 at the start of a line, and match data must be saved."
634   (cond ((not l) nil)
635                ((looking-at (car (car l)))
636                 (mdw-tabify (apply (function concat)
637                                    (mapcar (function mdw-do-prefix-match)
638                                            (cdr (car l))))))
639                (t (mdw-examine-fill-prefixes (cdr l)))))
640
641 (defun mdw-maybe-car (p)
642   "If P is a pair, return (car P), otherwise just return P."
643   (if (consp p) (car p) p))
644
645 (defun mdw-padding (s)
646   "Return a string the same width as S but made entirely from whitespace."
647   (let* ((l (length s)) (i 0) (n (make-string l ? )))
648     (while (< i l)
649       (if (= 9 (aref s i))
650           (aset n i 9))
651       (setq i (1+ i)))
652     n))
653
654 (defun mdw-do-prefix-match (m)
655   "Expand a dynamic prefix match element.
656 See `mdw-fill-prefix' for details."
657   (cond ((not (consp m)) (format "%s" m))
658            ((eq (car m) 'match) (match-string (mdw-maybe-car (cdr m))))
659            ((eq (car m) 'pad) (mdw-padding (match-string
660                                             (mdw-maybe-car (cdr m)))))
661            ((eq (car m) 'eval) (eval (cdr m)))
662            (t "")))
663
664 (defun mdw-choose-dynamic-fill-prefix ()
665   "Work out the dynamic fill prefix based on the variable `mdw-fill-prefix'."
666   (cond ((and fill-prefix (not (string= fill-prefix ""))) fill-prefix)
667            ((not mdw-fill-prefix) fill-prefix)
668            (t (save-excursion
669                 (beginning-of-line)
670                 (save-match-data
671                   (mdw-examine-fill-prefixes mdw-fill-prefix))))))
672
673 (defun do-auto-fill ()
674   "Handle auto-filling, working out a dynamic fill prefix in the
675 case where there isn't a sensible static one."
676   (let ((fill-prefix (mdw-choose-dynamic-fill-prefix)))
677     (mdw-do-auto-fill)))
678
679 (defun mdw-fill-paragraph ()
680   "Fill paragraph, getting a dynamic fill prefix."
681   (interactive)
682   (let ((fill-prefix (mdw-choose-dynamic-fill-prefix)))
683     (fill-paragraph nil)))
684
685 (defun mdw-standard-fill-prefix (rx &optional mat)
686   "Set the dynamic fill prefix, handling standard hanging indents and stuff.
687 This is just a short-cut for setting the thing by hand, and by
688 design it doesn't cope with anything approximating a complicated
689 case."
690   (setq mdw-fill-prefix
691            `((,(concat rx mdw-hanging-indents)
692               (match . 1)
693               (pad . ,(or mat 2))))))
694
695 ;;;--------------------------------------------------------------------------
696 ;;; Other common declarations.
697
698 ;; Common mode settings.
699
700 (defvar mdw-auto-indent t
701   "Whether to indent automatically after a newline.")
702
703 (defun mdw-whitespace-mode (&optional arg)
704   "Turn on/off whitespace mode, but don't highlight trailing space."
705   (interactive "P")
706   (when (and (boundp 'whitespace-style)
707              (fboundp 'whitespace-mode))
708     (let ((whitespace-style (remove 'trailing whitespace-style)))
709       (whitespace-mode arg))))
710
711 (defun mdw-misc-mode-config ()
712   (and mdw-auto-indent
713        (cond ((eq major-mode 'lisp-mode)
714               (local-set-key "\C-m" 'mdw-indent-newline-and-indent))
715              ((or (eq major-mode 'slime-repl-mode)
716                   (eq major-mode 'asm-mode))
717               nil)
718              (t
719               (local-set-key "\C-m" 'newline-and-indent))))
720   (local-set-key [C-return] 'newline)
721   (make-local-variable 'page-delimiter)
722   (setq page-delimiter "\f\\|^.*-\\{6\\}.*$")
723   (setq comment-column 40)
724   (auto-fill-mode 1)
725   (setq fill-column 77)
726   (setq show-trailing-whitespace t)
727   (mdw-whitespace-mode 1)
728   (and (fboundp 'gtags-mode)
729        (gtags-mode))
730   (outline-minor-mode t)
731   (hs-minor-mode t)
732   (reveal-mode t)
733   (trap (turn-on-font-lock)))
734
735 (defun mdw-post-config-mode-hack ()
736   (mdw-whitespace-mode 1))
737
738 (eval-after-load 'gtags
739   '(progn
740      (dolist (key '([mouse-2] [mouse-3]))
741        (define-key gtags-mode-map key nil))
742      (define-key gtags-mode-map [C-S-mouse-2] 'gtags-find-tag-by-event)
743      (define-key gtags-select-mode-map [C-S-mouse-2]
744        'gtags-select-tag-by-event)
745      (dolist (map (list gtags-mode-map gtags-select-mode-map))
746        (define-key map [C-S-mouse-3] 'gtags-pop-stack))))
747
748 ;; Backup file handling.
749
750 (defvar mdw-backup-disable-regexps nil
751   "*List of regular expressions: if a file name matches any of
752 these then the file is not backed up.")
753
754 (defun mdw-backup-enable-predicate (name)
755   "[mdw]'s default backup predicate.
756 Allows a backup if the standard predicate would allow it, and it
757 doesn't match any of the regular expressions in
758 `mdw-backup-disable-regexps'."
759   (and (normal-backup-enable-predicate name)
760        (let ((answer t) (list mdw-backup-disable-regexps))
761          (save-match-data
762            (while list
763              (if (string-match (car list) name)
764                  (setq answer nil))
765              (setq list (cdr list)))
766            answer))))
767 (setq backup-enable-predicate 'mdw-backup-enable-predicate)
768
769 ;; Frame cleanup.
770
771 (defun mdw-last-one-out-turn-off-the-lights (frame)
772   "Disconnect from an X display if this was the last frame on that display."
773   (let ((frame-display (frame-parameter frame 'display)))
774     (when (and frame-display
775                (eq window-system 'x)
776                (not (some (lambda (fr)
777                             (and (not (eq fr frame))
778                                  (string= (frame-parameter fr 'display)
779                                           frame-display)))
780                           (frame-list))))
781       (run-with-idle-timer 0 nil #'x-close-connection frame-display))))
782 (add-hook 'delete-frame-functions 'mdw-last-one-out-turn-off-the-lights)
783
784 ;;;--------------------------------------------------------------------------
785 ;;; General fontification.
786
787 (defmacro mdw-define-face (name &rest body)
788   "Define a face, and make sure it's actually set as the definition."
789   (declare (indent 1)
790            (debug 0))
791   `(progn
792      (make-face ',name)
793      (defvar ,name ',name)
794      (put ',name 'face-defface-spec ',body)
795      (face-spec-set ',name ',body nil)))
796
797 (mdw-define-face default
798   (((type w32)) :family "courier new" :height 85)
799   (((type x)) :family "6x13" :height 130)
800   (((type color)) :foreground "white" :background "black")
801   (t nil))
802 (mdw-define-face fixed-pitch
803   (((type w32)) :family "courier new" :height 85)
804   (((type x)) :family "6x13" :height 130)
805   (t :foreground "white" :background "black"))
806 (if (>= emacs-major-version 23)
807     (mdw-define-face variable-pitch
808       (((type x)) :family "sans" :height 100))
809   (mdw-define-face variable-pitch
810     (((type x)) :family "helvetica" :height 120)))
811 (mdw-define-face region
812   (((type tty) (class color)) :background "blue")
813   (((type tty) (class mono)) :inverse-video t)
814   (t :background "grey30"))
815 (mdw-define-face minibuffer-prompt
816   (t :weight bold))
817 (mdw-define-face mode-line
818   (((class color)) :foreground "blue" :background "yellow"
819                    :box (:line-width 1 :style released-button))
820   (t :inverse-video t))
821 (mdw-define-face mode-line-inactive
822   (((class color)) :foreground "yellow" :background "blue"
823                    :box (:line-width 1 :style released-button))
824   (t :inverse-video t))
825 (mdw-define-face scroll-bar
826   (t :foreground "black" :background "lightgrey"))
827 (mdw-define-face fringe
828   (t :foreground "yellow"))
829 (mdw-define-face show-paren-match
830   (((class color)) :background "darkgreen")
831   (t :underline t))
832 (mdw-define-face show-paren-mismatch
833   (((class color)) :background "red")
834   (t :inverse-video t))
835 (mdw-define-face highlight
836   (((class color)) :background "DarkSeaGreen4")
837   (t :inverse-video t))
838
839 (mdw-define-face holiday-face
840   (t :background "red"))
841 (mdw-define-face calendar-today-face
842   (t :foreground "yellow" :weight bold))
843
844 (mdw-define-face comint-highlight-prompt
845   (t :weight bold))
846 (mdw-define-face comint-highlight-input
847   (t nil))
848
849 (mdw-define-face trailing-whitespace
850   (((class color)) :background "red")
851   (t :inverse-video t))
852 (mdw-define-face mdw-punct-face
853   (((type tty)) :foreground "yellow") (t :foreground "burlywood2"))
854 (mdw-define-face mdw-number-face
855   (t :foreground "yellow"))
856 (mdw-define-face font-lock-function-name-face
857   (t :slant italic))
858 (mdw-define-face font-lock-keyword-face
859   (t :weight bold))
860 (mdw-define-face font-lock-constant-face
861   (t :slant italic))
862 (mdw-define-face font-lock-builtin-face
863   (t :weight bold))
864 (mdw-define-face font-lock-type-face
865   (t :weight bold :slant italic))
866 (mdw-define-face font-lock-reference-face
867   (t :weight bold))
868 (mdw-define-face font-lock-variable-name-face
869   (t :slant italic))
870 (mdw-define-face font-lock-comment-delimiter-face
871   (((class mono)) :weight bold)
872   (((type tty) (class color)) :foreground "green")
873   (t :slant italic :foreground "SeaGreen1"))
874 (mdw-define-face font-lock-comment-face
875   (((class mono)) :weight bold)
876   (((type tty) (class color)) :foreground "green")
877   (t :slant italic :foreground "SeaGreen1"))
878 (mdw-define-face font-lock-string-face
879   (((class mono)) :weight bold)
880   (((class color)) :foreground "SkyBlue1"))
881 (mdw-define-face message-separator
882   (t :background "red" :foreground "white" :weight bold))
883 (mdw-define-face message-cited-text
884   (default :slant italic)
885   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
886 (mdw-define-face message-header-cc
887   (default :weight bold)
888   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
889 (mdw-define-face message-header-newsgroups
890   (default :weight bold)
891   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
892 (mdw-define-face message-header-subject
893   (default :weight bold)
894   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
895 (mdw-define-face message-header-to
896   (default :weight bold)
897   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
898 (mdw-define-face message-header-xheader
899   (default :weight bold)
900   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
901 (mdw-define-face message-header-other
902   (default :weight bold)
903   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
904 (mdw-define-face message-header-name
905   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
906
907 (mdw-define-face diff-index
908   (t :weight bold))
909 (mdw-define-face diff-file-header
910   (t :weight bold))
911 (mdw-define-face diff-hunk-header
912   (t :foreground "SkyBlue1"))
913 (mdw-define-face diff-function
914   (t :foreground "SkyBlue1" :weight bold))
915 (mdw-define-face diff-header
916   (t :background "grey10"))
917 (mdw-define-face diff-added
918   (t :foreground "green"))
919 (mdw-define-face diff-removed
920   (t :foreground "red"))
921 (mdw-define-face diff-context
922   (t nil))
923
924 (mdw-define-face erc-input-face
925   (t :foreground "red"))
926
927 (mdw-define-face woman-bold
928   (t :weight bold))
929 (mdw-define-face woman-italic
930   (t :slant italic))
931
932 (mdw-define-face p4-depot-added-face
933   (t :foreground "green"))
934 (mdw-define-face p4-depot-branch-op-face
935   (t :foreground "yellow"))
936 (mdw-define-face p4-depot-deleted-face
937   (t :foreground "red"))
938 (mdw-define-face p4-depot-unmapped-face
939   (t :foreground "SkyBlue1"))
940 (mdw-define-face p4-diff-change-face
941   (t :foreground "yellow"))
942 (mdw-define-face p4-diff-del-face
943   (t :foreground "red"))
944 (mdw-define-face p4-diff-file-face
945   (t :foreground "SkyBlue1"))
946 (mdw-define-face p4-diff-head-face
947   (t :background "grey10"))
948 (mdw-define-face p4-diff-ins-face
949   (t :foreground "green"))
950
951 (mdw-define-face whizzy-slice-face
952   (t :background "grey10"))
953 (mdw-define-face whizzy-error-face
954   (t :background "darkred"))
955
956 ;;;--------------------------------------------------------------------------
957 ;;; C programming configuration.
958
959 ;; Linux kernel hacking.
960
961 (defvar linux-c-mode-hook)
962
963 (defun linux-c-mode ()
964   (interactive)
965   (c-mode)
966   (setq major-mode 'linux-c-mode)
967   (setq mode-name "Linux C")
968   (run-hooks 'linux-c-mode-hook))
969
970 ;; Make C indentation nice.
971
972 (defun mdw-c-lineup-arglist (langelem)
973   "Hack for DWIMmery in c-lineup-arglist."
974   (if (save-excursion
975         (c-block-in-arglist-dwim (c-langelem-2nd-pos c-syntactic-element)))
976       0
977     (c-lineup-arglist langelem)))
978
979 (defun mdw-c-indent-extern-mumble (langelem)
980   "Indent `extern \"...\" {' lines."
981   (save-excursion
982     (back-to-indentation)
983     (if (looking-at
984          "\\s-*\\<extern\\>\\s-*\"\\([^\\\\\"]+\\|\\.\\)*\"\\s-*{")
985         c-basic-offset
986       nil)))
987
988 (defun mdw-c-style ()
989   (c-add-style "[mdw] C and C++ style"
990                '((c-basic-offset . 2)
991                  (comment-column . 40)
992                  (c-class-key . "class")
993                  (c-backslash-column . 72)
994                  (c-offsets-alist
995                   (substatement-open . (add 0 c-indent-one-line-block))
996                   (defun-open . (add 0 c-indent-one-line-block))
997                   (arglist-cont-nonempty . mdw-c-lineup-arglist)
998                   (topmost-intro . mdw-c-indent-extern-mumble)
999                   (cpp-define-intro . 0)
1000                   (inextern-lang . [0])
1001                   (label . 0)
1002                   (case-label . +)
1003                   (access-label . -)
1004                   (inclass . +)
1005                   (inline-open . ++)
1006                   (statement-cont . 0)
1007                   (statement-case-intro . +)))
1008                t))
1009
1010 (defvar mdw-c-comment-fill-prefix
1011   `((,(concat "\\([ \t]*/?\\)"
1012               "\\(\*\\|//]\\)"
1013               "\\([ \t]*\\)"
1014               "\\([A-Za-z]+:[ \t]*\\)?"
1015               mdw-hanging-indents)
1016      (pad . 1) (match . 2) (pad . 3) (pad . 4) (pad . 5)))
1017   "Fill prefix matching C comments (both kinds).")
1018
1019 (defun mdw-fontify-c-and-c++ ()
1020
1021   ;; Fiddle with some syntax codes.
1022   (modify-syntax-entry ?* ". 23")
1023   (modify-syntax-entry ?/ ". 124b")
1024   (modify-syntax-entry ?\n "> b")
1025
1026   ;; Other stuff.
1027   (mdw-c-style)
1028   (setq c-hanging-comment-ender-p nil)
1029   (setq c-backslash-column 72)
1030   (setq c-label-minimum-indentation 0)
1031   (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
1032
1033   ;; Now define things to be fontified.
1034   (make-local-variable 'font-lock-keywords)
1035   (let ((c-keywords
1036          (mdw-regexps "and"             ;C++
1037                       "and_eq"          ;C++
1038                       "asm"             ;K&R, GCC
1039                       "auto"            ;K&R, C89
1040                       "bitand"          ;C++
1041                       "bitor"           ;C++
1042                       "bool"            ;C++, C9X macro
1043                       "break"           ;K&R, C89
1044                       "case"            ;K&R, C89
1045                       "catch"           ;C++
1046                       "char"            ;K&R, C89
1047                       "class"           ;C++
1048                       "complex"         ;C9X macro, C++ template type
1049                       "compl"           ;C++
1050                       "const"           ;C89
1051                       "const_cast"      ;C++
1052                       "continue"        ;K&R, C89
1053                       "defined"         ;C89 preprocessor
1054                       "default"         ;K&R, C89
1055                       "delete"          ;C++
1056                       "do"              ;K&R, C89
1057                       "double"          ;K&R, C89
1058                       "dynamic_cast"    ;C++
1059                       "else"            ;K&R, C89
1060                       ;; "entry"        ;K&R -- never used
1061                       "enum"            ;C89
1062                       "explicit"        ;C++
1063                       "export"          ;C++
1064                       "extern"          ;K&R, C89
1065                       "false"           ;C++, C9X macro
1066                       "float"           ;K&R, C89
1067                       "for"             ;K&R, C89
1068                       ;; "fortran"      ;K&R
1069                       "friend"          ;C++
1070                       "goto"            ;K&R, C89
1071                       "if"              ;K&R, C89
1072                       "imaginary"       ;C9X macro
1073                       "inline"          ;C++, C9X, GCC
1074                       "int"             ;K&R, C89
1075                       "long"            ;K&R, C89
1076                       "mutable"         ;C++
1077                       "namespace"       ;C++
1078                       "new"             ;C++
1079                       "operator"        ;C++
1080                       "or"              ;C++
1081                       "or_eq"           ;C++
1082                       "private"         ;C++
1083                       "protected"       ;C++
1084                       "public"          ;C++
1085                       "register"        ;K&R, C89
1086                       "reinterpret_cast" ;C++
1087                       "restrict"         ;C9X
1088                       "return"           ;K&R, C89
1089                       "short"            ;K&R, C89
1090                       "signed"           ;C89
1091                       "sizeof"           ;K&R, C89
1092                       "static"           ;K&R, C89
1093                       "static_cast"      ;C++
1094                       "struct"           ;K&R, C89
1095                       "switch"           ;K&R, C89
1096                       "template"         ;C++
1097                       "this"             ;C++
1098                       "throw"            ;C++
1099                       "true"             ;C++, C9X macro
1100                       "try"              ;C++
1101                       "this"             ;C++
1102                       "typedef"          ;C89
1103                       "typeid"           ;C++
1104                       "typeof"           ;GCC
1105                       "typename"         ;C++
1106                       "union"            ;K&R, C89
1107                       "unsigned"         ;K&R, C89
1108                       "using"            ;C++
1109                       "virtual"          ;C++
1110                       "void"             ;C89
1111                       "volatile"         ;C89
1112                       "wchar_t"          ;C++, C89 library type
1113                       "while"            ;K&R, C89
1114                       "xor"              ;C++
1115                       "xor_eq"           ;C++
1116                       "_Bool"            ;C9X
1117                       "_Complex"         ;C9X
1118                       "_Imaginary"       ;C9X
1119                       "_Pragma"          ;C9X preprocessor
1120                       "__alignof__"      ;GCC
1121                       "__asm__"          ;GCC
1122                       "__attribute__"    ;GCC
1123                       "__complex__"      ;GCC
1124                       "__const__"        ;GCC
1125                       "__extension__"    ;GCC
1126                       "__imag__"         ;GCC
1127                       "__inline__"       ;GCC
1128                       "__label__"        ;GCC
1129                       "__real__"         ;GCC
1130                       "__signed__"       ;GCC
1131                       "__typeof__"       ;GCC
1132                       "__volatile__"     ;GCC
1133                       ))
1134         (preprocessor-keywords
1135          (mdw-regexps "assert" "define" "elif" "else" "endif" "error"
1136                       "ident" "if" "ifdef" "ifndef" "import" "include"
1137                       "line" "pragma" "unassert" "undef" "warning"))
1138         (objc-keywords
1139          (mdw-regexps "class" "defs" "encode" "end" "implementation"
1140                       "interface" "private" "protected" "protocol" "public"
1141                       "selector")))
1142
1143     (setq font-lock-keywords
1144           (list
1145
1146            ;; Fontify include files as strings.
1147            (list (concat "^[ \t]*\\#[ \t]*"
1148                          "\\(include\\|import\\)"
1149                          "[ \t]*\\(<[^>]+\\(>\\|\\)\\)")
1150                  '(2 font-lock-string-face))
1151
1152            ;; Preprocessor directives are `references'?.
1153            (list (concat "^\\([ \t]*#[ \t]*\\(\\("
1154                          preprocessor-keywords
1155                          "\\)\\>\\|[0-9]+\\|$\\)\\)")
1156                  '(1 font-lock-keyword-face))
1157
1158            ;; Handle the keywords defined above.
1159            (list (concat "@\\<\\(" objc-keywords "\\)\\>")
1160                  '(0 font-lock-keyword-face))
1161
1162            (list (concat "\\<\\(" c-keywords "\\)\\>")
1163                  '(0 font-lock-keyword-face))
1164
1165            ;; Handle numbers too.
1166            ;;
1167            ;; This looks strange, I know.  It corresponds to the
1168            ;; preprocessor's idea of what a number looks like, rather than
1169            ;; anything sensible.
1170            (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
1171                          "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
1172                  '(0 mdw-number-face))
1173
1174            ;; And anything else is punctuation.
1175            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1176                  '(0 mdw-punct-face))))
1177
1178     (mdw-post-config-mode-hack)))
1179
1180 ;;;--------------------------------------------------------------------------
1181 ;;; AP calc mode.
1182
1183 (defun apcalc-mode ()
1184   (interactive)
1185   (c-mode)
1186   (setq major-mode 'apcalc-mode)
1187   (setq mode-name "AP Calc")
1188   (run-hooks 'apcalc-mode-hook))
1189
1190 (defun mdw-fontify-apcalc ()
1191
1192   ;; Fiddle with some syntax codes.
1193   (modify-syntax-entry ?* ". 23")
1194   (modify-syntax-entry ?/ ". 14")
1195
1196   ;; Other stuff.
1197   (mdw-c-style)
1198   (setq c-hanging-comment-ender-p nil)
1199   (setq c-backslash-column 72)
1200   (setq comment-start "/* ")
1201   (setq comment-end " */")
1202   (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
1203
1204   ;; Now define things to be fontified.
1205   (make-local-variable 'font-lock-keywords)
1206   (let ((c-keywords
1207          (mdw-regexps "break" "case" "cd" "continue" "define" "default"
1208                       "do" "else" "exit" "for" "global" "goto" "help" "if"
1209                       "local" "mat" "obj" "print" "quit" "read" "return"
1210                       "show" "static" "switch" "while" "write")))
1211
1212     (setq font-lock-keywords
1213           (list
1214
1215            ;; Handle the keywords defined above.
1216            (list (concat "\\<\\(" c-keywords "\\)\\>")
1217                  '(0 font-lock-keyword-face))
1218
1219            ;; Handle numbers too.
1220            ;;
1221            ;; This looks strange, I know.  It corresponds to the
1222            ;; preprocessor's idea of what a number looks like, rather than
1223            ;; anything sensible.
1224            (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
1225                          "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
1226                  '(0 mdw-number-face))
1227
1228            ;; And anything else is punctuation.
1229            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1230                  '(0 mdw-punct-face)))))
1231
1232   (mdw-post-config-mode-hack))
1233
1234 ;;;--------------------------------------------------------------------------
1235 ;;; Java programming configuration.
1236
1237 ;; Make indentation nice.
1238
1239 (defun mdw-java-style ()
1240   (c-add-style "[mdw] Java style"
1241                '((c-basic-offset . 2)
1242                  (c-offsets-alist (substatement-open . 0)
1243                                   (label . +)
1244                                   (case-label . +)
1245                                   (access-label . 0)
1246                                   (inclass . +)
1247                                   (statement-case-intro . +)))
1248                t))
1249
1250 ;; Declare Java fontification style.
1251
1252 (defun mdw-fontify-java ()
1253
1254   ;; Other stuff.
1255   (mdw-java-style)
1256   (setq c-hanging-comment-ender-p nil)
1257   (setq c-backslash-column 72)
1258   (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
1259
1260   ;; Now define things to be fontified.
1261   (make-local-variable 'font-lock-keywords)
1262   (let ((java-keywords
1263          (mdw-regexps "abstract" "boolean" "break" "byte" "case" "catch"
1264                       "char" "class" "const" "continue" "default" "do"
1265                       "double" "else" "extends" "final" "finally" "float"
1266                       "for" "goto" "if" "implements" "import" "instanceof"
1267                       "int" "interface" "long" "native" "new" "package"
1268                       "private" "protected" "public" "return" "short"
1269                       "static" "super" "switch" "synchronized" "this"
1270                       "throw" "throws" "transient" "try" "void" "volatile"
1271                       "while"
1272
1273                       "false" "null" "true")))
1274
1275     (setq font-lock-keywords
1276           (list
1277
1278            ;; Handle the keywords defined above.
1279            (list (concat "\\<\\(" java-keywords "\\)\\>")
1280                  '(0 font-lock-keyword-face))
1281
1282            ;; Handle numbers too.
1283            ;;
1284            ;; The following isn't quite right, but it's close enough.
1285            (list (concat "\\<\\("
1286                          "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1287                          "[0-9]+\\(\\.[0-9]*\\|\\)"
1288                          "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
1289                          "[lLfFdD]?")
1290                  '(0 mdw-number-face))
1291
1292            ;; And anything else is punctuation.
1293            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1294                  '(0 mdw-punct-face)))))
1295
1296   (mdw-post-config-mode-hack))
1297
1298 ;;;--------------------------------------------------------------------------
1299 ;;; C# programming configuration.
1300
1301 ;; Make indentation nice.
1302
1303 (defun mdw-csharp-style ()
1304   (c-add-style "[mdw] C# style"
1305                '((c-basic-offset . 2)
1306                  (c-offsets-alist (substatement-open . 0)
1307                                   (label . 0)
1308                                   (case-label . +)
1309                                   (access-label . 0)
1310                                   (inclass . +)
1311                                   (statement-case-intro . +)))
1312                t))
1313
1314 ;; Declare C# fontification style.
1315
1316 (defun mdw-fontify-csharp ()
1317
1318   ;; Other stuff.
1319   (mdw-csharp-style)
1320   (setq c-hanging-comment-ender-p nil)
1321   (setq c-backslash-column 72)
1322   (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
1323
1324   ;; Now define things to be fontified.
1325   (make-local-variable 'font-lock-keywords)
1326   (let ((csharp-keywords
1327          (mdw-regexps "abstract" "as" "base" "bool" "break"
1328                       "byte" "case" "catch" "char" "checked"
1329                       "class" "const" "continue" "decimal" "default"
1330                       "delegate" "do" "double" "else" "enum"
1331                       "event" "explicit" "extern" "false" "finally"
1332                       "fixed" "float" "for" "foreach" "goto"
1333                       "if" "implicit" "in" "int" "interface"
1334                       "internal" "is" "lock" "long" "namespace"
1335                       "new" "null" "object" "operator" "out"
1336                       "override" "params" "private" "protected" "public"
1337                       "readonly" "ref" "return" "sbyte" "sealed"
1338                       "short" "sizeof" "stackalloc" "static" "string"
1339                       "struct" "switch" "this" "throw" "true"
1340                       "try" "typeof" "uint" "ulong" "unchecked"
1341                       "unsafe" "ushort" "using" "virtual" "void"
1342                       "volatile" "while" "yield")))
1343
1344     (setq font-lock-keywords
1345           (list
1346
1347            ;; Handle the keywords defined above.
1348            (list (concat "\\<\\(" csharp-keywords "\\)\\>")
1349                  '(0 font-lock-keyword-face))
1350
1351            ;; Handle numbers too.
1352            ;;
1353            ;; The following isn't quite right, but it's close enough.
1354            (list (concat "\\<\\("
1355                          "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1356                          "[0-9]+\\(\\.[0-9]*\\|\\)"
1357                          "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
1358                          "[lLfFdD]?")
1359                  '(0 mdw-number-face))
1360
1361            ;; And anything else is punctuation.
1362            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1363                  '(0 mdw-punct-face)))))
1364
1365   (mdw-post-config-mode-hack))
1366
1367 (define-derived-mode csharp-mode java-mode "C#"
1368   "Major mode for editing C# code.")
1369
1370 ;;;--------------------------------------------------------------------------
1371 ;;; Go programming configuration.
1372
1373 (defun mdw-fontify-go ()
1374
1375   (make-local-variable 'font-lock-keywords)
1376   (let ((go-keywords
1377          (mdw-regexps "break" "case" "chan" "const" "continue"
1378                       "default" "defer" "else" "fallthrough" "for"
1379                       "func" "go" "goto" "if" "import"
1380                       "interface" "map" "package" "range" "return"
1381                       "select" "struct" "switch" "type" "var")))
1382
1383     (setq font-lock-keywords
1384           (list
1385
1386            ;; Handle the keywords defined above.
1387            (list (concat "\\<\\(" go-keywords "\\)\\>")
1388                  '(0 font-lock-keyword-face))
1389
1390            ;; Handle numbers too.
1391            ;;
1392            ;; The following isn't quite right, but it's close enough.
1393            (list (concat "\\<\\("
1394                          "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1395                          "[0-9]+\\(\\.[0-9]*\\|\\)"
1396                          "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)")
1397                  '(0 mdw-number-face))
1398
1399            ;; And anything else is punctuation.
1400            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1401                  '(0 mdw-punct-face)))))
1402
1403   (mdw-post-config-mode-hack))
1404
1405 ;;;--------------------------------------------------------------------------
1406 ;;; Awk programming configuration.
1407
1408 ;; Make Awk indentation nice.
1409
1410 (defun mdw-awk-style ()
1411   (c-add-style "[mdw] Awk style"
1412                '((c-basic-offset . 2)
1413                  (c-offsets-alist (substatement-open . 0)
1414                                   (statement-cont . 0)
1415                                   (statement-case-intro . +)))
1416                t))
1417
1418 ;; Declare Awk fontification style.
1419
1420 (defun mdw-fontify-awk ()
1421
1422   ;; Miscellaneous fiddling.
1423   (mdw-awk-style)
1424   (setq c-backslash-column 72)
1425   (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
1426
1427   ;; Now define things to be fontified.
1428   (make-local-variable 'font-lock-keywords)
1429   (let ((c-keywords
1430          (mdw-regexps "BEGIN" "END" "ARGC" "ARGIND" "ARGV" "CONVFMT"
1431                       "ENVIRON" "ERRNO" "FIELDWIDTHS" "FILENAME" "FNR"
1432                       "FS" "IGNORECASE" "NF" "NR" "OFMT" "OFS" "ORS" "RS"
1433                       "RSTART" "RLENGTH" "RT"   "SUBSEP"
1434                       "atan2" "break" "close" "continue" "cos" "delete"
1435                       "do" "else" "exit" "exp" "fflush" "file" "for" "func"
1436                       "function" "gensub" "getline" "gsub" "if" "in"
1437                       "index" "int" "length" "log" "match" "next" "rand"
1438                       "return" "print" "printf" "sin" "split" "sprintf"
1439                       "sqrt" "srand" "strftime" "sub" "substr" "system"
1440                       "systime" "tolower" "toupper" "while")))
1441
1442     (setq font-lock-keywords
1443           (list
1444
1445            ;; Handle the keywords defined above.
1446            (list (concat "\\<\\(" c-keywords "\\)\\>")
1447                  '(0 font-lock-keyword-face))
1448
1449            ;; Handle numbers too.
1450            ;;
1451            ;; The following isn't quite right, but it's close enough.
1452            (list (concat "\\<\\("
1453                          "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1454                          "[0-9]+\\(\\.[0-9]*\\|\\)"
1455                          "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
1456                          "[uUlL]*")
1457                  '(0 mdw-number-face))
1458
1459            ;; And anything else is punctuation.
1460            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1461                  '(0 mdw-punct-face)))))
1462
1463   (mdw-post-config-mode-hack))
1464
1465 ;;;--------------------------------------------------------------------------
1466 ;;; Perl programming style.
1467
1468 ;; Perl indentation style.
1469
1470 (setq cperl-indent-level 2)
1471 (setq cperl-continued-statement-offset 2)
1472 (setq cperl-continued-brace-offset 0)
1473 (setq cperl-brace-offset -2)
1474 (setq cperl-brace-imaginary-offset 0)
1475 (setq cperl-label-offset 0)
1476
1477 ;; Define perl fontification style.
1478
1479 (defun mdw-fontify-perl ()
1480
1481   ;; Miscellaneous fiddling.
1482   (modify-syntax-entry ?$ "\\")
1483   (modify-syntax-entry ?$ "\\" font-lock-syntax-table)
1484   (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
1485
1486   ;; Now define fontification things.
1487   (make-local-variable 'font-lock-keywords)
1488   (let ((perl-keywords
1489          (mdw-regexps "and" "cmp" "continue" "do" "else" "elsif" "eq"
1490                       "for" "foreach" "ge" "gt" "goto" "if"
1491                       "last" "le" "lt" "local" "my" "ne" "next" "or"
1492                       "package" "redo" "require" "return" "sub"
1493                       "undef" "unless" "until" "use" "while")))
1494
1495     (setq font-lock-keywords
1496           (list
1497
1498            ;; Set up the keywords defined above.
1499            (list (concat "\\<\\(" perl-keywords "\\)\\>")
1500                  '(0 font-lock-keyword-face))
1501
1502            ;; At least numbers are simpler than C.
1503            (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
1504                          "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
1505                          "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
1506                  '(0 mdw-number-face))
1507
1508            ;; And anything else is punctuation.
1509            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1510                  '(0 mdw-punct-face)))))
1511
1512   (mdw-post-config-mode-hack))
1513
1514 (defun perl-number-tests (&optional arg)
1515   "Assign consecutive numbers to lines containing `#t'.  With ARG,
1516 strip numbers instead."
1517   (interactive "P")
1518   (save-excursion
1519     (goto-char (point-min))
1520     (let ((i 0) (fmt (if arg "" " %4d")))
1521       (while (search-forward "#t" nil t)
1522         (delete-region (point) (line-end-position))
1523         (setq i (1+ i))
1524         (insert (format fmt i)))
1525       (goto-char (point-min))
1526       (if (re-search-forward "\\(tests\\s-*=>\\s-*\\)\\w*" nil t)
1527           (replace-match (format "\\1%d" i))))))
1528
1529 ;;;--------------------------------------------------------------------------
1530 ;;; Python programming style.
1531
1532 (defun mdw-fontify-pythonic (keywords)
1533
1534   ;; Miscellaneous fiddling.
1535   (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
1536   (setq indent-tabs-mode nil)
1537
1538   ;; Now define fontification things.
1539   (make-local-variable 'font-lock-keywords)
1540   (setq font-lock-keywords
1541         (list
1542
1543          ;; Set up the keywords defined above.
1544          (list (concat "\\<\\(" keywords "\\)\\>")
1545                '(0 font-lock-keyword-face))
1546
1547          ;; At least numbers are simpler than C.
1548          (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
1549                        "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
1550                        "\\([eE]\\([-+]\\|\\)[0-9_]+\\|[lL]\\|\\)")
1551                '(0 mdw-number-face))
1552
1553          ;; And anything else is punctuation.
1554          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1555                '(0 mdw-punct-face))))
1556
1557   (mdw-post-config-mode-hack))
1558
1559 ;; Define Python fontification styles.
1560
1561 (defun mdw-fontify-python ()
1562   (mdw-fontify-pythonic
1563    (mdw-regexps "and" "as" "assert" "break" "class" "continue" "def"
1564                 "del" "elif" "else" "except" "exec" "finally" "for"
1565                 "from" "global" "if" "import" "in" "is" "lambda"
1566                 "not" "or" "pass" "print" "raise" "return" "try"
1567                 "while" "with" "yield")))
1568
1569 (defun mdw-fontify-pyrex ()
1570   (mdw-fontify-pythonic
1571    (mdw-regexps "and" "as" "assert" "break" "cdef" "class" "continue"
1572                 "ctypedef" "def" "del" "elif" "else" "except" "exec"
1573                 "extern" "finally" "for" "from" "global" "if"
1574                 "import" "in" "is" "lambda" "not" "or" "pass" "print"
1575                 "raise" "return" "struct" "try" "while" "with"
1576                 "yield")))
1577
1578 ;;;--------------------------------------------------------------------------
1579 ;;; Icon programming style.
1580
1581 ;; Icon indentation style.
1582
1583 (setq icon-brace-offset 0
1584       icon-continued-brace-offset 0
1585       icon-continued-statement-offset 2
1586       icon-indent-level 2)
1587
1588 ;; Define Icon fontification style.
1589
1590 (defun mdw-fontify-icon ()
1591
1592   ;; Miscellaneous fiddling.
1593   (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
1594
1595   ;; Now define fontification things.
1596   (make-local-variable 'font-lock-keywords)
1597   (let ((icon-keywords
1598          (mdw-regexps "break" "by" "case" "create" "default" "do" "else"
1599                       "end" "every" "fail" "global" "if" "initial"
1600                       "invocable" "link" "local" "next" "not" "of"
1601                       "procedure" "record" "repeat" "return" "static"
1602                       "suspend" "then" "to" "until" "while"))
1603         (preprocessor-keywords
1604          (mdw-regexps "define" "else" "endif" "error" "ifdef" "ifndef"
1605                       "include" "line" "undef")))
1606     (setq font-lock-keywords
1607           (list
1608
1609            ;; Set up the keywords defined above.
1610            (list (concat "\\<\\(" icon-keywords "\\)\\>")
1611                  '(0 font-lock-keyword-face))
1612
1613            ;; The things that Icon calls keywords.
1614            (list "&\\sw+\\>" '(0 font-lock-variable-name-face))
1615
1616            ;; At least numbers are simpler than C.
1617            (list (concat "\\<[0-9]+"
1618                          "\\([rR][0-9a-zA-Z]+\\|"
1619                          "\\.[0-9]+\\([eE][+-]?[0-9]+\\)?\\)\\>\\|"
1620                          "\\.[0-9]+\\([eE][+-]?[0-9]+\\)?\\>")
1621                  '(0 mdw-number-face))
1622
1623            ;; Preprocessor.
1624            (list (concat "^[ \t]*$[ \t]*\\<\\("
1625                          preprocessor-keywords
1626                          "\\)\\>")
1627                  '(0 font-lock-keyword-face))
1628
1629            ;; And anything else is punctuation.
1630            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1631                  '(0 mdw-punct-face)))))
1632
1633   (mdw-post-config-mode-hack))
1634
1635 ;;;--------------------------------------------------------------------------
1636 ;;; ARM assembler programming configuration.
1637
1638 ;; There doesn't appear to be an Emacs mode for this yet.
1639 ;;
1640 ;; Better do something about that, I suppose.
1641
1642 (defvar arm-assembler-mode-map nil)
1643 (defvar arm-assembler-abbrev-table nil)
1644 (defvar arm-assembler-mode-syntax-table (make-syntax-table))
1645
1646 (or arm-assembler-mode-map
1647     (progn
1648       (setq arm-assembler-mode-map (make-sparse-keymap))
1649       (define-key arm-assembler-mode-map "\C-m" 'arm-assembler-newline)
1650       (define-key arm-assembler-mode-map [C-return] 'newline)
1651       (define-key arm-assembler-mode-map "\t" 'tab-to-tab-stop)))
1652
1653 (defun arm-assembler-mode ()
1654   "Major mode for ARM assembler programs"
1655   (interactive)
1656
1657   ;; Do standard major mode things.
1658   (kill-all-local-variables)
1659   (use-local-map arm-assembler-mode-map)
1660   (setq local-abbrev-table arm-assembler-abbrev-table)
1661   (setq major-mode 'arm-assembler-mode)
1662   (setq mode-name "ARM assembler")
1663
1664   ;; Set up syntax table.
1665   (set-syntax-table arm-assembler-mode-syntax-table)
1666   (modify-syntax-entry ?;   ; Nasty hack
1667                        "<" arm-assembler-mode-syntax-table)
1668   (modify-syntax-entry ?\n ">" arm-assembler-mode-syntax-table)
1669   (modify-syntax-entry ?_ "_" arm-assembler-mode-syntax-table)
1670
1671   (make-local-variable 'comment-start)
1672   (setq comment-start ";")
1673   (make-local-variable 'comment-end)
1674   (setq comment-end "")
1675   (make-local-variable 'comment-column)
1676   (setq comment-column 48)
1677   (make-local-variable 'comment-start-skip)
1678   (setq comment-start-skip ";+[ \t]*")
1679
1680   ;; Play with indentation.
1681   (make-local-variable 'indent-line-function)
1682   (setq indent-line-function 'indent-relative-maybe)
1683
1684   ;; Set fill prefix.
1685   (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)")
1686
1687   ;; Fiddle with fontification.
1688   (make-local-variable 'font-lock-keywords)
1689   (setq font-lock-keywords
1690         (list
1691
1692          ;; Handle numbers too.
1693          ;;
1694          ;; The following isn't quite right, but it's close enough.
1695          (list (concat "\\("
1696                        "&[0-9a-fA-F]+\\|"
1697                        "\\<[0-9]+\\(\\.[0-9]*\\|_[0-9a-zA-Z]+\\|\\)"
1698                        "\\)")
1699                '(0 mdw-number-face))
1700
1701          ;; Do something about operators.
1702          (list "^[^ \t]*[ \t]+\\(GET\\|LNK\\)[ \t]+\\([^;\n]*\\)"
1703                '(1 font-lock-keyword-face)
1704                '(2 font-lock-string-face))
1705          (list ":[a-zA-Z]+:"
1706                '(0 font-lock-keyword-face))
1707
1708          ;; Do menemonics and directives.
1709          (list "^[^ \t]*[ \t]+\\([a-zA-Z]+\\)"
1710                '(1 font-lock-keyword-face))
1711
1712          ;; And anything else is punctuation.
1713          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1714                '(0 mdw-punct-face)))
1715
1716   (mdw-post-config-mode-hack))
1717   (run-hooks 'arm-assembler-mode-hook))
1718
1719 ;;;--------------------------------------------------------------------------
1720 ;;; Assembler mode.
1721
1722 (defun mdw-fontify-asm ()
1723   (modify-syntax-entry ?' "\"")
1724   (modify-syntax-entry ?. "w")
1725   (setf fill-prefix nil)
1726   (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)"))
1727
1728 ;;;--------------------------------------------------------------------------
1729 ;;; TCL configuration.
1730
1731 (defun mdw-fontify-tcl ()
1732   (mapcar #'(lambda (ch) (modify-syntax-entry ch ".")) '(?$))
1733   (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
1734   (make-local-variable 'font-lock-keywords)
1735   (setq font-lock-keywords
1736         (list
1737          (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
1738                        "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
1739                        "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
1740                '(0 mdw-number-face))
1741          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1742                '(0 mdw-punct-face))))
1743   (mdw-post-config-mode-hack))
1744
1745 ;;;--------------------------------------------------------------------------
1746 ;;; REXX configuration.
1747
1748 (defun mdw-rexx-electric-* ()
1749   (interactive)
1750   (insert ?*)
1751   (rexx-indent-line))
1752
1753 (defun mdw-rexx-indent-newline-indent ()
1754   (interactive)
1755   (rexx-indent-line)
1756   (if abbrev-mode (expand-abbrev))
1757   (newline-and-indent))
1758
1759 (defun mdw-fontify-rexx ()
1760
1761   ;; Various bits of fiddling.
1762   (setq mdw-auto-indent nil)
1763   (local-set-key [?\C-m] 'mdw-rexx-indent-newline-indent)
1764   (local-set-key [?*] 'mdw-rexx-electric-*)
1765   (mapcar #'(lambda (ch) (modify-syntax-entry ch "w"))
1766           '(?! ?? ?# ?@ ?$))
1767   (mdw-standard-fill-prefix "\\([ \t]*/?\*[ \t]*\\)")
1768
1769   ;; Set up keywords and things for fontification.
1770   (make-local-variable 'font-lock-keywords-case-fold-search)
1771   (setq font-lock-keywords-case-fold-search t)
1772
1773   (setq rexx-indent 2)
1774   (setq rexx-end-indent rexx-indent)
1775   (setq rexx-cont-indent rexx-indent)
1776
1777   (make-local-variable 'font-lock-keywords)
1778   (let ((rexx-keywords
1779          (mdw-regexps "address" "arg" "by" "call" "digits" "do" "drop"
1780                       "else" "end" "engineering" "exit" "expose" "for"
1781                       "forever" "form" "fuzz" "if" "interpret" "iterate"
1782                       "leave" "linein" "name" "nop" "numeric" "off" "on"
1783                       "options" "otherwise" "parse" "procedure" "pull"
1784                       "push" "queue" "return" "say" "select" "signal"
1785                       "scientific" "source" "then" "trace" "to" "until"
1786                       "upper" "value" "var" "version" "when" "while"
1787                       "with"
1788
1789                       "abbrev" "abs" "bitand" "bitor" "bitxor" "b2x"
1790                       "center" "center" "charin" "charout" "chars"
1791                       "compare" "condition" "copies" "c2d" "c2x"
1792                       "datatype" "date" "delstr" "delword" "d2c" "d2x"
1793                       "errortext" "format" "fuzz" "insert" "lastpos"
1794                       "left" "length" "lineout" "lines" "max" "min"
1795                       "overlay" "pos" "queued" "random" "reverse" "right"
1796                       "sign" "sourceline" "space" "stream" "strip"
1797                       "substr" "subword" "symbol" "time" "translate"
1798                       "trunc" "value" "verify" "word" "wordindex"
1799                       "wordlength" "wordpos" "words" "xrange" "x2b" "x2c"
1800                       "x2d")))
1801
1802     (setq font-lock-keywords
1803           (list
1804
1805            ;; Set up the keywords defined above.
1806            (list (concat "\\<\\(" rexx-keywords "\\)\\>")
1807                  '(0 font-lock-keyword-face))
1808
1809            ;; Fontify all symbols the same way.
1810            (list (concat "\\<\\([0-9.][A-Za-z0-9.!?_#@$]*[Ee][+-]?[0-9]+\\|"
1811                          "[A-Za-z0-9.!?_#@$]+\\)")
1812                  '(0 font-lock-variable-name-face))
1813
1814            ;; And everything else is punctuation.
1815            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1816                  '(0 mdw-punct-face)))))
1817
1818   (mdw-post-config-mode-hack))
1819
1820 ;;;--------------------------------------------------------------------------
1821 ;;; Standard ML programming style.
1822
1823 (defun mdw-fontify-sml ()
1824
1825   ;; Make underscore an honorary letter.
1826   (modify-syntax-entry ?' "w")
1827
1828   ;; Set fill prefix.
1829   (mdw-standard-fill-prefix "\\([ \t]*(\*[ \t]*\\)")
1830
1831   ;; Now define fontification things.
1832   (make-local-variable 'font-lock-keywords)
1833   (let ((sml-keywords
1834          (mdw-regexps "abstype" "and" "andalso" "as"
1835                       "case"
1836                       "datatype" "do"
1837                       "else" "end" "eqtype" "exception"
1838                       "fn" "fun" "functor"
1839                       "handle"
1840                       "if" "in" "include" "infix" "infixr"
1841                       "let" "local"
1842                       "nonfix"
1843                       "of" "op" "open" "orelse"
1844                       "raise" "rec"
1845                       "sharing" "sig" "signature" "struct" "structure"
1846                       "then" "type"
1847                       "val"
1848                       "where" "while" "with" "withtype")))
1849
1850     (setq font-lock-keywords
1851           (list
1852
1853            ;; Set up the keywords defined above.
1854            (list (concat "\\<\\(" sml-keywords "\\)\\>")
1855                  '(0 font-lock-keyword-face))
1856
1857            ;; At least numbers are simpler than C.
1858            (list (concat "\\<\\(\\~\\|\\)"
1859                             "\\(0\\(\\([wW]\\|\\)[xX][0-9a-fA-F]+\\|"
1860                                    "[wW][0-9]+\\)\\|"
1861                                 "\\([0-9]+\\(\\.[0-9]+\\|\\)"
1862                                          "\\([eE]\\(\\~\\|\\)"
1863                                                 "[0-9]+\\|\\)\\)\\)")
1864                  '(0 mdw-number-face))
1865
1866            ;; And anything else is punctuation.
1867            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1868                  '(0 mdw-punct-face)))))
1869
1870   (mdw-post-config-mode-hack))
1871
1872 ;;;--------------------------------------------------------------------------
1873 ;;; Haskell configuration.
1874
1875 (defun mdw-fontify-haskell ()
1876
1877   ;; Fiddle with syntax table to get comments right.
1878   (modify-syntax-entry ?' "\"")
1879   (modify-syntax-entry ?- ". 123")
1880   (modify-syntax-entry ?{ ". 1b")
1881   (modify-syntax-entry ?} ". 4b")
1882   (modify-syntax-entry ?\n ">")
1883
1884   ;; Set fill prefix.
1885   (mdw-standard-fill-prefix "\\([ \t]*{?--?[ \t]*\\)")
1886
1887   ;; Fiddle with fontification.
1888   (make-local-variable 'font-lock-keywords)
1889   (let ((haskell-keywords
1890          (mdw-regexps "as" "case" "ccall" "class" "data" "default"
1891                       "deriving" "do" "else" "foreign" "hiding" "if"
1892                       "import" "in" "infix" "infixl" "infixr" "instance"
1893                       "let" "module" "newtype" "of" "qualified" "safe"
1894                       "stdcall" "then" "type" "unsafe" "where")))
1895
1896     (setq font-lock-keywords
1897           (list
1898            (list "--.*$"
1899                  '(0 font-lock-comment-face))
1900            (list (concat "\\<\\(" haskell-keywords "\\)\\>")
1901                  '(0 font-lock-keyword-face))
1902            (list (concat "\\<0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1903                          "\\<[0-9][0-9_]*\\(\\.[0-9]*\\|\\)"
1904                          "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)")
1905                  '(0 mdw-number-face))
1906            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1907                  '(0 mdw-punct-face)))))
1908
1909   (mdw-post-config-mode-hack))
1910
1911 ;;;--------------------------------------------------------------------------
1912 ;;; Erlang configuration.
1913
1914 (setq erlang-electric-commannds
1915       '(erlang-electric-newline erlang-electric-semicolon))
1916
1917 (defun mdw-fontify-erlang ()
1918
1919   ;; Set fill prefix.
1920   (mdw-standard-fill-prefix "\\([ \t]*{?%*[ \t]*\\)")
1921
1922   ;; Fiddle with fontification.
1923   (make-local-variable 'font-lock-keywords)
1924   (let ((erlang-keywords
1925          (mdw-regexps "after" "and" "andalso"
1926                       "band" "begin" "bnot" "bor" "bsl" "bsr" "bxor"
1927                       "case" "catch" "cond"
1928                       "div" "end" "fun" "if" "let" "not"
1929                       "of" "or" "orelse"
1930                       "query" "receive" "rem" "try" "when" "xor")))
1931
1932     (setq font-lock-keywords
1933           (list
1934            (list "%.*$"
1935                  '(0 font-lock-comment-face))
1936            (list (concat "\\<\\(" erlang-keywords "\\)\\>")
1937                  '(0 font-lock-keyword-face))
1938            (list (concat "^-\\sw+\\>")
1939                  '(0 font-lock-keyword-face))
1940            (list "\\<[0-9]+\\(\\|#[0-9a-zA-Z]+\\|[eE][+-]?[0-9]+\\)\\>"
1941                  '(0 mdw-number-face))
1942            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1943                  '(0 mdw-punct-face)))))
1944
1945   (mdw-post-config-mode-hack))
1946
1947 ;;;--------------------------------------------------------------------------
1948 ;;; Texinfo configuration.
1949
1950 (defun mdw-fontify-texinfo ()
1951
1952   ;; Set fill prefix.
1953   (mdw-standard-fill-prefix "\\([ \t]*@c[ \t]+\\)")
1954
1955   ;; Real fontification things.
1956   (make-local-variable 'font-lock-keywords)
1957   (setq font-lock-keywords
1958         (list
1959
1960          ;; Environment names are keywords.
1961          (list "@\\(end\\)  *\\([a-zA-Z]*\\)?"
1962                '(2 font-lock-keyword-face))
1963
1964          ;; Unmark escaped magic characters.
1965          (list "\\(@\\)\\([@{}]\\)"
1966                '(1 font-lock-keyword-face)
1967                '(2 font-lock-variable-name-face))
1968
1969          ;; Make sure we get comments properly.
1970          (list "@c\\(\\|omment\\)\\( .*\\)?$"
1971                '(0 font-lock-comment-face))
1972
1973          ;; Command names are keywords.
1974          (list "@\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
1975                '(0 font-lock-keyword-face))
1976
1977          ;; Fontify TeX special characters as punctuation.
1978          (list "[{}]+"
1979                '(0 mdw-punct-face))))
1980
1981   (mdw-post-config-mode-hack))
1982
1983 ;;;--------------------------------------------------------------------------
1984 ;;; TeX and LaTeX configuration.
1985
1986 (defun mdw-fontify-tex ()
1987   (setq ispell-parser 'tex)
1988   (turn-on-reftex)
1989
1990   ;; Don't make maths into a string.
1991   (modify-syntax-entry ?$ ".")
1992   (modify-syntax-entry ?$ "." font-lock-syntax-table)
1993   (local-set-key [?$] 'self-insert-command)
1994
1995   ;; Set fill prefix.
1996   (mdw-standard-fill-prefix "\\([ \t]*%+[ \t]*\\)")
1997
1998   ;; Real fontification things.
1999   (make-local-variable 'font-lock-keywords)
2000   (setq font-lock-keywords
2001         (list
2002
2003          ;; Environment names are keywords.
2004          (list (concat "\\\\\\(begin\\|end\\|newenvironment\\)"
2005                        "{\\([^}\n]*\\)}")
2006                '(2 font-lock-keyword-face))
2007
2008          ;; Suspended environment names are keywords too.
2009          (list (concat "\\\\\\(suspend\\|resume\\)\\(\\[[^]]*\\]\\)?"
2010                        "{\\([^}\n]*\\)}")
2011                '(3 font-lock-keyword-face))
2012
2013          ;; Command names are keywords.
2014          (list "\\\\\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
2015                '(0 font-lock-keyword-face))
2016
2017          ;; Handle @/.../ for italics.
2018          ;; (list "\\(@/\\)\\([^/]*\\)\\(/\\)"
2019          ;;       '(1 font-lock-keyword-face)
2020          ;;       '(3 font-lock-keyword-face))
2021
2022          ;; Handle @*...* for boldness.
2023          ;; (list "\\(@\\*\\)\\([^*]*\\)\\(\\*\\)"
2024          ;;       '(1 font-lock-keyword-face)
2025          ;;       '(3 font-lock-keyword-face))
2026
2027          ;; Handle @`...' for literal syntax things.
2028          ;; (list "\\(@`\\)\\([^']*\\)\\('\\)"
2029          ;;       '(1 font-lock-keyword-face)
2030          ;;       '(3 font-lock-keyword-face))
2031
2032          ;; Handle @<...> for nonterminals.
2033          ;; (list "\\(@<\\)\\([^>]*\\)\\(>\\)"
2034          ;;       '(1 font-lock-keyword-face)
2035          ;;       '(3 font-lock-keyword-face))
2036
2037          ;; Handle other @-commands.
2038          ;; (list "@\\([^a-zA-Z]\\|[a-zA-Z]*\\)"
2039          ;;       '(0 font-lock-keyword-face))
2040
2041          ;; Make sure we get comments properly.
2042          (list "%.*"
2043                '(0 font-lock-comment-face))
2044
2045          ;; Fontify TeX special characters as punctuation.
2046          (list "[$^_{}#&]"
2047                '(0 mdw-punct-face))))
2048
2049   (mdw-post-config-mode-hack))
2050
2051 ;;;--------------------------------------------------------------------------
2052 ;;; SGML hacking.
2053
2054 (defun mdw-sgml-mode ()
2055   (interactive)
2056   (sgml-mode)
2057   (mdw-standard-fill-prefix "")
2058   (make-local-variable 'sgml-delimiters)
2059   (setq sgml-delimiters
2060         '("AND" "&" "COM" "--" "CRO" "&#" "DSC" "]" "DSO" "[" "DTGC" "]"
2061           "DTGO" "[" "ERO" "&" "ETAGO" ":e" "GRPC" ")" "GRPO" "(" "LIT" "\""
2062           "LITA" "'" "MDC" ">" "MDO" "<!" "MINUS" "-" "MSC" "]]" "NESTC" "{"
2063           "NET" "}" "OPT" "?" "OR" "|" "PERO" "%" "PIC" ">" "PIO" "<?"
2064           "PLUS" "+" "REFC" "." "REP" "*" "RNI" "#" "SEQ" "," "STAGO" ":"
2065           "TAGC" "." "VI" "=" "MS-START" "<![" "MS-END" "]]>"
2066           "XML-ECOM" "-->" "XML-PIC" "?>" "XML-SCOM" "<!--" "XML-TAGCE" "/>"
2067           "NULL" ""))
2068   (setq major-mode 'mdw-sgml-mode)
2069   (setq mode-name "[mdw] SGML")
2070   (run-hooks 'mdw-sgml-mode-hook))
2071
2072 ;;;--------------------------------------------------------------------------
2073 ;;; Shell scripts.
2074
2075 (defun mdw-setup-sh-script-mode ()
2076
2077   ;; Fetch the shell interpreter's name.
2078   (let ((shell-name sh-shell-file))
2079
2080     ;; Try reading the hash-bang line.
2081     (save-excursion
2082       (goto-char (point-min))
2083       (if (looking-at "#![ \t]*\\([^ \t\n]*\\)")
2084           (setq shell-name (match-string 1))))
2085
2086     ;; Now try to set the shell.
2087     ;;
2088     ;; Don't let `sh-set-shell' bugger up my script.
2089     (let ((executable-set-magic #'(lambda (s &rest r) s)))
2090       (sh-set-shell shell-name)))
2091
2092   ;; Now enable my keys and the fontification.
2093   (mdw-misc-mode-config)
2094
2095   ;; Set the indentation level correctly.
2096   (setq sh-indentation 2)
2097   (setq sh-basic-offset 2))
2098
2099 ;;;--------------------------------------------------------------------------
2100 ;;; Emacs shell mode.
2101
2102 (defun mdw-eshell-prompt ()
2103   (let ((left "[") (right "]"))
2104     (when (= (user-uid) 0)
2105       (setq left "«" right "»"))
2106     (concat left
2107             (save-match-data
2108               (replace-regexp-in-string "\\..*$" "" (system-name)))
2109             " "
2110             (eshell/pwd)
2111             right)))
2112 (setq eshell-prompt-function 'mdw-eshell-prompt)
2113 (setq eshell-prompt-regexp "^\\[[^]>]+\\(\\]\\|>>?\\)")
2114
2115 (defalias 'eshell/e 'find-file)
2116 (defalias 'eshell/w3m 'w3m-goto-url)
2117
2118 (mdw-define-face eshell-prompt (t :weight bold))
2119 (mdw-define-face eshell-ls-archive (t :weight bold :foreground "red"))
2120 (mdw-define-face eshell-ls-backup (t :foreground "lightgrey" :slant italic))
2121 (mdw-define-face eshell-ls-product (t :foreground "lightgrey" :slant italic))
2122 (mdw-define-face eshell-ls-clutter (t :foreground "lightgrey" :slant italic))
2123 (mdw-define-face eshell-ls-executable (t :weight bold))
2124 (mdw-define-face eshell-ls-directory (t :foreground "cyan" :weight bold))
2125 (mdw-define-face eshell-ls-readonly (t nil))
2126 (mdw-define-face eshell-ls-symlink (t :foreground "cyan"))
2127
2128 ;;;--------------------------------------------------------------------------
2129 ;;; Messages-file mode.
2130
2131 (defun messages-mode-guts ()
2132   (setq messages-mode-syntax-table (make-syntax-table))
2133   (set-syntax-table messages-mode-syntax-table)
2134   (modify-syntax-entry ?0 "w" messages-mode-syntax-table)
2135   (modify-syntax-entry ?1 "w" messages-mode-syntax-table)
2136   (modify-syntax-entry ?2 "w" messages-mode-syntax-table)
2137   (modify-syntax-entry ?3 "w" messages-mode-syntax-table)
2138   (modify-syntax-entry ?4 "w" messages-mode-syntax-table)
2139   (modify-syntax-entry ?5 "w" messages-mode-syntax-table)
2140   (modify-syntax-entry ?6 "w" messages-mode-syntax-table)
2141   (modify-syntax-entry ?7 "w" messages-mode-syntax-table)
2142   (modify-syntax-entry ?8 "w" messages-mode-syntax-table)
2143   (modify-syntax-entry ?9 "w" messages-mode-syntax-table)
2144   (make-local-variable 'comment-start)
2145   (make-local-variable 'comment-end)
2146   (make-local-variable 'indent-line-function)
2147   (setq indent-line-function 'indent-relative)
2148   (mdw-standard-fill-prefix "\\([ \t]*\\(;\\|/?\\*\\)+[ \t]*\\)")
2149   (make-local-variable 'font-lock-defaults)
2150   (make-local-variable 'messages-mode-keywords)
2151   (let ((keywords
2152          (mdw-regexps "array" "bitmap" "callback" "docs[ \t]+enum"
2153                       "export" "enum" "fixed-octetstring" "flags"
2154                       "harmless" "map" "nested" "optional"
2155                       "optional-tagged" "package" "primitive"
2156                       "primitive-nullfree" "relaxed[ \t]+enum"
2157                       "set" "table" "tagged-optional"   "union"
2158                       "variadic" "vector" "version" "version-tag")))
2159     (setq messages-mode-keywords
2160           (list
2161            (list (concat "\\<\\(" keywords "\\)\\>:")
2162                  '(0 font-lock-keyword-face))
2163            '("\\([-a-zA-Z0-9]+:\\)" (0 font-lock-warning-face))
2164            '("\\(\\<[a-z][-_a-zA-Z0-9]*\\)"
2165              (0 font-lock-variable-name-face))
2166            '("\\<\\([0-9]+\\)\\>" (0 mdw-number-face))
2167            '("\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2168              (0 mdw-punct-face)))))
2169   (setq font-lock-defaults
2170         '(messages-mode-keywords nil nil nil nil))
2171   (run-hooks 'messages-file-hook))
2172
2173 (defun messages-mode ()
2174   (interactive)
2175   (fundamental-mode)
2176   (setq major-mode 'messages-mode)
2177   (setq mode-name "Messages")
2178   (messages-mode-guts)
2179   (modify-syntax-entry ?# "<" messages-mode-syntax-table)
2180   (modify-syntax-entry ?\n ">" messages-mode-syntax-table)
2181   (setq comment-start "# ")
2182   (setq comment-end "")
2183   (turn-on-font-lock-if-enabled)
2184   (run-hooks 'messages-mode-hook))
2185
2186 (defun cpp-messages-mode ()
2187   (interactive)
2188   (fundamental-mode)
2189   (setq major-mode 'cpp-messages-mode)
2190   (setq mode-name "CPP Messages")
2191   (messages-mode-guts)
2192   (modify-syntax-entry ?* ". 23" messages-mode-syntax-table)
2193   (modify-syntax-entry ?/ ". 14" messages-mode-syntax-table)
2194   (setq comment-start "/* ")
2195   (setq comment-end " */")
2196   (let ((preprocessor-keywords
2197          (mdw-regexps "assert" "define" "elif" "else" "endif" "error"
2198                       "ident" "if" "ifdef" "ifndef" "import" "include"
2199                       "line" "pragma" "unassert" "undef" "warning")))
2200     (setq messages-mode-keywords
2201           (append (list (list (concat "^[ \t]*\\#[ \t]*"
2202                                       "\\(include\\|import\\)"
2203                                       "[ \t]*\\(<[^>]+\\(>\\|\\)\\)")
2204                               '(2 font-lock-string-face))
2205                         (list (concat "^\\([ \t]*#[ \t]*\\(\\("
2206                                       preprocessor-keywords
2207                                       "\\)\\>\\|[0-9]+\\|$\\)\\)")
2208                               '(1 font-lock-keyword-face)))
2209                   messages-mode-keywords)))
2210   (turn-on-font-lock-if-enabled)
2211   (run-hooks 'cpp-messages-mode-hook))
2212
2213 (add-hook 'messages-mode-hook 'mdw-misc-mode-config t)
2214 (add-hook 'cpp-messages-mode-hook 'mdw-misc-mode-config t)
2215 ; (add-hook 'messages-file-hook 'mdw-fontify-messages t)
2216
2217 ;;;--------------------------------------------------------------------------
2218 ;;; Messages-file mode.
2219
2220 (defvar mallow-driver-substitution-face 'mallow-driver-substitution-face
2221   "Face to use for subsittution directives.")
2222 (make-face 'mallow-driver-substitution-face)
2223 (defvar mallow-driver-text-face 'mallow-driver-text-face
2224   "Face to use for body text.")
2225 (make-face 'mallow-driver-text-face)
2226
2227 (defun mallow-driver-mode ()
2228   (interactive)
2229   (fundamental-mode)
2230   (setq major-mode 'mallow-driver-mode)
2231   (setq mode-name "Mallow driver")
2232   (setq mallow-driver-mode-syntax-table (make-syntax-table))
2233   (set-syntax-table mallow-driver-mode-syntax-table)
2234   (make-local-variable 'comment-start)
2235   (make-local-variable 'comment-end)
2236   (make-local-variable 'indent-line-function)
2237   (setq indent-line-function 'indent-relative)
2238   (mdw-standard-fill-prefix "\\([ \t]*\\(;\\|/?\\*\\)+[ \t]*\\)")
2239   (make-local-variable 'font-lock-defaults)
2240   (make-local-variable 'mallow-driver-mode-keywords)
2241   (let ((keywords
2242          (mdw-regexps "each" "divert" "file" "if"
2243                       "perl" "set" "string" "type" "write")))
2244     (setq mallow-driver-mode-keywords
2245           (list
2246            (list (concat "^%\\s *\\(}\\|\\(" keywords "\\)\\>\\).*$")
2247                  '(0 font-lock-keyword-face))
2248            (list "^%\\s *\\(#.*\\|\\)$"
2249                  '(0 font-lock-comment-face))
2250            (list "^%"
2251                  '(0 font-lock-keyword-face))
2252            (list "^|?\\(.+\\)$" '(1 mallow-driver-text-face))
2253            (list "\\${[^}]*}"
2254                  '(0 mallow-driver-substitution-face t)))))
2255   (setq font-lock-defaults
2256         '(mallow-driver-mode-keywords nil nil nil nil))
2257   (modify-syntax-entry ?\" "_" mallow-driver-mode-syntax-table)
2258   (modify-syntax-entry ?\n ">" mallow-driver-mode-syntax-table)
2259   (setq comment-start "%# ")
2260   (setq comment-end "")
2261   (turn-on-font-lock-if-enabled)
2262   (run-hooks 'mallow-driver-mode-hook))
2263
2264 (add-hook 'mallow-driver-hook 'mdw-misc-mode-config t)
2265
2266 ;;;--------------------------------------------------------------------------
2267 ;;; NFast debugs.
2268
2269 (defun nfast-debug-mode ()
2270   (interactive)
2271   (fundamental-mode)
2272   (setq major-mode 'nfast-debug-mode)
2273   (setq mode-name "NFast debug")
2274   (setq messages-mode-syntax-table (make-syntax-table))
2275   (set-syntax-table messages-mode-syntax-table)
2276   (make-local-variable 'font-lock-defaults)
2277   (make-local-variable 'nfast-debug-mode-keywords)
2278   (setq truncate-lines t)
2279   (setq nfast-debug-mode-keywords
2280         (list
2281          '("^\\(NFast_\\(Connect\\|Disconnect\\|Submit\\|Wait\\)\\)"
2282            (0 font-lock-keyword-face))
2283          (list (concat "^[ \t]+\\(\\("
2284                        "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"
2285                        "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"
2286                        "[ \t]+\\)*"
2287                        "[0-9a-fA-F]+\\)[ \t]*$")
2288            '(0 mdw-number-face))
2289          '("^[ \t]+\.status=[ \t]+\\<\\(OK\\)\\>"
2290            (1 font-lock-keyword-face))
2291          '("^[ \t]+\.status=[ \t]+\\<\\([a-zA-Z][0-9a-zA-Z]*\\)\\>"
2292            (1 font-lock-warning-face))
2293          '("^[ \t]+\.status[ \t]+\\<\\(zero\\)\\>"
2294            (1 nil))
2295          (list (concat "^[ \t]+\\.cmd=[ \t]+"
2296                        "\\<\\([a-zA-Z][0-9a-zA-Z]*\\)\\>")
2297            '(1 font-lock-keyword-face))
2298          '("-?\\<\\([0-9]+\\|0x[0-9a-fA-F]+\\)\\>" (0 mdw-number-face))
2299          '("^\\([ \t]+[a-z0-9.]+\\)" (0 font-lock-variable-name-face))
2300          '("\\<\\([a-z][a-z0-9.]+\\)\\>=" (1 font-lock-variable-name-face))
2301          '("\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" (0 mdw-punct-face))))
2302   (setq font-lock-defaults
2303         '(nfast-debug-mode-keywords nil nil nil nil))
2304   (turn-on-font-lock-if-enabled)
2305   (run-hooks 'nfast-debug-mode-hook))
2306
2307 ;;;--------------------------------------------------------------------------
2308 ;;; Other languages.
2309
2310 ;; Smalltalk.
2311
2312 (defun mdw-setup-smalltalk ()
2313   (and mdw-auto-indent
2314        (local-set-key "\C-m" 'smalltalk-newline-and-indent))
2315   (make-local-variable 'mdw-auto-indent)
2316   (setq mdw-auto-indent nil)
2317   (local-set-key "\C-i" 'smalltalk-reindent))
2318
2319 (defun mdw-fontify-smalltalk ()
2320   (make-local-variable 'font-lock-keywords)
2321   (setq font-lock-keywords
2322         (list
2323          (list "\\<[A-Z][a-zA-Z0-9]*\\>"
2324                '(0 font-lock-keyword-face))
2325          (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
2326                        "[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
2327                        "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
2328                '(0 mdw-number-face))
2329          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2330                '(0 mdw-punct-face))))
2331   (mdw-post-config-mode-hack))
2332
2333 ;; Lispy languages.
2334
2335 ;; Unpleasant bodge.
2336 (unless (boundp 'slime-repl-mode-map)
2337   (setq slime-repl-mode-map (make-sparse-keymap)))
2338
2339 (defun mdw-indent-newline-and-indent ()
2340   (interactive)
2341   (indent-for-tab-command)
2342   (newline-and-indent))
2343
2344 (eval-after-load "cl-indent"
2345   '(progn
2346      (mapc #'(lambda (pair)
2347                (put (car pair)
2348                     'common-lisp-indent-function
2349                     (cdr pair)))
2350       '((destructuring-bind . ((&whole 4 &rest 1) 4 &body))
2351         (multiple-value-bind . ((&whole 4 &rest 1) 4 &body))))))
2352
2353 (defun mdw-common-lisp-indent ()
2354   (make-local-variable 'lisp-indent-function)
2355   (setq lisp-indent-function 'common-lisp-indent-function))
2356
2357 (setq lisp-simple-loop-indentation 2
2358       lisp-loop-keyword-indentation 6
2359       lisp-loop-forms-indentation 6)
2360
2361 (defun mdw-fontify-lispy ()
2362
2363   ;; Set fill prefix.
2364   (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)")
2365
2366   ;; Not much fontification needed.
2367   (make-local-variable 'font-lock-keywords)
2368   (setq font-lock-keywords
2369         (list
2370          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2371                '(0 mdw-punct-face))))
2372
2373   (mdw-post-config-mode-hack))
2374
2375 (defun comint-send-and-indent ()
2376   (interactive)
2377   (comint-send-input)
2378   (and mdw-auto-indent
2379        (indent-for-tab-command)))
2380
2381 (defun mdw-setup-m4 ()
2382   (mdw-standard-fill-prefix "\\([ \t]*\\(?:#+\\|\\<dnl\\>\\)[ \t]*\\)"))
2383
2384 ;;;--------------------------------------------------------------------------
2385 ;;; Text mode.
2386
2387 (defun mdw-text-mode ()
2388   (setq fill-column 72)
2389   (flyspell-mode t)
2390   (mdw-standard-fill-prefix
2391    "\\([ \t]*\\([>#|:] ?\\)*[ \t]*\\)" 3)
2392   (auto-fill-mode 1))
2393
2394 ;;;--------------------------------------------------------------------------
2395 ;;; Outline and hide/show modes.
2396
2397 (defun mdw-outline-collapse-all ()
2398   "Completely collapse everything in the entire buffer."
2399   (interactive)
2400   (save-excursion
2401     (goto-char (point-min))
2402     (while (< (point) (point-max))
2403       (hide-subtree)
2404       (forward-line))))
2405
2406 (setq hs-hide-comments-when-hiding-all nil)
2407
2408 (defadvice hs-hide-all (after hide-first-comment activate)
2409   (save-excursion (hs-hide-initial-comment-block)))
2410
2411 ;;;--------------------------------------------------------------------------
2412 ;;; Shell mode.
2413
2414 (defun mdw-sh-mode-setup ()
2415   (local-set-key [?\C-a] 'comint-bol)
2416   (add-hook 'comint-output-filter-functions
2417             'comint-watch-for-password-prompt))
2418
2419 (defun mdw-term-mode-setup ()
2420   (setq term-prompt-regexp shell-prompt-pattern)
2421   (make-local-variable 'mouse-yank-at-point)
2422   (make-local-variable 'transient-mark-mode)
2423   (setq mouse-yank-at-point t)
2424   (auto-fill-mode -1)
2425   (setq tab-width 8))
2426
2427 (defun term-send-meta-right () (interactive) (term-send-raw-string "\e\e[C"))
2428 (defun term-send-meta-left  () (interactive) (term-send-raw-string "\e\e[D"))
2429 (defun term-send-ctrl-uscore () (interactive) (term-send-raw-string "\C-_"))
2430 (defun term-send-meta-meta-something ()
2431   (interactive)
2432   (term-send-raw-string "\e\e")
2433   (term-send-raw))
2434 (eval-after-load 'term
2435   '(progn
2436      (define-key term-raw-map [?\e ?\e] nil)
2437      (define-key term-raw-map [?\e ?\e t] 'term-send-meta-meta-something)
2438      (define-key term-raw-map [?\C-/] 'term-send-ctrl-uscore)
2439      (define-key term-raw-map [M-right] 'term-send-meta-right)
2440      (define-key term-raw-map [?\e ?\M-O ?C] 'term-send-meta-right)
2441      (define-key term-raw-map [M-left] 'term-send-meta-left)
2442      (define-key term-raw-map [?\e ?\M-O ?D] 'term-send-meta-left)))
2443
2444 ;;;--------------------------------------------------------------------------
2445 ;;; Inferior Emacs Lisp.
2446
2447 (setq comint-prompt-read-only t)
2448
2449 (eval-after-load "comint"
2450   '(progn
2451      (define-key comint-mode-map "\C-w" 'comint-kill-region)
2452      (define-key comint-mode-map [C-S-backspace] 'comint-kill-whole-line)))
2453
2454 (eval-after-load "ielm"
2455   '(progn
2456      (define-key ielm-map "\C-w" 'comint-kill-region)
2457      (define-key ielm-map [C-S-backspace] 'comint-kill-whole-line)))
2458
2459 ;;;----- That's all, folks --------------------------------------------------
2460
2461 (provide 'dot-emacs)