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