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