chiark / gitweb /
Now that Emacs starts up pretty quick, favour it over lesser editors.
[profile] / dot-emacs.el
CommitLineData
502f4699 1;;; -*- mode: emacs-lisp; coding: utf-8 -*-
f617db13
MW
2;;;
3;;; $Id$
4;;;
5;;; Functions and macros for .emacs
6;;;
7;;; (c) 2004 Mark Wooding
8;;;
9
10;;;----- Licensing notice ---------------------------------------------------
11;;;
12;;; This program is free software; you can redistribute it and/or modify
13;;; it under the terms of the GNU General Public License as published by
14;;; the Free Software Foundation; either version 2 of the License, or
15;;; (at your option) any later version.
852cd5fb 16;;;
f617db13
MW
17;;; This program is distributed in the hope that it will be useful,
18;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;;; GNU General Public License for more details.
852cd5fb 21;;;
f617db13
MW
22;;; You should have received a copy of the GNU General Public License
23;;; along with this program; if not, write to the Free Software Foundation,
24;;; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25
c7a8da49
MW
26;;;----- Check command-line -------------------------------------------------
27
28(defvar mdw-fast-startup nil
29 "Whether .emacs should optimize for rapid startup.
30This may be at the expense of cool features.")
31(let ((probe nil) (next command-line-args))
32 (message "probe = %s" probe)
33 (message "next = %s" next)
34 (while next
35 (cond ((string= (car next) "--mdw-fast-startup")
36 (setq mdw-fast-startup t)
37 (if probe
38 (rplacd probe (cdr next))
39 (setq command-line-args (cdr next))))
40 (t
41 (setq probe next)))
42 (setq next (cdr next))))
43
f617db13
MW
44;;;----- Some general utilities ---------------------------------------------
45
c7a8da49
MW
46(evan-when-compile (or (fboundp 'make-regexp)
47 (load "make-regexp")))
48
49(defmacro mdw-regexps (&rest list)
50 "Turn a LIST of strings into a single regular expression at compile-time."
51 (make-regexp list))
52
f617db13
MW
53;; --- Some error trapping ---
54;;
55;; If individual bits of this file go tits-up, we don't particularly want
56;; the whole lot to stop right there and then, because it's bloody annoying.
57
58(defmacro trap (&rest forms)
59 "Execute FORMS without allowing errors to propagate outside."
60 `(condition-case err
61 ,(if (cdr forms) (cons 'progn forms) (car forms))
8df912e4
MW
62 (error (message "Error (trapped): %s in %s"
63 (error-message-string err)
64 ',forms))))
f617db13 65
f141fe0f
MW
66;; --- Configuration reading ---
67
68(defvar mdw-config nil)
69(defun mdw-config (sym)
70 "Read the configuration variable named SYM."
71 (unless mdw-config
72 (setq mdw-config (with-temp-buffer
73 (insert-file-contents "~/.mdw.conf")
74 (replace-regexp "^[ \t]*\\(#.*\\|\\)\n" ""
75 nil (point-min) (point-max))
76 (replace-regexp (concat "^[ \t]*"
77 "\\([-a-zA-Z0-9_.]*\\)"
78 "[ \t]*=[ \t]*"
79 "\\(.*[^ \t\n]\\|\\)"
80 "[ \t]**\\(\n\\|$\\)")
81 "(\\1 . \"\\2\") "
82 nil (point-min) (point-max))
83 (car (read-from-string
84 (concat "(" (buffer-string) ")"))))))
85 (cdr (assq sym mdw-config)))
86
cb6e2cd1
MW
87;; --- Is an Emacs library available? ---
88
89(defun library-exists-p (name)
90 "Return non-nil if NAME.el (or NAME.elc) is somewhere on the Emacs load
91path. The non-nil value is the filename we found for the library."
92 (let ((path load-path) elt (foundp nil))
93 (while (and path (not foundp))
94 (setq elt (car path))
95 (setq path (cdr path))
96 (setq foundp (or (let ((file (concat elt "/" name ".elc")))
97 (and (file-exists-p file) file))
98 (let ((file (concat elt "/" name ".el")))
99 (and (file-exists-p file) file)))))
100 foundp))
101
102(defun maybe-autoload (symbol file &optional docstring interactivep type)
103 "Set an autoload if the file actually exists."
104 (and (library-exists-p file)
105 (autoload symbol file docstring interactivep type)))
106
f617db13
MW
107;; --- Splitting windows ---
108
b5d724dd
MW
109(or (and (fboundp 'scroll-bar-columns)
110 (fboundp 'fringe-columns))
111 (progn
112 (defun scroll-bar-columns (side)
113 (cond ((eq side 'left) 0)
114 (window-system 3)
115 (t 1)))
116 (defun fringe-columns (side)
117 (cond ((not window-system) 0)
118 ((eq side 'left) 1)
119 (t 2)))))
120
f617db13
MW
121(defun mdw-divvy-window (&optional w)
122 "Split a wide window into appropriate widths."
123 (interactive)
b5d724dd
MW
124 (or w (setq w (if (and window-system
125 (>= emacs-major-version 22))
126 77
127 78)))
128 (let* ((win (selected-window))
129 (sb-width (if (not window-system)
130 1
131 (+ (scroll-bar-columns 'left)
132 (scroll-bar-columns 'right)
133 (fringe-columns 'left)
134 (fringe-columns 'right))))
135 (c (/ (+ (window-width) sb-width)
136 (+ w sb-width))))
f617db13
MW
137 (while (> c 1)
138 (setq c (1- c))
b5d724dd 139 (split-window-horizontally (+ w sb-width))
f617db13
MW
140 (other-window 1))
141 (select-window win)))
142
143;; --- Functions for sexp diary entries ---
144
145(defun mdw-weekday (l)
146 "Return non-nil if `date' falls on one of the days of the week in L.
147
148L is a list of day numbers (from 0 to 6 for Sunday through to Saturday) or
149symbols `sunday', `monday', etc. (or a mixture). If the date stored in
150`date' falls on a listed day, then the function returns non-nil."
151 (let ((d (calendar-day-of-week date)))
152 (or (memq d l)
153 (memq (nth d '(sunday monday tuesday wednesday
154 thursday friday saturday)) l))))
155
156(defun mdw-todo (&optional when)
157 "Return non-nil today, or on WHEN, whichever is later."
158 (let ((w (calendar-absolute-from-gregorian (calendar-current-date)))
159 (d (calendar-absolute-from-gregorian date)))
160 (if when
161 (setq w (max w (calendar-absolute-from-gregorian
162 (cond
163 ((not european-calendar-style)
164 when)
165 ((> (car when) 100)
166 (list (nth 1 when)
167 (nth 2 when)
168 (nth 0 when)))
169 (t
170 (list (nth 1 when)
171 (nth 0 when)
172 (nth 2 when))))))))
173 (eq w d)))
174
175;;;----- Utility functions --------------------------------------------------
176
b5d724dd
MW
177(or (fboundp 'line-number-at-pos)
178 (defun line-number-at-pos (&optional pos)
179 (let ((opoint (or pos (point))) start)
180 (save-excursion
181 (save-restriction
182 (goto-char (point-min))
183 (widen)
184 (forward-line 0)
185 (setq start (point))
186 (goto-char opoint)
187 (forward-line 0)
188 (1+ (count-lines 1 (point))))))))
459c9fb2 189
f617db13
MW
190;; --- mdw-uniquify-alist ---
191
192(defun mdw-uniquify-alist (&rest alists)
193
194 "Return the concatenation of the ALISTS with duplicate elements removed.
195
196The first association with a given key prevails; others are ignored. The
197input lists are not modified, although they'll probably become garbage."
198
199 (and alists
200 (let ((start-list (cons nil nil)))
201 (mdw-do-uniquify start-list
202 start-list
203 (car alists)
204 (cdr alists)))))
205
206;; --- mdw-do-uniquify ---
207;;
208;; The DONE argument is a list whose first element is `nil'. It contains the
209;; uniquified alist built so far. The leading `nil' is stripped off at the
210;; end of the operation; it's only there so that DONE always references a
211;; cons cell. END refers to the final cons cell in the DONE list; it is
212;; modified in place each time to avoid the overheads of `append'ing all the
213;; time. The L argument is the alist we're currently processing; the
214;; remaining alists are given in REST.
215
216(defun mdw-do-uniquify (done end l rest)
217 "A helper function for mdw-uniquify-alist."
218
219 ;; --- There are several different cases to deal with here ---
220
221 (cond
222
223 ;; --- Current list isn't empty ---
224 ;;
225 ;; Add the first item to the DONE list if there's not an item with the
226 ;; same KEY already there.
227
228 (l (or (assoc (car (car l)) done)
229 (progn
230 (setcdr end (cons (car l) nil))
231 (setq end (cdr end))))
232 (mdw-do-uniquify done end (cdr l) rest))
233
234 ;; --- The list we were working on is empty ---
235 ;;
236 ;; Shunt the next list into the current list position and go round again.
237
238 (rest (mdw-do-uniquify done end (car rest) (cdr rest)))
239
240 ;; --- Everything's done ---
241 ;;
242 ;; Remove the leading `nil' from the DONE list and return it. Finished!
243
244 (t (cdr done))))
245
246;; --- Insert a date ---
247
248(defun date ()
249 "Insert the current date in a pleasing way."
250 (interactive)
251 (insert (save-excursion
252 (let ((buffer (get-buffer-create "*tmp*")))
253 (unwind-protect (progn (set-buffer buffer)
254 (erase-buffer)
255 (shell-command "date +%Y-%m-%d" t)
256 (goto-char (mark))
257 (delete-backward-char 1)
258 (buffer-string))
259 (kill-buffer buffer))))))
260
261;; --- UUencoding ---
262
263(defun uuencode (file &optional name)
264 "UUencodes a file, maybe calling it NAME, into the current buffer."
265 (interactive "fInput file name: ")
266
267 ;; --- If NAME isn't specified, then guess from the filename ---
268
269 (if (not name)
270 (setq name
271 (substring file
272 (or (string-match "[^/]*$" file) 0))))
273
274 (print (format "uuencode `%s' `%s'" file name))
275
276 ;; --- Now actually do the thing ---
277
278 (call-process "uuencode" file t nil name))
279
280(defvar np-file "~/.np"
281 "*Where the `now-playing' file is.")
282
283(defun np (&optional arg)
284 "Grabs a `now-playing' string."
285 (interactive)
286 (save-excursion
287 (or arg (progn
852cd5fb 288 (goto-char (point-max))
f617db13 289 (insert "\nNP: ")
852cd5fb 290 (insert-file np-file)))))
f617db13 291
c7a8da49
MW
292(defun mdw-check-autorevert ()
293 "Sets global-auto-revert-ignore-buffer appropriately for this buffer,
294taking into consideration whether it's been found using tramp, which seems to
295get itself into a twist."
296 (cond ((and (buffer-file-name)
297 (tramp-tramp-file-p (buffer-file-name)))
298 (unless global-auto-revert-ignore-buffer
299 (setq global-auto-revert-ignore-buffer 'tramp)))
300 ((eq global-auto-revert-ignore-buffer 'tramp)
301 (setq global-auto-revert-ignore-buffer nil))))
302
303(defadvice find-file (after mdw-autorevert activate)
304 (mdw-check-autorevert))
305(defadvice write-file (after mdw-autorevert activate)
306 (mdw-check-autorevert)))
f617db13
MW
307
308(defun mdwmail-mode ()
309 "Major mode for editing news and mail messages from external programs
310Not much right now. Just support for doing MailCrypt stuff."
311 (interactive)
312 (kill-all-local-variables)
313 (use-local-map text-mode-map)
314 (setq local-abbrev-table text-mode-abbrev-table)
315 (setq major-mode 'mdwmail-mode)
316 (setq mode-name "[mdw] mail")
317 (make-local-variable 'paragraph-separate)
318 (make-local-variable 'paragraph-start)
319 (setq paragraph-start (concat "[ \t]*[-_][-_][-_]+$\\|^-- \\|-----\\|"
320 paragraph-start))
321 (setq paragraph-separate (concat "[ \t]*[-_][-_][-_]+$\\|^-- \\|-----\\|"
322 paragraph-separate))
323 (run-hooks 'text-mode-hook 'mdwmail-mode-hook 'mail-setup-hook))
324
325;; --- How to encrypt in mdwmail ---
326
327(defun mdwmail-mc-encrypt (&optional recip scm start end from sign)
328 (or start
329 (setq start (save-excursion
330 (goto-char (point-min))
331 (or (search-forward "\n\n" nil t) (point-min)))))
332 (or end
333 (setq end (point-max)))
334 (mc-encrypt-generic recip scm start end from sign))
335
336;; --- How to sign in mdwmail ---
337
338(defun mdwmail-mc-sign (key scm start end uclr)
339 (or start
340 (setq start (save-excursion
341 (goto-char (point-min))
342 (or (search-forward "\n\n" nil t) (point-min)))))
343 (or end
344 (setq end (point-max)))
345 (mc-sign-generic key scm start end uclr))
346
347;; --- Some signature mangling ---
348
349(defun mdwmail-mangle-signature ()
350 (save-excursion
351 (goto-char (point-min))
352 (perform-replace "\n-- \n" "\n-- " nil nil nil)))
353(add-hook 'mail-setup-hook 'mdwmail-mangle-signature)
354
a203fba8
MW
355;;;----- URL viewing --------------------------------------------------------
356
357(defun mdw-w3m-browse-url (url &optional new-session-p)
358 "Invoke w3m on the URL in its current window, or at least a different one.
359If NEW-SESSION-P, start a new session."
360 (interactive "sURL: \nP")
361 (save-excursion
63fb20c1
MW
362 (let ((window (selected-window)))
363 (unwind-protect
364 (progn
365 (select-window (or (and (not new-session-p)
366 (get-buffer-window "*w3m*"))
367 (progn
368 (if (one-window-p t) (split-window))
369 (get-lru-window))))
370 (w3m-browse-url url new-session-p))
371 (select-window window)))))
a203fba8
MW
372
373(defvar mdw-good-url-browsers
374 '((w3m . mdw-w3m-browse-url)
375 browse-url-w3
376 browse-url-mozilla)
377 "List of good browsers for mdw-good-url-browsers; each item is a browser
378function name, or a cons (CHECK . FUNC). A symbol FOO stands for (FOO
379. FOO).")
380
381(defun mdw-good-url-browser ()
382 "Return a good URL browser. Trundle the list of such things, finding the
383first item for which CHECK is fboundp, and returning the correponding FUNC."
384 (let ((bs mdw-good-url-browsers) b check func answer)
385 (while (and bs (not answer))
386 (setq b (car bs)
387 bs (cdr bs))
388 (if (consp b)
389 (setq check (car b) func (cdr b))
390 (setq check b func b))
391 (if (fboundp check)
392 (setq answer func)))
393 answer))
394
f617db13
MW
395;;;----- Paragraph filling --------------------------------------------------
396
397;; --- Useful variables ---
398
399(defvar mdw-fill-prefix nil
400 "*Used by `mdw-line-prefix' and `mdw-fill-paragraph'. If there's
401no fill prefix currently set (by the `fill-prefix' variable) and there's
402a match from one of the regexps here, it gets used to set the fill-prefix
403for the current operation.
404
405The variable is a list of items of the form `REGEXP . PREFIX'; if the
406REGEXP matches, the PREFIX is used to set the fill prefix. It in turn is
407a list of things:
408
409 STRING -- insert a literal string
410 (match . N) -- insert the thing matched by bracketed subexpression N
411 (pad . N) -- a string of whitespace the same width as subexpression N
412 (expr . FORM) -- the result of evaluating FORM")
413
414(make-variable-buffer-local 'mdw-fill-prefix)
415
416(defvar mdw-hanging-indents
417 "\\(\\(\\([*o]\\|--\\|[0-9]+\\.\\|\\[[0-9]+\\]\\|([a-zA-Z])\\)[ \t]+\\)?\\)"
418 "*Standard regular expression matching things which might be part of a
419hanging indent. This is mainly useful in `auto-fill-mode'.")
420
421;; --- Setting things up ---
422
423(fset 'mdw-do-auto-fill (symbol-function 'do-auto-fill))
424
425;; --- Utility functions ---
426
427(defun mdw-tabify (s)
428 "Tabify the string S. This is a horrid hack."
429 (save-excursion
430 (save-match-data
431 (let (start end)
432 (beginning-of-line)
433 (setq start (point-marker))
434 (insert s "\n")
435 (setq end (point-marker))
436 (tabify start end)
437 (setq s (buffer-substring start (1- end)))
438 (delete-region start end)
439 (set-marker start nil)
440 (set-marker end nil)
441 s))))
442
443(defun mdw-examine-fill-prefixes (l)
444 "Given a list of dynamic fill prefixes, pick one which matches context and
445return the static fill prefix to use. Point must be at the start of a line,
446and match data must be saved."
447 (cond ((not l) nil)
448 ((looking-at (car (car l)))
449 (mdw-tabify (apply (function concat)
450 (mapcar (function mdw-do-prefix-match)
451 (cdr (car l))))))
452 (t (mdw-examine-fill-prefixes (cdr l)))))
453
454(defun mdw-maybe-car (p)
455 "If P is a pair, return (car P), otherwise just return P."
456 (if (consp p) (car p) p))
457
458(defun mdw-padding (s)
459 "Return a string the same width as S but made entirely from whitespace."
460 (let* ((l (length s)) (i 0) (n (make-string l ? )))
461 (while (< i l)
462 (if (= 9 (aref s i))
463 (aset n i 9))
464 (setq i (1+ i)))
465 n))
466
467(defun mdw-do-prefix-match (m)
468 "Expand a dynamic prefix match element. See `mdw-fill-prefix' for
469details."
470 (cond ((not (consp m)) (format "%s" m))
471 ((eq (car m) 'match) (match-string (mdw-maybe-car (cdr m))))
472 ((eq (car m) 'pad) (mdw-padding (match-string
473 (mdw-maybe-car (cdr m)))))
474 ((eq (car m) 'eval) (eval (cdr m)))
475 (t "")))
476
477(defun mdw-choose-dynamic-fill-prefix ()
478 "Work out the dynamic fill prefix based on the variable `mdw-fill-prefix'."
479 (cond ((and fill-prefix (not (string= fill-prefix ""))) fill-prefix)
480 ((not mdw-fill-prefix) fill-prefix)
481 (t (save-excursion
482 (beginning-of-line)
483 (save-match-data
484 (mdw-examine-fill-prefixes mdw-fill-prefix))))))
485
486(defun do-auto-fill ()
487 "Handle auto-filling, working out a dynamic fill prefix in the case where
488there isn't a sensible static one."
489 (let ((fill-prefix (mdw-choose-dynamic-fill-prefix)))
490 (mdw-do-auto-fill)))
491
492(defun mdw-fill-paragraph ()
493 "Fill paragraph, getting a dynamic fill prefix."
494 (interactive)
495 (let ((fill-prefix (mdw-choose-dynamic-fill-prefix)))
496 (fill-paragraph nil)))
497
498(defun mdw-standard-fill-prefix (rx &optional mat)
499 "Set the dynamic fill prefix, handling standard hanging indents and stuff.
500This is just a short-cut for setting the thing by hand, and by design it
501doesn't cope with anything approximating a complicated case."
502 (setq mdw-fill-prefix
503 `((,(concat rx mdw-hanging-indents)
504 (match . 1)
505 (pad . ,(or mat 2))))))
506
507;;;----- Other common declarations ------------------------------------------
508
509(defun mdw-set-frame-transparency (&optional n)
510 (interactive "P")
511 (let* ((alist (frame-parameters))
512 (trans (assq 'transparency alist)))
513 (if trans
514 (rplacd trans (not (if n (zerop n) (cdr trans))))
515 (setq trans (cons 'transparency (not (equal 0 n)))))
516 (modify-frame-parameters (selected-frame) (list trans))))
517
518;; --- Mouse wheel support ---
519
520(defconst mdw-wheel-scroll-amount 15)
521(defun mdw-wheel-up (click)
522 (interactive "@e")
523 (mdw-wheel-scroll click (function scroll-down)))
524(defun mdw-wheel-down (click)
525 (interactive "@e")
526 (mdw-wheel-scroll click (function scroll-up)))
527
528(defun mdw-wheel-scroll (click func)
529 (let ((win (selected-window)))
530 (unwind-protect
531 (progn
532 (select-window (posn-window (event-start click)))
533 (let ((arg 2))
534 (funcall func (/ (window-height) 2))))
535 (select-window win))))
536
537;; --- Going backwards ---
538
539(defun other-window-backwards (arg)
540 (interactive "p")
541 (other-window (- arg)))
542
543;; --- Common mode settings ---
544
545(defvar mdw-auto-indent t
546 "Whether to indent automatically after a newline.")
547
548(defun mdw-misc-mode-config ()
549 (and mdw-auto-indent
550 (cond ((eq major-mode 'lisp-mode)
551 (local-set-key "\C-m" 'mdw-indent-newline-and-indent))
30c8a8fb
MW
552 ((or (eq major-mode 'slime-repl-mode)
553 (eq major-mode 'asm-mode))
554 nil)
f617db13
MW
555 (t
556 (local-set-key "\C-m" 'newline-and-indent))))
557 (local-set-key [C-return] 'newline)
30c8a8fb
MW
558 (or (eq major-mode 'asm-mode)
559 (local-set-key [?\;] 'self-insert-command))
f617db13
MW
560 (local-set-key [?\#] 'self-insert-command)
561 (local-set-key [?\"] 'self-insert-command)
562 (setq comment-column 40)
563 (auto-fill-mode 1)
564 (setq fill-column 77)
473ff3b0 565 (setq show-trailing-whitespace t)
f617db13
MW
566 (mdw-set-font))
567
568;; --- Set up all sorts of faces ---
569
570(defvar mdw-set-font nil)
571
572(defvar mdw-punct-face 'mdw-punct-face "Face to use for punctuation")
573(make-face 'mdw-punct-face)
574(defvar mdw-number-face 'mdw-number-face "Face to use for numbers")
575(make-face 'mdw-number-face)
576
577;;;----- General fontification ----------------------------------------------
578
473ff3b0
MW
579(defun mdw-set-fonts (frame faces)
580 (while faces
581 (let ((face (caar faces)))
582 (or (facep face) (make-face face))
583 (set-face-attribute face frame
584 :family 'unspecified
585 :width 'unspecified
586 :height 'unspecified
587 :weight 'unspecified
588 :slant 'unspecified
589 :foreground 'unspecified
590 :background 'unspecified
591 :underline 'unspecified
592 :overline 'unspecified
593 :strike-through 'unspecified
594 :box 'unspecified
595 :inverse-video 'unspecified
596 :stipple 'unspecified
597 ;:font 'unspecified
598 :inherit 'unspecified)
599 (apply 'set-face-attribute face frame (cdar faces))
600 (setq faces (cdr faces)))))
f617db13
MW
601
602(defun mdw-do-set-font (&optional frame)
603 (interactive)
604 (mdw-set-fonts (and (boundp 'frame) frame) `(
605 (default :foreground "white" :background "black"
606 ,@(cond ((eq window-system 'w32)
607 '(:family "courier new" :height 85))
608 ((eq window-system 'x)
9cbbe332 609 '(:family "misc-fixed" :height 130 :width semi-condensed))))
b5d724dd
MW
610 (fixed-pitch)
611 (minibuffer-prompt)
668e254c
MW
612 (mode-line :foreground "blue" :background "yellow"
613 :box (:line-width 1 :style released-button))
414d8484 614 (mode-line-inactive :foreground "yellow" :background "blue"
668e254c 615 :box (:line-width 1 :style released-button))
f617db13 616 (scroll-bar :foreground "black" :background "lightgrey")
414d8484 617 (fringe :foreground "yellow" :background "black")
f617db13
MW
618 (show-paren-match-face :background "darkgreen")
619 (show-paren-mismatch-face :background "red")
620 (font-lock-warning-face :background "red" :weight bold)
621 (highlight :background "DarkSeaGreen4")
622 (holiday-face :background "red")
623 (calendar-today-face :foreground "yellow" :weight bold)
624 (comint-highlight-prompt :weight bold)
625 (comint-highlight-input)
626 (font-lock-builtin-face :weight bold)
627 (font-lock-type-face :weight bold)
628 (region :background "grey30")
629 (isearch :background "palevioletred2")
630 (mdw-punct-face :foreground ,(if window-system "burlywood2" "yellow"))
631 (mdw-number-face :foreground "yellow")
632 (font-lock-function-name-face :weight bold)
633 (font-lock-variable-name-face :slant italic)
52696e46
MW
634 (font-lock-comment-delimiter-face
635 :foreground ,(if window-system "SeaGreen1" "green")
636 :slant italic)
f617db13
MW
637 (font-lock-comment-face
638 :foreground ,(if window-system "SeaGreen1" "green")
639 :slant italic)
640 (font-lock-string-face :foreground ,(if window-system "SkyBlue1" "cyan"))
641 (font-lock-keyword-face :weight bold)
642 (font-lock-constant-face :weight bold)
643 (font-lock-reference-face :weight bold)
644 (woman-bold-face :weight bold)
645 (woman-italic-face :slant italic)
8b6bc589
MW
646 (diff-index :weight bold)
647 (diff-file-header :weight bold)
648 (diff-hunk-header :foreground "SkyBlue1")
649 (diff-function :foreground "SkyBlue1" :weight bold)
650 (diff-header :background "grey10")
651 (diff-added :foreground "green")
652 (diff-removed :foreground "red")
653 (diff-context)
f617db13
MW
654 (whizzy-slice-face :background "grey10")
655 (whizzy-error-face :background "darkred")
473ff3b0 656 (trailing-whitespace :background "red")
f617db13
MW
657)))
658
659(defun mdw-set-font ()
660 (trap
661 (turn-on-font-lock)
662 (if (not mdw-set-font)
663 (progn
664 (setq mdw-set-font t)
665 (mdw-do-set-font nil)))))
666
667;;;----- C programming configuration ----------------------------------------
668
669;; --- Linux kernel hacking ---
670
671(defvar linux-c-mode-hook)
672
673(defun linux-c-mode ()
674 (interactive)
675 (c-mode)
676 (setq major-mode 'linux-c-mode)
677 (setq mode-name "Linux C")
678 (run-hooks 'linux-c-mode-hook))
679
680;; --- Make C indentation nice ---
681
682(defun mdw-c-style ()
683 (c-add-style "[mdw] C and C++ style"
684 '((c-basic-offset . 2)
685 (c-tab-always-indent . nil)
686 (comment-column . 40)
687 (c-class-key . "class")
688 (c-offsets-alist (substatement-open . 0)
689 (label . 0)
690 (case-label . +)
691 (access-label . -)
87c7cecb 692 (inclass . +)
f617db13
MW
693 (inline-open . ++)
694 (statement-cont . 0)
695 (statement-case-intro . +)))
696 t))
697
698(defun mdw-fontify-c-and-c++ ()
699
700 ;; --- Fiddle with some syntax codes ---
701
702 (modify-syntax-entry ?_ "w")
703 (modify-syntax-entry ?* ". 23")
704 (modify-syntax-entry ?/ ". 124b")
705 (modify-syntax-entry ?\n "> b")
706
707 ;; --- Other stuff ---
708
709 (mdw-c-style)
710 (setq c-hanging-comment-ender-p nil)
711 (setq c-backslash-column 72)
712 (setq c-label-minimum-indentation 0)
f617db13
MW
713 (setq mdw-fill-prefix
714 `((,(concat "\\([ \t]*/?\\)"
715 "\\([\*/][ \t]*\\)"
716 "\\([A-Za-z]+:[ \t]*\\)?"
717 mdw-hanging-indents)
718 (pad . 1) (match . 2) (pad . 3) (pad . 4))))
719
720 ;; --- Now define things to be fontified ---
721
02109a0d 722 (make-local-variable 'font-lock-keywords)
f617db13 723 (let ((c-keywords
c7a8da49 724 (mdw-regexps '(
4459800e
MW
725 "and" ;C++
726 "and_eq" ;C++
f617db13
MW
727 "asm" ;K&R, GCC
728 "auto" ;K&R, C89
4459800e
MW
729 "bitand" ;C++
730 "bitor" ;C++
f617db13
MW
731 "bool" ;C++, C9X macro
732 "break" ;K&R, C89
733 "case" ;K&R, C89
734 "catch" ;C++
735 "char" ;K&R, C89
736 "class" ;C++
737 "complex" ;C9X macro, C++ template type
4459800e 738 "compl" ;C++
f617db13
MW
739 "const" ;C89
740 "const_cast" ;C++
741 "continue" ;K&R, C89
742 "defined" ;C89 preprocessor
743 "default" ;K&R, C89
744 "delete" ;C++
745 "do" ;K&R, C89
746 "double" ;K&R, C89
747 "dynamic_cast" ;C++
748 "else" ;K&R, C89
749 ;; "entry" ;K&R -- never used
750 "enum" ;C89
751 "explicit" ;C++
4459800e 752 "export" ;C++
f617db13
MW
753 "extern" ;K&R, C89
754 "false" ;C++, C9X macro
755 "float" ;K&R, C89
756 "for" ;K&R, C89
4459800e 757 ;; "fortran" ;K&R
f617db13
MW
758 "friend" ;C++
759 "goto" ;K&R, C89
760 "if" ;K&R, C89
761 "imaginary" ;C9X macro
762 "inline" ;C++, C9X, GCC
763 "int" ;K&R, C89
764 "long" ;K&R, C89
765 "mutable" ;C++
766 "namespace" ;C++
767 "new" ;C++
768 "operator" ;C++
4459800e
MW
769 "or" ;C++
770 "or_eq" ;C++
f617db13
MW
771 "private" ;C++
772 "protected" ;C++
773 "public" ;C++
774 "register" ;K&R, C89
775 "reinterpret_cast" ;C++
776 "restrict" ;C9X
777 "return" ;K&R, C89
778 "short" ;K&R, C89
779 "signed" ;C89
780 "sizeof" ;K&R, C89
781 "static" ;K&R, C89
782 "static_cast" ;C++
783 "struct" ;K&R, C89
784 "switch" ;K&R, C89
785 "template" ;C++
786 "this" ;C++
787 "throw" ;C++
788 "true" ;C++, C9X macro
789 "try" ;C++
790 "this" ;C++
791 "typedef" ;C89
792 "typeid" ;C++
793 "typeof" ;GCC
794 "typename" ;C++
795 "union" ;K&R, C89
796 "unsigned" ;K&R, C89
797 "using" ;C++
798 "virtual" ;C++
799 "void" ;C89
800 "volatile" ;C89
801 "wchar_t" ;C++, C89 library type
802 "while" ;K&R, C89
4459800e
MW
803 "xor" ;C++
804 "xor_eq" ;C++
f617db13
MW
805 "_Bool" ;C9X
806 "_Complex" ;C9X
807 "_Imaginary" ;C9X
808 "_Pragma" ;C9X preprocessor
809 "__alignof__" ;GCC
810 "__asm__" ;GCC
811 "__attribute__" ;GCC
812 "__complex__" ;GCC
813 "__const__" ;GCC
814 "__extension__" ;GCC
815 "__imag__" ;GCC
816 "__inline__" ;GCC
817 "__label__" ;GCC
818 "__real__" ;GCC
819 "__signed__" ;GCC
820 "__typeof__" ;GCC
821 "__volatile__" ;GCC
822 )))
823 (preprocessor-keywords
c7a8da49 824 (mdw-regexps '("assert" "define" "elif" "else" "endif" "error"
f617db13
MW
825 "ident" "if" "ifdef" "ifndef" "import" "include"
826 "line" "pragma" "unassert" "undef" "warning")))
827 (objc-keywords
c7a8da49 828 (mdw-regexps '("class" "defs" "encode" "end" "implementation"
f617db13
MW
829 "interface" "private" "protected" "protocol" "public"
830 "selector"))))
831
832 (setq font-lock-keywords
833 (list
f617db13
MW
834
835 ;; --- Fontify include files as strings ---
836
837 (list (concat "^[ \t]*\\#[ \t]*"
838 "\\(include\\|import\\)"
839 "[ \t]*\\(<[^>]+\\(>\\|\\)\\)")
840 '(2 font-lock-string-face))
841
842 ;; --- Preprocessor directives are `references'? ---
843
844 (list (concat "^\\([ \t]*#[ \t]*\\(\\("
845 preprocessor-keywords
846 "\\)\\>\\|[0-9]+\\|$\\)\\)")
847 '(1 font-lock-keyword-face))
848
849 ;; --- Handle the keywords defined above ---
850
851 (list (concat "@\\<\\(" objc-keywords "\\)\\>")
852 '(0 font-lock-keyword-face))
853
854 (list (concat "\\<\\(" c-keywords "\\)\\>")
855 '(0 font-lock-keyword-face))
856
857 ;; --- Handle numbers too ---
858 ;;
859 ;; This looks strange, I know. It corresponds to the
860 ;; preprocessor's idea of what a number looks like, rather than
861 ;; anything sensible.
862
863 (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
864 "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
865 '(0 mdw-number-face))
866
867 ;; --- And anything else is punctuation ---
868
869 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
870 '(0 mdw-punct-face))))))
871
872;;;----- AP calc mode -------------------------------------------------------
873
874(defun apcalc-mode ()
875 (interactive)
876 (c-mode)
877 (setq major-mode 'apcalc-mode)
878 (setq mode-name "AP Calc")
879 (run-hooks 'apcalc-mode-hook))
880
881(defun mdw-fontify-apcalc ()
882
883 ;; --- Fiddle with some syntax codes ---
884
885 (modify-syntax-entry ?_ "w")
886 (modify-syntax-entry ?* ". 23")
887 (modify-syntax-entry ?/ ". 14")
888
889 ;; --- Other stuff ---
890
891 (mdw-c-style)
892 (setq c-hanging-comment-ender-p nil)
893 (setq c-backslash-column 72)
894 (setq comment-start "/* ")
895 (setq comment-end " */")
896 (setq mdw-fill-prefix
897 `((,(concat "\\([ \t]*/?\\)"
898 "\\([\*/][ \t]*\\)"
899 "\\([A-Za-z]+:[ \t]*\\)?"
900 mdw-hanging-indents)
901 (pad . 1) (match . 2) (pad . 3) (pad . 4))))
902
903 ;; --- Now define things to be fontified ---
904
02109a0d 905 (make-local-variable 'font-lock-keywords)
f617db13 906 (let ((c-keywords
c7a8da49 907 (mdw-regexps '("break" "case" "cd" "continue" "define" "default"
f617db13
MW
908 "do" "else" "exit" "for" "global" "goto" "help" "if"
909 "local" "mat" "obj" "print" "quit" "read" "return"
910 "show" "static" "switch" "while" "write"))))
911
912 (setq font-lock-keywords
913 (list
f617db13
MW
914
915 ;; --- Handle the keywords defined above ---
916
917 (list (concat "\\<\\(" c-keywords "\\)\\>")
918 '(0 font-lock-keyword-face))
919
920 ;; --- Handle numbers too ---
921 ;;
922 ;; This looks strange, I know. It corresponds to the
923 ;; preprocessor's idea of what a number looks like, rather than
924 ;; anything sensible.
925
926 (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
927 "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
928 '(0 mdw-number-face))
929
930 ;; --- And anything else is punctuation ---
931
932 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
933 '(0 mdw-punct-face))))))
934
935;;;----- Java programming configuration -------------------------------------
936
937;; --- Make indentation nice ---
938
939(defun mdw-java-style ()
940 (c-add-style "[mdw] Java style"
941 '((c-basic-offset . 2)
942 (c-tab-always-indent . nil)
943 (c-offsets-alist (substatement-open . 0)
944 (label . +)
945 (case-label . +)
946 (access-label . 0)
947 (inclass . +)
948 (statement-case-intro . +)))
949 t))
950
951;; --- Declare Java fontification style ---
952
953(defun mdw-fontify-java ()
954
955 ;; --- Other stuff ---
956
957 (mdw-java-style)
958 (modify-syntax-entry ?_ "w")
959 (setq c-hanging-comment-ender-p nil)
960 (setq c-backslash-column 72)
961 (setq comment-start "/* ")
962 (setq comment-end " */")
963 (setq mdw-fill-prefix
964 `((,(concat "\\([ \t]*/?\\)"
965 "\\([\*/][ \t]*\\)"
966 "\\([A-Za-z]+:[ \t]*\\)?"
967 mdw-hanging-indents)
968 (pad . 1) (match . 2) (pad . 3) (pad . 4))))
969
970 ;; --- Now define things to be fontified ---
971
02109a0d 972 (make-local-variable 'font-lock-keywords)
f617db13 973 (let ((java-keywords
c7a8da49 974 (mdw-regexps '("abstract" "boolean" "break" "byte" "case" "catch"
f617db13
MW
975 "char" "class" "const" "continue" "default" "do"
976 "double" "else" "extends" "final" "finally" "float"
977 "for" "goto" "if" "implements" "import" "instanceof"
978 "int" "interface" "long" "native" "new" "package"
979 "private" "protected" "public" "return" "short"
980 "static" "super" "switch" "synchronized" "this"
981 "throw" "throws" "transient" "try" "void" "volatile"
982 "while"
983
984 "false" "null" "true"))))
985
986 (setq font-lock-keywords
987 (list
f617db13
MW
988
989 ;; --- Handle the keywords defined above ---
990
991 (list (concat "\\<\\(" java-keywords "\\)\\>")
992 '(0 font-lock-keyword-face))
993
994 ;; --- Handle numbers too ---
995 ;;
996 ;; The following isn't quite right, but it's close enough.
997
998 (list (concat "\\<\\("
999 "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1000 "[0-9]+\\(\\.[0-9]*\\|\\)"
1001 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
1002 "[lLfFdD]?")
1003 '(0 mdw-number-face))
1004
1005 ;; --- And anything else is punctuation ---
1006
1007 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1008 '(0 mdw-punct-face))))))
1009
e808c1e5
MW
1010;;;----- C# programming configuration ---------------------------------------
1011
1012;; --- Make indentation nice ---
1013
1014(defun mdw-csharp-style ()
1015 (c-add-style "[mdw] C# style"
1016 '((c-basic-offset . 2)
1017 (c-tab-always-indent . nil)
1018 (c-offsets-alist (substatement-open . 0)
1019 (label . 0)
1020 (case-label . +)
1021 (access-label . 0)
1022 (inclass . +)
1023 (statement-case-intro . +)))
1024 t))
1025
1026;; --- Declare C# fontification style ---
1027
1028(defun mdw-fontify-csharp ()
1029
1030 ;; --- Other stuff ---
1031
1032 (mdw-csharp-style)
1033 (modify-syntax-entry ?_ "w")
1034 (setq c-hanging-comment-ender-p nil)
1035 (setq c-backslash-column 72)
1036 (setq comment-start "/* ")
1037 (setq comment-end " */")
1038 (setq mdw-fill-prefix
1039 `((,(concat "\\([ \t]*/?\\)"
1040 "\\([\*/][ \t]*\\)"
1041 "\\([A-Za-z]+:[ \t]*\\)?"
1042 mdw-hanging-indents)
1043 (pad . 1) (match . 2) (pad . 3) (pad . 4))))
1044
1045 ;; --- Now define things to be fontified ---
1046
1047 (make-local-variable 'font-lock-keywords)
1048 (let ((csharp-keywords
c7a8da49 1049 (mdw-regexps '("abstract" "as" "base" "bool" "break"
e808c1e5
MW
1050 "byte" "case" "catch" "char" "checked"
1051 "class" "const" "continue" "decimal" "default"
1052 "delegate" "do" "double" "else" "enum"
1053 "event" "explicit" "extern" "false" "finally"
1054 "fixed" "float" "for" "foreach" "goto"
1055 "if" "implicit" "in" "int" "interface"
1056 "internal" "is" "lock" "long" "namespace"
1057 "new" "null" "object" "operator" "out"
1058 "override" "params" "private" "protected" "public"
1059 "readonly" "ref" "return" "sbyte" "sealed"
1060 "short" "sizeof" "stackalloc" "static" "string"
1061 "struct" "switch" "this" "throw" "true"
1062 "try" "typeof" "uint" "ulong" "unchecked"
1063 "unsafe" "ushort" "using" "virtual" "void"
1064 "volatile" "while" "yield"))))
1065
1066 (setq font-lock-keywords
1067 (list
e808c1e5
MW
1068
1069 ;; --- Handle the keywords defined above ---
1070
1071 (list (concat "\\<\\(" csharp-keywords "\\)\\>")
1072 '(0 font-lock-keyword-face))
1073
1074 ;; --- Handle numbers too ---
1075 ;;
1076 ;; The following isn't quite right, but it's close enough.
1077
1078 (list (concat "\\<\\("
1079 "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1080 "[0-9]+\\(\\.[0-9]*\\|\\)"
1081 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
1082 "[lLfFdD]?")
1083 '(0 mdw-number-face))
1084
1085 ;; --- And anything else is punctuation ---
1086
1087 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1088 '(0 mdw-punct-face))))))
1089
1090(defun csharp-mode ()
1091 (interactive)
1092 (java-mode)
1093 (setq major-mode 'csharp-mode)
1094 (setq mode-name "C#")
1095 (mdw-fontify-csharp)
1096 (run-hooks 'csharp-mode-hook))
1097
f617db13
MW
1098;;;----- Awk programming configuration --------------------------------------
1099
1100;; --- Make Awk indentation nice ---
1101
1102(defun mdw-awk-style ()
1103 (c-add-style "[mdw] Awk style"
1104 '((c-basic-offset . 2)
1105 (c-tab-always-indent . nil)
1106 (c-offsets-alist (substatement-open . 0)
1107 (statement-cont . 0)
1108 (statement-case-intro . +)))
1109 t))
1110
1111;; --- Declare Awk fontification style ---
1112
1113(defun mdw-fontify-awk ()
1114
1115 ;; --- Miscellaneous fiddling ---
1116
1117 (modify-syntax-entry ?_ "w")
1118 (mdw-awk-style)
1119 (setq c-backslash-column 72)
1120 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
1121
1122 ;; --- Now define things to be fontified ---
1123
02109a0d 1124 (make-local-variable 'font-lock-keywords)
f617db13 1125 (let ((c-keywords
c7a8da49 1126 (mdw-regexps '("BEGIN" "END" "ARGC" "ARGIND" "ARGV" "CONVFMT"
f617db13
MW
1127 "ENVIRON" "ERRNO" "FIELDWIDTHS" "FILENAME" "FNR"
1128 "FS" "IGNORECASE" "NF" "NR" "OFMT" "OFS" "ORS" "RS"
1129 "RSTART" "RLENGTH" "RT" "SUBSEP"
1130 "atan2" "break" "close" "continue" "cos" "delete"
1131 "do" "else" "exit" "exp" "fflush" "file" "for" "func"
1132 "function" "gensub" "getline" "gsub" "if" "in"
1133 "index" "int" "length" "log" "match" "next" "rand"
1134 "return" "print" "printf" "sin" "split" "sprintf"
1135 "sqrt" "srand" "strftime" "sub" "substr" "system"
1136 "systime" "tolower" "toupper" "while"))))
1137
1138 (setq font-lock-keywords
1139 (list
f617db13
MW
1140
1141 ;; --- Handle the keywords defined above ---
1142
1143 (list (concat "\\<\\(" c-keywords "\\)\\>")
1144 '(0 font-lock-keyword-face))
1145
1146 ;; --- Handle numbers too ---
1147 ;;
1148 ;; The following isn't quite right, but it's close enough.
1149
1150 (list (concat "\\<\\("
1151 "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1152 "[0-9]+\\(\\.[0-9]*\\|\\)"
1153 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
1154 "[uUlL]*")
1155 '(0 mdw-number-face))
1156
1157 ;; --- And anything else is punctuation ---
1158
1159 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1160 '(0 mdw-punct-face))))))
1161
1162;;;----- Perl programming style ---------------------------------------------
1163
1164;; --- Perl indentation style ---
1165
1166(setq cperl-tab-always-indent nil)
1167
1168(setq cperl-indent-level 2)
1169(setq cperl-continued-statement-offset 2)
1170(setq cperl-continued-brace-offset 0)
1171(setq cperl-brace-offset -2)
1172(setq cperl-brace-imaginary-offset 0)
1173(setq cperl-label-offset 0)
1174
1175;; --- Define perl fontification style ---
1176
1177(defun mdw-fontify-perl ()
1178
1179 ;; --- Miscellaneous fiddling ---
1180
1181 (modify-syntax-entry ?_ "w")
1182 (modify-syntax-entry ?$ "\\")
1183 (modify-syntax-entry ?$ "\\" font-lock-syntax-table)
1184 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
1185
1186 ;; --- Now define fontification things ---
1187
02109a0d 1188 (make-local-variable 'font-lock-keywords)
f617db13 1189 (let ((perl-keywords
c7a8da49 1190 (mdw-regexps '("and" "cmp" "continue" "do" "else" "elsif" "eq"
f617db13
MW
1191 "for" "foreach" "ge" "gt" "goto" "if"
1192 "last" "le" "lt" "local" "my" "ne" "next" "or"
1193 "package" "redo" "require" "return" "sub"
1194 "undef" "unless" "until" "use" "while"))))
1195
1196 (setq font-lock-keywords
1197 (list
f617db13
MW
1198
1199 ;; --- Set up the keywords defined above ---
1200
1201 (list (concat "\\<\\(" perl-keywords "\\)\\>")
1202 '(0 font-lock-keyword-face))
1203
1204 ;; --- At least numbers are simpler than C ---
1205
1206 (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
1207 "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
1208 "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
1209 '(0 mdw-number-face))
1210
1211 ;; --- And anything else is punctuation ---
1212
1213 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1214 '(0 mdw-punct-face))))))
1215
1216(defun perl-number-tests (&optional arg)
1217 "Assign consecutive numbers to lines containing `#t'. With ARG,
1218strip numbers instead."
1219 (interactive "P")
1220 (save-excursion
1221 (goto-char (point-min))
1222 (let ((i 0) (fmt (if arg "" " %4d")))
1223 (while (search-forward "#t" nil t)
1224 (delete-region (point) (line-end-position))
1225 (setq i (1+ i))
1226 (insert (format fmt i)))
1227 (goto-char (point-min))
1228 (if (re-search-forward "\\(tests\\s-*=>\\s-*\\)\\w*" nil t)
1229 (replace-match (format "\\1%d" i))))))
1230
1231;;;----- Python programming style -------------------------------------------
1232
1233;; --- Define Python fontification style ---
1234
f617db13
MW
1235(defun mdw-fontify-python ()
1236
1237 ;; --- Miscellaneous fiddling ---
1238
1239 (modify-syntax-entry ?_ "w")
1240 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
1241
1242 ;; --- Now define fontification things ---
1243
02109a0d 1244 (make-local-variable 'font-lock-keywords)
f617db13 1245 (let ((python-keywords
c7a8da49 1246 (mdw-regexps '("and" "as" "assert" "break" "class" "continue" "def"
f617db13
MW
1247 "del" "elif" "else" "except" "exec" "finally" "for"
1248 "from" "global" "if" "import" "in" "is" "lambda"
1249 "not" "or" "pass" "print" "raise" "return" "try"
043e413b 1250 "while" "yield"))))
f617db13
MW
1251 (setq font-lock-keywords
1252 (list
f617db13
MW
1253
1254 ;; --- Set up the keywords defined above ---
1255
1256 (list (concat "\\<\\(" python-keywords "\\)\\>")
1257 '(0 font-lock-keyword-face))
1258
1259 ;; --- At least numbers are simpler than C ---
1260
1261 (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
1262 "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
1263 "\\([eE]\\([-+]\\|\\)[0-9_]+\\|[lL]\\|\\)")
1264 '(0 mdw-number-face))
1265
1266 ;; --- And anything else is punctuation ---
1267
1268 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1269 '(0 mdw-punct-face))))))
1270
1271;;;----- ARM assembler programming configuration ----------------------------
1272
1273;; --- There doesn't appear to be an Emacs mode for this yet ---
1274;;
1275;; Better do something about that, I suppose.
1276
1277(defvar arm-assembler-mode-map nil)
1278(defvar arm-assembler-abbrev-table nil)
1279(defvar arm-assembler-mode-syntax-table (make-syntax-table))
1280
1281(or arm-assembler-mode-map
1282 (progn
1283 (setq arm-assembler-mode-map (make-sparse-keymap))
1284 (define-key arm-assembler-mode-map "\C-m" 'arm-assembler-newline)
1285 (define-key arm-assembler-mode-map [C-return] 'newline)
1286 (define-key arm-assembler-mode-map "\t" 'tab-to-tab-stop)))
1287
1288(defun arm-assembler-mode ()
1289 "Major mode for ARM assembler programs"
1290 (interactive)
1291
1292 ;; --- Do standard major mode things ---
1293
1294 (kill-all-local-variables)
1295 (use-local-map arm-assembler-mode-map)
1296 (setq local-abbrev-table arm-assembler-abbrev-table)
1297 (setq major-mode 'arm-assembler-mode)
1298 (setq mode-name "ARM assembler")
1299
1300 ;; --- Set up syntax table ---
1301
1302 (set-syntax-table arm-assembler-mode-syntax-table)
1303 (modify-syntax-entry ?; ; Nasty hack
1304 "<" arm-assembler-mode-syntax-table)
1305 (modify-syntax-entry ?\n ">" arm-assembler-mode-syntax-table)
1306 (modify-syntax-entry ?_ "_" arm-assembler-mode-syntax-table)
1307
1308 (make-local-variable 'comment-start)
1309 (setq comment-start ";")
1310 (make-local-variable 'comment-end)
1311 (setq comment-end "")
1312 (make-local-variable 'comment-column)
1313 (setq comment-column 48)
1314 (make-local-variable 'comment-start-skip)
1315 (setq comment-start-skip ";+[ \t]*")
1316
1317 ;; --- Play with indentation ---
1318
1319 (make-local-variable 'indent-line-function)
1320 (setq indent-line-function 'indent-relative-maybe)
1321
1322 ;; --- Set fill prefix ---
1323
1324 (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)")
1325
1326 ;; --- Fiddle with fontification ---
1327
02109a0d 1328 (make-local-variable 'font-lock-keywords)
f617db13
MW
1329 (setq font-lock-keywords
1330 (list
f617db13
MW
1331
1332 ;; --- Handle numbers too ---
1333 ;;
1334 ;; The following isn't quite right, but it's close enough.
1335
1336 (list (concat "\\("
1337 "&[0-9a-fA-F]+\\|"
1338 "\\<[0-9]+\\(\\.[0-9]*\\|_[0-9a-zA-Z]+\\|\\)"
1339 "\\)")
1340 '(0 mdw-number-face))
1341
1342 ;; --- Do something about operators ---
1343
1344 (list "^[^ \t]*[ \t]+\\(GET\\|LNK\\)[ \t]+\\([^;\n]*\\)"
1345 '(1 font-lock-keyword-face)
1346 '(2 font-lock-string-face))
1347 (list ":[a-zA-Z]+:"
1348 '(0 font-lock-keyword-face))
1349
1350 ;; --- Do menemonics and directives ---
1351
1352 (list "^[^ \t]*[ \t]+\\([a-zA-Z]+\\)"
1353 '(1 font-lock-keyword-face))
1354
1355 ;; --- And anything else is punctuation ---
1356
1357 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1358 '(0 mdw-punct-face))))
1359
1360 (run-hooks 'arm-assembler-mode-hook))
1361
30c8a8fb
MW
1362;;;----- Assembler mode -----------------------------------------------------
1363
1364(defun mdw-fontify-asm ()
1365 (modify-syntax-entry ?' "\"")
1366 (modify-syntax-entry ?. "w")
1367 (setf fill-prefix nil)
1368 (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)"))
1369
f617db13
MW
1370;;;----- TCL configuration --------------------------------------------------
1371
1372(defun mdw-fontify-tcl ()
1373 (mapcar #'(lambda (ch) (modify-syntax-entry ch ".")) '(?$))
1374 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
02109a0d 1375 (make-local-variable 'font-lock-keywords)
f617db13
MW
1376 (setq font-lock-keywords
1377 (list
f617db13
MW
1378 (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
1379 "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
1380 "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
1381 '(0 mdw-number-face))
1382 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1383 '(0 mdw-punct-face)))))
1384
1385;;;----- REXX configuration -------------------------------------------------
1386
1387(defun mdw-rexx-electric-* ()
1388 (interactive)
1389 (insert ?*)
1390 (rexx-indent-line))
1391
1392(defun mdw-rexx-indent-newline-indent ()
1393 (interactive)
1394 (rexx-indent-line)
1395 (if abbrev-mode (expand-abbrev))
1396 (newline-and-indent))
1397
1398(defun mdw-fontify-rexx ()
1399
1400 ;; --- Various bits of fiddling ---
1401
1402 (setq mdw-auto-indent nil)
1403 (local-set-key [?\C-m] 'mdw-rexx-indent-newline-indent)
1404 (local-set-key [?*] 'mdw-rexx-electric-*)
1405 (mapcar #'(lambda (ch) (modify-syntax-entry ch "w"))
1406 '(?. ?! ?? ?_ ?# ?@ ?$))
1407 (mdw-standard-fill-prefix "\\([ \t]*/?\*[ \t]*\\)")
1408
1409 ;; --- Set up keywords and things for fontification ---
1410
1411 (make-local-variable 'font-lock-keywords-case-fold-search)
1412 (setq font-lock-keywords-case-fold-search t)
1413
1414 (setq rexx-indent 2)
1415 (setq rexx-end-indent rexx-indent)
1416 (setq rexx-tab-always-indent nil)
1417 (setq rexx-cont-indent rexx-indent)
1418
02109a0d 1419 (make-local-variable 'font-lock-keywords)
f617db13 1420 (let ((rexx-keywords
c7a8da49 1421 (mdw-regexps '("address" "arg" "by" "call" "digits" "do" "drop"
f617db13
MW
1422 "else" "end" "engineering" "exit" "expose" "for"
1423 "forever" "form" "fuzz" "if" "interpret" "iterate"
1424 "leave" "linein" "name" "nop" "numeric" "off" "on"
1425 "options" "otherwise" "parse" "procedure" "pull"
1426 "push" "queue" "return" "say" "select" "signal"
1427 "scientific" "source" "then" "trace" "to" "until"
1428 "upper" "value" "var" "version" "when" "while"
1429 "with"
1430
1431 "abbrev" "abs" "bitand" "bitor" "bitxor" "b2x"
1432 "center" "center" "charin" "charout" "chars"
1433 "compare" "condition" "copies" "c2d" "c2x"
1434 "datatype" "date" "delstr" "delword" "d2c" "d2x"
1435 "errortext" "format" "fuzz" "insert" "lastpos"
1436 "left" "length" "lineout" "lines" "max" "min"
1437 "overlay" "pos" "queued" "random" "reverse" "right"
1438 "sign" "sourceline" "space" "stream" "strip"
1439 "substr" "subword" "symbol" "time" "translate"
1440 "trunc" "value" "verify" "word" "wordindex"
1441 "wordlength" "wordpos" "words" "xrange" "x2b" "x2c"
1442 "x2d"))))
1443
1444 (setq font-lock-keywords
1445 (list
f617db13
MW
1446
1447 ;; --- Set up the keywords defined above ---
1448
1449 (list (concat "\\<\\(" rexx-keywords "\\)\\>")
1450 '(0 font-lock-keyword-face))
1451
1452 ;; --- Fontify all symbols the same way ---
1453
1454 (list (concat "\\<\\([0-9.][A-Za-z0-9.!?_#@$]*[Ee][+-]?[0-9]+\\|"
1455 "[A-Za-z0-9.!?_#@$]+\\)")
1456 '(0 font-lock-variable-name-face))
1457
1458 ;; --- And everything else is punctuation ---
1459
1460 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1461 '(0 mdw-punct-face))))))
1462
1463;;;----- Standard ML programming style --------------------------------------
1464
1465(defun mdw-fontify-sml ()
1466
1467 ;; --- Make underscore an honorary letter ---
1468
1469 (modify-syntax-entry ?_ "w")
1470 (modify-syntax-entry ?' "w")
1471
1472 ;; --- Set fill prefix ---
1473
1474 (mdw-standard-fill-prefix "\\([ \t]*(\*[ \t]*\\)")
1475
1476 ;; --- Now define fontification things ---
1477
02109a0d 1478 (make-local-variable 'font-lock-keywords)
f617db13 1479 (let ((sml-keywords
c7a8da49 1480 (mdw-regexps '("abstype" "and" "andalso" "as"
f617db13
MW
1481 "case"
1482 "datatype" "do"
1483 "else" "end" "eqtype" "exception"
1484 "fn" "fun" "functor"
1485 "handle"
1486 "if" "in" "include" "infix" "infixr"
1487 "let" "local"
1488 "nonfix"
1489 "of" "op" "open" "orelse"
1490 "raise" "rec"
1491 "sharing" "sig" "signature" "struct" "structure"
1492 "then" "type"
1493 "val"
1494 "where" "while" "with" "withtype"))))
1495
1496 (setq font-lock-keywords
1497 (list
f617db13
MW
1498
1499 ;; --- Set up the keywords defined above ---
1500
1501 (list (concat "\\<\\(" sml-keywords "\\)\\>")
1502 '(0 font-lock-keyword-face))
1503
1504 ;; --- At least numbers are simpler than C ---
1505
1506 (list (concat "\\<\\(\\~\\|\\)"
1507 "\\(0\\(\\([wW]\\|\\)[xX][0-9a-fA-F]+\\|"
852cd5fb
MW
1508 "[wW][0-9]+\\)\\|"
1509 "\\([0-9]+\\(\\.[0-9]+\\|\\)"
1510 "\\([eE]\\(\\~\\|\\)"
1511 "[0-9]+\\|\\)\\)\\)")
f617db13
MW
1512 '(0 mdw-number-face))
1513
1514 ;; --- And anything else is punctuation ---
1515
1516 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1517 '(0 mdw-punct-face))))))
1518
1519;;;----- Haskell configuration ----------------------------------------------
1520
1521(defun mdw-fontify-haskell ()
1522
1523 ;; --- Fiddle with syntax table to get comments right ---
1524
1525 (modify-syntax-entry ?_ "w")
1526 (modify-syntax-entry ?' "\"")
1527 (modify-syntax-entry ?- ". 123")
1528 (modify-syntax-entry ?{ ". 1b")
1529 (modify-syntax-entry ?} ". 4b")
1530 (modify-syntax-entry ?\n ">")
1531
1532 ;; --- Set fill prefix ---
1533
1534 (mdw-standard-fill-prefix "\\([ \t]*{?--?[ \t]*\\)")
1535
1536 ;; --- Fiddle with fontification ---
1537
02109a0d 1538 (make-local-variable 'font-lock-keywords)
f617db13 1539 (let ((haskell-keywords
c7a8da49 1540 (mdw-regexps '("as" "case" "ccall" "class" "data" "default"
f617db13
MW
1541 "deriving" "do" "else" "foreign" "hiding" "if"
1542 "import" "in" "infix" "infixl" "infixr" "instance"
1543 "let" "module" "newtype" "of" "qualified" "safe"
1544 "stdcall" "then" "type" "unsafe" "where"))))
1545
1546 (setq font-lock-keywords
1547 (list
f617db13
MW
1548 (list "--.*$"
1549 '(0 font-lock-comment-face))
1550 (list (concat "\\<\\(" haskell-keywords "\\)\\>")
1551 '(0 font-lock-keyword-face))
1552 (list (concat "\\<0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1553 "\\<[0-9][0-9_]*\\(\\.[0-9]*\\|\\)"
1554 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)")
1555 '(0 mdw-number-face))
1556 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1557 '(0 mdw-punct-face))))))
1558
1559;;;----- Texinfo configuration ----------------------------------------------
1560
1561(defun mdw-fontify-texinfo ()
1562
1563 ;; --- Set fill prefix ---
1564
1565 (mdw-standard-fill-prefix "\\([ \t]*@c[ \t]+\\)")
1566
1567 ;; --- Real fontification things ---
1568
02109a0d 1569 (make-local-variable 'font-lock-keywords)
f617db13
MW
1570 (setq font-lock-keywords
1571 (list
f617db13
MW
1572
1573 ;; --- Environment names are keywords ---
1574
1575 (list "@\\(end\\) *\\([a-zA-Z]*\\)?"
1576 '(2 font-lock-keyword-face))
1577
1578 ;; --- Unmark escaped magic characters ---
1579
1580 (list "\\(@\\)\\([@{}]\\)"
1581 '(1 font-lock-keyword-face)
1582 '(2 font-lock-variable-name-face))
1583
1584 ;; --- Make sure we get comments properly ---
1585
1586 (list "@c\\(\\|omment\\)\\( .*\\)?$"
1587 '(0 font-lock-comment-face))
1588
1589 ;; --- Command names are keywords ---
1590
1591 (list "@\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
1592 '(0 font-lock-keyword-face))
1593
1594 ;; --- Fontify TeX special characters as punctuation ---
1595
1596 (list "[{}]+"
1597 '(0 mdw-punct-face)))))
1598
1599;;;----- TeX and LaTeX configuration ----------------------------------------
1600
1601(defun mdw-fontify-tex ()
1602 (setq ispell-parser 'tex)
1603
1604 ;; --- Don't make maths into a string ---
1605
1606 (modify-syntax-entry ?$ ".")
1607 (modify-syntax-entry ?$ "." font-lock-syntax-table)
1608 (local-set-key [?$] 'self-insert-command)
1609
1610 ;; --- Set fill prefix ---
1611
1612 (mdw-standard-fill-prefix "\\([ \t]*%+[ \t]*\\)")
1613
1614 ;; --- Real fontification things ---
1615
02109a0d 1616 (make-local-variable 'font-lock-keywords)
f617db13
MW
1617 (setq font-lock-keywords
1618 (list
f617db13
MW
1619
1620 ;; --- Environment names are keywords ---
1621
1622 (list (concat "\\\\\\(begin\\|end\\|newenvironment\\)"
1623 "{\\([^}\n]*\\)}")
1624 '(2 font-lock-keyword-face))
1625
1626 ;; --- Suspended environment names are keywords too ---
1627
1628 (list (concat "\\\\\\(suspend\\|resume\\)\\(\\[[^]]*\\]\\)?"
1629 "{\\([^}\n]*\\)}")
1630 '(3 font-lock-keyword-face))
1631
1632 ;; --- Command names are keywords ---
1633
1634 (list "\\\\\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
1635 '(0 font-lock-keyword-face))
1636
1637 ;; --- Handle @/.../ for italics ---
1638
1639 ;; (list "\\(@/\\)\\([^/]*\\)\\(/\\)"
852cd5fb
MW
1640 ;; '(1 font-lock-keyword-face)
1641 ;; '(3 font-lock-keyword-face))
f617db13
MW
1642
1643 ;; --- Handle @*...* for boldness ---
1644
1645 ;; (list "\\(@\\*\\)\\([^*]*\\)\\(\\*\\)"
852cd5fb
MW
1646 ;; '(1 font-lock-keyword-face)
1647 ;; '(3 font-lock-keyword-face))
f617db13
MW
1648
1649 ;; --- Handle @`...' for literal syntax things ---
1650
1651 ;; (list "\\(@`\\)\\([^']*\\)\\('\\)"
852cd5fb
MW
1652 ;; '(1 font-lock-keyword-face)
1653 ;; '(3 font-lock-keyword-face))
f617db13
MW
1654
1655 ;; --- Handle @<...> for nonterminals ---
1656
1657 ;; (list "\\(@<\\)\\([^>]*\\)\\(>\\)"
852cd5fb
MW
1658 ;; '(1 font-lock-keyword-face)
1659 ;; '(3 font-lock-keyword-face))
f617db13
MW
1660
1661 ;; --- Handle other @-commands ---
1662
1663 ;; (list "@\\([^a-zA-Z]\\|[a-zA-Z]*\\)"
852cd5fb 1664 ;; '(0 font-lock-keyword-face))
f617db13
MW
1665
1666 ;; --- Make sure we get comments properly ---
1667
1668 (list "%.*"
1669 '(0 font-lock-comment-face))
1670
1671 ;; --- Fontify TeX special characters as punctuation ---
1672
1673 (list "[$^_{}#&]"
1674 '(0 mdw-punct-face)))))
1675
f25cf300
MW
1676;;;----- SGML hacking -------------------------------------------------------
1677
1678(defun mdw-sgml-mode ()
1679 (interactive)
1680 (sgml-mode)
1681 (mdw-standard-fill-prefix "")
1682 (make-variable-buffer-local 'sgml-delimiters)
1683 (setq sgml-delimiters
1684 '("AND" "&" "COM" "--" "CRO" "&#" "DSC" "]" "DSO" "[" "DTGC" "]"
1685 "DTGO" "[" "ERO" "&" "ETAGO" ":e" "GRPC" ")" "GRPO" "(" "LIT" "\""
1686 "LITA" "'" "MDC" ">" "MDO" "<!" "MINUS" "-" "MSC" "]]" "NESTC" "{"
1687 "NET" "}" "OPT" "?" "OR" "|" "PERO" "%" "PIC" ">" "PIO" "<?"
1688 "PLUS" "+" "REFC" "." "REP" "*" "RNI" "#" "SEQ" "," "STAGO" ":"
1689 "TAGC" "." "VI" "=" "MS-START" "<![" "MS-END" "]]>"
1690 "XML-ECOM" "-->" "XML-PIC" "?>" "XML-SCOM" "<!--" "XML-TAGCE" "/>"
1691 "NULL" ""))
1692 (setq major-mode 'mdw-sgml-mode)
1693 (setq mode-name "[mdw] SGML")
1694 (run-hooks 'mdw-sgml-mode-hook))
1695
f617db13
MW
1696;;;----- Shell scripts ------------------------------------------------------
1697
1698(defun mdw-setup-sh-script-mode ()
1699
1700 ;; --- Fetch the shell interpreter's name ---
1701
1702 (let ((shell-name sh-shell-file))
1703
1704 ;; --- Try reading the hash-bang line ---
1705
1706 (save-excursion
1707 (goto-char (point-min))
1708 (if (looking-at "#![ \t]*\\([^ \t\n]*\\)")
1709 (setq shell-name (match-string 1))))
1710
1711 ;; --- Now try to set the shell ---
1712 ;;
1713 ;; Don't let `sh-set-shell' bugger up my script.
1714
1715 (let ((executable-set-magic #'(lambda (s &rest r) s)))
1716 (sh-set-shell shell-name)))
1717
1718 ;; --- Now enable my keys and the fontification ---
1719
1720 (mdw-misc-mode-config)
1721
1722 ;; --- Set the indentation level correctly ---
1723
1724 (setq sh-indentation 2)
1725 (setq sh-basic-offset 2))
1726
1727;;;----- Messages-file mode -------------------------------------------------
1728
1729(defun message-mode-guts ()
1730 (setq messages-mode-syntax-table (make-syntax-table))
1731 (set-syntax-table messages-mode-syntax-table)
1732 (modify-syntax-entry ?_ "w" messages-mode-syntax-table)
1733 (modify-syntax-entry ?- "w" messages-mode-syntax-table)
1734 (modify-syntax-entry ?0 "w" messages-mode-syntax-table)
1735 (modify-syntax-entry ?1 "w" messages-mode-syntax-table)
1736 (modify-syntax-entry ?2 "w" messages-mode-syntax-table)
1737 (modify-syntax-entry ?3 "w" messages-mode-syntax-table)
1738 (modify-syntax-entry ?4 "w" messages-mode-syntax-table)
1739 (modify-syntax-entry ?5 "w" messages-mode-syntax-table)
1740 (modify-syntax-entry ?6 "w" messages-mode-syntax-table)
1741 (modify-syntax-entry ?7 "w" messages-mode-syntax-table)
1742 (modify-syntax-entry ?8 "w" messages-mode-syntax-table)
1743 (modify-syntax-entry ?9 "w" messages-mode-syntax-table)
1744 (make-local-variable 'comment-start)
1745 (make-local-variable 'comment-end)
1746 (make-local-variable 'indent-line-function)
1747 (setq indent-line-function 'indent-relative)
1748 (mdw-standard-fill-prefix "\\([ \t]*\\(;\\|/?\\*\\)+[ \t]*\\)")
1749 (make-local-variable 'font-lock-defaults)
1750 (make-local-variable 'message-mode-keywords)
1751 (let ((keywords
c7a8da49 1752 (mdw-regexps '("array" "bitmap" "callback" "docs[ \t]+enum"
f617db13
MW
1753 "export" "enum" "fixed-octetstring" "flags"
1754 "harmless" "map" "nested" "optional"
1755 "optional-tagged" "package" "primitive"
1756 "primitive-nullfree" "relaxed[ \t]+enum"
1757 "set" "table" "tagged-optional" "union"
1758 "variadic" "vector" "version" "version-tag"))))
1759 (setq message-mode-keywords
1760 (list
1761 (list (concat "\\<\\(" keywords "\\)\\>:")
1762 '(0 font-lock-keyword-face))
1763 '("\\([-a-zA-Z0-9]+:\\)" (0 font-lock-warning-face))
1764 '("\\(\\<[a-z][-_a-zA-Z0-9]*\\)"
1765 (0 font-lock-variable-name-face))
1766 '("\\<\\([0-9]+\\)\\>" (0 mdw-number-face))
1767 '("\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1768 (0 mdw-punct-face)))))
1769 (setq font-lock-defaults
1770 '(message-mode-keywords nil nil nil nil))
1771 (run-hooks 'messages-file-hook))
1772
1773(defun messages-mode ()
1774 (interactive)
1775 (fundamental-mode)
1776 (setq major-mode 'messages-mode)
1777 (setq mode-name "Messages")
1778 (message-mode-guts)
1779 (modify-syntax-entry ?# "<" messages-mode-syntax-table)
1780 (modify-syntax-entry ?\n ">" messages-mode-syntax-table)
1781 (setq comment-start "# ")
1782 (setq comment-end "")
1783 (turn-on-font-lock-if-enabled)
1784 (run-hooks 'messages-mode-hook))
1785
1786(defun cpp-messages-mode ()
1787 (interactive)
1788 (fundamental-mode)
1789 (setq major-mode 'cpp-messages-mode)
1790 (setq mode-name "CPP Messages")
1791 (message-mode-guts)
1792 (modify-syntax-entry ?* ". 23" messages-mode-syntax-table)
1793 (modify-syntax-entry ?/ ". 14" messages-mode-syntax-table)
1794 (setq comment-start "/* ")
1795 (setq comment-end " */")
1796 (let ((preprocessor-keywords
c7a8da49 1797 (mdw-regexps '("assert" "define" "elif" "else" "endif" "error"
f617db13
MW
1798 "ident" "if" "ifdef" "ifndef" "import" "include"
1799 "line" "pragma" "unassert" "undef" "warning"))))
1800 (setq message-mode-keywords
1801 (append (list (list (concat "^[ \t]*\\#[ \t]*"
1802 "\\(include\\|import\\)"
1803 "[ \t]*\\(<[^>]+\\(>\\|\\)\\)")
1804 '(2 font-lock-string-face))
1805 (list (concat "^\\([ \t]*#[ \t]*\\(\\("
1806 preprocessor-keywords
852cd5fb 1807 "\\)\\>\\|[0-9]+\\|$\\)\\)")
f617db13
MW
1808 '(1 font-lock-keyword-face)))
1809 message-mode-keywords)))
f617db13 1810 (turn-on-font-lock-if-enabled)
297d60aa 1811 (run-hooks 'cpp-messages-mode-hook))
f617db13 1812
297d60aa
MW
1813(add-hook 'messages-mode-hook 'mdw-misc-mode-config t)
1814(add-hook 'cpp-messages-mode-hook 'mdw-misc-mode-config t)
f617db13
MW
1815; (add-hook 'messages-file-hook 'mdw-fontify-messages t)
1816
1817;;;----- Messages-file mode -------------------------------------------------
1818
1819(defvar mallow-driver-substitution-face 'mallow-driver-substitution-face
1820 "Face to use for subsittution directives.")
1821(make-face 'mallow-driver-substitution-face)
1822(defvar mallow-driver-text-face 'mallow-driver-text-face
1823 "Face to use for body text.")
1824(make-face 'mallow-driver-text-face)
1825
1826(defun mallow-driver-mode ()
1827 (interactive)
1828 (fundamental-mode)
1829 (setq major-mode 'mallow-driver-mode)
1830 (setq mode-name "Mallow driver")
1831 (setq mallow-driver-mode-syntax-table (make-syntax-table))
1832 (set-syntax-table mallow-driver-mode-syntax-table)
1833 (make-local-variable 'comment-start)
1834 (make-local-variable 'comment-end)
1835 (make-local-variable 'indent-line-function)
1836 (setq indent-line-function 'indent-relative)
1837 (mdw-standard-fill-prefix "\\([ \t]*\\(;\\|/?\\*\\)+[ \t]*\\)")
1838 (make-local-variable 'font-lock-defaults)
1839 (make-local-variable 'mallow-driver-mode-keywords)
1840 (let ((keywords
c7a8da49 1841 (mdw-regexps '("each" "divert" "file" "if"
f617db13
MW
1842 "perl" "set" "string" "type" "write"))))
1843 (setq mallow-driver-mode-keywords
1844 (list
1845 (list (concat "^%\\s *\\(}\\|\\(" keywords "\\)\\>\\).*$")
1846 '(0 font-lock-keyword-face))
1847 (list "^%\\s *\\(#.*\\|\\)$"
1848 '(0 font-lock-comment-face))
1849 (list "^%"
1850 '(0 font-lock-keyword-face))
1851 (list "^|?\\(.+\\)$" '(1 mallow-driver-text-face))
1852 (list "\\${[^}]*}"
1853 '(0 mallow-driver-substitution-face t)))))
1854 (setq font-lock-defaults
1855 '(mallow-driver-mode-keywords nil nil nil nil))
1856 (modify-syntax-entry ?\" "_" mallow-driver-mode-syntax-table)
1857 (modify-syntax-entry ?\n ">" mallow-driver-mode-syntax-table)
1858 (setq comment-start "%# ")
1859 (setq comment-end "")
1860 (turn-on-font-lock-if-enabled)
1861 (run-hooks 'mallow-driver-mode-hook))
1862
1863(add-hook 'mallow-driver-hook 'mdw-misc-mode-config t)
1864
1865;;;----- NFast debugs -------------------------------------------------------
1866
1867(defun nfast-debug-mode ()
1868 (interactive)
1869 (fundamental-mode)
1870 (setq major-mode 'nfast-debug-mode)
1871 (setq mode-name "NFast debug")
1872 (setq messages-mode-syntax-table (make-syntax-table))
1873 (set-syntax-table messages-mode-syntax-table)
1874 (make-local-variable 'font-lock-defaults)
1875 (make-local-variable 'nfast-debug-mode-keywords)
1876 (setq truncate-lines t)
1877 (setq nfast-debug-mode-keywords
1878 (list
1879 '("^\\(NFast_\\(Connect\\|Disconnect\\|Submit\\|Wait\\)\\)"
1880 (0 font-lock-keyword-face))
1881 (list (concat "^[ \t]+\\(\\("
1882 "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"
1883 "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"
1884 "[ \t]+\\)*"
1885 "[0-9a-fA-F]+\\)[ \t]*$")
1886 '(0 mdw-number-face))
1887 '("^[ \t]+\.status=[ \t]+\\<\\(OK\\)\\>"
1888 (1 font-lock-keyword-face))
1889 '("^[ \t]+\.status=[ \t]+\\<\\([a-zA-Z][0-9a-zA-Z]*\\)\\>"
1890 (1 font-lock-warning-face))
1891 '("^[ \t]+\.status[ \t]+\\<\\(zero\\)\\>"
1892 (1 nil))
1893 (list (concat "^[ \t]+\\.cmd=[ \t]+"
1894 "\\<\\([a-zA-Z][0-9a-zA-Z]*\\)\\>")
1895 '(1 font-lock-keyword-face))
1896 '("-?\\<\\([0-9]+\\|0x[0-9a-fA-F]+\\)\\>" (0 mdw-number-face))
1897 '("^\\([ \t]+[a-z0-9.]+\\)" (0 font-lock-variable-name-face))
1898 '("\\<\\([a-z][a-z0-9.]+\\)\\>=" (1 font-lock-variable-name-face))
1899 '("\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" (0 mdw-punct-face))))
1900 (setq font-lock-defaults
1901 '(nfast-debug-mode-keywords nil nil nil nil))
1902 (turn-on-font-lock-if-enabled)
1903 (run-hooks 'nfast-debug-mode-hook))
1904
1905;;;----- Other languages ----------------------------------------------------
1906
1907;; --- Smalltalk ---
1908
1909(defun mdw-setup-smalltalk ()
1910 (and mdw-auto-indent
1911 (local-set-key "\C-m" 'smalltalk-newline-and-indent))
1912 (make-variable-buffer-local 'mdw-auto-indent)
1913 (setq mdw-auto-indent nil)
1914 (local-set-key "\C-i" 'smalltalk-reindent))
1915
1916(defun mdw-fontify-smalltalk ()
02109a0d 1917 (make-local-variable 'font-lock-keywords)
f617db13
MW
1918 (setq font-lock-keywords
1919 (list
f617db13
MW
1920 (list "\\<[A-Z][a-zA-Z0-9]*\\>"
1921 '(0 font-lock-keyword-face))
1922 (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
1923 "[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
1924 "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
1925 '(0 mdw-number-face))
1926 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1927 '(0 mdw-punct-face)))))
1928
1929;; --- Lispy languages ---
1930
1931(defun mdw-indent-newline-and-indent ()
1932 (interactive)
1933 (indent-for-tab-command)
1934 (newline-and-indent))
1935
1936(eval-after-load "cl-indent"
1937 '(progn
1938 (mapc #'(lambda (pair)
1939 (put (car pair)
1940 'common-lisp-indent-function
1941 (cdr pair)))
1942 '((destructuring-bind . ((&whole 4 &rest 1) 4 &body))
1943 (multiple-value-bind . ((&whole 4 &rest 1) 4 &body))))))
1944
1945(defun mdw-common-lisp-indent ()
1946 (make-variable-buffer-local 'lisp-indent-function)
1947 (setq lisp-indent-function 'common-lisp-indent-function))
1948
1949(defun mdw-fontify-lispy ()
1950
1951 ;; --- Set fill prefix ---
1952
1953 (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)")
1954
1955 ;; --- Not much fontification needed ---
1956
02109a0d 1957 (make-local-variable 'font-lock-keywords)
f617db13
MW
1958 (setq font-lock-keywords
1959 (list
f617db13
MW
1960 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1961 '(0 mdw-punct-face)))))
1962
1963(defun comint-send-and-indent ()
1964 (interactive)
1965 (comint-send-input)
1966 (and mdw-auto-indent
1967 (indent-for-tab-command)))
1968
ec007bea
MW
1969(defun mdw-setup-m4 ()
1970 (mdw-standard-fill-prefix "\\([ \t]*\\(?:#+\\|\\<dnl\\>\\)[ \t]*\\)"))
1971
f617db13
MW
1972;;;----- Text mode ----------------------------------------------------------
1973
1974(defun mdw-text-mode ()
1975 (setq fill-column 72)
1976 (flyspell-mode t)
1977 (mdw-standard-fill-prefix
c7a8da49 1978 "\\([ \t]*\\([>#|:] ?\\)*[ \t]*\\)" 3)
f617db13
MW
1979 (auto-fill-mode 1))
1980
1981;;;----- Shell mode ---------------------------------------------------------
1982
1983(defun mdw-sh-mode-setup ()
1984 (local-set-key [?\C-a] 'comint-bol)
1985 (add-hook 'comint-output-filter-functions
1986 'comint-watch-for-password-prompt))
1987
1988(defun mdw-term-mode-setup ()
502f4699 1989 (setq term-prompt-regexp "^[^]#$%>»}\n]*[]#$%>»}] *")
f617db13
MW
1990 (make-local-variable 'mouse-yank-at-point)
1991 (make-local-variable 'transient-mark-mode)
1992 (setq mouse-yank-at-point t)
1993 (setq transient-mark-mode nil)
1994 (auto-fill-mode -1)
1995 (setq tab-width 8))
1996
1997;;;----- That's all, folks --------------------------------------------------
1998
1999(provide 'dot-emacs)