chiark / gitweb /
dot/lisp-init.lisp: Don't override `HOME:' in CMUCL after all.
[profile] / el / dot-emacs.el
... / ...
CommitLineData
1;;; -*- mode: emacs-lisp; coding: utf-8 -*-
2;;;
3;;; Functions and macros for .emacs
4;;;
5;;; (c) 2004 Mark Wooding
6;;;
7
8;;;----- Licensing notice ---------------------------------------------------
9;;;
10;;; This program is free software; you can redistribute it and/or modify
11;;; it under the terms of the GNU General Public License as published by
12;;; the Free Software Foundation; either version 2 of the License, or
13;;; (at your option) any later version.
14;;;
15;;; This program is distributed in the hope that it will be useful,
16;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;;; GNU General Public License for more details.
19;;;
20;;; You should have received a copy of the GNU General Public License
21;;; along with this program; if not, write to the Free Software Foundation,
22;;; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24;;;--------------------------------------------------------------------------
25;;; Check command-line.
26
27(defvar mdw-fast-startup nil
28 "Whether .emacs should optimize for rapid startup.
29This may be at the expense of cool features.")
30(let ((probe nil) (next command-line-args))
31 (while next
32 (cond ((string= (car next) "--mdw-fast-startup")
33 (setq mdw-fast-startup t)
34 (if probe
35 (rplacd probe (cdr next))
36 (setq command-line-args (cdr next))))
37 (t
38 (setq probe next)))
39 (setq next (cdr next))))
40
41;;;--------------------------------------------------------------------------
42;;; Some general utilities.
43
44(eval-when-compile
45 (unless (fboundp 'make-regexp)
46 (load "make-regexp"))
47 (require 'cl))
48
49(defmacro mdw-regexps (&rest list)
50 "Turn a LIST of strings into a single regular expression at compile-time."
51 (declare (indent nil)
52 (debug 0))
53 `',(make-regexp list))
54
55(defun mdw-wrong ()
56 "This is not the key sequence you're looking for."
57 (interactive)
58 (error "wrong button"))
59
60;; Some error trapping.
61;;
62;; If individual bits of this file go tits-up, we don't particularly want
63;; the whole lot to stop right there and then, because it's bloody annoying.
64
65(defmacro trap (&rest forms)
66 "Execute FORMS without allowing errors to propagate outside."
67 (declare (indent 0)
68 (debug t))
69 `(condition-case err
70 ,(if (cdr forms) (cons 'progn forms) (car forms))
71 (error (message "Error (trapped): %s in %s"
72 (error-message-string err)
73 ',forms))))
74
75;; Configuration reading.
76
77(defvar mdw-config nil)
78(defun mdw-config (sym)
79 "Read the configuration variable named SYM."
80 (unless mdw-config
81 (setq mdw-config
82 (flet ((replace (what with)
83 (goto-char (point-min))
84 (while (re-search-forward what nil t)
85 (replace-match with t))))
86 (with-temp-buffer
87 (insert-file-contents "~/.mdw.conf")
88 (replace "^[ \t]*\\(#.*\\|\\)\n" "")
89 (replace (concat "^[ \t]*"
90 "\\([-a-zA-Z0-9_.]*\\)"
91 "[ \t]*=[ \t]*"
92 "\\(.*[^ \t\n]\\|\\)"
93 "[ \t]**\\(\n\\|$\\)")
94 "(\\1 . \"\\2\")\n")
95 (car (read-from-string
96 (concat "(" (buffer-string) ")")))))))
97 (cdr (assq sym mdw-config)))
98
99;; Local variables hacking.
100
101(defun run-local-vars-mode-hook ()
102 "Run a hook for the major-mode after local variables have been processed."
103 (run-hooks (intern (concat (symbol-name major-mode)
104 "-local-variables-hook"))))
105(add-hook 'hack-local-variables-hook 'run-local-vars-mode-hook)
106
107;; Set up the load path convincingly.
108
109(dolist (dir (append (and (boundp 'debian-emacs-flavor)
110 (list (concat "/usr/share/"
111 (symbol-name debian-emacs-flavor)
112 "/site-lisp")))))
113 (dolist (sub (directory-files dir t))
114 (when (and (file-accessible-directory-p sub)
115 (not (member sub load-path)))
116 (setq load-path (nconc load-path (list sub))))))
117
118;; Is an Emacs library available?
119
120(defun library-exists-p (name)
121 "Return non-nil if NAME is an available library.
122Return non-nil if NAME.el (or NAME.elc) somewhere on the Emacs
123load path. The non-nil value is the filename we found for the
124library."
125 (let ((path load-path) elt (foundp nil))
126 (while (and path (not foundp))
127 (setq elt (car path))
128 (setq path (cdr path))
129 (setq foundp (or (let ((file (concat elt "/" name ".elc")))
130 (and (file-exists-p file) file))
131 (let ((file (concat elt "/" name ".el")))
132 (and (file-exists-p file) file)))))
133 foundp))
134
135(defun maybe-autoload (symbol file &optional docstring interactivep type)
136 "Set an autoload if the file actually exists."
137 (and (library-exists-p file)
138 (autoload symbol file docstring interactivep type)))
139
140(defun mdw-kick-menu-bar (&optional frame)
141 "Regenerate FRAME's menu bar so it doesn't have empty menus."
142 (interactive)
143 (unless frame (setq frame (selected-frame)))
144 (let ((old (frame-parameter frame 'menu-bar-lines)))
145 (set-frame-parameter frame 'menu-bar-lines 0)
146 (set-frame-parameter frame 'menu-bar-lines old)))
147
148;; Splitting windows.
149
150(unless (fboundp 'scroll-bar-columns)
151 (defun scroll-bar-columns (side)
152 (cond ((eq side 'left) 0)
153 (window-system 3)
154 (t 1))))
155(unless (fboundp 'fringe-columns)
156 (defun fringe-columns (side)
157 (cond ((not window-system) 0)
158 ((eq side 'left) 1)
159 (t 2))))
160
161(defun mdw-horizontal-window-overhead ()
162 "Computes the horizontal window overhead.
163This is the number of columns used by fringes, scroll bars and other such
164cruft."
165 (if (not window-system)
166 1
167 (let ((tot 0))
168 (dolist (what '(scroll-bar fringe))
169 (dolist (side '(left right))
170 (incf tot (funcall (intern (concat (symbol-name what) "-columns"))
171 side))))
172 tot)))
173
174(defun mdw-split-window-horizontally (&optional width)
175 "Split a window horizontally.
176Without a numeric argument, split the window approximately in
177half. With a numeric argument WIDTH, allocate WIDTH columns to
178the left-hand window (if positive) or -WIDTH columns to the
179right-hand window (if negative). Space for scroll bars and
180fringes is not taken out of the allowance for WIDTH, unlike
181\\[split-window-horizontally]."
182 (interactive "P")
183 (split-window-horizontally
184 (cond ((null width) nil)
185 ((>= width 0) (+ width (mdw-horizontal-window-overhead)))
186 ((< width 0) width))))
187
188(defun mdw-divvy-window (&optional width)
189 "Split a wide window into appropriate widths."
190 (interactive "P")
191 (setq width (cond (width (prefix-numeric-value width))
192 ((and window-system
193 (>= emacs-major-version 22))
194 77)
195 (t 78)))
196 (let* ((win (selected-window))
197 (sb-width (mdw-horizontal-window-overhead))
198 (c (/ (+ (window-width) sb-width)
199 (+ width sb-width))))
200 (while (> c 1)
201 (setq c (1- c))
202 (split-window-horizontally (+ width sb-width))
203 (other-window 1))
204 (select-window win)))
205
206;; Don't raise windows unless I say so.
207
208(defvar mdw-inhibit-raise-frame nil
209 "*Whether `raise-frame' should do nothing when the frame is mapped.")
210
211(defadvice raise-frame
212 (around mdw-inhibit (&optional frame) activate compile)
213 "Don't actually do anything if `mdw-inhibit-raise-frame' is true, and the
214frame is actually mapped on the screen."
215 (if mdw-inhibit-raise-frame
216 (make-frame-visible frame)
217 ad-do-it))
218
219(defmacro mdw-advise-to-inhibit-raise-frame (function)
220 "Advise the FUNCTION not to raise frames, even if it wants to."
221 `(defadvice ,function
222 (around mdw-inhibit-raise (&rest hunoz) activate compile)
223 "Don't raise the window unless you have to."
224 (let ((mdw-inhibit-raise-frame t))
225 ad-do-it)))
226
227(mdw-advise-to-inhibit-raise-frame select-frame-set-input-focus)
228
229;; Transient mark mode hacks.
230
231(defadvice exchange-point-and-mark
232 (around mdw-highlight (&optional arg) activate compile)
233 "Maybe don't actually exchange point and mark.
234If `transient-mark-mode' is on and the mark is inactive, then
235just activate it. A non-trivial prefix argument will force the
236usual behaviour. A trivial prefix argument (i.e., just C-u) will
237activate the mark and temporarily enable `transient-mark-mode' if
238it's currently off."
239 (cond ((or mark-active
240 (and (not transient-mark-mode) (not arg))
241 (and arg (or (not (consp arg))
242 (not (= (car arg) 4)))))
243 ad-do-it)
244 (t
245 (or transient-mark-mode (setq transient-mark-mode 'only))
246 (set-mark (mark t)))))
247
248;; Functions for sexp diary entries.
249
250(defun mdw-weekday (l)
251 "Return non-nil if `date' falls on one of the days of the week in L.
252L is a list of day numbers (from 0 to 6 for Sunday through to
253Saturday) or symbols `sunday', `monday', etc. (or a mixture). If
254the date stored in `date' falls on a listed day, then the
255function returns non-nil."
256 (let ((d (calendar-day-of-week date)))
257 (or (memq d l)
258 (memq (nth d '(sunday monday tuesday wednesday
259 thursday friday saturday)) l))))
260
261(defun mdw-todo (&optional when)
262 "Return non-nil today, or on WHEN, whichever is later."
263 (let ((w (calendar-absolute-from-gregorian (calendar-current-date)))
264 (d (calendar-absolute-from-gregorian date)))
265 (if when
266 (setq w (max w (calendar-absolute-from-gregorian
267 (cond
268 ((not european-calendar-style)
269 when)
270 ((> (car when) 100)
271 (list (nth 1 when)
272 (nth 2 when)
273 (nth 0 when)))
274 (t
275 (list (nth 1 when)
276 (nth 0 when)
277 (nth 2 when))))))))
278 (eq w d)))
279
280;; Fighting with Org-mode's evil key maps.
281
282(defvar mdw-evil-keymap-keys
283 '(([S-up] . [?\C-c up])
284 ([S-down] . [?\C-c down])
285 ([S-left] . [?\C-c left])
286 ([S-right] . [?\C-c right])
287 (([M-up] [?\e up]) . [C-up])
288 (([M-down] [?\e down]) . [C-down])
289 (([M-left] [?\e left]) . [C-left])
290 (([M-right] [?\e right]) . [C-right]))
291 "Defines evil keybindings to clobber in `mdw-clobber-evil-keymap'.
292The value is an alist mapping evil keys (as a list, or singleton)
293to good keys (in the same form).")
294
295(defun mdw-clobber-evil-keymap (keymap)
296 "Replace evil key bindings in the KEYMAP.
297Evil key bindings are defined in `mdw-evil-keymap-keys'."
298 (dolist (entry mdw-evil-keymap-keys)
299 (let ((binding nil)
300 (keys (if (listp (car entry))
301 (car entry)
302 (list (car entry))))
303 (replacements (if (listp (cdr entry))
304 (cdr entry)
305 (list (cdr entry)))))
306 (catch 'found
307 (dolist (key keys)
308 (setq binding (lookup-key keymap key))
309 (when binding
310 (throw 'found nil))))
311 (when binding
312 (dolist (key keys)
313 (define-key keymap key nil))
314 (dolist (key replacements)
315 (define-key keymap key binding))))))
316
317(eval-after-load "org-latex"
318 '(progn
319 (push '("strayman"
320 "\\documentclass{strayman}
321\\usepackage[utf8]{inputenc}
322\\usepackage[palatino, helvetica, courier, maths=cmr]{mdwfonts}
323\\usepackage[T1]{fontenc}
324\\usepackage{graphicx, tikz, mdwtab, mdwmath, crypto, longtable}"
325 ("\\section{%s}" . "\\section*{%s}")
326 ("\\subsection{%s}" . "\\subsection*{%s}")
327 ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
328 ("\\paragraph{%s}" . "\\paragraph*{%s}")
329 ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
330 org-export-latex-classes)))
331
332(setq org-export-docbook-xslt-proc-command "xsltproc --output %o %s %i"
333 org-export-docbook-xsl-fo-proc-command "fop %i.safe %o"
334 org-export-docbook-xslt-stylesheet
335 "/usr/share/xml/docbook/stylesheet/docbook-xsl/fo/docbook.xsl")
336
337;; Some hacks to do with window placement.
338
339(defun mdw-clobber-other-windows-showing-buffer (buffer-or-name)
340 "Arrange that no windows on other frames are showing BUFFER-OR-NAME."
341 (interactive "bBuffer: ")
342 (let ((home-frame (selected-frame))
343 (buffer (get-buffer buffer-or-name))
344 (safe-buffer (get-buffer "*scratch*")))
345 (mapc (lambda (frame)
346 (or (eq frame home-frame)
347 (mapc (lambda (window)
348 (and (eq (window-buffer window) buffer)
349 (set-window-buffer window safe-buffer)))
350 (window-list frame))))
351 (frame-list))))
352
353(defvar mdw-inhibit-walk-windows nil
354 "If non-nil, then `walk-windows' does nothing.
355This is used by advice on `switch-to-buffer-other-frame' to inhibit finding
356buffers in random frames.")
357
358(defadvice walk-windows (around mdw-inhibit activate)
359 "If `mdw-inhibit-walk-windows' is non-nil, then do nothing."
360 (and (not mdw-inhibit-walk-windows)
361 ad-do-it))
362
363(defadvice switch-to-buffer-other-frame
364 (around mdw-always-new-frame activate)
365 "Always make a new frame.
366Even if an existing window in some random frame looks tempting."
367 (let ((mdw-inhibit-walk-windows t)) ad-do-it))
368
369(defadvice display-buffer (before mdw-inhibit-other-frames activate)
370 "Don't try to do anything fancy with other frames.
371Pretend they don't exist. They might be on other display devices."
372 (ad-set-arg 2 nil))
373
374;;;--------------------------------------------------------------------------
375;;; Mail and news hacking.
376
377(define-derived-mode mdwmail-mode mail-mode "[mdw] mail"
378 "Major mode for editing news and mail messages from external programs.
379Not much right now. Just support for doing MailCrypt stuff."
380 :syntax-table nil
381 :abbrev-table nil
382 (run-hooks 'mail-setup-hook))
383
384(define-key mdwmail-mode-map [?\C-c ?\C-c] 'disabled-operation)
385
386(add-hook 'mdwail-mode-hook
387 (lambda ()
388 (set-buffer-file-coding-system 'utf-8)
389 (make-local-variable 'paragraph-separate)
390 (make-local-variable 'paragraph-start)
391 (setq paragraph-start
392 (concat "[ \t]*[-_][-_][-_]+$\\|^-- \\|-----\\|"
393 paragraph-start))
394 (setq paragraph-separate
395 (concat "[ \t]*[-_][-_][-_]+$\\|^-- \\|-----\\|"
396 paragraph-separate))))
397
398;; How to encrypt in mdwmail.
399
400(defun mdwmail-mc-encrypt (&optional recip scm start end from sign)
401 (or start
402 (setq start (save-excursion
403 (goto-char (point-min))
404 (or (search-forward "\n\n" nil t) (point-min)))))
405 (or end
406 (setq end (point-max)))
407 (mc-encrypt-generic recip scm start end from sign))
408
409;; How to sign in mdwmail.
410
411(defun mdwmail-mc-sign (key scm start end uclr)
412 (or start
413 (setq start (save-excursion
414 (goto-char (point-min))
415 (or (search-forward "\n\n" nil t) (point-min)))))
416 (or end
417 (setq end (point-max)))
418 (mc-sign-generic key scm start end uclr))
419
420;; Some signature mangling.
421
422(defun mdwmail-mangle-signature ()
423 (save-excursion
424 (goto-char (point-min))
425 (perform-replace "\n-- \n" "\n-- " nil nil nil)))
426(add-hook 'mail-setup-hook 'mdwmail-mangle-signature)
427(add-hook 'message-setup-hook 'mdwmail-mangle-signature)
428
429;; Insert my login name into message-ids, so I can score replies.
430
431(defadvice message-unique-id (after mdw-user-name last activate compile)
432 "Ensure that the user's name appears at the end of the message-id string,
433so that it can be used for convenient filtering."
434 (setq ad-return-value (concat ad-return-value "." (user-login-name))))
435
436;; Tell my movemail hack where movemail is.
437;;
438;; This is needed to shup up warnings about LD_PRELOAD.
439
440(let ((path exec-path))
441 (while path
442 (let ((try (expand-file-name "movemail" (car path))))
443 (if (file-executable-p try)
444 (setenv "REAL_MOVEMAIL" try))
445 (setq path (cdr path)))))
446
447(eval-after-load "erc"
448 '(load "~/.ercrc.el"))
449
450;;;--------------------------------------------------------------------------
451;;; Utility functions.
452
453(or (fboundp 'line-number-at-pos)
454 (defun line-number-at-pos (&optional pos)
455 (let ((opoint (or pos (point))) start)
456 (save-excursion
457 (save-restriction
458 (goto-char (point-min))
459 (widen)
460 (forward-line 0)
461 (setq start (point))
462 (goto-char opoint)
463 (forward-line 0)
464 (1+ (count-lines 1 (point))))))))
465
466(defun mdw-uniquify-alist (&rest alists)
467 "Return the concatenation of the ALISTS with duplicate elements removed.
468The first association with a given key prevails; others are
469ignored. The input lists are not modified, although they'll
470probably become garbage."
471 (and alists
472 (let ((start-list (cons nil nil)))
473 (mdw-do-uniquify start-list
474 start-list
475 (car alists)
476 (cdr alists)))))
477
478(defun mdw-do-uniquify (done end l rest)
479 "A helper function for mdw-uniquify-alist.
480The DONE argument is a list whose first element is `nil'. It
481contains the uniquified alist built so far. The leading `nil' is
482stripped off at the end of the operation; it's only there so that
483DONE always references a cons cell. END refers to the final cons
484cell in the DONE list; it is modified in place each time to avoid
485the overheads of `append'ing all the time. The L argument is the
486alist we're currently processing; the remaining alists are given
487in REST."
488
489 ;; There are several different cases to deal with here.
490 (cond
491
492 ;; Current list isn't empty. Add the first item to the DONE list if
493 ;; there's not an item with the same KEY already there.
494 (l (or (assoc (car (car l)) done)
495 (progn
496 (setcdr end (cons (car l) nil))
497 (setq end (cdr end))))
498 (mdw-do-uniquify done end (cdr l) rest))
499
500 ;; The list we were working on is empty. Shunt the next list into the
501 ;; current list position and go round again.
502 (rest (mdw-do-uniquify done end (car rest) (cdr rest)))
503
504 ;; Everything's done. Remove the leading `nil' from the DONE list and
505 ;; return it. Finished!
506 (t (cdr done))))
507
508(defun date ()
509 "Insert the current date in a pleasing way."
510 (interactive)
511 (insert (save-excursion
512 (let ((buffer (get-buffer-create "*tmp*")))
513 (unwind-protect (progn (set-buffer buffer)
514 (erase-buffer)
515 (shell-command "date +%Y-%m-%d" t)
516 (goto-char (mark))
517 (delete-backward-char 1)
518 (buffer-string))
519 (kill-buffer buffer))))))
520
521(defun uuencode (file &optional name)
522 "UUencodes a file, maybe calling it NAME, into the current buffer."
523 (interactive "fInput file name: ")
524
525 ;; If NAME isn't specified, then guess from the filename.
526 (if (not name)
527 (setq name
528 (substring file
529 (or (string-match "[^/]*$" file) 0))))
530 (print (format "uuencode `%s' `%s'" file name))
531
532 ;; Now actually do the thing.
533 (call-process "uuencode" file t nil name))
534
535(defvar np-file "~/.np"
536 "*Where the `now-playing' file is.")
537
538(defun np (&optional arg)
539 "Grabs a `now-playing' string."
540 (interactive)
541 (save-excursion
542 (or arg (progn
543 (goto-char (point-max))
544 (insert "\nNP: ")
545 (insert-file-contents np-file)))))
546
547(defun mdw-version-< (ver-a ver-b)
548 "Answer whether VER-A is strictly earlier than VER-B.
549VER-A and VER-B are version numbers, which are strings containing digit
550sequences separated by `.'."
551 (let* ((la (mapcar (lambda (x) (car (read-from-string x)))
552 (split-string ver-a "\\.")))
553 (lb (mapcar (lambda (x) (car (read-from-string x)))
554 (split-string ver-b "\\."))))
555 (catch 'done
556 (while t
557 (cond ((null la) (throw 'done lb))
558 ((null lb) (throw 'done nil))
559 ((< (car la) (car lb)) (throw 'done t))
560 ((= (car la) (car lb)) (setq la (cdr la) lb (cdr lb))))))))
561
562(defun mdw-check-autorevert ()
563 "Sets global-auto-revert-ignore-buffer appropriately for this buffer.
564This takes into consideration whether it's been found using
565tramp, which seems to get itself into a twist."
566 (cond ((not (boundp 'global-auto-revert-ignore-buffer))
567 nil)
568 ((and (buffer-file-name)
569 (fboundp 'tramp-tramp-file-p)
570 (tramp-tramp-file-p (buffer-file-name)))
571 (unless global-auto-revert-ignore-buffer
572 (setq global-auto-revert-ignore-buffer 'tramp)))
573 ((eq global-auto-revert-ignore-buffer 'tramp)
574 (setq global-auto-revert-ignore-buffer nil))))
575
576(defadvice find-file (after mdw-autorevert activate)
577 (mdw-check-autorevert))
578(defadvice write-file (after mdw-autorevert activate)
579 (mdw-check-autorevert))
580
581;;;--------------------------------------------------------------------------
582;;; Dired hacking.
583
584(defadvice dired-maybe-insert-subdir
585 (around mdw-marked-insertion first activate)
586 "The DIRNAME may be a list of directory names to insert.
587Interactively, if files are marked, then insert all of them.
588With a numeric prefix argument, select that many entries near
589point; with a non-numeric prefix argument, prompt for listing
590options."
591 (interactive
592 (list (dired-get-marked-files nil
593 (and (integerp current-prefix-arg)
594 current-prefix-arg)
595 #'file-directory-p)
596 (and current-prefix-arg
597 (not (integerp current-prefix-arg))
598 (read-string "Switches for listing: "
599 (or dired-subdir-switches
600 dired-actual-switches)))))
601 (let ((dirs (ad-get-arg 0)))
602 (dolist (dir (if (listp dirs) dirs (list dirs)))
603 (ad-set-arg 0 dir)
604 ad-do-it)))
605
606;;;--------------------------------------------------------------------------
607;;; URL viewing.
608
609(defun mdw-w3m-browse-url (url &optional new-session-p)
610 "Invoke w3m on the URL in its current window, or at least a different one.
611If NEW-SESSION-P, start a new session."
612 (interactive "sURL: \nP")
613 (save-excursion
614 (let ((window (selected-window)))
615 (unwind-protect
616 (progn
617 (select-window (or (and (not new-session-p)
618 (get-buffer-window "*w3m*"))
619 (progn
620 (if (one-window-p t) (split-window))
621 (get-lru-window))))
622 (w3m-browse-url url new-session-p))
623 (select-window window)))))
624
625(defvar mdw-good-url-browsers
626 '(browse-url-mozilla
627 browse-url-generic
628 (w3m . mdw-w3m-browse-url)
629 browse-url-w3)
630 "List of good browsers for mdw-good-url-browsers.
631Each item is a browser function name, or a cons (CHECK . FUNC).
632A symbol FOO stands for (FOO . FOO).")
633
634(defun mdw-good-url-browser ()
635 "Return a good URL browser.
636Trundle the list of such things, finding the first item for which
637CHECK is fboundp, and returning the correponding FUNC."
638 (let ((bs mdw-good-url-browsers) b check func answer)
639 (while (and bs (not answer))
640 (setq b (car bs)
641 bs (cdr bs))
642 (if (consp b)
643 (setq check (car b) func (cdr b))
644 (setq check b func b))
645 (if (fboundp check)
646 (setq answer func)))
647 answer))
648
649(eval-after-load "w3m-search"
650 '(progn
651 (dolist
652 (item
653 '(("g" "Google" "http://www.google.co.uk/search?q=%s")
654 ("gd" "Google Directory"
655 "http://www.google.com/search?cat=gwd/Top&q=%s")
656 ("gg" "Google Groups" "http://groups.google.com/groups?q=%s")
657 ("ward" "Ward's wiki" "http://c2.com/cgi/wiki?%s")
658 ("gi" "Images" "http://images.google.com/images?q=%s")
659 ("rfc" "RFC"
660 "http://metalzone.distorted.org.uk/ftp/pub/mirrors/rfc/rfc%s.txt.gz")
661 ("wp" "Wikipedia"
662 "http://en.wikipedia.org/wiki/Special:Search?go=Go&search=%s")
663 ("imdb" "IMDb" "http://www.imdb.com/Find?%s")
664 ("nc-wiki" "nCipher wiki"
665 "http://wiki.ncipher.com/wiki/bin/view/Devel/?topic=%s")
666 ("map" "Google maps" "http://maps.google.co.uk/maps?q=%s&hl=en")
667 ("lp" "Launchpad bug by number"
668 "https://bugs.launchpad.net/bugs/%s")
669 ("lppkg" "Launchpad bugs by package"
670 "https://bugs.launchpad.net/%s")
671 ("msdn" "MSDN"
672 "http://social.msdn.microsoft.com/Search/en-GB/?query=%s&ac=8")
673 ("debbug" "Debian bug by number"
674 "http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=%s")
675 ("debbugpkg" "Debian bugs by package"
676 "http://bugs.debian.org/cgi-bin/pkgreport.cgi?pkg=%s")
677 ("ljlogin" "LJ login" "http://www.livejournal.com/login.bml")))
678 (add-to-list 'w3m-search-engine-alist
679 (list (cadr item) (caddr item) nil))
680 (add-to-list 'w3m-uri-replace-alist
681 (list (concat "\\`" (car item) ":")
682 'w3m-search-uri-replace
683 (cadr item))))))
684
685;;;--------------------------------------------------------------------------
686;;; Paragraph filling.
687
688;; Useful variables.
689
690(defvar mdw-fill-prefix nil
691 "*Used by `mdw-line-prefix' and `mdw-fill-paragraph'.
692If there's no fill prefix currently set (by the `fill-prefix'
693variable) and there's a match from one of the regexps here, it
694gets used to set the fill-prefix for the current operation.
695
696The variable is a list of items of the form `REGEXP . PREFIX'; if
697the REGEXP matches, the PREFIX is used to set the fill prefix.
698It in turn is a list of things:
699
700 STRING -- insert a literal string
701 (match . N) -- insert the thing matched by bracketed subexpression N
702 (pad . N) -- a string of whitespace the same width as subexpression N
703 (expr . FORM) -- the result of evaluating FORM")
704
705(make-variable-buffer-local 'mdw-fill-prefix)
706
707(defvar mdw-hanging-indents
708 (concat "\\(\\("
709 "\\([*o+]\\|-[-#]?\\|[0-9]+\\.\\|\\[[0-9]+\\]\\|([a-zA-Z])\\)"
710 "[ \t]+"
711 "\\)?\\)")
712 "*Standard regexp matching parts of a hanging indent.
713This is mainly useful in `auto-fill-mode'.")
714
715;; Setting things up.
716
717(fset 'mdw-do-auto-fill (symbol-function 'do-auto-fill))
718
719;; Utility functions.
720
721(defun mdw-maybe-tabify (s)
722 "Tabify or untabify the string S, according to `indent-tabs-mode'."
723 (let ((tabfun (if indent-tabs-mode #'tabify #'untabify)))
724 (with-temp-buffer
725 (save-match-data
726 (insert s "\n")
727 (let ((start (point-min)) (end (point-max)))
728 (funcall tabfun (point-min) (point-max))
729 (setq s (buffer-substring (point-min) (1- (point-max)))))))))
730
731(defun mdw-examine-fill-prefixes (l)
732 "Given a list of dynamic fill prefixes, pick one which matches
733context and return the static fill prefix to use. Point must be
734at the start of a line, and match data must be saved."
735 (cond ((not l) nil)
736 ((looking-at (car (car l)))
737 (mdw-maybe-tabify (apply #'concat
738 (mapcar #'mdw-do-prefix-match
739 (cdr (car l))))))
740 (t (mdw-examine-fill-prefixes (cdr l)))))
741
742(defun mdw-maybe-car (p)
743 "If P is a pair, return (car P), otherwise just return P."
744 (if (consp p) (car p) p))
745
746(defun mdw-padding (s)
747 "Return a string the same width as S but made entirely from whitespace."
748 (let* ((l (length s)) (i 0) (n (make-string l ? )))
749 (while (< i l)
750 (if (= 9 (aref s i))
751 (aset n i 9))
752 (setq i (1+ i)))
753 n))
754
755(defun mdw-do-prefix-match (m)
756 "Expand a dynamic prefix match element.
757See `mdw-fill-prefix' for details."
758 (cond ((not (consp m)) (format "%s" m))
759 ((eq (car m) 'match) (match-string (mdw-maybe-car (cdr m))))
760 ((eq (car m) 'pad) (mdw-padding (match-string
761 (mdw-maybe-car (cdr m)))))
762 ((eq (car m) 'eval) (eval (cdr m)))
763 (t "")))
764
765(defun mdw-choose-dynamic-fill-prefix ()
766 "Work out the dynamic fill prefix based on the variable `mdw-fill-prefix'."
767 (cond ((and fill-prefix (not (string= fill-prefix ""))) fill-prefix)
768 ((not mdw-fill-prefix) fill-prefix)
769 (t (save-excursion
770 (beginning-of-line)
771 (save-match-data
772 (mdw-examine-fill-prefixes mdw-fill-prefix))))))
773
774(defun do-auto-fill ()
775 "Handle auto-filling, working out a dynamic fill prefix in the
776case where there isn't a sensible static one."
777 (let ((fill-prefix (mdw-choose-dynamic-fill-prefix)))
778 (mdw-do-auto-fill)))
779
780(defun mdw-fill-paragraph ()
781 "Fill paragraph, getting a dynamic fill prefix."
782 (interactive)
783 (let ((fill-prefix (mdw-choose-dynamic-fill-prefix)))
784 (fill-paragraph nil)))
785
786(defun mdw-standard-fill-prefix (rx &optional mat)
787 "Set the dynamic fill prefix, handling standard hanging indents and stuff.
788This is just a short-cut for setting the thing by hand, and by
789design it doesn't cope with anything approximating a complicated
790case."
791 (setq mdw-fill-prefix
792 `((,(concat rx mdw-hanging-indents)
793 (match . 1)
794 (pad . ,(or mat 2))))))
795
796;;;--------------------------------------------------------------------------
797;;; Other common declarations.
798
799;; Common mode settings.
800
801(defvar mdw-auto-indent t
802 "Whether to indent automatically after a newline.")
803
804(defun mdw-whitespace-mode (&optional arg)
805 "Turn on/off whitespace mode, but don't highlight trailing space."
806 (interactive "P")
807 (when (and (boundp 'whitespace-style)
808 (fboundp 'whitespace-mode))
809 (let ((whitespace-style (remove 'trailing whitespace-style)))
810 (whitespace-mode arg))
811 (setq show-trailing-whitespace whitespace-mode)))
812
813(defvar mdw-do-misc-mode-hacking nil)
814
815(defun mdw-misc-mode-config ()
816 (and mdw-auto-indent
817 (cond ((eq major-mode 'lisp-mode)
818 (local-set-key "\C-m" 'mdw-indent-newline-and-indent))
819 ((or (eq major-mode 'slime-repl-mode)
820 (eq major-mode 'asm-mode))
821 nil)
822 (t
823 (local-set-key "\C-m" 'newline-and-indent))))
824 (set (make-local-variable 'mdw-do-misc-mode-hacking) t)
825 (local-set-key [C-return] 'newline)
826 (make-local-variable 'page-delimiter)
827 (setq page-delimiter "\f\\|^.*-\\{6\\}.*$")
828 (setq comment-column 40)
829 (auto-fill-mode 1)
830 (setq fill-column 77)
831 (and (fboundp 'gtags-mode)
832 (gtags-mode))
833 (if (fboundp 'hs-minor-mode)
834 (trap (hs-minor-mode t))
835 (outline-minor-mode t))
836 (reveal-mode t)
837 (trap (turn-on-font-lock)))
838
839(defun mdw-post-local-vars-misc-mode-config ()
840 (when (and mdw-do-misc-mode-hacking
841 (not buffer-read-only))
842 (setq show-trailing-whitespace t)
843 (mdw-whitespace-mode 1)))
844(add-hook 'hack-local-variables-hook 'mdw-post-local-vars-misc-mode-config)
845
846(defadvice toggle-read-only (after mdw-angry-fruit-salad activate)
847 (when mdw-do-misc-mode-hacking
848 (setq show-trailing-whitespace (not buffer-read-only))
849 (mdw-whitespace-mode (if buffer-read-only 0 1))))
850
851(eval-after-load 'gtags
852 '(progn
853 (dolist (key '([mouse-2] [mouse-3]))
854 (define-key gtags-mode-map key nil))
855 (define-key gtags-mode-map [C-S-mouse-2] 'gtags-find-tag-by-event)
856 (define-key gtags-select-mode-map [C-S-mouse-2]
857 'gtags-select-tag-by-event)
858 (dolist (map (list gtags-mode-map gtags-select-mode-map))
859 (define-key map [C-S-mouse-3] 'gtags-pop-stack))))
860
861;; Backup file handling.
862
863(defvar mdw-backup-disable-regexps nil
864 "*List of regular expressions: if a file name matches any of
865these then the file is not backed up.")
866
867(defun mdw-backup-enable-predicate (name)
868 "[mdw]'s default backup predicate.
869Allows a backup if the standard predicate would allow it, and it
870doesn't match any of the regular expressions in
871`mdw-backup-disable-regexps'."
872 (and (normal-backup-enable-predicate name)
873 (let ((answer t) (list mdw-backup-disable-regexps))
874 (save-match-data
875 (while list
876 (if (string-match (car list) name)
877 (setq answer nil))
878 (setq list (cdr list)))
879 answer))))
880(setq backup-enable-predicate 'mdw-backup-enable-predicate)
881
882;; Frame cleanup.
883
884(defun mdw-last-one-out-turn-off-the-lights (frame)
885 "Disconnect from an X display if this was the last frame on that display."
886 (let ((frame-display (frame-parameter frame 'display)))
887 (when (and frame-display
888 (eq window-system 'x)
889 (not (some (lambda (fr)
890 (and (not (eq fr frame))
891 (string= (frame-parameter fr 'display)
892 frame-display)))
893 (frame-list))))
894 (run-with-idle-timer 0 nil #'x-close-connection frame-display))))
895(add-hook 'delete-frame-functions 'mdw-last-one-out-turn-off-the-lights)
896
897;;;--------------------------------------------------------------------------
898;;; Where is point?
899
900(defvar mdw-point-overlay
901 (let ((ov (make-overlay 0 0))
902 (s "."))
903 (overlay-put ov 'priority 2)
904 (put-text-property 0 1 'display '(left-fringe vertical-bar) s)
905 (overlay-put ov 'before-string s)
906 (delete-overlay ov)
907 ov)
908 "An overlay used for showing where point is in the selected window.")
909
910(defun mdw-remove-point-overlay ()
911 "Remove the current-point overlay."
912 (delete-overlay mdw-point-overlay))
913
914(defun mdw-update-point-overlay ()
915 "Mark the current point position with an overlay."
916 (if (not mdw-point-overlay-mode)
917 (mdw-remove-point-overlay)
918 (overlay-put mdw-point-overlay 'window (selected-window))
919 (if (bolp)
920 (move-overlay mdw-point-overlay
921 (point) (1+ (point)) (current-buffer))
922 (move-overlay mdw-point-overlay
923 (1- (point)) (point) (current-buffer)))))
924
925(defvar mdw-point-overlay-buffers nil
926 "List of buffers using `mdw-point-overlay-mode'.")
927
928(define-minor-mode mdw-point-overlay-mode
929 "Indicate current line with an overlay."
930 :global nil
931 (let ((buffer (current-buffer)))
932 (setq mdw-point-overlay-buffers
933 (mapcan (lambda (buf)
934 (if (and (buffer-live-p buf)
935 (not (eq buf buffer)))
936 (list buf)))
937 mdw-point-overlay-buffers))
938 (if mdw-point-overlay-mode
939 (setq mdw-point-overlay-buffers
940 (cons buffer mdw-point-overlay-buffers))))
941 (cond (mdw-point-overlay-buffers
942 (add-hook 'pre-command-hook 'mdw-remove-point-overlay)
943 (add-hook 'post-command-hook 'mdw-update-point-overlay))
944 (t
945 (mdw-remove-point-overlay)
946 (remove-hook 'pre-command-hook 'mdw-remove-point-overlay)
947 (remove-hook 'post-command-hook 'mdw-update-point-overlay))))
948
949(define-globalized-minor-mode mdw-global-point-overlay-mode
950 mdw-point-overlay-mode
951 (lambda () (if (not (minibufferp)) (mdw-point-overlay-mode t))))
952
953;;;--------------------------------------------------------------------------
954;;; Fullscreen-ness.
955
956(defvar mdw-full-screen-parameters
957 '((menu-bar-lines . 0)
958 ;(vertical-scroll-bars . nil)
959 )
960 "Frame parameters to set when making a frame fullscreen.")
961
962(defvar mdw-full-screen-save
963 '(width height)
964 "Extra frame parameters to save when setting fullscreen.")
965
966(defun mdw-toggle-full-screen (&optional frame)
967 "Show the FRAME fullscreen."
968 (interactive)
969 (when window-system
970 (cond ((frame-parameter frame 'fullscreen)
971 (set-frame-parameter frame 'fullscreen nil)
972 (modify-frame-parameters
973 nil
974 (or (frame-parameter frame 'mdw-full-screen-saved)
975 (mapcar (lambda (assoc)
976 (assq (car assoc) default-frame-alist))
977 mdw-full-screen-parameters))))
978 (t
979 (let ((saved (mapcar (lambda (param)
980 (cons param (frame-parameter frame param)))
981 (append (mapcar #'car
982 mdw-full-screen-parameters)
983 mdw-full-screen-save))))
984 (set-frame-parameter frame 'mdw-full-screen-saved saved))
985 (modify-frame-parameters frame mdw-full-screen-parameters)
986 (set-frame-parameter frame 'fullscreen 'fullboth)))))
987
988;;;--------------------------------------------------------------------------
989;;; General fontification.
990
991(defmacro mdw-define-face (name &rest body)
992 "Define a face, and make sure it's actually set as the definition."
993 (declare (indent 1)
994 (debug 0))
995 `(progn
996 (make-face ',name)
997 (defvar ,name ',name)
998 (put ',name 'face-defface-spec ',body)
999 (face-spec-set ',name ',body nil)))
1000
1001(mdw-define-face default
1002 (((type w32)) :family "courier new" :height 85)
1003 (((type x)) :family "6x13" :foundry "trad" :height 130)
1004 (((type color)) :foreground "white" :background "black")
1005 (t nil))
1006(mdw-define-face fixed-pitch
1007 (((type w32)) :family "courier new" :height 85)
1008 (((type x)) :family "6x13" :foundry "trad" :height 130)
1009 (t :foreground "white" :background "black"))
1010(if (>= emacs-major-version 23)
1011 (mdw-define-face variable-pitch
1012 (((type x)) :family "sans" :height 100))
1013 (mdw-define-face variable-pitch
1014 (((type x)) :family "helvetica" :height 90)))
1015(mdw-define-face region
1016 (((type tty) (class color)) :background "blue")
1017 (((type tty) (class mono)) :inverse-video t)
1018 (t :background "grey30"))
1019(mdw-define-face match
1020 (((type tty) (class color)) :background "blue")
1021 (((type tty) (class mono)) :inverse-video t)
1022 (t :background "blue"))
1023(mdw-define-face mc/cursor-face
1024 (((type tty) (class mono)) :inverse-video t)
1025 (t :background "red"))
1026(mdw-define-face minibuffer-prompt
1027 (t :weight bold))
1028(mdw-define-face mode-line
1029 (((class color)) :foreground "blue" :background "yellow"
1030 :box (:line-width 1 :style released-button))
1031 (t :inverse-video t))
1032(mdw-define-face mode-line-inactive
1033 (((class color)) :foreground "yellow" :background "blue"
1034 :box (:line-width 1 :style released-button))
1035 (t :inverse-video t))
1036(mdw-define-face nobreak-space
1037 (((type tty)))
1038 (t :inherit escape-glyph :underline t))
1039(mdw-define-face scroll-bar
1040 (t :foreground "black" :background "lightgrey"))
1041(mdw-define-face fringe
1042 (t :foreground "yellow"))
1043(mdw-define-face show-paren-match
1044 (((class color)) :background "darkgreen")
1045 (t :underline t))
1046(mdw-define-face show-paren-mismatch
1047 (((class color)) :background "red")
1048 (t :inverse-video t))
1049(mdw-define-face highlight
1050 (((type x) (class color)) :background "DarkSeaGreen4")
1051 (((type tty) (class color)) :background "cyan")
1052 (t :inverse-video t))
1053
1054(mdw-define-face holiday-face
1055 (t :background "red"))
1056(mdw-define-face calendar-today-face
1057 (t :foreground "yellow" :weight bold))
1058
1059(mdw-define-face comint-highlight-prompt
1060 (t :weight bold))
1061(mdw-define-face comint-highlight-input
1062 (t nil))
1063
1064(mdw-define-face dired-directory
1065 (t :foreground "cyan" :weight bold))
1066(mdw-define-face dired-symlink
1067 (t :foreground "cyan"))
1068(mdw-define-face dired-perm-write
1069 (t nil))
1070
1071(mdw-define-face trailing-whitespace
1072 (((class color)) :background "red")
1073 (t :inverse-video t))
1074(mdw-define-face mdw-punct-face
1075 (((type tty)) :foreground "yellow") (t :foreground "burlywood2"))
1076(mdw-define-face mdw-number-face
1077 (t :foreground "yellow"))
1078(mdw-define-face mdw-trivial-face)
1079(mdw-define-face font-lock-function-name-face
1080 (t :slant italic))
1081(mdw-define-face font-lock-keyword-face
1082 (t :weight bold))
1083(mdw-define-face font-lock-constant-face
1084 (t :slant italic))
1085(mdw-define-face font-lock-builtin-face
1086 (t :weight bold))
1087(mdw-define-face font-lock-type-face
1088 (t :weight bold :slant italic))
1089(mdw-define-face font-lock-reference-face
1090 (t :weight bold))
1091(mdw-define-face font-lock-variable-name-face
1092 (t :slant italic))
1093(mdw-define-face font-lock-comment-delimiter-face
1094 (((class mono)) :weight bold)
1095 (((type tty) (class color)) :foreground "green")
1096 (t :slant italic :foreground "SeaGreen1"))
1097(mdw-define-face font-lock-comment-face
1098 (((class mono)) :weight bold)
1099 (((type tty) (class color)) :foreground "green")
1100 (t :slant italic :foreground "SeaGreen1"))
1101(mdw-define-face font-lock-string-face
1102 (((class mono)) :weight bold)
1103 (((class color)) :foreground "SkyBlue1"))
1104
1105(mdw-define-face message-separator
1106 (t :background "red" :foreground "white" :weight bold))
1107(mdw-define-face message-cited-text
1108 (default :slant italic)
1109 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1110(mdw-define-face message-header-cc
1111 (default :weight bold)
1112 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1113(mdw-define-face message-header-newsgroups
1114 (default :weight bold)
1115 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1116(mdw-define-face message-header-subject
1117 (default :weight bold)
1118 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1119(mdw-define-face message-header-to
1120 (default :weight bold)
1121 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1122(mdw-define-face message-header-xheader
1123 (default :weight bold)
1124 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1125(mdw-define-face message-header-other
1126 (default :weight bold)
1127 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1128(mdw-define-face message-header-name
1129 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1130(mdw-define-face which-func
1131 (t nil))
1132
1133(mdw-define-face diff-header
1134 (t nil))
1135(mdw-define-face diff-index
1136 (t :weight bold))
1137(mdw-define-face diff-file-header
1138 (t :weight bold))
1139(mdw-define-face diff-hunk-header
1140 (t :foreground "SkyBlue1"))
1141(mdw-define-face diff-function
1142 (t :foreground "SkyBlue1" :weight bold))
1143(mdw-define-face diff-header
1144 (t :background "grey10"))
1145(mdw-define-face diff-added
1146 (t :foreground "green"))
1147(mdw-define-face diff-removed
1148 (t :foreground "red"))
1149(mdw-define-face diff-context
1150 (t nil))
1151(mdw-define-face diff-refine-change
1152 (((class color) (type x)) :background "RoyalBlue4")
1153 (t :underline t))
1154
1155(mdw-define-face dylan-header-background
1156 (((class color) (type x)) :background "NavyBlue")
1157 (t :background "blue"))
1158
1159(mdw-define-face magit-diff-add
1160 (t :foreground "green"))
1161(mdw-define-face magit-diff-del
1162 (t :foreground "red"))
1163(mdw-define-face magit-diff-file-header
1164 (t :weight bold))
1165(mdw-define-face magit-diff-hunk-header
1166 (t :foreground "SkyBlue1"))
1167(mdw-define-face magit-item-highlight
1168 (((type tty)) :background "blue")
1169 (t :background "DarkSeaGreen4"))
1170(mdw-define-face magit-log-head-label-remote
1171 (((type tty)) :background "cyan" :foreground "green")
1172 (t :background "grey11" :foreground "DarkSeaGreen2" :box t))
1173(mdw-define-face magit-log-head-label-local
1174 (((type tty)) :background "cyan" :foreground "yellow")
1175 (t :background "grey11" :foreground "LightSkyBlue1" :box t))
1176(mdw-define-face magit-log-head-label-tags
1177 (((type tty)) :background "red" :foreground "yellow")
1178 (t :background "LemonChiffon1" :foreground "goldenrod4" :box t))
1179(mdw-define-face magit-log-graph
1180 (((type tty)) :foreground "magenta")
1181 (t :foreground "grey80"))
1182
1183(mdw-define-face erc-input-face
1184 (t :foreground "red"))
1185
1186(mdw-define-face woman-bold
1187 (t :weight bold))
1188(mdw-define-face woman-italic
1189 (t :slant italic))
1190
1191(eval-after-load "rst"
1192 '(progn
1193 (mdw-define-face rst-level-1-face
1194 (t :foreground "SkyBlue1" :weight bold))
1195 (mdw-define-face rst-level-2-face
1196 (t :foreground "SeaGreen1" :weight bold))
1197 (mdw-define-face rst-level-3-face
1198 (t :weight bold))
1199 (mdw-define-face rst-level-4-face
1200 (t :slant italic))
1201 (mdw-define-face rst-level-5-face
1202 (t :underline t))
1203 (mdw-define-face rst-level-6-face
1204 ())))
1205
1206(mdw-define-face p4-depot-added-face
1207 (t :foreground "green"))
1208(mdw-define-face p4-depot-branch-op-face
1209 (t :foreground "yellow"))
1210(mdw-define-face p4-depot-deleted-face
1211 (t :foreground "red"))
1212(mdw-define-face p4-depot-unmapped-face
1213 (t :foreground "SkyBlue1"))
1214(mdw-define-face p4-diff-change-face
1215 (t :foreground "yellow"))
1216(mdw-define-face p4-diff-del-face
1217 (t :foreground "red"))
1218(mdw-define-face p4-diff-file-face
1219 (t :foreground "SkyBlue1"))
1220(mdw-define-face p4-diff-head-face
1221 (t :background "grey10"))
1222(mdw-define-face p4-diff-ins-face
1223 (t :foreground "green"))
1224
1225(mdw-define-face w3m-anchor-face
1226 (t :foreground "SkyBlue1" :underline t))
1227(mdw-define-face w3m-arrived-anchor-face
1228 (t :foreground "SkyBlue1" :underline t))
1229
1230(mdw-define-face whizzy-slice-face
1231 (t :background "grey10"))
1232(mdw-define-face whizzy-error-face
1233 (t :background "darkred"))
1234
1235;; Ellipses used to indicate hidden text (and similar).
1236(mdw-define-face mdw-ellipsis-face
1237 (((type tty)) :foreground "blue") (t :foreground "grey60"))
1238(let ((dollar (make-glyph-code ?$ 'mdw-ellipsis-face))
1239 (backslash (make-glyph-code ?\\ 'mdw-ellipsis-face))
1240 (dot (make-glyph-code ?. 'mdw-ellipsis-face))
1241 (bar (make-glyph-code ?| mdw-ellipsis-face)))
1242 (set-display-table-slot standard-display-table 0 dollar)
1243 (set-display-table-slot standard-display-table 1 backslash)
1244 (set-display-table-slot standard-display-table 4
1245 (vector dot dot dot))
1246 (set-display-table-slot standard-display-table 5 bar))
1247
1248;;;--------------------------------------------------------------------------
1249;;; C programming configuration.
1250
1251;; Linux kernel hacking.
1252
1253(defvar linux-c-mode-hook)
1254
1255(defun linux-c-mode ()
1256 (interactive)
1257 (c-mode)
1258 (setq major-mode 'linux-c-mode)
1259 (setq mode-name "Linux C")
1260 (run-hooks 'linux-c-mode-hook))
1261
1262;; Make C indentation nice.
1263
1264(defun mdw-c-lineup-arglist (langelem)
1265 "Hack for DWIMmery in c-lineup-arglist."
1266 (if (save-excursion
1267 (c-block-in-arglist-dwim (c-langelem-2nd-pos c-syntactic-element)))
1268 0
1269 (c-lineup-arglist langelem)))
1270
1271(defun mdw-c-indent-extern-mumble (langelem)
1272 "Indent `extern \"...\" {' lines."
1273 (save-excursion
1274 (back-to-indentation)
1275 (if (looking-at
1276 "\\s-*\\<extern\\>\\s-*\"\\([^\\\\\"]+\\|\\.\\)*\"\\s-*{")
1277 c-basic-offset
1278 nil)))
1279
1280(defun mdw-c-style ()
1281 (c-add-style "[mdw] C and C++ style"
1282 '((c-basic-offset . 2)
1283 (comment-column . 40)
1284 (c-class-key . "class")
1285 (c-backslash-column . 72)
1286 (c-offsets-alist
1287 (substatement-open . (add 0 c-indent-one-line-block))
1288 (defun-open . (add 0 c-indent-one-line-block))
1289 (arglist-cont-nonempty . mdw-c-lineup-arglist)
1290 (topmost-intro . mdw-c-indent-extern-mumble)
1291 (cpp-define-intro . 0)
1292 (knr-argdecl . 0)
1293 (inextern-lang . [0])
1294 (label . 0)
1295 (case-label . +)
1296 (access-label . -)
1297 (inclass . +)
1298 (inline-open . ++)
1299 (statement-cont . +)
1300 (statement-case-intro . +)))
1301 t))
1302
1303(defvar mdw-c-comment-fill-prefix
1304 `((,(concat "\\([ \t]*/?\\)"
1305 "\\(\*\\|//]\\)"
1306 "\\([ \t]*\\)"
1307 "\\([A-Za-z]+:[ \t]*\\)?"
1308 mdw-hanging-indents)
1309 (pad . 1) (match . 2) (pad . 3) (pad . 4) (pad . 5)))
1310 "Fill prefix matching C comments (both kinds).")
1311
1312(defun mdw-fontify-c-and-c++ ()
1313
1314 ;; Fiddle with some syntax codes.
1315 (modify-syntax-entry ?* ". 23")
1316 (modify-syntax-entry ?/ ". 124b")
1317 (modify-syntax-entry ?\n "> b")
1318
1319 ;; Other stuff.
1320 (mdw-c-style)
1321 (setq c-hanging-comment-ender-p nil)
1322 (setq c-backslash-column 72)
1323 (setq c-label-minimum-indentation 0)
1324 (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
1325
1326 ;; Now define things to be fontified.
1327 (make-local-variable 'font-lock-keywords)
1328 (let ((c-keywords
1329 (mdw-regexps "and" ;C++
1330 "and_eq" ;C++
1331 "asm" ;K&R, GCC
1332 "auto" ;K&R, C89
1333 "bitand" ;C++
1334 "bitor" ;C++
1335 "bool" ;C++, C9X macro
1336 "break" ;K&R, C89
1337 "case" ;K&R, C89
1338 "catch" ;C++
1339 "char" ;K&R, C89
1340 "class" ;C++
1341 "complex" ;C9X macro, C++ template type
1342 "compl" ;C++
1343 "const" ;C89
1344 "const_cast" ;C++
1345 "continue" ;K&R, C89
1346 "defined" ;C89 preprocessor
1347 "default" ;K&R, C89
1348 "delete" ;C++
1349 "do" ;K&R, C89
1350 "double" ;K&R, C89
1351 "dynamic_cast" ;C++
1352 "else" ;K&R, C89
1353 ;; "entry" ;K&R -- never used
1354 "enum" ;C89
1355 "explicit" ;C++
1356 "export" ;C++
1357 "extern" ;K&R, C89
1358 "float" ;K&R, C89
1359 "for" ;K&R, C89
1360 ;; "fortran" ;K&R
1361 "friend" ;C++
1362 "goto" ;K&R, C89
1363 "if" ;K&R, C89
1364 "imaginary" ;C9X macro
1365 "inline" ;C++, C9X, GCC
1366 "int" ;K&R, C89
1367 "long" ;K&R, C89
1368 "mutable" ;C++
1369 "namespace" ;C++
1370 "new" ;C++
1371 "operator" ;C++
1372 "or" ;C++
1373 "or_eq" ;C++
1374 "private" ;C++
1375 "protected" ;C++
1376 "public" ;C++
1377 "register" ;K&R, C89
1378 "reinterpret_cast" ;C++
1379 "restrict" ;C9X
1380 "return" ;K&R, C89
1381 "short" ;K&R, C89
1382 "signed" ;C89
1383 "sizeof" ;K&R, C89
1384 "static" ;K&R, C89
1385 "static_cast" ;C++
1386 "struct" ;K&R, C89
1387 "switch" ;K&R, C89
1388 "template" ;C++
1389 "throw" ;C++
1390 "try" ;C++
1391 "this" ;C++
1392 "typedef" ;C89
1393 "typeid" ;C++
1394 "typeof" ;GCC
1395 "typename" ;C++
1396 "union" ;K&R, C89
1397 "unsigned" ;K&R, C89
1398 "using" ;C++
1399 "virtual" ;C++
1400 "void" ;C89
1401 "volatile" ;C89
1402 "wchar_t" ;C++, C89 library type
1403 "while" ;K&R, C89
1404 "xor" ;C++
1405 "xor_eq" ;C++
1406 "_Bool" ;C9X
1407 "_Complex" ;C9X
1408 "_Imaginary" ;C9X
1409 "_Pragma" ;C9X preprocessor
1410 "__alignof__" ;GCC
1411 "__asm__" ;GCC
1412 "__attribute__" ;GCC
1413 "__complex__" ;GCC
1414 "__const__" ;GCC
1415 "__extension__" ;GCC
1416 "__imag__" ;GCC
1417 "__inline__" ;GCC
1418 "__label__" ;GCC
1419 "__real__" ;GCC
1420 "__signed__" ;GCC
1421 "__typeof__" ;GCC
1422 "__volatile__" ;GCC
1423 ))
1424 (c-constants
1425 (mdw-regexps "false" ;C++, C9X macro
1426 "this" ;C++
1427 "true" ;C++, C9X macro
1428 ))
1429 (preprocessor-keywords
1430 (mdw-regexps "assert" "define" "elif" "else" "endif" "error"
1431 "ident" "if" "ifdef" "ifndef" "import" "include"
1432 "line" "pragma" "unassert" "undef" "warning"))
1433 (objc-keywords
1434 (mdw-regexps "class" "defs" "encode" "end" "implementation"
1435 "interface" "private" "protected" "protocol" "public"
1436 "selector")))
1437
1438 (setq font-lock-keywords
1439 (list
1440
1441 ;; Fontify include files as strings.
1442 (list (concat "^[ \t]*\\#[ \t]*"
1443 "\\(include\\|import\\)"
1444 "[ \t]*\\(<[^>]+\\(>\\|\\)\\)")
1445 '(2 font-lock-string-face))
1446
1447 ;; Preprocessor directives are `references'?.
1448 (list (concat "^\\([ \t]*#[ \t]*\\(\\("
1449 preprocessor-keywords
1450 "\\)\\>\\|[0-9]+\\|$\\)\\)")
1451 '(1 font-lock-keyword-face))
1452
1453 ;; Handle the keywords defined above.
1454 (list (concat "@\\<\\(" objc-keywords "\\)\\>")
1455 '(0 font-lock-keyword-face))
1456
1457 (list (concat "\\<\\(" c-keywords "\\)\\>")
1458 '(0 font-lock-keyword-face))
1459
1460 (list (concat "\\<\\(" c-constants "\\)\\>")
1461 '(0 font-lock-variable-name-face))
1462
1463 ;; Handle numbers too.
1464 ;;
1465 ;; This looks strange, I know. It corresponds to the
1466 ;; preprocessor's idea of what a number looks like, rather than
1467 ;; anything sensible.
1468 (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
1469 "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
1470 '(0 mdw-number-face))
1471
1472 ;; And anything else is punctuation.
1473 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1474 '(0 mdw-punct-face))))))
1475
1476;;;--------------------------------------------------------------------------
1477;;; AP calc mode.
1478
1479(defun apcalc-mode ()
1480 (interactive)
1481 (c-mode)
1482 (setq major-mode 'apcalc-mode)
1483 (setq mode-name "AP Calc")
1484 (run-hooks 'apcalc-mode-hook))
1485
1486(defun mdw-fontify-apcalc ()
1487
1488 ;; Fiddle with some syntax codes.
1489 (modify-syntax-entry ?* ". 23")
1490 (modify-syntax-entry ?/ ". 14")
1491
1492 ;; Other stuff.
1493 (mdw-c-style)
1494 (setq c-hanging-comment-ender-p nil)
1495 (setq c-backslash-column 72)
1496 (setq comment-start "/* ")
1497 (setq comment-end " */")
1498 (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
1499
1500 ;; Now define things to be fontified.
1501 (make-local-variable 'font-lock-keywords)
1502 (let ((c-keywords
1503 (mdw-regexps "break" "case" "cd" "continue" "define" "default"
1504 "do" "else" "exit" "for" "global" "goto" "help" "if"
1505 "local" "mat" "obj" "print" "quit" "read" "return"
1506 "show" "static" "switch" "while" "write")))
1507
1508 (setq font-lock-keywords
1509 (list
1510
1511 ;; Handle the keywords defined above.
1512 (list (concat "\\<\\(" c-keywords "\\)\\>")
1513 '(0 font-lock-keyword-face))
1514
1515 ;; Handle numbers too.
1516 ;;
1517 ;; This looks strange, I know. It corresponds to the
1518 ;; preprocessor's idea of what a number looks like, rather than
1519 ;; anything sensible.
1520 (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
1521 "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
1522 '(0 mdw-number-face))
1523
1524 ;; And anything else is punctuation.
1525 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1526 '(0 mdw-punct-face))))))
1527
1528;;;--------------------------------------------------------------------------
1529;;; Java programming configuration.
1530
1531;; Make indentation nice.
1532
1533(defun mdw-java-style ()
1534 (c-add-style "[mdw] Java style"
1535 '((c-basic-offset . 2)
1536 (c-offsets-alist (substatement-open . 0)
1537 (label . +)
1538 (case-label . +)
1539 (access-label . 0)
1540 (inclass . +)
1541 (statement-case-intro . +)))
1542 t))
1543
1544;; Declare Java fontification style.
1545
1546(defun mdw-fontify-java ()
1547
1548 ;; Other stuff.
1549 (mdw-java-style)
1550 (setq c-hanging-comment-ender-p nil)
1551 (setq c-backslash-column 72)
1552 (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
1553
1554 ;; Now define things to be fontified.
1555 (make-local-variable 'font-lock-keywords)
1556 (let ((java-keywords
1557 (mdw-regexps "abstract" "boolean" "break" "byte" "case" "catch"
1558 "char" "class" "const" "continue" "default" "do"
1559 "double" "else" "extends" "final" "finally" "float"
1560 "for" "goto" "if" "implements" "import" "instanceof"
1561 "int" "interface" "long" "native" "new" "package"
1562 "private" "protected" "public" "return" "short"
1563 "static" "switch" "synchronized" "throw" "throws"
1564 "transient" "try" "void" "volatile" "while"))
1565
1566 (java-constants
1567 (mdw-regexps "false" "null" "super" "this" "true")))
1568
1569 (setq font-lock-keywords
1570 (list
1571
1572 ;; Handle the keywords defined above.
1573 (list (concat "\\<\\(" java-keywords "\\)\\>")
1574 '(0 font-lock-keyword-face))
1575
1576 ;; Handle the magic constants defined above.
1577 (list (concat "\\<\\(" java-constants "\\)\\>")
1578 '(0 font-lock-variable-name-face))
1579
1580 ;; Handle numbers too.
1581 ;;
1582 ;; The following isn't quite right, but it's close enough.
1583 (list (concat "\\<\\("
1584 "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1585 "[0-9]+\\(\\.[0-9]*\\|\\)"
1586 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
1587 "[lLfFdD]?")
1588 '(0 mdw-number-face))
1589
1590 ;; And anything else is punctuation.
1591 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1592 '(0 mdw-punct-face))))))
1593
1594;;;--------------------------------------------------------------------------
1595;;; Javascript programming configuration.
1596
1597(defun mdw-javascript-style ()
1598 (setq js-indent-level 2)
1599 (setq js-expr-indent-offset 0))
1600
1601(defun mdw-fontify-javascript ()
1602
1603 ;; Other stuff.
1604 (mdw-javascript-style)
1605 (setq js-auto-indent-flag t)
1606
1607 ;; Now define things to be fontified.
1608 (make-local-variable 'font-lock-keywords)
1609 (let ((javascript-keywords
1610 (mdw-regexps "abstract" "boolean" "break" "byte" "case" "catch"
1611 "char" "class" "const" "continue" "debugger" "default"
1612 "delete" "do" "double" "else" "enum" "export" "extends"
1613 "final" "finally" "float" "for" "function" "goto" "if"
1614 "implements" "import" "in" "instanceof" "int"
1615 "interface" "let" "long" "native" "new" "package"
1616 "private" "protected" "public" "return" "short"
1617 "static" "super" "switch" "synchronized" "throw"
1618 "throws" "transient" "try" "typeof" "var" "void"
1619 "volatile" "while" "with" "yield"
1620
1621 "boolean" "byte" "char" "double" "float" "int" "long"
1622 "short" "void"))
1623 (javascript-constants
1624 (mdw-regexps "false" "null" "undefined" "Infinity" "NaN" "true"
1625 "arguments" "this")))
1626
1627 (setq font-lock-keywords
1628 (list
1629
1630 ;; Handle the keywords defined above.
1631 (list (concat "\\_<\\(" javascript-keywords "\\)\\_>")
1632 '(0 font-lock-keyword-face))
1633
1634 ;; Handle the predefined constants defined above.
1635 (list (concat "\\_<\\(" javascript-constants "\\)\\_>")
1636 '(0 font-lock-variable-name-face))
1637
1638 ;; Handle numbers too.
1639 ;;
1640 ;; The following isn't quite right, but it's close enough.
1641 (list (concat "\\_<\\("
1642 "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1643 "[0-9]+\\(\\.[0-9]*\\|\\)"
1644 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
1645 "[lLfFdD]?")
1646 '(0 mdw-number-face))
1647
1648 ;; And anything else is punctuation.
1649 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1650 '(0 mdw-punct-face))))))
1651
1652;;;--------------------------------------------------------------------------
1653;;; Scala programming configuration.
1654
1655(defun mdw-fontify-scala ()
1656
1657 ;; Comment filling.
1658 (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
1659
1660 ;; Define things to be fontified.
1661 (make-local-variable 'font-lock-keywords)
1662 (let ((scala-keywords
1663 (mdw-regexps "abstract" "case" "catch" "class" "def" "do" "else"
1664 "extends" "final" "finally" "for" "forSome" "if"
1665 "implicit" "import" "lazy" "match" "new" "object"
1666 "override" "package" "private" "protected" "return"
1667 "sealed" "throw" "trait" "try" "type" "val"
1668 "var" "while" "with" "yield"))
1669 (scala-constants
1670 (mdw-regexps "false" "null" "super" "this" "true"))
1671 (punctuation "[-!%^&*=+:@#~/?\\|`]"))
1672
1673 (setq font-lock-keywords
1674 (list
1675
1676 ;; Magical identifiers between backticks.
1677 (list (concat "`\\([^`]+\\)`")
1678 '(1 font-lock-variable-name-face))
1679
1680 ;; Handle the keywords defined above.
1681 (list (concat "\\_<\\(" scala-keywords "\\)\\_>")
1682 '(0 font-lock-keyword-face))
1683
1684 ;; Handle the constants defined above.
1685 (list (concat "\\_<\\(" scala-constants "\\)\\_>")
1686 '(0 font-lock-variable-name-face))
1687
1688 ;; Magical identifiers between backticks.
1689 (list (concat "`\\([^`]+\\)`")
1690 '(1 font-lock-variable-name-face))
1691
1692 ;; Handle numbers too.
1693 ;;
1694 ;; As usual, not quite right.
1695 (list (concat "\\_<\\("
1696 "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1697 "[0-9]+\\(\\.[0-9]*\\|\\)"
1698 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
1699 "[lLfFdD]?")
1700 '(0 mdw-number-face))
1701
1702 ;; Identifiers with trailing operators.
1703 (list (concat "_\\(" punctuation "\\)+")
1704 '(0 mdw-trivial-face))
1705
1706 ;; And everything else is punctuation.
1707 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1708 '(0 mdw-punct-face)))
1709
1710 font-lock-syntactic-keywords
1711 (list
1712
1713 ;; Single quotes around characters. But not when used to quote
1714 ;; symbol names. Ugh.
1715 (list (concat "\\('\\)"
1716 "\\(" "."
1717 "\\|" "\\\\" "\\(" "\\\\\\\\" "\\)*"
1718 "u+" "[0-9a-fA-F]\\{4\\}"
1719 "\\|" "\\\\" "[0-7]\\{1,3\\}"
1720 "\\|" "\\\\" "." "\\)"
1721 "\\('\\)")
1722 '(1 "\"")
1723 '(4 "\""))))))
1724
1725;;;--------------------------------------------------------------------------
1726;;; C# programming configuration.
1727
1728;; Make indentation nice.
1729
1730(defun mdw-csharp-style ()
1731 (c-add-style "[mdw] C# style"
1732 '((c-basic-offset . 2)
1733 (c-offsets-alist (substatement-open . 0)
1734 (label . 0)
1735 (case-label . +)
1736 (access-label . 0)
1737 (inclass . +)
1738 (statement-case-intro . +)))
1739 t))
1740
1741;; Declare C# fontification style.
1742
1743(defun mdw-fontify-csharp ()
1744
1745 ;; Other stuff.
1746 (mdw-csharp-style)
1747 (setq c-hanging-comment-ender-p nil)
1748 (setq c-backslash-column 72)
1749 (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
1750
1751 ;; Now define things to be fontified.
1752 (make-local-variable 'font-lock-keywords)
1753 (let ((csharp-keywords
1754 (mdw-regexps "abstract" "as" "bool" "break" "byte" "case" "catch"
1755 "char" "checked" "class" "const" "continue" "decimal"
1756 "default" "delegate" "do" "double" "else" "enum"
1757 "event" "explicit" "extern" "finally" "fixed" "float"
1758 "for" "foreach" "goto" "if" "implicit" "in" "int"
1759 "interface" "internal" "is" "lock" "long" "namespace"
1760 "new" "object" "operator" "out" "override" "params"
1761 "private" "protected" "public" "readonly" "ref"
1762 "return" "sbyte" "sealed" "short" "sizeof"
1763 "stackalloc" "static" "string" "struct" "switch"
1764 "throw" "try" "typeof" "uint" "ulong" "unchecked"
1765 "unsafe" "ushort" "using" "virtual" "void" "volatile"
1766 "while" "yield"))
1767
1768 (csharp-constants
1769 (mdw-regexps "base" "false" "null" "this" "true")))
1770
1771 (setq font-lock-keywords
1772 (list
1773
1774 ;; Handle the keywords defined above.
1775 (list (concat "\\<\\(" csharp-keywords "\\)\\>")
1776 '(0 font-lock-keyword-face))
1777
1778 ;; Handle the magic constants defined above.
1779 (list (concat "\\<\\(" csharp-constants "\\)\\>")
1780 '(0 font-lock-variable-name-face))
1781
1782 ;; Handle numbers too.
1783 ;;
1784 ;; The following isn't quite right, but it's close enough.
1785 (list (concat "\\<\\("
1786 "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1787 "[0-9]+\\(\\.[0-9]*\\|\\)"
1788 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
1789 "[lLfFdD]?")
1790 '(0 mdw-number-face))
1791
1792 ;; And anything else is punctuation.
1793 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1794 '(0 mdw-punct-face))))))
1795
1796(define-derived-mode csharp-mode java-mode "C#"
1797 "Major mode for editing C# code.")
1798
1799;;;--------------------------------------------------------------------------
1800;;; F# programming configuration.
1801
1802(setq fsharp-indent-offset 2)
1803
1804(defun mdw-fontify-fsharp ()
1805
1806 (let ((punct "=<>+-*/|&%!@?"))
1807 (do ((i 0 (1+ i)))
1808 ((>= i (length punct)))
1809 (modify-syntax-entry (aref punct i) ".")))
1810
1811 (modify-syntax-entry ?_ "_")
1812 (modify-syntax-entry ?( "(")
1813 (modify-syntax-entry ?) ")")
1814
1815 (setq indent-tabs-mode nil)
1816
1817 (let ((fsharp-keywords
1818 (mdw-regexps "abstract" "and" "as" "assert" "atomic"
1819 "begin" "break"
1820 "checked" "class" "component" "const" "constraint"
1821 "constructor" "continue"
1822 "default" "delegate" "do" "done" "downcast" "downto"
1823 "eager" "elif" "else" "end" "exception" "extern"
1824 "finally" "fixed" "for" "fori" "fun" "function"
1825 "functor"
1826 "global"
1827 "if" "in" "include" "inherit" "inline" "interface"
1828 "internal"
1829 "lazy" "let"
1830 "match" "measure" "member" "method" "mixin" "module"
1831 "mutable"
1832 "namespace" "new"
1833 "object" "of" "open" "or" "override"
1834 "parallel" "params" "private" "process" "protected"
1835 "public" "pure"
1836 "rec" "recursive" "return"
1837 "sealed" "sig" "static" "struct"
1838 "tailcall" "then" "to" "trait" "try" "type"
1839 "upcast" "use"
1840 "val" "virtual" "void" "volatile"
1841 "when" "while" "with"
1842 "yield"))
1843
1844 (fsharp-builtins
1845 (mdw-regexps "asr" "land" "lor" "lsl" "lsr" "lxor" "mod"
1846 "base" "false" "null" "true"))
1847
1848 (bang-keywords
1849 (mdw-regexps "do" "let" "return" "use" "yield"))
1850
1851 (preprocessor-keywords
1852 (mdw-regexps "if" "indent" "else" "endif")))
1853
1854 (setq font-lock-keywords
1855 (list (list (concat "\\(^\\|[^\"]\\)"
1856 "\\(" "(\\*"
1857 "[^*]*\\*+"
1858 "\\(" "[^)*]" "[^*]*" "\\*+" "\\)*"
1859 ")"
1860 "\\|"
1861 "//.*"
1862 "\\)")
1863 '(2 font-lock-comment-face))
1864
1865 (list (concat "'" "\\("
1866 "\\\\"
1867 "\\(" "[ntbr'\\]"
1868 "\\|" "[0-9][0-9][0-9]"
1869 "\\|" "u" "[0-9a-fA-F]\\{4\\}"
1870 "\\|" "U" "[0-9a-fA-F]\\{8\\}"
1871 "\\)"
1872 "\\|"
1873 "." "\\)" "'"
1874 "\\|"
1875 "\"" "[^\"\\]*"
1876 "\\(" "\\\\" "\\(.\\|\n\\)"
1877 "[^\"\\]*" "\\)*"
1878 "\\(\"\\|\\'\\)")
1879 '(0 font-lock-string-face))
1880
1881 (list (concat "\\_<\\(" bang-keywords "\\)!" "\\|"
1882 "^#[ \t]*\\(" preprocessor-keywords "\\)\\_>"
1883 "\\|"
1884 "\\_<\\(" fsharp-keywords "\\)\\_>")
1885 '(0 font-lock-keyword-face))
1886 (list (concat "\\<\\(" fsharp-builtins "\\)\\_>")
1887 '(0 font-lock-variable-name-face))
1888
1889 (list (concat "\\_<"
1890 "\\(" "0[bB][01]+" "\\|"
1891 "0[oO][0-7]+" "\\|"
1892 "0[xX][0-9a-fA-F]+" "\\)"
1893 "\\(" "lf\\|LF" "\\|"
1894 "[uU]?[ysnlL]?" "\\)"
1895 "\\|"
1896 "\\_<"
1897 "[0-9]+" "\\("
1898 "[mMQRZING]"
1899 "\\|"
1900 "\\(\\.[0-9]*\\)?"
1901 "\\([eE][-+]?[0-9]+\\)?"
1902 "[fFmM]?"
1903 "\\|"
1904 "[uU]?[ysnlL]?"
1905 "\\)")
1906 '(0 mdw-number-face))
1907
1908 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1909 '(0 mdw-punct-face))))))
1910
1911(defun mdw-fontify-inferior-fsharp ()
1912 (mdw-fontify-fsharp)
1913 (setq font-lock-keywords
1914 (append (list (list "^[#-]" '(0 font-lock-comment-face))
1915 (list "^>" '(0 font-lock-keyword-face)))
1916 font-lock-keywords)))
1917
1918;;;--------------------------------------------------------------------------
1919;;; Go programming configuration.
1920
1921(defun mdw-fontify-go ()
1922
1923 (make-local-variable 'font-lock-keywords)
1924 (let ((go-keywords
1925 (mdw-regexps "break" "case" "chan" "const" "continue"
1926 "default" "defer" "else" "fallthrough" "for"
1927 "func" "go" "goto" "if" "import"
1928 "interface" "map" "package" "range" "return"
1929 "select" "struct" "switch" "type" "var"))
1930 (go-intrinsics
1931 (mdw-regexps "bool" "byte" "complex64" "complex128" "error"
1932 "float32" "float64" "int" "uint8" "int16" "int32"
1933 "int64" "rune" "string" "uint" "uint8" "uint16"
1934 "uint32" "uint64" "uintptr" "void"
1935 "false" "iota" "nil" "true"
1936 "init" "main"
1937 "append" "cap" "copy" "delete" "imag" "len" "make"
1938 "new" "panic" "real" "recover")))
1939
1940 (setq font-lock-keywords
1941 (list
1942
1943 ;; Handle the keywords defined above.
1944 (list (concat "\\<\\(" go-keywords "\\)\\>")
1945 '(0 font-lock-keyword-face))
1946 (list (concat "\\<\\(" go-intrinsics "\\)\\>")
1947 '(0 font-lock-variable-name-face))
1948
1949 ;; Strings and characters.
1950 (list (concat "'"
1951 "\\(" "[^\\']" "\\|"
1952 "\\\\"
1953 "\\(" "[abfnrtv\\'\"]" "\\|"
1954 "[0-7]\\{3\\}" "\\|"
1955 "x" "[0-9A-Fa-f]\\{2\\}" "\\|"
1956 "u" "[0-9A-Fa-f]\\{4\\}" "\\|"
1957 "U" "[0-9A-Fa-f]\\{8\\}" "\\)" "\\)"
1958 "'"
1959 "\\|"
1960 "\""
1961 "\\(" "[^\n\\\"]+" "\\|" "\\\\." "\\)*"
1962 "\\(\"\\|$\\)"
1963 "\\|"
1964 "`" "[^`]+" "`")
1965 '(0 font-lock-string-face))
1966
1967 ;; Handle numbers too.
1968 ;;
1969 ;; The following isn't quite right, but it's close enough.
1970 (list (concat "\\<\\("
1971 "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1972 "[0-9]+\\(\\.[0-9]*\\|\\)"
1973 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)")
1974 '(0 mdw-number-face))
1975
1976 ;; And anything else is punctuation.
1977 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1978 '(0 mdw-punct-face))))))
1979
1980;;;--------------------------------------------------------------------------
1981;;; Rust programming configuration.
1982
1983(setq-default rust-indent-offset 2)
1984
1985(defun mdw-self-insert-and-indent (count)
1986 (interactive "p")
1987 (self-insert-command count)
1988 (indent-according-to-mode))
1989
1990(defun mdw-fontify-rust ()
1991
1992 ;; Hack syntax categories.
1993 (modify-syntax-entry ?= ".")
1994
1995 ;; Fontify keywords and things.
1996 (make-local-variable 'font-lock-keywords)
1997 (let ((rust-keywords
1998 (mdw-regexps "abstract" "alignof" "as"
1999 "become" "box" "break"
2000 "const" "continue" "create"
2001 "do"
2002 "else" "enum" "extern"
2003 "false" "final" "fn" "for"
2004 "if" "impl" "in"
2005 "let" "loop"
2006 "macro" "match" "mod" "move" "mut"
2007 "offsetof" "override"
2008 "priv" "pub" "pure"
2009 "ref" "return"
2010 "self" "sizeof" "static" "struct" "super"
2011 "true" "trait" "type" "typeof"
2012 "unsafe" "unsized" "use"
2013 "virtual"
2014 "where" "while"
2015 "yield"))
2016 (rust-builtins
2017 (mdw-regexps "array" "pointer" "slice" "tuple"
2018 "bool" "true" "false"
2019 "f32" "f64"
2020 "i8" "i16" "i32" "i64" "isize"
2021 "u8" "u16" "u32" "u64" "usize"
2022 "char" "str")))
2023 (setq font-lock-keywords
2024 (list
2025
2026 ;; Handle the keywords defined above.
2027 (list (concat "\\<\\(" rust-keywords "\\)\\>")
2028 '(0 font-lock-keyword-face))
2029 (list (concat "\\<\\(" rust-builtins "\\)\\>")
2030 '(0 font-lock-variable-name-face))
2031
2032 ;; Handle numbers too.
2033 (list (concat "\\<\\("
2034 "[0-9][0-9_]*"
2035 "\\(" "\\(\\.[0-9_]+\\)?[eE][-+]?[0-9_]+"
2036 "\\|" "\\.[0-9_]+"
2037 "\\)"
2038 "\\(f32\\|f64\\)?"
2039 "\\|" "\\(" "[0-9][0-9_]*"
2040 "\\|" "0x[0-9a-fA-F_]+"
2041 "\\|" "0o[0-7_]+"
2042 "\\|" "0b[01_]+"
2043 "\\)"
2044 "\\([ui]\\(8\\|16\\|32\\|64\\|s\\|size\\)\\)?"
2045 "\\)\\>")
2046 '(0 mdw-number-face))
2047
2048 ;; And anything else is punctuation.
2049 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2050 '(0 mdw-punct-face)))))
2051
2052 ;; Hack key bindings.
2053 (local-set-key [?{] 'mdw-self-insert-and-indent)
2054 (local-set-key [?}] 'mdw-self-insert-and-indent))
2055
2056;;;--------------------------------------------------------------------------
2057;;; Awk programming configuration.
2058
2059;; Make Awk indentation nice.
2060
2061(defun mdw-awk-style ()
2062 (c-add-style "[mdw] Awk style"
2063 '((c-basic-offset . 2)
2064 (c-offsets-alist (substatement-open . 0)
2065 (statement-cont . 0)
2066 (statement-case-intro . +)))
2067 t))
2068
2069;; Declare Awk fontification style.
2070
2071(defun mdw-fontify-awk ()
2072
2073 ;; Miscellaneous fiddling.
2074 (mdw-awk-style)
2075 (setq c-backslash-column 72)
2076 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
2077
2078 ;; Now define things to be fontified.
2079 (make-local-variable 'font-lock-keywords)
2080 (let ((c-keywords
2081 (mdw-regexps "BEGIN" "END" "ARGC" "ARGIND" "ARGV" "CONVFMT"
2082 "ENVIRON" "ERRNO" "FIELDWIDTHS" "FILENAME" "FNR"
2083 "FS" "IGNORECASE" "NF" "NR" "OFMT" "OFS" "ORS" "RS"
2084 "RSTART" "RLENGTH" "RT" "SUBSEP"
2085 "atan2" "break" "close" "continue" "cos" "delete"
2086 "do" "else" "exit" "exp" "fflush" "file" "for" "func"
2087 "function" "gensub" "getline" "gsub" "if" "in"
2088 "index" "int" "length" "log" "match" "next" "rand"
2089 "return" "print" "printf" "sin" "split" "sprintf"
2090 "sqrt" "srand" "strftime" "sub" "substr" "system"
2091 "systime" "tolower" "toupper" "while")))
2092
2093 (setq font-lock-keywords
2094 (list
2095
2096 ;; Handle the keywords defined above.
2097 (list (concat "\\<\\(" c-keywords "\\)\\>")
2098 '(0 font-lock-keyword-face))
2099
2100 ;; Handle numbers too.
2101 ;;
2102 ;; The following isn't quite right, but it's close enough.
2103 (list (concat "\\<\\("
2104 "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
2105 "[0-9]+\\(\\.[0-9]*\\|\\)"
2106 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
2107 "[uUlL]*")
2108 '(0 mdw-number-face))
2109
2110 ;; And anything else is punctuation.
2111 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2112 '(0 mdw-punct-face))))))
2113
2114;;;--------------------------------------------------------------------------
2115;;; Perl programming style.
2116
2117;; Perl indentation style.
2118
2119(setq perl-indent-level 2)
2120
2121(setq cperl-indent-level 2)
2122(setq cperl-continued-statement-offset 2)
2123(setq cperl-continued-brace-offset 0)
2124(setq cperl-brace-offset -2)
2125(setq cperl-brace-imaginary-offset 0)
2126(setq cperl-label-offset 0)
2127
2128;; Define perl fontification style.
2129
2130(defun mdw-fontify-perl ()
2131
2132 ;; Miscellaneous fiddling.
2133 (modify-syntax-entry ?$ "\\")
2134 (modify-syntax-entry ?$ "\\" font-lock-syntax-table)
2135 (modify-syntax-entry ?: "." font-lock-syntax-table)
2136 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
2137
2138 ;; Now define fontification things.
2139 (make-local-variable 'font-lock-keywords)
2140 (let ((perl-keywords
2141 (mdw-regexps "and"
2142 "break"
2143 "cmp" "continue"
2144 "default" "do"
2145 "else" "elsif" "eq"
2146 "for" "foreach"
2147 "ge" "given" "gt" "goto"
2148 "if"
2149 "last" "le" "local" "lt"
2150 "my"
2151 "ne" "next"
2152 "or" "our"
2153 "package"
2154 "redo" "require" "return"
2155 "sub"
2156 "undef" "unless" "until" "use"
2157 "when" "while")))
2158
2159 (setq font-lock-keywords
2160 (list
2161
2162 ;; Set up the keywords defined above.
2163 (list (concat "\\<\\(" perl-keywords "\\)\\>")
2164 '(0 font-lock-keyword-face))
2165
2166 ;; At least numbers are simpler than C.
2167 (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
2168 "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
2169 "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
2170 '(0 mdw-number-face))
2171
2172 ;; And anything else is punctuation.
2173 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2174 '(0 mdw-punct-face))))))
2175
2176(defun perl-number-tests (&optional arg)
2177 "Assign consecutive numbers to lines containing `#t'. With ARG,
2178strip numbers instead."
2179 (interactive "P")
2180 (save-excursion
2181 (goto-char (point-min))
2182 (let ((i 0) (fmt (if arg "" " %4d")))
2183 (while (search-forward "#t" nil t)
2184 (delete-region (point) (line-end-position))
2185 (setq i (1+ i))
2186 (insert (format fmt i)))
2187 (goto-char (point-min))
2188 (if (re-search-forward "\\(tests\\s-*=>\\s-*\\)\\w*" nil t)
2189 (replace-match (format "\\1%d" i))))))
2190
2191;;;--------------------------------------------------------------------------
2192;;; Python programming style.
2193
2194(defun mdw-fontify-pythonic (keywords)
2195
2196 ;; Miscellaneous fiddling.
2197 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
2198 (setq indent-tabs-mode nil)
2199
2200 ;; Now define fontification things.
2201 (make-local-variable 'font-lock-keywords)
2202 (setq font-lock-keywords
2203 (list
2204
2205 ;; Set up the keywords defined above.
2206 (list (concat "\\_<\\(" keywords "\\)\\_>")
2207 '(0 font-lock-keyword-face))
2208
2209 ;; At least numbers are simpler than C.
2210 (list (concat "\\_<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
2211 "\\_<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
2212 "\\([eE]\\([-+]\\|\\)[0-9_]+\\|[lL]\\|\\)")
2213 '(0 mdw-number-face))
2214
2215 ;; And anything else is punctuation.
2216 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2217 '(0 mdw-punct-face)))))
2218
2219;; Define Python fontification styles.
2220
2221(defun mdw-fontify-python ()
2222 (mdw-fontify-pythonic
2223 (mdw-regexps "and" "as" "assert" "break" "class" "continue" "def"
2224 "del" "elif" "else" "except" "exec" "finally" "for"
2225 "from" "global" "if" "import" "in" "is" "lambda"
2226 "not" "or" "pass" "print" "raise" "return" "try"
2227 "while" "with" "yield")))
2228
2229(defun mdw-fontify-pyrex ()
2230 (mdw-fontify-pythonic
2231 (mdw-regexps "and" "as" "assert" "break" "cdef" "class" "continue"
2232 "ctypedef" "def" "del" "elif" "else" "except" "exec"
2233 "extern" "finally" "for" "from" "global" "if"
2234 "import" "in" "is" "lambda" "not" "or" "pass" "print"
2235 "raise" "return" "struct" "try" "while" "with"
2236 "yield")))
2237
2238;;;--------------------------------------------------------------------------
2239;;; Icon programming style.
2240
2241;; Icon indentation style.
2242
2243(setq icon-brace-offset 0
2244 icon-continued-brace-offset 0
2245 icon-continued-statement-offset 2
2246 icon-indent-level 2)
2247
2248;; Define Icon fontification style.
2249
2250(defun mdw-fontify-icon ()
2251
2252 ;; Miscellaneous fiddling.
2253 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
2254
2255 ;; Now define fontification things.
2256 (make-local-variable 'font-lock-keywords)
2257 (let ((icon-keywords
2258 (mdw-regexps "break" "by" "case" "create" "default" "do" "else"
2259 "end" "every" "fail" "global" "if" "initial"
2260 "invocable" "link" "local" "next" "not" "of"
2261 "procedure" "record" "repeat" "return" "static"
2262 "suspend" "then" "to" "until" "while"))
2263 (preprocessor-keywords
2264 (mdw-regexps "define" "else" "endif" "error" "ifdef" "ifndef"
2265 "include" "line" "undef")))
2266 (setq font-lock-keywords
2267 (list
2268
2269 ;; Set up the keywords defined above.
2270 (list (concat "\\<\\(" icon-keywords "\\)\\>")
2271 '(0 font-lock-keyword-face))
2272
2273 ;; The things that Icon calls keywords.
2274 (list "&\\sw+\\>" '(0 font-lock-variable-name-face))
2275
2276 ;; At least numbers are simpler than C.
2277 (list (concat "\\<[0-9]+"
2278 "\\([rR][0-9a-zA-Z]+\\|"
2279 "\\.[0-9]+\\([eE][+-]?[0-9]+\\)?\\)\\>\\|"
2280 "\\.[0-9]+\\([eE][+-]?[0-9]+\\)?\\>")
2281 '(0 mdw-number-face))
2282
2283 ;; Preprocessor.
2284 (list (concat "^[ \t]*$[ \t]*\\<\\("
2285 preprocessor-keywords
2286 "\\)\\>")
2287 '(0 font-lock-keyword-face))
2288
2289 ;; And anything else is punctuation.
2290 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2291 '(0 mdw-punct-face))))))
2292
2293;;;--------------------------------------------------------------------------
2294;;; Assembler mode.
2295
2296(defun mdw-fontify-asm ()
2297 (modify-syntax-entry ?' "\"")
2298 (modify-syntax-entry ?. "w")
2299 (modify-syntax-entry ?\n ">")
2300 (setf fill-prefix nil)
2301 (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)"))
2302
2303(defun mdw-asm-set-comment ()
2304 (modify-syntax-entry ?; "."
2305 )
2306 (modify-syntax-entry asm-comment-char "<b")
2307 (setq comment-start (string asm-comment-char ? )))
2308(add-hook 'asm-mode-local-variables-hook 'mdw-asm-set-comment)
2309(put 'asm-comment-char 'safe-local-variable 'characterp)
2310
2311;;;--------------------------------------------------------------------------
2312;;; TCL configuration.
2313
2314(defun mdw-fontify-tcl ()
2315 (mapcar #'(lambda (ch) (modify-syntax-entry ch ".")) '(?$))
2316 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
2317 (make-local-variable 'font-lock-keywords)
2318 (setq font-lock-keywords
2319 (list
2320 (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
2321 "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
2322 "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
2323 '(0 mdw-number-face))
2324 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2325 '(0 mdw-punct-face)))))
2326
2327;;;--------------------------------------------------------------------------
2328;;; Dylan programming configuration.
2329
2330(defun mdw-fontify-dylan ()
2331
2332 (make-local-variable 'font-lock-keywords)
2333
2334 ;; Horrors. `dylan-mode' sets the `major-mode' name after calling this
2335 ;; hook, which undoes all of our configuration.
2336 (setq major-mode 'dylan-mode)
2337 (font-lock-set-defaults)
2338
2339 (let* ((word "[-_a-zA-Z!*@<>$%]+")
2340 (dylan-keywords (mdw-regexps
2341
2342 "C-address" "C-callable-wrapper" "C-function"
2343 "C-mapped-subtype" "C-pointer-type" "C-struct"
2344 "C-subtype" "C-union" "C-variable"
2345
2346 "above" "abstract" "afterwards" "all"
2347 "begin" "below" "block" "by"
2348 "case" "class" "cleanup" "constant" "create"
2349 "define" "domain"
2350 "else" "elseif" "end" "exception" "export"
2351 "finally" "for" "from" "function"
2352 "generic"
2353 "handler"
2354 "if" "in" "instance" "interface" "iterate"
2355 "keyed-by"
2356 "let" "library" "local"
2357 "macro" "method" "module"
2358 "otherwise"
2359 "profiling"
2360 "select" "slot" "subclass"
2361 "table" "then" "to"
2362 "unless" "until" "use"
2363 "variable" "virtual"
2364 "when" "while"))
2365 (sharp-keywords (mdw-regexps
2366 "all-keys" "key" "next" "rest" "include"
2367 "t" "f")))
2368 (setq font-lock-keywords
2369 (list (list (concat "\\<\\(" dylan-keywords
2370 "\\|" "with\\(out\\)?-" word
2371 "\\)\\>")
2372 '(0 font-lock-keyword-face))
2373 (list (concat "\\<" word ":" "\\|"
2374 "#\\(" sharp-keywords "\\)\\>")
2375 '(0 font-lock-variable-name-face))
2376 (list (concat "\\("
2377 "\\([-+]\\|\\<\\)[0-9]+" "\\("
2378 "\\(\\.[0-9]+\\)?" "\\([eE][-+][0-9]+\\)?"
2379 "\\|" "/[0-9]+"
2380 "\\)"
2381 "\\|" "\\.[0-9]+" "\\([eE][-+][0-9]+\\)?"
2382 "\\|" "#b[01]+"
2383 "\\|" "#o[0-7]+"
2384 "\\|" "#x[0-9a-zA-Z]+"
2385 "\\)\\>")
2386 '(0 mdw-number-face))
2387 (list (concat "\\("
2388 "\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\|"
2389 "\\_<[-+*/=<>:&|]+\\_>"
2390 "\\)")
2391 '(0 mdw-punct-face))))))
2392
2393;;;--------------------------------------------------------------------------
2394;;; Algol 68 configuration.
2395
2396(setq a68-indent-step 2)
2397
2398(defun mdw-fontify-algol-68 ()
2399
2400 ;; Fix up the syntax table.
2401 (modify-syntax-entry ?# "!" a68-mode-syntax-table)
2402 (dolist (ch '(?- ?+ ?= ?< ?> ?* ?/ ?| ?&))
2403 (modify-syntax-entry ch "." a68-mode-syntax-table))
2404
2405 (make-local-variable 'font-lock-keywords)
2406
2407 (let ((not-comment
2408 (let ((word "COMMENT"))
2409 (do ((regexp (concat "[^" (substring word 0 1) "]+")
2410 (concat regexp "\\|"
2411 (substring word 0 i)
2412 "[^" (substring word i (1+ i)) "]"))
2413 (i 1 (1+ i)))
2414 ((>= i (length word)) regexp)))))
2415 (setq font-lock-keywords
2416 (list (list (concat "\\<COMMENT\\>"
2417 "\\(" not-comment "\\)\\{0,5\\}"
2418 "\\(\\'\\|\\<COMMENT\\>\\)")
2419 '(0 font-lock-comment-face))
2420 (list (concat "\\<CO\\>"
2421 "\\([^C]+\\|C[^O]\\)\\{0,5\\}"
2422 "\\($\\|\\<CO\\>\\)")
2423 '(0 font-lock-comment-face))
2424 (list "\\<[A-Z_]+\\>"
2425 '(0 font-lock-keyword-face))
2426 (list (concat "\\<"
2427 "[0-9]+"
2428 "\\(\\.[0-9]+\\)?"
2429 "\\([eE][-+]?[0-9]+\\)?"
2430 "\\>")
2431 '(0 mdw-number-face))
2432 (list "\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/"
2433 '(0 mdw-punct-face))))))
2434
2435;;;--------------------------------------------------------------------------
2436;;; REXX configuration.
2437
2438(defun mdw-rexx-electric-* ()
2439 (interactive)
2440 (insert ?*)
2441 (rexx-indent-line))
2442
2443(defun mdw-rexx-indent-newline-indent ()
2444 (interactive)
2445 (rexx-indent-line)
2446 (if abbrev-mode (expand-abbrev))
2447 (newline-and-indent))
2448
2449(defun mdw-fontify-rexx ()
2450
2451 ;; Various bits of fiddling.
2452 (setq mdw-auto-indent nil)
2453 (local-set-key [?\C-m] 'mdw-rexx-indent-newline-indent)
2454 (local-set-key [?*] 'mdw-rexx-electric-*)
2455 (mapcar #'(lambda (ch) (modify-syntax-entry ch "w"))
2456 '(?! ?? ?# ?@ ?$))
2457 (mdw-standard-fill-prefix "\\([ \t]*/?\*[ \t]*\\)")
2458
2459 ;; Set up keywords and things for fontification.
2460 (make-local-variable 'font-lock-keywords-case-fold-search)
2461 (setq font-lock-keywords-case-fold-search t)
2462
2463 (setq rexx-indent 2)
2464 (setq rexx-end-indent rexx-indent)
2465 (setq rexx-cont-indent rexx-indent)
2466
2467 (make-local-variable 'font-lock-keywords)
2468 (let ((rexx-keywords
2469 (mdw-regexps "address" "arg" "by" "call" "digits" "do" "drop"
2470 "else" "end" "engineering" "exit" "expose" "for"
2471 "forever" "form" "fuzz" "if" "interpret" "iterate"
2472 "leave" "linein" "name" "nop" "numeric" "off" "on"
2473 "options" "otherwise" "parse" "procedure" "pull"
2474 "push" "queue" "return" "say" "select" "signal"
2475 "scientific" "source" "then" "trace" "to" "until"
2476 "upper" "value" "var" "version" "when" "while"
2477 "with"
2478
2479 "abbrev" "abs" "bitand" "bitor" "bitxor" "b2x"
2480 "center" "center" "charin" "charout" "chars"
2481 "compare" "condition" "copies" "c2d" "c2x"
2482 "datatype" "date" "delstr" "delword" "d2c" "d2x"
2483 "errortext" "format" "fuzz" "insert" "lastpos"
2484 "left" "length" "lineout" "lines" "max" "min"
2485 "overlay" "pos" "queued" "random" "reverse" "right"
2486 "sign" "sourceline" "space" "stream" "strip"
2487 "substr" "subword" "symbol" "time" "translate"
2488 "trunc" "value" "verify" "word" "wordindex"
2489 "wordlength" "wordpos" "words" "xrange" "x2b" "x2c"
2490 "x2d")))
2491
2492 (setq font-lock-keywords
2493 (list
2494
2495 ;; Set up the keywords defined above.
2496 (list (concat "\\<\\(" rexx-keywords "\\)\\>")
2497 '(0 font-lock-keyword-face))
2498
2499 ;; Fontify all symbols the same way.
2500 (list (concat "\\<\\([0-9.][A-Za-z0-9.!?_#@$]*[Ee][+-]?[0-9]+\\|"
2501 "[A-Za-z0-9.!?_#@$]+\\)")
2502 '(0 font-lock-variable-name-face))
2503
2504 ;; And everything else is punctuation.
2505 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2506 '(0 mdw-punct-face))))))
2507
2508;;;--------------------------------------------------------------------------
2509;;; Standard ML programming style.
2510
2511(defun mdw-fontify-sml ()
2512
2513 ;; Make underscore an honorary letter.
2514 (modify-syntax-entry ?' "w")
2515
2516 ;; Set fill prefix.
2517 (mdw-standard-fill-prefix "\\([ \t]*(\*[ \t]*\\)")
2518
2519 ;; Now define fontification things.
2520 (make-local-variable 'font-lock-keywords)
2521 (let ((sml-keywords
2522 (mdw-regexps "abstype" "and" "andalso" "as"
2523 "case"
2524 "datatype" "do"
2525 "else" "end" "eqtype" "exception"
2526 "fn" "fun" "functor"
2527 "handle"
2528 "if" "in" "include" "infix" "infixr"
2529 "let" "local"
2530 "nonfix"
2531 "of" "op" "open" "orelse"
2532 "raise" "rec"
2533 "sharing" "sig" "signature" "struct" "structure"
2534 "then" "type"
2535 "val"
2536 "where" "while" "with" "withtype")))
2537
2538 (setq font-lock-keywords
2539 (list
2540
2541 ;; Set up the keywords defined above.
2542 (list (concat "\\<\\(" sml-keywords "\\)\\>")
2543 '(0 font-lock-keyword-face))
2544
2545 ;; At least numbers are simpler than C.
2546 (list (concat "\\<\\(\\~\\|\\)"
2547 "\\(0\\(\\([wW]\\|\\)[xX][0-9a-fA-F]+\\|"
2548 "[wW][0-9]+\\)\\|"
2549 "\\([0-9]+\\(\\.[0-9]+\\|\\)"
2550 "\\([eE]\\(\\~\\|\\)"
2551 "[0-9]+\\|\\)\\)\\)")
2552 '(0 mdw-number-face))
2553
2554 ;; And anything else is punctuation.
2555 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2556 '(0 mdw-punct-face))))))
2557
2558;;;--------------------------------------------------------------------------
2559;;; Haskell configuration.
2560
2561(defun mdw-fontify-haskell ()
2562
2563 ;; Fiddle with syntax table to get comments right.
2564 (modify-syntax-entry ?' "_")
2565 (modify-syntax-entry ?- ". 12")
2566 (modify-syntax-entry ?\n ">")
2567
2568 ;; Make punctuation be punctuation
2569 (let ((punct "=<>+-*/|&%!@?$.^:#`"))
2570 (do ((i 0 (1+ i)))
2571 ((>= i (length punct)))
2572 (modify-syntax-entry (aref punct i) ".")))
2573
2574 ;; Set fill prefix.
2575 (mdw-standard-fill-prefix "\\([ \t]*{?--?[ \t]*\\)")
2576
2577 ;; Fiddle with fontification.
2578 (make-local-variable 'font-lock-keywords)
2579 (let ((haskell-keywords
2580 (mdw-regexps "as"
2581 "case" "ccall" "class"
2582 "data" "default" "deriving" "do"
2583 "else" "exists"
2584 "forall" "foreign"
2585 "hiding"
2586 "if" "import" "in" "infix" "infixl" "infixr" "instance"
2587 "let"
2588 "mdo" "module"
2589 "newtype"
2590 "of"
2591 "proc"
2592 "qualified"
2593 "rec"
2594 "safe" "stdcall"
2595 "then" "type"
2596 "unsafe"
2597 "where"))
2598 (control-sequences
2599 (mdw-regexps "ACK" "BEL" "BS" "CAN" "CR" "DC1" "DC2" "DC3" "DC4"
2600 "DEL" "DLE" "EM" "ENQ" "EOT" "ESC" "ETB" "ETX" "FF"
2601 "FS" "GS" "HT" "LF" "NAK" "NUL" "RS" "SI" "SO" "SOH"
2602 "SP" "STX" "SUB" "SYN" "US" "VT")))
2603
2604 (setq font-lock-keywords
2605 (list
2606 (list (concat "{-" "[^-]*" "\\(-+[^-}][^-]*\\)*"
2607 "\\(-+}\\|-*\\'\\)"
2608 "\\|"
2609 "--.*$")
2610 '(0 font-lock-comment-face))
2611 (list (concat "\\_<\\(" haskell-keywords "\\)\\_>")
2612 '(0 font-lock-keyword-face))
2613 (list (concat "'\\("
2614 "[^\\]"
2615 "\\|"
2616 "\\\\"
2617 "\\(" "[abfnrtv\\\"']" "\\|"
2618 "^" "\\(" control-sequences "\\|"
2619 "[]A-Z@[\\^_]" "\\)" "\\|"
2620 "\\|"
2621 "[0-9]+" "\\|"
2622 "[oO][0-7]+" "\\|"
2623 "[xX][0-9A-Fa-f]+"
2624 "\\)"
2625 "\\)'")
2626 '(0 font-lock-string-face))
2627 (list "\\_<[A-Z]\\(\\sw+\\|\\s_+\\)*\\_>"
2628 '(0 font-lock-variable-name-face))
2629 (list (concat "\\_<0\\([xX][0-9a-fA-F]+\\|[oO][0-7]+\\)\\|"
2630 "\\_<[0-9]+\\(\\.[0-9]*\\|\\)"
2631 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)")
2632 '(0 mdw-number-face))
2633 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2634 '(0 mdw-punct-face))))))
2635
2636;;;--------------------------------------------------------------------------
2637;;; Erlang configuration.
2638
2639(setq erlang-electric-commands nil)
2640
2641(defun mdw-fontify-erlang ()
2642
2643 ;; Set fill prefix.
2644 (mdw-standard-fill-prefix "\\([ \t]*{?%*[ \t]*\\)")
2645
2646 ;; Fiddle with fontification.
2647 (make-local-variable 'font-lock-keywords)
2648 (let ((erlang-keywords
2649 (mdw-regexps "after" "and" "andalso"
2650 "band" "begin" "bnot" "bor" "bsl" "bsr" "bxor"
2651 "case" "catch" "cond"
2652 "div" "end" "fun" "if" "let" "not"
2653 "of" "or" "orelse"
2654 "query" "receive" "rem" "try" "when" "xor")))
2655
2656 (setq font-lock-keywords
2657 (list
2658 (list "%.*$"
2659 '(0 font-lock-comment-face))
2660 (list (concat "\\<\\(" erlang-keywords "\\)\\>")
2661 '(0 font-lock-keyword-face))
2662 (list (concat "^-\\sw+\\>")
2663 '(0 font-lock-keyword-face))
2664 (list "\\<[0-9]+\\(\\|#[0-9a-zA-Z]+\\|[eE][+-]?[0-9]+\\)\\>"
2665 '(0 mdw-number-face))
2666 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2667 '(0 mdw-punct-face))))))
2668
2669;;;--------------------------------------------------------------------------
2670;;; Texinfo configuration.
2671
2672(defun mdw-fontify-texinfo ()
2673
2674 ;; Set fill prefix.
2675 (mdw-standard-fill-prefix "\\([ \t]*@c[ \t]+\\)")
2676
2677 ;; Real fontification things.
2678 (make-local-variable 'font-lock-keywords)
2679 (setq font-lock-keywords
2680 (list
2681
2682 ;; Environment names are keywords.
2683 (list "@\\(end\\) *\\([a-zA-Z]*\\)?"
2684 '(2 font-lock-keyword-face))
2685
2686 ;; Unmark escaped magic characters.
2687 (list "\\(@\\)\\([@{}]\\)"
2688 '(1 font-lock-keyword-face)
2689 '(2 font-lock-variable-name-face))
2690
2691 ;; Make sure we get comments properly.
2692 (list "@c\\(\\|omment\\)\\( .*\\)?$"
2693 '(0 font-lock-comment-face))
2694
2695 ;; Command names are keywords.
2696 (list "@\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
2697 '(0 font-lock-keyword-face))
2698
2699 ;; Fontify TeX special characters as punctuation.
2700 (list "[{}]+"
2701 '(0 mdw-punct-face)))))
2702
2703;;;--------------------------------------------------------------------------
2704;;; TeX and LaTeX configuration.
2705
2706(defun mdw-fontify-tex ()
2707 (setq ispell-parser 'tex)
2708 (turn-on-reftex)
2709
2710 ;; Don't make maths into a string.
2711 (modify-syntax-entry ?$ ".")
2712 (modify-syntax-entry ?$ "." font-lock-syntax-table)
2713 (local-set-key [?$] 'self-insert-command)
2714
2715 ;; Set fill prefix.
2716 (mdw-standard-fill-prefix "\\([ \t]*%+[ \t]*\\)")
2717
2718 ;; Real fontification things.
2719 (make-local-variable 'font-lock-keywords)
2720 (setq font-lock-keywords
2721 (list
2722
2723 ;; Environment names are keywords.
2724 (list (concat "\\\\\\(begin\\|end\\|newenvironment\\)"
2725 "{\\([^}\n]*\\)}")
2726 '(2 font-lock-keyword-face))
2727
2728 ;; Suspended environment names are keywords too.
2729 (list (concat "\\\\\\(suspend\\|resume\\)\\(\\[[^]]*\\]\\)?"
2730 "{\\([^}\n]*\\)}")
2731 '(3 font-lock-keyword-face))
2732
2733 ;; Command names are keywords.
2734 (list "\\\\\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
2735 '(0 font-lock-keyword-face))
2736
2737 ;; Handle @/.../ for italics.
2738 ;; (list "\\(@/\\)\\([^/]*\\)\\(/\\)"
2739 ;; '(1 font-lock-keyword-face)
2740 ;; '(3 font-lock-keyword-face))
2741
2742 ;; Handle @*...* for boldness.
2743 ;; (list "\\(@\\*\\)\\([^*]*\\)\\(\\*\\)"
2744 ;; '(1 font-lock-keyword-face)
2745 ;; '(3 font-lock-keyword-face))
2746
2747 ;; Handle @`...' for literal syntax things.
2748 ;; (list "\\(@`\\)\\([^']*\\)\\('\\)"
2749 ;; '(1 font-lock-keyword-face)
2750 ;; '(3 font-lock-keyword-face))
2751
2752 ;; Handle @<...> for nonterminals.
2753 ;; (list "\\(@<\\)\\([^>]*\\)\\(>\\)"
2754 ;; '(1 font-lock-keyword-face)
2755 ;; '(3 font-lock-keyword-face))
2756
2757 ;; Handle other @-commands.
2758 ;; (list "@\\([^a-zA-Z]\\|[a-zA-Z]*\\)"
2759 ;; '(0 font-lock-keyword-face))
2760
2761 ;; Make sure we get comments properly.
2762 (list "%.*"
2763 '(0 font-lock-comment-face))
2764
2765 ;; Fontify TeX special characters as punctuation.
2766 (list "[$^_{}#&]"
2767 '(0 mdw-punct-face)))))
2768
2769;;;--------------------------------------------------------------------------
2770;;; SGML hacking.
2771
2772(defun mdw-sgml-mode ()
2773 (interactive)
2774 (sgml-mode)
2775 (mdw-standard-fill-prefix "")
2776 (make-local-variable 'sgml-delimiters)
2777 (setq sgml-delimiters
2778 '("AND" "&" "COM" "--" "CRO" "&#" "DSC" "]" "DSO" "[" "DTGC" "]"
2779 "DTGO" "[" "ERO" "&" "ETAGO" ":e" "GRPC" ")" "GRPO" "(" "LIT" "\""
2780 "LITA" "'" "MDC" ">" "MDO" "<!" "MINUS" "-" "MSC" "]]" "NESTC" "{"
2781 "NET" "}" "OPT" "?" "OR" "|" "PERO" "%" "PIC" ">" "PIO" "<?"
2782 "PLUS" "+" "REFC" "." "REP" "*" "RNI" "#" "SEQ" "," "STAGO" ":"
2783 "TAGC" "." "VI" "=" "MS-START" "<![" "MS-END" "]]>"
2784 "XML-ECOM" "-->" "XML-PIC" "?>" "XML-SCOM" "<!--" "XML-TAGCE" "/>"
2785 "NULL" ""))
2786 (setq major-mode 'mdw-sgml-mode)
2787 (setq mode-name "[mdw] SGML")
2788 (run-hooks 'mdw-sgml-mode-hook))
2789
2790;;;--------------------------------------------------------------------------
2791;;; Configuration files.
2792
2793(defvar mdw-conf-quote-normal nil
2794 "*Control syntax category of quote characters `\"' and `''.
2795If this is `t', consider quote characters to be normal
2796punctuation, as for `conf-quote-normal'. If this is `nil' then
2797leave quote characters as quotes. If this is a list, then
2798consider the quote characters in the list to be normal
2799punctuation. If this is a single quote character, then consider
2800that character only to be normal punctuation.")
2801(defun mdw-conf-quote-normal-acceptable-value-p (value)
2802 "Is the VALUE is an acceptable value for `mdw-conf-quote-normal'?"
2803 (or (booleanp value)
2804 (every (lambda (v) (memq v '(?\" ?')))
2805 (if (listp value) value (list value)))))
2806(put 'mdw-conf-quote-normal 'safe-local-variable
2807 'mdw-conf-quote-normal-acceptable-value-p)
2808
2809(defun mdw-fix-up-quote ()
2810 "Apply the setting of `mdw-conf-quote-normal'."
2811 (let ((flag mdw-conf-quote-normal))
2812 (cond ((eq flag t)
2813 (conf-quote-normal t))
2814 ((not flag)
2815 nil)
2816 (t
2817 (let ((table (copy-syntax-table (syntax-table))))
2818 (mapc (lambda (ch) (modify-syntax-entry ch "." table))
2819 (if (listp flag) flag (list flag)))
2820 (set-syntax-table table)
2821 (and font-lock-mode (font-lock-fontify-buffer)))))))
2822(add-hook 'conf-mode-local-variables-hook 'mdw-fix-up-quote t t)
2823
2824;;;--------------------------------------------------------------------------
2825;;; Shell scripts.
2826
2827(defun mdw-setup-sh-script-mode ()
2828
2829 ;; Fetch the shell interpreter's name.
2830 (let ((shell-name sh-shell-file))
2831
2832 ;; Try reading the hash-bang line.
2833 (save-excursion
2834 (goto-char (point-min))
2835 (if (looking-at "#![ \t]*\\([^ \t\n]*\\)")
2836 (setq shell-name (match-string 1))))
2837
2838 ;; Now try to set the shell.
2839 ;;
2840 ;; Don't let `sh-set-shell' bugger up my script.
2841 (let ((executable-set-magic #'(lambda (s &rest r) s)))
2842 (sh-set-shell shell-name)))
2843
2844 ;; Don't insert here-document scaffolding automatically.
2845 (local-set-key "<" 'self-insert-command)
2846
2847 ;; Now enable my keys and the fontification.
2848 (mdw-misc-mode-config)
2849
2850 ;; Set the indentation level correctly.
2851 (setq sh-indentation 2)
2852 (setq sh-basic-offset 2))
2853
2854(setq sh-shell-file "/bin/sh")
2855
2856;; Awful hacking to override the shell detection for particular scripts.
2857(defmacro define-custom-shell-mode (name shell)
2858 `(defun ,name ()
2859 (interactive)
2860 (set (make-local-variable 'sh-shell-file) ,shell)
2861 (sh-mode)))
2862(define-custom-shell-mode bash-mode "/bin/bash")
2863(define-custom-shell-mode rc-mode "/usr/bin/rc")
2864(put 'sh-shell-file 'permanent-local t)
2865
2866;; Hack the rc syntax table. Backquotes aren't paired in rc.
2867(eval-after-load "sh-script"
2868 '(or (assq 'rc sh-mode-syntax-table-input)
2869 (let ((frag '(nil
2870 ?# "<"
2871 ?\n ">#"
2872 ?\" "\"\""
2873 ?\' "\"\'"
2874 ?$ "'"
2875 ?\` "."
2876 ?! "_"
2877 ?% "_"
2878 ?. "_"
2879 ?^ "_"
2880 ?~ "_"
2881 ?, "_"
2882 ?= "."
2883 ?< "."
2884 ?> "."))
2885 (assoc (assq 'rc sh-mode-syntax-table-input)))
2886 (if assoc
2887 (rplacd assoc frag)
2888 (setq sh-mode-syntax-table-input
2889 (cons (cons 'rc frag)
2890 sh-mode-syntax-table-input))))))
2891
2892;;;--------------------------------------------------------------------------
2893;;; Emacs shell mode.
2894
2895(defun mdw-eshell-prompt ()
2896 (let ((left "[") (right "]"))
2897 (when (= (user-uid) 0)
2898 (setq left "«" right "»"))
2899 (concat left
2900 (save-match-data
2901 (replace-regexp-in-string "\\..*$" "" (system-name)))
2902 " "
2903 (let* ((pwd (eshell/pwd)) (npwd (length pwd))
2904 (home (expand-file-name "~")) (nhome (length home)))
2905 (if (and (>= npwd nhome)
2906 (or (= nhome npwd)
2907 (= (elt pwd nhome) ?/))
2908 (string= (substring pwd 0 nhome) home))
2909 (concat "~" (substring pwd (length home)))
2910 pwd))
2911 right)))
2912(setq eshell-prompt-function 'mdw-eshell-prompt)
2913(setq eshell-prompt-regexp "^\\[[^]>]+\\(\\]\\|>>?\\)")
2914
2915(defun eshell/e (file) (find-file file) nil)
2916(defun eshell/ee (file) (find-file-other-window file) nil)
2917(defun eshell/w3m (url) (w3m-goto-url url) nil)
2918
2919(mdw-define-face eshell-prompt (t :weight bold))
2920(mdw-define-face eshell-ls-archive (t :weight bold :foreground "red"))
2921(mdw-define-face eshell-ls-backup (t :foreground "lightgrey" :slant italic))
2922(mdw-define-face eshell-ls-product (t :foreground "lightgrey" :slant italic))
2923(mdw-define-face eshell-ls-clutter (t :foreground "lightgrey" :slant italic))
2924(mdw-define-face eshell-ls-executable (t :weight bold))
2925(mdw-define-face eshell-ls-directory (t :foreground "cyan" :weight bold))
2926(mdw-define-face eshell-ls-readonly (t nil))
2927(mdw-define-face eshell-ls-symlink (t :foreground "cyan"))
2928
2929;;;--------------------------------------------------------------------------
2930;;; Messages-file mode.
2931
2932(defun messages-mode-guts ()
2933 (setq messages-mode-syntax-table (make-syntax-table))
2934 (set-syntax-table messages-mode-syntax-table)
2935 (modify-syntax-entry ?0 "w" messages-mode-syntax-table)
2936 (modify-syntax-entry ?1 "w" messages-mode-syntax-table)
2937 (modify-syntax-entry ?2 "w" messages-mode-syntax-table)
2938 (modify-syntax-entry ?3 "w" messages-mode-syntax-table)
2939 (modify-syntax-entry ?4 "w" messages-mode-syntax-table)
2940 (modify-syntax-entry ?5 "w" messages-mode-syntax-table)
2941 (modify-syntax-entry ?6 "w" messages-mode-syntax-table)
2942 (modify-syntax-entry ?7 "w" messages-mode-syntax-table)
2943 (modify-syntax-entry ?8 "w" messages-mode-syntax-table)
2944 (modify-syntax-entry ?9 "w" messages-mode-syntax-table)
2945 (make-local-variable 'comment-start)
2946 (make-local-variable 'comment-end)
2947 (make-local-variable 'indent-line-function)
2948 (setq indent-line-function 'indent-relative)
2949 (mdw-standard-fill-prefix "\\([ \t]*\\(;\\|/?\\*\\)+[ \t]*\\)")
2950 (make-local-variable 'font-lock-defaults)
2951 (make-local-variable 'messages-mode-keywords)
2952 (let ((keywords
2953 (mdw-regexps "array" "bitmap" "callback" "docs[ \t]+enum"
2954 "export" "enum" "fixed-octetstring" "flags"
2955 "harmless" "map" "nested" "optional"
2956 "optional-tagged" "package" "primitive"
2957 "primitive-nullfree" "relaxed[ \t]+enum"
2958 "set" "table" "tagged-optional" "union"
2959 "variadic" "vector" "version" "version-tag")))
2960 (setq messages-mode-keywords
2961 (list
2962 (list (concat "\\<\\(" keywords "\\)\\>:")
2963 '(0 font-lock-keyword-face))
2964 '("\\([-a-zA-Z0-9]+:\\)" (0 font-lock-warning-face))
2965 '("\\(\\<[a-z][-_a-zA-Z0-9]*\\)"
2966 (0 font-lock-variable-name-face))
2967 '("\\<\\([0-9]+\\)\\>" (0 mdw-number-face))
2968 '("\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2969 (0 mdw-punct-face)))))
2970 (setq font-lock-defaults
2971 '(messages-mode-keywords nil nil nil nil))
2972 (run-hooks 'messages-file-hook))
2973
2974(defun messages-mode ()
2975 (interactive)
2976 (fundamental-mode)
2977 (setq major-mode 'messages-mode)
2978 (setq mode-name "Messages")
2979 (messages-mode-guts)
2980 (modify-syntax-entry ?# "<" messages-mode-syntax-table)
2981 (modify-syntax-entry ?\n ">" messages-mode-syntax-table)
2982 (setq comment-start "# ")
2983 (setq comment-end "")
2984 (run-hooks 'messages-mode-hook))
2985
2986(defun cpp-messages-mode ()
2987 (interactive)
2988 (fundamental-mode)
2989 (setq major-mode 'cpp-messages-mode)
2990 (setq mode-name "CPP Messages")
2991 (messages-mode-guts)
2992 (modify-syntax-entry ?* ". 23" messages-mode-syntax-table)
2993 (modify-syntax-entry ?/ ". 14" messages-mode-syntax-table)
2994 (setq comment-start "/* ")
2995 (setq comment-end " */")
2996 (let ((preprocessor-keywords
2997 (mdw-regexps "assert" "define" "elif" "else" "endif" "error"
2998 "ident" "if" "ifdef" "ifndef" "import" "include"
2999 "line" "pragma" "unassert" "undef" "warning")))
3000 (setq messages-mode-keywords
3001 (append (list (list (concat "^[ \t]*\\#[ \t]*"
3002 "\\(include\\|import\\)"
3003 "[ \t]*\\(<[^>]+\\(>\\|\\)\\)")
3004 '(2 font-lock-string-face))
3005 (list (concat "^\\([ \t]*#[ \t]*\\(\\("
3006 preprocessor-keywords
3007 "\\)\\>\\|[0-9]+\\|$\\)\\)")
3008 '(1 font-lock-keyword-face)))
3009 messages-mode-keywords)))
3010 (run-hooks 'cpp-messages-mode-hook))
3011
3012(add-hook 'messages-mode-hook 'mdw-misc-mode-config t)
3013(add-hook 'cpp-messages-mode-hook 'mdw-misc-mode-config t)
3014; (add-hook 'messages-file-hook 'mdw-fontify-messages t)
3015
3016;;;--------------------------------------------------------------------------
3017;;; Messages-file mode.
3018
3019(defvar mallow-driver-substitution-face 'mallow-driver-substitution-face
3020 "Face to use for subsittution directives.")
3021(make-face 'mallow-driver-substitution-face)
3022(defvar mallow-driver-text-face 'mallow-driver-text-face
3023 "Face to use for body text.")
3024(make-face 'mallow-driver-text-face)
3025
3026(defun mallow-driver-mode ()
3027 (interactive)
3028 (fundamental-mode)
3029 (setq major-mode 'mallow-driver-mode)
3030 (setq mode-name "Mallow driver")
3031 (setq mallow-driver-mode-syntax-table (make-syntax-table))
3032 (set-syntax-table mallow-driver-mode-syntax-table)
3033 (make-local-variable 'comment-start)
3034 (make-local-variable 'comment-end)
3035 (make-local-variable 'indent-line-function)
3036 (setq indent-line-function 'indent-relative)
3037 (mdw-standard-fill-prefix "\\([ \t]*\\(;\\|/?\\*\\)+[ \t]*\\)")
3038 (make-local-variable 'font-lock-defaults)
3039 (make-local-variable 'mallow-driver-mode-keywords)
3040 (let ((keywords
3041 (mdw-regexps "each" "divert" "file" "if"
3042 "perl" "set" "string" "type" "write")))
3043 (setq mallow-driver-mode-keywords
3044 (list
3045 (list (concat "^%\\s *\\(}\\|\\(" keywords "\\)\\>\\).*$")
3046 '(0 font-lock-keyword-face))
3047 (list "^%\\s *\\(#.*\\|\\)$"
3048 '(0 font-lock-comment-face))
3049 (list "^%"
3050 '(0 font-lock-keyword-face))
3051 (list "^|?\\(.+\\)$" '(1 mallow-driver-text-face))
3052 (list "\\${[^}]*}"
3053 '(0 mallow-driver-substitution-face t)))))
3054 (setq font-lock-defaults
3055 '(mallow-driver-mode-keywords nil nil nil nil))
3056 (modify-syntax-entry ?\" "_" mallow-driver-mode-syntax-table)
3057 (modify-syntax-entry ?\n ">" mallow-driver-mode-syntax-table)
3058 (setq comment-start "%# ")
3059 (setq comment-end "")
3060 (run-hooks 'mallow-driver-mode-hook))
3061
3062(add-hook 'mallow-driver-hook 'mdw-misc-mode-config t)
3063
3064;;;--------------------------------------------------------------------------
3065;;; NFast debugs.
3066
3067(defun nfast-debug-mode ()
3068 (interactive)
3069 (fundamental-mode)
3070 (setq major-mode 'nfast-debug-mode)
3071 (setq mode-name "NFast debug")
3072 (setq messages-mode-syntax-table (make-syntax-table))
3073 (set-syntax-table messages-mode-syntax-table)
3074 (make-local-variable 'font-lock-defaults)
3075 (make-local-variable 'nfast-debug-mode-keywords)
3076 (setq truncate-lines t)
3077 (setq nfast-debug-mode-keywords
3078 (list
3079 '("^\\(NFast_\\(Connect\\|Disconnect\\|Submit\\|Wait\\)\\)"
3080 (0 font-lock-keyword-face))
3081 (list (concat "^[ \t]+\\(\\("
3082 "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"
3083 "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"
3084 "[ \t]+\\)*"
3085 "[0-9a-fA-F]+\\)[ \t]*$")
3086 '(0 mdw-number-face))
3087 '("^[ \t]+\.status=[ \t]+\\<\\(OK\\)\\>"
3088 (1 font-lock-keyword-face))
3089 '("^[ \t]+\.status=[ \t]+\\<\\([a-zA-Z][0-9a-zA-Z]*\\)\\>"
3090 (1 font-lock-warning-face))
3091 '("^[ \t]+\.status[ \t]+\\<\\(zero\\)\\>"
3092 (1 nil))
3093 (list (concat "^[ \t]+\\.cmd=[ \t]+"
3094 "\\<\\([a-zA-Z][0-9a-zA-Z]*\\)\\>")
3095 '(1 font-lock-keyword-face))
3096 '("-?\\<\\([0-9]+\\|0x[0-9a-fA-F]+\\)\\>" (0 mdw-number-face))
3097 '("^\\([ \t]+[a-z0-9.]+\\)" (0 font-lock-variable-name-face))
3098 '("\\<\\([a-z][a-z0-9.]+\\)\\>=" (1 font-lock-variable-name-face))
3099 '("\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" (0 mdw-punct-face))))
3100 (setq font-lock-defaults
3101 '(nfast-debug-mode-keywords nil nil nil nil))
3102 (run-hooks 'nfast-debug-mode-hook))
3103
3104;;;--------------------------------------------------------------------------
3105;;; Other languages.
3106
3107;; Smalltalk.
3108
3109(defun mdw-setup-smalltalk ()
3110 (and mdw-auto-indent
3111 (local-set-key "\C-m" 'smalltalk-newline-and-indent))
3112 (make-local-variable 'mdw-auto-indent)
3113 (setq mdw-auto-indent nil)
3114 (local-set-key "\C-i" 'smalltalk-reindent))
3115
3116(defun mdw-fontify-smalltalk ()
3117 (make-local-variable 'font-lock-keywords)
3118 (setq font-lock-keywords
3119 (list
3120 (list "\\<[A-Z][a-zA-Z0-9]*\\>"
3121 '(0 font-lock-keyword-face))
3122 (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
3123 "[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
3124 "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
3125 '(0 mdw-number-face))
3126 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
3127 '(0 mdw-punct-face)))))
3128
3129;; Lispy languages.
3130
3131;; Unpleasant bodge.
3132(unless (boundp 'slime-repl-mode-map)
3133 (setq slime-repl-mode-map (make-sparse-keymap)))
3134
3135(defun mdw-indent-newline-and-indent ()
3136 (interactive)
3137 (indent-for-tab-command)
3138 (newline-and-indent))
3139
3140(eval-after-load "cl-indent"
3141 '(progn
3142 (mapc #'(lambda (pair)
3143 (put (car pair)
3144 'common-lisp-indent-function
3145 (cdr pair)))
3146 '((destructuring-bind . ((&whole 4 &rest 1) 4 &body))
3147 (multiple-value-bind . ((&whole 4 &rest 1) 4 &body))))))
3148
3149(defun mdw-common-lisp-indent ()
3150 (make-local-variable 'lisp-indent-function)
3151 (setq lisp-indent-function 'common-lisp-indent-function))
3152
3153(setq lisp-simple-loop-indentation 2
3154 lisp-loop-keyword-indentation 6
3155 lisp-loop-forms-indentation 6)
3156
3157(defun mdw-fontify-lispy ()
3158
3159 ;; Set fill prefix.
3160 (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)")
3161
3162 ;; Not much fontification needed.
3163 (make-local-variable 'font-lock-keywords)
3164 (setq font-lock-keywords
3165 (list (list (concat "\\("
3166 "\\_<[-+]?"
3167 "\\(" "[0-9]+/[0-9]+"
3168 "\\|" "\\(" "[0-9]+" "\\(\\.[0-9]*\\)?" "\\|"
3169 "\\.[0-9]+" "\\)"
3170 "\\([dDeEfFlLsS][-+]?[0-9]+\\)?"
3171 "\\)"
3172 "\\|"
3173 "#"
3174 "\\(" "x" "[-+]?"
3175 "[0-9A-Fa-f]+" "\\(/[0-9A-Fa-f]+\\)?"
3176 "\\|" "o" "[-+]?" "[0-7]+" "\\(/[0-7]+\\)?"
3177 "\\|" "b" "[-+]?" "[01]+" "\\(/[01]+\\)?"
3178 "\\|" "[0-9]+" "r" "[-+]?"
3179 "[0-9a-zA-Z]+" "\\(/[0-9a-zA-Z]+\\)?"
3180 "\\)"
3181 "\\)\\_>")
3182 '(0 mdw-number-face))
3183 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
3184 '(0 mdw-punct-face)))))
3185
3186(defun comint-send-and-indent ()
3187 (interactive)
3188 (comint-send-input)
3189 (and mdw-auto-indent
3190 (indent-for-tab-command)))
3191
3192(defun mdw-setup-m4 ()
3193
3194 ;; Inexplicably, Emacs doesn't match braces in m4 mode. This is very
3195 ;; annoying: fix it.
3196 (modify-syntax-entry ?{ "(")
3197 (modify-syntax-entry ?} ")")
3198
3199 ;; Fill prefix.
3200 (mdw-standard-fill-prefix "\\([ \t]*\\(?:#+\\|\\<dnl\\>\\)[ \t]*\\)"))
3201
3202;;;--------------------------------------------------------------------------
3203;;; Text mode.
3204
3205(defun mdw-text-mode ()
3206 (setq fill-column 72)
3207 (flyspell-mode t)
3208 (mdw-standard-fill-prefix
3209 "\\([ \t]*\\([>#|:] ?\\)*[ \t]*\\)" 3)
3210 (auto-fill-mode 1))
3211
3212;;;--------------------------------------------------------------------------
3213;;; Outline and hide/show modes.
3214
3215(defun mdw-outline-collapse-all ()
3216 "Completely collapse everything in the entire buffer."
3217 (interactive)
3218 (save-excursion
3219 (goto-char (point-min))
3220 (while (< (point) (point-max))
3221 (hide-subtree)
3222 (forward-line))))
3223
3224(setq hs-hide-comments-when-hiding-all nil)
3225
3226(defadvice hs-hide-all (after hide-first-comment activate)
3227 (save-excursion (hs-hide-initial-comment-block)))
3228
3229;;;--------------------------------------------------------------------------
3230;;; Shell mode.
3231
3232(defun mdw-sh-mode-setup ()
3233 (local-set-key [?\C-a] 'comint-bol)
3234 (add-hook 'comint-output-filter-functions
3235 'comint-watch-for-password-prompt))
3236
3237(defun mdw-term-mode-setup ()
3238 (setq term-prompt-regexp shell-prompt-pattern)
3239 (make-local-variable 'mouse-yank-at-point)
3240 (make-local-variable 'transient-mark-mode)
3241 (setq mouse-yank-at-point t)
3242 (auto-fill-mode -1)
3243 (setq tab-width 8))
3244
3245(defun term-send-meta-right () (interactive) (term-send-raw-string "\e\e[C"))
3246(defun term-send-meta-left () (interactive) (term-send-raw-string "\e\e[D"))
3247(defun term-send-ctrl-uscore () (interactive) (term-send-raw-string "\C-_"))
3248(defun term-send-meta-meta-something ()
3249 (interactive)
3250 (term-send-raw-string "\e\e")
3251 (term-send-raw))
3252(eval-after-load 'term
3253 '(progn
3254 (define-key term-raw-map [?\e ?\e] nil)
3255 (define-key term-raw-map [?\e ?\e t] 'term-send-meta-meta-something)
3256 (define-key term-raw-map [?\C-/] 'term-send-ctrl-uscore)
3257 (define-key term-raw-map [M-right] 'term-send-meta-right)
3258 (define-key term-raw-map [?\e ?\M-O ?C] 'term-send-meta-right)
3259 (define-key term-raw-map [M-left] 'term-send-meta-left)
3260 (define-key term-raw-map [?\e ?\M-O ?D] 'term-send-meta-left)))
3261
3262(defadvice term-exec (before program-args-list compile activate)
3263 "If the PROGRAM argument is a list, interpret it as (PROGRAM . SWITCHES).
3264This allows you to pass a list of arguments through `ansi-term'."
3265 (let ((program (ad-get-arg 2)))
3266 (if (listp program)
3267 (progn
3268 (ad-set-arg 2 (car program))
3269 (ad-set-arg 4 (cdr program))))))
3270
3271(defun ssh (host)
3272 "Open a terminal containing an ssh session to the HOST."
3273 (interactive "sHost: ")
3274 (ansi-term (list "ssh" host) (format "ssh@%s" host)))
3275
3276(defvar git-grep-command
3277 "env PAGER=cat git grep --no-color -nH -e "
3278 "*The default command for \\[git-grep].")
3279
3280(defvar git-grep-history nil)
3281
3282(defun git-grep (command-args)
3283 "Run `git grep' with user-specified args and collect output in a buffer."
3284 (interactive
3285 (list (read-shell-command "Run git grep (like this): "
3286 git-grep-command 'git-grep-history)))
3287 (grep command-args))
3288
3289;;;--------------------------------------------------------------------------
3290;;; Inferior Emacs Lisp.
3291
3292(setq comint-prompt-read-only t)
3293
3294(eval-after-load "comint"
3295 '(progn
3296 (define-key comint-mode-map "\C-w" 'comint-kill-region)
3297 (define-key comint-mode-map [C-S-backspace] 'comint-kill-whole-line)))
3298
3299(eval-after-load "ielm"
3300 '(progn
3301 (define-key ielm-map "\C-w" 'comint-kill-region)
3302 (define-key ielm-map [C-S-backspace] 'comint-kill-whole-line)))
3303
3304;;;----- That's all, folks --------------------------------------------------
3305
3306(provide 'dot-emacs)