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