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