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