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