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