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