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