chiark / gitweb /
el/dot-emacs.el: Twiddle `variable-pitch' face size for Emacs 22.
[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   '((w3m . mdw-w3m-browse-url)
520     browse-url-w3
521     browse-url-mozilla)
522   "List of good browsers for mdw-good-url-browsers.
523 Each item is a browser function name, or a cons (CHECK . FUNC).
524 A symbol FOO stands for (FOO . FOO).")
525
526 (defun mdw-good-url-browser ()
527   "Return a good URL browser.
528 Trundle the list of such things, finding the first item for which
529 CHECK is fboundp, and returning the correponding FUNC."
530   (let ((bs mdw-good-url-browsers) b check func answer)
531     (while (and bs (not answer))
532       (setq b (car bs)
533             bs (cdr bs))
534       (if (consp b)
535           (setq check (car b) func (cdr b))
536         (setq check b func b))
537       (if (fboundp check)
538           (setq answer func)))
539     answer))
540
541 (eval-after-load "w3m-search"
542   '(progn
543      (dolist
544          (item
545           '(("g" "Google" "http://www.google.co.uk/search?q=%s")
546             ("gd" "Google Directory"
547              "http://www.google.com/search?cat=gwd/Top&q=%s")
548             ("gg" "Google Groups" "http://groups.google.com/groups?q=%s")
549             ("ward" "Ward's wiki" "http://c2.com/cgi/wiki?%s")
550             ("gi" "Images" "http://images.google.com/images?q=%s")
551             ("rfc" "RFC"
552              "http://metalzone.distorted.org.uk/ftp/pub/mirrors/rfc/rfc%s.txt.gz")
553             ("wp" "Wikipedia"
554              "http://en.wikipedia.org/wiki/Special:Search?go=Go&search=%s")
555             ("imdb" "IMDb" "http://www.imdb.com/Find?%s")
556             ("nc-wiki" "nCipher wiki"
557              "http://wiki.ncipher.com/wiki/bin/view/Devel/?topic=%s")
558             ("map" "Google maps" "http://maps.google.co.uk/maps?q=%s&hl=en")
559             ("lp" "Launchpad bug by number"
560              "https://bugs.launchpad.net/bugs/%s")
561             ("lppkg" "Launchpad bugs by package"
562              "https://bugs.launchpad.net/%s")
563             ("msdn" "MSDN"
564              "http://social.msdn.microsoft.com/Search/en-GB/?query=%s&ac=8")
565             ("debbug" "Debian bug by number"
566              "http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=%s")
567             ("debbugpkg" "Debian bugs by package"
568              "http://bugs.debian.org/cgi-bin/pkgreport.cgi?pkg=%s")
569             ("ljlogin" "LJ login" "http://www.livejournal.com/login.bml")))
570        (add-to-list 'w3m-search-engine-alist
571                     (list (cadr item) (caddr item) nil))
572        (add-to-list 'w3m-uri-replace-alist
573                     (list (concat "\\`" (car item) ":")
574                           'w3m-search-uri-replace
575                           (cadr item))))))
576
577 ;;;--------------------------------------------------------------------------
578 ;;; Paragraph filling.
579
580 ;; Useful variables.
581
582 (defvar mdw-fill-prefix nil
583   "*Used by `mdw-line-prefix' and `mdw-fill-paragraph'.
584 If there's no fill prefix currently set (by the `fill-prefix'
585 variable) and there's a match from one of the regexps here, it
586 gets used to set the fill-prefix for the current operation.
587
588 The variable is a list of items of the form `REGEXP . PREFIX'; if
589 the REGEXP matches, the PREFIX is used to set the fill prefix.
590 It in turn is a list of things:
591
592   STRING -- insert a literal string
593   (match . N) -- insert the thing matched by bracketed subexpression N
594   (pad . N) -- a string of whitespace the same width as subexpression N
595   (expr . FORM) -- the result of evaluating FORM")
596
597 (make-variable-buffer-local 'mdw-fill-prefix)
598
599 (defvar mdw-hanging-indents
600   (concat "\\(\\("
601             "\\([*o]\\|-[-#]?\\|[0-9]+\\.\\|\\[[0-9]+\\]\\|([a-zA-Z])\\)"
602             "[ \t]+"
603           "\\)?\\)")
604   "*Standard regexp matching parts of a hanging indent.
605 This is mainly useful in `auto-fill-mode'.")
606
607 ;; Setting things up.
608
609 (fset 'mdw-do-auto-fill (symbol-function 'do-auto-fill))
610
611 ;; Utility functions.
612
613 (defun mdw-tabify (s)
614   "Tabify the string S.  This is a horrid hack."
615   (save-excursion
616     (save-match-data
617       (let (start end)
618         (beginning-of-line)
619         (setq start (point-marker))
620         (insert s "\n")
621         (setq end (point-marker))
622         (tabify start end)
623         (setq s (buffer-substring start (1- end)))
624         (delete-region start end)
625         (set-marker start nil)
626         (set-marker end nil)
627         s))))
628
629 (defun mdw-examine-fill-prefixes (l)
630   "Given a list of dynamic fill prefixes, pick one which matches
631 context and return the static fill prefix to use.  Point must be
632 at the start of a line, and match data must be saved."
633   (cond ((not l) nil)
634                ((looking-at (car (car l)))
635                 (mdw-tabify (apply (function concat)
636                                    (mapcar (function mdw-do-prefix-match)
637                                            (cdr (car l))))))
638                (t (mdw-examine-fill-prefixes (cdr l)))))
639
640 (defun mdw-maybe-car (p)
641   "If P is a pair, return (car P), otherwise just return P."
642   (if (consp p) (car p) p))
643
644 (defun mdw-padding (s)
645   "Return a string the same width as S but made entirely from whitespace."
646   (let* ((l (length s)) (i 0) (n (make-string l ? )))
647     (while (< i l)
648       (if (= 9 (aref s i))
649           (aset n i 9))
650       (setq i (1+ i)))
651     n))
652
653 (defun mdw-do-prefix-match (m)
654   "Expand a dynamic prefix match element.
655 See `mdw-fill-prefix' for details."
656   (cond ((not (consp m)) (format "%s" m))
657            ((eq (car m) 'match) (match-string (mdw-maybe-car (cdr m))))
658            ((eq (car m) 'pad) (mdw-padding (match-string
659                                             (mdw-maybe-car (cdr m)))))
660            ((eq (car m) 'eval) (eval (cdr m)))
661            (t "")))
662
663 (defun mdw-choose-dynamic-fill-prefix ()
664   "Work out the dynamic fill prefix based on the variable `mdw-fill-prefix'."
665   (cond ((and fill-prefix (not (string= fill-prefix ""))) fill-prefix)
666            ((not mdw-fill-prefix) fill-prefix)
667            (t (save-excursion
668                 (beginning-of-line)
669                 (save-match-data
670                   (mdw-examine-fill-prefixes mdw-fill-prefix))))))
671
672 (defun do-auto-fill ()
673   "Handle auto-filling, working out a dynamic fill prefix in the
674 case where there isn't a sensible static one."
675   (let ((fill-prefix (mdw-choose-dynamic-fill-prefix)))
676     (mdw-do-auto-fill)))
677
678 (defun mdw-fill-paragraph ()
679   "Fill paragraph, getting a dynamic fill prefix."
680   (interactive)
681   (let ((fill-prefix (mdw-choose-dynamic-fill-prefix)))
682     (fill-paragraph nil)))
683
684 (defun mdw-standard-fill-prefix (rx &optional mat)
685   "Set the dynamic fill prefix, handling standard hanging indents and stuff.
686 This is just a short-cut for setting the thing by hand, and by
687 design it doesn't cope with anything approximating a complicated
688 case."
689   (setq mdw-fill-prefix
690            `((,(concat rx mdw-hanging-indents)
691               (match . 1)
692               (pad . ,(or mat 2))))))
693
694 ;;;--------------------------------------------------------------------------
695 ;;; Other common declarations.
696
697 ;; Common mode settings.
698
699 (defvar mdw-auto-indent t
700   "Whether to indent automatically after a newline.")
701
702 (defun mdw-misc-mode-config ()
703   (and mdw-auto-indent
704        (cond ((eq major-mode 'lisp-mode)
705               (local-set-key "\C-m" 'mdw-indent-newline-and-indent))
706              ((or (eq major-mode 'slime-repl-mode)
707                   (eq major-mode 'asm-mode))
708               nil)
709              (t
710               (local-set-key "\C-m" 'newline-and-indent))))
711   (local-set-key [C-return] 'newline)
712   (make-local-variable 'page-delimiter)
713   (setq page-delimiter "\f\\|^.*-\\{6\\}.*$")
714   (setq comment-column 40)
715   (auto-fill-mode 1)
716   (setq fill-column 77)
717   (setq show-trailing-whitespace t)
718   (let ((whitespace-style (remove 'trailing whitespace-style)))
719     (trap (whitespace-mode t)))
720   (and (fboundp 'gtags-mode)
721        (gtags-mode))
722   (outline-minor-mode t)
723   (hs-minor-mode t)
724   (reveal-mode t)
725   (trap (turn-on-font-lock)))
726
727 (defun mdw-post-config-mode-hack ()
728   (let ((whitespace-style (remove 'trailing whitespace-style)))
729     (trap (whitespace-mode t))))
730
731 (eval-after-load 'gtags
732   '(progn
733      (dolist (key '([mouse-2] [mouse-3]))
734        (define-key gtags-mode-map key nil))
735      (define-key gtags-mode-map [C-S-mouse-2] 'gtags-find-tag-by-event)
736      (define-key gtags-select-mode-map [C-S-mouse-2]
737        'gtags-select-tag-by-event)
738      (dolist (map (list gtags-mode-map gtags-select-mode-map))
739        (define-key map [C-S-mouse-3] 'gtags-pop-stack))))
740
741 ;; Backup file handling.
742
743 (defvar mdw-backup-disable-regexps nil
744   "*List of regular expressions: if a file name matches any of
745 these then the file is not backed up.")
746
747 (defun mdw-backup-enable-predicate (name)
748   "[mdw]'s default backup predicate.
749 Allows a backup if the standard predicate would allow it, and it
750 doesn't match any of the regular expressions in
751 `mdw-backup-disable-regexps'."
752   (and (normal-backup-enable-predicate name)
753        (let ((answer t) (list mdw-backup-disable-regexps))
754          (save-match-data
755            (while list
756              (if (string-match (car list) name)
757                  (setq answer nil))
758              (setq list (cdr list)))
759            answer))))
760 (setq backup-enable-predicate 'mdw-backup-enable-predicate)
761
762 ;; Frame cleanup.
763
764 (defun mdw-last-one-out-turn-off-the-lights (frame)
765   "Disconnect from an X display if this was the last frame on that display."
766   (let ((frame-display (frame-parameter frame 'display)))
767     (when (and frame-display
768                (eq window-system 'x)
769                (not (some (lambda (fr)
770                             (message "checking frame %s" frame)
771                             (and (not (eq fr frame))
772                                  (string= (frame-parameter fr 'display)
773                                           frame-display)
774                                  (progn "frame %s still uses us" nil)))
775                           (frame-list))))
776       (run-with-idle-timer 0 nil #'x-close-connection frame-display))))
777 (add-hook 'delete-frame-functions 'mdw-last-one-out-turn-off-the-lights)
778
779 (defvar mdw-frame-parameters-alist
780   '((nil (menu-bar-lines . 0))))
781 (defun mdw-set-frame-parameters (frame)
782   (let ((params (assq (if (fboundp 'window-system)
783                           (window-system frame)
784                         window-system)
785                       mdw-frame-parameters-alist)))
786     (when params
787       (modify-frame-parameters frame (cdr params)))))
788 (add-hook 'after-make-frame-functions 'mdw-set-frame-parameters)
789
790 ;;;--------------------------------------------------------------------------
791 ;;; General fontification.
792
793 (defmacro mdw-define-face (name &rest body)
794   "Define a face, and make sure it's actually set as the definition."
795   (declare (indent 1)
796            (debug 0))
797   `(progn
798      (make-face ',name)
799      (defvar ,name ',name)
800      (put ',name 'face-defface-spec ',body)
801      (face-spec-set ',name ',body nil)))
802
803 (mdw-define-face default
804   (((type w32)) :family "courier new" :height 85)
805   (((type x)) :family "6x13" :height 130)
806   (((type color)) :foreground "white" :background "black")
807   (t nil))
808 (mdw-define-face fixed-pitch
809   (((type w32)) :family "courier new" :height 85)
810   (((type x)) :family "6x13" :height 130)
811   (t :foreground "white" :background "black"))
812 (if (>= emacs-major-version 23)
813     (mdw-define-face variable-pitch
814       (((type x)) :family "sans" :height 100))
815   (mdw-define-face variable-pitch
816     (((type x)) :family "helvetica" :height 90)))
817 (mdw-define-face region
818   (((type tty) (class color)) :background "blue")
819   (((type tty) (class mono)) :inverse-video t)
820   (t :background "grey30"))
821 (mdw-define-face minibuffer-prompt
822   (t :weight bold))
823 (mdw-define-face mode-line
824   (((class color)) :foreground "blue" :background "yellow"
825                    :box (:line-width 1 :style released-button))
826   (t :inverse-video t))
827 (mdw-define-face mode-line-inactive
828   (((class color)) :foreground "yellow" :background "blue"
829                    :box (:line-width 1 :style released-button))
830   (t :inverse-video t))
831 (mdw-define-face scroll-bar
832   (t :foreground "black" :background "lightgrey"))
833 (mdw-define-face fringe
834   (t :foreground "yellow"))
835 (mdw-define-face show-paren-match
836   (((class color)) :background "darkgreen")
837   (t :underline t))
838 (mdw-define-face show-paren-mismatch
839   (((class color)) :background "red")
840   (t :inverse-video t))
841 (mdw-define-face highlight
842   (((class color)) :background "DarkSeaGreen4")
843   (t :inverse-video t))
844
845 (mdw-define-face holiday-face
846   (t :background "red"))
847 (mdw-define-face calendar-today-face
848   (t :foreground "yellow" :weight bold))
849
850 (mdw-define-face comint-highlight-prompt
851   (t :weight bold))
852 (mdw-define-face comint-highlight-input
853   (t nil))
854
855 (mdw-define-face trailing-whitespace
856   (((class color)) :background "red")
857   (t :inverse-video t))
858 (mdw-define-face mdw-punct-face
859   (((type tty)) :foreground "yellow") (t :foreground "burlywood2"))
860 (mdw-define-face mdw-number-face
861   (t :foreground "yellow"))
862 (mdw-define-face font-lock-function-name-face
863   (t :slant italic))
864 (mdw-define-face font-lock-keyword-face
865   (t :weight bold))
866 (mdw-define-face font-lock-constant-face
867   (t :slant italic))
868 (mdw-define-face font-lock-builtin-face
869   (t :weight bold))
870 (mdw-define-face font-lock-type-face
871   (t :weight bold :slant italic))
872 (mdw-define-face font-lock-reference-face
873   (t :weight bold))
874 (mdw-define-face font-lock-variable-name-face
875   (t :slant italic))
876 (mdw-define-face font-lock-comment-delimiter-face
877   (((class mono)) :weight bold)
878   (((type tty) (class color)) :foreground "green")
879   (t :slant italic :foreground "SeaGreen1"))
880 (mdw-define-face font-lock-comment-face
881   (((class mono)) :weight bold)
882   (((type tty) (class color)) :foreground "green")
883   (t :slant italic :foreground "SeaGreen1"))
884 (mdw-define-face font-lock-string-face
885   (((class mono)) :weight bold)
886   (((class color)) :foreground "SkyBlue1"))
887 (mdw-define-face message-separator
888   (t :background "red" :foreground "white" :weight bold))
889 (mdw-define-face message-cited-text
890   (default :slant italic)
891   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
892 (mdw-define-face message-header-cc
893   (default :weight bold)
894   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
895 (mdw-define-face message-header-newsgroups
896   (default :weight bold)
897   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
898 (mdw-define-face message-header-subject
899   (default :weight bold)
900   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
901 (mdw-define-face message-header-to
902   (default :weight bold)
903   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
904 (mdw-define-face message-header-xheader
905   (default :weight bold)
906   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
907 (mdw-define-face message-header-other
908   (default :weight bold)
909   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
910 (mdw-define-face message-header-name
911   (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
912
913 (mdw-define-face diff-index
914   (t :weight bold))
915 (mdw-define-face diff-file-header
916   (t :weight bold))
917 (mdw-define-face diff-hunk-header
918   (t :foreground "SkyBlue1"))
919 (mdw-define-face diff-function
920   (t :foreground "SkyBlue1" :weight bold))
921 (mdw-define-face diff-header
922   (t :background "grey10"))
923 (mdw-define-face diff-added
924   (t :foreground "green"))
925 (mdw-define-face diff-removed
926   (t :foreground "red"))
927 (mdw-define-face diff-context
928   (t nil))
929
930 (mdw-define-face erc-input-face
931   (t :foreground "red"))
932
933 (mdw-define-face woman-bold
934   (t :weight bold))
935 (mdw-define-face woman-italic
936   (t :slant italic))
937
938 (mdw-define-face p4-depot-added-face
939   (t :foreground "green"))
940 (mdw-define-face p4-depot-branch-op-face
941   (t :foreground "yellow"))
942 (mdw-define-face p4-depot-deleted-face
943   (t :foreground "red"))
944 (mdw-define-face p4-depot-unmapped-face
945   (t :foreground "SkyBlue1"))
946 (mdw-define-face p4-diff-change-face
947   (t :foreground "yellow"))
948 (mdw-define-face p4-diff-del-face
949   (t :foreground "red"))
950 (mdw-define-face p4-diff-file-face
951   (t :foreground "SkyBlue1"))
952 (mdw-define-face p4-diff-head-face
953   (t :background "grey10"))
954 (mdw-define-face p4-diff-ins-face
955   (t :foreground "green"))
956
957 (mdw-define-face whizzy-slice-face
958   (t :background "grey10"))
959 (mdw-define-face whizzy-error-face
960   (t :background "darkred"))
961
962 ;;;--------------------------------------------------------------------------
963 ;;; C programming configuration.
964
965 ;; Linux kernel hacking.
966
967 (defvar linux-c-mode-hook)
968
969 (defun linux-c-mode ()
970   (interactive)
971   (c-mode)
972   (setq major-mode 'linux-c-mode)
973   (setq mode-name "Linux C")
974   (run-hooks 'linux-c-mode-hook))
975
976 ;; Make C indentation nice.
977
978 (defun mdw-c-lineup-arglist (langelem)
979   "Hack for DWIMmery in c-lineup-arglist."
980   (if (save-excursion
981         (c-block-in-arglist-dwim (c-langelem-2nd-pos c-syntactic-element)))
982       0
983     (c-lineup-arglist langelem)))
984
985 (defun mdw-c-indent-extern-mumble (langelem)
986   "Indent `extern \"...\" {' lines."
987   (save-excursion
988     (back-to-indentation)
989     (if (looking-at
990          "\\s-*\\<extern\\>\\s-*\"\\([^\\\\\"]+\\|\\.\\)*\"\\s-*{")
991         c-basic-offset
992       nil)))
993
994 (defun mdw-c-style ()
995   (c-add-style "[mdw] C and C++ style"
996                '((c-basic-offset . 2)
997                  (comment-column . 40)
998                  (c-class-key . "class")
999                  (c-backslash-column . 72)
1000                  (c-offsets-alist
1001                   (substatement-open . (add 0 c-indent-one-line-block))
1002                   (defun-open . (add 0 c-indent-one-line-block))
1003                   (arglist-cont-nonempty . mdw-c-lineup-arglist)
1004                   (topmost-intro . mdw-c-indent-extern-mumble)
1005                   (cpp-define-intro . 0)
1006                   (inextern-lang . [0])
1007                   (label . 0)
1008                   (case-label . +)
1009                   (access-label . -)
1010                   (inclass . +)
1011                   (inline-open . ++)
1012                   (statement-cont . 0)
1013                   (statement-case-intro . +)))
1014                t))
1015
1016 (defvar mdw-c-comment-fill-prefix
1017   `((,(concat "\\([ \t]*/?\\)"
1018               "\\(\*\\|//]\\)"
1019               "\\([ \t]*\\)"
1020               "\\([A-Za-z]+:[ \t]*\\)?"
1021               mdw-hanging-indents)
1022      (pad . 1) (match . 2) (pad . 3) (pad . 4) (pad . 5)))
1023   "Fill prefix matching C comments (both kinds).")
1024
1025 (defun mdw-fontify-c-and-c++ ()
1026
1027   ;; Fiddle with some syntax codes.
1028   (modify-syntax-entry ?* ". 23")
1029   (modify-syntax-entry ?/ ". 124b")
1030   (modify-syntax-entry ?\n "> b")
1031
1032   ;; Other stuff.
1033   (mdw-c-style)
1034   (setq c-hanging-comment-ender-p nil)
1035   (setq c-backslash-column 72)
1036   (setq c-label-minimum-indentation 0)
1037   (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
1038
1039   ;; Now define things to be fontified.
1040   (make-local-variable 'font-lock-keywords)
1041   (let ((c-keywords
1042          (mdw-regexps "and"             ;C++
1043                       "and_eq"          ;C++
1044                       "asm"             ;K&R, GCC
1045                       "auto"            ;K&R, C89
1046                       "bitand"          ;C++
1047                       "bitor"           ;C++
1048                       "bool"            ;C++, C9X macro
1049                       "break"           ;K&R, C89
1050                       "case"            ;K&R, C89
1051                       "catch"           ;C++
1052                       "char"            ;K&R, C89
1053                       "class"           ;C++
1054                       "complex"         ;C9X macro, C++ template type
1055                       "compl"           ;C++
1056                       "const"           ;C89
1057                       "const_cast"      ;C++
1058                       "continue"        ;K&R, C89
1059                       "defined"         ;C89 preprocessor
1060                       "default"         ;K&R, C89
1061                       "delete"          ;C++
1062                       "do"              ;K&R, C89
1063                       "double"          ;K&R, C89
1064                       "dynamic_cast"    ;C++
1065                       "else"            ;K&R, C89
1066                       ;; "entry"        ;K&R -- never used
1067                       "enum"            ;C89
1068                       "explicit"        ;C++
1069                       "export"          ;C++
1070                       "extern"          ;K&R, C89
1071                       "false"           ;C++, C9X macro
1072                       "float"           ;K&R, C89
1073                       "for"             ;K&R, C89
1074                       ;; "fortran"      ;K&R
1075                       "friend"          ;C++
1076                       "goto"            ;K&R, C89
1077                       "if"              ;K&R, C89
1078                       "imaginary"       ;C9X macro
1079                       "inline"          ;C++, C9X, GCC
1080                       "int"             ;K&R, C89
1081                       "long"            ;K&R, C89
1082                       "mutable"         ;C++
1083                       "namespace"       ;C++
1084                       "new"             ;C++
1085                       "operator"        ;C++
1086                       "or"              ;C++
1087                       "or_eq"           ;C++
1088                       "private"         ;C++
1089                       "protected"       ;C++
1090                       "public"          ;C++
1091                       "register"        ;K&R, C89
1092                       "reinterpret_cast" ;C++
1093                       "restrict"         ;C9X
1094                       "return"           ;K&R, C89
1095                       "short"            ;K&R, C89
1096                       "signed"           ;C89
1097                       "sizeof"           ;K&R, C89
1098                       "static"           ;K&R, C89
1099                       "static_cast"      ;C++
1100                       "struct"           ;K&R, C89
1101                       "switch"           ;K&R, C89
1102                       "template"         ;C++
1103                       "this"             ;C++
1104                       "throw"            ;C++
1105                       "true"             ;C++, C9X macro
1106                       "try"              ;C++
1107                       "this"             ;C++
1108                       "typedef"          ;C89
1109                       "typeid"           ;C++
1110                       "typeof"           ;GCC
1111                       "typename"         ;C++
1112                       "union"            ;K&R, C89
1113                       "unsigned"         ;K&R, C89
1114                       "using"            ;C++
1115                       "virtual"          ;C++
1116                       "void"             ;C89
1117                       "volatile"         ;C89
1118                       "wchar_t"          ;C++, C89 library type
1119                       "while"            ;K&R, C89
1120                       "xor"              ;C++
1121                       "xor_eq"           ;C++
1122                       "_Bool"            ;C9X
1123                       "_Complex"         ;C9X
1124                       "_Imaginary"       ;C9X
1125                       "_Pragma"          ;C9X preprocessor
1126                       "__alignof__"      ;GCC
1127                       "__asm__"          ;GCC
1128                       "__attribute__"    ;GCC
1129                       "__complex__"      ;GCC
1130                       "__const__"        ;GCC
1131                       "__extension__"    ;GCC
1132                       "__imag__"         ;GCC
1133                       "__inline__"       ;GCC
1134                       "__label__"        ;GCC
1135                       "__real__"         ;GCC
1136                       "__signed__"       ;GCC
1137                       "__typeof__"       ;GCC
1138                       "__volatile__"     ;GCC
1139                       ))
1140         (preprocessor-keywords
1141          (mdw-regexps "assert" "define" "elif" "else" "endif" "error"
1142                       "ident" "if" "ifdef" "ifndef" "import" "include"
1143                       "line" "pragma" "unassert" "undef" "warning"))
1144         (objc-keywords
1145          (mdw-regexps "class" "defs" "encode" "end" "implementation"
1146                       "interface" "private" "protected" "protocol" "public"
1147                       "selector")))
1148
1149     (setq font-lock-keywords
1150           (list
1151
1152            ;; Fontify include files as strings.
1153            (list (concat "^[ \t]*\\#[ \t]*"
1154                          "\\(include\\|import\\)"
1155                          "[ \t]*\\(<[^>]+\\(>\\|\\)\\)")
1156                  '(2 font-lock-string-face))
1157
1158            ;; Preprocessor directives are `references'?.
1159            (list (concat "^\\([ \t]*#[ \t]*\\(\\("
1160                          preprocessor-keywords
1161                          "\\)\\>\\|[0-9]+\\|$\\)\\)")
1162                  '(1 font-lock-keyword-face))
1163
1164            ;; Handle the keywords defined above.
1165            (list (concat "@\\<\\(" objc-keywords "\\)\\>")
1166                  '(0 font-lock-keyword-face))
1167
1168            (list (concat "\\<\\(" c-keywords "\\)\\>")
1169                  '(0 font-lock-keyword-face))
1170
1171            ;; Handle numbers too.
1172            ;;
1173            ;; This looks strange, I know.  It corresponds to the
1174            ;; preprocessor's idea of what a number looks like, rather than
1175            ;; anything sensible.
1176            (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
1177                          "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
1178                  '(0 mdw-number-face))
1179
1180            ;; And anything else is punctuation.
1181            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1182                  '(0 mdw-punct-face))))
1183
1184     (mdw-post-config-mode-hack)))
1185
1186 ;;;--------------------------------------------------------------------------
1187 ;;; AP calc mode.
1188
1189 (defun apcalc-mode ()
1190   (interactive)
1191   (c-mode)
1192   (setq major-mode 'apcalc-mode)
1193   (setq mode-name "AP Calc")
1194   (run-hooks 'apcalc-mode-hook))
1195
1196 (defun mdw-fontify-apcalc ()
1197
1198   ;; Fiddle with some syntax codes.
1199   (modify-syntax-entry ?* ". 23")
1200   (modify-syntax-entry ?/ ". 14")
1201
1202   ;; Other stuff.
1203   (mdw-c-style)
1204   (setq c-hanging-comment-ender-p nil)
1205   (setq c-backslash-column 72)
1206   (setq comment-start "/* ")
1207   (setq comment-end " */")
1208   (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
1209
1210   ;; Now define things to be fontified.
1211   (make-local-variable 'font-lock-keywords)
1212   (let ((c-keywords
1213          (mdw-regexps "break" "case" "cd" "continue" "define" "default"
1214                       "do" "else" "exit" "for" "global" "goto" "help" "if"
1215                       "local" "mat" "obj" "print" "quit" "read" "return"
1216                       "show" "static" "switch" "while" "write")))
1217
1218     (setq font-lock-keywords
1219           (list
1220
1221            ;; Handle the keywords defined above.
1222            (list (concat "\\<\\(" c-keywords "\\)\\>")
1223                  '(0 font-lock-keyword-face))
1224
1225            ;; Handle numbers too.
1226            ;;
1227            ;; This looks strange, I know.  It corresponds to the
1228            ;; preprocessor's idea of what a number looks like, rather than
1229            ;; anything sensible.
1230            (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
1231                          "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
1232                  '(0 mdw-number-face))
1233
1234            ;; And anything else is punctuation.
1235            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1236                  '(0 mdw-punct-face)))))
1237
1238   (mdw-post-config-mode-hack))
1239
1240 ;;;--------------------------------------------------------------------------
1241 ;;; Java programming configuration.
1242
1243 ;; Make indentation nice.
1244
1245 (defun mdw-java-style ()
1246   (c-add-style "[mdw] Java style"
1247                '((c-basic-offset . 2)
1248                  (c-offsets-alist (substatement-open . 0)
1249                                   (label . +)
1250                                   (case-label . +)
1251                                   (access-label . 0)
1252                                   (inclass . +)
1253                                   (statement-case-intro . +)))
1254                t))
1255
1256 ;; Declare Java fontification style.
1257
1258 (defun mdw-fontify-java ()
1259
1260   ;; Other stuff.
1261   (mdw-java-style)
1262   (setq c-hanging-comment-ender-p nil)
1263   (setq c-backslash-column 72)
1264   (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
1265
1266   ;; Now define things to be fontified.
1267   (make-local-variable 'font-lock-keywords)
1268   (let ((java-keywords
1269          (mdw-regexps "abstract" "boolean" "break" "byte" "case" "catch"
1270                       "char" "class" "const" "continue" "default" "do"
1271                       "double" "else" "extends" "final" "finally" "float"
1272                       "for" "goto" "if" "implements" "import" "instanceof"
1273                       "int" "interface" "long" "native" "new" "package"
1274                       "private" "protected" "public" "return" "short"
1275                       "static" "super" "switch" "synchronized" "this"
1276                       "throw" "throws" "transient" "try" "void" "volatile"
1277                       "while"
1278
1279                       "false" "null" "true")))
1280
1281     (setq font-lock-keywords
1282           (list
1283
1284            ;; Handle the keywords defined above.
1285            (list (concat "\\<\\(" java-keywords "\\)\\>")
1286                  '(0 font-lock-keyword-face))
1287
1288            ;; Handle numbers too.
1289            ;;
1290            ;; The following isn't quite right, but it's close enough.
1291            (list (concat "\\<\\("
1292                          "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1293                          "[0-9]+\\(\\.[0-9]*\\|\\)"
1294                          "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
1295                          "[lLfFdD]?")
1296                  '(0 mdw-number-face))
1297
1298            ;; And anything else is punctuation.
1299            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1300                  '(0 mdw-punct-face)))))
1301
1302   (mdw-post-config-mode-hack))
1303
1304 ;;;--------------------------------------------------------------------------
1305 ;;; C# programming configuration.
1306
1307 ;; Make indentation nice.
1308
1309 (defun mdw-csharp-style ()
1310   (c-add-style "[mdw] C# style"
1311                '((c-basic-offset . 2)
1312                  (c-offsets-alist (substatement-open . 0)
1313                                   (label . 0)
1314                                   (case-label . +)
1315                                   (access-label . 0)
1316                                   (inclass . +)
1317                                   (statement-case-intro . +)))
1318                t))
1319
1320 ;; Declare C# fontification style.
1321
1322 (defun mdw-fontify-csharp ()
1323
1324   ;; Other stuff.
1325   (mdw-csharp-style)
1326   (setq c-hanging-comment-ender-p nil)
1327   (setq c-backslash-column 72)
1328   (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
1329
1330   ;; Now define things to be fontified.
1331   (make-local-variable 'font-lock-keywords)
1332   (let ((csharp-keywords
1333          (mdw-regexps "abstract" "as" "base" "bool" "break"
1334                       "byte" "case" "catch" "char" "checked"
1335                       "class" "const" "continue" "decimal" "default"
1336                       "delegate" "do" "double" "else" "enum"
1337                       "event" "explicit" "extern" "false" "finally"
1338                       "fixed" "float" "for" "foreach" "goto"
1339                       "if" "implicit" "in" "int" "interface"
1340                       "internal" "is" "lock" "long" "namespace"
1341                       "new" "null" "object" "operator" "out"
1342                       "override" "params" "private" "protected" "public"
1343                       "readonly" "ref" "return" "sbyte" "sealed"
1344                       "short" "sizeof" "stackalloc" "static" "string"
1345                       "struct" "switch" "this" "throw" "true"
1346                       "try" "typeof" "uint" "ulong" "unchecked"
1347                       "unsafe" "ushort" "using" "virtual" "void"
1348                       "volatile" "while" "yield")))
1349
1350     (setq font-lock-keywords
1351           (list
1352
1353            ;; Handle the keywords defined above.
1354            (list (concat "\\<\\(" csharp-keywords "\\)\\>")
1355                  '(0 font-lock-keyword-face))
1356
1357            ;; Handle numbers too.
1358            ;;
1359            ;; The following isn't quite right, but it's close enough.
1360            (list (concat "\\<\\("
1361                          "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1362                          "[0-9]+\\(\\.[0-9]*\\|\\)"
1363                          "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
1364                          "[lLfFdD]?")
1365                  '(0 mdw-number-face))
1366
1367            ;; And anything else is punctuation.
1368            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1369                  '(0 mdw-punct-face)))))
1370
1371   (mdw-post-config-mode-hack))
1372
1373 (define-derived-mode csharp-mode java-mode "C#"
1374   "Major mode for editing C# code.")
1375
1376 ;;;--------------------------------------------------------------------------
1377 ;;; Go programming configuration.
1378
1379 (defun mdw-fontify-go ()
1380
1381   (make-local-variable 'font-lock-keywords)
1382   (let ((go-keywords
1383          (mdw-regexps "break" "case" "chan" "const" "continue"
1384                       "default" "defer" "else" "fallthrough" "for"
1385                       "func" "go" "goto" "if" "import"
1386                       "interface" "map" "package" "range" "return"
1387                       "select" "struct" "switch" "type" "var")))
1388
1389     (setq font-lock-keywords
1390           (list
1391
1392            ;; Handle the keywords defined above.
1393            (list (concat "\\<\\(" go-keywords "\\)\\>")
1394                  '(0 font-lock-keyword-face))
1395
1396            ;; Handle numbers too.
1397            ;;
1398            ;; The following isn't quite right, but it's close enough.
1399            (list (concat "\\<\\("
1400                          "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1401                          "[0-9]+\\(\\.[0-9]*\\|\\)"
1402                          "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)")
1403                  '(0 mdw-number-face))
1404
1405            ;; And anything else is punctuation.
1406            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1407                  '(0 mdw-punct-face)))))
1408
1409   (mdw-post-config-mode-hack))
1410
1411 ;;;--------------------------------------------------------------------------
1412 ;;; Awk programming configuration.
1413
1414 ;; Make Awk indentation nice.
1415
1416 (defun mdw-awk-style ()
1417   (c-add-style "[mdw] Awk style"
1418                '((c-basic-offset . 2)
1419                  (c-offsets-alist (substatement-open . 0)
1420                                   (statement-cont . 0)
1421                                   (statement-case-intro . +)))
1422                t))
1423
1424 ;; Declare Awk fontification style.
1425
1426 (defun mdw-fontify-awk ()
1427
1428   ;; Miscellaneous fiddling.
1429   (mdw-awk-style)
1430   (setq c-backslash-column 72)
1431   (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
1432
1433   ;; Now define things to be fontified.
1434   (make-local-variable 'font-lock-keywords)
1435   (let ((c-keywords
1436          (mdw-regexps "BEGIN" "END" "ARGC" "ARGIND" "ARGV" "CONVFMT"
1437                       "ENVIRON" "ERRNO" "FIELDWIDTHS" "FILENAME" "FNR"
1438                       "FS" "IGNORECASE" "NF" "NR" "OFMT" "OFS" "ORS" "RS"
1439                       "RSTART" "RLENGTH" "RT"   "SUBSEP"
1440                       "atan2" "break" "close" "continue" "cos" "delete"
1441                       "do" "else" "exit" "exp" "fflush" "file" "for" "func"
1442                       "function" "gensub" "getline" "gsub" "if" "in"
1443                       "index" "int" "length" "log" "match" "next" "rand"
1444                       "return" "print" "printf" "sin" "split" "sprintf"
1445                       "sqrt" "srand" "strftime" "sub" "substr" "system"
1446                       "systime" "tolower" "toupper" "while")))
1447
1448     (setq font-lock-keywords
1449           (list
1450
1451            ;; Handle the keywords defined above.
1452            (list (concat "\\<\\(" c-keywords "\\)\\>")
1453                  '(0 font-lock-keyword-face))
1454
1455            ;; Handle numbers too.
1456            ;;
1457            ;; The following isn't quite right, but it's close enough.
1458            (list (concat "\\<\\("
1459                          "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1460                          "[0-9]+\\(\\.[0-9]*\\|\\)"
1461                          "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
1462                          "[uUlL]*")
1463                  '(0 mdw-number-face))
1464
1465            ;; And anything else is punctuation.
1466            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1467                  '(0 mdw-punct-face)))))
1468
1469   (mdw-post-config-mode-hack))
1470
1471 ;;;--------------------------------------------------------------------------
1472 ;;; Perl programming style.
1473
1474 ;; Perl indentation style.
1475
1476 (setq cperl-indent-level 2)
1477 (setq cperl-continued-statement-offset 2)
1478 (setq cperl-continued-brace-offset 0)
1479 (setq cperl-brace-offset -2)
1480 (setq cperl-brace-imaginary-offset 0)
1481 (setq cperl-label-offset 0)
1482
1483 ;; Define perl fontification style.
1484
1485 (defun mdw-fontify-perl ()
1486
1487   ;; Miscellaneous fiddling.
1488   (modify-syntax-entry ?$ "\\")
1489   (modify-syntax-entry ?$ "\\" font-lock-syntax-table)
1490   (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
1491
1492   ;; Now define fontification things.
1493   (make-local-variable 'font-lock-keywords)
1494   (let ((perl-keywords
1495          (mdw-regexps "and" "cmp" "continue" "do" "else" "elsif" "eq"
1496                       "for" "foreach" "ge" "gt" "goto" "if"
1497                       "last" "le" "lt" "local" "my" "ne" "next" "or"
1498                       "package" "redo" "require" "return" "sub"
1499                       "undef" "unless" "until" "use" "while")))
1500
1501     (setq font-lock-keywords
1502           (list
1503
1504            ;; Set up the keywords defined above.
1505            (list (concat "\\<\\(" perl-keywords "\\)\\>")
1506                  '(0 font-lock-keyword-face))
1507
1508            ;; At least numbers are simpler than C.
1509            (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
1510                          "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
1511                          "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
1512                  '(0 mdw-number-face))
1513
1514            ;; And anything else is punctuation.
1515            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1516                  '(0 mdw-punct-face)))))
1517
1518   (mdw-post-config-mode-hack))
1519
1520 (defun perl-number-tests (&optional arg)
1521   "Assign consecutive numbers to lines containing `#t'.  With ARG,
1522 strip numbers instead."
1523   (interactive "P")
1524   (save-excursion
1525     (goto-char (point-min))
1526     (let ((i 0) (fmt (if arg "" " %4d")))
1527       (while (search-forward "#t" nil t)
1528         (delete-region (point) (line-end-position))
1529         (setq i (1+ i))
1530         (insert (format fmt i)))
1531       (goto-char (point-min))
1532       (if (re-search-forward "\\(tests\\s-*=>\\s-*\\)\\w*" nil t)
1533           (replace-match (format "\\1%d" i))))))
1534
1535 ;;;--------------------------------------------------------------------------
1536 ;;; Python programming style.
1537
1538 (defun mdw-fontify-pythonic (keywords)
1539
1540   ;; Miscellaneous fiddling.
1541   (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
1542
1543   ;; Now define fontification things.
1544   (make-local-variable 'font-lock-keywords)
1545   (setq font-lock-keywords
1546         (list
1547
1548          ;; Set up the keywords defined above.
1549          (list (concat "\\<\\(" keywords "\\)\\>")
1550                '(0 font-lock-keyword-face))
1551
1552          ;; At least numbers are simpler than C.
1553          (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
1554                        "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
1555                        "\\([eE]\\([-+]\\|\\)[0-9_]+\\|[lL]\\|\\)")
1556                '(0 mdw-number-face))
1557
1558          ;; And anything else is punctuation.
1559          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1560                '(0 mdw-punct-face))))
1561
1562   (mdw-post-config-mode-hack))
1563
1564 ;; Define Python fontification styles.
1565
1566 (defun mdw-fontify-python ()
1567   (mdw-fontify-pythonic
1568    (mdw-regexps "and" "as" "assert" "break" "class" "continue" "def"
1569                 "del" "elif" "else" "except" "exec" "finally" "for"
1570                 "from" "global" "if" "import" "in" "is" "lambda"
1571                 "not" "or" "pass" "print" "raise" "return" "try"
1572                 "while" "with" "yield")))
1573
1574 (defun mdw-fontify-pyrex ()
1575   (mdw-fontify-pythonic
1576    (mdw-regexps "and" "as" "assert" "break" "cdef" "class" "continue"
1577                 "ctypedef" "def" "del" "elif" "else" "except" "exec"
1578                 "extern" "finally" "for" "from" "global" "if"
1579                 "import" "in" "is" "lambda" "not" "or" "pass" "print"
1580                 "raise" "return" "struct" "try" "while" "with"
1581                 "yield")))
1582
1583 ;;;--------------------------------------------------------------------------
1584 ;;; Icon programming style.
1585
1586 ;; Icon indentation style.
1587
1588 (setq icon-brace-offset 0
1589       icon-continued-brace-offset 0
1590       icon-continued-statement-offset 2
1591       icon-indent-level 2)
1592
1593 ;; Define Icon fontification style.
1594
1595 (defun mdw-fontify-icon ()
1596
1597   ;; Miscellaneous fiddling.
1598   (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
1599
1600   ;; Now define fontification things.
1601   (make-local-variable 'font-lock-keywords)
1602   (let ((icon-keywords
1603          (mdw-regexps "break" "by" "case" "create" "default" "do" "else"
1604                       "end" "every" "fail" "global" "if" "initial"
1605                       "invocable" "link" "local" "next" "not" "of"
1606                       "procedure" "record" "repeat" "return" "static"
1607                       "suspend" "then" "to" "until" "while"))
1608         (preprocessor-keywords
1609          (mdw-regexps "define" "else" "endif" "error" "ifdef" "ifndef"
1610                       "include" "line" "undef")))
1611     (setq font-lock-keywords
1612           (list
1613
1614            ;; Set up the keywords defined above.
1615            (list (concat "\\<\\(" icon-keywords "\\)\\>")
1616                  '(0 font-lock-keyword-face))
1617
1618            ;; The things that Icon calls keywords.
1619            (list "&\\sw+\\>" '(0 font-lock-variable-name-face))
1620
1621            ;; At least numbers are simpler than C.
1622            (list (concat "\\<[0-9]+"
1623                          "\\([rR][0-9a-zA-Z]+\\|"
1624                          "\\.[0-9]+\\([eE][+-]?[0-9]+\\)?\\)\\>\\|"
1625                          "\\.[0-9]+\\([eE][+-]?[0-9]+\\)?\\>")
1626                  '(0 mdw-number-face))
1627
1628            ;; Preprocessor.
1629            (list (concat "^[ \t]*$[ \t]*\\<\\("
1630                          preprocessor-keywords
1631                          "\\)\\>")
1632                  '(0 font-lock-keyword-face))
1633
1634            ;; And anything else is punctuation.
1635            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1636                  '(0 mdw-punct-face)))))
1637
1638   (mdw-post-config-mode-hack))
1639
1640 ;;;--------------------------------------------------------------------------
1641 ;;; ARM assembler programming configuration.
1642
1643 ;; There doesn't appear to be an Emacs mode for this yet.
1644 ;;
1645 ;; Better do something about that, I suppose.
1646
1647 (defvar arm-assembler-mode-map nil)
1648 (defvar arm-assembler-abbrev-table nil)
1649 (defvar arm-assembler-mode-syntax-table (make-syntax-table))
1650
1651 (or arm-assembler-mode-map
1652     (progn
1653       (setq arm-assembler-mode-map (make-sparse-keymap))
1654       (define-key arm-assembler-mode-map "\C-m" 'arm-assembler-newline)
1655       (define-key arm-assembler-mode-map [C-return] 'newline)
1656       (define-key arm-assembler-mode-map "\t" 'tab-to-tab-stop)))
1657
1658 (defun arm-assembler-mode ()
1659   "Major mode for ARM assembler programs"
1660   (interactive)
1661
1662   ;; Do standard major mode things.
1663   (kill-all-local-variables)
1664   (use-local-map arm-assembler-mode-map)
1665   (setq local-abbrev-table arm-assembler-abbrev-table)
1666   (setq major-mode 'arm-assembler-mode)
1667   (setq mode-name "ARM assembler")
1668
1669   ;; Set up syntax table.
1670   (set-syntax-table arm-assembler-mode-syntax-table)
1671   (modify-syntax-entry ?;   ; Nasty hack
1672                        "<" arm-assembler-mode-syntax-table)
1673   (modify-syntax-entry ?\n ">" arm-assembler-mode-syntax-table)
1674   (modify-syntax-entry ?_ "_" arm-assembler-mode-syntax-table)
1675
1676   (make-local-variable 'comment-start)
1677   (setq comment-start ";")
1678   (make-local-variable 'comment-end)
1679   (setq comment-end "")
1680   (make-local-variable 'comment-column)
1681   (setq comment-column 48)
1682   (make-local-variable 'comment-start-skip)
1683   (setq comment-start-skip ";+[ \t]*")
1684
1685   ;; Play with indentation.
1686   (make-local-variable 'indent-line-function)
1687   (setq indent-line-function 'indent-relative-maybe)
1688
1689   ;; Set fill prefix.
1690   (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)")
1691
1692   ;; Fiddle with fontification.
1693   (make-local-variable 'font-lock-keywords)
1694   (setq font-lock-keywords
1695         (list
1696
1697          ;; Handle numbers too.
1698          ;;
1699          ;; The following isn't quite right, but it's close enough.
1700          (list (concat "\\("
1701                        "&[0-9a-fA-F]+\\|"
1702                        "\\<[0-9]+\\(\\.[0-9]*\\|_[0-9a-zA-Z]+\\|\\)"
1703                        "\\)")
1704                '(0 mdw-number-face))
1705
1706          ;; Do something about operators.
1707          (list "^[^ \t]*[ \t]+\\(GET\\|LNK\\)[ \t]+\\([^;\n]*\\)"
1708                '(1 font-lock-keyword-face)
1709                '(2 font-lock-string-face))
1710          (list ":[a-zA-Z]+:"
1711                '(0 font-lock-keyword-face))
1712
1713          ;; Do menemonics and directives.
1714          (list "^[^ \t]*[ \t]+\\([a-zA-Z]+\\)"
1715                '(1 font-lock-keyword-face))
1716
1717          ;; And anything else is punctuation.
1718          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1719                '(0 mdw-punct-face)))
1720
1721   (mdw-post-config-mode-hack))
1722   (run-hooks 'arm-assembler-mode-hook))
1723
1724 ;;;--------------------------------------------------------------------------
1725 ;;; Assembler mode.
1726
1727 (defun mdw-fontify-asm ()
1728   (modify-syntax-entry ?' "\"")
1729   (modify-syntax-entry ?. "w")
1730   (setf fill-prefix nil)
1731   (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)"))
1732
1733 ;;;--------------------------------------------------------------------------
1734 ;;; TCL configuration.
1735
1736 (defun mdw-fontify-tcl ()
1737   (mapcar #'(lambda (ch) (modify-syntax-entry ch ".")) '(?$))
1738   (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
1739   (make-local-variable 'font-lock-keywords)
1740   (setq font-lock-keywords
1741         (list
1742          (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
1743                        "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
1744                        "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
1745                '(0 mdw-number-face))
1746          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1747                '(0 mdw-punct-face))))
1748   (mdw-post-config-mode-hack))
1749
1750 ;;;--------------------------------------------------------------------------
1751 ;;; REXX configuration.
1752
1753 (defun mdw-rexx-electric-* ()
1754   (interactive)
1755   (insert ?*)
1756   (rexx-indent-line))
1757
1758 (defun mdw-rexx-indent-newline-indent ()
1759   (interactive)
1760   (rexx-indent-line)
1761   (if abbrev-mode (expand-abbrev))
1762   (newline-and-indent))
1763
1764 (defun mdw-fontify-rexx ()
1765
1766   ;; Various bits of fiddling.
1767   (setq mdw-auto-indent nil)
1768   (local-set-key [?\C-m] 'mdw-rexx-indent-newline-indent)
1769   (local-set-key [?*] 'mdw-rexx-electric-*)
1770   (mapcar #'(lambda (ch) (modify-syntax-entry ch "w"))
1771           '(?! ?? ?# ?@ ?$))
1772   (mdw-standard-fill-prefix "\\([ \t]*/?\*[ \t]*\\)")
1773
1774   ;; Set up keywords and things for fontification.
1775   (make-local-variable 'font-lock-keywords-case-fold-search)
1776   (setq font-lock-keywords-case-fold-search t)
1777
1778   (setq rexx-indent 2)
1779   (setq rexx-end-indent rexx-indent)
1780   (setq rexx-cont-indent rexx-indent)
1781
1782   (make-local-variable 'font-lock-keywords)
1783   (let ((rexx-keywords
1784          (mdw-regexps "address" "arg" "by" "call" "digits" "do" "drop"
1785                       "else" "end" "engineering" "exit" "expose" "for"
1786                       "forever" "form" "fuzz" "if" "interpret" "iterate"
1787                       "leave" "linein" "name" "nop" "numeric" "off" "on"
1788                       "options" "otherwise" "parse" "procedure" "pull"
1789                       "push" "queue" "return" "say" "select" "signal"
1790                       "scientific" "source" "then" "trace" "to" "until"
1791                       "upper" "value" "var" "version" "when" "while"
1792                       "with"
1793
1794                       "abbrev" "abs" "bitand" "bitor" "bitxor" "b2x"
1795                       "center" "center" "charin" "charout" "chars"
1796                       "compare" "condition" "copies" "c2d" "c2x"
1797                       "datatype" "date" "delstr" "delword" "d2c" "d2x"
1798                       "errortext" "format" "fuzz" "insert" "lastpos"
1799                       "left" "length" "lineout" "lines" "max" "min"
1800                       "overlay" "pos" "queued" "random" "reverse" "right"
1801                       "sign" "sourceline" "space" "stream" "strip"
1802                       "substr" "subword" "symbol" "time" "translate"
1803                       "trunc" "value" "verify" "word" "wordindex"
1804                       "wordlength" "wordpos" "words" "xrange" "x2b" "x2c"
1805                       "x2d")))
1806
1807     (setq font-lock-keywords
1808           (list
1809
1810            ;; Set up the keywords defined above.
1811            (list (concat "\\<\\(" rexx-keywords "\\)\\>")
1812                  '(0 font-lock-keyword-face))
1813
1814            ;; Fontify all symbols the same way.
1815            (list (concat "\\<\\([0-9.][A-Za-z0-9.!?_#@$]*[Ee][+-]?[0-9]+\\|"
1816                          "[A-Za-z0-9.!?_#@$]+\\)")
1817                  '(0 font-lock-variable-name-face))
1818
1819            ;; And everything else is punctuation.
1820            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1821                  '(0 mdw-punct-face)))))
1822
1823   (mdw-post-config-mode-hack))
1824
1825 ;;;--------------------------------------------------------------------------
1826 ;;; Standard ML programming style.
1827
1828 (defun mdw-fontify-sml ()
1829
1830   ;; Make underscore an honorary letter.
1831   (modify-syntax-entry ?' "w")
1832
1833   ;; Set fill prefix.
1834   (mdw-standard-fill-prefix "\\([ \t]*(\*[ \t]*\\)")
1835
1836   ;; Now define fontification things.
1837   (make-local-variable 'font-lock-keywords)
1838   (let ((sml-keywords
1839          (mdw-regexps "abstype" "and" "andalso" "as"
1840                       "case"
1841                       "datatype" "do"
1842                       "else" "end" "eqtype" "exception"
1843                       "fn" "fun" "functor"
1844                       "handle"
1845                       "if" "in" "include" "infix" "infixr"
1846                       "let" "local"
1847                       "nonfix"
1848                       "of" "op" "open" "orelse"
1849                       "raise" "rec"
1850                       "sharing" "sig" "signature" "struct" "structure"
1851                       "then" "type"
1852                       "val"
1853                       "where" "while" "with" "withtype")))
1854
1855     (setq font-lock-keywords
1856           (list
1857
1858            ;; Set up the keywords defined above.
1859            (list (concat "\\<\\(" sml-keywords "\\)\\>")
1860                  '(0 font-lock-keyword-face))
1861
1862            ;; At least numbers are simpler than C.
1863            (list (concat "\\<\\(\\~\\|\\)"
1864                             "\\(0\\(\\([wW]\\|\\)[xX][0-9a-fA-F]+\\|"
1865                                    "[wW][0-9]+\\)\\|"
1866                                 "\\([0-9]+\\(\\.[0-9]+\\|\\)"
1867                                          "\\([eE]\\(\\~\\|\\)"
1868                                                 "[0-9]+\\|\\)\\)\\)")
1869                  '(0 mdw-number-face))
1870
1871            ;; And anything else is punctuation.
1872            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1873                  '(0 mdw-punct-face)))))
1874
1875   (mdw-post-config-mode-hack))
1876
1877 ;;;--------------------------------------------------------------------------
1878 ;;; Haskell configuration.
1879
1880 (defun mdw-fontify-haskell ()
1881
1882   ;; Fiddle with syntax table to get comments right.
1883   (modify-syntax-entry ?' "\"")
1884   (modify-syntax-entry ?- ". 123")
1885   (modify-syntax-entry ?{ ". 1b")
1886   (modify-syntax-entry ?} ". 4b")
1887   (modify-syntax-entry ?\n ">")
1888
1889   ;; Set fill prefix.
1890   (mdw-standard-fill-prefix "\\([ \t]*{?--?[ \t]*\\)")
1891
1892   ;; Fiddle with fontification.
1893   (make-local-variable 'font-lock-keywords)
1894   (let ((haskell-keywords
1895          (mdw-regexps "as" "case" "ccall" "class" "data" "default"
1896                       "deriving" "do" "else" "foreign" "hiding" "if"
1897                       "import" "in" "infix" "infixl" "infixr" "instance"
1898                       "let" "module" "newtype" "of" "qualified" "safe"
1899                       "stdcall" "then" "type" "unsafe" "where")))
1900
1901     (setq font-lock-keywords
1902           (list
1903            (list "--.*$"
1904                  '(0 font-lock-comment-face))
1905            (list (concat "\\<\\(" haskell-keywords "\\)\\>")
1906                  '(0 font-lock-keyword-face))
1907            (list (concat "\\<0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1908                          "\\<[0-9][0-9_]*\\(\\.[0-9]*\\|\\)"
1909                          "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)")
1910                  '(0 mdw-number-face))
1911            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1912                  '(0 mdw-punct-face)))))
1913
1914   (mdw-post-config-mode-hack))
1915
1916 ;;;--------------------------------------------------------------------------
1917 ;;; Erlang configuration.
1918
1919 (setq erlang-electric-commannds
1920       '(erlang-electric-newline erlang-electric-semicolon))
1921
1922 (defun mdw-fontify-erlang ()
1923
1924   ;; Set fill prefix.
1925   (mdw-standard-fill-prefix "\\([ \t]*{?%*[ \t]*\\)")
1926
1927   ;; Fiddle with fontification.
1928   (make-local-variable 'font-lock-keywords)
1929   (let ((erlang-keywords
1930          (mdw-regexps "after" "and" "andalso"
1931                       "band" "begin" "bnot" "bor" "bsl" "bsr" "bxor"
1932                       "case" "catch" "cond"
1933                       "div" "end" "fun" "if" "let" "not"
1934                       "of" "or" "orelse"
1935                       "query" "receive" "rem" "try" "when" "xor")))
1936
1937     (setq font-lock-keywords
1938           (list
1939            (list "%.*$"
1940                  '(0 font-lock-comment-face))
1941            (list (concat "\\<\\(" erlang-keywords "\\)\\>")
1942                  '(0 font-lock-keyword-face))
1943            (list (concat "^-\\sw+\\>")
1944                  '(0 font-lock-keyword-face))
1945            (list "\\<[0-9]+\\(\\|#[0-9a-zA-Z]+\\|[eE][+-]?[0-9]+\\)\\>"
1946                  '(0 mdw-number-face))
1947            (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1948                  '(0 mdw-punct-face)))))
1949
1950   (mdw-post-config-mode-hack))
1951
1952 ;;;--------------------------------------------------------------------------
1953 ;;; Texinfo configuration.
1954
1955 (defun mdw-fontify-texinfo ()
1956
1957   ;; Set fill prefix.
1958   (mdw-standard-fill-prefix "\\([ \t]*@c[ \t]+\\)")
1959
1960   ;; Real fontification things.
1961   (make-local-variable 'font-lock-keywords)
1962   (setq font-lock-keywords
1963         (list
1964
1965          ;; Environment names are keywords.
1966          (list "@\\(end\\)  *\\([a-zA-Z]*\\)?"
1967                '(2 font-lock-keyword-face))
1968
1969          ;; Unmark escaped magic characters.
1970          (list "\\(@\\)\\([@{}]\\)"
1971                '(1 font-lock-keyword-face)
1972                '(2 font-lock-variable-name-face))
1973
1974          ;; Make sure we get comments properly.
1975          (list "@c\\(\\|omment\\)\\( .*\\)?$"
1976                '(0 font-lock-comment-face))
1977
1978          ;; Command names are keywords.
1979          (list "@\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
1980                '(0 font-lock-keyword-face))
1981
1982          ;; Fontify TeX special characters as punctuation.
1983          (list "[{}]+"
1984                '(0 mdw-punct-face))))
1985
1986   (mdw-post-config-mode-hack))
1987
1988 ;;;--------------------------------------------------------------------------
1989 ;;; TeX and LaTeX configuration.
1990
1991 (defun mdw-fontify-tex ()
1992   (setq ispell-parser 'tex)
1993   (turn-on-reftex)
1994
1995   ;; Don't make maths into a string.
1996   (modify-syntax-entry ?$ ".")
1997   (modify-syntax-entry ?$ "." font-lock-syntax-table)
1998   (local-set-key [?$] 'self-insert-command)
1999
2000   ;; Set fill prefix.
2001   (mdw-standard-fill-prefix "\\([ \t]*%+[ \t]*\\)")
2002
2003   ;; Real fontification things.
2004   (make-local-variable 'font-lock-keywords)
2005   (setq font-lock-keywords
2006         (list
2007
2008          ;; Environment names are keywords.
2009          (list (concat "\\\\\\(begin\\|end\\|newenvironment\\)"
2010                        "{\\([^}\n]*\\)}")
2011                '(2 font-lock-keyword-face))
2012
2013          ;; Suspended environment names are keywords too.
2014          (list (concat "\\\\\\(suspend\\|resume\\)\\(\\[[^]]*\\]\\)?"
2015                        "{\\([^}\n]*\\)}")
2016                '(3 font-lock-keyword-face))
2017
2018          ;; Command names are keywords.
2019          (list "\\\\\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
2020                '(0 font-lock-keyword-face))
2021
2022          ;; Handle @/.../ for italics.
2023          ;; (list "\\(@/\\)\\([^/]*\\)\\(/\\)"
2024          ;;       '(1 font-lock-keyword-face)
2025          ;;       '(3 font-lock-keyword-face))
2026
2027          ;; Handle @*...* for boldness.
2028          ;; (list "\\(@\\*\\)\\([^*]*\\)\\(\\*\\)"
2029          ;;       '(1 font-lock-keyword-face)
2030          ;;       '(3 font-lock-keyword-face))
2031
2032          ;; Handle @`...' for literal syntax things.
2033          ;; (list "\\(@`\\)\\([^']*\\)\\('\\)"
2034          ;;       '(1 font-lock-keyword-face)
2035          ;;       '(3 font-lock-keyword-face))
2036
2037          ;; Handle @<...> for nonterminals.
2038          ;; (list "\\(@<\\)\\([^>]*\\)\\(>\\)"
2039          ;;       '(1 font-lock-keyword-face)
2040          ;;       '(3 font-lock-keyword-face))
2041
2042          ;; Handle other @-commands.
2043          ;; (list "@\\([^a-zA-Z]\\|[a-zA-Z]*\\)"
2044          ;;       '(0 font-lock-keyword-face))
2045
2046          ;; Make sure we get comments properly.
2047          (list "%.*"
2048                '(0 font-lock-comment-face))
2049
2050          ;; Fontify TeX special characters as punctuation.
2051          (list "[$^_{}#&]"
2052                '(0 mdw-punct-face))))
2053
2054   (mdw-post-config-mode-hack))
2055
2056 ;;;--------------------------------------------------------------------------
2057 ;;; SGML hacking.
2058
2059 (defun mdw-sgml-mode ()
2060   (interactive)
2061   (sgml-mode)
2062   (mdw-standard-fill-prefix "")
2063   (make-local-variable 'sgml-delimiters)
2064   (setq sgml-delimiters
2065         '("AND" "&" "COM" "--" "CRO" "&#" "DSC" "]" "DSO" "[" "DTGC" "]"
2066           "DTGO" "[" "ERO" "&" "ETAGO" ":e" "GRPC" ")" "GRPO" "(" "LIT" "\""
2067           "LITA" "'" "MDC" ">" "MDO" "<!" "MINUS" "-" "MSC" "]]" "NESTC" "{"
2068           "NET" "}" "OPT" "?" "OR" "|" "PERO" "%" "PIC" ">" "PIO" "<?"
2069           "PLUS" "+" "REFC" "." "REP" "*" "RNI" "#" "SEQ" "," "STAGO" ":"
2070           "TAGC" "." "VI" "=" "MS-START" "<![" "MS-END" "]]>"
2071           "XML-ECOM" "-->" "XML-PIC" "?>" "XML-SCOM" "<!--" "XML-TAGCE" "/>"
2072           "NULL" ""))
2073   (setq major-mode 'mdw-sgml-mode)
2074   (setq mode-name "[mdw] SGML")
2075   (run-hooks 'mdw-sgml-mode-hook))
2076
2077 ;;;--------------------------------------------------------------------------
2078 ;;; Shell scripts.
2079
2080 (defun mdw-setup-sh-script-mode ()
2081
2082   ;; Fetch the shell interpreter's name.
2083   (let ((shell-name sh-shell-file))
2084
2085     ;; Try reading the hash-bang line.
2086     (save-excursion
2087       (goto-char (point-min))
2088       (if (looking-at "#![ \t]*\\([^ \t\n]*\\)")
2089           (setq shell-name (match-string 1))))
2090
2091     ;; Now try to set the shell.
2092     ;;
2093     ;; Don't let `sh-set-shell' bugger up my script.
2094     (let ((executable-set-magic #'(lambda (s &rest r) s)))
2095       (sh-set-shell shell-name)))
2096
2097   ;; Now enable my keys and the fontification.
2098   (mdw-misc-mode-config)
2099
2100   ;; Set the indentation level correctly.
2101   (setq sh-indentation 2)
2102   (setq sh-basic-offset 2))
2103
2104 ;;;--------------------------------------------------------------------------
2105 ;;; Emacs shell mode.
2106
2107 (defun mdw-eshell-prompt ()
2108   (let ((left "[") (right "]"))
2109     (when (= (user-uid) 0)
2110       (setq left "«" right "»"))
2111     (concat left
2112             (save-match-data
2113               (replace-regexp-in-string "\\..*$" "" (system-name)))
2114             " "
2115             (eshell/pwd)
2116             right)))
2117 (setq eshell-prompt-function 'mdw-eshell-prompt)
2118 (setq eshell-prompt-regexp "^\\[[^]>]+\\(\\]\\|>>?\\)")
2119
2120 (defalias 'eshell/e 'find-file)
2121 (defalias 'eshell/w3m 'w3m-goto-url)
2122
2123 (mdw-define-face eshell-prompt (t :weight bold))
2124 (mdw-define-face eshell-ls-archive (t :weight bold :foreground "red"))
2125 (mdw-define-face eshell-ls-backup (t :foreground "lightgrey" :slant italic))
2126 (mdw-define-face eshell-ls-product (t :foreground "lightgrey" :slant italic))
2127 (mdw-define-face eshell-ls-clutter (t :foreground "lightgrey" :slant italic))
2128 (mdw-define-face eshell-ls-executable (t :weight bold))
2129 (mdw-define-face eshell-ls-directory (t :foreground "cyan" :weight bold))
2130 (mdw-define-face eshell-ls-readonly (t nil))
2131 (mdw-define-face eshell-ls-symlink (t :foreground "cyan"))
2132
2133 ;;;--------------------------------------------------------------------------
2134 ;;; Messages-file mode.
2135
2136 (defun messages-mode-guts ()
2137   (setq messages-mode-syntax-table (make-syntax-table))
2138   (set-syntax-table messages-mode-syntax-table)
2139   (modify-syntax-entry ?0 "w" messages-mode-syntax-table)
2140   (modify-syntax-entry ?1 "w" messages-mode-syntax-table)
2141   (modify-syntax-entry ?2 "w" messages-mode-syntax-table)
2142   (modify-syntax-entry ?3 "w" messages-mode-syntax-table)
2143   (modify-syntax-entry ?4 "w" messages-mode-syntax-table)
2144   (modify-syntax-entry ?5 "w" messages-mode-syntax-table)
2145   (modify-syntax-entry ?6 "w" messages-mode-syntax-table)
2146   (modify-syntax-entry ?7 "w" messages-mode-syntax-table)
2147   (modify-syntax-entry ?8 "w" messages-mode-syntax-table)
2148   (modify-syntax-entry ?9 "w" messages-mode-syntax-table)
2149   (make-local-variable 'comment-start)
2150   (make-local-variable 'comment-end)
2151   (make-local-variable 'indent-line-function)
2152   (setq indent-line-function 'indent-relative)
2153   (mdw-standard-fill-prefix "\\([ \t]*\\(;\\|/?\\*\\)+[ \t]*\\)")
2154   (make-local-variable 'font-lock-defaults)
2155   (make-local-variable 'messages-mode-keywords)
2156   (let ((keywords
2157          (mdw-regexps "array" "bitmap" "callback" "docs[ \t]+enum"
2158                       "export" "enum" "fixed-octetstring" "flags"
2159                       "harmless" "map" "nested" "optional"
2160                       "optional-tagged" "package" "primitive"
2161                       "primitive-nullfree" "relaxed[ \t]+enum"
2162                       "set" "table" "tagged-optional"   "union"
2163                       "variadic" "vector" "version" "version-tag")))
2164     (setq messages-mode-keywords
2165           (list
2166            (list (concat "\\<\\(" keywords "\\)\\>:")
2167                  '(0 font-lock-keyword-face))
2168            '("\\([-a-zA-Z0-9]+:\\)" (0 font-lock-warning-face))
2169            '("\\(\\<[a-z][-_a-zA-Z0-9]*\\)"
2170              (0 font-lock-variable-name-face))
2171            '("\\<\\([0-9]+\\)\\>" (0 mdw-number-face))
2172            '("\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2173              (0 mdw-punct-face)))))
2174   (setq font-lock-defaults
2175         '(messages-mode-keywords nil nil nil nil))
2176   (run-hooks 'messages-file-hook))
2177
2178 (defun messages-mode ()
2179   (interactive)
2180   (fundamental-mode)
2181   (setq major-mode 'messages-mode)
2182   (setq mode-name "Messages")
2183   (messages-mode-guts)
2184   (modify-syntax-entry ?# "<" messages-mode-syntax-table)
2185   (modify-syntax-entry ?\n ">" messages-mode-syntax-table)
2186   (setq comment-start "# ")
2187   (setq comment-end "")
2188   (turn-on-font-lock-if-enabled)
2189   (run-hooks 'messages-mode-hook))
2190
2191 (defun cpp-messages-mode ()
2192   (interactive)
2193   (fundamental-mode)
2194   (setq major-mode 'cpp-messages-mode)
2195   (setq mode-name "CPP Messages")
2196   (messages-mode-guts)
2197   (modify-syntax-entry ?* ". 23" messages-mode-syntax-table)
2198   (modify-syntax-entry ?/ ". 14" messages-mode-syntax-table)
2199   (setq comment-start "/* ")
2200   (setq comment-end " */")
2201   (let ((preprocessor-keywords
2202          (mdw-regexps "assert" "define" "elif" "else" "endif" "error"
2203                       "ident" "if" "ifdef" "ifndef" "import" "include"
2204                       "line" "pragma" "unassert" "undef" "warning")))
2205     (setq messages-mode-keywords
2206           (append (list (list (concat "^[ \t]*\\#[ \t]*"
2207                                       "\\(include\\|import\\)"
2208                                       "[ \t]*\\(<[^>]+\\(>\\|\\)\\)")
2209                               '(2 font-lock-string-face))
2210                         (list (concat "^\\([ \t]*#[ \t]*\\(\\("
2211                                       preprocessor-keywords
2212                                       "\\)\\>\\|[0-9]+\\|$\\)\\)")
2213                               '(1 font-lock-keyword-face)))
2214                   messages-mode-keywords)))
2215   (turn-on-font-lock-if-enabled)
2216   (run-hooks 'cpp-messages-mode-hook))
2217
2218 (add-hook 'messages-mode-hook 'mdw-misc-mode-config t)
2219 (add-hook 'cpp-messages-mode-hook 'mdw-misc-mode-config t)
2220 ; (add-hook 'messages-file-hook 'mdw-fontify-messages t)
2221
2222 ;;;--------------------------------------------------------------------------
2223 ;;; Messages-file mode.
2224
2225 (defvar mallow-driver-substitution-face 'mallow-driver-substitution-face
2226   "Face to use for subsittution directives.")
2227 (make-face 'mallow-driver-substitution-face)
2228 (defvar mallow-driver-text-face 'mallow-driver-text-face
2229   "Face to use for body text.")
2230 (make-face 'mallow-driver-text-face)
2231
2232 (defun mallow-driver-mode ()
2233   (interactive)
2234   (fundamental-mode)
2235   (setq major-mode 'mallow-driver-mode)
2236   (setq mode-name "Mallow driver")
2237   (setq mallow-driver-mode-syntax-table (make-syntax-table))
2238   (set-syntax-table mallow-driver-mode-syntax-table)
2239   (make-local-variable 'comment-start)
2240   (make-local-variable 'comment-end)
2241   (make-local-variable 'indent-line-function)
2242   (setq indent-line-function 'indent-relative)
2243   (mdw-standard-fill-prefix "\\([ \t]*\\(;\\|/?\\*\\)+[ \t]*\\)")
2244   (make-local-variable 'font-lock-defaults)
2245   (make-local-variable 'mallow-driver-mode-keywords)
2246   (let ((keywords
2247          (mdw-regexps "each" "divert" "file" "if"
2248                       "perl" "set" "string" "type" "write")))
2249     (setq mallow-driver-mode-keywords
2250           (list
2251            (list (concat "^%\\s *\\(}\\|\\(" keywords "\\)\\>\\).*$")
2252                  '(0 font-lock-keyword-face))
2253            (list "^%\\s *\\(#.*\\|\\)$"
2254                  '(0 font-lock-comment-face))
2255            (list "^%"
2256                  '(0 font-lock-keyword-face))
2257            (list "^|?\\(.+\\)$" '(1 mallow-driver-text-face))
2258            (list "\\${[^}]*}"
2259                  '(0 mallow-driver-substitution-face t)))))
2260   (setq font-lock-defaults
2261         '(mallow-driver-mode-keywords nil nil nil nil))
2262   (modify-syntax-entry ?\" "_" mallow-driver-mode-syntax-table)
2263   (modify-syntax-entry ?\n ">" mallow-driver-mode-syntax-table)
2264   (setq comment-start "%# ")
2265   (setq comment-end "")
2266   (turn-on-font-lock-if-enabled)
2267   (run-hooks 'mallow-driver-mode-hook))
2268
2269 (add-hook 'mallow-driver-hook 'mdw-misc-mode-config t)
2270
2271 ;;;--------------------------------------------------------------------------
2272 ;;; NFast debugs.
2273
2274 (defun nfast-debug-mode ()
2275   (interactive)
2276   (fundamental-mode)
2277   (setq major-mode 'nfast-debug-mode)
2278   (setq mode-name "NFast debug")
2279   (setq messages-mode-syntax-table (make-syntax-table))
2280   (set-syntax-table messages-mode-syntax-table)
2281   (make-local-variable 'font-lock-defaults)
2282   (make-local-variable 'nfast-debug-mode-keywords)
2283   (setq truncate-lines t)
2284   (setq nfast-debug-mode-keywords
2285         (list
2286          '("^\\(NFast_\\(Connect\\|Disconnect\\|Submit\\|Wait\\)\\)"
2287            (0 font-lock-keyword-face))
2288          (list (concat "^[ \t]+\\(\\("
2289                        "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"
2290                        "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"
2291                        "[ \t]+\\)*"
2292                        "[0-9a-fA-F]+\\)[ \t]*$")
2293            '(0 mdw-number-face))
2294          '("^[ \t]+\.status=[ \t]+\\<\\(OK\\)\\>"
2295            (1 font-lock-keyword-face))
2296          '("^[ \t]+\.status=[ \t]+\\<\\([a-zA-Z][0-9a-zA-Z]*\\)\\>"
2297            (1 font-lock-warning-face))
2298          '("^[ \t]+\.status[ \t]+\\<\\(zero\\)\\>"
2299            (1 nil))
2300          (list (concat "^[ \t]+\\.cmd=[ \t]+"
2301                        "\\<\\([a-zA-Z][0-9a-zA-Z]*\\)\\>")
2302            '(1 font-lock-keyword-face))
2303          '("-?\\<\\([0-9]+\\|0x[0-9a-fA-F]+\\)\\>" (0 mdw-number-face))
2304          '("^\\([ \t]+[a-z0-9.]+\\)" (0 font-lock-variable-name-face))
2305          '("\\<\\([a-z][a-z0-9.]+\\)\\>=" (1 font-lock-variable-name-face))
2306          '("\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" (0 mdw-punct-face))))
2307   (setq font-lock-defaults
2308         '(nfast-debug-mode-keywords nil nil nil nil))
2309   (turn-on-font-lock-if-enabled)
2310   (run-hooks 'nfast-debug-mode-hook))
2311
2312 ;;;--------------------------------------------------------------------------
2313 ;;; Other languages.
2314
2315 ;; Smalltalk.
2316
2317 (defun mdw-setup-smalltalk ()
2318   (and mdw-auto-indent
2319        (local-set-key "\C-m" 'smalltalk-newline-and-indent))
2320   (make-local-variable 'mdw-auto-indent)
2321   (setq mdw-auto-indent nil)
2322   (local-set-key "\C-i" 'smalltalk-reindent))
2323
2324 (defun mdw-fontify-smalltalk ()
2325   (make-local-variable 'font-lock-keywords)
2326   (setq font-lock-keywords
2327         (list
2328          (list "\\<[A-Z][a-zA-Z0-9]*\\>"
2329                '(0 font-lock-keyword-face))
2330          (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
2331                        "[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
2332                        "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
2333                '(0 mdw-number-face))
2334          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2335                '(0 mdw-punct-face))))
2336   (mdw-post-config-mode-hack))
2337
2338 ;; Lispy languages.
2339
2340 ;; Unpleasant bodge.
2341 (unless (boundp 'slime-repl-mode-map)
2342   (setq slime-repl-mode-map (make-sparse-keymap)))
2343
2344 (defun mdw-indent-newline-and-indent ()
2345   (interactive)
2346   (indent-for-tab-command)
2347   (newline-and-indent))
2348
2349 (eval-after-load "cl-indent"
2350   '(progn
2351      (mapc #'(lambda (pair)
2352                (put (car pair)
2353                     'common-lisp-indent-function
2354                     (cdr pair)))
2355       '((destructuring-bind . ((&whole 4 &rest 1) 4 &body))
2356         (multiple-value-bind . ((&whole 4 &rest 1) 4 &body))))))
2357
2358 (defun mdw-common-lisp-indent ()
2359   (make-local-variable 'lisp-indent-function)
2360   (setq lisp-indent-function 'common-lisp-indent-function))
2361
2362 (setq lisp-simple-loop-indentation 2
2363       lisp-loop-keyword-indentation 6
2364       lisp-loop-forms-indentation 6)
2365
2366 (defun mdw-fontify-lispy ()
2367
2368   ;; Set fill prefix.
2369   (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)")
2370
2371   ;; Not much fontification needed.
2372   (make-local-variable 'font-lock-keywords)
2373   (setq font-lock-keywords
2374         (list
2375          (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2376                '(0 mdw-punct-face))))
2377
2378   (mdw-post-config-mode-hack))
2379
2380 (defun comint-send-and-indent ()
2381   (interactive)
2382   (comint-send-input)
2383   (and mdw-auto-indent
2384        (indent-for-tab-command)))
2385
2386 (defun mdw-setup-m4 ()
2387   (mdw-standard-fill-prefix "\\([ \t]*\\(?:#+\\|\\<dnl\\>\\)[ \t]*\\)"))
2388
2389 ;;;--------------------------------------------------------------------------
2390 ;;; Text mode.
2391
2392 (defun mdw-text-mode ()
2393   (setq fill-column 72)
2394   (flyspell-mode t)
2395   (mdw-standard-fill-prefix
2396    "\\([ \t]*\\([>#|:] ?\\)*[ \t]*\\)" 3)
2397   (auto-fill-mode 1))
2398
2399 ;;;--------------------------------------------------------------------------
2400 ;;; Outline and hide/show modes.
2401
2402 (defun mdw-outline-collapse-all ()
2403   "Completely collapse everything in the entire buffer."
2404   (interactive)
2405   (save-excursion
2406     (goto-char (point-min))
2407     (while (< (point) (point-max))
2408       (hide-subtree)
2409       (forward-line))))
2410
2411 (setq hs-hide-comments-when-hiding-all nil)
2412
2413 (defadvice hs-hide-all (after hide-first-comment activate)
2414   (save-excursion (hs-hide-initial-comment-block)))
2415
2416 ;;;--------------------------------------------------------------------------
2417 ;;; Shell mode.
2418
2419 (defun mdw-sh-mode-setup ()
2420   (local-set-key [?\C-a] 'comint-bol)
2421   (add-hook 'comint-output-filter-functions
2422             'comint-watch-for-password-prompt))
2423
2424 (defun mdw-term-mode-setup ()
2425   (setq term-prompt-regexp shell-prompt-pattern)
2426   (make-local-variable 'mouse-yank-at-point)
2427   (make-local-variable 'transient-mark-mode)
2428   (setq mouse-yank-at-point t)
2429   (auto-fill-mode -1)
2430   (setq tab-width 8))
2431
2432 (defun term-send-meta-right () (interactive) (term-send-raw-string "\e\e[C"))
2433 (defun term-send-meta-left  () (interactive) (term-send-raw-string "\e\e[D"))
2434 (defun term-send-ctrl-uscore () (interactive) (term-send-raw-string "\C-_"))
2435 (defun term-send-meta-meta-something ()
2436   (interactive)
2437   (term-send-raw-string "\e\e")
2438   (term-send-raw))
2439 (eval-after-load 'term
2440   '(progn
2441      (define-key term-raw-map [?\e ?\e] nil)
2442      (define-key term-raw-map [?\e ?\e t] 'term-send-meta-meta-something)
2443      (define-key term-raw-map [?\C-/] 'term-send-ctrl-uscore)
2444      (define-key term-raw-map [M-right] 'term-send-meta-right)
2445      (define-key term-raw-map [?\e ?\M-O ?C] 'term-send-meta-right)
2446      (define-key term-raw-map [M-left] 'term-send-meta-left)
2447      (define-key term-raw-map [?\e ?\M-O ?D] 'term-send-meta-left)))
2448
2449 ;;;--------------------------------------------------------------------------
2450 ;;; Inferior Emacs Lisp.
2451
2452 (setq comint-prompt-read-only t)
2453
2454 (eval-after-load "comint"
2455   '(progn
2456      (define-key comint-mode-map "\C-w" 'comint-kill-region)
2457      (define-key comint-mode-map [C-S-backspace] 'comint-kill-whole-line)))
2458
2459 (eval-after-load "ielm"
2460   '(progn
2461      (define-key ielm-map "\C-w" 'comint-kill-region)
2462      (define-key ielm-map [C-S-backspace] 'comint-kill-whole-line)))
2463
2464 ;;;----- That's all, folks --------------------------------------------------
2465
2466 (provide 'dot-emacs)