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