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